summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/interpreter')
-rw-r--r--JavaScriptCore/interpreter/CallFrame.cpp5
-rw-r--r--JavaScriptCore/interpreter/CallFrame.h33
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp199
-rw-r--r--JavaScriptCore/interpreter/Interpreter.h2
-rw-r--r--JavaScriptCore/interpreter/Register.h22
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;
}