diff options
author | Ben Murdoch <benm@google.com> | 2009-08-11 17:01:47 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2009-08-11 18:21:02 +0100 |
commit | 0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch) | |
tree | 2943df35f62d885c89d01063cc528dd73b480fea /JavaScriptCore/interpreter | |
parent | 7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff) | |
download | external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2 |
Merge in WebKit r47029.
Diffstat (limited to 'JavaScriptCore/interpreter')
-rw-r--r-- | JavaScriptCore/interpreter/CachedCall.h | 2 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/CallFrame.h | 28 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/CallFrameClosure.h | 2 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/Interpreter.cpp | 779 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/Interpreter.h | 10 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/Register.h | 60 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/RegisterFile.h | 26 |
7 files changed, 420 insertions, 487 deletions
diff --git a/JavaScriptCore/interpreter/CachedCall.h b/JavaScriptCore/interpreter/CachedCall.h index f48f4f4..767c262 100644 --- a/JavaScriptCore/interpreter/CachedCall.h +++ b/JavaScriptCore/interpreter/CachedCall.h @@ -32,7 +32,7 @@ #include "Interpreter.h" namespace JSC { - class CachedCall : Noncopyable { + class CachedCall : public Noncopyable { public: CachedCall(CallFrame* callFrame, JSFunction* function, int argCount, JSValue* exception) : m_valid(false) diff --git a/JavaScriptCore/interpreter/CallFrame.h b/JavaScriptCore/interpreter/CallFrame.h index a61e143..92ec06e 100644 --- a/JavaScriptCore/interpreter/CallFrame.h +++ b/JavaScriptCore/interpreter/CallFrame.h @@ -89,6 +89,7 @@ namespace JSC { #endif static const HashTable* arrayTable(CallFrame* callFrame) { return callFrame->globalData().arrayTable; } static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; } + static const HashTable* jsonTable(CallFrame* callFrame) { return callFrame->globalData().jsonTable; } static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; } static const HashTable* numberTable(CallFrame* callFrame) { return callFrame->globalData().numberTable; } static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; } @@ -104,7 +105,7 @@ namespace JSC { Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); } Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); } - void setCalleeArguments(Arguments* arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; } + void setCalleeArguments(JSValue arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; } void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; } void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; } @@ -117,32 +118,29 @@ namespace JSC { setScopeChain(scopeChain); setCallerFrame(callerFrame); this[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. - this[RegisterFile::ReturnValueRegister] = returnValueRegister; + this[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister); setArgumentCount(argc); // original argument count (for the sake of the "arguments" object) setCallee(function); - setCalleeArguments(0); + setCalleeArguments(JSValue()); } - private: - friend class Arguments; - friend class JSActivation; - friend class JSGlobalObject; - friend class Interpreter; - friend struct CallFrameClosure; + // Read a register from the codeframe (or constant from the CodeBlock). + inline Register& r(int); + static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); } int returnValueRegister() const { return this[RegisterFile::ReturnValueRegister].i(); } - void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = count; } + bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; } + CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); } + CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); } + + private: + void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = Register::withInt(count); } void setCallee(JSFunction* callee) { this[RegisterFile::Callee] = callee; } void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; } static const intptr_t HostCallFrameFlag = 1; - static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); } - bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; } - CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); } - CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); } - ExecState(); ~ExecState(); }; diff --git a/JavaScriptCore/interpreter/CallFrameClosure.h b/JavaScriptCore/interpreter/CallFrameClosure.h index 0e14ced..9085327 100644 --- a/JavaScriptCore/interpreter/CallFrameClosure.h +++ b/JavaScriptCore/interpreter/CallFrameClosure.h @@ -49,7 +49,7 @@ struct CallFrameClosure { void resetCallFrame() { newCallFrame->setScopeChain(scopeChain); - newCallFrame->setCalleeArguments(0); + newCallFrame->setCalleeArguments(JSValue()); for (int i = providedParams; i < expectedParams; ++i) newCallFrame[i - RegisterFile::CallFrameHeaderSize - expectedParams] = jsUndefined(); } diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index d980962..f102739 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/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 - using namespace std; namespace JSC { @@ -76,7 +73,7 @@ namespace JSC { static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, void* pc) { #if ENABLE(JIT) - return codeBlock->getBytecodeIndex(callFrame, pc); + return codeBlock->getBytecodeIndex(callFrame, ReturnAddressPtr(pc)); #else UNUSED_PARAM(callFrame); return static_cast<Instruction*>(pc) - codeBlock->instructions().begin(); @@ -112,7 +109,7 @@ NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, J exceptionValue = callFrame->globalData().exception; if (exceptionValue) return false; - callFrame[dst] = JSValue(result); + callFrame->r(dst) = JSValue(result); return true; } } while (++iter != end); @@ -145,7 +142,7 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP exceptionValue = callFrame->globalData().exception; if (exceptionValue) return false; - callFrame[dst] = JSValue(result); + callFrame->r(dst) = JSValue(result); return true; } } while (++iter != end); @@ -163,7 +160,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* int offset = (vPC + 5)->u.operand; if (structure == globalObject->structure()) { - callFrame[dst] = JSValue(globalObject->getDirectOffset(offset)); + callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset)); return true; } @@ -178,14 +175,14 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* globalObject->structure()->ref(); vPC[4] = globalObject->structure(); vPC[5] = slot.cachedOffset(); - callFrame[dst] = JSValue(result); + callFrame->r(dst) = JSValue(result); return true; } exceptionValue = callFrame->globalData().exception; if (exceptionValue) return false; - callFrame[dst] = JSValue(result); + callFrame->r(dst) = JSValue(result); return true; } @@ -197,7 +194,7 @@ NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vP { int dst = (vPC + 1)->u.operand; int property = (vPC + 2)->u.operand; - callFrame[dst] = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain())); + callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain())); } NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) @@ -225,8 +222,8 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst exceptionValue = callFrame->globalData().exception; if (exceptionValue) return false; - callFrame[propDst] = JSValue(result); - callFrame[baseDst] = JSValue(base); + callFrame->r(propDst) = JSValue(result); + callFrame->r(baseDst) = JSValue(base); return true; } ++iter; @@ -270,8 +267,8 @@ NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruct if (exceptionValue) return false; - callFrame[baseDst] = JSValue(thisObj); - callFrame[funcDst] = JSValue(result); + callFrame->r(baseDst) = JSValue(thisObj); + callFrame->r(funcDst) = JSValue(result); return true; } ++iter; @@ -350,7 +347,7 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r UString programSource = asString(program)->value(); - LiteralParser preparser(callFrame, programSource); + LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON); if (JSValue parsedObject = preparser.tryLiteralParse()) return parsedObject; @@ -384,77 +381,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()); - ++it; - ++registerCount; - } while (it != end); - } - printf("----------------------------------------------------\n"); - - end = it + codeBlock->m_numConstants; - 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_numConstants - codeBlock->m_numVars; + 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 @@ -567,13 +579,13 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV if (Profiler* profiler = *Profiler::enabledProfilerReference()) { #if !ENABLE(JIT) if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode)) - profiler->didExecute(callFrame, callFrame[codeBlock->instructions()[bytecodeOffset + 2].u.operand].jsValue()); + profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 2].u.operand).jsValue()); else if (codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct)) - profiler->didExecute(callFrame, callFrame[codeBlock->instructions()[bytecodeOffset + 10].u.operand].jsValue()); + profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 10].u.operand).jsValue()); #else int functionRegisterIndex; if (codeBlock->functionRegisterForBytecodeOffset(bytecodeOffset, functionRegisterIndex)) - profiler->didExecute(callFrame, callFrame[functionRegisterIndex].jsValue()); + profiler->didExecute(callFrame, callFrame->r(functionRegisterIndex).jsValue()); #endif } @@ -625,7 +637,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco globalObject->copyGlobalsTo(m_registerFile); CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize); - newCallFrame[codeBlock->thisRegister()] = JSValue(thisObj); + newCallFrame->r(codeBlock->thisRegister()) = JSValue(thisObj); newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), 0, 0, 0); if (codeBlock->needsFullScopeChain()) @@ -682,10 +694,10 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call CallFrame* newCallFrame = CallFrame::create(oldEnd); size_t dst = 0; - newCallFrame[0] = JSValue(thisObj); + newCallFrame->r(0) = JSValue(thisObj); ArgList::const_iterator end = args.end(); for (ArgList::const_iterator it = args.begin(); it != end; ++it) - newCallFrame[++dst] = *it; + newCallFrame->r(++dst) = *it; CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain); newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); @@ -743,7 +755,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod CallFrame* newCallFrame = CallFrame::create(oldEnd); size_t dst = 0; for (int i = 0; i < argc; ++i) - newCallFrame[++dst] = jsUndefined(); + newCallFrame->r(++dst) = jsUndefined(); CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain); newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); @@ -854,7 +866,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset); // a 0 codeBlock indicates a built-in caller - newCallFrame[codeBlock->thisRegister()] = JSValue(thisObj); + newCallFrame->r(codeBlock->thisRegister()) = JSValue(thisObj); newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, 0, 0); if (codeBlock->needsFullScopeChain()) @@ -918,9 +930,9 @@ NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFr int dst = (++vPC)->u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); Identifier& property = codeBlock->identifier((++vPC)->u.operand); - JSValue value = callFrame[(++vPC)->u.operand].jsValue(); + JSValue value = callFrame->r((++vPC)->u.operand).jsValue(); JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete); - callFrame[dst] = JSValue(scope); + callFrame->r(dst) = JSValue(scope); return callFrame->scopeChain()->push(scope); } @@ -970,12 +982,18 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* return; } + StructureChain* protoChain = structure->prototypeChain(callFrame); + if (!protoChain->isCacheable()) { + vPC[0] = getOpcode(op_put_by_id_generic); + return; + } + // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { vPC[0] = getOpcode(op_put_by_id_transition); vPC[4] = structure->previousID(); vPC[5] = structure; - vPC[6] = structure->prototypeChain(callFrame); + vPC[6] = protoChain; vPC[7] = slot.cachedOffset(); codeBlock->refStructures(vPC); return; @@ -1077,9 +1095,15 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* return; } + StructureChain* protoChain = structure->prototypeChain(callFrame); + if (!protoChain->isCacheable()) { + vPC[0] = getOpcode(op_get_by_id_generic); + return; + } + vPC[0] = getOpcode(op_get_by_id_chain); vPC[4] = structure; - vPC[5] = structure->prototypeChain(callFrame); + vPC[5] = protoChain; vPC[6] = count; vPC[7] = slot.cachedOffset(); codeBlock->refStructures(vPC); @@ -1113,7 +1137,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) @@ -1185,7 +1209,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor, and puts the result in register dst. */ int dst = (++vPC)->u.operand; - callFrame[dst] = JSValue(constructEmptyObject(callFrame)); + callFrame->r(dst) = JSValue(constructEmptyObject(callFrame)); ++vPC; NEXT_INSTRUCTION(); @@ -1202,7 +1226,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int firstArg = (++vPC)->u.operand; int argCount = (++vPC)->u.operand; ArgList args(callFrame->registers() + firstArg, argCount); - callFrame[dst] = JSValue(constructArray(callFrame, args)); + callFrame->r(dst) = JSValue(constructArray(callFrame, args)); ++vPC; NEXT_INSTRUCTION(); @@ -1216,7 +1240,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int regExp = (++vPC)->u.operand; - callFrame[dst] = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp))); + callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp))); ++vPC; NEXT_INSTRUCTION(); @@ -1228,7 +1252,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = callFrame[src]; + callFrame->r(dst) = callFrame->r(src); ++vPC; NEXT_INSTRUCTION(); @@ -1241,14 +1265,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame[dst] = JSFastMath::equal(src1, src2); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; @@ -1261,15 +1285,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi operator, and puts the result as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); if (src.isUndefinedOrNull()) { - callFrame[dst] = jsBoolean(true); + callFrame->r(dst) = jsBoolean(true); ++vPC; NEXT_INSTRUCTION(); } - callFrame[dst] = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); + callFrame->r(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); ++vPC; NEXT_INSTRUCTION(); } @@ -1281,14 +1305,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi result as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame[dst] = JSFastMath::notEqual(src1, src2); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; @@ -1301,15 +1325,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi operator, and puts the result as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); if (src.isUndefinedOrNull()) { - callFrame[dst] = jsBoolean(false); + callFrame->r(dst) = jsBoolean(false); ++vPC; NEXT_INSTRUCTION(); } - callFrame[dst] = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined()); + callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined()); ++vPC; NEXT_INSTRUCTION(); } @@ -1321,9 +1345,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi result as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - callFrame[dst] = jsBoolean(JSValue::strictEqual(src1, src2)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + callFrame->r(dst) = jsBoolean(JSValue::strictEqual(src1, src2)); ++vPC; NEXT_INSTRUCTION(); @@ -1336,9 +1360,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi puts the result as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - callFrame[dst] = jsBoolean(!JSValue::strictEqual(src1, src2)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(src1, src2)); ++vPC; NEXT_INSTRUCTION(); @@ -1351,11 +1375,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue result = jsBoolean(jsLess(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); @@ -1368,11 +1392,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi puts the result as a boolean in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); @@ -1384,13 +1408,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi back in register srcDst. */ int srcDst = (++vPC)->u.operand; - JSValue v = callFrame[srcDst].jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) - callFrame[srcDst] = JSValue(JSFastMath::incImmediateNumber(v)); + JSValue v = callFrame->r(srcDst).jsValue(); + 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(); - callFrame[srcDst] = result; + callFrame->r(srcDst) = result; } ++vPC; @@ -1403,13 +1427,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi back in register srcDst. */ int srcDst = (++vPC)->u.operand; - JSValue v = callFrame[srcDst].jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) - callFrame[srcDst] = JSValue(JSFastMath::decImmediateNumber(v)); + JSValue v = callFrame->r(srcDst).jsValue(); + 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(); - callFrame[srcDst] = result; + callFrame->r(srcDst) = result; } ++vPC; @@ -1424,15 +1448,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int srcDst = (++vPC)->u.operand; - JSValue v = callFrame[srcDst].jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) { - callFrame[dst] = v; - callFrame[srcDst] = JSValue(JSFastMath::incImmediateNumber(v)); + JSValue v = callFrame->r(srcDst).jsValue(); + if (v.isInt32() && v.asInt32() < INT_MAX) { + callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); + callFrame->r(dst) = v; } else { - JSValue number = callFrame[srcDst].jsValue().toJSNumber(callFrame); + JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); CHECK_FOR_EXCEPTION(); - callFrame[dst] = number; - callFrame[srcDst] = JSValue(jsNumber(callFrame, number.uncheckedGetNumber() + 1)); + callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() + 1); + callFrame->r(dst) = number; } ++vPC; @@ -1447,15 +1471,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int srcDst = (++vPC)->u.operand; - JSValue v = callFrame[srcDst].jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) { - callFrame[dst] = v; - callFrame[srcDst] = JSValue(JSFastMath::decImmediateNumber(v)); + JSValue v = callFrame->r(srcDst).jsValue(); + if (v.isInt32() && v.asInt32() > INT_MIN) { + callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); + callFrame->r(dst) = v; } else { - JSValue number = callFrame[srcDst].jsValue().toJSNumber(callFrame); + JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); CHECK_FOR_EXCEPTION(); - callFrame[dst] = number; - callFrame[srcDst] = JSValue(jsNumber(callFrame, number.uncheckedGetNumber() - 1)); + callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() - 1); + callFrame->r(dst) = number; } ++vPC; @@ -1470,14 +1494,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - JSValue srcVal = callFrame[src].jsValue(); + JSValue srcVal = callFrame->r(src).jsValue(); if (LIKELY(srcVal.isNumber())) - callFrame[dst] = callFrame[src]; + callFrame->r(dst) = callFrame->r(src); else { JSValue result = srcVal.toJSNumber(callFrame); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; @@ -1490,17 +1514,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi result in register dst. */ int dst = (++vPC)->u.operand; - JSValue src = callFrame[(++vPC)->u.operand].jsValue(); - ++vPC; - double v; - if (src.getNumber(v)) - callFrame[dst] = JSValue(jsNumber(callFrame, -v)); + JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + if (src.isInt32() && src.asInt32()) + callFrame->r(dst) = jsNumber(callFrame, -src.asInt32()); else { JSValue result = jsNumber(callFrame, -src.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; } + ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_add) { @@ -1511,14 +1534,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi numeric add, depending on the types of the operands.) */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(src1, src2)) - callFrame[dst] = JSValue(JSFastMath::addImmediateNumbers(src1, src2)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } vPC += 2; NEXT_INSTRUCTION(); @@ -1530,23 +1553,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi numbers), and puts the product in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++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[dst] = JSValue(jsNumber(callFrame, left * right)); - else - callFrame[dst] = JSValue(jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right))); - } else if (src1.getNumber(left) && src2.getNumber(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left * right)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } vPC += 2; @@ -1560,18 +1574,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi quotient in register dst. */ int dst = (++vPC)->u.operand; - JSValue dividend = callFrame[(++vPC)->u.operand].jsValue(); - JSValue divisor = callFrame[(++vPC)->u.operand].jsValue(); - double left; - double right; - if (dividend.getNumber(left) && divisor.getNumber(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left / right)); - else { - JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); - CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; - } - ++vPC; + JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); + + 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) { @@ -1582,26 +1592,24 @@ 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[dividend].jsValue(); - JSValue divisorValue = callFrame[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[dst] = 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[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); } @@ -1613,18 +1621,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - double left; - double right; - if (JSFastMath::canDoFastAdditiveOperations(src1, src2)) - callFrame[dst] = JSValue(JSFastMath::subImmediateNumbers(src1, src2)); - else if (src1.getNumber(left) && src2.getNumber(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left - right)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } vPC += 2; NEXT_INSTRUCTION(); @@ -1637,18 +1641,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. */ int dst = (++vPC)->u.operand; - JSValue val = callFrame[(++vPC)->u.operand].jsValue(); - JSValue shift = callFrame[(++vPC)->u.operand].jsValue(); - int32_t left; - uint32_t right; - if (JSValue::areBothInt32Fast(val, shift)) - callFrame[dst] = JSValue(jsNumber(callFrame, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f))); - else if (val.numberToInt32(left) && shift.numberToUInt32(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left << (right & 0x1f))); + JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; @@ -1662,18 +1663,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi uint32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; - JSValue val = callFrame[(++vPC)->u.operand].jsValue(); - JSValue shift = callFrame[(++vPC)->u.operand].jsValue(); - int32_t left; - uint32_t right; - if (JSFastMath::canDoFastRshift(val, shift)) - callFrame[dst] = JSValue(JSFastMath::rightShiftImmediateNumbers(val, shift)); - else if (val.numberToInt32(left) && shift.numberToUInt32(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left >> (right & 0x1f))); + JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; @@ -1687,14 +1685,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi uint32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; - JSValue val = callFrame[(++vPC)->u.operand].jsValue(); - JSValue shift = callFrame[(++vPC)->u.operand].jsValue(); - if (JSFastMath::canDoFastUrshift(val, shift)) - callFrame[dst] = JSValue(JSFastMath::rightShiftImmediateNumbers(val, shift)); + JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; @@ -1708,18 +1706,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - int32_t left; - int32_t right; - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame[dst] = JSValue(JSFastMath::andImmediateNumbers(src1, src2)); - else if (src1.numberToInt32(left) && src2.numberToInt32(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left & right)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } vPC += 2; @@ -1733,18 +1727,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - int32_t left; - int32_t right; - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame[dst] = JSValue(JSFastMath::xorImmediateNumbers(src1, src2)); - else if (src1.numberToInt32(left) && src2.numberToInt32(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left ^ right)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } vPC += 2; @@ -1758,18 +1748,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi result in register dst. */ int dst = (++vPC)->u.operand; - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); - int32_t left; - int32_t right; - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame[dst] = JSValue(JSFastMath::orImmediateNumbers(src1, src2)); - else if (src1.numberToInt32(left) && src2.numberToInt32(right)) - callFrame[dst] = JSValue(jsNumber(callFrame, left | right)); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + 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(); - callFrame[dst] = result; + callFrame->r(dst) = result; } vPC += 2; @@ -1782,14 +1768,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and puts the result in register dst. */ int dst = (++vPC)->u.operand; - JSValue src = callFrame[(++vPC)->u.operand].jsValue(); - int32_t value; - if (src.numberToInt32(value)) - callFrame[dst] = JSValue(jsNumber(callFrame, ~value)); + JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + if (src.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32()); else { JSValue result = jsNumber(callFrame, ~src.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; } ++vPC; NEXT_INSTRUCTION(); @@ -1802,9 +1787,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - JSValue result = jsBoolean(!callFrame[src].jsValue().toBoolean(callFrame)); + JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); @@ -1827,14 +1812,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int base = vPC[3].u.operand; int baseProto = vPC[4].u.operand; - JSValue baseVal = callFrame[base].jsValue(); + JSValue baseVal = callFrame->r(base).jsValue(); if (isInvalidParamForInstanceOf(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue)) goto vm_throw; - bool result = asObject(baseVal)->hasInstance(callFrame, callFrame[value].jsValue(), callFrame[baseProto].jsValue()); + bool result = asObject(baseVal)->hasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue()); CHECK_FOR_EXCEPTION(); - callFrame[dst] = jsBoolean(result); + callFrame->r(dst) = jsBoolean(result); vPC += 5; NEXT_INSTRUCTION(); @@ -1847,7 +1832,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = JSValue(jsTypeStringForValue(callFrame, callFrame[src].jsValue())); + callFrame->r(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue())); ++vPC; NEXT_INSTRUCTION(); @@ -1861,8 +1846,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - JSValue v = callFrame[src].jsValue(); - callFrame[dst] = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()); + JSValue v = callFrame->r(src).jsValue(); + callFrame->r(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()); ++vPC; NEXT_INSTRUCTION(); @@ -1876,7 +1861,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = jsBoolean(callFrame[src].jsValue().isBoolean()); + callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean()); ++vPC; NEXT_INSTRUCTION(); @@ -1890,7 +1875,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = jsBoolean(callFrame[src].jsValue().isNumber()); + callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber()); ++vPC; NEXT_INSTRUCTION(); @@ -1904,7 +1889,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = jsBoolean(callFrame[src].jsValue().isString()); + callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isString()); ++vPC; NEXT_INSTRUCTION(); @@ -1918,7 +1903,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = jsBoolean(jsIsObjectType(callFrame[src].jsValue())); + callFrame->r(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue())); ++vPC; NEXT_INSTRUCTION(); @@ -1932,7 +1917,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = jsBoolean(jsIsFunctionType(callFrame[src].jsValue())); + callFrame->r(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue())); ++vPC; NEXT_INSTRUCTION(); @@ -1950,21 +1935,21 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int property = (++vPC)->u.operand; int base = (++vPC)->u.operand; - JSValue baseVal = callFrame[base].jsValue(); + JSValue baseVal = callFrame->r(base).jsValue(); if (isInvalidParamForIn(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue)) goto vm_throw; JSObject* baseObj = asObject(baseVal); - JSValue propName = callFrame[property].jsValue(); + JSValue propName = callFrame->r(property).jsValue(); uint32_t i; if (propName.getUInt32(i)) - callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, i)); + callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, i)); else { Identifier property(callFrame, propName.toString(callFrame)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, property)); + callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, property)); } ++vPC; @@ -2022,7 +2007,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(scope->isGlobalObject()); int index = (++vPC)->u.operand; - callFrame[dst] = scope->registerAt(index); + callFrame->r(dst) = scope->registerAt(index); ++vPC; NEXT_INSTRUCTION(); } @@ -2036,7 +2021,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int index = (++vPC)->u.operand; int value = (++vPC)->u.operand; - scope->registerAt(index) = JSValue(callFrame[value].jsValue()); + scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); ++vPC; NEXT_INSTRUCTION(); } @@ -2061,7 +2046,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT((*iter)->isVariableObject()); JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); - callFrame[dst] = scope->registerAt(index); + callFrame->r(dst) = scope->registerAt(index); ++vPC; NEXT_INSTRUCTION(); } @@ -2084,7 +2069,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT((*iter)->isVariableObject()); JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); - scope->registerAt(index) = JSValue(callFrame[value].jsValue()); + scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); ++vPC; NEXT_INSTRUCTION(); } @@ -2119,27 +2104,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) @@ -2152,14 +2116,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CodeBlock* codeBlock = callFrame->codeBlock(); Identifier& ident = codeBlock->identifier(property); - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); PropertySlot slot(baseValue); JSValue result = baseValue.get(callFrame, ident, slot); CHECK_FOR_EXCEPTION(); tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot); - callFrame[dst] = result; + callFrame->r(dst) = result; vPC += 8; NEXT_INSTRUCTION(); } @@ -2171,7 +2135,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi op_get_by_id. */ int base = vPC[2].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(baseValue.isCell())) { JSCell* baseCell = asCell(baseValue); @@ -2184,7 +2148,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int offset = vPC[5].u.operand; ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); - callFrame[dst] = JSValue(baseObject->getDirectOffset(offset)); + callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset)); vPC += 8; NEXT_INSTRUCTION(); @@ -2202,7 +2166,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi reverts to op_get_by_id. */ int base = vPC[2].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(baseValue.isCell())) { JSCell* baseCell = asCell(baseValue); @@ -2218,7 +2182,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int offset = vPC[6].u.operand; ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); - callFrame[dst] = JSValue(protoObject->getDirectOffset(offset)); + callFrame->r(dst) = JSValue(protoObject->getDirectOffset(offset)); vPC += 8; NEXT_INSTRUCTION(); @@ -2251,7 +2215,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi reverts to op_get_by_id. */ int base = vPC[2].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(baseValue.isCell())) { JSCell* baseCell = asCell(baseValue); @@ -2273,7 +2237,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int offset = vPC[7].u.operand; ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); - callFrame[dst] = JSValue(baseObject->getDirectOffset(offset)); + callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset)); vPC += 8; NEXT_INSTRUCTION(); @@ -2299,12 +2263,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int property = vPC[3].u.operand; Identifier& ident = callFrame->codeBlock()->identifier(property); - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); PropertySlot slot(baseValue); JSValue result = baseValue.get(callFrame, ident, slot); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; vPC += 8; NEXT_INSTRUCTION(); } @@ -2317,10 +2281,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int base = vPC[2].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(isJSArray(globalData, baseValue))) { int dst = vPC[1].u.operand; - callFrame[dst] = JSValue(jsNumber(callFrame, asArray(baseValue)->length())); + callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length()); vPC += 8; NEXT_INSTRUCTION(); } @@ -2337,10 +2301,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int base = vPC[2].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(isJSString(globalData, baseValue))) { int dst = vPC[1].u.operand; - callFrame[dst] = JSValue(jsNumber(callFrame, asString(baseValue)->value().size())); + callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size()); vPC += 8; NEXT_INSTRUCTION(); } @@ -2363,10 +2327,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int value = vPC[3].u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); Identifier& ident = codeBlock->identifier(property); PutPropertySlot slot; - baseValue.put(callFrame, ident, callFrame[value].jsValue(), slot); + baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); CHECK_FOR_EXCEPTION(); tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot); @@ -2386,7 +2350,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the register file. */ int base = vPC[1].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(baseValue.isCell())) { JSCell* baseCell = asCell(baseValue); @@ -2414,7 +2378,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int value = vPC[3].u.operand; unsigned offset = vPC[7].u.operand; ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset); - baseObject->putDirectOffset(offset, callFrame[value].jsValue()); + baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); vPC += 8; NEXT_INSTRUCTION(); @@ -2436,7 +2400,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the register file. */ int base = vPC[1].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(baseValue.isCell())) { JSCell* baseCell = asCell(baseValue); @@ -2449,7 +2413,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi unsigned offset = vPC[5].u.operand; ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset); - baseObject->putDirectOffset(offset, callFrame[value].jsValue()); + baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); vPC += 8; NEXT_INSTRUCTION(); @@ -2472,10 +2436,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int property = vPC[2].u.operand; int value = vPC[3].u.operand; - JSValue baseValue = callFrame[base].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); Identifier& ident = callFrame->codeBlock()->identifier(property); PutPropertySlot slot; - baseValue.put(callFrame, ident, callFrame[value].jsValue(), slot); + baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); CHECK_FOR_EXCEPTION(); vPC += 8; @@ -2493,11 +2457,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int base = (++vPC)->u.operand; int property = (++vPC)->u.operand; - JSObject* baseObj = callFrame[base].jsValue().toObject(callFrame); + JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); Identifier& ident = callFrame->codeBlock()->identifier(property); JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident)); CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); } @@ -2513,13 +2477,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int base = (++vPC)->u.operand; int property = (++vPC)->u.operand; - JSValue baseValue = callFrame[base].jsValue(); - JSValue subscript = callFrame[property].jsValue(); + JSValue baseValue = callFrame->r(base).jsValue(); + JSValue subscript = callFrame->r(property).jsValue(); 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)) @@ -2538,7 +2502,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); } @@ -2557,34 +2521,34 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int property = (++vPC)->u.operand; int value = (++vPC)->u.operand; - JSValue baseValue = callFrame[base].jsValue(); - JSValue subscript = callFrame[property].jsValue(); + 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)) - jsArray->setIndex(i, callFrame[value].jsValue()); + jsArray->setIndex(i, callFrame->r(value).jsValue()); else - jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue()); + jsArray->JSArray::put(callFrame, i, callFrame->r(value).jsValue()); } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { JSByteArray* jsByteArray = asByteArray(baseValue); double dValue = 0; - JSValue jsValue = callFrame[value].jsValue(); - if (jsValue.isInt32Fast()) - jsByteArray->setIndex(i, jsValue.getInt32Fast()); + JSValue jsValue = callFrame->r(value).jsValue(); + if (jsValue.isInt32()) + jsByteArray->setIndex(i, jsValue.asInt32()); else if (jsValue.getNumber(dValue)) jsByteArray->setIndex(i, dValue); else baseValue.put(callFrame, i, jsValue); } else - baseValue.put(callFrame, i, callFrame[value].jsValue()); + baseValue.put(callFrame, i, callFrame->r(value).jsValue()); } else { Identifier property(callFrame, subscript.toString(callFrame)); if (!globalData->exception) { // Don't put to an object if toString threw an exception. PutPropertySlot slot; - baseValue.put(callFrame, property, callFrame[value].jsValue(), slot); + baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot); } } @@ -2604,9 +2568,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int base = (++vPC)->u.operand; int property = (++vPC)->u.operand; - JSObject* baseObj = callFrame[base].jsValue().toObject(callFrame); // may throw + JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw - JSValue subscript = callFrame[property].jsValue(); + JSValue subscript = callFrame->r(property).jsValue(); JSValue result; uint32_t i; if (subscript.getUInt32(i)) @@ -2619,7 +2583,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - callFrame[dst] = result; + callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); } @@ -2639,7 +2603,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi unsigned property = (++vPC)->u.operand; int value = (++vPC)->u.operand; - callFrame[base].jsValue().put(callFrame, property, callFrame[value].jsValue()); + callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue()); ++vPC; NEXT_INSTRUCTION(); @@ -2686,7 +2650,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int cond = (++vPC)->u.operand; int target = (++vPC)->u.operand; - if (callFrame[cond].jsValue().toBoolean(callFrame)) { + if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; CHECK_FOR_TIMEOUT(); NEXT_INSTRUCTION(); @@ -2703,7 +2667,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int cond = (++vPC)->u.operand; int target = (++vPC)->u.operand; - if (callFrame[cond].jsValue().toBoolean(callFrame)) { + if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; NEXT_INSTRUCTION(); } @@ -2719,7 +2683,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int cond = (++vPC)->u.operand; int target = (++vPC)->u.operand; - if (!callFrame[cond].jsValue().toBoolean(callFrame)) { + if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; NEXT_INSTRUCTION(); } @@ -2735,7 +2699,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int src = (++vPC)->u.operand; int target = (++vPC)->u.operand; - JSValue srcValue = callFrame[src].jsValue(); + JSValue srcValue = callFrame->r(src).jsValue(); if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { vPC += target; @@ -2753,7 +2717,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int src = (++vPC)->u.operand; int target = (++vPC)->u.operand; - JSValue srcValue = callFrame[src].jsValue(); + JSValue srcValue = callFrame->r(src).jsValue(); if (!srcValue.isUndefinedOrNull() || (srcValue.isCell() && !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { vPC += target; @@ -2772,7 +2736,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int src = (++vPC)->u.operand; JSValue ptr = JSValue((++vPC)->u.jsCell); int target = (++vPC)->u.operand; - JSValue srcValue = callFrame[src].jsValue(); + JSValue srcValue = callFrame->r(src).jsValue(); if (srcValue != ptr) { vPC += target; NEXT_INSTRUCTION(); @@ -2792,8 +2756,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); int target = (++vPC)->u.operand; bool result = jsLess(callFrame, src1, src2); @@ -2819,8 +2783,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); int target = (++vPC)->u.operand; bool result = jsLessEq(callFrame, src1, src2); @@ -2843,8 +2807,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi target from the current instruction, if and only if the result of the comparison is false. */ - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); int target = (++vPC)->u.operand; bool result = jsLess(callFrame, src1, src2); @@ -2866,8 +2830,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and then jumps to offset target from the current instruction, if and only if theresult of the comparison is false. */ - JSValue src1 = callFrame[(++vPC)->u.operand].jsValue(); - JSValue src2 = callFrame[(++vPC)->u.operand].jsValue(); + JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); int target = (++vPC)->u.operand; bool result = jsLessEq(callFrame, src1, src2); @@ -2892,9 +2856,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int tableIndex = (++vPC)->u.operand; int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame[(++vPC)->u.operand].jsValue(); - if (scrutinee.isInt32Fast()) - vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.getInt32Fast(), defaultOffset); + JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + if (scrutinee.isInt32()) + vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset); else { double value; int32_t intValue; @@ -2916,7 +2880,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int tableIndex = (++vPC)->u.operand; int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame[(++vPC)->u.operand].jsValue(); + JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); if (!scrutinee.isString()) vPC += defaultOffset; else { @@ -2939,7 +2903,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int tableIndex = (++vPC)->u.operand; int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame[(++vPC)->u.operand].jsValue(); + JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); if (!scrutinee.isString()) vPC += defaultOffset; else @@ -2957,7 +2921,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int func = (++vPC)->u.operand; - callFrame[dst] = callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain()); + callFrame->r(dst) = JSValue(callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain())); ++vPC; NEXT_INSTRUCTION(); @@ -2973,7 +2937,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int func = (++vPC)->u.operand; - callFrame[dst] = callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain()); + callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain())); ++vPC; NEXT_INSTRUCTION(); @@ -2995,7 +2959,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int argCount = vPC[3].u.operand; int registerOffset = vPC[4].u.operand; - JSValue funcVal = callFrame[func].jsValue(); + JSValue funcVal = callFrame->r(func).jsValue(); Register* newCallFrame = callFrame->registers() + registerOffset; Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount; @@ -3006,7 +2970,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue); if (exceptionValue) goto vm_throw; - callFrame[dst] = result; + callFrame->r(dst) = result; vPC += 5; NEXT_INSTRUCTION(); @@ -3032,7 +2996,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int argCount = vPC[3].u.operand; int registerOffset = vPC[4].u.operand; - JSValue v = callFrame[func].jsValue(); + JSValue v = callFrame->r(func).jsValue(); CallData callData; CallType callType = v.getCallData(callData); @@ -3081,7 +3045,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - callFrame[dst] = JSValue(returnValue); + callFrame->r(dst) = returnValue; vPC += 5; NEXT_INSTRUCTION(); @@ -3096,19 +3060,19 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int argCountDst = (++vPC)->u.operand; int argsOffset = (++vPC)->u.operand; - JSValue arguments = callFrame[argsOffset].jsValue(); - uint32_t argCount = 0; + JSValue arguments = callFrame->r(argsOffset).jsValue(); + int32_t argCount = 0; if (!arguments) { - argCount = (uint32_t)(callFrame[RegisterFile::ArgumentCount].u.i) - 1; + argCount = (uint32_t)(callFrame->argumentCount()) - 1; int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { exceptionValue = createStackOverflowError(callFrame); goto vm_throw; } - uint32_t expectedParams = asFunction(callFrame[RegisterFile::Callee].jsValue())->body()->parameterCount(); - uint32_t inplaceArgs = min(argCount, expectedParams); - uint32_t i = 0; + int32_t expectedParams = callFrame->callee()->body()->parameterCount(); + int32_t inplaceArgs = min(argCount, expectedParams); + int32_t i = 0; Register* argStore = callFrame->registers() + argsOffset; // First step is to copy the "expected" parameters from their normal location relative to the callframe @@ -3152,7 +3116,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi goto vm_throw; } Register* argsBuffer = callFrame->registers() + argsOffset; - for (unsigned i = 0; i < argCount; ++i) { + for (int32_t i = 0; i < argCount; ++i) { argsBuffer[i] = asObject(arguments)->get(callFrame, i); CHECK_FOR_EXCEPTION(); } @@ -3164,7 +3128,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } } CHECK_FOR_EXCEPTION(); - callFrame[argCountDst] = argCount + 1; + callFrame->r(argCountDst) = Register::withInt(argCount + 1); ++vPC; NEXT_INSTRUCTION(); } @@ -3185,8 +3149,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int argCountReg = vPC[3].u.operand; int registerOffset = vPC[4].u.operand; - JSValue v = callFrame[func].jsValue(); - int argCount = callFrame[argCountReg].i(); + JSValue v = callFrame->r(func).jsValue(); + int argCount = callFrame->r(argCountReg).i(); registerOffset += argCount; CallData callData; CallType callType = v.getCallData(callData); @@ -3235,7 +3199,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - callFrame[dst] = JSValue(returnValue); + callFrame->r(dst) = returnValue; vPC += 5; NEXT_INSTRUCTION(); @@ -3262,7 +3226,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int src = (++vPC)->u.operand; ASSERT(callFrame->codeBlock()->needsFullScopeChain()); - asActivation(callFrame[src].jsValue())->copyRegisters(callFrame->optionalCalleeArguments()); + asActivation(callFrame->r(src).jsValue())->copyRegisters(callFrame->optionalCalleeArguments()); ++vPC; NEXT_INSTRUCTION(); @@ -3281,6 +3245,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain()); + if (callFrame->optionalCalleeArguments()) callFrame->optionalCalleeArguments()->copyRegisters(); @@ -3302,7 +3267,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callFrame->codeBlock()->needsFullScopeChain()) callFrame->scopeChain()->deref(); - JSValue returnValue = callFrame[result].jsValue(); + JSValue returnValue = callFrame->r(result).jsValue(); vPC = callFrame->returnPC(); int dst = callFrame->returnValueRegister(); @@ -3311,7 +3276,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callFrame->hasHostCallFrameFlag()) return returnValue; - callFrame[dst] = JSValue(returnValue); + callFrame->r(dst) = returnValue; NEXT_INSTRUCTION(); } @@ -3330,10 +3295,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CodeBlock* codeBlock = callFrame->codeBlock(); for (size_t count = codeBlock->m_numVars; i < count; ++i) - callFrame[i] = jsUndefined(); - - for (size_t count = codeBlock->numberOfConstantRegisters(), j = 0; j < count; ++i, ++j) - callFrame[i] = codeBlock->constantRegister(j); + callFrame->r(i) = jsUndefined(); ++vPC; NEXT_INSTRUCTION(); @@ -3355,14 +3317,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CodeBlock* codeBlock = callFrame->codeBlock(); for (size_t count = codeBlock->m_numVars; i < count; ++i) - callFrame[i] = jsUndefined(); - - for (size_t count = codeBlock->numberOfConstantRegisters(), j = 0; j < count; ++i, ++j) - callFrame[i] = codeBlock->constantRegister(j); + callFrame->r(i) = jsUndefined(); int dst = (++vPC)->u.operand; JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode())); - callFrame[dst] = activation; + callFrame->r(dst) = JSValue(activation); callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); ++vPC; @@ -3381,9 +3340,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int thisRegister = (++vPC)->u.operand; - JSValue thisVal = callFrame[thisRegister].jsValue(); + JSValue thisVal = callFrame->r(thisRegister).jsValue(); if (thisVal.needsThisConversion()) - callFrame[thisRegister] = JSValue(thisVal.toThisObject(callFrame)); + callFrame->r(thisRegister) = JSValue(thisVal.toThisObject(callFrame)); ++vPC; NEXT_INSTRUCTION(); @@ -3398,7 +3357,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi This opcode should only be used at the beginning of a code block. */ - callFrame[RegisterFile::ArgumentsRegister] = JSValue(); + callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(); ++vPC; NEXT_INSTRUCTION(); } @@ -3410,10 +3369,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register, if it has not already been initialised. */ - if (!callFrame->optionalCalleeArguments()) { + if (!callFrame->r(RegisterFile::ArgumentsRegister).jsValue()) { Arguments* arguments = new (globalData) Arguments(callFrame); callFrame->setCalleeArguments(arguments); - callFrame[RegisterFile::ArgumentsRegister] = arguments; + callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments); } ++vPC; NEXT_INSTRUCTION(); @@ -3440,7 +3399,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int proto = vPC[5].u.operand; int thisRegister = vPC[6].u.operand; - JSValue v = callFrame[func].jsValue(); + JSValue v = callFrame->r(func).jsValue(); ConstructData constructData; ConstructType constructType = v.getConstructData(constructData); @@ -3451,14 +3410,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain); Structure* structure; - JSValue prototype = callFrame[proto].jsValue(); + JSValue prototype = callFrame->r(proto).jsValue(); if (prototype.isObject()) structure = asObject(prototype)->inheritorID(); else structure = callDataScopeChain->globalObject()->emptyObjectStructure(); JSObject* newObject = new (globalData) JSObject(structure); - callFrame[thisRegister] = JSValue(newObject); // "this" value + callFrame->r(thisRegister) = JSValue(newObject); // "this" value CallFrame* previousCallFrame = callFrame; @@ -3492,7 +3451,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi returnValue = constructData.native.function(newCallFrame, asObject(v), args); } CHECK_FOR_EXCEPTION(); - callFrame[dst] = JSValue(returnValue); + callFrame->r(dst) = JSValue(returnValue); vPC += 7; NEXT_INSTRUCTION(); @@ -3511,13 +3470,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = vPC[1].u.operand; - if (LIKELY(callFrame[dst].jsValue().isObject())) { + if (LIKELY(callFrame->r(dst).jsValue().isObject())) { vPC += 3; NEXT_INSTRUCTION(); } int override = vPC[2].u.operand; - callFrame[dst] = callFrame[override]; + callFrame->r(dst) = callFrame->r(override); vPC += 3; NEXT_INSTRUCTION(); @@ -3527,7 +3486,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int src = (++vPC)->u.operand; int count = (++vPC)->u.operand; - callFrame[dst] = concatenateStrings(callFrame, &callFrame->registers()[src], count); + callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count); ++vPC; NEXT_INSTRUCTION(); @@ -3536,7 +3495,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; - callFrame[dst] = callFrame[src].jsValue().toPrimitive(callFrame); + callFrame->r(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame); ++vPC; NEXT_INSTRUCTION(); @@ -3549,11 +3508,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi are replaced by the result of toObject conversion of the scope. */ int scope = (++vPC)->u.operand; - JSValue v = callFrame[scope].jsValue(); + JSValue v = callFrame->r(scope).jsValue(); JSObject* o = v.toObject(callFrame); CHECK_FOR_EXCEPTION(); - callFrame[scope] = JSValue(o); + callFrame->r(scope) = JSValue(o); callFrame->setScopeChain(callFrame->scopeChain()->push(o)); ++vPC; @@ -3580,7 +3539,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int base = (++vPC)->u.operand; - callFrame[dst] = JSPropertyNameIterator::create(callFrame, callFrame[base].jsValue()); + callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue()); ++vPC; NEXT_INSTRUCTION(); } @@ -3597,10 +3556,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int iter = (++vPC)->u.operand; int target = (++vPC)->u.operand; - JSPropertyNameIterator* it = callFrame[iter].propertyNameIterator(); + JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); if (JSValue temp = it->next(callFrame)) { CHECK_FOR_TIMEOUT(); - callFrame[dst] = JSValue(temp); + callFrame->r(dst) = JSValue(temp); vPC += target; NEXT_INSTRUCTION(); } @@ -3656,7 +3615,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(exceptionValue); ASSERT(!globalData->exception); int ex = (++vPC)->u.operand; - callFrame[ex] = exceptionValue; + callFrame->r(ex) = exceptionValue; exceptionValue = JSValue(); ++vPC; @@ -3674,7 +3633,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int ex = (++vPC)->u.operand; - exceptionValue = callFrame[ex].jsValue(); + exceptionValue = callFrame->r(ex).jsValue(); handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true); if (!handler) { @@ -3685,18 +3644,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi vPC = callFrame->codeBlock()->instructions().begin() + handler->target; NEXT_INSTRUCTION(); } - DEFINE_OPCODE(op_unexpected_load) { - /* unexpected_load load dst(r) src(k) - - Copies constant src to register dst. - */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; - callFrame[dst] = JSValue(callFrame->codeBlock()->unexpectedConstant(src)); - - ++vPC; - NEXT_INSTRUCTION(); - } DEFINE_OPCODE(op_new_error) { /* new_error dst(r) type(n) message(k) @@ -3710,7 +3657,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int message = (++vPC)->u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); - callFrame[dst] = JSValue(Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstant(message).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->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL())); ++vPC; NEXT_INSTRUCTION(); @@ -3728,7 +3675,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi scopeChain->deref(); } int result = (++vPC)->u.operand; - return callFrame[result].jsValue(); + return callFrame->r(result).jsValue(); } DEFINE_OPCODE(op_put_getter) { /* put_getter base(r) property(id) function(r) @@ -3745,11 +3692,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int property = (++vPC)->u.operand; int function = (++vPC)->u.operand; - ASSERT(callFrame[base].jsValue().isObject()); - JSObject* baseObj = asObject(callFrame[base].jsValue()); + ASSERT(callFrame->r(base).jsValue().isObject()); + JSObject* baseObj = asObject(callFrame->r(base).jsValue()); Identifier& ident = callFrame->codeBlock()->identifier(property); - ASSERT(callFrame[function].jsValue().isObject()); - baseObj->defineGetter(callFrame, ident, asObject(callFrame[function].jsValue())); + ASSERT(callFrame->r(function).jsValue().isObject()); + baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); ++vPC; NEXT_INSTRUCTION(); @@ -3769,11 +3716,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int property = (++vPC)->u.operand; int function = (++vPC)->u.operand; - ASSERT(callFrame[base].jsValue().isObject()); - JSObject* baseObj = asObject(callFrame[base].jsValue()); + ASSERT(callFrame->r(base).jsValue().isObject()); + JSObject* baseObj = asObject(callFrame->r(base).jsValue()); Identifier& ident = callFrame->codeBlock()->identifier(property); - ASSERT(callFrame[function].jsValue().isObject()); - baseObj->defineSetter(callFrame, ident, asObject(callFrame[function].jsValue())); + ASSERT(callFrame->r(function).jsValue().isObject()); + baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); ++vPC; NEXT_INSTRUCTION(); @@ -3790,7 +3737,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int retAddrDst = (++vPC)->u.operand; int target = (++vPC)->u.operand; - callFrame[retAddrDst] = vPC + 1; + callFrame->r(retAddrDst) = vPC + 1; vPC += target; NEXT_INSTRUCTION(); @@ -3803,7 +3750,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register, not as an immediate. */ int retAddrSrc = (++vPC)->u.operand; - vPC = callFrame[retAddrSrc].vPC(); + vPC = callFrame->r(retAddrSrc).vPC(); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_debug) { @@ -3830,7 +3777,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int function = vPC[1].u.operand; if (*enabledProfilerReference) - (*enabledProfilerReference)->willExecute(callFrame, callFrame[function].jsValue()); + (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue()); vPC += 2; NEXT_INSTRUCTION(); @@ -3844,7 +3791,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int function = vPC[1].u.operand; if (*enabledProfilerReference) - (*enabledProfilerReference)->didExecute(callFrame, callFrame[function].jsValue()); + (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue()); vPC += 2; NEXT_INSTRUCTION(); @@ -3887,12 +3834,12 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio ASSERT(codeBlock->codeType() == FunctionCode); SymbolTable& symbolTable = codeBlock->symbolTable(); int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex(); - if (!functionCallFrame[argumentsIndex].arguments()) { + if (!functionCallFrame->r(argumentsIndex).jsValue()) { Arguments* arguments = new (callFrame) Arguments(functionCallFrame); functionCallFrame->setCalleeArguments(arguments); - functionCallFrame[RegisterFile::ArgumentsRegister] = arguments; + functionCallFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments); } - return functionCallFrame[argumentsIndex].jsValue(); + return functionCallFrame->r(argumentsIndex).jsValue(); } Arguments* arguments = functionCallFrame->optionalCalleeArguments(); diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h index 7cab254..519c508 100644 --- a/JavaScriptCore/interpreter/Interpreter.h +++ b/JavaScriptCore/interpreter/Interpreter.h @@ -31,21 +31,20 @@ #include "ArgList.h" #include "FastAllocBase.h" -#include "HashMap.h" #include "JSCell.h" #include "JSValue.h" #include "JSObject.h" #include "Opcode.h" #include "RegisterFile.h" +#include <wtf/HashMap.h> + namespace JSC { class CodeBlock; class EvalNode; class FunctionBodyNode; - class Instruction; class InternalFunction; - class AssemblerBuffer; class JSFunction; class JSGlobalObject; class ProgramNode; @@ -54,7 +53,8 @@ namespace JSC { class SamplingTool; struct CallFrameClosure; struct HandlerInfo; - + struct Instruction; + enum DebugHookID { WillExecuteProgram, DidExecuteProgram, @@ -66,7 +66,7 @@ namespace JSC { enum { MaxMainThreadReentryDepth = 256, MaxSecondaryThreadReentryDepth = 32 }; - class Interpreter : public WTF::FastAllocBase { + class Interpreter : public FastAllocBase { friend class JIT; friend class CachedCall; public: diff --git a/JavaScriptCore/interpreter/Register.h b/JavaScriptCore/interpreter/Register.h index cceac74..95ae5f6 100644 --- a/JavaScriptCore/interpreter/Register.h +++ b/JavaScriptCore/interpreter/Register.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +31,7 @@ #include "JSValue.h" #include <wtf/Assertions.h> +#include <wtf/FastAllocBase.h> #include <wtf/VectorTraits.h> namespace JSC { @@ -47,28 +48,16 @@ namespace JSC { typedef ExecState CallFrame; - class Register { + class Register : public WTF::FastAllocBase { public: Register(); Register(JSValue); - Register(Arguments*); JSValue jsValue() const; bool marked() const; - void mark(); + void markChildren(MarkStack&); - int32_t i() const; - void* v() const; - - private: - friend class ExecState; - friend class Interpreter; - - // Only CallFrame, Interpreter, and JITStubs should use these functions. - - Register(intptr_t); - Register(JSActivation*); Register(CallFrame*); Register(CodeBlock*); @@ -77,6 +66,7 @@ namespace JSC { Register(ScopeChainNode*); Register(Instruction*); + int32_t i() const; JSActivation* activation() const; Arguments* arguments() const; CallFrame* callFrame() const; @@ -86,13 +76,19 @@ namespace JSC { ScopeChainNode* scopeChain() const; Instruction* vPC() const; + static Register withInt(int32_t i) + { + return Register(i); + } + + private: + Register(int32_t); + union { - intptr_t i; - void* v; + int32_t i; EncodedJSValue value; JSActivation* activation; - Arguments* arguments; CallFrame* callFrame; CodeBlock* codeBlock; JSFunction* function; @@ -124,18 +120,8 @@ namespace JSC { return jsValue().marked(); } - ALWAYS_INLINE void Register::mark() - { - jsValue().mark(); - } - // Interpreter functions - ALWAYS_INLINE Register::Register(Arguments* arguments) - { - u.arguments = arguments; - } - ALWAYS_INLINE Register::Register(JSActivation* activation) { u.activation = activation; @@ -171,35 +157,21 @@ namespace JSC { u.propertyNameIterator = propertyNameIterator; } - ALWAYS_INLINE Register::Register(intptr_t i) + ALWAYS_INLINE Register::Register(int32_t i) { - // See comment on 'i()' below. - ASSERT(i == static_cast<int32_t>(i)); u.i = i; } - // Read 'i' as a 32-bit integer; we only use it to hold 32-bit values, - // and we only write 32-bits when writing the arg count from JIT code. ALWAYS_INLINE int32_t Register::i() const { - return static_cast<int32_t>(u.i); + return u.i; } - ALWAYS_INLINE void* Register::v() const - { - return u.v; - } - ALWAYS_INLINE JSActivation* Register::activation() const { return u.activation; } - ALWAYS_INLINE Arguments* Register::arguments() const - { - return u.arguments; - } - ALWAYS_INLINE CallFrame* Register::callFrame() const { return u.callFrame; diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h index 09a3963..b5f7452 100644 --- a/JavaScriptCore/interpreter/RegisterFile.h +++ b/JavaScriptCore/interpreter/RegisterFile.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,12 +32,12 @@ #include "Collector.h" #include "ExecutableAllocator.h" #include "Register.h" +#include <stdio.h> #include <wtf/Noncopyable.h> #include <wtf/VMTags.h> #if HAVE(MMAP) #include <errno.h> -#include <stdio.h> #include <sys/mman.h> #endif @@ -92,7 +92,7 @@ namespace JSC { class JSGlobalObject; - class RegisterFile : Noncopyable { + class RegisterFile : public Noncopyable { friend class JIT; public: enum CallFrameHeaderEntry { @@ -136,8 +136,8 @@ namespace JSC { Register* lastGlobal() const { return m_start - m_numGlobals; } - void markGlobals(Heap* heap) { heap->markConservatively(lastGlobal(), m_start); } - void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); } + void markGlobals(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, lastGlobal(), m_start); } + void markCallFrames(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, m_start, m_end); } private: void releaseExcessCapacity(); @@ -176,19 +176,31 @@ namespace JSC { #if HAVE(MMAP) m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, VM_TAG_FOR_REGISTERFILE_MEMORY, 0)); if (m_buffer == MAP_FAILED) { +#if PLATFORM(WINCE) + fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); +#else fprintf(stderr, "Could not allocate register file: %d\n", errno); +#endif CRASH(); } #elif HAVE(VIRTUALALLOC) m_buffer = static_cast<Register*>(VirtualAlloc(0, roundUpAllocationSize(bufferLength, commitSize), MEM_RESERVE, PAGE_READWRITE)); if (!m_buffer) { +#if PLATFORM(WINCE) + fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); +#else fprintf(stderr, "Could not allocate register file: %d\n", errno); +#endif CRASH(); } size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize); void* commitCheck = VirtualAlloc(m_buffer, committedSize, MEM_COMMIT, PAGE_READWRITE); if (commitCheck != m_buffer) { +#if PLATFORM(WINCE) + fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); +#else fprintf(stderr, "Could not allocate register file: %d\n", errno); +#endif CRASH(); } m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + committedSize); @@ -222,7 +234,11 @@ namespace JSC { if (newEnd > m_commitEnd) { size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize); if (!VirtualAlloc(m_commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) { +#if PLATFORM(WINCE) + fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); +#else fprintf(stderr, "Could not allocate register file: %d\n", errno); +#endif CRASH(); } m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_commitEnd) + size); |