Changeset 180595 in webkit


Ignore:
Timestamp:
Feb 24, 2015 4:41:35 PM (9 years ago)
Author:
rniwa@webkit.org
Message:

Use "this" instead of "callee" to get the constructor
https://bugs.webkit.org/show_bug.cgi?id=141019

Reviewed by Filip Pizlo.

This patch uses "this" register to pass the constructor (newTarget) to op_create_this from
op_construct or op_construct_varargs. This will allow future patches that implement ES6 class
to pass in the most derived class' constructor through "this" argument.

BytecodeGenerator's emitConstruct and emitConstructVarargs now passes thisRegister like
regular calls and emitCreateThis passes in this register to op_create_this as constructor.

The rest of the code change removes the code for special casing "this" register not being used
in call to construct.

  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitCreateThis):
(JSC::BytecodeGenerator::emitConstructVarargs):
(JSC::BytecodeGenerator::emitConstruct):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::NewExprNode::emitBytecode):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
(JSC::DFG::ByteCodeParser::handleVarargsCall):
(JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
(JSC::DFG::ByteCodeParser::attemptToInlineCall):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGJITCode.cpp:

(JSC::DFG::JITCode::reconstruct):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::emitCall):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::emitCall):

  • ftl/FTLJSCallVarargs.cpp:

(JSC::FTL::JSCallVarargs::emit):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
(JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
(JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::executeConstruct):

  • jit/JITOperations.cpp:
Location:
trunk/Source/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r180594 r180595  
     12015-02-24  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Use "this" instead of "callee" to get the constructor
     4        https://bugs.webkit.org/show_bug.cgi?id=141019
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch uses "this" register to pass the constructor (newTarget) to op_create_this from
     9        op_construct or op_construct_varargs. This will allow future patches that implement ES6 class
     10        to pass in the most derived class' constructor through "this" argument.
     11
     12        BytecodeGenerator's emitConstruct and emitConstructVarargs now passes thisRegister like
     13        regular calls and emitCreateThis passes in this register to op_create_this as constructor.
     14
     15        The rest of the code change removes the code for special casing "this" register not being used
     16        in call to construct.
     17
     18        * bytecode/BytecodeUseDef.h:
     19        (JSC::computeUsesForBytecodeOffset):
     20        * bytecompiler/BytecodeGenerator.cpp:
     21        (JSC::BytecodeGenerator::emitCreateThis):
     22        (JSC::BytecodeGenerator::emitConstructVarargs):
     23        (JSC::BytecodeGenerator::emitConstruct):
     24        * bytecompiler/BytecodeGenerator.h:
     25        * bytecompiler/NodesCodegen.cpp:
     26        (JSC::NewExprNode::emitBytecode):
     27        * dfg/DFGByteCodeParser.cpp:
     28        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
     29        (JSC::DFG::ByteCodeParser::handleVarargsCall):
     30        (JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
     31        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
     32        (JSC::DFG::ByteCodeParser::handleInlining):
     33        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
     34        (JSC::DFG::ByteCodeParser::parseBlock):
     35        * dfg/DFGJITCode.cpp:
     36        (JSC::DFG::JITCode::reconstruct):
     37        * dfg/DFGSpeculativeJIT32_64.cpp:
     38        (JSC::DFG::SpeculativeJIT::emitCall):
     39        * dfg/DFGSpeculativeJIT64.cpp:
     40        (JSC::DFG::SpeculativeJIT::emitCall):
     41        * ftl/FTLJSCallVarargs.cpp:
     42        (JSC::FTL::JSCallVarargs::emit):
     43        * ftl/FTLLowerDFGToLLVM.cpp:
     44        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
     45        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
     46        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
     47        * interpreter/Interpreter.cpp:
     48        (JSC::Interpreter::executeConstruct):
     49        * jit/JITOperations.cpp:
     50
    1512015-02-24  Joseph Pecoraro  <pecoraro@apple.com>
    252
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r180587 r180595  
    219219        int registerOffset = -instruction[4].u.operand;
    220220        int lastArg = registerOffset + CallFrame::thisArgumentOffset();
    221         for (int i = opcodeID == op_construct ? 1 : 0; i < argCount; i++)
     221        for (int i = 0; i < argCount; i++)
    222222            functor(codeBlock, instruction, opcodeID, lastArg + i);
    223223        return;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r180587 r180595  
    15651565RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
    15661566{
    1567     RefPtr<RegisterID> func = newTemporary();
    1568 
    1569     m_codeBlock->addPropertyAccessInstruction(instructions().size());
    1570     emitOpcode(op_get_callee);
    1571     instructions().append(func->index());
    1572     instructions().append(0);
    1573 
    15741567    size_t begin = instructions().size();
    15751568    m_staticPropertyAnalyzer.createThis(m_thisRegister.index(), begin + 3);
     
    15771570    emitOpcode(op_create_this);
    15781571    instructions().append(m_thisRegister.index());
    1579     instructions().append(func->index());
     1572    instructions().append(m_thisRegister.index());
    15801573    instructions().append(0);
    15811574    return dst;
     
    18821875}
    18831876
    1884 RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
    1885 {
    1886     return emitCallVarargs(op_construct_varargs, dst, func, 0, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
     1877RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
     1878{
     1879    return emitCallVarargs(op_construct_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
    18871880}
    18881881   
     
    19801973            else
    19811974                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
    1982             return emitConstructVarargs(dst, func, argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
     1975            return emitConstructVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
    19831976        }
    19841977       
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r180332 r180595  
    668668        RegisterID* emitInitLazyRegister(RegisterID*);
    669669       
    670         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
     670        RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
    671671        RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
    672672        RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&, RegisterID*);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r180518 r180595  
    454454    RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
    455455    CallArguments callArguments(generator, m_args);
     456    generator.emitMove(callArguments.thisRegister(), func.get());
    456457    return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
    457458}
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r180587 r180595  
    186186    void handleVarargsCall(Instruction* pc, NodeType op, CodeSpecializationKind);
    187187    void emitFunctionChecks(CallVariant, Node* callTarget, VirtualRegister thisArgumnt);
    188     void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind);
     188    void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis);
    189189    unsigned inliningCost(CallVariant, int argumentCountIncludingThis, CodeSpecializationKind); // Return UINT_MAX if it's not an inlining candidate. By convention, intrinsics have a cost of 1.
    190190    // Handle inlining. Return true if it succeeded, false if we need to plant a call.
     
    695695            m_parameterSlots = parameterSlots;
    696696
    697         int dummyThisArgument = op == Call || op == NativeCall ? 0 : 1;
    698         for (int i = 0 + dummyThisArgument; i < argCount; ++i)
     697        for (int i = 0; i < argCount; ++i)
    699698            addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
    700699
     
    11421141    data->firstVarArgOffset = firstVarArgOffset;
    11431142   
    1144     Node* thisChild;
    1145     if (kind == CodeForCall)
    1146         thisChild = get(VirtualRegister(thisReg));
    1147     else
    1148         thisChild = nullptr;
     1143    Node* thisChild = get(VirtualRegister(thisReg));
    11491144   
    11501145    Node* call = addToGraph(op, OpInfo(data), OpInfo(prediction), callTarget, get(VirtualRegister(arguments)), thisChild);
     
    11761171}
    11771172
    1178 void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind kind)
     1173void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis)
    11791174{
    1180     for (int i = kind == CodeForCall ? 0 : 1; i < argumentCountIncludingThis; ++i)
     1175    for (int i = 0; i < argumentCountIncludingThis; ++i)
    11811176        addToGraph(Phantom, get(virtualRegisterForArgument(i, registerOffset)));
    11821177}
     
    14481443            RELEASE_ASSERT(didInsertChecks);
    14491444            addToGraph(Phantom, callTargetNode);
    1450             emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
     1445            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
    14511446            inliningBalance--;
    14521447            return true;
     
    14611456            RELEASE_ASSERT(didInsertChecks);
    14621457            addToGraph(Phantom, callTargetNode);
    1463             emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
     1458            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
    14641459            inliningBalance--;
    14651460            return true;
     
    15461541            argumentCountIncludingThis, nextOffset, kind, CallerDoesNormalLinking, prediction,
    15471542            inliningBalance, [&] (CodeBlock* codeBlock) {
    1548                 emitFunctionChecks(callLinkStatus[0], callTargetNode, specializationKind == CodeForCall ? thisArgument : VirtualRegister());
     1543                emitFunctionChecks(callLinkStatus[0], callTargetNode, thisArgument);
    15491544
    15501545                // If we have a varargs call, we want to extract the arguments right now.
     
    15801575                    Node* setArgumentCount = addToGraph(SetArgument, OpInfo(countVariable));
    15811576                    m_currentBlock->variablesAtTail.setOperand(countVariable->local(), setArgumentCount);
    1582            
    1583                     if (specializationKind == CodeForCall)
    1584                         set(VirtualRegister(argumentStart), get(thisArgument), ImmediateNakedSet);
     1577
     1578                    set(VirtualRegister(argumentStart), get(thisArgument), ImmediateNakedSet);
    15851579                    for (unsigned argument = 1; argument < maxNumArguments; ++argument) {
    15861580                        VariableAccessData* variable = newVariableAccessData(
     
    17631757        addToGraph(CheckBadCell);
    17641758        addToGraph(Phantom, myCallTargetNode);
    1765         emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
     1759        emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
    17661760       
    17671761        set(VirtualRegister(resultOperand), addToGraph(BottomValue));
     
    21512145        }
    21522146       
     2147        // FIXME: Array constructor should use "this" as newTarget.
    21532148        for (int i = 1; i < argumentCountIncludingThis; ++i)
    21542149            addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
     
    25892584            for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
    25902585                set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet);
    2591             if (m_inlineStackTop->m_codeBlock->specializationKind() == CodeForConstruct)
    2592                 set(virtualRegisterForArgument(0), undefined, ImmediateNakedSet);
    25932586            NEXT_OPCODE(op_enter);
    25942587        }
  • trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp

    r164229 r180595  
    8383   
    8484    result = Operands<JSValue>(OperandsLike, recoveries);
    85     for (size_t i = result.size(); i--;) {
    86         int operand = result.operandForIndex(i);
    87        
    88         if (codeOrigin == CodeOrigin(0)
    89             && operandIsArgument(operand)
    90             && !VirtualRegister(operand).toArgument()
    91             && codeBlock->codeType() == FunctionCode
    92             && codeBlock->specializationKind() == CodeForConstruct) {
    93             // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
    94             // also never be used. It doesn't matter what we put into the value for this,
    95             // but it has to be an actual value that can be grokked by subsequent DFG passes,
    96             // so we sanitize it here by turning it into Undefined.
    97             result[i] = jsUndefined();
    98             continue;
    99         }
    100        
     85    for (size_t i = result.size(); i--;)
    10186        result[i] = recoveries[i].recover(exec);
    102     }
    10387}
    10488
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r180587 r180595  
    641641{
    642642    CallLinkInfo::CallType callType;
    643     bool isCall;
    644643    bool isVarargs;
    645644    switch (node->op()) {
    646645    case Call:
    647646        callType = CallLinkInfo::Call;
    648         isCall = true;
    649647        isVarargs = false;
    650648        break;
    651649    case Construct:
    652650        callType = CallLinkInfo::Construct;
    653         isCall = false;
    654651        isVarargs = false;
    655652        break;
     
    657654    case CallForwardVarargs:
    658655        callType = CallLinkInfo::CallVarargs;
    659         isCall = true;
    660656        isVarargs = true;
    661657        break;
    662658    case ConstructVarargs:
    663659        callType = CallLinkInfo::ConstructVarargs;
    664         isCall = false;
    665660        isVarargs = true;
    666661        break;
     
    771766        if (node->op() != CallForwardVarargs)
    772767            use(node->child2());
    773        
    774         if (isCall) {
    775             // Now set up the "this" argument.
    776             JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
    777             GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
    778             GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
    779             thisArgument.use();
    780            
    781             m_jit.store32(thisArgumentTagGPR, JITCompiler::calleeArgumentTagSlot(0));
    782             m_jit.store32(thisArgumentPayloadGPR, JITCompiler::calleeArgumentPayloadSlot(0));
    783         }
    784     } else {
    785         // For constructors, the this argument is not passed but we have to make space
    786         // for it.
    787         int dummyThisArgument = isCall ? 0 : 1;
    788        
     768
     769        // Now set up the "this" argument.
     770        JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
     771        GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
     772        GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
     773        thisArgument.use();
     774       
     775        m_jit.store32(thisArgumentTagGPR, JITCompiler::calleeArgumentTagSlot(0));
     776        m_jit.store32(thisArgumentPayloadGPR, JITCompiler::calleeArgumentPayloadSlot(0));
     777    } else {       
    789778        // The call instruction's first child is either the function (normal call) or the
    790779        // receiver (method call). subsequent children are the arguments.
    791780        int numPassedArgs = node->numChildren() - 1;
    792        
    793         int numArgs = numPassedArgs + dummyThisArgument;
    794        
    795         m_jit.store32(MacroAssembler::TrustedImm32(numArgs), m_jit.calleeFramePayloadSlot(JSStack::ArgumentCount));
     781
     782        m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), m_jit.calleeFramePayloadSlot(JSStack::ArgumentCount));
    796783       
    797784        for (int i = 0; i < numPassedArgs; i++) {
     
    802789            use(argEdge);
    803790           
    804             m_jit.store32(argTagGPR, m_jit.calleeArgumentTagSlot(i + dummyThisArgument));
    805             m_jit.store32(argPayloadGPR, m_jit.calleeArgumentPayloadSlot(i + dummyThisArgument));
     791            m_jit.store32(argTagGPR, m_jit.calleeArgumentTagSlot(i));
     792            m_jit.store32(argPayloadGPR, m_jit.calleeArgumentPayloadSlot(i));
    806793        }
    807794    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r180587 r180595  
    627627{
    628628    CallLinkInfo::CallType callType;
    629     bool isCall;
    630629    bool isVarargs;
    631630    switch (node->op()) {
    632631    case Call:
    633632        callType = CallLinkInfo::Call;
    634         isCall = true;
    635633        isVarargs = false;
    636634        break;
    637635    case Construct:
    638636        callType = CallLinkInfo::Construct;
    639         isCall = false;
    640637        isVarargs = false;
    641638        break;
     
    643640    case CallForwardVarargs:
    644641        callType = CallLinkInfo::CallVarargs;
    645         isCall = true;
    646642        isVarargs = true;
    647643        break;
    648644    case ConstructVarargs:
    649645        callType = CallLinkInfo::ConstructVarargs;
    650         isCall = false;
    651646        isVarargs = true;
    652647        break;
     
    747742        if (node->op() != CallForwardVarargs)
    748743            use(node->child2());
    749        
    750         if (isCall) {
    751             // Now set up the "this" argument.
    752             JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
    753             GPRReg thisArgumentGPR = thisArgument.gpr();
    754             thisArgument.use();
    755            
    756             m_jit.store64(thisArgumentGPR, JITCompiler::calleeArgumentSlot(0));
    757         }
     744
     745        // Now set up the "this" argument.
     746        JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
     747        GPRReg thisArgumentGPR = thisArgument.gpr();
     748        thisArgument.use();
     749       
     750        m_jit.store64(thisArgumentGPR, JITCompiler::calleeArgumentSlot(0));
    758751    } else {
    759         // For constructors, the this argument is not passed but we have to make space
    760         // for it.
    761         int dummyThisArgument = isCall ? 0 : 1;
    762    
    763752        // The call instruction's first child is the function; the subsequent children are the
    764753        // arguments.
    765754        int numPassedArgs = node->numChildren() - 1;
    766    
    767         int numArgs = numPassedArgs + dummyThisArgument;
    768    
    769         m_jit.store32(MacroAssembler::TrustedImm32(numArgs), JITCompiler::calleeFramePayloadSlot(JSStack::ArgumentCount));
     755
     756        m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), JITCompiler::calleeFramePayloadSlot(JSStack::ArgumentCount));
    770757   
    771758        for (int i = 0; i < numPassedArgs; i++) {
     
    775762            use(argEdge);
    776763       
    777             m_jit.store64(argGPR, JITCompiler::calleeArgumentSlot(i + dummyThisArgument));
     764            m_jit.store64(argGPR, JITCompiler::calleeArgumentSlot(i));
    778765        }
    779766    }
  • trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp

    r180279 r180595  
    7070    // - The arguments object.
    7171    // - The "this" value, if it's a constructor call.
    72    
    73     bool isCall = m_node->op() != ConstructVarargs;
    74    
     72
    7573    CallVarargsData* data = m_node->callVarargsData();
    7674   
     
    9290    case ConstructVarargs:
    9391        argumentsGPR = GPRInfo::argumentGPR1;
     92        thisGPR = GPRInfo::argumentGPR2;
    9493        break;
    9594    default:
     
    111110    if (argumentsGPR != InvalidGPRReg)
    112111        usedRegisters.set(argumentsGPR);
    113     if (thisGPR != InvalidGPRReg)
    114         usedRegisters.set(thisGPR);
     112    ASSERT(thisGPR);
     113    usedRegisters.set(thisGPR);
    115114    ScratchRegisterAllocator allocator(usedRegisters);
    116115    GPRReg scratchGPR1 = allocator.allocateScratchGPR();
     
    183182    if (!argumentsOnStack)
    184183        jit.store64(argumentsGPR, CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot));
    185     if (isCall)
    186         jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
     184    jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
    187185   
    188186    unsigned extraStack = sizeof(CallerFrameAndPC) +
     
    202200   
    203201    jit.move(GPRInfo::returnValueGPR, scratchGPR2);
    204    
    205     if (isCall)
    206         jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
     202
     203    jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
    207204    jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0);
    208205   
     
    211208   
    212209    jit.addPtr(CCallHelpers::TrustedImm32(sizeof(CallerFrameAndPC)), scratchGPR2, CCallHelpers::stackPointerRegister);
    213    
    214     if (isCall)
    215         jit.store64(thisGPR, CCallHelpers::calleeArgumentSlot(0));
     210
     211    jit.store64(thisGPR, CCallHelpers::calleeArgumentSlot(0));
    216212   
    217213    // Henceforth we make the call. The base FTL call machinery expects the callee in regT0 and for the
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r180587 r180595  
    37673767    void compileNativeCallOrConstruct()
    37683768    {
    3769         int dummyThisArgument = m_node->op() == NativeCall ? 0 : 1;
    37703769        int numPassedArgs = m_node->numChildren() - 1;
    3771         int numArgs = numPassedArgs + dummyThisArgument;
     3770        int numArgs = numPassedArgs;
    37723771
    37733772        JSFunction* knownFunction = jsCast<JSFunction*>(m_node->cellOperand()->value().asCell());
     
    37903789        m_out.store64(m_out.constInt64(numArgs), addressFor(m_execStorage, JSStack::ArgumentCount));
    37913790
    3792         if (dummyThisArgument)
    3793             m_out.storePtr(getUndef(m_out.int64), addressFor(m_execStorage, JSStack::ThisArgument));
    3794        
    37953791        for (int i = 0; i < numPassedArgs; ++i) {
    37963792            m_out.storePtr(lowJSValue(m_graph.varArgChild(m_node, 1 + i)),
    3797                 addressFor(m_execStorage, dummyThisArgument ? JSStack::FirstArgument : JSStack::ThisArgument, i * sizeof(Register)));
     3793                addressFor(m_execStorage, JSStack::ThisArgument, i * sizeof(Register)));
    37983794        }
    37993795
     
    38183814    void compileCallOrConstruct()
    38193815    {
    3820         int dummyThisArgument = m_node->op() == Call ? 0 : 1;
    38213816        int numPassedArgs = m_node->numChildren() - 1;
    3822         int numArgs = numPassedArgs + dummyThisArgument;
     3817        int numArgs = numPassedArgs;
    38233818
    38243819        LValue jsCallee = lowJSValue(m_graph.varArgChild(m_node, 0));
     
    38353830        arguments.append(jsCallee); // callee -> stack
    38363831        arguments.append(m_out.constInt64(numArgs)); // argument count and zeros for the tag
    3837         if (dummyThisArgument)
    3838             arguments.append(getUndef(m_out.int64));
    38393832        for (int i = 0; i < numPassedArgs; ++i)
    38403833            arguments.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
     
    38673860        case ConstructVarargs:
    38683861            jsArguments = lowJSValue(m_node->child2());
     3862            thisArg = lowJSValue(m_node->child3());
    38693863            break;
    38703864        default:
     
    38793873        arguments.append(m_out.constInt32(sizeOfICFor(m_node)));
    38803874        arguments.append(constNull(m_out.ref8));
    3881         arguments.append(m_out.constInt32(1 + !!jsArguments + !!thisArg));
     3875        arguments.append(m_out.constInt32(2 + !!jsArguments));
    38823876        arguments.append(jsCallee);
    38833877        if (jsArguments)
    38843878            arguments.append(jsArguments);
    3885         if (thisArg)
    3886             arguments.append(thisArg);
     3879        ASSERT(thisArg);
     3880        arguments.append(thisArg);
    38873881       
    38883882        callPreflight();
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r180506 r180595  
    976976
    977977    ProtoCallFrame protoCallFrame;
    978     protoCallFrame.init(newCodeBlock, constructor, jsUndefined(), argsCount, args.data());
     978    protoCallFrame.init(newCodeBlock, constructor, constructor, argsCount, args.data());
    979979
    980980    if (LegacyProfiler* profiler = vm.enabledProfiler())
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r180514 r180595  
    11601160        for (size_t i = 0; i < mustHandleValues.size(); ++i) {
    11611161            int operand = mustHandleValues.operandForIndex(i);
    1162             if (operandIsArgument(operand)
    1163                 && !VirtualRegister(operand).toArgument()
    1164                 && codeBlock->codeType() == FunctionCode
    1165                 && codeBlock->specializationKind() == CodeForConstruct) {
    1166                 // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
    1167                 // also never be used. It doesn't matter what we put into the value for this,
    1168                 // but it has to be an actual value that can be grokked by subsequent DFG passes,
    1169                 // so we sanitize it here by turning it into Undefined.
    1170                 mustHandleValues[i] = jsUndefined();
    1171             } else
    1172                 mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
     1162            mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
    11731163        }
    11741164
Note: See TracChangeset for help on using the changeset viewer.