Changeset 38330 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Nov 12, 2008, 1:34:22 AM (17 years ago)
Author:
[email protected]
Message:

2008-11-12 Cameron Zwarich <[email protected]>

Rubber-stamped by Mark Rowe.

Roll out r38322 due to test failures on the bots.

JavaScriptCore:

  • VM/CTI.cpp: (JSC::CTI::compileOpCallSetupArgs): (JSC::CTI::compileOpCall): (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases):
  • VM/CTI.h:
  • VM/CodeBlock.cpp: (JSC::CodeBlock::dump):
  • VM/Machine.cpp: (JSC::Machine::callEval): (JSC::Machine::dumpCallFrame): (JSC::Machine::dumpRegisters): (JSC::Machine::execute): (JSC::Machine::privateExecute): (JSC::Machine::throwStackOverflowPreviousFrame): (JSC::Machine::cti_register_file_check): (JSC::Machine::cti_op_call_arityCheck): (JSC::Machine::cti_op_call_NotJSFunction): (JSC::Machine::cti_op_construct_JSConstruct): (JSC::Machine::cti_op_construct_NotJSConstruct): (JSC::Machine::cti_op_call_eval): (JSC::Machine::cti_vm_throw):
  • VM/Machine.h:
  • bytecompiler/CodeGenerator.cpp: (JSC::CodeGenerator::emitCall): (JSC::CodeGenerator::emitCallEval): (JSC::CodeGenerator::emitConstruct):
  • bytecompiler/CodeGenerator.h:
  • parser/Nodes.cpp: (JSC::EvalFunctionCallNode::emitCode): (JSC::FunctionCallValueNode::emitCode): (JSC::FunctionCallResolveNode::emitCode): (JSC::FunctionCallBracketNode::emitCode): (JSC::FunctionCallDotNode::emitCode):
  • parser/Nodes.h: (JSC::ScopeNode::neededConstants):

LayoutTests:

  • fast/js/global-recursion-on-full-stack-expected.txt:
Location:
trunk/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r38322 r38330  
     12008-11-12  Cameron Zwarich  <[email protected]>
     2
     3        Rubber-stamped by Mark Rowe.
     4
     5        Roll out r38322 due to test failures on the bots.
     6
     7        * VM/CTI.cpp:
     8        (JSC::CTI::compileOpCallSetupArgs):
     9        (JSC::CTI::compileOpCall):
     10        (JSC::CTI::privateCompileMainPass):
     11        (JSC::CTI::privateCompileSlowCases):
     12        * VM/CTI.h:
     13        * VM/CodeBlock.cpp:
     14        (JSC::CodeBlock::dump):
     15        * VM/Machine.cpp:
     16        (JSC::Machine::callEval):
     17        (JSC::Machine::dumpCallFrame):
     18        (JSC::Machine::dumpRegisters):
     19        (JSC::Machine::execute):
     20        (JSC::Machine::privateExecute):
     21        (JSC::Machine::throwStackOverflowPreviousFrame):
     22        (JSC::Machine::cti_register_file_check):
     23        (JSC::Machine::cti_op_call_arityCheck):
     24        (JSC::Machine::cti_op_call_NotJSFunction):
     25        (JSC::Machine::cti_op_construct_JSConstruct):
     26        (JSC::Machine::cti_op_construct_NotJSConstruct):
     27        (JSC::Machine::cti_op_call_eval):
     28        (JSC::Machine::cti_vm_throw):
     29        * VM/Machine.h:
     30        * bytecompiler/CodeGenerator.cpp:
     31        (JSC::CodeGenerator::emitCall):
     32        (JSC::CodeGenerator::emitCallEval):
     33        (JSC::CodeGenerator::emitConstruct):
     34        * bytecompiler/CodeGenerator.h:
     35        * parser/Nodes.cpp:
     36        (JSC::EvalFunctionCallNode::emitCode):
     37        (JSC::FunctionCallValueNode::emitCode):
     38        (JSC::FunctionCallResolveNode::emitCode):
     39        (JSC::FunctionCallBracketNode::emitCode):
     40        (JSC::FunctionCallDotNode::emitCode):
     41        * parser/Nodes.h:
     42        (JSC::ScopeNode::neededConstants):
     43
    1442008-11-11  Geoffrey Garen  <[email protected]>
    245
  • trunk/JavaScriptCore/VM/CTI.cpp

    r38322 r38330  
    588588}
    589589
    590 void CTI::compileOpCallSetupArgs(Instruction* instruction)
    591 {
    592     int argCount = instruction[3].u.operand;
    593     int registerOffset = instruction[4].u.operand;
    594 
    595     // ecx holds func
     590void CTI::compileOpCallSetupArgs(Instruction* instruction, bool isConstruct, bool isEval)
     591{
     592    int firstArg = instruction[4].u.operand;
     593    int argCount = instruction[5].u.operand;
     594    int registerOffset = instruction[6].u.operand;
     595
    596596    emitPutArg(X86::ecx, 0);
    597597    emitPutArgConstant(registerOffset, 4);
    598598    emitPutArgConstant(argCount, 8);
    599599    emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 12);
    600 }
    601 
    602 void CTI::compileOpCallEvalSetupArgs(Instruction* instruction)
    603 {
    604     int argCount = instruction[3].u.operand;
    605     int registerOffset = instruction[4].u.operand;
    606 
    607     // ecx holds func
    608     emitPutArg(X86::ecx, 0);
    609     emitPutArgConstant(registerOffset, 4);
    610     emitPutArgConstant(argCount, 8);
    611     emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 12);
    612 }
    613 
    614 void CTI::compileOpConstructSetupArgs(Instruction* instruction)
    615 {
    616     int argCount = instruction[3].u.operand;
    617     int registerOffset = instruction[4].u.operand;
    618     int proto = instruction[5].u.operand;
    619     int thisRegister = instruction[6].u.operand;
    620 
    621     // ecx holds func
    622     emitPutArg(X86::ecx, 0);
    623     emitPutArgConstant(registerOffset, 4);
    624     emitPutArgConstant(argCount, 8);
    625     emitGetPutArg(proto, 12, X86::eax);
    626     emitPutArgConstant(thisRegister, 16);
    627     emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 20);
     600    if (isConstruct) {
     601        emitGetPutArg(instruction[3].u.operand, 16, X86::eax);
     602        emitPutArgConstant(firstArg, 20);
     603    } else if (isEval)
     604        emitGetPutArg(instruction[3].u.operand, 16, X86::eax);
    628605}
    629606
     
    632609    int dst = instruction[1].u.operand;
    633610    int callee = instruction[2].u.operand;
    634     int argCount = instruction[3].u.operand;
    635     int registerOffset = instruction[4].u.operand;
     611    int firstArg = instruction[4].u.operand;
     612    int argCount = instruction[5].u.operand;
     613    int registerOffset = instruction[6].u.operand;
     614
     615    // Setup this value as the first argument (does not apply to constructors)
     616    if (opcodeID != op_construct) {
     617        int thisVal = instruction[3].u.operand;
     618        if (thisVal == missingThisObjectMarker())
     619            m_jit.movl_i32m(asInteger(jsNull()), firstArg * sizeof(Register), X86::edi);
     620        else {
     621            emitGetArg(thisVal, X86::eax);
     622            emitPutResult(firstArg);
     623        }
     624    }
    636625
    637626    // Handle eval
     
    639628    if (opcodeID == op_call_eval) {
    640629        emitGetArg(callee, X86::ecx);
    641         compileOpCallEvalSetupArgs(instruction);
     630        compileOpCallSetupArgs(instruction, false, true);
    642631
    643632        emitCTICall(instruction, i, Machine::cti_op_call_eval);
     
    659648    // In the case of OpConstruct, call out to a cti_ function to create the new object.
    660649    if (opcodeID == op_construct) {
    661         int proto = instruction[5].u.operand;
    662         int thisRegister = instruction[6].u.operand;
    663 
    664650        emitPutArg(X86::ecx, 0);
    665         emitGetPutArg(proto, 12, X86::eax);
     651        emitGetPutArg(instruction[3].u.operand, 16, X86::eax);
    666652        emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruct);
    667         emitPutResult(thisRegister);
     653        emitPutResult(firstArg);
    668654        emitGetArg(callee, X86::ecx);
    669655    }
     
    13001286            break;
    13011287        }
    1302         case op_call:
    1303         case op_call_eval:
    1304         case op_construct: {
     1288        case op_call: {
    13051289            compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
    1306             i += (opcodeID == op_construct ? 7 : 5);
     1290            i += 7;
    13071291            break;
    13081292        }
     
    13961380            emitPutResult(instruction[i + 1].u.operand);
    13971381            i += 3;
     1382            break;
     1383        }
     1384        case op_construct: {
     1385            compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
     1386            i += 7;
    13981387            break;
    13991388        }
     
    19231912            emitPutResult(instruction[i + 1].u.operand);
    19241913            i += 5;
     1914            break;
     1915        }
     1916        case op_call_eval: {
     1917            compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
     1918            i += 7;
    19251919            break;
    19261920        }
     
    27742768            int dst = instruction[i + 1].u.operand;
    27752769            int callee = instruction[i + 2].u.operand;
    2776             int argCount = instruction[i + 3].u.operand;
    2777             int registerOffset = instruction[i + 4].u.operand;
     2770            int firstArg = instruction[i + 4].u.operand;
     2771            int argCount = instruction[i + 5].u.operand;
     2772            int registerOffset = instruction[i + 6].u.operand;
    27782773
    27792774            m_jit.link(iter->from, m_jit.label());
    27802775
    27812776            // The arguments have been set up on the hot path for op_call_eval
    2782             if (opcodeID == op_call)
    2783                 compileOpCallSetupArgs(instruction + i);
    2784             else if (opcodeID == op_construct)
    2785                 compileOpConstructSetupArgs(instruction + i);
     2777            if (opcodeID != op_call_eval)
     2778                compileOpCallSetupArgs(instruction + i, (opcodeID == op_construct), false);
    27862779
    27872780            // Fast check for JS function.
     
    27912784            X86Assembler::JmpSrc callLinkFailNotJSFunction = m_jit.emitUnlinkedJne();
    27922785
    2793             // First, in the case of a construct, allocate the new object.
     2786            // First, in the cale of a construct, allocate the new object.
    27942787            if (opcodeID == op_construct) {
    27952788                emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruct);
    2796                 emitPutResult(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
     2789                emitPutResult(firstArg);
    27972790                emitGetArg(callee, X86::ecx);
    27982791            }
     
    28352828
    28362829            // The arguments have been set up on the hot path for op_call_eval
    2837             if (opcodeID == op_call)
    2838                 compileOpCallSetupArgs(instruction + i);
    2839             else if (opcodeID == op_construct)
    2840                 compileOpConstructSetupArgs(instruction + i);
     2830            if (opcodeID != op_call_eval)
     2831                compileOpCallSetupArgs(instruction + i, (opcodeID == op_construct), false);
    28412832
    28422833            // Check for JSFunctions.
     
    28572848            m_jit.link(isJSFunction, m_jit.label());
    28582849
    2859             // First, in the case of a construct, allocate the new object.
     2850            // First, in the cale of a construct, allocate the new object.
    28602851            if (opcodeID == op_construct) {
    28612852                emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruct);
    2862                 emitPutResult(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
     2853                emitPutResult(firstArg);
    28632854                emitGetArg(callee, X86::ecx);
    28642855            }
     
    29052896            ++callLinkInfoIndex;
    29062897
    2907             i += (opcodeID == op_construct ? 7 : 5);
     2898            i += 7;
    29082899            break;
    29092900        }
  • trunk/JavaScriptCore/VM/CTI.h

    r38322 r38330  
    366366        void compileOpCall(OpcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex);
    367367        void compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount);
    368         void compileOpCallSetupArgs(Instruction*);
    369         void compileOpCallEvalSetupArgs(Instruction*);
    370         void compileOpConstructSetupArgs(Instruction*);
     368        void compileOpCallSetupArgs(Instruction* instruction, bool isConstruct, bool isEval);
    371369        enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
    372370        void compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type);
  • trunk/JavaScriptCore/VM/CodeBlock.cpp

    r38322 r38330  
    813813        }
    814814        case op_call: {
    815             int dst = (++it)->u.operand;
    816             int func = (++it)->u.operand;
     815            int r0 = (++it)->u.operand;
     816            int r1 = (++it)->u.operand;
     817            int r2 = (++it)->u.operand;
     818            int tempCount = (++it)->u.operand;
    817819            int argCount = (++it)->u.operand;
    818820            int registerOffset = (++it)->u.operand;
    819             printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
     821            printf("[%4d] call\t\t %s, %s, %s, %d, %d, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), tempCount, argCount, registerOffset);
    820822            break;
    821823        }
    822824        case op_call_eval: {
    823             int dst = (++it)->u.operand;
    824             int func = (++it)->u.operand;
     825            int r0 = (++it)->u.operand;
     826            int r1 = (++it)->u.operand;
     827            int r2 = (++it)->u.operand;
     828            int tempCount = (++it)->u.operand;
    825829            int argCount = (++it)->u.operand;
    826830            int registerOffset = (++it)->u.operand;
    827             printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
     831            printf("[%4d] call_eval\t\t %s, %s, %s, %d, %d, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), tempCount, argCount, registerOffset);
    828832            break;
    829833        }
     
    843847        }
    844848        case op_construct: {
    845             int dst = (++it)->u.operand;
    846             int func = (++it)->u.operand;
     849            int r0 = (++it)->u.operand;
     850            int r1 = (++it)->u.operand;
     851            int r2 = (++it)->u.operand;
     852            int tempCount = (++it)->u.operand;
    847853            int argCount = (++it)->u.operand;
    848854            int registerOffset = (++it)->u.operand;
    849             int proto = (++it)->u.operand;
    850             int thisRegister = (++it)->u.operand;
    851             printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset, registerName(proto).c_str(), registerName(thisRegister).c_str());
     855            printf("[%4d] construct\t %s, %s, %s, %d, %d, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), tempCount, argCount, registerOffset);
    852856            break;
    853857        }
  • trunk/JavaScriptCore/VM/Machine.cpp

    r38322 r38330  
    581581}
    582582
    583 NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValue*& exceptionValue)
     583NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, int argv, int argc, JSValue*& exceptionValue)
    584584{
    585585    if (argc < 2)
    586586        return jsUndefined();
    587587
    588     JSValue* program = argv[1].jsValue(callFrame);
     588    JSValue* program = callFrame[argv + 1].jsValue(callFrame);
    589589
    590590    if (!program->isString())
     
    593593    UString programSource = asString(program)->value();
    594594
    595     ScopeChainNode* scopeChain = callFrame->scopeChain();
    596595    CodeBlock* codeBlock = callFrame->codeBlock();
    597596    RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programSource, scopeChain, exceptionValue);
     
    599598    JSValue* result = jsUndefined();
    600599    if (evalNode)
    601         result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, callFrame->thisValue()->toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
     600        result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, thisObj, callFrame->registers() - registerFile->start() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue);
    602601
    603602    return result;
     
    657656#ifndef NDEBUG
    658657
    659 void Machine::dumpCallFrame(CallFrame* callFrame)
    660 {
    661     callFrame->codeBlock()->dump(callFrame);
    662     dumpRegisters(callFrame);
    663 }
    664 
    665 void Machine::dumpRegisters(CallFrame* callFrame)
     658void Machine::dumpCallFrame(const RegisterFile* registerFile, CallFrame* callFrame)
     659{
     660    JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
     661
     662    CodeBlock* codeBlock = callFrame->codeBlock();
     663    codeBlock->dump(globalObject->globalExec());
     664
     665    dumpRegisters(registerFile, callFrame);
     666}
     667
     668void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFrame)
    666669{
    667670    printf("Register frame: \n\n");
     
    671674
    672675    CodeBlock* codeBlock = callFrame->codeBlock();
    673     RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->machine->registerFile();
    674676    const Register* it;
    675677    const Register* end;
     
    10221024}
    10231025
    1024 JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue** exception)
     1026JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
    10251027{
    10261028    ASSERT(!scopeChain->globalData->exception);
     
    10681070
    10691071    Register* oldEnd = m_registerFile.end();
    1070     Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->numCalleeRegisters;
     1072    Register* newEnd = m_registerFile.start() + registerOffset + codeBlock->numCalleeRegisters;
    10711073    if (!m_registerFile.grow(newEnd)) {
    10721074        *exception = createStackOverflowError(callFrame);
     
    10741076    }
    10751077
    1076     CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset);
     1078    CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + registerOffset);
    10771079
    10781080    // a 0 codeBlock indicates a built-in caller
     
    32633265    }
    32643266    BEGIN_OPCODE(op_call_eval) {
    3265         /* call_eval dst(r) func(r) argCount(n) registerOffset(n)
     3267        /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
    32663268
    32673269           Call a function named "eval" with no explicit "this" value
     
    32763278        int dst = vPC[1].u.operand;
    32773279        int func = vPC[2].u.operand;
    3278         int argCount = vPC[3].u.operand;
    3279         int registerOffset = vPC[4].u.operand;
     3280        int thisVal = vPC[3].u.operand;
     3281        int firstArg = vPC[4].u.operand;
     3282        int argCount = vPC[5].u.operand;
    32803283
    32813284        JSValue* funcVal = callFrame[func].jsValue(callFrame);
    3282 
    3283         Register* newCallFrame = callFrame->registers() + registerOffset;
    3284         Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
    3285         JSValue* thisValue = argv[0].jsValue(callFrame);
    3286         JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
    3287 
    3288         if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
    3289             JSValue* result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
     3285        JSValue* baseVal = callFrame[thisVal].jsValue(callFrame);
     3286
     3287        ScopeChainNode* scopeChain = callFrame->scopeChain();
     3288        if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
     3289            JSObject* thisObject = asObject(callFrame[callFrame->codeBlock()->thisRegister].jsValue(callFrame));
     3290            JSValue* result = callEval(callFrame, thisObject, scopeChain, registerFile, firstArg, argCount, exceptionValue);
    32903291            if (exceptionValue)
    32913292                goto vm_throw;
     3293
    32923294            callFrame[dst] = result;
    32933295
    3294             vPC += 5;
     3296            vPC += 7;
    32953297            NEXT_OPCODE;
    32963298        }
    32973299
    3298         // We didn't find the blessed version of eval, so process this
    3299         // instruction as a normal function call.
     3300        // We didn't find the blessed version of eval, so reset vPC and process
     3301        // this instruction as a normal function call, supplying the proper 'this'
     3302        // value.
     3303        callFrame[thisVal] = baseVal->toThisObject(callFrame);
    33003304
    33013305#if HAVE(COMPUTED_GOTO)
     
    33083312    }
    33093313    BEGIN_OPCODE(op_call) {
    3310         /* call dst(r) func(r) argCount(n) registerOffset(n)
    3311 
    3312            Perform a function call.
    3313            
    3314            registerOffset is the distance the callFrame pointer should move
    3315            before the VM initializes the new call frame's header.
    3316            
    3317            dst is where op_ret should store its result.
     3314        /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset(n)
     3315
     3316           Perform a function call. Specifically, call register func
     3317           with a "this" value of register thisVal, and put the result
     3318           in register dst.
     3319
     3320           The arguments start at register firstArg and go up to
     3321           argCount, but the "this" value is considered an implicit
     3322           first argument, so the argCount should be one greater than
     3323           the number of explicit arguments passed, and the register
     3324           after firstArg should contain the actual first
     3325           argument. This opcode will copy from the thisVal register
     3326           to the firstArg register, unless the register index of
     3327           thisVal is the special missing this object marker, which is
     3328           2^31-1; in that case, the global object will be used as the
     3329           "this" value.
     3330
     3331           If func is a native code function, then this opcode calls
     3332           it and returns the value immediately.
     3333
     3334           But if it is a JS function, then the current scope chain
     3335           and code block is set to the function's, and we slide the
     3336           register window so that the arguments would form the first
     3337           few local registers of the called function's register
     3338           window. In addition, a call frame header is written
     3339           immediately before the arguments; see the call frame
     3340           documentation for an explanation of how many registers a
     3341           call frame takes and what they contain. That many registers
     3342           before the firstArg register will be overwritten by the
     3343           call. In addition, any registers higher than firstArg +
     3344           argCount may be overwritten. Once this setup is complete,
     3345           execution continues from the called function's first
     3346           argument, and does not return until a "ret" opcode is
     3347           encountered.
    33183348         */
    33193349
    33203350        int dst = vPC[1].u.operand;
    33213351        int func = vPC[2].u.operand;
    3322         int argCount = vPC[3].u.operand;
    3323         int registerOffset = vPC[4].u.operand;
     3352        int thisVal = vPC[3].u.operand;
     3353        int firstArg = vPC[4].u.operand;
     3354        int argCount = vPC[5].u.operand;
     3355        int registerOffset = vPC[6].u.operand;
    33243356
    33253357        JSValue* v = callFrame[func].jsValue(callFrame);
     
    33333365            CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
    33343366
     3367            callFrame[firstArg] = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
     3368           
    33353369            CallFrame* previousCallFrame = callFrame;
    33363370
     
    33423376            }
    33433377
    3344             callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
     3378            callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
    33453379            vPC = newCodeBlock->instructions.begin();
    33463380
     
    33533387
    33543388        if (callType == CallTypeHost) {
     3389            JSValue* thisValue = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
     3390            ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
     3391
    33553392            ScopeChainNode* scopeChain = callFrame->scopeChain();
    33563393            CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
    3357             newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0);
    3358 
    3359             Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
    3360             ArgList args(thisRegister + 1, argCount - 1);
    3361 
    3362             // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
    3363             JSValue* thisValue = thisRegister->jsValue(callFrame);
    3364             if (thisValue == jsNull())
    3365                 thisValue = callFrame->globalThisValue();
     3394            newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
    33663395
    33673396            JSValue* returnValue;
     
    33743403            callFrame[dst] = returnValue;
    33753404
    3376             vPC += 5;
     3405            vPC += 7;
    33773406            NEXT_OPCODE;
    33783407        }
     
    35443573    }
    35453574    BEGIN_OPCODE(op_construct) {
    3546         /* construct dst(r) func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)
    3547 
    3548            Invoke register "func" as a constructor. For JS
     3575        /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) registerOffset(n)
     3576
     3577           Invoke register "constr" as a constructor. For JS
    35493578           functions, the calling convention is exactly as for the
    35503579           "call" opcode, except that the "this" value is a newly
    3551            created Object. For native constructors, no "this"
    3552            value is passed. In either case, the argCount and registerOffset
     3580           created Object. For native constructors, a null "this"
     3581           value is passed. In either case, the firstArg and argCount
    35533582           registers are interpreted as for the "call" opcode.
    35543583
    3555            Register proto must contain the prototype property of
    3556            register func. This is to enable polymorphic inline
     3584           Register constrProto must contain the prototype property of
     3585           register constsr. This is to enable polymorphic inline
    35573586           caching of this lookup.
    35583587        */
    35593588
    35603589        int dst = vPC[1].u.operand;
    3561         int func = vPC[2].u.operand;
    3562         int argCount = vPC[3].u.operand;
    3563         int registerOffset = vPC[4].u.operand;
    3564         int proto = vPC[5].u.operand;
    3565         int thisRegister = vPC[6].u.operand;
    3566 
    3567         JSValue* v = callFrame[func].jsValue(callFrame);
     3590        int constr = vPC[2].u.operand;
     3591        int constrProto = vPC[3].u.operand;
     3592        int firstArg = vPC[4].u.operand;
     3593        int argCount = vPC[5].u.operand;
     3594        int registerOffset = vPC[6].u.operand;
     3595
     3596        JSValue* v = callFrame[constr].jsValue(callFrame);
    35683597
    35693598        ConstructData constructData;
     
    35763605
    35773606            StructureID* structure;
    3578             JSValue* prototype = callFrame[proto].jsValue(callFrame);
     3607            JSValue* prototype = callFrame[constrProto].jsValue(callFrame);
    35793608            if (prototype->isObject())
    35803609                structure = asObject(prototype)->inheritorID();
     
    35833612            JSObject* newObject = new (globalData) JSObject(structure);
    35843613
    3585             callFrame[thisRegister] = newObject; // "this" value
     3614            callFrame[firstArg] = newObject; // "this" value
    35863615
    35873616            CallFrame* previousCallFrame = callFrame;
     
    36053634
    36063635        if (constructType == ConstructTypeHost) {
    3607             ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1);
     3636            ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
    36083637
    36093638            ScopeChainNode* scopeChain = callFrame->scopeChain();
     
    43364365    } while (0)
    43374366
    4338 // This macro rewinds to the previous call frame because CTI functions that
    4339 // throw stack overflow exceptions execute after the call frame has
    4340 // optimistically moved forward.
    4341 #define CTI_THROW_STACK_OVERFLOW() do { \
    4342     CallFrame* oldCallFrame = ARG_callFrame->callerFrame(); \
    4343     JSGlobalData* globalData = ARG_globalData; \
    4344     globalData->exception = createStackOverflowError(oldCallFrame); \
    4345     globalData->throwReturnAddress = CTI_RETURN_ADDRESS; \
    4346     ARG_setCallFrame(oldCallFrame); \
    4347     CTI_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiVMThrowTrampoline)); \
    4348 } while (0);
    4349 
    43504367JSObject* Machine::cti_op_convert_this(CTI_ARGS)
    43514368{
     
    44364453}
    44374454
     4455NEVER_INLINE void Machine::throwStackOverflowPreviousFrame(CallFrame* callFrame, JSGlobalData* globalData, void*& returnAddress)
     4456{
     4457    globalData->exception = createStackOverflowError(callFrame->callerFrame());
     4458    globalData->throwReturnAddress = callFrame->returnPC();
     4459    ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
     4460}
     4461
    44384462void Machine::cti_register_file_check(CTI_ARGS)
    44394463{
     
    44434467        return;
    44444468
    4445     CTI_THROW_STACK_OVERFLOW();
     4469    ARG_setCallFrame(ARG_callFrame->callerFrame());
     4470    throwStackOverflowPreviousFrame(ARG_callFrame, ARG_globalData, CTI_RETURN_ADDRESS);
    44464471}
    44474472
     
    47204745        Register* newEnd = r + newCodeBlock->numCalleeRegisters;
    47214746        if (!ARG_registerFile->grow(newEnd)) {
    4722             CTI_THROW_STACK_OVERFLOW();
    4723             VoidPtrPairValue pair = {{ 0, 0 }};
    4724             return pair.i;
     4747            ARG_globalData->exception = createStackOverflowError(oldCallFrame);
     4748            VM_THROW_EXCEPTION_2();
    47254749        }
    47264750
     
    47874811            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
    47884812
    4789             // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
     4813            // All host methods should be calling toThisObject, but this is not presently the case.
    47904814            JSValue* thisValue = argv[0].jsValue(callFrame);
    47914815            if (thisValue == jsNull())
     
    49114935
    49124936    StructureID* structure;
    4913     if (ARG_src4->isObject())
    4914         structure = asObject(ARG_src4)->inheritorID();
     4937    if (ARG_src5->isObject())
     4938        structure = asObject(ARG_src5)->inheritorID();
    49154939    else
    49164940        structure = asFunction(ARG_src1)->m_scopeChain.node()->globalObject()->emptyObjectStructure();
     
    49264950    JSValue* constrVal = ARG_src1;
    49274951    int argCount = ARG_int3;
    4928     int thisRegister = ARG_int5;
     4952    int firstArg = ARG_int6;
    49294953
    49304954    ConstructData constructData;
     
    49324956
    49334957    if (constructType == ConstructTypeHost) {
    4934         ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1);
     4958        ArgList argList(callFrame->registers() + firstArg + 1, argCount - 1);
    49354959
    49364960        JSValue* returnValue;
     
    49464970    ASSERT(constructType == ConstructTypeNone);
    49474971
    4948     ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr6, callFrame->codeBlock());
     4972    ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr4, callFrame->codeBlock());
    49494973    VM_THROW_EXCEPTION();
    49504974}
     
    55455569    CallFrame* callFrame = ARG_callFrame;
    55465570    RegisterFile* registerFile = ARG_registerFile;
     5571    CodeBlock* codeBlock = callFrame->codeBlock();
     5572    ScopeChainNode* scopeChain = callFrame->scopeChain();
    55475573
    55485574    Machine* machine = ARG_globalData->machine;
     
    55515577    int registerOffset = ARG_int2;
    55525578    int argCount = ARG_int3;
    5553 
    5554     Register* newCallFrame = callFrame->registers() + registerOffset;
    5555     Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
    5556     JSValue* thisValue = argv[0].jsValue(callFrame);
    5557     JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
    5558 
    5559     if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
     5579    JSValue* baseVal = ARG_src5;
     5580
     5581    if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
     5582        JSObject* thisObject = callFrame[codeBlock->thisRegister].jsValue(callFrame)->toThisObject(callFrame);
    55605583        JSValue* exceptionValue = noValue();
    5561         JSValue* result = machine->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
     5584        JSValue* result = machine->callEval(callFrame, thisObject, scopeChain, registerFile, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue);
    55625585        if (UNLIKELY(exceptionValue != noValue())) {
    55635586            ARG_globalData->exception = exceptionValue;
     
    59225945    CallFrame* callFrame = ARG_callFrame;
    59235946    CodeBlock* codeBlock = callFrame->codeBlock();
    5924     JSGlobalData* globalData = ARG_globalData;
    5925 
    5926     ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(globalData->throwReturnAddress));
    5927     unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(globalData->throwReturnAddress);
    5928 
    5929     JSValue* exceptionValue = globalData->exception;
     5947
     5948    ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(ARG_globalData->throwReturnAddress));
     5949    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(ARG_globalData->throwReturnAddress);
     5950
     5951    JSValue* exceptionValue = ARG_globalData->exception;
    59305952    ASSERT(exceptionValue);
    5931     globalData->exception = noValue();
    5932 
    5933     Instruction* handlerVPC = globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false);
     5953    ARG_globalData->exception = noValue();
     5954
     5955    Instruction* handlerVPC = ARG_globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false);
    59345956
    59355957    if (!handlerVPC) {
  • trunk/JavaScriptCore/VM/Machine.h

    r38322 r38330  
    285285        enum ExecutionFlag { Normal, InitializeAndReturn };
    286286
    287         NEVER_INLINE JSValue* callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValue*& exceptionValue);
    288         JSValue* execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue** exception);
     287        NEVER_INLINE JSValue* callEval(CallFrame*, JSObject* thisObject, ScopeChainNode*, RegisterFile*, int argv, int argc, JSValue*& exceptionValue);
     288        JSValue* execute(EvalNode*, CallFrame*, JSObject* thisObject, int registerOffset, ScopeChainNode*, JSValue** exception);
    289289
    290290        NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
     
    307307        JSValue* privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValue** exception);
    308308
    309         void dumpCallFrame(CallFrame*);
    310         void dumpRegisters(CallFrame*);
     309        void dumpCallFrame(const RegisterFile*, CallFrame*);
     310        void dumpRegisters(const RegisterFile*, CallFrame*);
    311311
    312312        JSValue* checkTimeout(JSGlobalObject*);
     
    321321
    322322#if ENABLE(CTI)
    323         static void throwStackOverflowPreviousFrame(CallFrame**, JSGlobalData*, void*& returnAddress);
     323        static void throwStackOverflowPreviousFrame(CallFrame*, JSGlobalData*, void*& returnAddress);
    324324
    325325        void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const Identifier& propertyName, const PropertySlot&);
  • trunk/JavaScriptCore/bytecompiler/CodeGenerator.cpp

    r38322 r38330  
    12201220}
    12211221
    1222 RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    1223 {
    1224     return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
    1225 }
    1226 
    1227 RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    1228 {
    1229     return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
    1230 }
    1231 
    1232 RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1222RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1223{
     1224    return emitCall(op_call, dst, func, base, argumentsNode, divot, startOffset, endOffset);
     1225}
     1226
     1227RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1228{
     1229    return emitCall(op_call_eval, dst, func, base, argumentsNode, divot, startOffset, endOffset);
     1230}
     1231
     1232RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    12331233{
    12341234    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
    12351235    ASSERT(func->refCount());
     1236    ASSERT(!base || base->refCount());
    12361237   
    12371238    // Generate code for arguments.
    12381239    Vector<RefPtr<RegisterID>, 16> argv;
    1239     argv.append(thisRegister);
     1240    argv.append(newTemporary()); // reserve space for "this"
    12401241    for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
    12411242        argv.append(newTemporary());
     
    12551256    emitExpressionInfo(divot, startOffset, endOffset);
    12561257    m_codeBlock->callLinkInfos.append(CallLinkInfo());
    1257 
    1258     // Emit call.
    12591258    emitOpcode(opcodeID);
    1260     instructions().append(dst->index()); // dst
    1261     instructions().append(func->index()); // func
    1262     instructions().append(argv.size()); // argCount
     1259    instructions().append(dst->index());
     1260    instructions().append(func->index());
     1261    instructions().append(base ? base->index() : missingThisObjectMarker()); // We encode the "this" value in the instruction stream, to avoid an explicit instruction for copying or loading it.
     1262    instructions().append(argv[0]->index()); // argv
     1263    instructions().append(argv.size()); // argc
    12631264    instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
    12641265
     
    13191320    emitExpressionInfo(divot, startOffset, endOffset);
    13201321    m_codeBlock->callLinkInfos.append(CallLinkInfo());
    1321 
    13221322    emitOpcode(op_construct);
    1323     instructions().append(dst->index()); // dst
    1324     instructions().append(func->index()); // func
    1325     instructions().append(argv.size()); // argCount
     1323    instructions().append(dst->index());
     1324    instructions().append(func->index());
     1325    instructions().append(funcProto->index());
     1326    instructions().append(argv[0]->index()); // argv
     1327    instructions().append(argv.size()); // argc
    13261328    instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
    1327     instructions().append(funcProto->index()); // proto
    1328     instructions().append(argv[0]->index()); // thisRegister
    13291329
    13301330    emitOpcode(op_construct_verify);
  • trunk/JavaScriptCore/bytecompiler/CodeGenerator.h

    r38322 r38330  
    274274        RegisterID* emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value);
    275275
    276         RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    277         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
     276        RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
     277        RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    278278
    279279        RegisterID* emitReturn(RegisterID* src);
     
    346346        typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap;
    347347
    348         RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
     348        RegisterID* emitCall(OpcodeID, RegisterID*, RegisterID*, RegisterID*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    349349       
    350350        RegisterID* newRegister();
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r38322 r38330  
    586586RegisterID* EvalFunctionCallNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    587587{
    588     RefPtr<RegisterID> func = generator.tempDestination(dst);
    589     RefPtr<RegisterID> thisRegister = generator.newTemporary();
    590     generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
    591     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     588    RefPtr<RegisterID> base = generator.tempDestination(dst);
     589    RefPtr<RegisterID> func = generator.newTemporary();
     590    generator.emitResolveWithBase(base.get(), func.get(), generator.propertyNames().eval);
     591    return generator.emitCallEval(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
    592592}
    593593
     
    608608{
    609609    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
    610     RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
    611     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     610    return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), divot(), startOffset(), endOffset());
    612611}
    613612
     
    626625RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    627626{
    628     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
    629         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
    630         return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    631     }
     627    if (RefPtr<RegisterID> local = generator.registerFor(m_ident))
     628        return generator.emitCall(generator.finalDestination(dst), local.get(), 0, m_args.get(), divot(), startOffset(), endOffset());
    632629
    633630    int index = 0;
     
    636633    if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
    637634        RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
    638         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
    639         return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    640     }
    641 
    642     RefPtr<RegisterID> func = generator.tempDestination(dst);
    643     RefPtr<RegisterID> thisRegister = generator.newTemporary();
     635        return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), divot(), startOffset(), endOffset());
     636    }
     637
     638    RefPtr<RegisterID> base = generator.tempDestination(dst);
     639    RefPtr<RegisterID> func = generator.newTemporary();
    644640    int identifierStart = divot() - startOffset();
    645641    generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
    646     generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
    647     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     642    generator.emitResolveFunction(base.get(), func.get(), m_ident);
     643    return generator.emitCall(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
    648644}
    649645
     
    667663    RegisterID* property = generator.emitNode(m_subscript.get());
    668664    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    669     RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
    670     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
    671     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     665    RefPtr<RegisterID> function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
     666    return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
    672667}
    673668
     
    689684    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
    690685    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    691     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
    692     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
    693     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     686    RefPtr<RegisterID> function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
     687    return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
    694688}
    695689
  • trunk/JavaScriptCore/parser/Nodes.h

    r38322 r38330  
    20792079        int neededConstants()
    20802080        {
    2081             // We may need 2 more constants than the count given by the parser,
    2082             // because of the various uses of jsUndefined() and jsNull().
    2083             return m_numConstants + 2;
     2081            // We may need 1 more constant than the count given by the parser,
     2082            // because of the various uses of jsUndefined().
     2083            return m_numConstants + 1;
    20842084        }
    20852085
Note: See TracChangeset for help on using the changeset viewer.