/*
- * 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
#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>
class ExecutableBase;
class FunctionExecutable;
class VM;
+ class JSFunction;
class JSGlobalObject;
class LLIntOffsetsExtractor;
class ProgramExecutable;
struct StackFrame {
Strong<JSObject> callee;
StackFrameCodeType codeType;
- Strong<ExecutableBase> executable;
+ Strong<ScriptExecutable> executable;
Strong<UnlinkedCodeBlock> codeBlock;
RefPtr<SourceProvider> code;
int lineOffset;
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<JSC::StackFrame> oldExceptionStack;
+ Exception* oldException;
VM* m_vm;
};
: vm(currentVM)
, oldCallFrame(currentVM.topCallFrame)
{
- ASSERT(!callFrame->isVMEntrySentinel());
currentVM.topCallFrame = callFrame;
}
~TopCallFrameSetter()
{
- ASSERT(!oldCallFrame->isVMEntrySentinel());
vm.topCallFrame = oldCallFrame;
}
private:
{
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 {
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<StackFrame>);
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 };
JSValue execute(CallFrameClosure&);
- void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
+
void dumpRegisters(CallFrame*);
void enableSampler();
int m_sampleEntryDepth;
- OwnPtr<SamplingTool> m_sampler;
+ std::unique_ptr<SamplingTool> m_sampler;
VM& m_vm;
JSStack m_stack;
};
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