Convert more methods to use ReturnedValue

Change Exception.value() and a few other places.

Change-Id: I53ce17e5656e260138b1ac7f6d467e4636c0a0b9
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2013-09-12 15:27:01 +02:00 committed by The Qt Project
parent 16f92ad85c
commit ce5dee2422
14 changed files with 86 additions and 63 deletions

View File

@ -776,9 +776,9 @@ void InstructionSelection::callBuiltinThrow(V4IR::Expr *arg)
typedef void *(*MiddleOfFunctionEntryPoint(ExecutionContext *, void *localsPtr));
static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunctionEntryPoint tryBody, MiddleOfFunctionEntryPoint catchBody,
QV4::String *exceptionVarName, Value *exceptionVar)
QV4::String *exceptionVarName, ValueRef exceptionVar)
{
*exceptionVar = Value::undefinedValue();
exceptionVar = Value::undefinedValue();
void *addressToContinueAt = 0;
Value *jsStackTop = context->engine->jsStackTop;
try {
@ -786,7 +786,7 @@ static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunc
} catch (Exception& ex) {
context->engine->jsStackTop = jsStackTop;
ex.accept(context);
*exceptionVar = ex.value();
exceptionVar = ex.value();
try {
QV4::Scope scope(context);
QV4::ScopedValue exception(scope, ex.value());
@ -795,7 +795,7 @@ static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunc
context = __qmljs_builtin_pop_scope(catchContext);
} catch (Exception& ex) {
context->engine->jsStackTop = jsStackTop;
*exceptionVar = ex.value();
exceptionVar = ex.value();
ex.accept(context);
addressToContinueAt = catchBody(context, localsPtr);
}

View File

@ -260,18 +260,20 @@ void QJSEngine::collectGarbage()
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
QV4::Scope scope(d->m_v4Engine);
QV4::ExecutionContext *ctx = d->m_v4Engine->current;
QV4::ScopedValue result(scope);
try {
QV4::Script script(ctx, program, fileName, lineNumber);
script.strictMode = ctx->strictMode;
script.inheritContext = true;
script.parse();
QV4::Value result = script.run();
return new QJSValuePrivate(d->m_v4Engine, result);
result = script.run();
} catch (QV4::Exception& ex) {
ex.accept(ctx);
return new QJSValuePrivate(d->m_v4Engine, ex.value());
result = ex.value();
}
return new QJSValuePrivate(d->m_v4Engine, result);
}
/*!

View File

@ -807,13 +807,14 @@ QJSValue QJSValue::property(const QString& name) const
s->makeIdentifier();
QV4::ExecutionContext *ctx = engine->current;
QV4::ScopedValue result(scope);
try {
QV4::ScopedValue v(scope, o->get(s));
return new QJSValuePrivate(engine, v);
result = o->get(s);
} catch (QV4::Exception &e) {
e.accept(ctx);
return new QJSValuePrivate(engine, e.value());
result = e.value();
}
return new QJSValuePrivate(engine, result);
}
/*!
@ -840,13 +841,14 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
return QJSValue();
QV4::ExecutionContext *ctx = engine->current;
QV4::ScopedValue result(scope);
try {
QV4::ScopedValue v(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex));
return new QJSValuePrivate(engine, v);
result = arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex);
} catch (QV4::Exception &e) {
e.accept(ctx);
return new QJSValuePrivate(engine, e.value());
result = e.value();
}
return new QJSValuePrivate(engine, result);
}
/*!

View File

@ -87,7 +87,8 @@ void Exception::throwException(ExecutionContext *context, const Value &value)
}
Exception::Exception(ExecutionContext *throwingContext, const Value &exceptionValue)
: exception(exceptionValue)
: e(throwingContext->engine)
, exception(exceptionValue)
{
this->throwingContext = throwingContext->engine->current;
accepted = false;

View File

@ -58,15 +58,17 @@ struct Q_QML_EXPORT Exception {
void partiallyUnwindContext(ExecutionContext *catchingContext);
Value value() const { return exception; }
ReturnedValue value() const { return exception.value().asReturnedValue(); }
ExecutionEngine::StackTrace stackTrace() const { return m_stackTrace; }
ExecutionEngine *engine() const { return e; }
private:
void *operator new(size_t, void *p) { return p; }
explicit Exception(ExecutionContext *throwingContext, const Value &exceptionValue);
ExecutionEngine *e;
ExecutionContext *throwingContext;
bool accepted;
PersistentValue exception;

View File

@ -149,7 +149,8 @@ void QV4Include::finished()
QV4::Script script(v4, m_qmlglobal.value().asObject(), code, m_url.toString());
QV4::ExecutionContext *ctx = v4->current;
QV4::Object *o = m_resultObject.value().asObject();
QV4::Scope scope(v4);
QV4::Scoped<QV4::Object> o(scope, m_resultObject.value());
try {
script.parse();
script.run();
@ -157,7 +158,8 @@ void QV4Include::finished()
} catch (QV4::Exception &e) {
e.accept(ctx);
o->put(v4->newString("status"), QV4::Value::fromInt32(Exception));
o->put(v4->newString("exception"), e.value());
QV4::ScopedValue ex(scope, e.value());
o->put(v4->newString("exception"), ex);
}
} else {
m_resultObject.value().asObject()->put(v4->newString("status"), QV4::Value::fromInt32(NetworkError));
@ -178,6 +180,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx)
return QV4::Encode::undefined();
QV4::ExecutionEngine *v4 = ctx->engine;
QV4::Scope scope(v4);
QV8Engine *engine = v4->v8Engine;
QQmlContextData *context = QV4::QmlContextWrapper::callingContext(v4);
@ -192,7 +195,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx)
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
QV4::Value result = QV4::Value::undefinedValue();
QV4::ScopedValue result(scope);
if (localFile.isEmpty()) {
@ -210,8 +213,8 @@ QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx)
QString code = QString::fromUtf8(data);
QQmlScript::Parser::extractPragmas(code);
QV4::Object *qmlglobal = v4->qmlContextObject();
QV4::Script script(v4, qmlglobal, code, url.toString());
QV4::Scoped<QV4::Object> qmlglobal(scope, QV4::Value::fromObject(v4->qmlContextObject()));
QV4::Script script(v4, qmlglobal.getPointer(), code, url.toString());
QV4::ExecutionContext *ctx = v4->current;
try {
@ -221,7 +224,8 @@ QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx)
} catch (QV4::Exception &e) {
e.accept(ctx);
result = resultValue(v4, Exception);
result.asObject()->put(v4->newString("exception"), e.value());
QV4::ScopedValue ex(scope, e.value());
result->asObject()->put(v4->newString("exception"), ex);
}
} else {
result = resultValue(v4, NetworkError);

View File

@ -204,12 +204,12 @@ void Script::parse()
v4->current->throwError(QV4::Value::fromObject(v4->newSyntaxErrorObject("Syntax error")));
}
Value Script::run()
ReturnedValue Script::run()
{
if (!parsed)
parse();
if (!vmFunction)
return Value::undefinedValue();
return Encode::undefined();
QV4::ExecutionEngine *engine = scope->engine;
QV4::Scope valueScope(engine);
@ -246,13 +246,13 @@ Value Script::run()
scope->compiledFunction = oldCompiledFunction;
scope->runtimeStrings = oldRuntimeStrings;
return result;
return result.asReturnedValue();
} else {
FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject());
ScopedCallData callData(valueScope, 0);
callData->thisObject = Value::undefinedValue();
return Value::fromReturnedValue(f->call(callData));
return f->call(callData);
}
}
@ -271,17 +271,17 @@ Value Script::qmlBinding()
return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject()));
}
QV4::Value Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)
QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)
{
QV4::Scope scope(engine);
QV4::Script qmlScript(engine, scopeObject, script, QString());
QV4::ExecutionContext *ctx = engine->current;
QV4::Value result = QV4::Value::undefinedValue();
try {
qmlScript.parse();
result = qmlScript.run();
return qmlScript.run();
} catch (QV4::Exception &e) {
e.accept(ctx);
}
return result;
return Encode::undefined();
}

View File

@ -74,13 +74,13 @@ struct Q_QML_EXPORT Script {
bool parseAsBinding;
void parse();
Value run();
ReturnedValue run();
Value qmlBinding();
Function *function();
static Value evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject);
static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject);
};
}

View File

@ -375,7 +375,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code,
context->interpreterInstructionPointer = &code;
} catch (QV4::Exception &ex) {
ex.accept(context);
VALUE(instr.exceptionVar) = ex.value();
STOREVALUE(instr.exceptionVar, ex.value());
try {
QV4::ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(runtimeStrings[instr.exceptionVarName], VALUEPTR(instr.exceptionVar), context);
const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset;
@ -385,7 +385,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code,
context = __qmljs_builtin_pop_scope(catchContext);
} catch (QV4::Exception &ex) {
ex.accept(context);
VALUE(instr.exceptionVar) = ex.value();
STOREVALUE(instr.exceptionVar, ex.value());
const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset;
run(context, catchCode, stack, stackSize);
code = catchCode;

View File

@ -1226,12 +1226,12 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (!valuemap.isEmpty()) {
QQmlComponentExtension *e = componentExtension(v8engine);
QV4::Value f = QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject());
QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject()));
QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4engine->globalObject);
callData->args[0] = object;
callData->args[1] = valuemap;
f.asFunctionObject()->call(callData);
f->call(callData);
}
d->completeCreate();
@ -1374,12 +1374,13 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu
if (!valuemap.isEmpty()) {
QQmlComponentExtension *e = componentExtension(v8engine);
QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject());
QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(QV8Engine::getV4(v8engine),
QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()));
QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4engine->globalObject);
callData->args[0] = object;
callData->args[1] = valuemap;
f.asFunctionObject()->call(callData);
f->call(callData);
}
}
@ -1474,12 +1475,12 @@ void QmlIncubatorObject::setInitialState(QObject *o)
QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8);
QV4::Scope scope(v4);
QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject());
QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()));
QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4->globalObject);
callData->args[0] = QV4::QObjectWrapper::wrap(v4, o);
callData->args[1] = valuemap;
f.asFunctionObject()->call(callData);
f->call(callData);
}
}

View File

@ -86,7 +86,7 @@ void QQmlDelayedError::setErrorObject(QObject *object)
void QQmlDelayedError::setError(const QV4::Exception &e)
{
m_error.setDescription(e.value().toQStringNoThrow());
m_error.setDescription(QV4::Value::fromReturnedValue(e.value()).toQStringNoThrow());
QV4::ExecutionEngine::StackTrace trace = e.stackTrace();
if (!trace.isEmpty()) {
QV4::ExecutionEngine::StackFrame frame = trace.first();
@ -186,13 +186,15 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
delayedError()->clearError();
} catch (QV4::Exception &e) {
e.accept(ctx);
QV4::ScopedValue ex(scope, e.value());
if (isUndefined)
*isUndefined = true;
if (!watcher.wasDeleted()) {
if (!e.value().isEmpty()) {
if (!ex->isEmpty()) {
delayedError()->setError(e);
} else {
if (hasDelayedError()) delayedError()->clearError();
if (hasDelayedError())
delayedError()->clearError();
}
}
}
@ -303,6 +305,7 @@ QQmlDelayedError *QQmlJavaScriptExpression::delayedError()
void QQmlJavaScriptExpression::exceptionToError(const QV4::Exception &e, QQmlError &error)
{
QV4::Scope scope(e.engine());
QV4::ExecutionEngine::StackTrace trace = e.stackTrace();
if (!trace.isEmpty()) {
QV4::ExecutionEngine::StackFrame frame = trace.first();
@ -310,15 +313,18 @@ void QQmlJavaScriptExpression::exceptionToError(const QV4::Exception &e, QQmlErr
error.setLine(frame.line);
error.setColumn(frame.column);
}
QV4::ErrorObject *errorObj = e.value().asErrorObject();
if (errorObj && errorObj->asSyntaxError())
error.setDescription(QV4::Value::fromReturnedValue(errorObj->get(errorObj->engine()->newString("message"))).toQStringNoThrow());
else
error.setDescription(e.value().toQStringNoThrow());
QV4::Scoped<QV4::ErrorObject> errorObj(scope, e.value());
if (!!errorObj && errorObj->asSyntaxError()) {
QV4::ScopedValue v(scope, errorObj->get(errorObj->engine()->newString("message")));
error.setDescription(v->toQStringNoThrow());
} else {
QV4::ScopedValue v(scope, e.value());
error.setDescription(v->toQStringNoThrow());
}
}
QV4::PersistentValue
QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObject,
const QString &code, const QString &filename, quint16 line,
QV4::PersistentValue *qmlscope)
{
@ -327,10 +333,11 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::ExecutionContext *ctx = v4->current;
QV4::Scope scope(v4);
QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scope);
QV4::Script script(v4, scopeObject.asObject(), code, filename, line);
QV4::Value result;
QV4::Scoped<QV4::Object> qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scopeObject));
QV4::Script script(v4, qmlScopeObject.getPointer(), code, filename, line);
QV4::ScopedValue result(scope);
try {
script.parse();
result = script.run();
@ -344,13 +351,13 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setLine(line);
if (error.url().isEmpty())
error.setUrl(QUrl::fromLocalFile(filename));
error.setObject(scope);
error.setObject(scopeObject);
ep->warning(error);
return QV4::PersistentValue();
}
if (qmlscope)
*qmlscope = scopeObject;
return result;
*qmlscope = qmlScopeObject.asValue();
return result.asReturnedValue();
}
QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *scope,

View File

@ -404,6 +404,7 @@ QVariant QV8Engine::toBasicVariant(const QV4::Value &value)
void QV8Engine::initializeGlobal()
{
QV4::Scope scope(m_v4Engine);
QV4::GlobalExtensions::init(m_engine, m_v4Engine->globalObject);
QQmlLocale::registerStringLocaleCompare(m_v4Engine);
@ -440,9 +441,9 @@ void QV8Engine::initializeGlobal()
" }"\
"})"
QV4::Value result = QV4::Script::evaluate(m_v4Engine, QString::fromUtf8(FREEZE_SOURCE), 0);
Q_ASSERT(result.asFunctionObject());
m_freezeObject = result;
QV4::Scoped<QV4::FunctionObject> result(scope, QV4::Script::evaluate(m_v4Engine, QString::fromUtf8(FREEZE_SOURCE), 0));
Q_ASSERT(!!result);
m_freezeObject = result.asValue();
#undef FREEZE_SOURCE
}
}

View File

@ -231,7 +231,7 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
QV4::Scope scope(m_v4Engine);
onmessage = QV4::Script(m_v4Engine->rootContext, CALL_ONMESSAGE_SCRIPT).run();
QV4::Script createsendscript(m_v4Engine->rootContext, SEND_MESSAGE_CREATE_SCRIPT);
QV4::FunctionObject *createsendconstructor = createsendscript.run().asFunctionObject();
QV4::Scoped<QV4::FunctionObject> createsendconstructor(scope, createsendscript.run());
QV4::Value function = QV4::Value::fromObject(m_v4Engine->newBuiltinFunction(m_v4Engine->rootContext, m_v4Engine->newString(QStringLiteral("sendMessage")),
QQuickWorkerScriptEnginePrivate::method_sendMessage));

View File

@ -117,9 +117,11 @@ DEFINE_MANAGED_VTABLE(GC);
static void showException(QV4::ExecutionContext *ctx, const QV4::Exception &exception)
{
QV4::ErrorObject *e = exception.value().asErrorObject();
QV4::Scope scope(ctx);
QV4::ScopedValue ex(scope, exception.value());
QV4::ErrorObject *e = ex->asErrorObject();
if (!e) {
std::cerr << "Uncaught exception: " << qPrintable(exception.value().toString(ctx)->toQString()) << std::endl;
std::cerr << "Uncaught exception: " << qPrintable(ex->toString(ctx)->toQString()) << std::endl;
} else {
std::cerr << "Uncaught exception: " << qPrintable(QV4::Value::fromReturnedValue(e->get(ctx->engine->newString(QStringLiteral("message")), 0)).toString(ctx)->toQString()) << std::endl;
}
@ -187,6 +189,7 @@ int main(int argc, char *argv[])
QV4::ExecutionEngine vm(iSelFactory);
QV4::ExecutionContext *ctx = vm.rootContext;
QV4::Scope scope(ctx);
QV4::Object *globalObject = vm.globalObject;
QV4::Object *print = new (ctx->engine->memoryManager) builtins::Print(ctx);
@ -204,10 +207,10 @@ int main(int argc, char *argv[])
QV4::Script script(ctx, code, fn);
script.parseAsBinding = runAsQml;
script.parse();
QV4::Value result = script.run();
if (!result.isUndefined()) {
QV4::ScopedValue result(scope, script.run());
if (!result->isUndefined()) {
if (! qgetenv("SHOW_EXIT_VALUE").isEmpty())
std::cout << "exit value: " << qPrintable(result.toString(ctx)->toQString()) << std::endl;
std::cout << "exit value: " << qPrintable(result->toString(ctx)->toQString()) << std::endl;
}
} catch (QV4::Exception& ex) {
ex.accept(ctx);