Attachment #702295: Bytecode emitter support for bug #568953

View | Details | Raw Unified | Return to bug 568953
Collapse All | Expand All

(-)a/js/src/frontend/BytecodeEmitter.cpp (-8 / +86 lines)
Line     Link Here 
 Lines 26-41    Link Here 
26
#include "jsversion.h"
26
#include "jsversion.h"
27
#include "jsfun.h"
27
#include "jsfun.h"
28
#include "jsnum.h"
28
#include "jsnum.h"
29
#include "jsopcode.h"
29
#include "jsopcode.h"
30
#include "jsscope.h"
30
#include "jsscope.h"
31
#include "jsscript.h"
31
#include "jsscript.h"
32
#include "jsautooplen.h"        // generated headers last
32
#include "jsautooplen.h"        // generated headers last
33
33
34
#include "builtin/Module.h"
34
#include "ds/LifoAlloc.h"
35
#include "ds/LifoAlloc.h"
35
#include "frontend/BytecodeEmitter.h"
36
#include "frontend/BytecodeEmitter.h"
36
#include "frontend/Parser.h"
37
#include "frontend/Parser.h"
37
#include "frontend/TokenStream.h"
38
#include "frontend/TokenStream.h"
38
#include "vm/Debugger.h"
39
#include "vm/Debugger.h"
39
#include "vm/RegExpObject.h"
40
#include "vm/RegExpObject.h"
40
41
41
#include "jsatominlines.h"
42
#include "jsatominlines.h"
 Lines 695-716   PushStatementBCE(BytecodeEmitter *bce, S Link Here 
695
 * block object or compiler created function.
696
 * block object or compiler created function.
696
 */
697
 */
697
static JSObject *
698
static JSObject *
698
EnclosingStaticScope(BytecodeEmitter *bce)
699
EnclosingStaticScope(BytecodeEmitter *bce)
699
{
700
{
700
    if (bce->blockChain)
701
    if (bce->blockChain)
701
        return bce->blockChain;
702
        return bce->blockChain;
702
703
703
    if (!bce->sc->isFunctionBox()) {
704
    if (bce->sc->isGlobalSharedContext()) {
704
        JS_ASSERT(!bce->parent);
705
        JS_ASSERT(!bce->parent);
705
        return NULL;
706
        return NULL;
706
    }
707
    } else if (bce->sc->isModuleBox()) {
707
708
        return bce->sc->asModuleBox()->module();
708
    return bce->sc->asFunctionBox()->function();
709
    } else {
710
        return bce->sc->asFunctionBox()->function();
711
    }
709
}
712
}
710
713
711
// Push a block scope statement and link blockObj into bce->blockChain.
714
// Push a block scope statement and link blockObj into bce->blockChain.
712
static void
715
static void
713
PushBlockScopeBCE(BytecodeEmitter *bce, StmtInfoBCE *stmt, StaticBlockObject &blockObj,
716
PushBlockScopeBCE(BytecodeEmitter *bce, StmtInfoBCE *stmt, StaticBlockObject &blockObj,
714
                  ptrdiff_t top)
717
                  ptrdiff_t top)
715
{
718
{
716
    PushStatementBCE(bce, stmt, STMT_BLOCK, top);
719
    PushStatementBCE(bce, stmt, STMT_BLOCK, top);
 Lines 958-974   EmitAliasedVarOp(JSContext *cx, JSOp op, Link Here 
958
    }
961
    }
959
962
960
    return EmitAliasedVarOp(cx, op, sc, bce);
963
    return EmitAliasedVarOp(cx, op, sc, bce);
961
}
964
}
962
965
963
static bool
966
static bool
964
EmitVarOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
967
EmitVarOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
965
{
968
{
966
    JS_ASSERT(pn->isKind(PNK_FUNCTION) || pn->isKind(PNK_NAME));
969
    JS_ASSERT(pn->isKind(PNK_MODULE) || pn->isKind(PNK_FUNCTION) || pn->isKind(PNK_NAME));
967
    JS_ASSERT_IF(pn->isKind(PNK_NAME), IsArgOp(op) || IsLocalOp(op));
970
    JS_ASSERT_IF(pn->isKind(PNK_NAME), IsArgOp(op) || IsLocalOp(op));
968
    JS_ASSERT(!pn->pn_cookie.isFree());
971
    JS_ASSERT(!pn->pn_cookie.isFree());
969
972
970
    if (!bce->isAliasedName(pn)) {
973
    if (!bce->isAliasedName(pn)) {
971
        JS_ASSERT(pn->isUsed() || pn->isDefn());
974
        JS_ASSERT(pn->isUsed() || pn->isDefn());
972
        JS_ASSERT_IF(pn->isUsed(), pn->pn_cookie.level() == 0);
975
        JS_ASSERT_IF(pn->isUsed(), pn->pn_cookie.level() == 0);
973
        JS_ASSERT_IF(pn->isDefn(), pn->pn_cookie.level() == bce->script->staticLevel);
976
        JS_ASSERT_IF(pn->isDefn(), pn->pn_cookie.level() == bce->script->staticLevel);
974
        return EmitUnaliasedVarOp(cx, op, pn->pn_cookie.slot(), bce);
977
        return EmitUnaliasedVarOp(cx, op, pn->pn_cookie.slot(), bce);
 Lines 1441-1457   BindNameToSlot(JSContext *cx, BytecodeEm Link Here 
1441
     * bloat where a single live function keeps its whole global script
1444
     * bloat where a single live function keeps its whole global script
1442
     * alive.), ScopeCoordinateToTypeSet is not able to find the var/let's
1445
     * alive.), ScopeCoordinateToTypeSet is not able to find the var/let's
1443
     * associated types::TypeSet.
1446
     * associated types::TypeSet.
1444
     */
1447
     */
1445
    if (skip) {
1448
    if (skip) {
1446
        BytecodeEmitter *bceSkipped = bce;
1449
        BytecodeEmitter *bceSkipped = bce;
1447
        for (unsigned i = 0; i < skip; i++)
1450
        for (unsigned i = 0; i < skip; i++)
1448
            bceSkipped = bceSkipped->parent;
1451
            bceSkipped = bceSkipped->parent;
1449
        if (!bceSkipped->sc->isFunctionBox())
1452
        if (bceSkipped->sc->isGlobalSharedContext())
1450
            return true;
1453
            return true;
1451
    }
1454
    }
1452
1455
1453
    JS_ASSERT(!pn->isOp(op));
1456
    JS_ASSERT(!pn->isOp(op));
1454
    pn->setOp(op);
1457
    pn->setOp(op);
1455
    if (!pn->pn_cookie.set(bce->sc->context, skip, dn->pn_cookie.slot()))
1458
    if (!pn->pn_cookie.set(bce->sc->context, skip, dn->pn_cookie.slot()))
1456
        return false;
1459
        return false;
1457
1460
 Lines 1694-1710   BytecodeEmitter::needsImplicitThis() Link Here 
1694
            return true;
1697
            return true;
1695
    }
1698
    }
1696
    return false;
1699
    return false;
1697
}
1700
}
1698
1701
1699
void
1702
void
1700
BytecodeEmitter::tellDebuggerAboutCompiledScript(JSContext *cx)
1703
BytecodeEmitter::tellDebuggerAboutCompiledScript(JSContext *cx)
1701
{
1704
{
1702
    RootedFunction function(cx, script->function());
1705
    RootedFunction function(cx, script->isFunctionScript() ? script->function() : NULL);
1703
    CallNewScriptHook(cx, script, function);
1706
    CallNewScriptHook(cx, script, function);
1704
    if (!parent) {
1707
    if (!parent) {
1705
        GlobalObject *compileAndGoGlobal = NULL;
1708
        GlobalObject *compileAndGoGlobal = NULL;
1706
        if (script->compileAndGo)
1709
        if (script->compileAndGo)
1707
            compileAndGoGlobal = &script->global();
1710
            compileAndGoGlobal = &script->global();
1708
        Debugger::onNewScript(cx, script, compileAndGoGlobal);
1711
        Debugger::onNewScript(cx, script, compileAndGoGlobal);
1709
    }
1712
    }
1710
}
1713
}
 Lines 4779-4794   static inline bool Link Here 
4779
EmitFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
4782
EmitFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
4780
{
4783
{
4781
    JS_ASSERT(pn->pn_left->isKind(PNK_FORIN) || pn->pn_left->isKind(PNK_FORHEAD));
4784
    JS_ASSERT(pn->pn_left->isKind(PNK_FORIN) || pn->pn_left->isKind(PNK_FORHEAD));
4782
    return pn->pn_left->isKind(PNK_FORIN)
4785
    return pn->pn_left->isKind(PNK_FORIN)
4783
           ? EmitForIn(cx, bce, pn, top)
4786
           ? EmitForIn(cx, bce, pn, top)
4784
           : EmitNormalFor(cx, bce, pn, top);
4787
           : EmitNormalFor(cx, bce, pn, top);
4785
}
4788
}
4786
4789
4790
static bool
4791
EmitModule(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
4792
{
4793
    if (pn->pn_modulebox->module()->script()) {
4794
        return EmitIndex32(cx, JSOP_INITMODULE,
4795
                           bce->objectList.indexOf(pn->pn_modulebox->module()),
4796
                           bce);
4797
    }
4798
4799
    RootedScript enclosingScript(cx, bce->script);
4800
    RootedObject enclosingScope(cx, EnclosingStaticScope(bce));
4801
    CompileOptions options(cx);
4802
    options.setPrincipals(enclosingScript->principals)
4803
           .setOriginPrincipals(enclosingScript->originPrincipals)
4804
           .setCompileAndGo(enclosingScript->compileAndGo)
4805
           .setNoScriptRval(false)
4806
           .setVersion(enclosingScript->getVersion());
4807
    RootedScript script(cx, JSScript::Create(cx, enclosingScope, false, options,
4808
                                             enclosingScript->staticLevel + 1,
4809
                                             enclosingScript->scriptSource(),
4810
                                             pn->pn_modulebox->bufStart,
4811
                                             pn->pn_modulebox->bufEnd));
4812
    if (!script)
4813
        return false;
4814
    script->bindings = pn->pn_modulebox->bindings;
4815
    BytecodeEmitter bce2(bce, bce->parser, pn->pn_modulebox, script,
4816
                         bce->callerFrame, bce->hasGlobalScope,
4817
                         pn->pn_pos.begin.lineno, bce->selfHostingMode);
4818
    if (!bce2.init())
4819
        return false;
4820
    if (!EmitTree(cx, &bce2, pn->pn_body))
4821
        return false;
4822
    if (Emit1(cx, &bce2, JSOP_STOP) < 0)
4823
        return false;
4824
    if (!JSScript::fullyInitFromEmitter(cx, bce2.script, &bce2))
4825
        return false;
4826
    pn->pn_modulebox->module()->setScript(script);
4827
4828
    if (bce->sc->isGlobalSharedContext()) {
4829
        unsigned index = bce->objectList.add(pn->pn_modulebox);
4830
        bce->switchToProlog();
4831
        if (!EmitIndex32(cx, JSOP_DEFMODULE, index, bce))
4832
            return false;
4833
        bce->switchToMain();
4834
        if (!EmitIndex32(cx, JSOP_INITMODULE, index, bce))
4835
            return false;
4836
    } else {
4837
        JS_ASSERT(bce->sc->isModuleBox());
4838
        if (!EmitObjectOp(cx, pn->pn_modulebox, JSOP_MODULE, bce))
4839
            return false;
4840
        if (!EmitVarOp(cx, pn, JSOP_SETLOCAL, bce))
4841
            return false;
4842
        if (Emit1(cx, bce, JSOP_POP) < 0)
4843
            return false;
4844
    }
4845
    return true;
4846
}
4847
4787
static JS_NEVER_INLINE bool
4848
static JS_NEVER_INLINE bool
4788
EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
4849
EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
4789
{
4850
{
4790
    AssertCanGC();
4851
    AssertCanGC();
4791
    RootedFunction fun(cx, pn->pn_funbox->function());
4852
    RootedFunction fun(cx, pn->pn_funbox->function());
4792
    JS_ASSERT(fun->isInterpreted());
4853
    JS_ASSERT(fun->isInterpreted());
4793
    if (fun->hasScript()) {
4854
    if (fun->hasScript()) {
4794
        /*
4855
        /*
 Lines 4853-4869   EmitFunc(JSContext *cx, BytecodeEmitter Link Here 
4853
     * For a script we emit the code as we parse. Thus the bytecode for
4914
     * For a script we emit the code as we parse. Thus the bytecode for
4854
     * top-level functions should go in the prolog to predefine their
4915
     * top-level functions should go in the prolog to predefine their
4855
     * names in the variable object before the already-generated main code
4916
     * names in the variable object before the already-generated main code
4856
     * is executed. This extra work for top-level scripts is not necessary
4917
     * is executed. This extra work for top-level scripts is not necessary
4857
     * when we emit the code for a function. It is fully parsed prior to
4918
     * when we emit the code for a function. It is fully parsed prior to
4858
     * invocation of the emitter and calls to EmitTree for function
4919
     * invocation of the emitter and calls to EmitTree for function
4859
     * definitions can be scheduled before generating the rest of code.
4920
     * definitions can be scheduled before generating the rest of code.
4860
     */
4921
     */
4861
    if (!bce->sc->isFunctionBox()) {
4922
    if (bce->sc->isGlobalSharedContext()) {
4862
        JS_ASSERT(pn->pn_cookie.isFree());
4923
        JS_ASSERT(pn->pn_cookie.isFree());
4863
        JS_ASSERT(pn->getOp() == JSOP_NOP);
4924
        JS_ASSERT(pn->getOp() == JSOP_NOP);
4864
        JS_ASSERT(!bce->topStmt);
4925
        JS_ASSERT(!bce->topStmt);
4865
        bce->switchToProlog();
4926
        bce->switchToProlog();
4866
        if (!EmitIndex32(cx, JSOP_DEFFUN, index, bce))
4927
        if (!EmitIndex32(cx, JSOP_DEFFUN, index, bce))
4867
            return false;
4928
            return false;
4868
        if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
4929
        if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
4869
            return false;
4930
            return false;
 Lines 5955-5970   frontend::EmitTree(JSContext *cx, Byteco Link Here 
5955
    ptrdiff_t top = bce->offset();
6016
    ptrdiff_t top = bce->offset();
5956
    pn->pn_offset = top;
6017
    pn->pn_offset = top;
5957
6018
5958
    /* Emit notes to tell the current bytecode's source line number. */
6019
    /* Emit notes to tell the current bytecode's source line number. */
5959
    if (!UpdateLineNumberNotes(cx, bce, pn->pn_pos.begin.lineno))
6020
    if (!UpdateLineNumberNotes(cx, bce, pn->pn_pos.begin.lineno))
5960
        return false;
6021
        return false;
5961
6022
5962
    switch (pn->getKind()) {
6023
    switch (pn->getKind()) {
6024
      case PNK_MODULE:
6025
        ok = EmitModule(cx, bce, pn);
6026
        break;
6027
5963
      case PNK_FUNCTION:
6028
      case PNK_FUNCTION:
5964
        ok = EmitFunc(cx, bce, pn);
6029
        ok = EmitFunc(cx, bce, pn);
5965
        break;
6030
        break;
5966
6031
5967
      case PNK_ARGSBODY:
6032
      case PNK_ARGSBODY:
5968
      {
6033
      {
5969
        RootedFunction fun(cx, bce->sc->asFunctionBox()->function());
6034
        RootedFunction fun(cx, bce->sc->asFunctionBox()->function());
5970
        ParseNode *pnlast = pn->last();
6035
        ParseNode *pnlast = pn->last();
 Lines 6140-6155   frontend::EmitTree(JSContext *cx, Byteco Link Here 
6140
        if (!EmitTree(cx, bce, pn->pn_kid))
6205
        if (!EmitTree(cx, bce, pn->pn_kid))
6141
            return false;
6206
            return false;
6142
        if (Emit1(cx, bce, pn->getOp()) < 0)
6207
        if (Emit1(cx, bce, pn->getOp()) < 0)
6143
            return false;
6208
            return false;
6144
        break;
6209
        break;
6145
#endif
6210
#endif
6146
6211
6147
      case PNK_STATEMENTLIST:
6212
      case PNK_STATEMENTLIST:
6213
        if (pn->pn_xflags & PNX_MODULEDEFS) {
6214
            for (ParseNode *pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
6215
                if (pn2->isKind(PNK_MODULE)) {
6216
                    if (!EmitTree(cx, bce, pn2))
6217
                        return false;
6218
                }
6219
            }
6220
        }
6148
        ok = EmitStatementList(cx, bce, pn, top);
6221
        ok = EmitStatementList(cx, bce, pn, top);
6149
        break;
6222
        break;
6150
6223
6151
      case PNK_SEQ:
6224
      case PNK_SEQ:
6152
        ok = EmitSyntheticStatements(cx, bce, pn, top);
6225
        ok = EmitSyntheticStatements(cx, bce, pn, top);
6153
        break;
6226
        break;
6154
6227
6155
      case PNK_SEMI:
6228
      case PNK_SEMI:
 Lines 6390-6405   frontend::EmitTree(JSContext *cx, Byteco Link Here 
6390
6463
6391
#if JS_HAS_BLOCK_SCOPE
6464
#if JS_HAS_BLOCK_SCOPE
6392
      case PNK_LET:
6465
      case PNK_LET:
6393
        ok = pn->isArity(PN_BINARY)
6466
        ok = pn->isArity(PN_BINARY)
6394
             ? EmitLet(cx, bce, pn)
6467
             ? EmitLet(cx, bce, pn)
6395
             : EmitVariables(cx, bce, pn, InitializeVars);
6468
             : EmitVariables(cx, bce, pn, InitializeVars);
6396
        break;
6469
        break;
6397
#endif /* JS_HAS_BLOCK_SCOPE */
6470
#endif /* JS_HAS_BLOCK_SCOPE */
6471
6472
      case PNK_EXPORT:
6473
        ok = EmitTree(cx, bce, pn->pn_kid);
6474
        break;
6475
6398
#if JS_HAS_GENERATORS
6476
#if JS_HAS_GENERATORS
6399
      case PNK_ARRAYPUSH: {
6477
      case PNK_ARRAYPUSH: {
6400
        int slot;
6478
        int slot;
6401
6479
6402
        /*
6480
        /*
6403
         * The array object's stack index is in bce->arrayCompDepth. See below
6481
         * The array object's stack index is in bce->arrayCompDepth. See below
6404
         * under the array initialiser code generator for array comprehension
6482
         * under the array initialiser code generator for array comprehension
6405
         * special casing. Note that the array object is a pure stack value,
6483
         * special casing. Note that the array object is a pure stack value,
(-)a/js/src/ion/IonFrames.cpp (-1 / +3 lines)
Line     Link Here 
 Lines 320-336   ion::HandleException(ResumeFromException Link Here 
320
            for (;;) {
320
            for (;;) {
321
                CloseLiveIterators(cx, frames);
321
                CloseLiveIterators(cx, frames);
322
322
323
                // When profiling, each frame popped needs a notification that
323
                // When profiling, each frame popped needs a notification that
324
                // the function has exited, so invoke the probe that a function
324
                // the function has exited, so invoke the probe that a function
325
                // is exiting.
325
                // is exiting.
326
                AutoAssertNoGC nogc;
326
                AutoAssertNoGC nogc;
327
                RawScript script = frames.script();
327
                RawScript script = frames.script();
328
                Probes::exitScript(cx, script, script->function(), NULL);
328
                Probes::exitScript(cx, script,
329
                                   script->isFunctionScript() ? script->function() : NULL,
330
                                   NULL);
329
                if (!frames.more())
331
                if (!frames.more())
330
                    break;
332
                    break;
331
                ++frames;
333
                ++frames;
332
            }
334
            }
333
335
334
            IonScript *ionScript;
336
            IonScript *ionScript;
335
            if (iter.checkInvalidation(&ionScript))
337
            if (iter.checkInvalidation(&ionScript))
336
                ionScript->decref(cx->runtime->defaultFreeOp());
338
                ionScript->decref(cx->runtime->defaultFreeOp());
(-)a/js/src/ion/TypeOracle.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 184-200   TypeInferenceOracle::getOsrTypes(jsbytec Link Here 
184
    // scripts. This means we have to subtract 1 for global/eval scripts.
184
    // scripts. This means we have to subtract 1 for global/eval scripts.
185
    JS_ASSERT(ThisSlot() == 1);
185
    JS_ASSERT(ThisSlot() == 1);
186
    JS_ASSERT(ArgSlot(0) == 2);
186
    JS_ASSERT(ArgSlot(0) == 2);
187
187
188
#ifdef DEBUG
188
#ifdef DEBUG
189
    uint32_t stackDepth = analysis->getCode(osrPc).stackDepth;
189
    uint32_t stackDepth = analysis->getCode(osrPc).stackDepth;
190
#endif
190
#endif
191
191
192
    if (script()->function()) {
192
    if (script()->isFunctionScript()) {
193
        JS_ASSERT(slotTypes.length() == TotalSlots(script()) + stackDepth);
193
        JS_ASSERT(slotTypes.length() == TotalSlots(script()) + stackDepth);
194
194
195
        for (size_t i = ThisSlot(); i < TotalSlots(script()); i++)
195
        for (size_t i = ThisSlot(); i < TotalSlots(script()); i++)
196
            slotTypes[i] = getMIRType(slotTypeSets[i]);
196
            slotTypes[i] = getMIRType(slotTypeSets[i]);
197
    } else {
197
    } else {
198
        JS_ASSERT(slotTypes.length() == TotalSlots(script()) + stackDepth - 1);
198
        JS_ASSERT(slotTypes.length() == TotalSlots(script()) + stackDepth - 1);
199
199
200
        for (size_t i = ArgSlot(0); i < TotalSlots(script()); i++)
200
        for (size_t i = ArgSlot(0); i < TotalSlots(script()); i++)
(-)a/js/src/jsanalyze.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 154-170   ScriptAnalysis::analyzeBytecode(JSContex Link Here 
154
154
155
    /*
155
    /*
156
     * If the script is in debug mode, JS_SetFrameReturnValue can be called at
156
     * If the script is in debug mode, JS_SetFrameReturnValue can be called at
157
     * any safe point.
157
     * any safe point.
158
     */
158
     */
159
    if (cx->compartment->debugMode())
159
    if (cx->compartment->debugMode())
160
        usesReturnValue_ = true;
160
        usesReturnValue_ = true;
161
161
162
    bool heavyweight = script_->function() && script_->function()->isHeavyweight();
162
    bool heavyweight = script_->isFunctionScript() && script_->function() && script_->function()->isHeavyweight();
163
163
164
    isJaegerCompileable = true;
164
    isJaegerCompileable = true;
165
165
166
    isJaegerInlineable = isIonInlineable = true;
166
    isJaegerInlineable = isIonInlineable = true;
167
    if (heavyweight || cx->compartment->debugMode())
167
    if (heavyweight || cx->compartment->debugMode())
168
        isJaegerInlineable = isIonInlineable = false;
168
        isJaegerInlineable = isIonInlineable = false;
169
    if (script_->argumentsHasVarBinding())
169
    if (script_->argumentsHasVarBinding())
170
        isJaegerInlineable = false;
170
        isJaegerInlineable = false;
(-)a/js/src/jsanalyze.h (-1 / +1 lines)
Line     Link Here 
 Lines 351-367   static inline uint32_t CalleeSlot() { Link Here 
351
}
351
}
352
static inline uint32_t ThisSlot() {
352
static inline uint32_t ThisSlot() {
353
    return 1;
353
    return 1;
354
}
354
}
355
static inline uint32_t ArgSlot(uint32_t arg) {
355
static inline uint32_t ArgSlot(uint32_t arg) {
356
    return 2 + arg;
356
    return 2 + arg;
357
}
357
}
358
static inline uint32_t LocalSlot(UnrootedScript script, uint32_t local) {
358
static inline uint32_t LocalSlot(UnrootedScript script, uint32_t local) {
359
    return 2 + (script->function() ? script->function()->nargs : 0) + local;
359
    return 2 + (script->isFunctionScript() ? script->function()->nargs : 0) + local;
360
}
360
}
361
static inline uint32_t TotalSlots(UnrootedScript script) {
361
static inline uint32_t TotalSlots(UnrootedScript script) {
362
    return LocalSlot(script, 0) + script->nfixed;
362
    return LocalSlot(script, 0) + script->nfixed;
363
}
363
}
364
364
365
static inline uint32_t StackSlot(UnrootedScript script, uint32_t index) {
365
static inline uint32_t StackSlot(UnrootedScript script, uint32_t index) {
366
    return TotalSlots(script) + index;
366
    return TotalSlots(script) + index;
367
}
367
}
(-)a/js/src/jsapi.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 5539-5555   JS_CompileFunction(JSContext *cx, JSObje Link Here 
5539
JS_PUBLIC_API(JSString *)
5539
JS_PUBLIC_API(JSString *)
5540
JS_DecompileScript(JSContext *cx, JSScript *scriptArg, const char *name, unsigned indent)
5540
JS_DecompileScript(JSContext *cx, JSScript *scriptArg, const char *name, unsigned indent)
5541
{
5541
{
5542
    JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
5542
    JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
5543
5543
5544
    AssertHeapIsIdle(cx);
5544
    AssertHeapIsIdle(cx);
5545
    CHECK_REQUEST(cx);
5545
    CHECK_REQUEST(cx);
5546
    RootedScript script(cx, scriptArg);
5546
    RootedScript script(cx, scriptArg);
5547
    RootedFunction fun(cx, script->function());
5547
    RootedFunction fun(cx, script->isFunctionScript() ? script->function() : NULL);
5548
    if (fun)
5548
    if (fun)
5549
        return JS_DecompileFunction(cx, fun, indent);
5549
        return JS_DecompileFunction(cx, fun, indent);
5550
    bool haveSource = script->scriptSource()->hasSourceData();
5550
    bool haveSource = script->scriptSource()->hasSourceData();
5551
    if (!haveSource && !JSScript::loadSource(cx, script, &haveSource))
5551
    if (!haveSource && !JSScript::loadSource(cx, script, &haveSource))
5552
        return NULL;
5552
        return NULL;
5553
    return haveSource ? script->sourceData(cx) : js_NewStringCopyZ(cx, "[no source]");
5553
    return haveSource ? script->sourceData(cx) : js_NewStringCopyZ(cx, "[no source]");
5554
}
5554
}
5555
5555
(-)a/js/src/jsfun.cpp (-2 / +2 lines)
Line     Link Here 
 Lines 421-437   js::XDRInterpretedFunction(XDRState<mode Link Here 
421
    if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
421
    if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
422
        return false;
422
        return false;
423
423
424
    if (mode == XDR_DECODE) {
424
    if (mode == XDR_DECODE) {
425
        fun->nargs = flagsword >> 16;
425
        fun->nargs = flagsword >> 16;
426
        fun->flags = uint16_t(flagsword);
426
        fun->flags = uint16_t(flagsword);
427
        fun->initAtom(atom);
427
        fun->initAtom(atom);
428
        fun->initScript(script);
428
        fun->initScript(script);
429
        script->setFunction(fun);
429
        script->setOwner(fun);
430
        if (!JSFunction::setTypeForScriptedFunction(cx, fun))
430
        if (!JSFunction::setTypeForScriptedFunction(cx, fun))
431
            return false;
431
            return false;
432
        JS_ASSERT(fun->nargs == fun->nonLazyScript()->bindings.numArgs());
432
        JS_ASSERT(fun->nargs == fun->nonLazyScript()->bindings.numArgs());
433
        RootedScript script(cx, fun->nonLazyScript());
433
        RootedScript script(cx, fun->nonLazyScript());
434
        CallNewScriptHook(cx, script, fun);
434
        CallNewScriptHook(cx, script, fun);
435
        objp.set(fun);
435
        objp.set(fun);
436
    }
436
    }
437
437
 Lines 460-476   js::CloneInterpretedFunction(JSContext * Link Here 
460
    RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript));
460
    RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript));
461
    if (!clonedScript)
461
    if (!clonedScript)
462
        return NULL;
462
        return NULL;
463
463
464
    clone->nargs = srcFun->nargs;
464
    clone->nargs = srcFun->nargs;
465
    clone->flags = srcFun->flags;
465
    clone->flags = srcFun->flags;
466
    clone->initAtom(srcFun->displayAtom());
466
    clone->initAtom(srcFun->displayAtom());
467
    clone->initScript(clonedScript);
467
    clone->initScript(clonedScript);
468
    clonedScript->setFunction(clone);
468
    clonedScript->setOwner(clone);
469
    if (!JSFunction::setTypeForScriptedFunction(cx, clone))
469
    if (!JSFunction::setTypeForScriptedFunction(cx, clone))
470
        return NULL;
470
        return NULL;
471
471
472
    RootedScript cloneScript(cx, clone->nonLazyScript());
472
    RootedScript cloneScript(cx, clone->nonLazyScript());
473
    CallNewScriptHook(cx, cloneScript, clone);
473
    CallNewScriptHook(cx, cloneScript, clone);
474
    return clone;
474
    return clone;
475
}
475
}
476
476
(-)a/js/src/jsinfer.cpp (-4 / +4 lines)
Line     Link Here 
 Lines 2169-2185   AddPendingRecompile(JSContext *cx, Handl Link Here 
2169
        }
2169
        }
2170
    }
2170
    }
2171
2171
2172
    /*
2172
    /*
2173
     * When one script is inlined into another the caller listens to state
2173
     * When one script is inlined into another the caller listens to state
2174
     * changes on the callee's script, so trigger these to force recompilation
2174
     * changes on the callee's script, so trigger these to force recompilation
2175
     * of any such callers.
2175
     * of any such callers.
2176
     */
2176
     */
2177
    if (script->function() && !script->function()->hasLazyType())
2177
    if (script->isFunctionScript() && !script->function()->hasLazyType())
2178
        ObjectStateChange(cx, script->function()->type(), false, true);
2178
        ObjectStateChange(cx, script->function()->type(), false, true);
2179
}
2179
}
2180
2180
2181
/*
2181
/*
2182
 * As for TypeConstraintFreeze, but describes an implicit freeze constraint
2182
 * As for TypeConstraintFreeze, but describes an implicit freeze constraint
2183
 * added for stack types within a script. Applies to all compilations of the
2183
 * added for stack types within a script. Applies to all compilations of the
2184
 * script, not just a single one.
2184
 * script, not just a single one.
2185
 */
2185
 */
 Lines 2462-2478   bool Link Here 
2462
types::UseNewTypeForInitializer(JSContext *cx, HandleScript script, jsbytecode *pc, JSProtoKey key)
2462
types::UseNewTypeForInitializer(JSContext *cx, HandleScript script, jsbytecode *pc, JSProtoKey key)
2463
{
2463
{
2464
    /*
2464
    /*
2465
     * Objects created outside loops in global and eval scripts should have
2465
     * Objects created outside loops in global and eval scripts should have
2466
     * singleton types. For now this is only done for plain objects and typed
2466
     * singleton types. For now this is only done for plain objects and typed
2467
     * arrays, but not normal arrays.
2467
     * arrays, but not normal arrays.
2468
     */
2468
     */
2469
2469
2470
    if (!cx->typeInferenceEnabled() || script->function())
2470
    if (!cx->typeInferenceEnabled() || script->isFunctionScript())
2471
        return false;
2471
        return false;
2472
2472
2473
    if (key != JSProto_Object && !(key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray))
2473
    if (key != JSProto_Object && !(key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray))
2474
        return false;
2474
        return false;
2475
2475
2476
    AutoEnterTypeInference enter(cx);
2476
    AutoEnterTypeInference enter(cx);
2477
2477
2478
    if (!JSScript::ensureRanAnalysis(cx, script))
2478
    if (!JSScript::ensureRanAnalysis(cx, script))
 Lines 3911-3927   ScriptAnalysis::analyzeTypesBytecode(JSC Link Here 
3911
        break;
3911
        break;
3912
3912
3913
      case JSOP_OBJECT:
3913
      case JSOP_OBJECT:
3914
        pushed[0].addType(cx, Type::ObjectType(script_->getObject(GET_UINT32_INDEX(pc))));
3914
        pushed[0].addType(cx, Type::ObjectType(script_->getObject(GET_UINT32_INDEX(pc))));
3915
        break;
3915
        break;
3916
3916
3917
      case JSOP_STOP:
3917
      case JSOP_STOP:
3918
        /* If a stop is reachable then the return type may be void. */
3918
        /* If a stop is reachable then the return type may be void. */
3919
          if (script_->function())
3919
          if (script_->isFunctionScript())
3920
            TypeScript::ReturnTypes(script_)->addType(cx, Type::UndefinedType());
3920
            TypeScript::ReturnTypes(script_)->addType(cx, Type::UndefinedType());
3921
        break;
3921
        break;
3922
3922
3923
      case JSOP_OR:
3923
      case JSOP_OR:
3924
      case JSOP_AND:
3924
      case JSOP_AND:
3925
        /* OR/AND push whichever operand determined the result. */
3925
        /* OR/AND push whichever operand determined the result. */
3926
        poppedTypes(pc, 0)->addSubset(cx, &pushed[0]);
3926
        poppedTypes(pc, 0)->addSubset(cx, &pushed[0]);
3927
        break;
3927
        break;
 Lines 5621-5637   JSScript::makeTypes(JSContext *cx) Link Here 
5621
                  i, id());
5621
                  i, id());
5622
    InferSpew(ISpewOps, "typeSet: %sT%p%s return #%u",
5622
    InferSpew(ISpewOps, "typeSet: %sT%p%s return #%u",
5623
              InferSpewColor(returnTypes), returnTypes, InferSpewColorReset(),
5623
              InferSpewColor(returnTypes), returnTypes, InferSpewColorReset(),
5624
              id());
5624
              id());
5625
    TypeSet *thisTypes = TypeScript::ThisTypes(this);
5625
    TypeSet *thisTypes = TypeScript::ThisTypes(this);
5626
    InferSpew(ISpewOps, "typeSet: %sT%p%s this #%u",
5626
    InferSpew(ISpewOps, "typeSet: %sT%p%s this #%u",
5627
              InferSpewColor(thisTypes), thisTypes, InferSpewColorReset(),
5627
              InferSpewColor(thisTypes), thisTypes, InferSpewColorReset(),
5628
              id());
5628
              id());
5629
    unsigned nargs = function() ? function()->nargs : 0;
5629
    unsigned nargs = isFunctionScript() ? function()->nargs : 0;
5630
    for (unsigned i = 0; i < nargs; i++) {
5630
    for (unsigned i = 0; i < nargs; i++) {
5631
        TypeSet *types = TypeScript::ArgTypes(this, i);
5631
        TypeSet *types = TypeScript::ArgTypes(this, i);
5632
        InferSpew(ISpewOps, "typeSet: %sT%p%s arg%u #%u",
5632
        InferSpew(ISpewOps, "typeSet: %sT%p%s arg%u #%u",
5633
                  InferSpewColor(types), types, InferSpewColorReset(),
5633
                  InferSpewColor(types), types, InferSpewColorReset(),
5634
                  i, id());
5634
                  i, id());
5635
    }
5635
    }
5636
    for (unsigned i = 0; i < nfixed; i++) {
5636
    for (unsigned i = 0; i < nfixed; i++) {
5637
        TypeSet *types = TypeScript::LocalTypes(this, i);
5637
        TypeSet *types = TypeScript::LocalTypes(this, i);
(-)a/js/src/jsopcode.tbl (+4 lines)
Line     Link Here 
 Lines 539-546   OPDEF(JSOP_TOID, 225, "toid", Link Here 
539
/* Push the implicit 'this' value for calls to the associated name. */
539
/* Push the implicit 'this' value for calls to the associated name. */
540
OPDEF(JSOP_IMPLICITTHIS,  226, "implicitthis", "",    5,  0,  1,  0,  JOF_ATOM)
540
OPDEF(JSOP_IMPLICITTHIS,  226, "implicitthis", "",    5,  0,  1,  0,  JOF_ATOM)
541
541
542
/* This opcode is the target of the entry jump for some loop. */
542
/* This opcode is the target of the entry jump for some loop. */
543
OPDEF(JSOP_LOOPENTRY,     227, "loopentry",    NULL,  1,  0,  0,  0,  JOF_BYTE)
543
OPDEF(JSOP_LOOPENTRY,     227, "loopentry",    NULL,  1,  0,  0,  0,  JOF_BYTE)
544
544
545
/* Notes the point at which a value is pushed as an argument. */
545
/* Notes the point at which a value is pushed as an argument. */
546
OPDEF(JSOP_NOTEARG,       228, "notearg",      NULL,  1,  0,  0,  0,  JOF_BYTE)
546
OPDEF(JSOP_NOTEARG,       228, "notearg",      NULL,  1,  0,  0,  0,  JOF_BYTE)
547
548
OPDEF(JSOP_DEFMODULE,     229, "defmodule",    NULL,  5,  0,  0,  0,  JOF_OBJECT)
549
OPDEF(JSOP_MODULE,        230, "module",       NULL,  5,  0,  1,  0,  JOF_OBJECT)
550
OPDEF(JSOP_INITMODULE,    231, "initmodule",   NULL,  5,  0,  0,  0,  JOF_OBJECT)
(-)a/js/src/jsscript.cpp (-11 / +11 lines)
Line     Link Here 
 Lines 23-38    Link Here 
23
#include "jsgc.h"
23
#include "jsgc.h"
24
#include "jsinterp.h"
24
#include "jsinterp.h"
25
#include "jslock.h"
25
#include "jslock.h"
26
#include "jsnum.h"
26
#include "jsnum.h"
27
#include "jsopcode.h"
27
#include "jsopcode.h"
28
#include "jsscope.h"
28
#include "jsscope.h"
29
#include "jsscript.h"
29
#include "jsscript.h"
30
30
31
#include "builtin/Module.h"
31
#include "gc/Marking.h"
32
#include "gc/Marking.h"
32
#include "frontend/BytecodeEmitter.h"
33
#include "frontend/BytecodeEmitter.h"
33
#include "frontend/Parser.h"
34
#include "frontend/Parser.h"
34
#include "js/MemoryMetrics.h"
35
#include "js/MemoryMetrics.h"
35
#include "methodjit/MethodJIT.h"
36
#include "methodjit/MethodJIT.h"
36
#include "ion/IonCode.h"
37
#include "ion/IonCode.h"
37
#include "methodjit/Retcon.h"
38
#include "methodjit/Retcon.h"
38
#include "vm/Debugger.h"
39
#include "vm/Debugger.h"
 Lines 1760-1816   JSScript::fullyInitFromEmitter(JSContext Link Here 
1760
    }
1761
    }
1761
    script->lineno = bce->firstLine;
1762
    script->lineno = bce->firstLine;
1762
    if (script->nfixed + bce->maxStackDepth >= JS_BIT(16)) {
1763
    if (script->nfixed + bce->maxStackDepth >= JS_BIT(16)) {
1763
        bce->reportError(NULL, JSMSG_NEED_DIET, "script");
1764
        bce->reportError(NULL, JSMSG_NEED_DIET, "script");
1764
        return false;
1765
        return false;
1765
    }
1766
    }
1766
    script->nslots = script->nfixed + bce->maxStackDepth;
1767
    script->nslots = script->nfixed + bce->maxStackDepth;
1767
1768
1768
    FunctionBox *funbox = bce->sc->isFunctionBox() ? bce->sc->asFunctionBox() : NULL;
1769
1770
    if (!FinishTakingSrcNotes(cx, bce, script->notes()))
1769
    if (!FinishTakingSrcNotes(cx, bce, script->notes()))
1771
        return false;
1770
        return false;
1772
    if (bce->tryNoteList.length() != 0)
1771
    if (bce->tryNoteList.length() != 0)
1773
        bce->tryNoteList.finish(script->trynotes());
1772
        bce->tryNoteList.finish(script->trynotes());
1774
    if (bce->objectList.length != 0)
1773
    if (bce->objectList.length != 0)
1775
        bce->objectList.finish(script->objects());
1774
        bce->objectList.finish(script->objects());
1776
    if (bce->regexpList.length != 0)
1775
    if (bce->regexpList.length != 0)
1777
        bce->regexpList.finish(script->regexps());
1776
        bce->regexpList.finish(script->regexps());
1778
    if (bce->constList.length() != 0)
1777
    if (bce->constList.length() != 0)
1779
        bce->constList.finish(script->consts());
1778
        bce->constList.finish(script->consts());
1780
    script->strict = bce->sc->strict;
1779
    script->strict = bce->sc->strict;
1781
    script->explicitUseStrict = bce->sc->hasExplicitUseStrict();
1780
    script->explicitUseStrict = bce->sc->hasExplicitUseStrict();
1782
    script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
1781
    script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
1783
    script->funHasExtensibleScope = funbox ? funbox->hasExtensibleScope() : false;
1784
    script->hasSingletons = bce->hasSingletons;
1782
    script->hasSingletons = bce->hasSingletons;
1785
#ifdef JS_METHODJIT
1783
#ifdef JS_METHODJIT
1786
    if (cx->compartment->debugMode())
1784
    if (cx->compartment->debugMode())
1787
        script->debugMode = true;
1785
        script->debugMode = true;
1788
#endif
1786
#endif
1789
1787
1790
    if (funbox) {
1788
    if (bce->sc->isModuleBox()) {
1789
        script->setOwner(bce->sc->asModuleBox()->module());
1790
    } else if (bce->sc->isFunctionBox()) {
1791
        FunctionBox *funbox = bce->sc->asFunctionBox();
1792
        script->funHasExtensibleScope = funbox->hasExtensibleScope();
1793
1791
        if (funbox->argumentsHasLocalBinding()) {
1794
        if (funbox->argumentsHasLocalBinding()) {
1792
            // This must precede the script->bindings.transfer() call below
1795
            // This must precede the script->bindings.transfer() call below
1793
            script->setArgumentsHasVarBinding();
1796
            script->setArgumentsHasVarBinding();
1794
            if (funbox->definitelyNeedsArgsObj())
1797
            if (funbox->definitelyNeedsArgsObj())
1795
                script->setNeedsArgsObj(true);
1798
                script->setNeedsArgsObj(true);
1796
        } else {
1799
        } else {
1797
            JS_ASSERT(!funbox->definitelyNeedsArgsObj());
1800
            JS_ASSERT(!funbox->definitelyNeedsArgsObj());
1798
        }
1801
        }
1799
1802
1800
        script->ndefaults = funbox->ndefaults;
1803
        script->ndefaults = funbox->ndefaults;
1801
    }
1802
1804
1803
    RootedFunction fun(cx, NULL);
1804
    if (funbox) {
1805
        JS_ASSERT(!bce->script->noScriptRval);
1805
        JS_ASSERT(!bce->script->noScriptRval);
1806
        script->isGenerator = funbox->isGenerator();
1806
        script->isGenerator = funbox->isGenerator();
1807
        script->isGeneratorExp = funbox->inGenexpLambda;
1807
        script->isGeneratorExp = funbox->inGenexpLambda;
1808
        script->setFunction(funbox->function());
1808
        script->setOwner(funbox->function());
1809
    }
1809
    }
1810
1810
1811
    /*
1811
    /*
1812
     * initScriptCounts updates scriptCountsMap if necessary. The other script
1812
     * initScriptCounts updates scriptCountsMap if necessary. The other script
1813
     * maps in JSCompartment are populated lazily.
1813
     * maps in JSCompartment are populated lazily.
1814
     */
1814
     */
1815
    if (cx->hasRunOption(JSOPTION_PCCOUNT))
1815
    if (cx->hasRunOption(JSOPTION_PCCOUNT))
1816
        (void) script->initScriptCounts(cx);
1816
        (void) script->initScriptCounts(cx);
 Lines 2358-2374   js::CloneFunctionScript(JSContext *cx, H Link Here 
2358
2358
2359
    clone->mutableScript().init(NULL);
2359
    clone->mutableScript().init(NULL);
2360
2360
2361
    RawScript cscript = CloneScript(cx, scope, clone, script);
2361
    RawScript cscript = CloneScript(cx, scope, clone, script);
2362
    if (!cscript)
2362
    if (!cscript)
2363
        return false;
2363
        return false;
2364
2364
2365
    clone->setScript(cscript);
2365
    clone->setScript(cscript);
2366
    cscript->setFunction(clone);
2366
    cscript->setOwner(clone);
2367
2367
2368
    GlobalObject *global = script->compileAndGo ? &script->global() : NULL;
2368
    GlobalObject *global = script->compileAndGo ? &script->global() : NULL;
2369
2369
2370
    script = clone->nonLazyScript();
2370
    script = clone->nonLazyScript();
2371
    CallNewScriptHook(cx, script, clone);
2371
    CallNewScriptHook(cx, script, clone);
2372
    Debugger::onNewScript(cx, script, global);
2372
    Debugger::onNewScript(cx, script, global);
2373
2373
2374
    return true;
2374
    return true;
 Lines 2613-2630   JSScript::markChildren(JSTracer *trc) Link Here 
2613
        MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
2613
        MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
2614
    }
2614
    }
2615
2615
2616
    if (hasConsts()) {
2616
    if (hasConsts()) {
2617
        ConstArray *constarray = consts();
2617
        ConstArray *constarray = consts();
2618
        MarkValueRange(trc, constarray->length, constarray->vector, "consts");
2618
        MarkValueRange(trc, constarray->length, constarray->vector, "consts");
2619
    }
2619
    }
2620
2620
2621
    if (function())
2621
    if (owner_)
2622
        MarkObject(trc, &function_, "function");
2622
        MarkObject(trc, &owner_, "owner");
2623
2623
2624
    if (enclosingScope_)
2624
    if (enclosingScope_)
2625
        MarkObject(trc, &enclosingScope_, "enclosing");
2625
        MarkObject(trc, &enclosingScope_, "enclosing");
2626
2626
2627
    if (IS_GC_MARKING_TRACER(trc) && filename)
2627
    if (IS_GC_MARKING_TRACER(trc) && filename)
2628
        MarkScriptFilename(trc->runtime, filename);
2628
        MarkScriptFilename(trc->runtime, filename);
2629
2629
2630
    bindings.trace(trc);
2630
    bindings.trace(trc);
(-)a/js/src/jsscript.h (-3 / +7 lines)
Line     Link Here 
 Lines 376-392   class JSScript : public js::gc::Cell Link Here 
376
376
377
  private:
377
  private:
378
    js::ScriptSource *scriptSource_; /* source code */
378
    js::ScriptSource *scriptSource_; /* source code */
379
#ifdef JS_METHODJIT
379
#ifdef JS_METHODJIT
380
    JITScriptSet *mJITInfo;
380
    JITScriptSet *mJITInfo;
381
#else
381
#else
382
    void         *mJITInfoPad;
382
    void         *mJITInfoPad;
383
#endif
383
#endif
384
    js::HeapPtrFunction function_;
384
    js::HeapPtrObject   owner_;
385
    js::HeapPtrObject   enclosingScope_;
385
    js::HeapPtrObject   enclosingScope_;
386
386
387
    // 32-bit fields.
387
    // 32-bit fields.
388
388
389
  public:
389
  public:
390
    uint32_t        length;     /* length of code vector */
390
    uint32_t        length;     /* length of code vector */
391
391
392
    uint32_t        lineno;     /* base line number of script */
392
    uint32_t        lineno;     /* base line number of script */
 Lines 605-622   class JSScript : public js::gc::Cell Link Here 
605
        JS_ASSERT(hasParallelIonScript());
605
        JS_ASSERT(hasParallelIonScript());
606
        return parallelIon;
606
        return parallelIon;
607
    }
607
    }
608
608
609
    /*
609
    /*
610
     * Original compiled function for the script, if it has a function.
610
     * Original compiled function for the script, if it has a function.
611
     * NULL for global and eval scripts.
611
     * NULL for global and eval scripts.
612
     */
612
     */
613
    JSFunction *function() const { return function_; }
613
    bool isGlobalScript() const { return !owner_; }
614
    void setFunction(JSFunction *fun);
614
    bool isModuleScript() const { return owner_ && owner_->isModule(); }
615
    bool isFunctionScript() const { return owner_ && owner_->isFunction(); }
616
    js::Module *module() const { JS_ASSERT(owner_->isModule()); return &owner_->asModule(); }
617
    JSFunction *function() const { JS_ASSERT(owner_->isFunction()); return owner_->toFunction(); }
618
    void setOwner(JSObject *owner) { owner_ = owner; }
615
619
616
    JSFlatString *sourceData(JSContext *cx);
620
    JSFlatString *sourceData(JSContext *cx);
617
621
618
    static bool loadSource(JSContext *cx, js::HandleScript scr, bool *worked);
622
    static bool loadSource(JSContext *cx, js::HandleScript scr, bool *worked);
619
623
620
    js::ScriptSource *scriptSource() {
624
    js::ScriptSource *scriptSource() {
621
        return scriptSource_;
625
        return scriptSource_;
622
    }
626
    }
(-)a/js/src/jsscriptinlines.h (-6 lines)
Line     Link Here 
 Lines 74-95   MarkScriptFilename(JSRuntime *rt, const Link Here 
74
     * to preserve this invariant, only mark during a full gc.
74
     * to preserve this invariant, only mark during a full gc.
75
     */
75
     */
76
    if (rt->gcIsFull)
76
    if (rt->gcIsFull)
77
        ScriptFilenameEntry::fromFilename(filename)->marked = true;
77
        ScriptFilenameEntry::fromFilename(filename)->marked = true;
78
}
78
}
79
79
80
} // namespace js
80
} // namespace js
81
81
82
inline void
83
JSScript::setFunction(JSFunction *fun)
84
{
85
    function_ = fun;
86
}
87
88
inline JSFunction *
82
inline JSFunction *
89
JSScript::getFunction(size_t index)
83
JSScript::getFunction(size_t index)
90
{
84
{
91
    JSObject *funobj = getObject(index);
85
    JSObject *funobj = getObject(index);
92
    JS_ASSERT(funobj->isFunction() && funobj->toFunction()->isInterpreted());
86
    JS_ASSERT(funobj->isFunction() && funobj->toFunction()->isInterpreted());
93
    return funobj->toFunction();
87
    return funobj->toFunction();
94
}
88
}
95
89
(-)a/js/src/methodjit/Compiler.cpp (-9 / +9 lines)
Line     Link Here 
 Lines 145-161   mjit::Compiler::compile() Link Here 
145
    CompileStatus status = performCompilation();
145
    CompileStatus status = performCompilation();
146
    if (status != Compile_Okay && status != Compile_Retry) {
146
    if (status != Compile_Okay && status != Compile_Retry) {
147
        if (!outerScript->ensureHasMJITInfo(cx))
147
        if (!outerScript->ensureHasMJITInfo(cx))
148
            return Compile_Error;
148
            return Compile_Error;
149
        JSScript::JITScriptHandle *jith = outerScript->jitHandle(isConstructing, cx->compartment->compileBarriers());
149
        JSScript::JITScriptHandle *jith = outerScript->jitHandle(isConstructing, cx->compartment->compileBarriers());
150
        JSScript::ReleaseCode(cx->runtime->defaultFreeOp(), jith);
150
        JSScript::ReleaseCode(cx->runtime->defaultFreeOp(), jith);
151
        jith->setUnjittable();
151
        jith->setUnjittable();
152
152
153
        if (outerScript->function()) {
153
        if (outerScript->isFunctionScript()) {
154
            outerScript->uninlineable = true;
154
            outerScript->uninlineable = true;
155
            types::MarkTypeObjectFlags(cx, outerScript->function(),
155
            types::MarkTypeObjectFlags(cx, outerScript->function(),
156
                                       types::OBJECT_FLAG_UNINLINEABLE);
156
                                       types::OBJECT_FLAG_UNINLINEABLE);
157
        }
157
        }
158
    }
158
    }
159
159
160
    return status;
160
    return status;
161
}
161
}
 Lines 1110-1126   CompileStatus Link Here 
1110
mjit::Compiler::generatePrologue()
1110
mjit::Compiler::generatePrologue()
1111
{
1111
{
1112
    fastEntryLabel = masm.label();
1112
    fastEntryLabel = masm.label();
1113
1113
1114
    /*
1114
    /*
1115
     * If there is no function, then this can only be called via JaegerShot(),
1115
     * If there is no function, then this can only be called via JaegerShot(),
1116
     * which expects an existing frame to be initialized like the interpreter.
1116
     * which expects an existing frame to be initialized like the interpreter.
1117
     */
1117
     */
1118
    if (script_->function()) {
1118
    if (script_->isFunctionScript()) {
1119
        Jump j = masm.jump();
1119
        Jump j = masm.jump();
1120
1120
1121
        /*
1121
        /*
1122
         * Entry point #2: The caller has partially constructed a frame, and
1122
         * Entry point #2: The caller has partially constructed a frame, and
1123
         * either argc >= nargs or the arity check has corrected the frame.
1123
         * either argc >= nargs or the arity check has corrected the frame.
1124
         */
1124
         */
1125
        fastEntryLabel = masm.label();
1125
        fastEntryLabel = masm.label();
1126
1126
 Lines 1226-1254   mjit::Compiler::generatePrologue() Link Here 
1226
            hasArgs.linkTo(masm.label(), &masm);
1226
            hasArgs.linkTo(masm.label(), &masm);
1227
        }
1227
        }
1228
1228
1229
        j.linkTo(masm.label(), &masm);
1229
        j.linkTo(masm.label(), &masm);
1230
    }
1230
    }
1231
1231
1232
    if (cx->typeInferenceEnabled()) {
1232
    if (cx->typeInferenceEnabled()) {
1233
#ifdef DEBUG
1233
#ifdef DEBUG
1234
        if (script_->function()) {
1234
        if (script_->isFunctionScript()) {
1235
            prepareStubCall(Uses(0));
1235
            prepareStubCall(Uses(0));
1236
            INLINE_STUBCALL(stubs::AssertArgumentTypes, REJOIN_NONE);
1236
            INLINE_STUBCALL(stubs::AssertArgumentTypes, REJOIN_NONE);
1237
        }
1237
        }
1238
#endif
1238
#endif
1239
        ensureDoubleArguments();
1239
        ensureDoubleArguments();
1240
    }
1240
    }
1241
1241
1242
    /* Inline StackFrame::prologue. */
1242
    /* Inline StackFrame::prologue. */
1243
    if (script_->isActiveEval && script_->strict) {
1243
    if (script_->isActiveEval && script_->strict) {
1244
        prepareStubCall(Uses(0));
1244
        prepareStubCall(Uses(0));
1245
        INLINE_STUBCALL(stubs::StrictEvalPrologue, REJOIN_EVAL_PROLOGUE);
1245
        INLINE_STUBCALL(stubs::StrictEvalPrologue, REJOIN_EVAL_PROLOGUE);
1246
    } else if (script_->function()) {
1246
    } else if (script_->isFunctionScript()) {
1247
        if (script_->function()->isHeavyweight()) {
1247
        if (script_->function()->isHeavyweight()) {
1248
            prepareStubCall(Uses(0));
1248
            prepareStubCall(Uses(0));
1249
            INLINE_STUBCALL(stubs::HeavyweightFunctionPrologue, REJOIN_FUNCTION_PROLOGUE);
1249
            INLINE_STUBCALL(stubs::HeavyweightFunctionPrologue, REJOIN_FUNCTION_PROLOGUE);
1250
        }
1250
        }
1251
1251
1252
        if (isConstructing && !constructThis())
1252
        if (isConstructing && !constructThis())
1253
            return Compile_Error;
1253
            return Compile_Error;
1254
    }
1254
    }
 Lines 1263-1279   mjit::Compiler::generatePrologue() Link Here 
1263
1263
1264
    return status;
1264
    return status;
1265
}
1265
}
1266
1266
1267
void
1267
void
1268
mjit::Compiler::ensureDoubleArguments()
1268
mjit::Compiler::ensureDoubleArguments()
1269
{
1269
{
1270
    /* Convert integer arguments which were inferred as (int|double) to doubles. */
1270
    /* Convert integer arguments which were inferred as (int|double) to doubles. */
1271
    for (uint32_t i = 0; script_->function() && i < script_->function()->nargs; i++) {
1271
    for (uint32_t i = 0; script_->isFunctionScript() && i < script_->function()->nargs; i++) {
1272
        uint32_t slot = ArgSlot(i);
1272
        uint32_t slot = ArgSlot(i);
1273
        if (a->varTypes[slot].getTypeTag() == JSVAL_TYPE_DOUBLE && analysis->trackSlot(slot))
1273
        if (a->varTypes[slot].getTypeTag() == JSVAL_TYPE_DOUBLE && analysis->trackSlot(slot))
1274
            frame.ensureDouble(frame.getArg(i));
1274
            frame.ensureDouble(frame.getArg(i));
1275
    }
1275
    }
1276
}
1276
}
1277
1277
1278
void
1278
void
1279
mjit::Compiler::markUndefinedLocal(uint32_t offset, uint32_t i)
1279
mjit::Compiler::markUndefinedLocal(uint32_t offset, uint32_t i)
 Lines 1435-1451   mjit::Compiler::finishThisUp() Link Here 
1435
1435
1436
    JS_ASSERT(outerScript == script_);
1436
    JS_ASSERT(outerScript == script_);
1437
1437
1438
    chunk->code = JSC::MacroAssemblerCodeRef(result, execPool, masm.size() + stubcc.size());
1438
    chunk->code = JSC::MacroAssemblerCodeRef(result, execPool, masm.size() + stubcc.size());
1439
    chunk->pcLengths = pcLengths;
1439
    chunk->pcLengths = pcLengths;
1440
1440
1441
    if (chunkIndex == 0) {
1441
    if (chunkIndex == 0) {
1442
        jit->invokeEntry = result;
1442
        jit->invokeEntry = result;
1443
        if (script_->function()) {
1443
        if (script_->isFunctionScript()) {
1444
            jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress();
1444
            jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress();
1445
            jit->argsCheckEntry = stubCode.locationOf(argsCheckLabel).executableAddress();
1445
            jit->argsCheckEntry = stubCode.locationOf(argsCheckLabel).executableAddress();
1446
            jit->fastEntry = fullCode.locationOf(fastEntryLabel).executableAddress();
1446
            jit->fastEntry = fullCode.locationOf(fastEntryLabel).executableAddress();
1447
        }
1447
        }
1448
    }
1448
    }
1449
1449
1450
    /*
1450
    /*
1451
     * WARNING: mics(), callICs() et al depend on the ordering of these
1451
     * WARNING: mics(), callICs() et al depend on the ordering of these
 Lines 1572-1588   mjit::Compiler::finishThisUp() Link Here 
1572
1572
1573
    uint32_t *jitTypeBarrierBytecodes = (uint32_t *)cursor;
1573
    uint32_t *jitTypeBarrierBytecodes = (uint32_t *)cursor;
1574
    chunk->nTypeBarrierBytecodes = typeBarrierBytecodes.length();
1574
    chunk->nTypeBarrierBytecodes = typeBarrierBytecodes.length();
1575
    cursor += sizeof(uint32_t) * chunk->nTypeBarrierBytecodes;
1575
    cursor += sizeof(uint32_t) * chunk->nTypeBarrierBytecodes;
1576
    for (size_t i = 0; i < chunk->nTypeBarrierBytecodes; i++)
1576
    for (size_t i = 0; i < chunk->nTypeBarrierBytecodes; i++)
1577
        jitTypeBarrierBytecodes[i] = typeBarrierBytecodes[i];
1577
        jitTypeBarrierBytecodes[i] = typeBarrierBytecodes[i];
1578
1578
1579
#if defined JS_MONOIC
1579
#if defined JS_MONOIC
1580
    if (chunkIndex == 0 && script_->function()) {
1580
    if (chunkIndex == 0 && script_->isFunctionScript()) {
1581
        JS_ASSERT(jit->argsCheckPool == NULL);
1581
        JS_ASSERT(jit->argsCheckPool == NULL);
1582
        if (cx->typeInferenceEnabled()) {
1582
        if (cx->typeInferenceEnabled()) {
1583
            jit->argsCheckStub = stubCode.locationOf(argsCheckStub);
1583
            jit->argsCheckStub = stubCode.locationOf(argsCheckStub);
1584
            jit->argsCheckFallthrough = stubCode.locationOf(argsCheckFallthrough);
1584
            jit->argsCheckFallthrough = stubCode.locationOf(argsCheckFallthrough);
1585
            jit->argsCheckJump = stubCode.locationOf(argsCheckJump);
1585
            jit->argsCheckJump = stubCode.locationOf(argsCheckJump);
1586
        }
1586
        }
1587
    }
1587
    }
1588
1588
 Lines 3797-3813   mjit::Compiler::emitInlineReturnValue(Fr Link Here 
3797
    a->returnSet = true;
3797
    a->returnSet = true;
3798
    if (a->exitState)
3798
    if (a->exitState)
3799
        a->exitState->setUnassigned(a->returnRegister);
3799
        a->exitState->setUnassigned(a->returnRegister);
3800
}
3800
}
3801
3801
3802
void
3802
void
3803
mjit::Compiler::emitReturn(FrameEntry *fe)
3803
mjit::Compiler::emitReturn(FrameEntry *fe)
3804
{
3804
{
3805
    JS_ASSERT_IF(!script_->function(), JSOp(*PC) == JSOP_STOP);
3805
    JS_ASSERT_IF(!script_->isFunctionScript(), JSOp(*PC) == JSOP_STOP);
3806
3806
3807
    /* Only the top of the stack can be returned. */
3807
    /* Only the top of the stack can be returned. */
3808
    JS_ASSERT_IF(fe, fe == frame.peek(-1));
3808
    JS_ASSERT_IF(fe, fe == frame.peek(-1));
3809
3809
3810
    if (debugMode()) {
3810
    if (debugMode()) {
3811
        /* If the return value isn't in the frame's rval slot, move it there. */
3811
        /* If the return value isn't in the frame's rval slot, move it there. */
3812
        if (fe) {
3812
        if (fe) {
3813
            frame.storeTo(fe, Address(JSFrameReg, StackFrame::offsetOfReturnValue()), true);
3813
            frame.storeTo(fe, Address(JSFrameReg, StackFrame::offsetOfReturnValue()), true);
 Lines 6107-6123   mjit::Compiler::jsop_this() Link Here 
6107
{
6107
{
6108
    frame.pushThis();
6108
    frame.pushThis();
6109
6109
6110
    /*
6110
    /*
6111
     * In strict mode and self-hosted code, we don't wrap 'this'.
6111
     * In strict mode and self-hosted code, we don't wrap 'this'.
6112
     * In direct-call eval code, we wrapped 'this' before entering the eval.
6112
     * In direct-call eval code, we wrapped 'this' before entering the eval.
6113
     * In global code, 'this' is always an object.
6113
     * In global code, 'this' is always an object.
6114
     */
6114
     */
6115
    if (script_->function() && !script_->strict &&
6115
    if (script_->isFunctionScript() && !script_->strict &&
6116
        !script_->function()->isSelfHostedBuiltin())
6116
        !script_->function()->isSelfHostedBuiltin())
6117
    {
6117
    {
6118
        FrameEntry *thisFe = frame.peek(-1);
6118
        FrameEntry *thisFe = frame.peek(-1);
6119
6119
6120
        if (!thisFe->isType(JSVAL_TYPE_OBJECT)) {
6120
        if (!thisFe->isType(JSVAL_TYPE_OBJECT)) {
6121
            /*
6121
            /*
6122
             * Watch out for an obscure case where we don't know we are pushing
6122
             * Watch out for an obscure case where we don't know we are pushing
6123
             * an object: the script has not yet had a 'this' value assigned,
6123
             * an object: the script has not yet had a 'this' value assigned,
(-)a/js/src/methodjit/FrameState-inl.h (-1 / +2 lines)
Line     Link Here 
 Lines 1020-1036   FrameState::frameOffset(const FrameEntry Link Here 
1020
    /* Note: fe == a->sp is allowed for addressOfTop */
1020
    /* Note: fe == a->sp is allowed for addressOfTop */
1021
    JS_ASSERT(fe >= a->callee_ && fe <= a->sp);
1021
    JS_ASSERT(fe >= a->callee_ && fe <= a->sp);
1022
1022
1023
    if (fe >= a->locals)
1023
    if (fe >= a->locals)
1024
        return StackFrame::offsetOfFixed(uint32_t(fe - a->locals));
1024
        return StackFrame::offsetOfFixed(uint32_t(fe - a->locals));
1025
    if (fe >= a->args)
1025
    if (fe >= a->args)
1026
        return StackFrame::offsetOfFormalArg(a->script->function(), uint32_t(fe - a->args));
1026
        return StackFrame::offsetOfFormalArg(a->script->function(), uint32_t(fe - a->args));
1027
    if (fe == a->this_)
1027
    if (fe == a->this_)
1028
        return StackFrame::offsetOfThis(a->script->function());
1028
        return StackFrame::offsetOfThis(a->script->isFunctionScript()
1029
                                        ? a->script->function() : NULL);
1029
    if (fe == a->callee_)
1030
    if (fe == a->callee_)
1030
        return StackFrame::offsetOfCallee(a->script->function());
1031
        return StackFrame::offsetOfCallee(a->script->function());
1031
    JS_NOT_REACHED("Bad fe");
1032
    JS_NOT_REACHED("Bad fe");
1032
    return 0;
1033
    return 0;
1033
}
1034
}
1034
1035
1035
inline JSC::MacroAssembler::Address
1036
inline JSC::MacroAssembler::Address
1036
FrameState::addressOf(const FrameEntry *fe) const
1037
FrameState::addressOf(const FrameEntry *fe) const
(-)a/js/src/methodjit/InvokeHelpers.cpp (-1 / +3 lines)
Line     Link Here 
 Lines 692-708   stubs::CreateThis(VMFrame &f, JSObject * Link Here 
692
        THROW();
692
        THROW();
693
    fp->thisValue() = ObjectValue(*obj);
693
    fp->thisValue() = ObjectValue(*obj);
694
}
694
}
695
695
696
void JS_FASTCALL
696
void JS_FASTCALL
697
stubs::ScriptDebugPrologue(VMFrame &f)
697
stubs::ScriptDebugPrologue(VMFrame &f)
698
{
698
{
699
    AssertCanGC();
699
    AssertCanGC();
700
    Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
700
    Probes::enterScript(f.cx, f.script(),
701
                        f.script()->isFunctionScript() ? f.script()->function() : NULL,
702
                        f.fp());
701
    JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
703
    JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
702
    switch (status) {
704
    switch (status) {
703
      case JSTRAP_CONTINUE:
705
      case JSTRAP_CONTINUE:
704
        break;
706
        break;
705
      case JSTRAP_RETURN:
707
      case JSTRAP_RETURN:
706
        *f.returnAddressLocation() = f.cx->jaegerRuntime().forceReturnFromFastCall();
708
        *f.returnAddressLocation() = f.cx->jaegerRuntime().forceReturnFromFastCall();
707
        return;
709
        return;
708
      case JSTRAP_ERROR:
710
      case JSTRAP_ERROR:
(-)a/js/src/methodjit/LoopState.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 99-115   LoopState::init(jsbytecode *head, Jump e Link Here 
99
99
100
    this->alloc = alloc;
100
    this->alloc = alloc;
101
    this->loopRegs = Registers::AvailAnyRegs;
101
    this->loopRegs = Registers::AvailAnyRegs;
102
102
103
    /*
103
    /*
104
     * Don't hoist bounds checks or loop invariant code in scripts that have
104
     * Don't hoist bounds checks or loop invariant code in scripts that have
105
     * had indirect modification of their arguments.
105
     * had indirect modification of their arguments.
106
     */
106
     */
107
    if (outerScript->function()) {
107
    if (outerScript->isFunctionScript()) {
108
        if (HeapTypeSet::HasObjectFlags(cx, outerScript->function()->getType(cx), OBJECT_FLAG_UNINLINEABLE))
108
        if (HeapTypeSet::HasObjectFlags(cx, outerScript->function()->getType(cx), OBJECT_FLAG_UNINLINEABLE))
109
            this->skipAnalysis = true;
109
            this->skipAnalysis = true;
110
    }
110
    }
111
111
112
    /*
112
    /*
113
     * Don't hoist bounds checks or loop invariant code in loops with safe
113
     * Don't hoist bounds checks or loop invariant code in loops with safe
114
     * points in the middle, which the interpreter can join at directly without
114
     * points in the middle, which the interpreter can join at directly without
115
     * performing hoisted bounds checks or doing initial computation of loop
115
     * performing hoisted bounds checks or doing initial computation of loop
(-)a/js/src/methodjit/MonoIC.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 1082-1098   class CallCompiler : public BaseCompiler Link Here 
1082
        types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
1082
        types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
1083
1083
1084
        /*
1084
        /*
1085
         * Native stubs are not generated for inline frames. The overhead of
1085
         * Native stubs are not generated for inline frames. The overhead of
1086
         * bailing out from the IC is far greater than the time saved by
1086
         * bailing out from the IC is far greater than the time saved by
1087
         * inlining the parent frame in the first place, so mark the immediate
1087
         * inlining the parent frame in the first place, so mark the immediate
1088
         * caller as uninlineable.
1088
         * caller as uninlineable.
1089
         */
1089
         */
1090
        if (fscript->function()) {
1090
        if (fscript->isFunctionScript()) {
1091
            fscript->uninlineable = true;
1091
            fscript->uninlineable = true;
1092
            MarkTypeObjectFlags(cx, fscript->function(), types::OBJECT_FLAG_UNINLINEABLE);
1092
            MarkTypeObjectFlags(cx, fscript->function(), types::OBJECT_FLAG_UNINLINEABLE);
1093
        }
1093
        }
1094
1094
1095
        /* Don't touch the IC if the call triggered a recompilation. */
1095
        /* Don't touch the IC if the call triggered a recompilation. */
1096
        if (monitor.recompiled())
1096
        if (monitor.recompiled())
1097
            return true;
1097
            return true;
1098
1098
(-)a/js/src/vm/GlobalObject.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 248-264   GlobalObject::initFunctionAndObjectClass Link Here 
248
                                                 ss,
248
                                                 ss,
249
                                                 0,
249
                                                 0,
250
                                                 ss->length()));
250
                                                 ss->length()));
251
        if (!script || !JSScript::fullyInitTrivial(cx, script))
251
        if (!script || !JSScript::fullyInitTrivial(cx, script))
252
            return NULL;
252
            return NULL;
253
253
254
        functionProto->initScript(script);
254
        functionProto->initScript(script);
255
        functionProto->getType(cx)->interpretedFunction = functionProto;
255
        functionProto->getType(cx)->interpretedFunction = functionProto;
256
        script->setFunction(functionProto);
256
        script->setOwner(functionProto);
257
257
258
        if (!JSObject::setSingletonType(cx, functionProto))
258
        if (!JSObject::setSingletonType(cx, functionProto))
259
            return NULL;
259
            return NULL;
260
260
261
        /*
261
        /*
262
         * The default 'new' type of Function.prototype is required by type
262
         * The default 'new' type of Function.prototype is required by type
263
         * inference to have unknown properties, to simplify handling of e.g.
263
         * inference to have unknown properties, to simplify handling of e.g.
264
         * CloneFunctionObject.
264
         * CloneFunctionObject.
(-)a/js/src/vm/SelfHosting.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 367-383   JSRuntime::cloneSelfHostedFunctionScript Link Here 
367
367
368
    RootedFunction sourceFun(cx, funVal.toObject().toFunction());
368
    RootedFunction sourceFun(cx, funVal.toObject().toFunction());
369
    Rooted<JSScript*> sourceScript(cx, sourceFun->nonLazyScript());
369
    Rooted<JSScript*> sourceScript(cx, sourceFun->nonLazyScript());
370
    JS_ASSERT(!sourceScript->enclosingStaticScope());
370
    JS_ASSERT(!sourceScript->enclosingStaticScope());
371
    RawScript cscript = CloneScript(cx, NullPtr(), targetFun, sourceScript);
371
    RawScript cscript = CloneScript(cx, NullPtr(), targetFun, sourceScript);
372
    if (!cscript)
372
    if (!cscript)
373
        return false;
373
        return false;
374
    targetFun->setScript(cscript);
374
    targetFun->setScript(cscript);
375
    cscript->setFunction(targetFun);
375
    cscript->setOwner(targetFun);
376
    JS_ASSERT(sourceFun->nargs == targetFun->nargs);
376
    JS_ASSERT(sourceFun->nargs == targetFun->nargs);
377
    targetFun->flags = sourceFun->flags | JSFunction::EXTENDED;
377
    targetFun->flags = sourceFun->flags | JSFunction::EXTENDED;
378
    return true;
378
    return true;
379
}
379
}
380
380
381
bool
381
bool
382
JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle<PropertyName*> name, MutableHandleValue vp)
382
JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle<PropertyName*> name, MutableHandleValue vp)
383
{
383
{
(-)a/js/src/vm/Stack.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 325-341   StackFrame::prologue(JSContext *cx, bool Link Here 
325
325
326
void
326
void
327
StackFrame::epilogue(JSContext *cx)
327
StackFrame::epilogue(JSContext *cx)
328
{
328
{
329
    JS_ASSERT(!isYielding());
329
    JS_ASSERT(!isYielding());
330
    JS_ASSERT(!hasBlockChain());
330
    JS_ASSERT(!hasBlockChain());
331
331
332
    RootedScript script(cx, this->script());
332
    RootedScript script(cx, this->script());
333
    Probes::exitScript(cx, script, script->function(), this);
333
    Probes::exitScript(cx, script, script->isFunctionScript() ? script->function() : NULL, this);
334
334
335
    if (isEvalFrame()) {
335
    if (isEvalFrame()) {
336
        if (isStrictEvalFrame()) {
336
        if (isStrictEvalFrame()) {
337
            JS_ASSERT_IF(hasCallObj(), scopeChain()->asCall().isForEval());
337
            JS_ASSERT_IF(hasCallObj(), scopeChain()->asCall().isForEval());
338
            if (cx->compartment->debugMode())
338
            if (cx->compartment->debugMode())
339
                DebugScopes::onPopStrictEvalScope(this);
339
                DebugScopes::onPopStrictEvalScope(this);
340
        } else if (isDirectEvalFrame()) {
340
        } else if (isDirectEvalFrame()) {
341
            if (isDebuggerFrame())
341
            if (isDebuggerFrame())

Return to bug 568953