summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp430
1 files changed, 202 insertions, 228 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
index 42e0b056da..7d3a84d50b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
@@ -58,6 +58,7 @@
#include "RegExpPrototype.h"
#include "Register.h"
#include "SamplingTool.h"
+#include <limits.h>
#include <stdio.h>
#include <wtf/Threading.h>
@@ -65,10 +66,6 @@
#include "JIT.h"
#endif
-#if ENABLE(ASSEMBLER)
-#include "AssemblerBuffer.h"
-#endif
-
#ifdef QT_BUILD_SCRIPT_LIB
#include "bridge/qscriptobject_p.h"
#endif
@@ -176,7 +173,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
PropertySlot slot(globalObject);
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) {
+ if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
if (vPC[4].u.structure)
vPC[4].u.structure->deref();
globalObject->structure()->ref();
@@ -357,15 +354,14 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
if (JSValue parsedObject = preparser.tryLiteralParse())
return parsedObject;
-
-
+
ScopeChainNode* scopeChain = callFrame->scopeChain();
CodeBlock* codeBlock = callFrame->codeBlock();
- RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
+ RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
JSValue result = jsUndefined();
- if (evalNode)
- result = callFrame->globalData().interpreter->execute(evalNode.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
+ if (eval)
+ result = callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
return result;
}
@@ -388,67 +384,92 @@ void Interpreter::dumpCallFrame(CallFrame* callFrame)
void Interpreter::dumpRegisters(CallFrame* callFrame)
{
printf("Register frame: \n\n");
- printf("----------------------------------------------------\n");
- printf(" use | address | value \n");
- printf("----------------------------------------------------\n");
+ printf("-----------------------------------------------------------------------------\n");
+ printf(" use | address | value \n");
+ printf("-----------------------------------------------------------------------------\n");
CodeBlock* codeBlock = callFrame->codeBlock();
RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->interpreter->registerFile();
const Register* it;
const Register* end;
+ JSValue v;
if (codeBlock->codeType() == GlobalCode) {
it = registerFile->lastGlobal();
end = it + registerFile->numGlobals();
while (it != end) {
- printf("[global var] | %10p | %10p \n", it, (*it).v());
+ v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+ printf("[global var] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
+#else
+ printf("[global var] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
+#endif
++it;
}
- printf("----------------------------------------------------\n");
+ printf("-----------------------------------------------------------------------------\n");
}
it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->m_numParameters;
- printf("[this] | %10p | %10p \n", it, (*it).v()); ++it;
+ v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+ printf("[this] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it;
+#else
+ printf("[this] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it;
+#endif
end = it + max(codeBlock->m_numParameters - 1, 0); // - 1 to skip "this"
if (it != end) {
do {
- printf("[param] | %10p | %10p \n", it, (*it).v());
+ v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+ printf("[param] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
+#else
+ printf("[param] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
+#endif
++it;
} while (it != end);
}
- printf("----------------------------------------------------\n");
-
- printf("[CodeBlock] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[ScopeChain] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[CallerRegisters] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[ReturnPC] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[ReturnValueRegister] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[ArgumentCount] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[Callee] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("[OptionalCalleeArguments] | %10p | %10p \n", it, (*it).v()); ++it;
- printf("----------------------------------------------------\n");
+ printf("-----------------------------------------------------------------------------\n");
+ printf("[CodeBlock] | %10p | %p \n", it, (*it).codeBlock()); ++it;
+ printf("[ScopeChain] | %10p | %p \n", it, (*it).scopeChain()); ++it;
+ printf("[CallerRegisters] | %10p | %d \n", it, (*it).i()); ++it;
+ printf("[ReturnPC] | %10p | %p \n", it, (*it).vPC()); ++it;
+ printf("[ReturnValueRegister] | %10p | %d \n", it, (*it).i()); ++it;
+ printf("[ArgumentCount] | %10p | %d \n", it, (*it).i()); ++it;
+ printf("[Callee] | %10p | %p \n", it, (*it).function()); ++it;
+ printf("[OptionalCalleeArguments] | %10p | %p \n", it, (*it).arguments()); ++it;
+ printf("-----------------------------------------------------------------------------\n");
int registerCount = 0;
end = it + codeBlock->m_numVars;
if (it != end) {
do {
- printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v());
+ v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+ printf("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
+#else
+ printf("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
+#endif
++it;
++registerCount;
} while (it != end);
}
- printf("----------------------------------------------------\n");
+ printf("-----------------------------------------------------------------------------\n");
end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars;
if (it != end) {
do {
- printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v());
+ v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+ printf("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
+#else
+ printf("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
+#endif
++it;
++registerCount;
} while (it != end);
}
- printf("----------------------------------------------------\n");
+ printf("-----------------------------------------------------------------------------\n");
}
#endif
@@ -472,24 +493,24 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
if (callFrame->callee()) {
- debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine());
+ debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
#ifdef QT_BUILD_SCRIPT_LIB
- debugger->functionExit(exceptionValue, codeBlock->ownerNode()->sourceID());
+ debugger->functionExit(exceptionValue, codeBlock->ownerExecutable()->sourceID());
#endif
} else
- debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine());
+ debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
}
if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
if (callFrame->callee())
profiler->didExecute(callFrame, callFrame->callee());
else
- profiler->didExecute(callFrame, codeBlock->ownerNode()->sourceURL(), codeBlock->ownerNode()->lineNo());
+ profiler->didExecute(callFrame, codeBlock->ownerExecutable()->sourceURL(), codeBlock->ownerExecutable()->lineNo());
}
// If this call frame created an activation or an 'arguments' object, tear it off.
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) {
- while (!scopeChain->object->isObject(&JSActivation::info))
+ while (!scopeChain->object->inherits(&JSActivation::info))
scopeChain = scopeChain->pop();
static_cast<JSActivation*>(scopeChain->object)->copyRegisters(callFrame->optionalCalleeArguments());
} else if (Arguments* arguments = callFrame->optionalCalleeArguments()) {
@@ -540,8 +561,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
exception->putWithAttributes(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName), jsNumber(callFrame, divotPoint + endOffset), ReadOnly | DontDelete);
} else
exception->putWithAttributes(callFrame, Identifier(callFrame, JSC_ERROR_LINENUMBER_PROPERTYNAME), jsNumber(callFrame, codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)), ReadOnly | DontDelete);
- exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode()->sourceID()), ReadOnly | DontDelete);
- exception->putWithAttributes(callFrame, Identifier(callFrame, JSC_ERROR_FILENAME_PROPERTYNAME), jsOwnedString(callFrame, codeBlock->ownerNode()->sourceURL()), ReadOnly | DontDelete);
+ exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerExecutable()->sourceID()), ReadOnly | DontDelete);
+ exception->putWithAttributes(callFrame, Identifier(callFrame, JSC_ERROR_FILENAME_PROPERTYNAME), jsOwnedString(callFrame, codeBlock->ownerExecutable()->sourceURL()), ReadOnly | DontDelete);
}
if (exception->isWatchdogException()) {
@@ -556,7 +577,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
if (debugger) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
- debugger->exception(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset));
+ debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset));
}
// If we throw in the middle of a call instruction, we need to notify
@@ -597,7 +618,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
}
}
if (debugger)
- debugger->exceptionThrow(DebuggerCallFrame(callFrame, exceptionValue), codeBlock->ownerNode()->sourceID(), hasHandler);
+ debugger->exceptionThrow(DebuggerCallFrame(callFrame, exceptionValue), codeBlock->ownerExecutable()->sourceID(), hasHandler);
#endif
while (!(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
@@ -618,7 +639,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
return handler;
}
-JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception)
+JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -629,7 +650,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
}
}
- CodeBlock* codeBlock = &programNode->bytecode(scopeChain);
+ CodeBlock* codeBlock = &program->bytecode(callFrame, scopeChain);
Register* oldEnd = m_registerFile.end();
Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
@@ -653,7 +674,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
- (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo());
+ (*profiler)->willExecute(newCallFrame, program->sourceURL(), program->lineNo());
JSValue result;
{
@@ -661,7 +682,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
m_reentryDepth++;
#if ENABLE(JIT)
- result = programNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -669,7 +690,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
}
if (*profiler)
- (*profiler)->didExecute(callFrame, programNode->sourceURL(), programNode->lineNo());
+ (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo());
if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject)
lastGlobalObject->copyGlobalsTo(m_registerFile);
@@ -679,7 +700,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
return result;
}
-JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -707,7 +728,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
for (ArgList::const_iterator it = args.begin(); it != end; ++it)
newCallFrame->r(++dst) = *it;
- CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
+ CodeBlock* codeBlock = &functionExecutable->bytecode(callFrame, scopeChain);
newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
if (UNLIKELY(!newCallFrame)) {
*exception = createStackOverflowError(callFrame);
@@ -727,7 +748,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
m_reentryDepth++;
#if ENABLE(JIT)
- result = functionBodyNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = functionExecutable->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -741,7 +762,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
return result;
}
-CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception)
+CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -765,7 +786,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod
for (int i = 0; i < argc; ++i)
newCallFrame->r(++dst) = jsUndefined();
- CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
+ CodeBlock* codeBlock = &FunctionExecutable->bytecode(callFrame, scopeChain);
newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
if (UNLIKELY(!newCallFrame)) {
*exception = createStackOverflowError(callFrame);
@@ -775,10 +796,10 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod
// a 0 codeBlock indicates a built-in caller
newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);
#if ENABLE(JIT)
- functionBodyNode->jitCode(scopeChain);
+ FunctionExecutable->jitCode(newCallFrame, scopeChain);
#endif
- CallFrameClosure result = { callFrame, newCallFrame, function, functionBodyNode, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
+ CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
return result;
}
@@ -795,7 +816,7 @@ JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception)
m_reentryDepth++;
#if ENABLE(JIT)
- result = closure.functionBody->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
+ result = closure.functionExecutable->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception);
#endif
@@ -812,12 +833,12 @@ void Interpreter::endRepeatCall(CallFrameClosure& closure)
m_registerFile.shrink(closure.oldEnd);
}
-JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
{
- return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->bytecode(scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
+ return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->bytecode(callFrame, scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
}
-JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -830,7 +851,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
- EvalCodeBlock* codeBlock = &evalNode->bytecode(scopeChain);
+ EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain);
JSVariableObject* variableObject;
for (ScopeChainNode* node = scopeChain; ; node = node->next) {
@@ -845,21 +866,20 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
BatchedTransitionOptimizer optimizer(variableObject);
- const DeclarationStacks::VarStack& varStack = codeBlock->ownerNode()->varStack();
- DeclarationStacks::VarStack::const_iterator varStackEnd = varStack.end();
- for (DeclarationStacks::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) {
- const Identifier& ident = (*it).first;
+ unsigned numVariables = codeBlock->numVariables();
+ for (unsigned i = 0; i < numVariables; ++i) {
+ const Identifier& ident = codeBlock->variable(i);
if (!variableObject->hasProperty(callFrame, ident)) {
PutPropertySlot slot;
variableObject->put(callFrame, ident, jsUndefined(), slot);
}
}
- const DeclarationStacks::FunctionStack& functionStack = codeBlock->ownerNode()->functionStack();
- DeclarationStacks::FunctionStack::const_iterator functionStackEnd = functionStack.end();
- for (DeclarationStacks::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) {
+ int numFunctions = codeBlock->numberOfFunctionDecls();
+ for (int i = 0; i < numFunctions; ++i) {
+ FunctionExecutable* function = codeBlock->functionDecl(i);
PutPropertySlot slot;
- variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(callFrame, scopeChain), slot);
+ variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot);
}
}
@@ -882,7 +902,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
- (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo());
+ (*profiler)->willExecute(newCallFrame, eval->sourceURL(), eval->lineNo());
JSValue result;
{
@@ -890,7 +910,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
m_reentryDepth++;
#if ENABLE(JIT)
- result = evalNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -898,7 +918,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
}
if (*profiler)
- (*profiler)->didExecute(callFrame, evalNode->sourceURL(), evalNode->lineNo());
+ (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
m_registerFile.shrink(oldEnd);
return result;
@@ -912,22 +932,22 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
switch (debugHookID) {
case DidEnterCallFrame:
- debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
+ debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
return;
case WillLeaveCallFrame:
- debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
+ debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
return;
case WillExecuteStatement:
- debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine, column);
+ debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
return;
case WillExecuteProgram:
- debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
+ debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
return;
case DidExecuteProgram:
- debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
+ debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
return;
case DidReachBreakpoint:
- debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine, column);
+ debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
return;
}
}
@@ -963,7 +983,7 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
JSCell* baseCell = asCell(baseValue);
Structure* structure = baseCell->structure();
- if (structure->isDictionary()) {
+ if (structure->isUncacheableDictionary()) {
vPC[0] = getOpcode(op_put_by_id_generic);
return;
}
@@ -1050,7 +1070,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
Structure* structure = asCell(baseValue)->structure();
- if (structure->isDictionary()) {
+ if (structure->isUncacheableDictionary()) {
vPC[0] = getOpcode(op_get_by_id_generic);
return;
}
@@ -1145,7 +1165,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
#if ENABLE(JIT)
- // Currently with CTI enabled we never interpret functions
+ // Mixing Interpreter + JIT is not supported.
ASSERT_NOT_REACHED();
#endif
#if !USE(INTERPRETER)
@@ -1184,7 +1204,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
tickCount = globalData->timeoutChecker->ticksUntilNextCheck(); \
CHECK_FOR_EXCEPTION(); \
}
-
+
#if ENABLE(OPCODE_SAMPLING)
#define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
#else
@@ -1276,8 +1296,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
- callFrame->r(dst) = JSFastMath::equal(src1, src2);
+ if (src1.isInt32() && src2.isInt32())
+ callFrame->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
else {
JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2));
CHECK_FOR_EXCEPTION();
@@ -1316,8 +1336,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
- callFrame->r(dst) = JSFastMath::notEqual(src1, src2);
+ if (src1.isInt32() && src2.isInt32())
+ callFrame->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
else {
JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2));
CHECK_FOR_EXCEPTION();
@@ -1418,8 +1438,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int srcDst = (++vPC)->u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
- if (JSFastMath::canDoFastAdditiveOperations(v))
- callFrame->r(srcDst) = JSValue(JSFastMath::incImmediateNumber(v));
+ if (v.isInt32() && v.asInt32() < INT_MAX)
+ callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
else {
JSValue result = jsNumber(callFrame, v.toNumber(callFrame) + 1);
CHECK_FOR_EXCEPTION();
@@ -1437,8 +1457,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int srcDst = (++vPC)->u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
- if (JSFastMath::canDoFastAdditiveOperations(v))
- callFrame->r(srcDst) = JSValue(JSFastMath::decImmediateNumber(v));
+ if (v.isInt32() && v.asInt32() > INT_MIN)
+ callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
else {
JSValue result = jsNumber(callFrame, v.toNumber(callFrame) - 1);
CHECK_FOR_EXCEPTION();
@@ -1458,14 +1478,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
int srcDst = (++vPC)->u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
- if (JSFastMath::canDoFastAdditiveOperations(v)) {
+ if (v.isInt32() && v.asInt32() < INT_MAX) {
+ callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
callFrame->r(dst) = v;
- callFrame->r(srcDst) = JSValue(JSFastMath::incImmediateNumber(v));
} else {
JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame);
CHECK_FOR_EXCEPTION();
+ callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() + 1);
callFrame->r(dst) = number;
- callFrame->r(srcDst) = JSValue(jsNumber(callFrame, number.uncheckedGetNumber() + 1));
}
++vPC;
@@ -1481,14 +1501,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
int srcDst = (++vPC)->u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
- if (JSFastMath::canDoFastAdditiveOperations(v)) {
+ if (v.isInt32() && v.asInt32() > INT_MIN) {
+ callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
callFrame->r(dst) = v;
- callFrame->r(srcDst) = JSValue(JSFastMath::decImmediateNumber(v));
} else {
JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame);
CHECK_FOR_EXCEPTION();
+ callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() - 1);
callFrame->r(dst) = number;
- callFrame->r(srcDst) = JSValue(jsNumber(callFrame, number.uncheckedGetNumber() - 1));
}
++vPC;
@@ -1524,16 +1544,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int dst = (++vPC)->u.operand;
JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
- ++vPC;
- double v;
- if (src.getNumber(v))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, -v));
+ if (src.isInt32() && src.asInt32())
+ callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
else {
JSValue result = jsNumber(callFrame, -src.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
+ ++vPC;
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_add) {
@@ -1546,8 +1565,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- if (JSFastMath::canDoFastAdditiveOperations(src1, src2))
- callFrame->r(dst) = JSValue(JSFastMath::addImmediateNumbers(src1, src2));
+ if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+ callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32());
else {
JSValue result = jsAdd(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
@@ -1565,17 +1584,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- double left;
- double right;
- if (JSValue::areBothInt32Fast(src1, src2)) {
- int32_t left = src1.getInt32Fast();
- int32_t right = src2.getInt32Fast();
- if ((left | right) >> 15 == 0)
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left * right));
- else
- callFrame->r(dst) = JSValue(jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right)));
- } else if (src1.getNumber(left) && src2.getNumber(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left * right));
+ if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow
+ callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32());
else {
JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
@@ -1595,16 +1605,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
- double left;
- double right;
- if (dividend.getNumber(left) && divisor.getNumber(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left / right));
- else {
- JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->r(dst) = result;
- }
- ++vPC;
+
+ JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION();
+ callFrame->r(dst) = result;
+
+ vPC += 2;
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_mod) {
@@ -1615,24 +1621,22 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
remainder in register dst.
*/
int dst = (++vPC)->u.operand;
- int dividend = (++vPC)->u.operand;
- int divisor = (++vPC)->u.operand;
-
- JSValue dividendValue = callFrame->r(dividend).jsValue();
- JSValue divisorValue = callFrame->r(divisor).jsValue();
+ JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
+ JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
- if (JSValue::areBothInt32Fast(dividendValue, divisorValue) && divisorValue != jsNumber(callFrame, 0)) {
- // We expect the result of the modulus of a number that was representable as an int32 to also be representable
- // as an int32.
- JSValue result = JSValue::makeInt32Fast(dividendValue.getInt32Fast() % divisorValue.getInt32Fast());
+ if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
+ JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32());
ASSERT(result);
callFrame->r(dst) = result;
++vPC;
NEXT_INSTRUCTION();
}
- double d = dividendValue.toNumber(callFrame);
- JSValue result = jsNumber(callFrame, fmod(d, divisorValue.toNumber(callFrame)));
+ // Conversion to double must happen outside the call to fmod since the
+ // order of argument evaluation is not guaranteed.
+ double d1 = dividend.toNumber(callFrame);
+ double d2 = divisor.toNumber(callFrame);
+ JSValue result = jsNumber(callFrame, fmod(d1, d2));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
++vPC;
@@ -1648,12 +1652,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- double left;
- double right;
- if (JSFastMath::canDoFastAdditiveOperations(src1, src2))
- callFrame->r(dst) = JSValue(JSFastMath::subImmediateNumbers(src1, src2));
- else if (src1.getNumber(left) && src2.getNumber(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left - right));
+ if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+ callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32());
else {
JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
@@ -1672,12 +1672,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
- int32_t left;
- uint32_t right;
- if (JSValue::areBothInt32Fast(val, shift))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f)));
- else if (val.numberToInt32(left) && shift.numberToUInt32(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left << (right & 0x1f)));
+
+ if (val.isInt32() && shift.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f));
else {
JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
CHECK_FOR_EXCEPTION();
@@ -1697,12 +1694,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
- int32_t left;
- uint32_t right;
- if (JSFastMath::canDoFastRshift(val, shift))
- callFrame->r(dst) = JSValue(JSFastMath::rightShiftImmediateNumbers(val, shift));
- else if (val.numberToInt32(left) && shift.numberToUInt32(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left >> (right & 0x1f)));
+
+ if (val.isInt32() && shift.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
else {
JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
CHECK_FOR_EXCEPTION();
@@ -1722,8 +1716,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
- if (JSFastMath::canDoFastUrshift(val, shift))
- callFrame->r(dst) = JSValue(JSFastMath::rightShiftImmediateNumbers(val, shift));
+ if (val.isUInt32() && shift.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
else {
JSValue result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
CHECK_FOR_EXCEPTION();
@@ -1743,12 +1737,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int32_t left;
- int32_t right;
- if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
- callFrame->r(dst) = JSValue(JSFastMath::andImmediateNumbers(src1, src2));
- else if (src1.numberToInt32(left) && src2.numberToInt32(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left & right));
+ if (src1.isInt32() && src2.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32());
else {
JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
@@ -1768,12 +1758,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int32_t left;
- int32_t right;
- if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
- callFrame->r(dst) = JSValue(JSFastMath::xorImmediateNumbers(src1, src2));
- else if (src1.numberToInt32(left) && src2.numberToInt32(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left ^ right));
+ if (src1.isInt32() && src2.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32());
else {
JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
@@ -1793,12 +1779,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int32_t left;
- int32_t right;
- if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
- callFrame->r(dst) = JSValue(JSFastMath::orImmediateNumbers(src1, src2));
- else if (src1.numberToInt32(left) && src2.numberToInt32(right))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, left | right));
+ if (src1.isInt32() && src2.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32());
else {
JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
@@ -1816,9 +1798,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int dst = (++vPC)->u.operand;
JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
- int32_t value;
- if (src.numberToInt32(value))
- callFrame->r(dst) = JSValue(jsNumber(callFrame, ~value));
+ if (src.isInt32())
+ callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32());
else {
JSValue result = jsNumber(callFrame, ~src.toInt32(callFrame));
CHECK_FOR_EXCEPTION();
@@ -2152,27 +2133,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
vPC += 4;
NEXT_INSTRUCTION();
}
- DEFINE_OPCODE(op_resolve_func) {
- /* resolve_func baseDst(r) funcDst(r) property(id)
-
- Searches the scope chain for an object containing
- identifier property, and if one is found, writes the
- appropriate object to use as "this" when calling its
- properties to register baseDst; and the retrieved property
- value to register propDst. If the property is not found,
- raises an exception.
-
- This differs from resolve_with_base, because the
- global this value will be substituted for activations or
- the global object, which is the right behavior for function
- calls but not for other property lookup.
- */
- if (UNLIKELY(!resolveBaseAndFunc(callFrame, vPC, exceptionValue)))
- goto vm_throw;
-
- vPC += 4;
- NEXT_INSTRUCTION();
- }
DEFINE_OPCODE(op_get_by_id) {
/* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
@@ -2353,7 +2313,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(isJSArray(globalData, baseValue))) {
int dst = vPC[1].u.operand;
- callFrame->r(dst) = JSValue(jsNumber(callFrame, asArray(baseValue)->length()));
+ callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length());
vPC += 8;
NEXT_INSTRUCTION();
}
@@ -2373,7 +2333,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(isJSString(globalData, baseValue))) {
int dst = vPC[1].u.operand;
- callFrame->r(dst) = JSValue(jsNumber(callFrame, asString(baseValue)->value().size()));
+ callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size());
vPC += 8;
NEXT_INSTRUCTION();
}
@@ -2551,8 +2511,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue result;
- if (LIKELY(subscript.isUInt32Fast())) {
- uint32_t i = subscript.getUInt32Fast();
+ if (LIKELY(subscript.isUInt32())) {
+ uint32_t i = subscript.asUInt32();
if (isJSArray(globalData, baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canGetIndex(i))
@@ -2593,8 +2553,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
JSValue subscript = callFrame->r(property).jsValue();
- if (LIKELY(subscript.isUInt32Fast())) {
- uint32_t i = subscript.getUInt32Fast();
+ if (LIKELY(subscript.isUInt32())) {
+ uint32_t i = subscript.asUInt32();
if (isJSArray(globalData, baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canSetIndex(i))
@@ -2605,8 +2565,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSByteArray* jsByteArray = asByteArray(baseValue);
double dValue = 0;
JSValue jsValue = callFrame->r(value).jsValue();
- if (jsValue.isInt32Fast())
- jsByteArray->setIndex(i, jsValue.getInt32Fast());
+ if (jsValue.isInt32())
+ jsByteArray->setIndex(i, jsValue.asInt32());
else if (jsValue.getNumber(dValue))
jsByteArray->setIndex(i, dValue);
else
@@ -2926,8 +2886,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int tableIndex = (++vPC)->u.operand;
int defaultOffset = (++vPC)->u.operand;
JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
- if (scrutinee.isInt32Fast())
- vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.getInt32Fast(), defaultOffset);
+ if (scrutinee.isInt32())
+ vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
else {
double value;
int32_t intValue;
@@ -2990,7 +2950,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = (++vPC)->u.operand;
int func = (++vPC)->u.operand;
- callFrame->r(dst) = callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain());
+ callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionDecl(func)->make(callFrame, callFrame->scopeChain()));
++vPC;
NEXT_INSTRUCTION();
@@ -3004,9 +2964,24 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
puts the result in register dst.
*/
int dst = (++vPC)->u.operand;
- int func = (++vPC)->u.operand;
+ int funcIndex = (++vPC)->u.operand;
+
+ FunctionExecutable* function = callFrame->codeBlock()->functionExpr(funcIndex);
+ JSFunction* func = function->make(callFrame, callFrame->scopeChain());
- callFrame->r(dst) = callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain());
+ /*
+ The Identifier in a FunctionExpression can be referenced from inside
+ the FunctionExpression's FunctionBody to allow the function to call
+ itself recursively. However, unlike in a FunctionDeclaration, the
+ Identifier in a FunctionExpression cannot be referenced from and
+ does not affect the scope enclosing the FunctionExpression.
+ */
+ if (!function->name().isNull()) {
+ JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete);
+ func->scope().push(functionScopeObject);
+ }
+
+ callFrame->r(dst) = JSValue(func);
++vPC;
NEXT_INSTRUCTION();
@@ -3072,8 +3047,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
- FunctionBodyNode* functionBodyNode = callData.js.functionBody;
- CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+ CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
CallFrame* previousCallFrame = callFrame;
@@ -3114,7 +3088,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
CHECK_FOR_EXCEPTION();
- callFrame->r(dst) = JSValue(returnValue);
+ callFrame->r(dst) = returnValue;
vPC += 5;
NEXT_INSTRUCTION();
@@ -3139,7 +3113,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
exceptionValue = createStackOverflowError(callFrame);
goto vm_throw;
}
- int32_t expectedParams = static_cast<JSFunction*>(callFrame->callee())->body()->parameterCount();
+ ASSERT(!callFrame->callee()->isHostFunction());
+ int32_t expectedParams = static_cast<JSFunction*>(callFrame->callee())->jsExecutable()->parameterCount();
int32_t inplaceArgs = min(argCount, expectedParams);
int32_t i = 0;
Register* argStore = callFrame->registers() + argsOffset;
@@ -3197,7 +3172,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
}
CHECK_FOR_EXCEPTION();
- callFrame->r(argCountDst) = argCount + 1;
+ callFrame->r(argCountDst) = Register::withInt(argCount + 1);
++vPC;
NEXT_INSTRUCTION();
}
@@ -3226,8 +3201,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
- FunctionBodyNode* functionBodyNode = callData.js.functionBody;
- CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+ CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
CallFrame* previousCallFrame = callFrame;
@@ -3268,7 +3242,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
CHECK_FOR_EXCEPTION();
- callFrame->r(dst) = JSValue(returnValue);
+ callFrame->r(dst) = returnValue;
vPC += 5;
NEXT_INSTRUCTION();
@@ -3314,6 +3288,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain());
+
if (callFrame->optionalCalleeArguments())
callFrame->optionalCalleeArguments()->copyRegisters();
@@ -3354,7 +3329,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (callFrame->hasHostCallFrameFlag())
return returnValue;
- callFrame->r(dst) = JSValue(returnValue);
+ callFrame->r(dst) = returnValue;
NEXT_INSTRUCTION();
}
@@ -3398,8 +3373,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(i) = jsUndefined();
int dst = (++vPC)->u.operand;
- JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode()));
- callFrame->r(dst) = activation;
+ JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
+ callFrame->r(dst) = JSValue(activation);
callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
++vPC;
@@ -3450,7 +3425,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (!callFrame->r(RegisterFile::ArgumentsRegister).jsValue()) {
Arguments* arguments = new (globalData) Arguments(callFrame);
callFrame->setCalleeArguments(arguments);
- callFrame->r(RegisterFile::ArgumentsRegister) = arguments;
+ callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments);
}
++vPC;
NEXT_INSTRUCTION();
@@ -3484,8 +3459,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (constructType == ConstructTypeJS) {
ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
- FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
- CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+ CodeBlock* newCodeBlock = &constructData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
Structure* structure;
JSValue prototype = callFrame->r(proto).jsValue();
@@ -3703,7 +3677,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
if (debugger) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
- debugger->exceptionCatch(debuggerCallFrame, codeBlock->ownerNode()->sourceID());
+ debugger->exceptionCatch(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID());
}
#endif
@@ -3750,7 +3724,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int message = (++vPC)->u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
- callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
+ callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()));
++vPC;
NEXT_INSTRUCTION();
@@ -3813,7 +3787,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSObject* baseObj = asObject(callFrame->r(base).jsValue());
Identifier& ident = callFrame->codeBlock()->identifier(property);
ASSERT(callFrame->r(function).jsValue().isObject());
- baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()));
+ baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0);
++vPC;
NEXT_INSTRUCTION();
@@ -3926,12 +3900,12 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio
CodeBlock* codeBlock = functionCallFrame->codeBlock();
if (codeBlock->usesArguments()) {
ASSERT(codeBlock->codeType() == FunctionCode);
- SymbolTable& symbolTable = codeBlock->symbolTable();
+ SymbolTable& symbolTable = *codeBlock->symbolTable();
int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex();
- if (!functionCallFrame->r(argumentsIndex).arguments()) {
+ if (!functionCallFrame->r(argumentsIndex).jsValue()) {
Arguments* arguments = new (callFrame) Arguments(functionCallFrame);
functionCallFrame->setCalleeArguments(arguments);
- functionCallFrame->r(RegisterFile::ArgumentsRegister) = arguments;
+ functionCallFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments);
}
return functionCallFrame->r(argumentsIndex).jsValue();
}
@@ -3979,8 +3953,8 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
unsigned bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC());
lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
- sourceID = callerCodeBlock->ownerNode()->sourceID();
- sourceURL = callerCodeBlock->ownerNode()->sourceURL();
+ sourceID = callerCodeBlock->ownerExecutable()->sourceID();
+ sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
function = callerFrame->callee();
}