diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/interpreter/Interpreter.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/interpreter/Interpreter.h')
-rw-r--r-- | Source/JavaScriptCore/interpreter/Interpreter.h | 232 |
1 files changed, 74 insertions, 158 deletions
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h index cfc721b38..c3bf90bbc 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-2017 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. * @@ -27,161 +27,65 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef Interpreter_h -#define Interpreter_h +#pragma once #include "ArgList.h" +#include "CatchScope.h" +#include "FrameTracers.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> + +#if !ENABLE(JIT) +#include "CLoopStack.h" +#endif + namespace JSC { class CodeBlock; class EvalExecutable; - 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; + class StackFrame; struct CallFrameClosure; struct HandlerInfo; struct Instruction; struct ProtoCallFrame; + struct UnlinkedInstruction; - enum DebugHookID { + enum UnwindStart : uint8_t { UnwindFromCurrentFrame, UnwindFromCallerFrame }; + + enum DebugHookType { WillExecuteProgram, DidExecuteProgram, DidEnterCallFrame, DidReachBreakpoint, WillLeaveCallFrame, - WillExecuteStatement + WillExecuteStatement, + WillExecuteExpression, }; enum StackFrameCodeType { StackFrameGlobalCode, StackFrameEvalCode, + StackFrameModuleCode, StackFrameFunctionCode, StackFrameNativeCode }; - struct StackFrame { - Strong<JSObject> callee; - StackFrameCodeType codeType; - Strong<ExecutableBase> executable; - Strong<UnlinkedCodeBlock> codeBlock; - RefPtr<SourceProvider> code; - int lineOffset; - unsigned firstLineColumnOffset; - unsigned characterOffset; - 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; - } - JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column); - - private: - void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column); - }; - - class ClearExceptionScope { - public: - ClearExceptionScope(VM* vm): m_vm(vm) - { - vm->getExceptionInfo(oldException, oldExceptionStack); - vm->clearException(); - } - ~ClearExceptionScope() - { - m_vm->setExceptionInfo(oldException, oldExceptionStack); - } - private: - JSC::JSValue oldException; - RefCountedArray<JSC::StackFrame> oldExceptionStack; - VM* m_vm; - }; - - class TopCallFrameSetter { - public: - TopCallFrameSetter(VM& currentVM, CallFrame* callFrame) - : vm(currentVM) - , oldCallFrame(currentVM.topCallFrame) - { - ASSERT(!callFrame->isVMEntrySentinel()); - currentVM.topCallFrame = callFrame; - } - - ~TopCallFrameSetter() - { - ASSERT(!oldCallFrame->isVMEntrySentinel()); - vm.topCallFrame = oldCallFrame; - } - private: - VM& vm; - CallFrame* oldCallFrame; - }; - - class NativeCallFrameTracer { - public: - ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame) - { - ASSERT(vm); - ASSERT(callFrame); - ASSERT(!callFrame->isVMEntrySentinel()); - vm->topCallFrame = callFrame; - } - }; - class Interpreter { WTF_MAKE_FAST_ALLOCATED; friend class CachedCall; @@ -190,20 +94,14 @@ namespace JSC { 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; } +#if !ENABLE(JIT) + CLoopStack& cloopStack() { return m_cloopStack; } +#endif Opcode getOpcode(OpcodeID id) { @@ -218,64 +116,60 @@ 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 return opcode; #endif } - + + OpcodeID getOpcodeID(const Instruction&); + OpcodeID getOpcodeID(const UnlinkedInstruction&); + bool isOpcode(Opcode); - JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj); + JSValue executeProgram(const SourceCode&, 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*); 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(CallFrame*&, JSValue&); - NEVER_INLINE void debug(CallFrame*, DebugHookID); - JSString* stackTraceAsString(ExecState*, Vector<StackFrame>); + NEVER_INLINE HandlerInfo* unwind(VM&, CallFrame*&, Exception*, UnwindStart); + void notifyDebuggerOfExceptionToBeThrown(CallFrame*, Exception*); + NEVER_INLINE void debug(CallFrame*, DebugHookType); + static JSString* stackTraceAsString(VM&, const Vector<StackFrame>&); 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(); - void stopSampling(); - JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*); + void getStackTrace(Vector<StackFrame>& results, size_t framesToSkip = 0, size_t maxStackSize = std::numeric_limits<size_t>::max()); + private: enum ExecutionFlag { Normal, InitializeAndReturn }; - CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*); + CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, const ArgList&); JSValue execute(CallFrameClosure&); - void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max()); + void dumpRegisters(CallFrame*); - bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); } - - void enableSampler(); - int m_sampleEntryDepth; - OwnPtr<SamplingTool> m_sampler; + bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval) || opcode == getOpcode(op_tail_call); } VM& m_vm; - JSStack m_stack; - int m_errorHandlingModeReentry; +#if !ENABLE(JIT) + CLoopStack m_cloopStack; +#endif -#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 @@ -286,8 +180,30 @@ namespace JSC { }; JSValue eval(CallFrame*); - CallFrame* sizeAndAllocFrameForVarargs(CallFrame*, JSStack*, JSValue, int); - void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue); -} // namespace JSC -#endif // Interpreter_h + inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis) + { + // 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 + CallFrame::headerSizeInRegisters) - CallFrame::headerSizeInRegisters; + + // Align the frame offset here. + unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf( + stackAlignmentRegisters(), + numUsedStackSlots + argumentCountIncludingThis + CallFrame::headerSizeInRegisters); + return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); + } + + unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset); + static const unsigned maxArguments = 0x10000; + unsigned sizeFrameForVarargs(CallFrame* exec, VM&, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset); + unsigned sizeFrameForForwardArguments(CallFrame* exec, VM&, unsigned numUsedStackSlots); + 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); + void setupForwardArgumentsFrame(CallFrame* execCaller, CallFrame* execCallee, uint32_t length); + void setupForwardArgumentsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, uint32_t length); + +} // namespace JSC |