diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-04-06 10:20:08 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:17:51 +0000 |
commit | 922e6f42b4fa9b9fa87246c577c13bb945bd4bc4 (patch) | |
tree | 182cf430b7340c4f34c0cb350af1c15fd41b6648 /src/qml/jsruntime | |
parent | 20d30b6b3a253eebedc927dbb91685bbec52cfee (diff) |
Rework catch context handling
Remove the need for a specialized catch context, instead
use a regular block context, that also captures the
catched variable.
This also removes the need to do lookups by name inside
a catch expression.
Change-Id: I8b037add7f423922e2a76b4c0da646ca7e25813a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 48 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 27 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4enginebase_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 2 |
7 files changed, 17 insertions, 75 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 39fdcf0227..bd2e0faebf 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -53,7 +53,6 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(ExecutionContext); DEFINE_MANAGED_VTABLE(CallContext); -DEFINE_MANAGED_VTABLE(CatchContext); Heap::CallContext *ExecutionContext::newBlockContext(CppStackFrame *frame, int blockIndex) { @@ -119,11 +118,14 @@ Heap::ExecutionContext *ExecutionContext::newWithContext(Heap::Object *with) return c; } -Heap::CatchContext *ExecutionContext::newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue) +Heap::ExecutionContext *ExecutionContext::newCatchContext(CppStackFrame *frame, int blockIndex, Heap::String *exceptionVarName) { - Scope scope(this); - ScopedValue e(scope, exceptionValue); - return engine()->memoryManager->alloc<CatchContext>(d(), exceptionVarName, e); + Scope scope(frame->context()); + ScopedString name(scope, exceptionVarName); + ScopedValue val(scope, scope.engine->catchException(nullptr)); + ScopedContext ctx(scope, newBlockContext(frame, blockIndex)); + ctx->setProperty(name, val); + return ctx->d(); } void ExecutionContext::createMutableBinding(String *name, bool deletable) @@ -170,16 +172,6 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) activation->__defineOwnProperty__(scope.engine, name, desc, attrs); } -void Heap::CatchContext::init(ExecutionContext *outerContext, String *exceptionVarName, - const Value &exceptionValue) -{ - Heap::ExecutionContext::init(Heap::ExecutionContext::Type_CatchContext); - outer.set(internalClass->engine, outerContext); - - this->exceptionVarName.set(internalClass->engine, exceptionVarName); - this->exceptionValue.set(internalClass->engine, exceptionValue); -} - bool ExecutionContext::deleteProperty(String *name) { name->makeIdentifier(); @@ -188,12 +180,6 @@ bool ExecutionContext::deleteProperty(String *name) Heap::ExecutionContext *ctx = d(); for (; ctx; ctx = ctx->outer) { switch (ctx->type) { - case Heap::ExecutionContext::Type_CatchContext: { - Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx); - if (c->exceptionVarName->isEqualTo(name->d())) - return false; - break; - } case Heap::ExecutionContext::Type_BlockContext: case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); @@ -232,14 +218,6 @@ ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value for (; ctx; ctx = ctx->outer) { switch (ctx->type) { - case Heap::ExecutionContext::Type_CatchContext: { - Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx); - if (c->exceptionVarName->isEqualTo(name->d())) { - c->exceptionValue.set(v4, value); - return NoError; - } - break; - } case Heap::ExecutionContext::Type_WithContext: { Scope scope(v4); ScopedObject w(scope, ctx->activation); @@ -293,12 +271,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) Heap::ExecutionContext *ctx = d(); for (; ctx; ctx = ctx->outer) { switch (ctx->type) { - case Heap::ExecutionContext::Type_CatchContext: { - Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx); - if (c->exceptionVarName->isEqualTo(name->d())) - return c->exceptionValue.asReturnedValue(); - break; - } case Heap::ExecutionContext::Type_BlockContext: case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); @@ -335,12 +307,6 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) Heap::ExecutionContext *ctx = d(); for (; ctx; ctx = ctx->outer) { switch (ctx->type) { - case Heap::ExecutionContext::Type_CatchContext: { - Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx); - if (c->exceptionVarName->isEqualTo(name->d())) - return c->exceptionValue.asReturnedValue(); - break; - } case Heap::ExecutionContext::Type_BlockContext: case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 5a9c85c941..cd99f162d2 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -107,11 +107,10 @@ DECLARE_HEAP_OBJECT(ExecutionContext, Base) { enum ContextType { Type_GlobalContext = 0x1, - Type_CatchContext = 0x2, - Type_WithContext = 0x3, - Type_QmlContext = 0x4, - Type_BlockContext = 0x5, - Type_CallContext = 0x6 + Type_WithContext = 0x2, + Type_QmlContext = 0x3, + Type_BlockContext = 0x4, + Type_CallContext = 0x5 }; void init(ContextType t) @@ -169,16 +168,6 @@ Q_STATIC_ASSERT(offsetof(CallContextData, function) == 0); //Q_STATIC_ASSERT(sizeof(CallContext) == sizeof(ExecutionContext) + sizeof(CallContextData)); //#endif -#define CatchContextMembers(class, Member) \ - Member(class, Pointer, String *, exceptionVarName) \ - Member(class, HeapValue, HeapValue, exceptionValue) - -DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) { - DECLARE_MARKOBJECTS(CatchContext); - - void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue); -}; -Q_STATIC_ASSERT(std::is_trivial< CatchContext >::value); } @@ -195,7 +184,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed static Heap::CallContext *newBlockContext(QV4::CppStackFrame *frame, int blockIndex); static Heap::CallContext *newCallContext(QV4::CppStackFrame *frame); Heap::ExecutionContext *newWithContext(Heap::Object *with); - Heap::CatchContext *newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue); + static Heap::ExecutionContext *newCatchContext(CppStackFrame *frame, int blockIndex, Heap::String *exceptionVarName); void createMutableBinding(String *name, bool deletable); @@ -228,12 +217,6 @@ struct Q_QML_EXPORT CallContext : public ExecutionContext } }; -struct CatchContext : public ExecutionContext -{ - V4_MANAGED(CatchContext, ExecutionContext) - V4_INTERNALCLASS(CatchContext) -}; - inline CallContext *ExecutionContext::asCallContext() { return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<CallContext *>(this) : nullptr; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 10030a14e4..3660ab3855 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -209,7 +209,6 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) classes[Class_SparseArrayData] = classes[Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable()); classes[Class_ExecutionContext] = classes[Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable()); classes[Class_CallContext] = classes[Class_Empty]->changeVTable(QV4::CallContext::staticVTable()); - classes[Class_CatchContext] = classes[Class_Empty]->changeVTable(QV4::CatchContext::staticVTable()); classes[Class_QmlContext] = classes[Class_Empty]->changeVTable(QV4::QmlContext::staticVTable()); jsStrings[String_Empty] = newIdentifier(QString()); diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h index b7f6b8d3cd..c01b9b1842 100644 --- a/src/qml/jsruntime/qv4enginebase_p.h +++ b/src/qml/jsruntime/qv4enginebase_p.h @@ -96,7 +96,6 @@ struct Q_QML_EXPORT EngineBase { Class_SparseArrayData, Class_ExecutionContext, Class_CallContext, - Class_CatchContext, Class_QmlContext, Class_Object, Class_ArrayObject, diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 95e4017344..40e08ededb 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1183,11 +1183,6 @@ QV4::ReturnedValue Runtime::method_typeofName(ExecutionEngine *engine, int nameI return method_typeofValue(engine, prop); } -/* The next three methods are a bit tricky. They can't open up a Scope, as that - * would mess up the pushing of the context. - * - * Instead the push/pop pair acts as a non local scope. - */ ReturnedValue Runtime::method_createWithContext(ExecutionContext *parent, const Value &o) { Q_ASSERT(o.isObject()); @@ -1195,11 +1190,11 @@ ReturnedValue Runtime::method_createWithContext(ExecutionContext *parent, const return parent->newWithContext(obj.d())->asReturnedValue(); } -ReturnedValue Runtime::method_createCatchContext(ExecutionContext *parent, int exceptionVarNameIndex) +ReturnedValue Runtime::method_createCatchContext(ExecutionContext *parent, int blockIndex, int exceptionVarNameIndex) { ExecutionEngine *e = parent->engine(); - return parent->newCatchContext(e->currentStackFrame->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex], - e->catchException(nullptr))->asReturnedValue(); + return parent->newCatchContext(e->currentStackFrame, blockIndex, + e->currentStackFrame->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex])->asReturnedValue(); } ReturnedValue Runtime::method_createBlockContext(ExecutionContext *parent, int index) diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index 24bab70327..a1a7bd9ed0 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -125,7 +125,7 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { /* exceptions & scopes */ \ F(void, throwException, (ExecutionEngine *engine, const Value &value)) \ F(ReturnedValue, createWithContext, (ExecutionContext *parent, const Value &o)) \ - F(ReturnedValue, createCatchContext, (ExecutionContext *parent, int exceptionVarNameIndex)) \ + F(ReturnedValue, createCatchContext, (ExecutionContext *parent, int blockIndex, int exceptionVarNameIndex)) \ F(ReturnedValue, createBlockContext, (ExecutionContext *parent, int index)) \ \ /* closures */ \ diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index a515abd9de..4a7339ca3a 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -877,7 +877,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObj MOTH_BEGIN_INSTR(PushCatchContext) STACK_VALUE(reg) = STACK_VALUE(CallData::Context); ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context); - STACK_VALUE(CallData::Context) = Runtime::method_createCatchContext(c, name); + STACK_VALUE(CallData::Context) = Runtime::method_createCatchContext(c, index, name); MOTH_END_INSTR(PushCatchContext) MOTH_BEGIN_INSTR(CreateCallContext) |