diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-11-06 16:14:46 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-11-15 18:46:46 +0000 |
commit | 6b738e3224c26fcce148b569188e2a25520e54d6 (patch) | |
tree | be505078357b95574d6b59f6832bfa78cf3a63e6 | |
parent | 557ea845157d4f6b757ec2eebbc71e1af9910cc6 (diff) |
Don't copy unnamed arguments onto the JS stack
These can only be referenced through the arguments
objects, and have so far messed up initialization
of local variables.
Change-Id: I3100520ed55c93204dd7953da8cc3d2b7d200d11
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 7 |
3 files changed, 16 insertions, 9 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 86b1f0eb2c..00d816fe91 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -55,9 +55,12 @@ DEFINE_MANAGED_VTABLE(ExecutionContext); DEFINE_MANAGED_VTABLE(CallContext); DEFINE_MANAGED_VTABLE(CatchContext); -Heap::CallContext *ExecutionContext::newCallContext(Heap::ExecutionContext *outer, Function *function, CallData *callData) +Heap::CallContext *ExecutionContext::newCallContext(CppStackFrame *frame) { - uint nFormals = qMax(static_cast<uint>(callData->argc()), function->nFormals); + Function *function = frame->v4Function; + Heap::ExecutionContext *outer = static_cast<Heap::ExecutionContext *>(frame->context()->m()); + + uint nFormals = qMax(static_cast<uint>(frame->originalArgumentsCount), function->nFormals); uint localsAndFormals = function->compiledFunction->nLocals + nFormals; size_t requiredMemory = sizeof(CallContext::Data) - sizeof(Value) + sizeof(Value) * (localsAndFormals); @@ -66,7 +69,7 @@ Heap::CallContext *ExecutionContext::newCallContext(Heap::ExecutionContext *oute c->init(); c->outer.set(v4, outer); - c->function.set(v4, static_cast<Heap::FunctionObject *>(callData->function.m())); + c->function.set(v4, static_cast<Heap::FunctionObject *>(frame->jsFrame->function.m())); const CompiledData::Function *compiledFunction = function->compiledFunction; uint nLocals = compiledFunction->nLocals; @@ -75,8 +78,11 @@ Heap::CallContext *ExecutionContext::newCallContext(Heap::ExecutionContext *oute // memory allocated from the JS heap is 0 initialized, so check if undefined is 0 Q_ASSERT(Primitive::undefinedValue().asReturnedValue() == 0); - ::memcpy(c->locals.values + nLocals, &callData->args[0], nFormals * sizeof(Value)); - c->nArgs = callData->argc(); + Value *args = c->locals.values + nLocals; + ::memcpy(args, frame->originalArguments, frame->originalArgumentsCount * sizeof(Value)); + c->nArgs = frame->originalArgumentsCount; + for (uint i = frame->originalArgumentsCount; i < function->nFormals; ++i) + args[i] = Encode::undefined(); return c; } diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index a73e7118ea..4efd0bc899 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -204,7 +204,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed Q_MANAGED_TYPE(ExecutionContext) V4_INTERNALCLASS(ExecutionContext) - static Heap::CallContext *newCallContext(Heap::ExecutionContext *outer, Function *function, CallData *callData); + static Heap::CallContext *newCallContext(QV4::CppStackFrame *frame); Heap::ExecutionContext *newWithContext(Heap::Object *with); Heap::CatchContext *newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 9eb51763ca..9159f55245 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -530,11 +530,13 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject, callData->context = scope; callData->accumulator = Encode::undefined(); callData->thisObject = thisObject ? *thisObject : Primitive::undefinedValue(); + if (argc > int(function->nFormals)) + argc = int(function->nFormals); 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 + memcpy(callData->args, argv, argc*sizeof(Value)); for (Value *v = callData->args + argc; v < engine->jsStackTop; ++v) *v = Encode::undefined(); @@ -849,8 +851,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject, MOTH_END_INSTR(PushCatchContext) MOTH_BEGIN_INSTR(CreateCallContext) - Heap::ExecutionContext *ctx = static_cast<Heap::ExecutionContext *>(stack[CallData::Context].m()); - stack[CallData::Context] = ExecutionContext::newCallContext(ctx, function, reinterpret_cast<CallData *>(stack)); + stack[CallData::Context] = ExecutionContext::newCallContext(&frame); MOTH_END_INSTR(CreateCallContext) MOTH_BEGIN_INSTR(PushWithContext) |