Commit afeead10 authored by mark.lam@apple.com's avatar mark.lam@apple.com

Make the C Loop LLINT work with callToJavaScript.

https://bugs.webkit.org/show_bug.cgi?id=125294.

Reviewed by Michael Saboff.

1. Changed the C Loop LLINT to dispatch to an Executable via its JITCode
   instance which is consistent with how the ASM LLINT works.
2. Changed CLoop::execute() to take an Opcode instead of an OpcodeID.
   This makes it play nice with the use of JITCode for dispatching.
3. Introduce a callToJavaScript and callToNativeFunction for the C Loop
   LLINT. These will call JSStack::pushFrame() and popFrame() to setup
   and teardown the CallFrame.
4. Also introduced a C Loop returnFromJavaScript which is just a
   replacement for ctiOpThrowNotCaught which had the same function.
5. Remove a lot of #if ENABLE(LLINT_C_LOOP) code now that the dispatch
   mechanism is consistent.

This patch has been tested with both configurations of COMPUTED_GOTOs
on and off.

* interpreter/CachedCall.h:
(JSC::CachedCall::CachedCall):
(JSC::CachedCall::call):
(JSC::CachedCall::setArgument):
* interpreter/CallFrameClosure.h:
(JSC::CallFrameClosure::setThis):
(JSC::CallFrameClosure::setArgument):
(JSC::CallFrameClosure::resetCallFrame):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/Interpreter.h:
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
(JSC::JSStack::pushFrame):
* interpreter/ProtoCallFrame.h:
(JSC::ProtoCallFrame::scope):
(JSC::ProtoCallFrame::callee):
(JSC::ProtoCallFrame::thisValue):
(JSC::ProtoCallFrame::argument):
(JSC::ProtoCallFrame::setArgument):
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITCode.h:
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* llint/LLIntCLoop.cpp:
(JSC::LLInt::CLoop::initialize):
* llint/LLIntCLoop.h:
* llint/LLIntEntrypoint.cpp:
(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
- Inverted the check for vm.canUseJIT(). This allows the JIT case to be
  #if'd out nicely when building the C Loop LLINT.
* llint/LLIntOpcode.h:
* llint/LLIntThunks.cpp:
(JSC::doCallToJavaScript):
(JSC::executeJS):
(JSC::callToJavaScript):
(JSC::executeNative):
(JSC::callToNativeFunction):
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* runtime/Executable.h:
(JSC::ExecutableBase::offsetOfNumParametersFor):
(JSC::ExecutableBase::hostCodeEntryFor):
(JSC::ExecutableBase::jsCodeEntryFor):
(JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
(JSC::NativeExecutable::create):
(JSC::NativeExecutable::finishCreation):
(JSC::ProgramExecutable::generatedJITCode):
* runtime/JSArray.cpp:
(JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
* runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
* runtime/VM.cpp:
(JSC::VM::getHostFunction):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160186 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d882a076
2013-12-05 Mark Lam <mark.lam@apple.com>
Make the C Loop LLINT work with callToJavaScript.
https://bugs.webkit.org/show_bug.cgi?id=125294.
Reviewed by Michael Saboff.
1. Changed the C Loop LLINT to dispatch to an Executable via its JITCode
instance which is consistent with how the ASM LLINT works.
2. Changed CLoop::execute() to take an Opcode instead of an OpcodeID.
This makes it play nice with the use of JITCode for dispatching.
3. Introduce a callToJavaScript and callToNativeFunction for the C Loop
LLINT. These will call JSStack::pushFrame() and popFrame() to setup
and teardown the CallFrame.
4. Also introduced a C Loop returnFromJavaScript which is just a
replacement for ctiOpThrowNotCaught which had the same function.
5. Remove a lot of #if ENABLE(LLINT_C_LOOP) code now that the dispatch
mechanism is consistent.
This patch has been tested with both configurations of COMPUTED_GOTOs
on and off.
* interpreter/CachedCall.h:
(JSC::CachedCall::CachedCall):
(JSC::CachedCall::call):
(JSC::CachedCall::setArgument):
* interpreter/CallFrameClosure.h:
(JSC::CallFrameClosure::setThis):
(JSC::CallFrameClosure::setArgument):
(JSC::CallFrameClosure::resetCallFrame):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/Interpreter.h:
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
(JSC::JSStack::pushFrame):
* interpreter/ProtoCallFrame.h:
(JSC::ProtoCallFrame::scope):
(JSC::ProtoCallFrame::callee):
(JSC::ProtoCallFrame::thisValue):
(JSC::ProtoCallFrame::argument):
(JSC::ProtoCallFrame::setArgument):
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITCode.h:
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* llint/LLIntCLoop.cpp:
(JSC::LLInt::CLoop::initialize):
* llint/LLIntCLoop.h:
* llint/LLIntEntrypoint.cpp:
(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
- Inverted the check for vm.canUseJIT(). This allows the JIT case to be
#if'd out nicely when building the C Loop LLINT.
* llint/LLIntOpcode.h:
* llint/LLIntThunks.cpp:
(JSC::doCallToJavaScript):
(JSC::executeJS):
(JSC::callToJavaScript):
(JSC::executeNative):
(JSC::callToNativeFunction):
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* runtime/Executable.h:
(JSC::ExecutableBase::offsetOfNumParametersFor):
(JSC::ExecutableBase::hostCodeEntryFor):
(JSC::ExecutableBase::jsCodeEntryFor):
(JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
(JSC::NativeExecutable::create):
(JSC::NativeExecutable::finishCreation):
(JSC::ProgramExecutable::generatedJITCode):
* runtime/JSArray.cpp:
(JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
* runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
* runtime/VM.cpp:
(JSC::VM::getHostFunction):
2013-12-05 Laszlo Vidacs <lac@inf.u-szeged.hu>
Fix JavaScriptCore build if cloop is enabled after r160094
......
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -45,12 +45,8 @@ namespace JSC {
{
ASSERT(!function->isHostFunction());
if (callFrame->vm().isSafeToRecurse()) {
#if !ENABLE(LLINT_C_LOOP)
m_arguments.resize(argumentCount);
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, &m_protoCallFrame, function, argumentCount + 1, function->scope(), m_arguments.data());
#else
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argumentCount + 1, function->scope());
#endif
} else
throwStackOverflowError(callFrame);
m_valid = !callFrame->hadException();
......@@ -61,35 +57,15 @@ namespace JSC {
ASSERT(m_valid);
return m_interpreter->execute(m_closure);
}
#if !ENABLE(LLINT_C_LOOP)
void setThis(JSValue v) { m_protoCallFrame.setThisValue(v); }
void setArgument(int n, JSValue v) { m_protoCallFrame.setArgument(n, v); }
#else
void setThis(JSValue v) { m_closure.setThis(v); }
void setArgument(int n, JSValue v) { m_closure.setArgument(n, v); }
CallFrame* newCallFrame(ExecState* exec)
{
CallFrame* callFrame = m_closure.newCallFrame;
callFrame->setScope(exec->scope());
return callFrame;
}
~CachedCall()
{
if (m_valid)
m_interpreter->endRepeatCall(m_closure);
}
#endif
private:
bool m_valid;
Interpreter* m_interpreter;
VMEntryScope m_entryScope;
#if !ENABLE(LLINT_C_LOOP)
ProtoCallFrame m_protoCallFrame;
Vector<JSValue> m_arguments;
#endif
CallFrameClosure m_closure;
};
}
......
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -32,11 +32,7 @@ namespace JSC {
struct CallFrameClosure {
CallFrame* oldCallFrame;
#if ENABLE(LLINT_C_LOOP)
CallFrame* newCallFrame;
#else
ProtoCallFrame* newCallFrame;
#endif
ProtoCallFrame* protoCallFrame;
JSFunction* function;
FunctionExecutable* functionExecutable;
VM* vm;
......@@ -46,25 +42,17 @@ struct CallFrameClosure {
void setThis(JSValue value)
{
newCallFrame->setThisValue(value);
protoCallFrame->setThisValue(value);
}
void setArgument(int argument, JSValue value)
{
newCallFrame->setArgument(argument, value);
protoCallFrame->setArgument(argument, value);
}
void resetCallFrame()
{
newCallFrame->setScope(scope);
#if ENABLE(LLINT_C_LOOP)
// setArgument() takes an arg index that starts from 0 for the first
// argument after the 'this' value. Since both argumentCountIncludingThis
// and parameterCountIncludingThis includes the 'this' value, we need to
// subtract 1 from them to make it a valid argument index for setArgument().
for (int i = argumentCountIncludingThis-1; i < parameterCountIncludingThis-1; ++i)
newCallFrame->setArgument(i, jsUndefined());
#endif
protoCallFrame->setScope(scope);
}
};
......
......@@ -860,22 +860,13 @@ failedJSONP:
if (UNLIKELY(vm.watchdog.didFire(callFrame)))
return throwTerminatedExecutionException(callFrame);
// Push the call frame for this invocation:
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
#if ENABLE(LLINT_C_LOOP)
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
if (UNLIKELY(!newCallFrame))
return checkedReturn(throwStackOverflowError(callFrame));
// Set the arguments for the callee:
newCallFrame->setThisValue(thisObj);
#else
if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
return checkedReturn(throwStackOverflowError(callFrame));
ProtoCallFrame protoCallFrame;
protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
#endif
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, program->sourceURL(), program->lineNo());
......@@ -886,20 +877,12 @@ failedJSONP:
SamplingTool::CallRecord callRecord(m_sampler.get());
Watchdog::Scope watchdogScope(vm.watchdog);
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
#elif ENABLE(JIT)
result = program->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
#endif // ENABLE(JIT)
}
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
#if ENABLE(LLINT_C_LOOP)
m_stack.popFrame(newCallFrame);
#endif
return checkedReturn(result);
}
......@@ -942,22 +925,11 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (UNLIKELY(vm.watchdog.didFire(callFrame)))
return throwTerminatedExecutionException(callFrame);
#if ENABLE(LLINT_C_LOOP)
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
if (UNLIKELY(!newCallFrame))
return checkedReturn(throwStackOverflowError(callFrame));
// Set the arguments for the callee:
newCallFrame->setThisValue(thisValue);
for (size_t i = 0; i < args.size(); ++i)
newCallFrame->setArgument(i, args.at(i));
#else
if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
return checkedReturn(throwStackOverflowError(callFrame));
ProtoCallFrame protoCallFrame;
protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
#endif
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, function);
......@@ -968,27 +940,15 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
Watchdog::Scope watchdogScope(vm.watchdog);
// Execute the code:
if (isJSCall) {
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
#elif ENABLE(JIT)
if (isJSCall)
result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
#endif // ENABLE(JIT)
} else {
#if ENABLE(LLINT_C_LOOP)
result = JSValue::decode(callData.native.function(newCallFrame));
#else
else
result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
#endif
}
}
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, function);
#if ENABLE(LLINT_C_LOOP)
m_stack.popFrame(newCallFrame);
#endif
return checkedReturn(result);
}
......@@ -1032,22 +992,12 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (UNLIKELY(vm.watchdog.didFire(callFrame)))
return throwTerminatedExecutionException(callFrame);
#if ENABLE(LLINT_C_LOOP)
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, constructor);
if (UNLIKELY(!newCallFrame))
return checkedReturn(throwStackOverflowError(callFrame));
// Set the arguments for the callee:
newCallFrame->setThisValue(jsUndefined());
for (size_t i = 0; i < args.size(); ++i)
newCallFrame->setArgument(i, args.at(i));
#else
if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
return checkedReturn(throwStackOverflowError(callFrame));
ProtoCallFrame protoCallFrame;
protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
#endif
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, constructor);
......@@ -1058,18 +1008,11 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
Watchdog::Scope watchdogScope(vm.watchdog);
// Execute the code.
if (isJSConstruct) {
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
#elif ENABLE(JIT)
if (isJSConstruct)
result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
#endif // ENABLE(JIT)
} else {
#if ENABLE(LLINT_C_LOOP)
result = JSValue::decode(constructData.native.function(newCallFrame));
#else
else {
result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
#endif
if (!callFrame->hadException())
RELEASE_ASSERT(result.isObject());
}
......@@ -1078,21 +1021,13 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, constructor);
#if ENABLE(LLINT_C_LOOP)
m_stack.popFrame(newCallFrame);
#endif
if (callFrame->hadException())
return 0;
ASSERT(result.isObject());
return checkedReturn(asObject(result));
}
#if ENABLE(LLINT_C_LOOP)
CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
#else
CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
#endif
{
VM& vm = *scope->vm();
ASSERT(!vm.exception());
......@@ -1111,17 +1046,6 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
size_t argsCount = argumentCountIncludingThis;
#if ENABLE(LLINT_C_LOOP)
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
if (UNLIKELY(!newCallFrame)) {
throwStackOverflowError(callFrame);
return CallFrameClosure();
}
// Return the successful closure:
CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
#else
if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount))) {
throwStackOverflowError(callFrame);
return CallFrameClosure();
......@@ -1130,7 +1054,6 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
// Return the successful closure:
CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
#endif
return result;
}
......@@ -1144,13 +1067,7 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
return jsNull();
StackStats::CheckPoint stackCheckPoint;
#if ENABLE(LLINT_C_LOOP)
m_stack.validateFence(closure.newCallFrame, "BEFORE");
#endif
closure.resetCallFrame();
#if ENABLE(LLINT_C_LOOP)
m_stack.validateFence(closure.newCallFrame, "STEP 1");
#endif
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(closure.oldCallFrame, closure.function);
......@@ -1158,47 +1075,21 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
if (UNLIKELY(vm.watchdog.didFire(closure.oldCallFrame)))
return throwTerminatedExecutionException(closure.oldCallFrame);
// The code execution below may push more frames and point the topCallFrame
// to those newer frames, or it may pop to the top frame to the caller of
// the current repeat frame, or it may leave the top frame pointing to the
// current repeat frame.
//
// Hence, we need to preserve the topCallFrame here ourselves before
// repeating this call on a second callback function.
#if ENABLE(LLINT_C_LOOP)
TopCallFrameSetter topCallFrame(vm, closure.newCallFrame);
#endif
// Execute the code:
JSValue result;
{
SamplingTool::CallRecord callRecord(m_sampler.get());
Watchdog::Scope watchdogScope(vm.watchdog);
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
#elif ENABLE(JIT)
result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.newCallFrame, m_stack.getTopOfStack());
#endif // ENABLE(JIT)
result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.protoCallFrame, m_stack.getTopOfStack());
}
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(closure.oldCallFrame, closure.function);
#if ENABLE(LLINT_C_LOOP)
m_stack.validateFence(closure.newCallFrame, "AFTER");
#endif
return checkedReturn(result);
}
#if ENABLE(LLINT_C_LOOP)
void Interpreter::endRepeatCall(CallFrameClosure& closure)
{
m_stack.popFrame(closure.newCallFrame);
}
#endif
JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
{
VM& vm = *scope->vm();
......@@ -1259,22 +1150,13 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
if (UNLIKELY(vm.watchdog.didFire(callFrame)))
return throwTerminatedExecutionException(callFrame);
// Push the frame:
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
#if ENABLE(LLINT_C_LOOP)
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
if (UNLIKELY(!newCallFrame))
return checkedReturn(throwStackOverflowError(callFrame));
// Set the arguments for the callee:
newCallFrame->setThisValue(thisValue);
#else
if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
return checkedReturn(throwStackOverflowError(callFrame));
ProtoCallFrame protoCallFrame;
protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
#endif
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo());
......@@ -1285,19 +1167,12 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
SamplingTool::CallRecord callRecord(m_sampler.get());
Watchdog::Scope watchdogScope(vm.watchdog);
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
#elif ENABLE(JIT)
result = eval->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
#endif // ENABLE(JIT)
}
if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
#if ENABLE(LLINT_C_LOOP)
m_stack.popFrame(newCallFrame);
#endif
return checkedReturn(result);
}
......
......@@ -257,12 +257,8 @@ namespace JSC {
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
#if !ENABLE(LLINT_C_LOOP)
CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*);
#else
CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*);
void endRepeatCall(CallFrameClosure&);
#endif
JSValue execute(CallFrameClosure&);
void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
......
......@@ -102,8 +102,7 @@ namespace JSC {
bool entryCheck(class CodeBlock*, int);
CallFrame* pushFrame(CallFrame* callerFrame, class CodeBlock*,
JSScope*, int argsCount, JSObject* callee);
CallFrame* pushFrame(class CodeBlock*, JSScope*, int argsCount, JSObject* callee);
void popFrame(CallFrame*);
......
......@@ -80,8 +80,7 @@ inline bool JSStack::entryCheck(class CodeBlock* codeBlock, int argsCount)
return true;
}
inline CallFrame* JSStack::pushFrame(CallFrame* callerFrame,
class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
inline CallFrame* JSStack::pushFrame(class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
{
ASSERT(!!scope);
Register* oldEnd = getTopOfStack();
......@@ -119,7 +118,7 @@ inline CallFrame* JSStack::pushFrame(CallFrame* callerFrame,
// The caller frame should always be the real previous frame on the stack,
// and not a potential GlobalExec that was passed in. Point callerFrame to
// the top frame on the stack.
callerFrame = m_topCallFrame;
CallFrame* callerFrame = m_topCallFrame;
// Initialize the VM sentinel frame header:
newVMEntrySentinelFrame->initializeVMEntrySentinelFrame(callerFrame);
......
......@@ -40,21 +40,35 @@ struct ProtoCallFrame {
JSValue *args;
void init(CodeBlock*, JSScope*, JSObject*, JSValue, int, JSValue* otherArgs = 0);
CodeBlock* codeBlock() const { return codeBlockValue.Register::codeBlock(); }
void setCodeBlock(CodeBlock* codeBlock) { codeBlockValue = codeBlock; }
JSScope* scope() const { return scopeChainValue.Register::scope(); }
void setScope(JSScope* scope) { scopeChainValue = scope; }
JSObject* callee() const { return calleeValue.Register::function(); }
void setCallee(JSObject* callee) { calleeValue = Register::withCallee(callee); }
int argumentCountIncludingThis() const { return argCountAndCodeOriginValue.payload(); }
int argumentCount() const { return argumentCountIncludingThis() - 1; }
void setArgumentCountIncludingThis(int count) { argCountAndCodeOriginValue.payload() = count; }
void setPaddedArgsCount(size_t argCount) { paddedArgCount = argCount; }
void clearCurrentVPC() { argCountAndCodeOriginValue.tag() = 0; }
JSValue thisValue() const { return thisArg.Register::jsValue(); }
void setThisValue(JSValue value) { thisArg = value; }
void setArgument(size_t argument, JSValue value)
JSValue argument(size_t argumentIndex)
{
ASSERT(static_cast<int>(argumentIndex) < argumentCount());
return args[argumentIndex];
}
void setArgument(size_t argumentIndex, JSValue value)
{
ASSERT(static_cast<int>(argument) < argumentCount());
args[argument] = value;
ASSERT(static_cast<int>(argumentIndex) < argumentCount());
args[argumentIndex] = value;
}
};
......
......@@ -41,7 +41,6 @@ JITCode::~JITCode()
{
}
#if ENABLE(JIT)
JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame, Register* topOfStack)
{
ASSERT(!vm->topCallFrame || ((Register*)(vm->topCallFrame) >= topOfStack));
......@@ -49,7 +48,6 @@ JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame, Register* topOf
JSValue result = JSValue::decode(callToJavaScript(executableAddress(), &vm->topCallFrame, protoCallFrame, topOfStack));
return vm->exception() ? jsNull() : result;
}
#endif
DFG::CommonData* JITCode::dfgCommon()
{
......
......@@ -47,11 +47,7 @@ class JITCode;
}
struct ProtoCallFrame;
#if ENABLE(JIT)
class VM;
class JSStack;
#endif
class JITCode : public ThreadSafeRefCounted<JITCode> {
public:
......
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
* Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -39,8 +39,6 @@
#include "Operations.h"
#include "VM.h"
#if ENABLE(JIT) || ENABLE(LLINT)
namespace JSC {
void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
......@@ -52,14 +50,13 @@ void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
Instruction* catchPCForInterpreter = 0;
if (handler) {
catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
catchRoutine = ExecutableBase::catchRoutineFor(handler, catchPCForInterpreter);
} else {
#if ENABLE(LLINT_C_LOOP)