summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/interpreter/Interpreter.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/interpreter/Interpreter.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/interpreter/Interpreter.h')
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h232
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