diff options
Diffstat (limited to 'JavaScriptCore/interpreter')
| -rw-r--r-- | JavaScriptCore/interpreter/CallFrame.cpp | 5 | ||||
| -rw-r--r-- | JavaScriptCore/interpreter/CallFrame.h | 33 | ||||
| -rw-r--r-- | JavaScriptCore/interpreter/Interpreter.cpp | 199 | ||||
| -rw-r--r-- | JavaScriptCore/interpreter/Interpreter.h | 2 | ||||
| -rw-r--r-- | JavaScriptCore/interpreter/Register.h | 22 |
5 files changed, 159 insertions, 102 deletions
diff --git a/JavaScriptCore/interpreter/CallFrame.cpp b/JavaScriptCore/interpreter/CallFrame.cpp index 9724875..f53e6f4 100644 --- a/JavaScriptCore/interpreter/CallFrame.cpp +++ b/JavaScriptCore/interpreter/CallFrame.cpp @@ -31,11 +31,6 @@ namespace JSC { -JSValue CallFrame::thisValue() -{ - return this[codeBlock()->thisRegister()].jsValue(); -} - #ifndef NDEBUG void CallFrame::dumpCaller() { diff --git a/JavaScriptCore/interpreter/CallFrame.h b/JavaScriptCore/interpreter/CallFrame.h index a875119..2a7bce2 100644 --- a/JavaScriptCore/interpreter/CallFrame.h +++ b/JavaScriptCore/interpreter/CallFrame.h @@ -38,16 +38,13 @@ namespace JSC { // Passed as the first argument to most functions. class ExecState : private Register { public: - JSFunction* callee() const { return this[RegisterFile::Callee].function(); } + JSObject* callee() const { return this[RegisterFile::Callee].function(); } CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); } ScopeChainNode* scopeChain() const { ASSERT(this[RegisterFile::ScopeChain].Register::scopeChain()); return this[RegisterFile::ScopeChain].Register::scopeChain(); } - int argumentCount() const { return this[RegisterFile::ArgumentCount].i(); } - - JSValue thisValue(); // Global object in which execution began. JSGlobalObject* dynamicGlobalObject(); @@ -118,32 +115,46 @@ namespace JSC { void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; } ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, - CallFrame* callerFrame, int, int argc, JSFunction* function) + CallFrame* callerFrame, int argc, JSObject* callee) { ASSERT(callerFrame); // Use noCaller() rather than 0 for the outer host call frame caller. setCodeBlock(codeBlock); setScopeChain(scopeChain); setCallerFrame(callerFrame); - static_cast<Register*>(this)[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. - setArgumentCount(argc); // original argument count (for the sake of the "arguments" object) - setCallee(function); + setReturnPC(vPC); // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. + setArgumentCountIncludingThis(argc); // original argument count (for the sake of the "arguments" object) + setCallee(callee); } // Read a register from the codeframe (or constant from the CodeBlock). inline Register& r(int); + // Access to arguments. + int hostThisRegister() { return -RegisterFile::CallFrameHeaderSize - argumentCountIncludingThis(); } + JSValue hostThisValue() { return this[hostThisRegister()].jsValue(); } + size_t argumentCount() const { return argumentCountIncludingThis() - 1; } + size_t argumentCountIncludingThis() const { return this[RegisterFile::ArgumentCount].i(); } + JSValue argument(int argumentNumber) + { + int argumentIndex = -RegisterFile::CallFrameHeaderSize - this[RegisterFile::ArgumentCount].i() + argumentNumber + 1; + if (argumentIndex >= -RegisterFile::CallFrameHeaderSize) + return jsUndefined(); + return this[argumentIndex].jsValue(); + } + static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); } bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; } CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); } CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); } - private: - void setArgumentCount(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount] = Register::withInt(count); } - void setCallee(JSFunction* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = callee; } + void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount] = Register::withInt(count); } + void setCallee(JSObject* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = Register::withCallee(callee); } void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; } + void setReturnPC(void* value) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = (Instruction*)value; } + private: static const intptr_t HostCallFrameFlag = 1; ExecState(); diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index 1fbc9b7..12ac323 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/JavaScriptCore/interpreter/Interpreter.cpp @@ -375,7 +375,7 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r JSValue result = jsUndefined(); if (eval) - result = callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue); + result = callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->r(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue); return result; } @@ -628,8 +628,10 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV return 0; } - // Now unwind the scope chain within the exception handler's call frame. + // Shrink the JS stack, in case stack overflow made it huge. + m_registerFile.shrink(callFrame->registers() + callFrame->codeBlock()->m_numCalleeRegisters); + // Unwind the scope chain within the exception handler's call frame. ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChain sc(scopeChain); int scopeDelta = depth(codeBlock, sc) - handler->scopeDepth; @@ -661,19 +663,20 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S return jsNull(); } - DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); - JSGlobalObject* lastGlobalObject = m_registerFile.globalObject(); JSGlobalObject* globalObject = callFrame->dynamicGlobalObject(); globalObject->copyGlobalsTo(m_registerFile); CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize); - newCallFrame->r(codeBlock->thisRegister()) = JSValue(thisObj); - newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), 0, 0, 0); + ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. + newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->m_numParameters, 0); + newCallFrame->r(newCallFrame->hostThisRegister()) = JSValue(thisObj); if (codeBlock->needsFullScopeChain()) scopeChain->ref(); + DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); + Profiler** profiler = Profiler::enabledProfilerReference(); if (*profiler) (*profiler)->willExecute(newCallFrame, program->sourceURL(), program->lineNo()); @@ -702,9 +705,9 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S return result; } -JSValue Interpreter::executeCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception) +JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, JSValue* exception) { - ASSERT(!scopeChain->globalData->exception); + ASSERT(!callFrame->hadException()); if (m_reentryDepth >= MaxSmallThreadReentryDepth) { if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) { @@ -714,51 +717,79 @@ JSValue Interpreter::executeCall(FunctionExecutable* functionExecutable, CallFra } Register* oldEnd = m_registerFile.end(); - int argc = 1 + args.size(); // implicit "this" parameter + int argCount = 1 + args.size(); // implicit "this" parameter + size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; - if (!m_registerFile.grow(oldEnd + argc)) { + if (!m_registerFile.grow(oldEnd + registerOffset)) { *exception = createStackOverflowError(callFrame); return jsNull(); } - DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); - CallFrame* newCallFrame = CallFrame::create(oldEnd); size_t dst = 0; - newCallFrame->r(0) = JSValue(thisObj); + newCallFrame->r(0) = thisValue; ArgList::const_iterator end = args.end(); for (ArgList::const_iterator it = args.begin(); it != end; ++it) newCallFrame->r(++dst) = *it; - CodeBlock* codeBlock = &functionExecutable->bytecodeForCall(callFrame, scopeChain); - newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); - if (UNLIKELY(!newCallFrame)) { - *exception = createStackOverflowError(callFrame); + if (callType == CallTypeJS) { + ScopeChainNode* callDataScopeChain = callData.js.scopeChain; + CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecodeForCall(callFrame, callDataScopeChain); + + newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount); + if (UNLIKELY(!newCallFrame)) { + *exception = createStackOverflowError(callFrame); + m_registerFile.shrink(oldEnd); + return jsNull(); + } + + newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function); + + DynamicGlobalObjectScope globalObjectScope(newCallFrame, callDataScopeChain->globalObject); + + Profiler** profiler = Profiler::enabledProfilerReference(); + if (*profiler) + (*profiler)->willExecute(newCallFrame, function); + + JSValue result; + { + SamplingTool::CallRecord callRecord(m_sampler.get()); + + m_reentryDepth++; + #if ENABLE(JIT) + result = callData.js.functionExecutable->jitCodeForCall(newCallFrame, callDataScopeChain).execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData, exception); + #else + result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); + #endif + m_reentryDepth--; + } + + if (*profiler) + (*profiler)->didExecute(newCallFrame, function); + m_registerFile.shrink(oldEnd); - return jsNull(); + return result; } - // a 0 codeBlock indicates a built-in caller - newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function); + + ASSERT(callType == CallTypeHost); + ScopeChainNode* scopeChain = callFrame->scopeChain(); + newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset); + newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function); + + DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject); Profiler** profiler = Profiler::enabledProfilerReference(); if (*profiler) - (*profiler)->willExecute(callFrame, function); + (*profiler)->willExecute(newCallFrame, function); JSValue result; { - SamplingTool::CallRecord callRecord(m_sampler.get()); - - m_reentryDepth++; -#if ENABLE(JIT) - result = functionExecutable->jitCodeForCall(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); -#else - result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); -#endif - m_reentryDepth--; + SamplingTool::HostCallRecord callRecord(m_sampler.get()); + result = callData.native.function(newCallFrame); } if (*profiler) - (*profiler)->didExecute(callFrame, function); + (*profiler)->didExecute(newCallFrame, function); m_registerFile.shrink(oldEnd); return result; @@ -783,8 +814,6 @@ JSValue Interpreter::executeConstruct(FunctionExecutable* functionExecutable, Ca return jsNull(); } - DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); - CallFrame* newCallFrame = CallFrame::create(oldEnd); size_t dst = 0; newCallFrame->r(0) = JSValue(thisObj); @@ -800,7 +829,9 @@ JSValue Interpreter::executeConstruct(FunctionExecutable* functionExecutable, Ca return jsNull(); } // a 0 codeBlock indicates a built-in caller - newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function); + newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function); + + DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); Profiler** profiler = Profiler::enabledProfilerReference(); if (*profiler) @@ -858,7 +889,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE return CallFrameClosure(); } // a 0 codeBlock indicates a built-in caller - newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function); + newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function); #if ENABLE(JIT) FunctionExecutable->jitCodeForCall(newCallFrame, scopeChain); #endif @@ -957,8 +988,9 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset); // a 0 codeBlock indicates a built-in caller - newCallFrame->r(codeBlock->thisRegister()) = JSValue(thisObj); - newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, 0, 0); + ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. + newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->m_numParameters, 0); + newCallFrame->r(newCallFrame->hostThisRegister()) = JSValue(thisObj); if (codeBlock->needsFullScopeChain()) scopeChain->ref(); @@ -2938,7 +2970,7 @@ skip_id_custom_self: JSValue result; int offset = 0; if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) { - callFrame->r(dst) = asObject(baseValue)->getDirectOffset(offset); + callFrame->r(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset)); vPC += OPCODE_LENGTH(op_get_by_pname); NEXT_INSTRUCTION(); } @@ -3577,7 +3609,7 @@ skip_id_custom_self: goto vm_throw; } - callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScopeChain, previousCallFrame, 0, argCount, asFunction(v)); + callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); codeBlock = newCodeBlock; ASSERT(codeBlock == callFrame->codeBlock()); vPC = newCodeBlock->instructions().begin(); @@ -3592,20 +3624,15 @@ skip_id_custom_self: if (callType == CallTypeHost) { ScopeChainNode* scopeChain = callFrame->scopeChain(); CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); - newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scopeChain, callFrame, 0, argCount, 0); + newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scopeChain, callFrame, argCount, asObject(v)); Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount; ArgList args(thisRegister + 1, argCount - 1); - // FIXME: All host methods should be calling toThisObject, but this is not presently the case. - JSValue thisValue = thisRegister->jsValue(); - if (thisValue == jsNull()) - thisValue = callFrame->globalThisValue(); - JSValue returnValue; { SamplingTool::HostCallRecord callRecord(m_sampler.get()); - returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args); + returnValue = callData.native.function(newCallFrame); } CHECK_FOR_EXCEPTION(); @@ -3627,15 +3654,15 @@ skip_id_custom_self: JSValue arguments = callFrame->r(argsOffset).jsValue(); int32_t argCount = 0; if (!arguments) { - argCount = (uint32_t)(callFrame->argumentCount()) - 1; + argCount = (uint32_t)(callFrame->argumentCount()); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { exceptionValue = createStackOverflowError(callFrame); goto vm_throw; } - ASSERT(!callFrame->callee()->isHostFunction()); - int32_t expectedParams = callFrame->callee()->jsExecutable()->parameterCount(); + ASSERT(!asFunction(callFrame->callee())->isHostFunction()); + int32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount(); int32_t inplaceArgs = min(argCount, expectedParams); int32_t i = 0; Register* argStore = callFrame->registers() + argsOffset; @@ -3732,7 +3759,7 @@ skip_id_custom_self: goto vm_throw; } - callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScopeChain, previousCallFrame, 0, argCount, asFunction(v)); + callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); codeBlock = newCodeBlock; ASSERT(codeBlock == callFrame->codeBlock()); vPC = newCodeBlock->instructions().begin(); @@ -3747,20 +3774,15 @@ skip_id_custom_self: if (callType == CallTypeHost) { ScopeChainNode* scopeChain = callFrame->scopeChain(); CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); - newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scopeChain, callFrame, 0, argCount, 0); + newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scopeChain, callFrame, argCount, asObject(v)); Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount; ArgList args(thisRegister + 1, argCount - 1); - // FIXME: All host methods should be calling toThisObject, but this is not presently the case. - JSValue thisValue = thisRegister->jsValue(); - if (thisValue == jsNull()) - thisValue = callFrame->globalThisValue(); - JSValue returnValue; { SamplingTool::HostCallRecord callRecord(m_sampler.get()); - returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args); + returnValue = callData.native.function(newCallFrame); } CHECK_FOR_EXCEPTION(); @@ -3883,7 +3905,7 @@ skip_id_custom_self: vPC = callFrame->returnPC(); callFrame = callFrame->callerFrame(); - + if (callFrame->hasHostCallFrameFlag()) return returnValue; @@ -3930,6 +3952,46 @@ skip_id_custom_self: vPC += OPCODE_LENGTH(op_enter_with_activation); NEXT_INSTRUCTION(); } + DEFINE_OPCODE(op_get_callee) { + /* op_get_callee callee(r) + + Move callee into a register. + */ + + callFrame->r(vPC[1].u.operand) = JSValue(callFrame->callee()); + + vPC += OPCODE_LENGTH(op_get_callee); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(op_create_this) { + /* op_create_this this(r) proto(r) + + Allocate an object as 'this', fr use in construction. + + This opcode should only be used at the beginning of a code + block. + */ + + int thisRegister = vPC[1].u.operand; + int protoRegister = vPC[2].u.operand; + + JSFunction* constructor = asFunction(callFrame->callee()); +#if !ASSERT_DISABLED + ConstructData constructData; + ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS); +#endif + + Structure* structure; + JSValue proto = callFrame->r(protoRegister).jsValue(); + if (proto.isObject()) + structure = asObject(proto)->inheritorID(); + else + structure = constructor->scope().node()->globalObject->emptyObjectStructure(); + callFrame->r(thisRegister) = JSValue(new (&callFrame->globalData()) JSObject(structure)); + + vPC += OPCODE_LENGTH(op_create_this); + NEXT_INSTRUCTION(); + } DEFINE_OPCODE(op_convert_this) { /* convert_this this(r) @@ -4000,8 +4062,6 @@ skip_id_custom_self: int func = vPC[1].u.operand; int argCount = vPC[2].u.operand; int registerOffset = vPC[3].u.operand; - int proto = vPC[4].u.operand; - int thisRegister = vPC[5].u.operand; JSValue v = callFrame->r(func).jsValue(); @@ -4012,16 +4072,6 @@ skip_id_custom_self: ScopeChainNode* callDataScopeChain = constructData.js.scopeChain; CodeBlock* newCodeBlock = &constructData.js.functionExecutable->bytecodeForConstruct(callFrame, callDataScopeChain); - Structure* structure; - JSValue prototype = callFrame->r(proto).jsValue(); - if (prototype.isObject()) - structure = asObject(prototype)->inheritorID(); - else - structure = callDataScopeChain->globalObject->emptyObjectStructure(); - JSObject* newObject = new (globalData) JSObject(structure); - - callFrame->r(thisRegister) = JSValue(newObject); // "this" value - CallFrame* previousCallFrame = callFrame; callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); @@ -4031,7 +4081,7 @@ skip_id_custom_self: goto vm_throw; } - callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScopeChain, previousCallFrame, 0, argCount, asFunction(v)); + callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); codeBlock = newCodeBlock; vPC = newCodeBlock->instructions().begin(); @@ -4043,11 +4093,12 @@ skip_id_custom_self: } if (constructType == ConstructTypeHost) { - ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1); - ScopeChainNode* scopeChain = callFrame->scopeChain(); CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); - newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scopeChain, callFrame, 0, argCount, 0); + newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scopeChain, callFrame, argCount, 0); + + Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount; + ArgList args(thisRegister + 1, argCount - 1); JSValue returnValue; { diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h index 3572617..13df468 100644 --- a/JavaScriptCore/interpreter/Interpreter.h +++ b/JavaScriptCore/interpreter/Interpreter.h @@ -95,7 +95,7 @@ namespace JSC { bool isOpcode(Opcode); JSValue execute(ProgramExecutable*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue* exception); - JSValue executeCall(FunctionExecutable*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue* exception); + JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&, JSValue* exception); JSValue executeConstruct(FunctionExecutable*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue* exception); JSValue execute(EvalExecutable* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception); diff --git a/JavaScriptCore/interpreter/Register.h b/JavaScriptCore/interpreter/Register.h index 723112e..38d1647 100644 --- a/JavaScriptCore/interpreter/Register.h +++ b/JavaScriptCore/interpreter/Register.h @@ -39,7 +39,7 @@ namespace JSC { class CodeBlock; class ExecState; class JSActivation; - class JSFunction; + class JSObject; class JSPropertyNameIterator; class ScopeChainNode; @@ -58,7 +58,6 @@ namespace JSC { Register& operator=(JSActivation*); Register& operator=(CallFrame*); Register& operator=(CodeBlock*); - Register& operator=(JSFunction*); Register& operator=(JSPropertyNameIterator*); Register& operator=(ScopeChainNode*); Register& operator=(Instruction*); @@ -67,7 +66,7 @@ namespace JSC { JSActivation* activation() const; CallFrame* callFrame() const; CodeBlock* codeBlock() const; - JSFunction* function() const; + JSObject* function() const; JSPropertyNameIterator* propertyNameIterator() const; ScopeChainNode* scopeChain() const; Instruction* vPC() const; @@ -79,6 +78,13 @@ namespace JSC { return r; } + static Register withCallee(JSObject* callee) + { + Register r; + r.u.function = callee; + return r; + } + private: union { int32_t i; @@ -87,7 +93,7 @@ namespace JSC { JSActivation* activation; CallFrame* callFrame; CodeBlock* codeBlock; - JSFunction* function; + JSObject* function; JSPropertyNameIterator* propertyNameIterator; ScopeChainNode* scopeChain; Instruction* vPC; @@ -143,12 +149,6 @@ namespace JSC { return *this; } - ALWAYS_INLINE Register& Register::operator=(JSFunction* function) - { - u.function = function; - return *this; - } - ALWAYS_INLINE Register& Register::operator=(Instruction* vPC) { u.vPC = vPC; @@ -187,7 +187,7 @@ namespace JSC { return u.codeBlock; } - ALWAYS_INLINE JSFunction* Register::function() const + ALWAYS_INLINE JSObject* Register::function() const { return u.function; } |
