aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-04-06 10:20:08 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-02 14:17:51 +0000
commit922e6f42b4fa9b9fa87246c577c13bb945bd4bc4 (patch)
tree182cf430b7340c4f34c0cb350af1c15fd41b6648 /src/qml/jsruntime
parent20d30b6b3a253eebedc927dbb91685bbec52cfee (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.cpp48
-rw-r--r--src/qml/jsruntime/qv4context_p.h27
-rw-r--r--src/qml/jsruntime/qv4engine.cpp1
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h1
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp11
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
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)