#include "ArgList.h"
#include "JSCell.h"
+#include "JSFunction.h"
#include "JSValue.h"
+#include "JSObject.h"
+#include "LLIntData.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 EvalExecutable;
+ class ExecutableBase;
+ class FunctionExecutable;
class JSGlobalObject;
- class ProgramNode;
+ class LLIntOffsetsExtractor;
+ class ProgramExecutable;
class Register;
class ScopeChainNode;
class SamplingTool;
+ struct CallFrameClosure;
struct HandlerInfo;
-
-#if ENABLE(JIT)
-
-#if USE(JIT_STUB_ARGUMENT_VA_LIST)
- #define STUB_ARGS void* args, ...
- #define ARGS (reinterpret_cast<void**>(vl_args) - 1)
-#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
- #define STUB_ARGS void** args
- #define ARGS (args)
-#endif
-
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
- #if PLATFORM(X86_64)
- #define JIT_STUB
- #elif COMPILER(MSVC)
- #define JIT_STUB __fastcall
- #elif COMPILER(GCC)
- #define JIT_STUB __attribute__ ((fastcall))
- #else
- #error Need to support register calling convention in this compiler
- #endif
-#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
- #if COMPILER(MSVC)
- #define JIT_STUB __cdecl
- #else
- #define JIT_STUB
- #endif
-#endif
-
-// The Mac compilers are fine with this,
-#if PLATFORM(MAC)
- struct VoidPtrPair {
- void* first;
- void* second;
- };
-#define RETURN_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
-#else
- typedef uint64_t VoidPtrPair;
- union VoidPtrPairValue {
- struct { void* first; void* second; } s;
- VoidPtrPair i;
- };
-#define RETURN_PAIR(a,b) VoidPtrPairValue pair = {{ a, b }}; return pair.i
-#endif
-
-#endif // ENABLE(JIT)
-
+ struct Instruction;
+
enum DebugHookID {
WillExecuteProgram,
DidExecuteProgram,
WillExecuteStatement
};
+ enum StackFrameCodeType {
+ StackFrameGlobalCode,
+ StackFrameEvalCode,
+ StackFrameFunctionCode,
+ StackFrameNativeCode
+ };
+
+ struct StackFrame {
+ Strong<JSObject> callee;
+ StackFrameCodeType codeType;
+ Strong<ExecutableBase> executable;
+ int line;
+ UString sourceURL;
+ UString toString(CallFrame* callFrame) const
+ {
+ bool hasSourceURLInfo = !sourceURL.isNull() && !sourceURL.isEmpty();
+ bool hasLineInfo = line > -1;
+ String traceLine;
+ JSObject* stackFrameCallee = callee.get();
+
+ switch (codeType) {
+ case StackFrameEvalCode:
+ if (hasSourceURLInfo) {
+ traceLine = hasLineInfo ? String::format("eval code@%s:%d", sourceURL.ascii().data(), line)
+ : String::format("eval code@%s", sourceURL.ascii().data());
+ } else
+ traceLine = String::format("eval code");
+ break;
+ case StackFrameNativeCode: {
+ if (callee) {
+ UString functionName = getCalculatedDisplayName(callFrame, stackFrameCallee);
+ traceLine = String::format("%s@[native code]", functionName.ascii().data());
+ } else
+ traceLine = "[native code]";
+ break;
+ }
+ case StackFrameFunctionCode: {
+ UString functionName = getCalculatedDisplayName(callFrame, stackFrameCallee);
+ if (hasSourceURLInfo) {
+ traceLine = hasLineInfo ? String::format("%s@%s:%d", functionName.ascii().data(), sourceURL.ascii().data(), line)
+ : String::format("%s@%s", functionName.ascii().data(), sourceURL.ascii().data());
+ } else
+ traceLine = String::format("%s\n", functionName.ascii().data());
+ break;
+ }
+ case StackFrameGlobalCode:
+ if (hasSourceURLInfo) {
+ traceLine = hasLineInfo ? String::format("global code@%s:%d", sourceURL.ascii().data(), line)
+ : String::format("global code@%s", sourceURL.ascii().data());
+ } else
+ traceLine = String::format("global code");
+
+ }
+ return traceLine.impl();
+ }
+ };
+
+ class TopCallFrameSetter {
+ public:
+ TopCallFrameSetter(JSGlobalData& global, CallFrame* callFrame)
+ : globalData(global)
+ , oldCallFrame(global.topCallFrame)
+ {
+ global.topCallFrame = callFrame;
+ }
+
+ ~TopCallFrameSetter()
+ {
+ globalData.topCallFrame = oldCallFrame;
+ }
+ private:
+ JSGlobalData& globalData;
+ CallFrame* oldCallFrame;
+ };
+
+ class NativeCallFrameTracer {
+ public:
+ ALWAYS_INLINE NativeCallFrameTracer(JSGlobalData* global, CallFrame* callFrame)
+ {
+ ASSERT(global);
+ ASSERT(callFrame);
+ global->topCallFrame = callFrame;
+ }
+ };
+
// We use a smaller reentrancy limit on iPhone because of the high amount of
// stack space required on the web thread.
- enum { MaxReentryDepth = 100 };
+ enum { MaxLargeThreadReentryDepth = 64, MaxSmallThreadReentryDepth = 16 };
class Interpreter {
+ WTF_MAKE_FAST_ALLOCATED;
+ friend class CachedCall;
+ friend class LLIntOffsetsExtractor;
friend class JIT;
public:
Interpreter();
~Interpreter();
-
- void initialize(JSGlobalData*);
+ void initialize(LLInt::Data*, bool canUseJIT);
+
RegisterFile& registerFile() { return m_registerFile; }
Opcode getOpcode(OpcodeID id)
{
- #if HAVE(COMPUTED_GOTO)
- return m_opcodeTable[id];
- #else
- return id;
- #endif
+ ASSERT(m_initialized);
+#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
+ return m_opcodeTable[id];
+#else
+ return id;
+#endif
}
OpcodeID getOpcodeID(Opcode opcode)
{
- #if HAVE(COMPUTED_GOTO)
- ASSERT(isOpcode(opcode));
- return m_opcodeIDTable.get(opcode);
- #else
- return opcode;
- #endif
- }
-
- bool isOpcode(Opcode);
-
- JSValuePtr execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValuePtr* exception);
- JSValuePtr execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValuePtr* exception);
- JSValuePtr execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValuePtr* exception);
-
- JSValuePtr retrieveArguments(CallFrame*, JSFunction*) const;
- JSValuePtr retrieveCaller(CallFrame*, InternalFunction*) const;
- void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const;
-
- void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
- void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
-
- void startTimeoutCheck()
- {
- if (!m_timeoutCheckCount)
- resetTimeoutCheck();
-
- ++m_timeoutCheckCount;
+ ASSERT(m_initialized);
+#if ENABLE(LLINT)
+ ASSERT(isOpcode(opcode));
+ return m_opcodeIDTable.get(opcode);
+#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
+ ASSERT(isOpcode(opcode));
+ if (!m_classicEnabled)
+ return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
+
+ return m_opcodeIDTable.get(opcode);
+#else
+ return opcode;
+#endif
}
- void stopTimeoutCheck()
+ bool classicEnabled()
{
- ASSERT(m_timeoutCheckCount);
- --m_timeoutCheckCount;
+ return m_classicEnabled;
}
- inline void initTimeout()
- {
- ASSERT(!m_timeoutCheckCount);
- resetTimeoutCheck();
- m_timeoutTime = 0;
- m_timeoutCheckCount = 0;
- }
+ bool isOpcode(Opcode);
- void setSampler(SamplingTool* sampler) { m_sampler = sampler; }
- SamplingTool* sampler() { return m_sampler; }
-
-#if ENABLE(JIT)
-
- static int JIT_STUB cti_timeout_check(STUB_ARGS);
- static void JIT_STUB cti_register_file_check(STUB_ARGS);
-
- static JSObject* JIT_STUB cti_op_convert_this(STUB_ARGS);
- static void JIT_STUB cti_op_end(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_add(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_inc(STUB_ARGS);
- static int JIT_STUB cti_op_loop_if_less(STUB_ARGS);
- static int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_object(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id_second(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_second(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_generic(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_id(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_instanceof(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_mul(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_func(STUB_ARGS);
- static void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS);
- static void JIT_STUB cti_op_create_arguments(STUB_ARGS);
- static void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS);
- static void JIT_STUB cti_op_tear_off_activation(STUB_ARGS);
- static void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS);
- static void JIT_STUB cti_op_profile_will_call(STUB_ARGS);
- static void JIT_STUB cti_op_profile_did_call(STUB_ARGS);
- static void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_array(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_global(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_resolve_func(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_sub(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_val(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_val_array(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_lesseq(STUB_ARGS);
- static int JIT_STUB cti_op_loop_if_true(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_base(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_negate(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_skip(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_div(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_dec(STUB_ARGS);
- static int JIT_STUB cti_op_jless(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_not(STUB_ARGS);
- static int JIT_STUB cti_op_jtrue(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_post_inc(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_eq(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_lshift(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitand(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_rshift(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitnot(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_resolve_with_base(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_mod(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_less(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_neq(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_post_dec(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_urshift(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitxor(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitor(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_call_eval(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_throw(STUB_ARGS);
- static JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_next_pname(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS);
- static void JIT_STUB cti_op_pop_scope(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_typeof(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_undefined(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_boolean(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_number(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_string(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_object(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_function(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_stricteq(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_nstricteq(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_to_jsnumber(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_in(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS);
- static void JIT_STUB cti_op_jmp_scopes(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_index(STUB_ARGS);
- static void* JIT_STUB cti_op_switch_imm(STUB_ARGS);
- static void* JIT_STUB cti_op_switch_char(STUB_ARGS);
- static void* JIT_STUB cti_op_switch_string(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_val(STUB_ARGS);
- static void JIT_STUB cti_op_put_getter(STUB_ARGS);
- static void JIT_STUB cti_op_put_setter(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_error(STUB_ARGS);
- static void JIT_STUB cti_op_debug(STUB_ARGS);
-
- static JSValueEncodedAsPointer* JIT_STUB cti_vm_throw(STUB_ARGS);
- static void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS);
- static void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS);
-
-#endif // ENABLE(JIT)
+ JSValue execute(ProgramExecutable*, CallFrame*, ScopeChainNode*, JSObject* thisObj);
+ JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&);
+ JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&);
+ JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, ScopeChainNode*);
+ JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, ScopeChainNode*, int globalRegisterOffset);
- // Default number of ticks before a timeout check should be done.
- static const int initialTickCountThreshold = 1024;
+ JSValue retrieveArgumentsFromVMCode(CallFrame*, JSFunction*) const;
+ JSValue retrieveCallerFromVMCode(CallFrame*, JSFunction*) const;
+ JS_EXPORT_PRIVATE void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const;
+
+ void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
+
+ SamplingTool* sampler() { return m_sampler.get(); }
- bool isJSArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsArrayVptr; }
- bool isJSString(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsStringVptr; }
- bool isJSByteArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsByteArrayVptr; }
+ NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
+ NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
+ static const UString getTraceLine(CallFrame*, StackFrameCodeType, const UString&, int);
+ JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, Vector<StackFrame>& results);
+ static void addStackTraceIfNecessary(CallFrame*, JSObject* error);
+ void dumpSampleData(ExecState* exec);
+ void startSampling();
+ void stopSampling();
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
- NEVER_INLINE JSValuePtr callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue);
- JSValuePtr execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValuePtr* exception);
+ CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, ScopeChainNode*);
+ void endRepeatCall(CallFrameClosure&);
+ JSValue execute(CallFrameClosure&);
- NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
-
- NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
- NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
- NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+#if ENABLE(CLASSIC_INTERPRETER)
+ NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue& exceptionValue);
+ NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue& exceptionValue);
+ NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue);
+ NEVER_INLINE bool resolveGlobalDynamic(CallFrame*, Instruction*, JSValue& exceptionValue);
NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
- NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+ NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
+ NEVER_INLINE bool resolveThisAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
- NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValuePtr, unsigned& bytecodeOffset, CodeBlock*&);
- NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValuePtr&, unsigned bytecodeOffset, bool);
- NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+ void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
+ void uncacheGetByID(CodeBlock*, Instruction* vPC);
+ void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
+ void uncachePutByID(CodeBlock*, Instruction* vPC);
+#endif // ENABLE(CLASSIC_INTERPRETER)
+
+ NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
- static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
+ static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*);
- JSValuePtr privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValuePtr* exception);
+ JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
void dumpCallFrame(CallFrame*);
void dumpRegisters(CallFrame*);
-
- bool checkTimeout(JSGlobalObject*);
- void resetTimeoutCheck();
-
- void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
- void uncacheGetByID(CodeBlock*, Instruction* vPC);
- void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const PutPropertySlot&);
- void uncachePutByID(CodeBlock*, Instruction* vPC);
bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
-#if ENABLE(JIT)
- static void throwStackOverflowPreviousFrame(CallFrame**, JSGlobalData*, void*& returnAddress);
-
- void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
- void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot&);
-#endif
-
- SamplingTool* m_sampler;
-
-#if ENABLE(JIT)
- RefPtr<ExecutablePool> m_executablePool;
- void* m_ctiArrayLengthTrampoline;
- void* m_ctiStringLengthTrampoline;
- void* m_ctiVirtualCallPreLink;
- void* m_ctiVirtualCallLink;
- void* m_ctiVirtualCall;
-#endif
+ void enableSampler();
+ int m_sampleEntryDepth;
+ OwnPtr<SamplingTool> m_sampler;
int m_reentryDepth;
- unsigned m_timeoutTime;
- unsigned m_timeAtLastCheckTimeout;
- unsigned m_timeExecuting;
- unsigned m_timeoutCheckCount;
- unsigned m_ticksUntilNextTimeoutCheck;
RegisterFile m_registerFile;
- void* m_jsArrayVptr;
- void* m_jsByteArrayVptr;
- void* m_jsStringVptr;
- void* m_jsFunctionVptr;
-
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(LLINT)
+ Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
+ HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
+#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
#endif
+
+#if !ASSERT_DISABLED
+ bool m_initialized;
+#endif
+ bool m_classicEnabled;
};
+ // This value must not be an object that would require this conversion (WebCore's global object).
+ inline bool isValidThisObject(JSValue thisValue, ExecState* exec)
+ {
+ return !thisValue.isObject() || thisValue.toThisObject(exec) == thisValue;
+ }
+
+ inline JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, ScopeChainNode* scopeChain)
+ {
+ return execute(eval, callFrame, thisValue, scopeChain, m_registerFile.size() + 1 + RegisterFile::CallFrameHeaderSize);
+ }
+
+ JSValue eval(CallFrame*);
+ CallFrame* loadVarargs(CallFrame*, RegisterFile*, JSValue thisValue, JSValue arguments, int firstFreeRegister);
+
} // namespace JSC
#endif // Interpreter_h