return false;
}
-ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argv, int argc, int calledAsConstructor, JSValue* function)
+ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argv, int argc, JSValue* function)
{
callFrame[RegisterFile::CallerCodeBlock] = codeBlock;
callFrame[RegisterFile::ReturnVPC] = vPC + 1;
callFrame[RegisterFile::ReturnValueRegister] = returnValueRegister;
callFrame[RegisterFile::ArgumentStartRegister] = argv; // original argument vector (for the sake of the "arguments" object)
callFrame[RegisterFile::ArgumentCount] = argc; // original argument count (for the sake of the "arguments" object)
- callFrame[RegisterFile::CalledAsConstructor] = calledAsConstructor;
callFrame[RegisterFile::Callee] = function;
callFrame[RegisterFile::OptionalCalleeActivation] = nullJSValue;
}
printf("[ReturnValueRegister] | %10p | %10p \n", it, (*it).v()); ++it;
printf("[ArgumentStartRegister] | %10p | %10p \n", it, (*it).v()); ++it;
printf("[ArgumentCount] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[CalledAsConstructor] | %10p | %10p \n", it, (*it).v()); ++it;
printf("[Callee] | %10p | %10p \n", it, (*it).v()); ++it;
printf("[OptionalCalleeActivation] | %10p | %10p \n", it, (*it).v()); ++it;
printf("----------------------------------------------------\n");
Register* callFrame = m_registerFile.base() + oldSize;
// a 0 codeBlock indicates a built-in caller
- initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0);
Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
r[codeBlock->thisRegister] = thisObj;
(*++dst) = *it;
// a 0 codeBlock indicates a built-in caller
- initializeCallFrame(callFrame, 0, 0, 0, callFrame, 0, argv, argc, 0, function);
+ initializeCallFrame(callFrame, 0, 0, 0, callFrame, 0, argv, argc, function);
CodeBlock* newCodeBlock = &functionBodyNode->byteCode(scopeChain);
Register* r = slideRegisterWindowForCall(exec, newCodeBlock, &m_registerFile, m_registerFile.base(), callFrame, argv, argc, *exception);
Register* callFrame = m_registerFile.base() + registerOffset;
// a 0 codeBlock indicates a built-in caller
- initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0);
Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
r[codeBlock->thisRegister] = thisObj;
(*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
- initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, 0, v);
+ initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, v);
exec->m_callFrame = callFrame;
if (callType == CallTypeJS) {
scopeChain->deref();
JSValue* returnValue = r[result].jsValue(exec);
- if (callFrame[RegisterFile::CalledAsConstructor].i() && !returnValue->isObject()) {
- JSValue* thisObject = callFrame[RegisterFile::CallFrameHeaderSize].jsValue(exec);
- returnValue = thisObject;
- }
codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
if (!codeBlock)
r[firstArg] = newObject; // "this" value
Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
- initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, 1, constructor);
+ initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, constructor);
exec->m_callFrame = callFrame;
r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
exceptionValue = createNotAConstructorError(exec, constrVal, vPC, codeBlock);
goto vm_throw;
}
+ BEGIN_OPCODE(op_construct_verify) {
+ /* construct_verify dst(r) override(r)
+
+ Verifies that register dst holds an object. If not, moves
+ the object in register override to register dst.
+ */
+
+ int dst = vPC[1].u.operand;;
+ if (LIKELY(r[dst].jsValue(exec)->isObject())) {
+ vPC += 3;
+ NEXT_OPCODE;
+ }
+
+ int override = vPC[2].u.operand;
+ r[dst] = r[override];
+
+ vPC += 3;
+ NEXT_OPCODE;
+ }
BEGIN_OPCODE(op_push_scope) {
/* push_scope scope(r)
r[firstArg] = thisValue;
Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
- machine->initializeCallFrame(callFrame, codeBlock, ARG_instr5, scopeChain, r, 0/*dst*/, firstArg, argCount, 0, funcVal);
+ machine->initializeCallFrame(callFrame, codeBlock, ARG_instr5, scopeChain, r, 0/*dst*/, firstArg, argCount, funcVal);
exec->m_callFrame = callFrame;
r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
Register* oldCallFrame = exec->m_callFrame;
Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
- machine->initializeCallFrame(callFrame, codeBlock, ARG_instr5, scopeChain, r, 0/*dst*/, firstArg, argCount, 0, funcVal);
+ machine->initializeCallFrame(callFrame, codeBlock, ARG_instr5, scopeChain, r, 0/*dst*/, firstArg, argCount, funcVal);
exec->m_callFrame = callFrame;
if (*ARG_profilerReference)
if (codeBlock->needsFullScopeChain)
scopeChain->deref();
- JSValue* returnValue = ARG_src1;
- if (callFrame[RegisterFile::CalledAsConstructor].i() && !returnValue->isObject()) {
- JSValue* thisObject = callFrame[RegisterFile::CallFrameHeaderSize].jsValue(exec);
- returnValue = thisObject;
- }
-
codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
if (codeBlock) {
machine->setScopeChain(exec, scopeChain, callFrame[RegisterFile::CallerScopeChain].scopeChain());
ARG_setCodeBlock(codeBlock);
ARG_setR(r);
- return returnValue;
+ return ARG_src1;
}
JSValue* Machine::cti_op_new_array(CTI_ARGS)
r[firstArg] = newObject; // "this" value
Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
- machine->initializeCallFrame(callFrame, codeBlock, ARG_instr4, scopeChain, r, 0/*dst*/, firstArg, argCount, 1, constructor);
+ machine->initializeCallFrame(callFrame, codeBlock, ARG_instr4, scopeChain, r, 0/*dst*/, firstArg, argCount, constructor);
exec->m_callFrame = callFrame;
r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
return codeBlock->ctiCode;
}
+void Machine::cti_op_construct_verify(CTI_ARGS)
+{
+ ExecState* exec = ARG_exec;
+ Register* r = ARG_r;
+ int dst = ARG_int1;
+
+ if (LIKELY(r[dst].jsValue(exec)->isObject()))
+ return;
+
+ int override = ARG_int2;
+ r[dst] = r[override];
+}
+
JSValue* Machine::cti_op_construct_NotJSConstruct(CTI_ARGS)
{
ExecState* exec = ARG_exec;
Register* oldCallFrame = exec->m_callFrame;
Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
- machine->initializeCallFrame(callFrame, codeBlock, ARG_instr5, scopeChain, r, 0/*dst*/, firstArg, argCount, 1, constrVal);
+ machine->initializeCallFrame(callFrame, codeBlock, ARG_instr5, scopeChain, r, 0/*dst*/, firstArg, argCount, constrVal);
exec->m_callFrame = callFrame;
if (*ARG_profilerReference)