diff options
author | Lars Knoll <[email protected]> | 2017-01-05 15:14:37 +0100 |
---|---|---|
committer | Lars Knoll <[email protected]> | 2017-01-25 08:31:21 +0000 |
commit | 119e2edb3ea52a6b3b9da6183dc0fcf350ba8431 (patch) | |
tree | 40de3542e30d2de31f336409a9030d76a5d34cc4 | |
parent | afc29a54791e70264f7c175b2da0a234f791f749 (diff) |
Convert more builtin functions
Change-Id: I2dc8797e2240fcfc4176cb08b982e3e98b879646
Reviewed-by: Simon Hausmann <[email protected]>
-rw-r--r-- | src/qml/jsruntime/qv4errorobject.cpp | 25 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4errorobject_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 75 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4global_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4globalobject.cpp | 146 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4globalobject_p.h | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4include.cpp | 19 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4include_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jsonobject.cpp | 23 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jsonobject_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 94 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject_p.h | 18 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 4 |
14 files changed, 206 insertions, 237 deletions
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index 597ded6ae1..f290bc5136 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -153,12 +153,11 @@ const char *ErrorObject::className(Heap::ErrorObject::ErrorType t) Q_UNREACHABLE(); } -ReturnedValue ErrorObject::method_get_stack(CallContext *ctx) +void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped<ErrorObject> This(scope, ctx->thisObject()); + Scoped<ErrorObject> This(scope, callData->thisObject); if (!This) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (!This->d()->stack) { QString trace; for (int i = 0; i < This->d()->stackTrace->count(); ++i) { @@ -169,9 +168,9 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx) if (frame.line >= 0) trace += QLatin1Char(':') + QString::number(frame.line); } - This->d()->stack = ctx->d()->engine->newString(trace); + This->d()->stack = scope.engine->newString(trace); } - return This->d()->stack->asReturnedValue(); + scope.result = This->d()->stack; } void ErrorObject::markObjects(Heap::Base *that, ExecutionEngine *e) @@ -335,22 +334,20 @@ void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, He obj->defineDefaultProperty(engine->id_toString(), method_toString, 0); } -ReturnedValue ErrorPrototype::method_toString(CallContext *ctx) +void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - - Object *o = ctx->thisObject().as<Object>(); + Object *o = callData->thisObject.as<Object>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - ScopedValue name(scope, o->get(ctx->d()->engine->id_name())); + ScopedValue name(scope, o->get(scope.engine->id_name())); QString qname; if (name->isUndefined()) qname = QStringLiteral("Error"); else qname = name->toQString(); - ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("message"))); + ScopedString s(scope, scope.engine->newString(QStringLiteral("message"))); ScopedValue message(scope, o->get(s)); QString qmessage; if (!message->isUndefined()) @@ -365,5 +362,5 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx) str = qname + QLatin1String(": ") + qmessage; } - return ctx->d()->engine->newString(str)->asReturnedValue(); + scope.result = scope.engine->newString(str)->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index 2b3ab25e2d..9ba9f05234 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -172,7 +172,7 @@ struct ErrorObject: Object { static const char *className(Heap::ErrorObject::ErrorType t); - static ReturnedValue method_get_stack(CallContext *ctx); + static void method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData); static void markObjects(Heap::Base *that, ExecutionEngine *e); }; @@ -282,7 +282,7 @@ struct ErrorPrototype : ErrorObject void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, this, Heap::ErrorObject::Error); } static void init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t); - static ReturnedValue method_toString(CallContext *ctx); + static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); }; struct EvalErrorPrototype : ErrorObject diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 1458c77d88..b2d89220ea 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -270,23 +270,22 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor) } -ReturnedValue FunctionPrototype::method_toString(CallContext *ctx) +void FunctionPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *fun = ctx->thisObject().as<FunctionObject>(); + FunctionObject *fun = callData->thisObject.as<FunctionObject>(); if (!fun) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return ctx->d()->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue(); + scope.result = scope.engine->newString(QStringLiteral("function() { [code] }")); } -ReturnedValue FunctionPrototype::method_apply(CallContext *ctx) +void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *o = ctx->thisObject().as<FunctionObject>(); + FunctionObject *o = callData->thisObject.as<FunctionObject>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - Scope scope(ctx); - ScopedValue arg(scope, ctx->argument(1)); + ScopedValue arg(scope, callData->argument(1)); ScopedObject arr(scope, arg); @@ -294,75 +293,71 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx) if (!arr) { len = 0; if (!arg->isNullOrUndefined()) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); } else { len = arr->getLength(); } - ScopedCallData callData(scope, len); + ScopedCallData cData(scope, len); if (len) { if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) { QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>(); int l = qMin(len, (uint)a->d()->context->callData->argc); - memcpy(callData->args, a->d()->context->callData->args, l*sizeof(Value)); + memcpy(cData->args, a->d()->context->callData->args, l*sizeof(Value)); for (quint32 i = l; i < len; ++i) - callData->args[i] = Primitive::undefinedValue(); + cData->args[i] = Primitive::undefinedValue(); } else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) { auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData()); uint alen = sad ? sad->len : 0; if (alen > len) alen = len; for (uint i = 0; i < alen; ++i) - callData->args[i] = sad->data(i); + cData->args[i] = sad->data(i); for (quint32 i = alen; i < len; ++i) - callData->args[i] = Primitive::undefinedValue(); + cData->args[i] = Primitive::undefinedValue(); } else { for (quint32 i = 0; i < len; ++i) - callData->args[i] = arr->getIndexed(i); + cData->args[i] = arr->getIndexed(i); } } - callData->thisObject = ctx->argument(0); - o->call(scope, callData); - return scope.result.asReturnedValue(); + cData->thisObject = callData->argument(0); + o->call(scope, cData); } -ReturnedValue FunctionPrototype::method_call(CallContext *ctx) +void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *o = ctx->thisObject().as<FunctionObject>(); + FunctionObject *o = callData->thisObject.as<FunctionObject>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - Scope scope(ctx); - ScopedCallData callData(scope, ctx->argc() ? ctx->argc() - 1 : 0); - if (ctx->argc()) { - for (int i = 1; i < ctx->argc(); ++i) - callData->args[i - 1] = ctx->args()[i]; + ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0); + if (callData->argc) { + for (int i = 1; i < callData->argc; ++i) + cData->args[i - 1] = callData->args[i]; } - callData->thisObject = ctx->argument(0); + cData->thisObject = callData->argument(0); - o->call(scope, callData); - return scope.result.asReturnedValue(); + o->call(scope, cData); } -ReturnedValue FunctionPrototype::method_bind(CallContext *ctx) +void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *target = ctx->thisObject().as<FunctionObject>(); + FunctionObject *target = callData->thisObject.as<FunctionObject>(); if (!target) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - Scope scope(ctx); - ScopedValue boundThis(scope, ctx->argument(0)); + ScopedValue boundThis(scope, callData->argument(0)); Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0); - if (ctx->argc() > 1) { - boundArgs = MemberData::allocate(scope.engine, ctx->argc() - 1); - boundArgs->d()->size = ctx->argc() - 1; - memcpy(boundArgs->data(), ctx->args() + 1, (ctx->argc() - 1)*sizeof(Value)); + if (callData->argc > 1) { + boundArgs = MemberData::allocate(scope.engine, callData->argc - 1); + boundArgs->d()->size = callData->argc - 1; + memcpy(boundArgs->data(), callData->args + 1, (callData->argc - 1)*sizeof(Value)); } ExecutionContext *global = scope.engine->rootContext(); - return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue(); + scope.result = BoundFunction::create(global, target, boundThis, boundArgs); } DEFINE_OBJECT_VTABLE(ScriptFunction); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 31b05666a7..45d7485f1b 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -184,10 +184,10 @@ struct FunctionPrototype: FunctionObject void init(ExecutionEngine *engine, Object *ctor); - static ReturnedValue method_toString(CallContext *ctx); - static ReturnedValue method_apply(CallContext *ctx); - static ReturnedValue method_call(CallContext *ctx); - static ReturnedValue method_bind(CallContext *ctx); + static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_apply(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_call(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_bind(const BuiltinFunction *, Scope &scope, CallData *callData); }; struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject { diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 1dbc538be2..66861bf697 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -208,6 +208,7 @@ struct StringObject; struct ArrayObject; struct DateObject; struct FunctionObject; +struct BuiltinFunction; struct ErrorObject; struct ArgumentsObject; struct Managed; diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index af92ce1ad8..1bc91f832b 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -423,18 +423,15 @@ static inline int toInt(const QChar &qc, int R) } // parseInt [15.1.2.2] -ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx) +void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - ScopedValue inputString(scope, ctx->argument(0)); - ScopedValue radix(scope, ctx->argument(1)); + ScopedValue inputString(scope, callData->argument(0)); + ScopedValue radix(scope, callData->argument(1)); int R = radix->isUndefined() ? 0 : radix->toInt32(); // [15.1.2.2] step by step: QString trimmed = inputString->toQString().trimmed(); // 1 + 2 - - if (ctx->d()->engine->hasException) - return Encode::undefined(); + CHECK_EXCEPTION(); const QChar *pos = trimmed.constData(); const QChar *end = pos + trimmed.length(); @@ -449,7 +446,7 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx) bool stripPrefix = true; // 7 if (R) { // 8 if (R < 2 || R > 36) - return Encode(std::numeric_limits<double>::quiet_NaN()); // 8a + RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 8a if (R != 16) stripPrefix = false; // 8b } else { // 9 @@ -466,13 +463,13 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx) // 11: Z is progressively built below // 13: this is handled by the toInt function if (pos == end) // 12 - return Encode(std::numeric_limits<double>::quiet_NaN()); + RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); bool overflow = false; qint64 v_overflow = 0; unsigned overflow_digit_count = 0; int d = toInt(*pos++, R); if (d == -1) - return Encode(std::numeric_limits<double>::quiet_NaN()); + RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); qint64 v = d; while (pos != end) { d = toInt(*pos++, R); @@ -499,155 +496,148 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx) if (overflow) { double result = (double) v_overflow * pow(static_cast<double>(R), static_cast<double>(overflow_digit_count)); result += v; - return Encode(sign * result); + RETURN_RESULT(Encode(sign * result)); } else { - return Encode(sign * (double) v); // 15 + RETURN_RESULT(Encode(sign * (double) v)); // 15 } } // parseFloat [15.1.2.3] -ReturnedValue GlobalFunctions::method_parseFloat(CallContext *ctx) +void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - // [15.1.2.3] step by step: - ScopedString inputString(scope, ctx->argument(0), ScopedString::Convert); - if (scope.engine->hasException) - return Encode::undefined(); + ScopedString inputString(scope, callData->argument(0), ScopedString::Convert); + CHECK_EXCEPTION(); QString trimmed = inputString->toQString().trimmed(); // 2 // 4: if (trimmed.startsWith(QLatin1String("Infinity")) || trimmed.startsWith(QLatin1String("+Infinity"))) - return Encode(Q_INFINITY); + RETURN_RESULT(Encode(Q_INFINITY)); if (trimmed.startsWith(QLatin1String("-Infinity"))) - return Encode(-Q_INFINITY); + RETURN_RESULT(Encode(-Q_INFINITY)); QByteArray ba = trimmed.toLatin1(); bool ok; const char *begin = ba.constData(); const char *end = 0; double d = qstrtod(begin, &end, &ok); if (end - begin == 0) - return Encode(std::numeric_limits<double>::quiet_NaN()); // 3 + RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 3 else - return Encode(d); + RETURN_RESULT(Encode(d)); } /// isNaN [15.1.2.4] -ReturnedValue GlobalFunctions::method_isNaN(CallContext *ctx) +void GlobalFunctions::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (!ctx->argc()) + if (!callData->argc) // undefined gets converted to NaN - return Encode(true); + RETURN_RESULT(Encode(true)); - if (ctx->args()[0].integerCompatible()) - return Encode(false); + if (callData->args[0].integerCompatible()) + RETURN_RESULT(Encode(false)); - double d = ctx->args()[0].toNumber(); - return Encode((bool)std::isnan(d)); + double d = callData->args[0].toNumber(); + RETURN_RESULT(Encode((bool)std::isnan(d))); } /// isFinite [15.1.2.5] -ReturnedValue GlobalFunctions::method_isFinite(CallContext *ctx) +void GlobalFunctions::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (!ctx->argc()) + if (!callData->argc) // undefined gets converted to NaN - return Encode(false); + RETURN_RESULT(Encode(false)); - if (ctx->args()[0].integerCompatible()) - return Encode(true); + if (callData->args[0].integerCompatible()) + RETURN_RESULT(Encode(true)); - double d = ctx->args()[0].toNumber(); - return Encode((bool)std::isfinite(d)); + double d = callData->args[0].toNumber(); + RETURN_RESULT(Encode((bool)std::isfinite(d))); } /// decodeURI [15.1.3.1] -ReturnedValue GlobalFunctions::method_decodeURI(CallContext *context) +void GlobalFunctions::method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (context->argc() == 0) - return Encode::undefined(); + if (callData->argc == 0) + RETURN_UNDEFINED(); - QString uriString = context->args()[0].toQString(); + QString uriString = callData->args[0].toQString(); bool ok; QString out = decode(uriString, DecodeNonReserved, &ok); if (!ok) { - Scope scope(context); - ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence"))); - return context->engine()->throwURIError(s); + ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); + RETURN_RESULT(scope.engine->throwURIError(s)); } - return context->d()->engine->newString(out)->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(out)); } /// decodeURIComponent [15.1.3.2] -ReturnedValue GlobalFunctions::method_decodeURIComponent(CallContext *context) +void GlobalFunctions::method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (context->argc() == 0) - return Encode::undefined(); + if (callData->argc == 0) + RETURN_UNDEFINED(); - QString uriString = context->args()[0].toQString(); + QString uriString = callData->args[0].toQString(); bool ok; QString out = decode(uriString, DecodeAll, &ok); if (!ok) { - Scope scope(context); - ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence"))); - return context->engine()->throwURIError(s); + ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); + RETURN_RESULT(scope.engine->throwURIError(s)); } - return context->d()->engine->newString(out)->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(out)); } /// encodeURI [15.1.3.3] -ReturnedValue GlobalFunctions::method_encodeURI(CallContext *context) +void GlobalFunctions::method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (context->argc() == 0) - return Encode::undefined(); + if (callData->argc == 0) + RETURN_UNDEFINED(); - QString uriString = context->args()[0].toQString(); + QString uriString = callData->args[0].toQString(); bool ok; QString out = encode(uriString, uriUnescapedReserved, &ok); if (!ok) { - Scope scope(context); - ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence"))); - return context->engine()->throwURIError(s); + ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); + RETURN_RESULT(scope.engine->throwURIError(s)); } - return context->d()->engine->newString(out)->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(out)); } /// encodeURIComponent [15.1.3.4] -ReturnedValue GlobalFunctions::method_encodeURIComponent(CallContext *context) +void GlobalFunctions::method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (context->argc() == 0) - return Encode::undefined(); + if (callData->argc == 0) + RETURN_UNDEFINED(); - QString uriString = context->args()[0].toQString(); + QString uriString = callData->args[0].toQString(); bool ok; QString out = encode(uriString, uriUnescaped, &ok); if (!ok) { - Scope scope(context); - ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence"))); - return context->engine()->throwURIError(s); + ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); + RETURN_RESULT(scope.engine->throwURIError(s)); } - return context->d()->engine->newString(out)->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(out)); } -ReturnedValue GlobalFunctions::method_escape(CallContext *context) +void GlobalFunctions::method_escape(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (!context->argc()) - return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue(); + if (!callData->argc) + RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined"))); - QString str = context->args()[0].toQString(); - return context->d()->engine->newString(escape(str))->asReturnedValue(); + QString str = callData->args[0].toQString(); + RETURN_RESULT(scope.engine->newString(escape(str))); } -ReturnedValue GlobalFunctions::method_unescape(CallContext *context) +void GlobalFunctions::method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (!context->argc()) - return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue(); + if (!callData->argc) + RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined"))); - QString str = context->args()[0].toQString(); - return context->d()->engine->newString(unescape(str))->asReturnedValue(); + QString str = callData->args[0].toQString(); + RETURN_RESULT(scope.engine->newString(unescape(str))); } diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h index e8b3a92d34..273f1ba7ea 100644 --- a/src/qml/jsruntime/qv4globalobject_p.h +++ b/src/qml/jsruntime/qv4globalobject_p.h @@ -76,16 +76,16 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject struct GlobalFunctions { - static ReturnedValue method_parseInt(CallContext *context); - static ReturnedValue method_parseFloat(CallContext *context); - static ReturnedValue method_isNaN(CallContext *context); - static ReturnedValue method_isFinite(CallContext *ctx); - static ReturnedValue method_decodeURI(CallContext *context); - static ReturnedValue method_decodeURIComponent(CallContext *context); - static ReturnedValue method_encodeURI(CallContext *context); - static ReturnedValue method_encodeURIComponent(CallContext *context); - static ReturnedValue method_escape(CallContext *context); - static ReturnedValue method_unescape(CallContext *context); + static void method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_escape(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData); }; } diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 1d393cf0aa..f033eb2d2d 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -195,23 +195,22 @@ void QV4Include::finished() /* Documented in qv8engine.cpp */ -QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx) +void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - if (!ctx->argc()) - return QV4::Encode::undefined(); + if (!callData->argc) + RETURN_UNDEFINED(); - QV4::Scope scope(ctx->engine()); QQmlContextData *context = scope.engine->callingQmlContext(); if (!context || !context->isJSContext) - V4THROW_ERROR("Qt.include(): Can only be called from JavaScript files"); + RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files"))); QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue()); - if (ctx->argc() >= 2 && ctx->args()[1].as<QV4::FunctionObject>()) - callbackFunction = ctx->args()[1]; + if (callData->argc >= 2 && callData->args[1].as<QV4::FunctionObject>()) + callbackFunction = callData->args[1]; #if QT_CONFIG(qml_network) - QUrl url(scope.engine->resolvedUrl(ctx->args()[0].toQStringNoThrow())); + QUrl url(scope.engine->resolvedUrl(callData->args[0].toQStringNoThrow())); if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor()) url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile); @@ -261,12 +260,12 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx) callback(callbackFunction, result); } - return result->asReturnedValue(); + scope.result = result; #else QV4::ScopedValue result(scope); result = resultValue(scope.engine, NetworkError); callback(callbackFunction, result); - return result->asReturnedValue(); + scope.result = result; #endif } diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h index 4c601a5e7b..5908d6bfde 100644 --- a/src/qml/jsruntime/qv4include_p.h +++ b/src/qml/jsruntime/qv4include_p.h @@ -77,7 +77,7 @@ public: Exception = 3 }; - static QV4::ReturnedValue method_include(QV4::CallContext *ctx); + static void method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); private Q_SLOTS: void finished(); diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index d79e6242ba..1d571f53f3 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -883,10 +883,9 @@ void Heap::JsonObject::init() } -ReturnedValue JsonObject::method_parse(CallContext *ctx) +void JsonObject::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - ScopedValue v(scope, ctx->argument(0)); + ScopedValue v(scope, callData->argument(0)); QString jtext = v->toQString(); DEBUG << "parsing source = " << jtext; @@ -895,19 +894,17 @@ ReturnedValue JsonObject::method_parse(CallContext *ctx) ScopedValue result(scope, parser.parse(&error)); if (error.error != QJsonParseError::NoError) { DEBUG << "parse error" << error.errorString(); - return ctx->engine()->throwSyntaxError(QStringLiteral("JSON.parse: Parse error")); + RETURN_RESULT(scope.engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"))); } - return result->asReturnedValue(); + scope.result = result; } -ReturnedValue JsonObject::method_stringify(CallContext *ctx) +void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Stringify stringify(scope.engine); - ScopedObject o(scope, ctx->argument(1)); + ScopedObject o(scope, callData->argument(1)); if (o) { stringify.replacerFunction = o->as<FunctionObject>(); if (o->isArrayObject()) { @@ -932,7 +929,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx) } } - ScopedValue s(scope, ctx->argument(2)); + ScopedValue s(scope, callData->argument(2)); if (NumberObject *n = s->as<NumberObject>()) s = Encode(n->value()); else if (StringObject *so = s->as<StringObject>()) @@ -945,11 +942,11 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx) } - ScopedValue arg0(scope, ctx->argument(0)); + ScopedValue arg0(scope, callData->argument(0)); QString result = stringify.Str(QString(), arg0); if (result.isEmpty() || scope.engine->hasException) - return Encode::undefined(); - return ctx->d()->engine->newString(result)->asReturnedValue(); + RETURN_UNDEFINED(); + scope.result = scope.engine->newString(result); } diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h index 43248a214d..a73ce1c74e 100644 --- a/src/qml/jsruntime/qv4jsonobject_p.h +++ b/src/qml/jsruntime/qv4jsonobject_p.h @@ -88,8 +88,8 @@ private: typedef QSet<ObjectItem> V4ObjectSet; public: - static ReturnedValue method_parse(CallContext *ctx); - static ReturnedValue method_stringify(CallContext *ctx); + static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData); static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value); static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object); diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 41d8010fef..40682aaa4b 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -349,34 +349,33 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor) defineDefaultProperty(QStringLiteral("compile"), method_compile, 2); } -ReturnedValue RegExpPrototype::method_exec(CallContext *ctx) +void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>()); + Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - ScopedValue arg(scope, ctx->argument(0)); + ScopedValue arg(scope, callData->argument(0)); ScopedString str(scope, arg->toString(scope.engine)); if (scope.hasException()) - return Encode::undefined(); + RETURN_UNDEFINED(); QString s = str->toQString(); int offset = r->global() ? r->lastIndexProperty()->toInt32() : 0; if (offset < 0 || offset > s.length()) { *r->lastIndexProperty() = Primitive::fromInt32(0); - return Encode::null(); + RETURN_RESULT(Encode::null()); } uint* matchOffsets = (uint*)alloca(r->value()->captureCount() * 2 * sizeof(uint)); const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets); - Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor()); + Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor()); regExpCtor->d()->clearLastMatch(); if (result == -1) { *r->lastIndexProperty() = Primitive::fromInt32(0); - return Encode::null(); + RETURN_RESULT(Encode::null()); } // fill in result data @@ -387,7 +386,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx) for (int i = 0; i < len; ++i) { int start = matchOffsets[i * 2]; int end = matchOffsets[i * 2 + 1]; - v = (start != -1) ? ctx->d()->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined(); + v = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined(); array->arrayPut(i, v); } array->setArrayLengthUnchecked(len); @@ -403,84 +402,75 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx) if (r->global()) *r->lastIndexProperty() = Primitive::fromInt32(matchOffsets[1]); - return array.asReturnedValue(); + scope.result = array; } -ReturnedValue RegExpPrototype::method_test(CallContext *ctx) +void RegExpPrototype::method_test(const BuiltinFunction *b, Scope &scope, CallData *callData) { - Scope scope(ctx); - ScopedValue r(scope, method_exec(ctx)); - return Encode(!r->isNull()); + method_exec(b, scope, callData); + scope.result = Encode(!scope.result.isNull()); } -ReturnedValue RegExpPrototype::method_toString(CallContext *ctx) +void RegExpPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>()); + Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return ctx->d()->engine->newString(r->toString())->asReturnedValue(); + scope.result = scope.engine->newString(r->toString()); } -ReturnedValue RegExpPrototype::method_compile(CallContext *ctx) +void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>()); + Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - ScopedCallData callData(scope, ctx->argc()); - memcpy(callData->args, ctx->args(), ctx->argc()*sizeof(Value)); + ScopedCallData cData(scope, callData->argc); + memcpy(cData->args, callData->args, callData->argc*sizeof(Value)); - ctx->d()->engine->regExpCtor()->as<FunctionObject>()->construct(scope, callData); + scope.engine->regExpCtor()->as<FunctionObject>()->construct(scope, cData); Scoped<RegExpObject> re(scope, scope.result.asReturnedValue()); r->d()->value = re->value(); r->d()->global = re->global(); - return Encode::undefined(); + RETURN_UNDEFINED(); } template <int index> -ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx) +void RegExpPrototype::method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *) { - Scope scope(ctx); - ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch()); - ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined()); - if (result->isUndefined()) - return ctx->d()->engine->newString()->asReturnedValue(); - return result->asReturnedValue(); + ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch()); + scope.result = lastMatch ? lastMatch->getIndexed(index) : Encode::undefined(); + if (scope.result.isUndefined()) + scope.result = scope.engine->newString(); } -ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx) +void RegExpPrototype::method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *) { - Scope scope(ctx); - ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch()); - ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined()); - if (result->isUndefined()) - return ctx->d()->engine->newString()->asReturnedValue(); - return result->asReturnedValue(); + ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch()); + scope.result = lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined(); + if (scope.result.isUndefined()) + scope.result = scope.engine->newString(); } -ReturnedValue RegExpPrototype::method_get_input(CallContext *ctx) +void RegExpPrototype::method_get_input(const BuiltinFunction *, Scope &scope, CallData *) { - return static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastInput()->asReturnedValue(); + scope.result = static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastInput(); } -ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx) +void RegExpPrototype::method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *) { - Scope scope(ctx); - Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor()); + Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor()); QString lastInput = regExpCtor->lastInput()->toQString(); - return ctx->d()->engine->newString(lastInput.left(regExpCtor->lastMatchStart()))->asReturnedValue(); + scope.result = scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart())); } -ReturnedValue RegExpPrototype::method_get_rightContext(CallContext *ctx) +void RegExpPrototype::method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *) { - Scope scope(ctx); - Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor()); + Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor()); QString lastInput = regExpCtor->lastInput()->toQString(); - return ctx->d()->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()))->asReturnedValue(); + scope.result = scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd())); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index 2c82cfdfd1..c0c7dfa78a 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -149,17 +149,17 @@ struct RegExpPrototype: RegExpObject { void init(ExecutionEngine *engine, Object *ctor); - static ReturnedValue method_exec(CallContext *ctx); - static ReturnedValue method_test(CallContext *ctx); - static ReturnedValue method_toString(CallContext *ctx); - static ReturnedValue method_compile(CallContext *ctx); + static void method_exec(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_test(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_compile(const BuiltinFunction *, Scope &scope, CallData *callData); template <int index> - static ReturnedValue method_get_lastMatch_n(CallContext *ctx); - static ReturnedValue method_get_lastParen(CallContext *ctx); - static ReturnedValue method_get_input(CallContext *ctx); - static ReturnedValue method_get_leftContext(CallContext *ctx); - static ReturnedValue method_get_rightContext(CallContext *ctx); + static void method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_input(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *callData); }; } diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 379c3babda..6cdc6200e7 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -71,14 +71,14 @@ struct ScopedValue; #define CHECK_EXCEPTION() \ do { \ if (scope.hasException()) { \ - scope.result = Encode::undefined(); \ + scope.result = QV4::Encode::undefined(); \ return; \ } \ } while (false) #define RETURN_UNDEFINED() \ do { \ - scope.result = Encode::undefined(); \ + scope.result = QV4::Encode::undefined(); \ return; \ } while (false) |