diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-10-24 14:57:53 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-11-13 08:56:11 +0000 |
commit | 831ddc54932d2681712ca9fa3e94484ae11d59f7 (patch) | |
tree | 0cf4ad8756d9cae65f3c57f1c77c946eaf1f5749 /src/qml/jsruntime/qv4vme_moth.cpp | |
parent | d9b0878595e7ee2698ddc8c724657574d5fe4d4c (diff) |
Cut out one more C++ layer when doing JS function calls
Change-Id: I0e2ac30b7e6d77fe41deb84a97b0a7f220437c6a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4vme_moth.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 5b01e5a26b..58b54cf86c 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -497,46 +497,66 @@ static bool compareEqualInt(Value &accumulator, Value lhs, int rhs) } \ } while (false) -QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function) +QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc) { qt_v4ResolvePendingBreakpointsHook(); + ExecutionEngine *engine; + Value *stack; + CppStackFrame frame; + Function *function; - MOTH_JUMP_TABLE; + { + Heap::ExecutionContext *scope; + + quintptr d = reinterpret_cast<quintptr>(fo); + if (d & 0x1) { + // we don't have a FunctionObject, but a ExecData + ExecData *data = reinterpret_cast<ExecData *>(d - 1); + function = data->function; + scope = data->scope->d(); + fo = nullptr; + } else { + function = fo->function(); + scope = fo->scope(); + } - ExecutionEngine *engine = function->internalClass->engine; - CHECK_STACK_LIMITS(engine); - Profiling::FunctionCallProfiler profiler(engine, function); - Q_UNUSED(profiler) - - Value *jsStackTop = engine->jsStackTop; - - Q_ASSERT(engine->jsStackTop == callData->args + callData->argc()); - Value *stack = reinterpret_cast<Value *>(callData); - int stackSpaceToAdd = int(function->compiledFunction->nRegisters) - callData->argc(); - if (stackSpaceToAdd > 0) { - // clear out remaining arguments and local registers - for (int i = 0; i < stackSpaceToAdd; ++i) - engine->jsStackTop[i] = Encode::undefined(); - engine->jsStackTop += stackSpaceToAdd; + engine = function->internalClass->engine; + + stack = engine->jsStackTop; + CallData *callData = reinterpret_cast<CallData *>(stack); + callData->function = fo ? fo->asReturnedValue() : Encode::undefined(); + callData->context = scope; + callData->accumulator = Encode::undefined(); + callData->thisObject = thisObject ? *thisObject : Primitive::undefinedValue(); + callData->setArgc(argc); + + int jsStackFrameSize = offsetof(CallData, args)/sizeof(Value) + function->compiledFunction->nRegisters; + engine->jsStackTop += jsStackFrameSize; + memcpy(callData->args, argv, argc*sizeof(Value)); // ### Fixme: only copy nFormals + for (Value *v = callData->args + argc; v < engine->jsStackTop; ++v) + *v = Encode::undefined(); + + frame.parent = engine->currentStackFrame; + frame.v4Function = function; + frame.instructionPointer = function->codeData; + frame.jsFrame = callData; + engine->currentStackFrame = &frame; } + CHECK_STACK_LIMITS(engine); - CppStackFrame frame; - frame.parent = engine->currentStackFrame; - frame.v4Function = function; - frame.instructionPointer = function->codeData; - frame.jsFrame = callData; - engine->currentStackFrame = &frame; + Profiling::FunctionCallProfiler profiler(engine, function); + if (QV4::Debugging::Debugger *debugger = engine->debugger()) + debugger->enteringFunction(); const uchar *exceptionHandler = 0; QV4::Value &accumulator = frame.jsFrame->accumulator; QV4::ReturnedValue acc = Encode::undefined(); - if (QV4::Debugging::Debugger *debugger = engine->debugger()) - debugger->enteringFunction(); - const uchar *code = function->codeData; + MOTH_JUMP_TABLE; + for (;;) { MOTH_DISPATCH() Q_UNREACHABLE(); // only reached when the dispatch doesn't jump somewhere @@ -1321,7 +1341,7 @@ functionExit: if (QV4::Debugging::Debugger *debugger = engine->debugger()) debugger->leavingFunction(ACC.asReturnedValue()); engine->currentStackFrame = frame.parent; - engine->jsStackTop = jsStackTop; + engine->jsStackTop = stack; return acc; } |