X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/2d39b0e377c0896910ee49ae70082ba665faf986..refs/heads/master:/interpreter/Interpreter.h diff --git a/interpreter/Interpreter.h b/interpreter/Interpreter.h index c77019e..ef4ec0d 100644 --- a/interpreter/Interpreter.h +++ b/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 @@ -33,12 +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 #include @@ -50,6 +50,7 @@ namespace JSC { class ExecutableBase; class FunctionExecutable; class VM; + class JSFunction; class JSGlobalObject; class LLIntOffsetsExtractor; class ProgramExecutable; @@ -80,7 +81,7 @@ namespace JSC { struct StackFrame { Strong callee; StackFrameCodeType codeType; - Strong executable; + Strong executable; Strong codeBlock; RefPtr code; int lineOffset; @@ -89,65 +90,28 @@ 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 ClearExceptionScope { + class SuspendExceptionScope { public: - ClearExceptionScope(VM* vm): m_vm(vm) + SuspendExceptionScope(VM* vm) + : m_vm(vm) { - vm->getExceptionInfo(oldException, oldExceptionStack); + oldException = vm->exception(); vm->clearException(); } - ~ClearExceptionScope() + ~SuspendExceptionScope() { - m_vm->setExceptionInfo(oldException, oldExceptionStack); + m_vm->setException(oldException); } private: - JSC::JSValue oldException; - RefCountedArray oldExceptionStack; + Exception* oldException; VM* m_vm; }; @@ -157,13 +121,11 @@ namespace JSC { : vm(currentVM) , oldCallFrame(currentVM.topCallFrame) { - ASSERT(!callFrame->isVMEntrySentinel()); currentVM.topCallFrame = callFrame; } ~TopCallFrameSetter() { - ASSERT(!oldCallFrame->isVMEntrySentinel()); vm.topCallFrame = oldCallFrame; } private: @@ -177,18 +139,33 @@ namespace JSC { { ASSERT(vm); ASSERT(callFrame); - ASSERT(!callFrame->isVMEntrySentinel()); vm->topCallFrame = callFrame; } - - enum VMEntrySentinelOKTag { VMEntrySentinelOK }; - ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame, VMEntrySentinelOKTag) + }; + + class NativeCallFrameTracerWithRestore { + public: + ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame) + : m_vm(vm) { ASSERT(vm); ASSERT(callFrame); - if (!callFrame->isVMEntrySentinel()) - vm->topCallFrame = 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 { @@ -238,7 +215,7 @@ namespace JSC { SamplingTool* sampler() { return m_sampler.get(); } - NEVER_INLINE HandlerInfo* unwind(CallFrame*&, JSValue&); + NEVER_INLINE HandlerInfo* unwind(VMEntryFrame*&, CallFrame*&, Exception*); NEVER_INLINE void debug(CallFrame*, DebugHookID); JSString* stackTraceAsString(ExecState*, Vector); @@ -253,6 +230,8 @@ namespace JSC { JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*); + void getStackTrace(Vector& results, size_t maxStackSize = std::numeric_limits::max()); + private: enum ExecutionFlag { Normal, InitializeAndReturn }; @@ -260,7 +239,7 @@ namespace JSC { JSValue execute(CallFrameClosure&); - void getStackTrace(Vector& results, size_t maxStackSize = std::numeric_limits::max()); + void dumpRegisters(CallFrame*); @@ -268,7 +247,7 @@ namespace JSC { void enableSampler(); int m_sampleEntryDepth; - OwnPtr m_sampler; + std::unique_ptr m_sampler; VM& m_vm; JSStack m_stack; @@ -285,8 +264,22 @@ namespace JSC { }; JSValue eval(CallFrame*); - CallFrame* sizeFrameForVarargs(CallFrame*, JSStack*, JSValue, int, uint32_t firstVarArgOffset); - void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue, uint32_t firstVarArgOffset); + + inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis) + { + unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf( + stackAlignmentRegisters(), + numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize); + return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); + } + + 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