summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-03-06 20:04:39 +0100
committerLars Knoll <lars.knoll@digia.com>2013-03-06 22:19:32 +0100
commit85e92adeb6a31702a74aeef387423427541ebcf4 (patch)
tree71a56885312ba09b36d4b288a12469fc77513bd3
parent117455638a555629e82e415312908128280ad72d (diff)
Get rid of 'Value ExecutionEngine::exception' member
Instead the JS exception value is now part of the C++ Exception object. This also allows getting rid of some run-time functions. Change-Id: I43ff773cacd5e925ba96601f3633ccf3b62273be Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/v4/llvm_runtime.cpp12
-rw-r--r--src/v4/moth/qv4vme_moth.cpp8
-rw-r--r--src/v4/qmljs_engine.cpp3
-rw-r--r--src/v4/qmljs_engine.h2
-rw-r--r--src/v4/qmljs_environment.cpp10
-rw-r--r--src/v4/qmljs_environment.h4
-rw-r--r--src/v4/qmljs_runtime.cpp21
-rw-r--r--src/v4/qmljs_runtime.h11
-rw-r--r--src/v4/qv4isel_masm.cpp9
-rw-r--r--tools/v4/main.cpp9
10 files changed, 29 insertions, 60 deletions
diff --git a/src/v4/llvm_runtime.cpp b/src/v4/llvm_runtime.cpp
index c3aede78..c0c5415e 100644
--- a/src/v4/llvm_runtime.cpp
+++ b/src/v4/llvm_runtime.cpp
@@ -474,23 +474,11 @@ void __qmljs_llvm_throw(ExecutionContext *context, Value *value)
__qmljs_throw(context, *value);
}
-void __qmljs_llvm_create_exception_handler(ExecutionContext *context, Value *result)
-{
- // ### FIXME.
- __qmljs_create_exception_handler(context);
- *result = Value::undefinedValue();
-}
-
void __qmljs_llvm_delete_exception_handler(ExecutionContext *context)
{
// ### FIXME.
}
-void __qmljs_llvm_get_exception(ExecutionContext *context, Value *result)
-{
- __qmljs_get_exception(context, result);
-}
-
void __qmljs_llvm_foreach_iterator_object(ExecutionContext *context, Value *result, Value *in)
{
__qmljs_foreach_iterator_object(context, result, *in);
diff --git a/src/v4/moth/qv4vme_moth.cpp b/src/v4/moth/qv4vme_moth.cpp
index a20fdbf3..6487efc4 100644
--- a/src/v4/moth/qv4vme_moth.cpp
+++ b/src/v4/moth/qv4vme_moth.cpp
@@ -259,23 +259,23 @@ VM::Value VME::run(QQmlJS::VM::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(CallBuiltinThrow)
MOTH_BEGIN_INSTR(EnterTry)
- __qmljs_create_exception_handler(context);
+ VALUE(instr.exceptionVar) = VM::Value::undefinedValue();
try {
const uchar *tryCode = ((uchar *)&instr.tryOffset) + instr.tryOffset;
run(context, tryCode, stack, stackSize);
code = tryCode;
} catch (VM::Exception &ex) {
ex.accept(context);
- __qmljs_get_exception(context, VALUEPTR(instr.exceptionVar));
+ VALUE(instr.exceptionVar) = ex.value();
try {
- VM::ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(instr.exceptionVarName, context);
+ VM::ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(instr.exceptionVarName, ex.value(), context);
const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset;
run(catchContext, catchCode, stack, stackSize);
code = catchCode;
context = __qmljs_builtin_pop_scope(catchContext);
} catch (VM::Exception &ex) {
ex.accept(context);
- __qmljs_get_exception(context, VALUEPTR(instr.exceptionVar));
+ VALUE(instr.exceptionVar) = ex.value();
const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset;
run(context, catchCode, stack, stackSize);
code = catchCode;
diff --git a/src/v4/qmljs_engine.cpp b/src/v4/qmljs_engine.cpp
index bf482ca6..900190e3 100644
--- a/src/v4/qmljs_engine.cpp
+++ b/src/v4/qmljs_engine.cpp
@@ -69,7 +69,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, debugger(0)
, globalObject(Value::nullValue())
, globalCode(0)
- , exception(Value::nullValue())
, externalResourceComparison(0)
{
MemoryManager::GCBlocker gcBlocker(memoryManager);
@@ -431,8 +430,6 @@ void ExecutionEngine::markObjects()
if (globalCode)
globalCode->mark();
- exception.mark();
-
for (int i = 0; i < argumentsAccessors.size(); ++i) {
const PropertyDescriptor &pd = argumentsAccessors.at(i);
pd.get->mark();
diff --git a/src/v4/qmljs_engine.h b/src/v4/qmljs_engine.h
index 39330fa7..056e5bb9 100644
--- a/src/v4/qmljs_engine.h
+++ b/src/v4/qmljs_engine.h
@@ -180,8 +180,6 @@ struct Q_V4_EXPORT ExecutionEngine
String *id_set;
String *id_eval;
- Value exception;
-
QVector<Function *> functions;
ExternalResourceComparison externalResourceComparison;
diff --git a/src/v4/qmljs_environment.cpp b/src/v4/qmljs_environment.cpp
index f4b2f51f..1f55717d 100644
--- a/src/v4/qmljs_environment.cpp
+++ b/src/v4/qmljs_environment.cpp
@@ -178,10 +178,10 @@ ExecutionContext *ExecutionContext::createWithScope(Object *with)
return withCtx;
}
-ExecutionContext *ExecutionContext::createCatchScope(String *exceptionVarName)
+ExecutionContext *ExecutionContext::createCatchScope(String *exceptionVarName, const Value &exceptionValue)
{
ExecutionContext *catchCtx = engine->newContext();
- catchCtx->initForCatch(this, exceptionVarName);
+ catchCtx->initForCatch(this, exceptionVarName, exceptionValue);
engine->current = catchCtx;
return catchCtx;
}
@@ -235,8 +235,6 @@ void ExecutionContext::init(ExecutionEngine *eng)
strictMode = false;
activation = 0;
withObject = 0;
-
- eng->exception = Value::undefinedValue();
}
void ExecutionContext::init(ExecutionContext *p, Object *with)
@@ -259,7 +257,7 @@ void ExecutionContext::init(ExecutionContext *p, Object *with)
withObject = with;
}
-void ExecutionContext::initForCatch(ExecutionContext *p, String *exceptionVarName)
+void ExecutionContext::initForCatch(ExecutionContext *p, String *exceptionVarName, const Value &exceptionValue)
{
engine = p->engine;
parent = p;
@@ -272,7 +270,7 @@ void ExecutionContext::initForCatch(ExecutionContext *p, String *exceptionVarNam
argumentCount = 0;
locals = 0;
this->exceptionVarName = exceptionVarName;
- exceptionValue = engine->exception;
+ this->exceptionValue = exceptionValue;
strictMode = p->strictMode;
activation = 0;
withObject = 0;
diff --git a/src/v4/qmljs_environment.h b/src/v4/qmljs_environment.h
index 42aeba12..934015c9 100644
--- a/src/v4/qmljs_environment.h
+++ b/src/v4/qmljs_environment.h
@@ -103,7 +103,7 @@ struct ExecutionContext
void init(ExecutionEngine *e);
void init(ExecutionContext *p, Object *with);
- void initForCatch(ExecutionContext *p, String *exceptionVarName);
+ void initForCatch(ExecutionContext *p, String *exceptionVarName, const QQmlJS::VM::Value &exceptionValue);
void destroy();
bool hasBinding(String *name) const;
@@ -113,7 +113,7 @@ struct ExecutionContext
bool deleteBinding(ExecutionContext *ctx, String *name);
ExecutionContext *createWithScope(Object *with);
- ExecutionContext *createCatchScope(String* exceptionVarName);
+ ExecutionContext *createCatchScope(String* exceptionVarName, const QQmlJS::VM::Value &exceptionValue);
ExecutionContext *popScope();
void initCallContext(ExecutionContext *parent);
diff --git a/src/v4/qmljs_runtime.cpp b/src/v4/qmljs_runtime.cpp
index 447600f0..f04ed199 100644
--- a/src/v4/qmljs_runtime.cpp
+++ b/src/v4/qmljs_runtime.cpp
@@ -112,9 +112,10 @@ QString numberToString(double num, int radix = 10)
return str;
}
-Exception::Exception(ExecutionContext *throwingContext)
+Exception::Exception(ExecutionContext *throwingContext, const Value &exceptionValue)
{
this->throwingContext = throwingContext;
+ this->exception = exceptionValue;
accepted = false;
}
@@ -1009,19 +1010,7 @@ void __qmljs_throw(ExecutionContext *context, const Value &value)
if (context->engine->debugger)
context->engine->debugger->aboutToThrow(value);
- context->engine->exception = value;
-
- throw Exception(context);
-}
-
-Q_V4_EXPORT void __qmljs_create_exception_handler(ExecutionContext *context)
-{
- context->engine->exception = Value::undefinedValue();
-}
-
-void __qmljs_get_exception(ExecutionContext *context, Value *result)
-{
- *result = context->engine->exception;
+ throw Exception(context, value);
}
void __qmljs_builtin_typeof(ExecutionContext *ctx, Value *result, const Value &value)
@@ -1253,9 +1242,9 @@ ExecutionContext *__qmljs_builtin_push_with_scope(const Value &o, ExecutionConte
return ctx->createWithScope(obj);
}
-ExecutionContext *__qmljs_builtin_push_catch_scope(String *exceptionVarName, ExecutionContext *ctx)
+ExecutionContext *__qmljs_builtin_push_catch_scope(String *exceptionVarName, const Value &exceptionValue, ExecutionContext *ctx)
{
- return ctx->createCatchScope(exceptionVarName);
+ return ctx->createCatchScope(exceptionVarName, exceptionValue);
}
ExecutionContext *__qmljs_builtin_pop_scope(ExecutionContext *ctx)
diff --git a/src/v4/qmljs_runtime.h b/src/v4/qmljs_runtime.h
index 3cd19729..5795eff3 100644
--- a/src/v4/qmljs_runtime.h
+++ b/src/v4/qmljs_runtime.h
@@ -90,15 +90,19 @@ struct ErrorObject;
struct ExecutionEngine;
struct Q_V4_EXPORT Exception {
- explicit Exception(ExecutionContext *throwingContext);
+ explicit Exception(ExecutionContext *throwingContext, const Value &exceptionValue);
~Exception();
void accept(ExecutionContext *catchingContext);
void partiallyUnwindContext(ExecutionContext *catchingContext);
+
+ Value value() const { return exception; }
+
private:
ExecutionContext *throwingContext;
bool accepted;
+ Value exception;
};
extern "C" {
@@ -132,7 +136,7 @@ void __qmljs_builtin_post_decrement_element(ExecutionContext *context, Value *re
void Q_NORETURN __qmljs_builtin_throw(ExecutionContext *context, const Value &val);
void Q_NORETURN __qmljs_builtin_rethrow(ExecutionContext *context);
ExecutionContext *__qmljs_builtin_push_with_scope(const Value &o, ExecutionContext *ctx);
-ExecutionContext *__qmljs_builtin_push_catch_scope(String *exceptionVarName, ExecutionContext *ctx);
+ExecutionContext *__qmljs_builtin_push_catch_scope(String *exceptionVarName, const QQmlJS::VM::Value &exceptionValue, ExecutionContext *ctx);
ExecutionContext *__qmljs_builtin_pop_scope(ExecutionContext *ctx);
void __qmljs_builtin_declare_var(ExecutionContext *ctx, bool deletable, String *name);
void __qmljs_builtin_define_property(ExecutionContext *ctx, const Value &object, String *name, Value *val);
@@ -204,9 +208,6 @@ void __qmljs_delete_member(ExecutionContext *ctx, Value *result, const Value &ba
void __qmljs_delete_name(ExecutionContext *ctx, Value *result, String *name);
void Q_NORETURN __qmljs_throw(ExecutionContext*, const Value &value);
-// actually returns a jmp_buf *
-Q_V4_EXPORT void __qmljs_create_exception_handler(ExecutionContext *context);
-void __qmljs_get_exception(ExecutionContext *context, Value *result);
// binary operators
typedef void (*BinOp)(ExecutionContext *ctx, Value *result, const Value &left, const Value &right);
diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp
index aa58086c..b92b26fe 100644
--- a/src/v4/qv4isel_masm.cpp
+++ b/src/v4/qv4isel_masm.cpp
@@ -680,18 +680,19 @@ typedef void *(*MiddleOfFunctionEntryPoint(ExecutionContext *, void *localsPtr))
static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunctionEntryPoint tryBody, MiddleOfFunctionEntryPoint catchBody,
VM::String *exceptionVarName, Value *exceptionVar)
{
+ *exceptionVar = Value::undefinedValue();
void *addressToContinueAt = 0;
try {
addressToContinueAt = tryBody(context, localsPtr);
} catch (Exception& ex) {
ex.accept(context);
- __qmljs_get_exception(context, exceptionVar);
+ *exceptionVar = ex.value();
try {
- ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(exceptionVarName, context);
+ ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(exceptionVarName, ex.value(), context);
addressToContinueAt = catchBody(catchContext, localsPtr);
context = __qmljs_builtin_pop_scope(catchContext);
} catch (Exception& ex) {
- __qmljs_get_exception(context, exceptionVar);
+ *exceptionVar = ex.value();
ex.accept(context);
addressToContinueAt = catchBody(context, localsPtr);
}
@@ -701,8 +702,6 @@ static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunc
void InstructionSelection::visitTry(IR::Try *t)
{
- generateFunctionCall(Assembler::Void, __qmljs_create_exception_handler, Assembler::ContextRegister);
-
// Call tryWrapper, which is going to re-enter the same function at the address of the try block. At then end
// of the try function the JIT code will return with the address of the sub-sequent instruction, which tryWrapper
// returns and to which we jump to.
diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp
index 03ba8285..7238355c 100644
--- a/tools/v4/main.cpp
+++ b/tools/v4/main.cpp
@@ -116,11 +116,11 @@ DEFINE_MANAGED_VTABLE(GC);
} // builtins
-static void showException(QQmlJS::VM::ExecutionContext *ctx)
+static void showException(QQmlJS::VM::ExecutionContext *ctx, const QQmlJS::VM::Value &exception)
{
- QQmlJS::VM::ErrorObject *e = ctx->engine->exception.asErrorObject();
+ QQmlJS::VM::ErrorObject *e = exception.asErrorObject();
if (!e) {
- std::cerr << "Uncaught exception: " << qPrintable(ctx->engine->exception.toString(ctx)->toQString()) << std::endl;
+ std::cerr << "Uncaught exception: " << qPrintable(exception.toString(ctx)->toQString()) << std::endl;
return;
}
@@ -369,7 +369,6 @@ int main(int argc, char *argv[])
const QString code = QString::fromUtf8(file.readAll());
file.close();
- __qmljs_create_exception_handler(ctx);
try {
QQmlJS::VM::Function *f = QQmlJS::VM::EvalFunction::parseSource(ctx, fn, code, QQmlJS::Codegen::GlobalCode,
/*strictMode =*/ false, /*inheritContext =*/ false);
@@ -382,7 +381,7 @@ int main(int argc, char *argv[])
}
} catch (QQmlJS::VM::Exception& ex) {
ex.accept(ctx);
- showException(ctx);
+ showException(ctx, ex.value());
return EXIT_FAILURE;
}