diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/interpreter/Interpreter.h | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/interpreter/Interpreter.h')
-rw-r--r-- | Source/JavaScriptCore/interpreter/Interpreter.h | 193 |
1 files changed, 108 insertions, 85 deletions
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h index e5eca0e1c..aba745f17 100644 --- a/Source/JavaScriptCore/interpreter/Interpreter.h +++ b/Source/JavaScriptCore/interpreter/Interpreter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved. * Copyright (C) 2012 Research In Motion Limited. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -33,11 +33,12 @@ #include "ArgList.h" #include "JSCJSValue.h" #include "JSCell.h" -#include "JSFunction.h" #include "JSObject.h" #include "JSStack.h" #include "LLIntData.h" #include "Opcode.h" +#include "SourceProvider.h" +#include "StackAlignment.h" #include <wtf/HashMap.h> #include <wtf/text/StringBuilder.h> @@ -49,16 +50,23 @@ namespace JSC { class ExecutableBase; class FunctionExecutable; class VM; + class JSFunction; class JSGlobalObject; + class JSModuleEnvironment; + class JSModuleRecord; class LLIntOffsetsExtractor; class ProgramExecutable; + class ModuleProgramExecutable; class Register; class JSScope; class SamplingTool; struct CallFrameClosure; struct HandlerInfo; struct Instruction; - + struct ProtoCallFrame; + + enum UnwindStart { UnwindFromCurrentFrame, UnwindFromCallerFrame }; + enum DebugHookID { WillExecuteProgram, DidExecuteProgram, @@ -71,6 +79,7 @@ namespace JSC { enum StackFrameCodeType { StackFrameGlobalCode, StackFrameEvalCode, + StackFrameModuleCode, StackFrameFunctionCode, StackFrameNativeCode }; @@ -78,7 +87,7 @@ namespace JSC { struct StackFrame { Strong<JSObject> callee; StackFrameCodeType codeType; - Strong<ExecutableBase> executable; + Strong<ScriptExecutable> executable; Strong<UnlinkedCodeBlock> codeBlock; RefPtr<SourceProvider> code; int lineOffset; @@ -87,58 +96,38 @@ namespace JSC { unsigned bytecodeOffset; String sourceURL; JS_EXPORT_PRIVATE String toString(CallFrame*); - String friendlySourceURL() const - { - String traceLine; - - switch (codeType) { - case StackFrameEvalCode: - case StackFrameFunctionCode: - case StackFrameGlobalCode: - if (!sourceURL.isEmpty()) - traceLine = sourceURL.impl(); - break; - case StackFrameNativeCode: - traceLine = "[native code]"; - break; - } - return traceLine.isNull() ? emptyString() : traceLine; - } - String friendlyFunctionName(CallFrame* callFrame) const - { - String traceLine; - JSObject* stackFrameCallee = callee.get(); - - switch (codeType) { - case StackFrameEvalCode: - traceLine = "eval code"; - break; - case StackFrameNativeCode: - if (callee) - traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl(); - break; - case StackFrameFunctionCode: - traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl(); - break; - case StackFrameGlobalCode: - traceLine = "global code"; - break; - } - return traceLine.isNull() ? emptyString() : traceLine; - } + String friendlySourceURL() const; + String friendlyFunctionName(CallFrame*) const; JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column); private: void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column); }; + class SuspendExceptionScope { + public: + SuspendExceptionScope(VM* vm) + : m_vm(vm) + { + oldException = vm->exception(); + vm->clearException(); + } + ~SuspendExceptionScope() + { + m_vm->restorePreviousException(oldException); + } + private: + Exception* oldException; + VM* m_vm; + }; + class TopCallFrameSetter { public: - TopCallFrameSetter(VM& global, CallFrame* callFrame) - : vm(global) - , oldCallFrame(global.topCallFrame) + TopCallFrameSetter(VM& currentVM, CallFrame* callFrame) + : vm(currentVM) + , oldCallFrame(currentVM.topCallFrame) { - global.topCallFrame = callFrame; + currentVM.topCallFrame = callFrame; } ~TopCallFrameSetter() @@ -152,33 +141,52 @@ namespace JSC { class NativeCallFrameTracer { public: - ALWAYS_INLINE NativeCallFrameTracer(VM* global, CallFrame* callFrame) + ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame) { - ASSERT(global); + ASSERT(vm); ASSERT(callFrame); - global->topCallFrame = callFrame; + ASSERT(callFrame < vm->topVMEntryFrame); + vm->topCallFrame = callFrame; } }; + class NativeCallFrameTracerWithRestore { + public: + ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame) + : m_vm(vm) + { + ASSERT(vm); + ASSERT(callFrame); + m_savedTopVMEntryFrame = vm->topVMEntryFrame; + m_savedTopCallFrame = vm->topCallFrame; + vm->topVMEntryFrame = vmEntryFrame; + vm->topCallFrame = callFrame; + } + + ALWAYS_INLINE ~NativeCallFrameTracerWithRestore() + { + m_vm->topVMEntryFrame = m_savedTopVMEntryFrame; + m_vm->topCallFrame = m_savedTopCallFrame; + } + + private: + VM* m_vm; + VMEntryFrame* m_savedTopVMEntryFrame; + CallFrame* m_savedTopCallFrame; + }; + class Interpreter { WTF_MAKE_FAST_ALLOCATED; friend class CachedCall; friend class LLIntOffsetsExtractor; friend class JIT; + friend class VM; public: - class ErrorHandlingMode { - public: - JS_EXPORT_PRIVATE ErrorHandlingMode(ExecState*); - JS_EXPORT_PRIVATE ~ErrorHandlingMode(); - private: - Interpreter& m_interpreter; - }; - Interpreter(VM &); ~Interpreter(); - void initialize(bool canUseJIT); + void initialize(); JSStack& stack() { return m_stack; } @@ -195,7 +203,7 @@ namespace JSC { OpcodeID getOpcodeID(Opcode opcode) { ASSERT(m_initialized); -#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT) +#if ENABLE(COMPUTED_GOTO_OPCODES) ASSERT(isOpcode(opcode)); return m_opcodeIDTable.get(opcode); #else @@ -207,24 +215,23 @@ namespace JSC { JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj); JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&); - JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&); + JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&, JSValue newTarget); JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, JSScope*); + JSValue execute(ModuleProgramExecutable*, CallFrame*, JSModuleEnvironment*); - JSValue retrieveArgumentsFromVMCode(CallFrame*, JSFunction*) const; - JSValue retrieveCallerFromVMCode(CallFrame*, JSFunction*) const; - JS_EXPORT_PRIVATE void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, String& sourceURL, JSValue& function) const; - void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); SamplingTool* sampler() { return m_sampler.get(); } - bool isInErrorHandlingMode() { return m_errorHandlingModeReentry; } + NEVER_INLINE HandlerInfo* unwind(VM&, CallFrame*&, Exception*, UnwindStart); + void notifyDebuggerOfExceptionToBeThrown(CallFrame*, Exception*); + NEVER_INLINE void debug(CallFrame*, DebugHookID); + JSString* stackTraceAsString(ExecState*, Vector<StackFrame>); - NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset); - NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column); - static const String getTraceLine(CallFrame*, StackFrameCodeType, const String&, int); - JS_EXPORT_PRIVATE static void getStackTrace(VM*, Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max()); - static void addStackTraceIfNecessary(CallFrame*, JSValue error); + static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState*); + static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*); + static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*); + static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*); void dumpSampleData(ExecState* exec); void startSampling(); @@ -232,29 +239,30 @@ namespace JSC { JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*); + void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max()); + private: enum ExecutionFlag { Normal, InitializeAndReturn }; - CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*); - void endRepeatCall(CallFrameClosure&); + CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*); + JSValue execute(CallFrameClosure&); - NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&); - static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*); void dumpRegisters(CallFrame*); - bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); } + bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval) || opcode == getOpcode(op_tail_call); } void enableSampler(); int m_sampleEntryDepth; - OwnPtr<SamplingTool> m_sampler; + std::unique_ptr<SamplingTool> m_sampler; + VM& m_vm; JSStack m_stack; int m_errorHandlingModeReentry; -#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT) +#if ENABLE(COMPUTED_GOTO_OPCODES) Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling #endif @@ -264,15 +272,30 @@ namespace JSC { #endif }; - // This value must not be an object that would require this conversion (WebCore's global object). - inline bool isValidThisObject(JSValue thisValue, ExecState* exec) + JSValue eval(CallFrame*); + + inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis) { - return !thisValue.isObject() || thisValue.toThisObject(exec) == thisValue; + // We want the new frame to be allocated on a stack aligned offset with a stack + // aligned size. Align the size here. + argumentCountIncludingThis = WTF::roundUpToMultipleOf( + stackAlignmentRegisters(), + argumentCountIncludingThis + JSStack::CallFrameHeaderSize) - JSStack::CallFrameHeaderSize; + + // Align the frame offset here. + unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf( + stackAlignmentRegisters(), + numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize); + return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); } - JSValue eval(CallFrame*); - CallFrame* loadVarargs(CallFrame*, JSStack*, JSValue thisValue, JSValue arguments, int firstFreeRegister); - + unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset); + static const unsigned maxArguments = 0x10000; + unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset); + void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length); + void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length); + void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length); + } // namespace JSC #endif // Interpreter_h |