diff options
author | Erik Verbruggen <[email protected]> | 2016-06-22 10:12:13 +0200 |
---|---|---|
committer | Erik Verbruggen <[email protected]> | 2016-06-22 11:07:05 +0000 |
commit | 702c4247d74ffb7e4fb1aaca96d70f4591203ba2 (patch) | |
tree | 6c0a41332cf4a8ab0051600efdd27b0746574795 /src/qml/jsruntime/qv4scopedvalue_p.h | |
parent | fd0e3c6d569a7410fff33974ce9f908dc2de0e22 (diff) |
V4: Pass scope around as parameters inside the runtime.
The implementation of many (or all) runtime functions consist of first
creating a QV4::Scope, which saves and restores the JS stack pointer.
It also prevents tail-calls because of that restoring behavior. In many
cases it suffices to do that at the entry-point of the runtime.
The return value of a JS function call is now also stored in the scope.
Previously, all return values were stored in a ScopedValue, got loaded
on return, and immediately stored in another ScopedValue in the caller.
This resulted in a lot of stores, where now there is only one store
needed, and no extra ScopedValue for every function.
Change-Id: I13d80fc0ce72c5702ef1536d41d12f710c5914fa
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src/qml/jsruntime/qv4scopedvalue_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index a6f7f8e0e7..aa811ddba4 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -71,14 +71,18 @@ struct ScopedValue; struct Scope { inline Scope(ExecutionContext *ctx) : engine(ctx->d()->engine) + , mark(engine->jsStackTop) + , result(*engine->jsAlloca(1)) { - mark = engine->jsStackTop; + result = Encode::undefined(); } explicit Scope(ExecutionEngine *e) : engine(e) + , mark(engine->jsStackTop) + , result(*engine->jsAlloca(1)) { - mark = engine->jsStackTop; + result = Encode::undefined(); } ~Scope() { @@ -93,7 +97,7 @@ struct Scope { engine->jsStackTop = mark; } - Value *alloc(int nValues) { + Value *alloc(int nValues) const { return engine->jsAlloca(nValues); } @@ -103,6 +107,7 @@ struct Scope { ExecutionEngine *engine; Value *mark; + Value &result; private: Q_DISABLE_COPY(Scope) @@ -190,59 +195,59 @@ struct Scoped Scoped(const Scope &scope) { - ptr = scope.engine->jsStackTop++; - ptr->setM(0); + ptr = scope.engine->jsAlloca(1); } Scoped(const Scope &scope, const Value &v) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); setPointer(v.as<T>()); } Scoped(const Scope &scope, Heap::Base *o) { Value v; v = o; - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); setPointer(v.as<T>()); } Scoped(const Scope &scope, const ScopedValue &v) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); setPointer(v.ptr->as<T>()); } Scoped(const Scope &scope, const Value &v, ConvertType) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); ptr->setRawValue(value_convert<T>(scope.engine, v)); } Scoped(const Scope &scope, const Value *v) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); setPointer(v ? v->as<T>() : 0); } Scoped(const Scope &scope, T *t) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); setPointer(t); } Scoped(const Scope &scope, typename T::Data *t) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); *ptr = t; } Scoped(const Scope &scope, const ReturnedValue &v) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); setPointer(QV4::Value::fromReturnedValue(v).as<T>()); } + Scoped(const Scope &scope, const ReturnedValue &v, ConvertType) { - ptr = scope.engine->jsStackTop++; + ptr = scope.engine->jsAlloca(1); ptr->setRawValue(value_convert<T>(scope.engine, QV4::Value::fromReturnedValue(v))); } @@ -311,7 +316,7 @@ struct Scoped }; struct ScopedCallData { - ScopedCallData(Scope &scope, int argc = 0) + ScopedCallData(const Scope &scope, int argc = 0) { int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value); ptr = reinterpret_cast<CallData *>(scope.alloc(size)); @@ -362,19 +367,19 @@ struct ScopedProperty struct ExecutionContextSaver { - ExecutionEngine *engine; + Scope scope; // this makes sure that a reference to context on the JS stack goes out of scope as soon as the context is not used anymore. ExecutionContext *savedContext; - ExecutionContextSaver(Scope &scope) - : engine(scope.engine) + ExecutionContextSaver(const Scope &scope) + : scope(scope.engine) { - savedContext = engine->currentContext; + savedContext = scope.engine->currentContext; } ~ExecutionContextSaver() { - Q_ASSERT(engine->jsStackTop > engine->currentContext); - engine->currentContext = savedContext; - engine->current = savedContext->d(); + Q_ASSERT(scope.engine->jsStackTop > scope.engine->currentContext); + scope.engine->currentContext = savedContext; + scope.engine->current = savedContext->d(); } }; |