summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/interpreter/Interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/interpreter/Interpreter.cpp')
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp308
1 files changed, 140 insertions, 168 deletions
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index 632571d..68be9fa 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -283,7 +283,7 @@ NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vP
bool isStrictPut = vPC[3].u.operand;
Identifier ident = callFrame->codeBlock()->identifier(property);
JSValue result = JSC::resolveBase(callFrame, ident, callFrame->scopeChain(), isStrictPut);
- if (!result) {
+ if (result) {
callFrame->r(dst) = result;
ASSERT(callFrame->r(dst).jsValue());
} else
@@ -383,7 +383,7 @@ static NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, CodeB
}
#endif
-NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValue& exceptionValue)
+NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset)
{
if (argc < 2)
return jsUndefined();
@@ -407,13 +407,14 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
}
ScopeChainNode* scopeChain = callFrame->scopeChain();
+ JSValue exceptionValue;
RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
- JSValue result = jsUndefined();
- if (eval)
- result = callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->r(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
+ ASSERT(!eval == exceptionValue);
+ if (UNLIKELY(!eval))
+ return throwError(callFrame, exceptionValue);
- return result;
+ return callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->r(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain);
}
Interpreter::Interpreter()
@@ -421,7 +422,7 @@ Interpreter::Interpreter()
, m_reentryDepth(0)
{
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
- privateExecute(InitializeAndReturn, 0, 0, 0);
+ privateExecute(InitializeAndReturn, 0, 0);
for (int i = 0; i < numOpcodeIDs; ++i)
m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
@@ -448,7 +449,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
printf("-----------------------------------------------------------------------------\n");
CodeBlock* codeBlock = callFrame->codeBlock();
- RegisterFile* registerFile = &callFrame->scopeChain()->globalObject->globalData()->interpreter->registerFile();
+ RegisterFile* registerFile = &callFrame->scopeChain()->globalObject->globalData().interpreter->registerFile();
const Register* it;
const Register* end;
JSValue v;
@@ -676,8 +677,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
}
// Shrink the JS stack, in case stack overflow made it huge.
- Register* highWaterMark = callFrame->registers() + callFrame->codeBlock()->m_numCalleeRegisters;
- for (CallFrame* callerFrame = callFrame->callerFrame()->removeHostCallFrameFlag(); callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) {
+ Register* highWaterMark = 0;
+ for (CallFrame* callerFrame = callFrame; callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) {
CodeBlock* codeBlock = callerFrame->codeBlock();
if (!codeBlock)
continue;
@@ -701,30 +702,34 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
return handler;
}
-JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception)
+static inline JSValue checkedReturn(JSValue returnValue)
+{
+ ASSERT(returnValue);
+ return returnValue;
+}
+
+static inline JSObject* checkedReturn(JSObject* returnValue)
+{
+ ASSERT(returnValue);
+ return returnValue;
+}
+
+JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj)
{
ASSERT(!scopeChain->globalData->exception);
- if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
- if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
- *exception = createStackOverflowError(callFrame);
- return jsNull();
- }
- }
+ if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
+ return checkedReturn(throwStackOverflowError(callFrame));
JSObject* error = program->compile(callFrame, scopeChain);
- if (error) {
- *exception = error;
- return jsNull();
- }
+ if (error)
+ return checkedReturn(throwError(callFrame, error));
CodeBlock* codeBlock = &program->generatedBytecode();
Register* oldEnd = m_registerFile.end();
Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
- if (!m_registerFile.grow(newEnd)) {
- *exception = createStackOverflowError(callFrame);
- return jsNull();
- }
+ if (!m_registerFile.grow(newEnd))
+ return checkedReturn(throwStackOverflowError(callFrame));
JSGlobalObject* lastGlobalObject = m_registerFile.globalObject();
JSGlobalObject* globalObject = callFrame->dynamicGlobalObject();
@@ -751,10 +756,10 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
m_reentryDepth++;
#if ENABLE(JIT)
if (callFrame->globalData().canUseJIT())
- result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
else
#endif
- result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+ result = privateExecute(Normal, &m_registerFile, newCallFrame);
m_reentryDepth--;
}
@@ -767,28 +772,22 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
m_registerFile.shrink(oldEnd);
- return result;
+ return checkedReturn(result);
}
-JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, JSValue* exception)
+JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
{
ASSERT(!callFrame->hadException());
- if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
- if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
- *exception = createStackOverflowError(callFrame);
- return jsNull();
- }
- }
+ if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
+ return checkedReturn(throwStackOverflowError(callFrame));
Register* oldEnd = m_registerFile.end();
int argCount = 1 + args.size(); // implicit "this" parameter
size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;
- if (!m_registerFile.grow(oldEnd + registerOffset)) {
- *exception = createStackOverflowError(callFrame);
- return jsNull();
- }
+ if (!m_registerFile.grow(oldEnd + registerOffset))
+ return checkedReturn(throwStackOverflowError(callFrame));
CallFrame* newCallFrame = CallFrame::create(oldEnd);
size_t dst = 0;
@@ -802,17 +801,15 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
if (UNLIKELY(!!compileError)) {
- *exception = compileError;
m_registerFile.shrink(oldEnd);
- return jsNull();
+ return checkedReturn(throwError(callFrame, compileError));
}
CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount);
if (UNLIKELY(!newCallFrame)) {
- *exception = createStackOverflowError(callFrame);
m_registerFile.shrink(oldEnd);
- return jsNull();
+ return checkedReturn(throwStackOverflowError(callFrame));
}
newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
@@ -830,10 +827,10 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
m_reentryDepth++;
#if ENABLE(JIT)
if (callFrame->globalData().canUseJIT())
- result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData, exception);
+ result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData);
else
#endif
- result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+ result = privateExecute(Normal, &m_registerFile, newCallFrame);
m_reentryDepth--;
}
@@ -841,7 +838,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
(*profiler)->didExecute(newCallFrame, function);
m_registerFile.shrink(oldEnd);
- return result;
+ return checkedReturn(result);
}
ASSERT(callType == CallTypeHost);
@@ -865,28 +862,22 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
(*profiler)->didExecute(newCallFrame, function);
m_registerFile.shrink(oldEnd);
- return result;
+ return checkedReturn(result);
}
-JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args, JSValue* exception)
+JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
{
ASSERT(!callFrame->hadException());
- if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
- if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
- *exception = createStackOverflowError(callFrame);
- return 0;
- }
- }
+ if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
+ return checkedReturn(throwStackOverflowError(callFrame));
Register* oldEnd = m_registerFile.end();
int argCount = 1 + args.size(); // implicit "this" parameter
size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;
- if (!m_registerFile.grow(oldEnd + registerOffset)) {
- *exception = createStackOverflowError(callFrame);
- return 0;
- }
+ if (!m_registerFile.grow(oldEnd + registerOffset))
+ return checkedReturn(throwStackOverflowError(callFrame));
CallFrame* newCallFrame = CallFrame::create(oldEnd);
size_t dst = 0;
@@ -899,17 +890,15 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain);
if (UNLIKELY(!!compileError)) {
- *exception = compileError;
m_registerFile.shrink(oldEnd);
- return 0;
+ return checkedReturn(throwError(callFrame, compileError));
}
CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount);
if (UNLIKELY(!newCallFrame)) {
- *exception = createStackOverflowError(callFrame);
m_registerFile.shrink(oldEnd);
- return 0;
+ return checkedReturn(throwStackOverflowError(callFrame));
}
newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
@@ -927,10 +916,10 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
m_reentryDepth++;
#if ENABLE(JIT)
if (callFrame->globalData().canUseJIT())
- result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData, exception);
+ result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData);
else
#endif
- result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+ result = privateExecute(Normal, &m_registerFile, newCallFrame);
m_reentryDepth--;
}
@@ -941,7 +930,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (callFrame->hadException())
return 0;
ASSERT(result.isObject());
- return asObject(result);
+ return checkedReturn(asObject(result));
}
ASSERT(constructType == ConstructTypeHost);
@@ -968,16 +957,16 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (callFrame->hadException())
return 0;
ASSERT(result.isObject());
- return asObject(result);
+ return checkedReturn(asObject(result));
}
-CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception)
+CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain)
{
ASSERT(!scopeChain->globalData->exception);
if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
- *exception = createStackOverflowError(callFrame);
+ throwStackOverflowError(callFrame);
return CallFrameClosure();
}
}
@@ -986,7 +975,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
int argc = 1 + argCount; // implicit "this" parameter
if (!m_registerFile.grow(oldEnd + argc)) {
- *exception = createStackOverflowError(callFrame);
+ throwStackOverflowError(callFrame);
return CallFrameClosure();
}
@@ -997,7 +986,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
JSObject* error = FunctionExecutable->compileForCall(callFrame, scopeChain);
if (error) {
- *exception = error;
+ throwError(callFrame, error);
m_registerFile.shrink(oldEnd);
return CallFrameClosure();
}
@@ -1005,17 +994,16 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
if (UNLIKELY(!newCallFrame)) {
- *exception = createStackOverflowError(callFrame);
+ throwStackOverflowError(callFrame);
m_registerFile.shrink(oldEnd);
return CallFrameClosure();
}
- // a 0 codeBlock indicates a built-in caller
newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function);
CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
return result;
}
-JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception)
+JSValue Interpreter::execute(CallFrameClosure& closure)
{
closure.resetCallFrame();
Profiler** profiler = Profiler::enabledProfilerReference();
@@ -1031,20 +1019,20 @@ JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception)
#if ENABLE(INTERPRETER)
if (closure.newCallFrame->globalData().canUseJIT())
#endif
- result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
+ result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
#if ENABLE(INTERPRETER)
else
#endif
#endif
#if ENABLE(INTERPRETER)
- result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception);
+ result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
#endif
m_reentryDepth--;
}
if (*profiler)
(*profiler)->didExecute(closure.oldCallFrame, closure.function);
- return result;
+ return checkedReturn(result);
}
void Interpreter::endRepeatCall(CallFrameClosure& closure)
@@ -1052,34 +1040,26 @@ void Interpreter::endRepeatCall(CallFrameClosure& closure)
m_registerFile.shrink(closure.oldEnd);
}
-JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain)
{
JSObject* compileError = eval->compile(callFrame, scopeChain);
- if (UNLIKELY(!!compileError)) {
- *exception = compileError;
- return jsNull();
- }
- return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->generatedBytecode().m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
+ if (UNLIKELY(!!compileError))
+ return checkedReturn(throwError(callFrame, compileError));
+ return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->generatedBytecode().m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain);
}
-JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain)
{
ASSERT(!scopeChain->globalData->exception);
- if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
- if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
- *exception = createStackOverflowError(callFrame);
- return jsNull();
- }
- }
+ if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
+ return checkedReturn(throwStackOverflowError(callFrame));
DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
JSObject* compileError = eval->compile(callFrame, scopeChain);
- if (UNLIKELY(!!compileError)) {
- *exception = compileError;
- return jsNull();
- }
+ if (UNLIKELY(!!compileError))
+ return checkedReturn(throwError(callFrame, compileError));
EvalCodeBlock* codeBlock = &eval->generatedBytecode();
JSObject* variableObject;
@@ -1121,15 +1101,13 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
Register* oldEnd = m_registerFile.end();
Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
if (!m_registerFile.grow(newEnd)) {
- *exception = createStackOverflowError(callFrame);
if (pushedScope)
scopeChain->pop();
- return jsNull();
+ return checkedReturn(throwStackOverflowError(callFrame));
}
CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset);
- // a 0 codeBlock indicates a built-in caller
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);
@@ -1151,13 +1129,13 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
#if ENABLE(INTERPRETER)
if (callFrame->globalData().canUseJIT())
#endif
- result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
#if ENABLE(INTERPRETER)
else
#endif
#endif
#if ENABLE(INTERPRETER)
- result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+ result = privateExecute(Normal, &m_registerFile, newCallFrame);
#endif
m_reentryDepth--;
}
@@ -1168,7 +1146,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
m_registerFile.shrink(oldEnd);
if (pushedScope)
scopeChain->pop();
- return result;
+ return checkedReturn(result);
}
NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
@@ -1227,7 +1205,7 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
return;
}
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = baseCell->structure();
if (structure->isUncacheableDictionary()) {
@@ -1317,7 +1295,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
return;
}
- Structure* structure = asCell(baseValue)->structure();
+ Structure* structure = baseValue.asCell()->structure();
if (structure->isUncacheableDictionary()) {
vPC[0] = getOpcode(op_get_by_id_generic);
@@ -1437,7 +1415,7 @@ NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction*
#endif // ENABLE(INTERPRETER)
-JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame, JSValue* exception)
+JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
{
// One-time initialization of our address tables. We have to put this code
// here because our labels are only in scope inside this function.
@@ -1445,7 +1423,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
#define LIST_OPCODE_LABEL(id, length) &&id,
static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
- for (size_t i = 0; i < sizeof(labels) / sizeof(Opcode); ++i)
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i)
m_opcodeTable[i] = labels[i];
#undef LIST_OPCODE_LABEL
#endif // ENABLE(COMPUTED_GOTO_INTERPRETER)
@@ -1463,7 +1441,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if !ENABLE(INTERPRETER)
UNUSED_PARAM(registerFile);
UNUSED_PARAM(callFrame);
- UNUSED_PARAM(exception);
return JSValue();
#else
@@ -1656,7 +1633,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());
+ callFrame->r(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
vPC += OPCODE_LENGTH(op_neq_null);
NEXT_INSTRUCTION();
}
@@ -1737,9 +1714,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int srcDst = vPC[1].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() < INT_MAX)
- callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
+ callFrame->r(srcDst) = jsNumber(v.asInt32() + 1);
else {
- JSValue result = jsNumber(callFrame, v.toNumber(callFrame) + 1);
+ JSValue result = jsNumber(v.toNumber(callFrame) + 1);
CHECK_FOR_EXCEPTION();
callFrame->r(srcDst) = result;
}
@@ -1756,9 +1733,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int srcDst = vPC[1].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() > INT_MIN)
- callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
+ callFrame->r(srcDst) = jsNumber(v.asInt32() - 1);
else {
- JSValue result = jsNumber(callFrame, v.toNumber(callFrame) - 1);
+ JSValue result = jsNumber(v.toNumber(callFrame) - 1);
CHECK_FOR_EXCEPTION();
callFrame->r(srcDst) = result;
}
@@ -1777,12 +1754,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int srcDst = vPC[2].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() < INT_MAX) {
- callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
+ callFrame->r(srcDst) = jsNumber(v.asInt32() + 1);
callFrame->r(dst) = v;
} else {
JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame);
CHECK_FOR_EXCEPTION();
- callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() + 1);
+ callFrame->r(srcDst) = jsNumber(number.uncheckedGetNumber() + 1);
callFrame->r(dst) = number;
}
@@ -1800,12 +1777,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int srcDst = vPC[2].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() > INT_MIN) {
- callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
+ callFrame->r(srcDst) = jsNumber(v.asInt32() - 1);
callFrame->r(dst) = v;
} else {
JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame);
CHECK_FOR_EXCEPTION();
- callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() - 1);
+ callFrame->r(srcDst) = jsNumber(number.uncheckedGetNumber() - 1);
callFrame->r(dst) = number;
}
@@ -1843,9 +1820,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = vPC[1].u.operand;
JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow
- callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
+ callFrame->r(dst) = jsNumber(-src.asInt32());
else {
- JSValue result = jsNumber(callFrame, -src.toNumber(callFrame));
+ JSValue result = jsNumber(-src.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -1864,7 +1841,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
- callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32());
+ callFrame->r(dst) = jsNumber(src1.asInt32() + src2.asInt32());
else {
JSValue result = jsAdd(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
@@ -1883,9 +1860,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow
- callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32());
+ callFrame->r(dst) = jsNumber(src1.asInt32() * src2.asInt32());
else {
- JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame));
+ JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -1904,7 +1881,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
- JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
+ JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
@@ -1923,7 +1900,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
- JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32());
+ JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32());
ASSERT(result);
callFrame->r(dst) = result;
vPC += OPCODE_LENGTH(op_mod);
@@ -1934,7 +1911,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
// order of argument evaluation is not guaranteed.
double d1 = dividend.toNumber(callFrame);
double d2 = divisor.toNumber(callFrame);
- JSValue result = jsNumber(callFrame, fmod(d1, d2));
+ JSValue result = jsNumber(fmod(d1, d2));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
vPC += OPCODE_LENGTH(op_mod);
@@ -1951,9 +1928,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
- callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32());
+ callFrame->r(dst) = jsNumber(src1.asInt32() - src2.asInt32());
else {
- JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
+ JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -1972,9 +1949,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
if (val.isInt32() && shift.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f));
+ callFrame->r(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f));
else {
- JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
+ JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -1994,9 +1971,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
if (val.isInt32() && shift.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
+ callFrame->r(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
else {
- JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -2015,9 +1992,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
if (val.isUInt32() && shift.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
+ callFrame->r(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
else {
- JSValue result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -2036,9 +2013,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32());
+ callFrame->r(dst) = jsNumber(src1.asInt32() & src2.asInt32());
else {
- JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame));
+ JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -2057,9 +2034,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32());
+ callFrame->r(dst) = jsNumber(src1.asInt32() ^ src2.asInt32());
else {
- JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
+ JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -2078,9 +2055,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32());
+ callFrame->r(dst) = jsNumber(src1.asInt32() | src2.asInt32());
else {
- JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame));
+ JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -2097,9 +2074,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = vPC[1].u.operand;
JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
if (src.isInt32())
- callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32());
+ callFrame->r(dst) = jsNumber(~src.asInt32());
else {
- JSValue result = jsNumber(callFrame, ~src.toInt32(callFrame));
+ JSValue result = jsNumber(~src.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
@@ -2515,7 +2492,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2546,7 +2523,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2585,7 +2562,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2630,7 +2607,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2711,7 +2688,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2760,7 +2737,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2803,7 +2780,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2860,7 +2837,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2915,7 +2892,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -2965,7 +2942,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(isJSArray(globalData, baseValue))) {
int dst = vPC[1].u.operand;
- callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length());
+ callFrame->r(dst) = jsNumber(asArray(baseValue)->length());
vPC += OPCODE_LENGTH(op_get_array_length);
NEXT_INSTRUCTION();
}
@@ -2985,7 +2962,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(isJSString(globalData, baseValue))) {
int dst = vPC[1].u.operand;
- callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->length());
+ callFrame->r(dst) = jsNumber(asString(baseValue)->length());
vPC += OPCODE_LENGTH(op_get_string_length);
NEXT_INSTRUCTION();
}
@@ -3041,7 +3018,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* oldStructure = vPC[4].u.structure;
Structure* newStructure = vPC[5].u.structure;
@@ -3093,7 +3070,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = asCell(baseValue);
+ JSCell* baseCell = baseValue.asCell();
Structure* structure = vPC[4].u.structure;
if (LIKELY(baseCell->structure() == structure)) {
@@ -3203,7 +3180,7 @@ skip_id_custom_self:
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
} else
- callFrame->r(dst) = jsNumber(callFrame, callFrame->argumentCount());
+ callFrame->r(dst) = jsNumber(callFrame->argumentCount());
vPC += OPCODE_LENGTH(op_get_arguments_length);
NEXT_INSTRUCTION();
@@ -3820,8 +3797,8 @@ skip_id_custom_self:
JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject;
if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
- JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
- if (exceptionValue)
+ JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset);
+ if ((exceptionValue = globalData->exception))
goto vm_throw;
functionReturnValue = result;
@@ -4087,14 +4064,13 @@ skip_id_custom_self:
if (activationValue) {
asActivation(activationValue)->copyRegisters();
- if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue())
- asArguments(argumentsValue)->setActivation(asActivation(activationValue));
- } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue())
- asArguments(argumentsValue)->copyRegisters();
-
- if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
+ if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
+ if (!codeBlock->isStrictMode())
+ asArguments(argumentsValue)->setActivation(asActivation(activationValue));
+ }
+ } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
if (!codeBlock->isStrictMode())
- asArguments(argumentsValue)->setActivation(asActivation(activationValue));
+ asArguments(argumentsValue)->copyRegisters();
}
vPC += OPCODE_LENGTH(op_tear_off_activation);
@@ -4601,10 +4577,8 @@ skip_id_custom_self:
exceptionValue = callFrame->r(ex).jsValue();
handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin(), true);
- if (!handler) {
- *exception = exceptionValue;
- return jsNull();
- }
+ if (!handler)
+ return throwError(callFrame, exceptionValue);
codeBlock = callFrame->codeBlock();
vPC = codeBlock->instructions().begin() + handler->target;
@@ -4771,10 +4745,8 @@ skip_id_custom_self:
exceptionValue = createInterruptedExecutionException(globalData);
}
handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin(), false);
- if (!handler) {
- *exception = exceptionValue;
- return jsNull();
- }
+ if (!handler)
+ return throwError(callFrame, exceptionValue);
codeBlock = callFrame->codeBlock();
vPC = codeBlock->instructions().begin() + handler->target;