Changeset 180595 in webkit
- Timestamp:
- Feb 24, 2015 4:41:35 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r180594 r180595 1 2015-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 1 51 2015-02-24 Joseph Pecoraro <pecoraro@apple.com> 2 52 -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r180587 r180595 219 219 int registerOffset = -instruction[4].u.operand; 220 220 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++) 222 222 functor(codeBlock, instruction, opcodeID, lastArg + i); 223 223 return; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r180587 r180595 1565 1565 RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst) 1566 1566 { 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 1574 1567 size_t begin = instructions().size(); 1575 1568 m_staticPropertyAnalyzer.createThis(m_thisRegister.index(), begin + 3); … … 1577 1570 emitOpcode(op_create_this); 1578 1571 instructions().append(m_thisRegister.index()); 1579 instructions().append( func->index());1572 instructions().append(m_thisRegister.index()); 1580 1573 instructions().append(0); 1581 1574 return dst; … … 1882 1875 } 1883 1876 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);1877 RegisterID* 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); 1887 1880 } 1888 1881 … … 1980 1973 else 1981 1974 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); 1983 1976 } 1984 1977 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r180332 r180595 668 668 RegisterID* emitInitLazyRegister(RegisterID*); 669 669 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); 671 671 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); 672 672 RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&, RegisterID*); -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r180518 r180595 454 454 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get()); 455 455 CallArguments callArguments(generator, m_args); 456 generator.emitMove(callArguments.thisRegister(), func.get()); 456 457 return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd()); 457 458 } -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r180587 r180595 186 186 void handleVarargsCall(Instruction* pc, NodeType op, CodeSpecializationKind); 187 187 void emitFunctionChecks(CallVariant, Node* callTarget, VirtualRegister thisArgumnt); 188 void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis , CodeSpecializationKind);188 void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis); 189 189 unsigned inliningCost(CallVariant, int argumentCountIncludingThis, CodeSpecializationKind); // Return UINT_MAX if it's not an inlining candidate. By convention, intrinsics have a cost of 1. 190 190 // Handle inlining. Return true if it succeeded, false if we need to plant a call. … … 695 695 m_parameterSlots = parameterSlots; 696 696 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) 699 698 addVarArgChild(get(virtualRegisterForArgument(i, registerOffset))); 700 699 … … 1142 1141 data->firstVarArgOffset = firstVarArgOffset; 1143 1142 1144 Node* thisChild; 1145 if (kind == CodeForCall) 1146 thisChild = get(VirtualRegister(thisReg)); 1147 else 1148 thisChild = nullptr; 1143 Node* thisChild = get(VirtualRegister(thisReg)); 1149 1144 1150 1145 Node* call = addToGraph(op, OpInfo(data), OpInfo(prediction), callTarget, get(VirtualRegister(arguments)), thisChild); … … 1176 1171 } 1177 1172 1178 void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis , CodeSpecializationKind kind)1173 void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis) 1179 1174 { 1180 for (int i = kind == CodeForCall ? 0 : 1; i < argumentCountIncludingThis; ++i)1175 for (int i = 0; i < argumentCountIncludingThis; ++i) 1181 1176 addToGraph(Phantom, get(virtualRegisterForArgument(i, registerOffset))); 1182 1177 } … … 1448 1443 RELEASE_ASSERT(didInsertChecks); 1449 1444 addToGraph(Phantom, callTargetNode); 1450 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis , specializationKind);1445 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1451 1446 inliningBalance--; 1452 1447 return true; … … 1461 1456 RELEASE_ASSERT(didInsertChecks); 1462 1457 addToGraph(Phantom, callTargetNode); 1463 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis , specializationKind);1458 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1464 1459 inliningBalance--; 1465 1460 return true; … … 1546 1541 argumentCountIncludingThis, nextOffset, kind, CallerDoesNormalLinking, prediction, 1547 1542 inliningBalance, [&] (CodeBlock* codeBlock) { 1548 emitFunctionChecks(callLinkStatus[0], callTargetNode, specializationKind == CodeForCall ? thisArgument : VirtualRegister());1543 emitFunctionChecks(callLinkStatus[0], callTargetNode, thisArgument); 1549 1544 1550 1545 // If we have a varargs call, we want to extract the arguments right now. … … 1580 1575 Node* setArgumentCount = addToGraph(SetArgument, OpInfo(countVariable)); 1581 1576 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); 1585 1579 for (unsigned argument = 1; argument < maxNumArguments; ++argument) { 1586 1580 VariableAccessData* variable = newVariableAccessData( … … 1763 1757 addToGraph(CheckBadCell); 1764 1758 addToGraph(Phantom, myCallTargetNode); 1765 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis , specializationKind);1759 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1766 1760 1767 1761 set(VirtualRegister(resultOperand), addToGraph(BottomValue)); … … 2151 2145 } 2152 2146 2147 // FIXME: Array constructor should use "this" as newTarget. 2153 2148 for (int i = 1; i < argumentCountIncludingThis; ++i) 2154 2149 addVarArgChild(get(virtualRegisterForArgument(i, registerOffset))); … … 2589 2584 for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i) 2590 2585 set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet); 2591 if (m_inlineStackTop->m_codeBlock->specializationKind() == CodeForConstruct)2592 set(virtualRegisterForArgument(0), undefined, ImmediateNakedSet);2593 2586 NEXT_OPCODE(op_enter); 2594 2587 } -
trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp
r164229 r180595 83 83 84 84 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--;) 101 86 result[i] = recoveries[i].recover(exec); 102 }103 87 } 104 88 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r180587 r180595 641 641 { 642 642 CallLinkInfo::CallType callType; 643 bool isCall;644 643 bool isVarargs; 645 644 switch (node->op()) { 646 645 case Call: 647 646 callType = CallLinkInfo::Call; 648 isCall = true;649 647 isVarargs = false; 650 648 break; 651 649 case Construct: 652 650 callType = CallLinkInfo::Construct; 653 isCall = false;654 651 isVarargs = false; 655 652 break; … … 657 654 case CallForwardVarargs: 658 655 callType = CallLinkInfo::CallVarargs; 659 isCall = true;660 656 isVarargs = true; 661 657 break; 662 658 case ConstructVarargs: 663 659 callType = CallLinkInfo::ConstructVarargs; 664 isCall = false;665 660 isVarargs = true; 666 661 break; … … 771 766 if (node->op() != CallForwardVarargs) 772 767 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 { 789 778 // The call instruction's first child is either the function (normal call) or the 790 779 // receiver (method call). subsequent children are the arguments. 791 780 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)); 796 783 797 784 for (int i = 0; i < numPassedArgs; i++) { … … 802 789 use(argEdge); 803 790 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)); 806 793 } 807 794 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r180587 r180595 627 627 { 628 628 CallLinkInfo::CallType callType; 629 bool isCall;630 629 bool isVarargs; 631 630 switch (node->op()) { 632 631 case Call: 633 632 callType = CallLinkInfo::Call; 634 isCall = true;635 633 isVarargs = false; 636 634 break; 637 635 case Construct: 638 636 callType = CallLinkInfo::Construct; 639 isCall = false;640 637 isVarargs = false; 641 638 break; … … 643 640 case CallForwardVarargs: 644 641 callType = CallLinkInfo::CallVarargs; 645 isCall = true;646 642 isVarargs = true; 647 643 break; 648 644 case ConstructVarargs: 649 645 callType = CallLinkInfo::ConstructVarargs; 650 isCall = false;651 646 isVarargs = true; 652 647 break; … … 747 742 if (node->op() != CallForwardVarargs) 748 743 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)); 758 751 } else { 759 // For constructors, the this argument is not passed but we have to make space760 // for it.761 int dummyThisArgument = isCall ? 0 : 1;762 763 752 // The call instruction's first child is the function; the subsequent children are the 764 753 // arguments. 765 754 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)); 770 757 771 758 for (int i = 0; i < numPassedArgs; i++) { … … 775 762 use(argEdge); 776 763 777 m_jit.store64(argGPR, JITCompiler::calleeArgumentSlot(i + dummyThisArgument));764 m_jit.store64(argGPR, JITCompiler::calleeArgumentSlot(i)); 778 765 } 779 766 } -
trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp
r180279 r180595 70 70 // - The arguments object. 71 71 // - The "this" value, if it's a constructor call. 72 73 bool isCall = m_node->op() != ConstructVarargs; 74 72 75 73 CallVarargsData* data = m_node->callVarargsData(); 76 74 … … 92 90 case ConstructVarargs: 93 91 argumentsGPR = GPRInfo::argumentGPR1; 92 thisGPR = GPRInfo::argumentGPR2; 94 93 break; 95 94 default: … … 111 110 if (argumentsGPR != InvalidGPRReg) 112 111 usedRegisters.set(argumentsGPR); 113 if (thisGPR != InvalidGPRReg)114 112 ASSERT(thisGPR); 113 usedRegisters.set(thisGPR); 115 114 ScratchRegisterAllocator allocator(usedRegisters); 116 115 GPRReg scratchGPR1 = allocator.allocateScratchGPR(); … … 183 182 if (!argumentsOnStack) 184 183 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)); 187 185 188 186 unsigned extraStack = sizeof(CallerFrameAndPC) + … … 202 200 203 201 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); 207 204 jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0); 208 205 … … 211 208 212 209 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)); 216 212 217 213 // 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 3767 3767 void compileNativeCallOrConstruct() 3768 3768 { 3769 int dummyThisArgument = m_node->op() == NativeCall ? 0 : 1;3770 3769 int numPassedArgs = m_node->numChildren() - 1; 3771 int numArgs = numPassedArgs + dummyThisArgument;3770 int numArgs = numPassedArgs; 3772 3771 3773 3772 JSFunction* knownFunction = jsCast<JSFunction*>(m_node->cellOperand()->value().asCell()); … … 3790 3789 m_out.store64(m_out.constInt64(numArgs), addressFor(m_execStorage, JSStack::ArgumentCount)); 3791 3790 3792 if (dummyThisArgument)3793 m_out.storePtr(getUndef(m_out.int64), addressFor(m_execStorage, JSStack::ThisArgument));3794 3795 3791 for (int i = 0; i < numPassedArgs; ++i) { 3796 3792 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))); 3798 3794 } 3799 3795 … … 3818 3814 void compileCallOrConstruct() 3819 3815 { 3820 int dummyThisArgument = m_node->op() == Call ? 0 : 1;3821 3816 int numPassedArgs = m_node->numChildren() - 1; 3822 int numArgs = numPassedArgs + dummyThisArgument;3817 int numArgs = numPassedArgs; 3823 3818 3824 3819 LValue jsCallee = lowJSValue(m_graph.varArgChild(m_node, 0)); … … 3835 3830 arguments.append(jsCallee); // callee -> stack 3836 3831 arguments.append(m_out.constInt64(numArgs)); // argument count and zeros for the tag 3837 if (dummyThisArgument)3838 arguments.append(getUndef(m_out.int64));3839 3832 for (int i = 0; i < numPassedArgs; ++i) 3840 3833 arguments.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i))); … … 3867 3860 case ConstructVarargs: 3868 3861 jsArguments = lowJSValue(m_node->child2()); 3862 thisArg = lowJSValue(m_node->child3()); 3869 3863 break; 3870 3864 default: … … 3879 3873 arguments.append(m_out.constInt32(sizeOfICFor(m_node))); 3880 3874 arguments.append(constNull(m_out.ref8)); 3881 arguments.append(m_out.constInt32( 1 + !!jsArguments + !!thisArg));3875 arguments.append(m_out.constInt32(2 + !!jsArguments)); 3882 3876 arguments.append(jsCallee); 3883 3877 if (jsArguments) 3884 3878 arguments.append(jsArguments); 3885 if (thisArg)3886 3879 ASSERT(thisArg); 3880 arguments.append(thisArg); 3887 3881 3888 3882 callPreflight(); -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r180506 r180595 976 976 977 977 ProtoCallFrame protoCallFrame; 978 protoCallFrame.init(newCodeBlock, constructor, jsUndefined(), argsCount, args.data());978 protoCallFrame.init(newCodeBlock, constructor, constructor, argsCount, args.data()); 979 979 980 980 if (LegacyProfiler* profiler = vm.enabledProfiler()) -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r180514 r180595 1160 1160 for (size_t i = 0; i < mustHandleValues.size(); ++i) { 1161 1161 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(); 1173 1163 } 1174 1164
Note: See TracChangeset
for help on using the changeset viewer.