diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-04 18:53:51 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-08 18:58:14 +0000 |
commit | 50e7badd5f261bd69db9d8f03d5651e346087218 (patch) | |
tree | 73c2771fbc98168280182e77337b06efa39f4a7b /src/qml/jsruntime/qv4numberobject.cpp | |
parent | 8abb6c41bf055d59c6b57a809e3b027293568848 (diff) |
Remove Scope::result and convert calling convention for builtins
Allow for faster calling of builtins, and completely avoid
scope creation in many cases.
Change-Id: I0f1681e19e9908db10def85a74e134a87fc2e44c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4numberobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4numberobject.cpp | 163 |
1 files changed, 73 insertions, 90 deletions
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 40586b558b..1db5079355 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -124,117 +124,99 @@ QT_WARNING_POP defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision, 1); } -inline ReturnedValue thisNumberValue(Scope &scope, CallData *callData) +inline ReturnedValue thisNumberValue(ExecutionEngine *v4, CallData *callData) { if (callData->thisObject.isNumber()) return callData->thisObject.asReturnedValue(); NumberObject *n = callData->thisObject.as<NumberObject>(); if (!n) { - scope.engine->throwTypeError(); + v4->throwTypeError(); return Encode::undefined(); } return Encode(n->value()); } -inline double thisNumber(Scope &scope, CallData *callData) +inline double thisNumber(ExecutionEngine *engine, CallData *callData) { if (callData->thisObject.isNumber()) return callData->thisObject.asDouble(); NumberObject *n = callData->thisObject.as<NumberObject>(); if (!n) { - scope.engine->throwTypeError(); + engine->throwTypeError(); return 0; } return n->value(); } -void NumberPrototype::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isFinite(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); double v = callData->args[0].toNumber(); - scope.result = Encode(!std::isnan(v) && !qt_is_inf(v)); + return Encode(!std::isnan(v) && !qt_is_inf(v)); } -void NumberPrototype::method_isInteger(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isInteger(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); const Value &v = callData->args[0]; - if (!v.isNumber()) { - scope.result = Encode(false); - return; - } + if (!v.isNumber()) + return Encode(false); double dv = v.toNumber(); - if (std::isnan(dv) || qt_is_inf(dv)) { - scope.result = Encode(false); - return; - } + if (std::isnan(dv) || qt_is_inf(dv)) + return Encode(false); double iv = v.toInteger(); - scope.result = Encode(dv == iv); + return Encode(dv == iv); } -void NumberPrototype::method_isSafeInteger(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isSafeInteger(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); const Value &v = callData->args[0]; - if (!v.isNumber()) { - scope.result = Encode(false); - return; - } + if (!v.isNumber()) + return Encode(false); double dv = v.toNumber(); - if (std::isnan(dv) || qt_is_inf(dv)) { - scope.result = Encode(false); - return; - } + if (std::isnan(dv) || qt_is_inf(dv)) + return Encode(false); double iv = v.toInteger(); - scope.result = Encode(dv == iv && std::fabs(iv) <= (2^53)-1); + return Encode(dv == iv && std::fabs(iv) <= (2^53)-1); } -void NumberPrototype::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isNaN(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); double v = callData->args[0].toNumber(); - scope.result = Encode(std::isnan(v)); + return Encode(std::isnan(v)); } -void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { - double num = thisNumber(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + double num = thisNumber(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); if (callData->argc && !callData->args[0].isUndefined()) { int radix = callData->args[0].toInt32(); if (radix < 2 || radix > 36) { - scope.result = scope.engine->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix") - .arg(radix)); - return; + return v4->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix").arg(radix)); } if (std::isnan(num)) { - scope.result = scope.engine->newString(QStringLiteral("NaN")); - return; + return Encode(v4->newString(QStringLiteral("NaN"))); } else if (qt_is_inf(num)) { - scope.result = scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity")); - return; + return Encode(v4->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"))); } if (radix != 10) { @@ -264,30 +246,31 @@ void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, Cal } if (negative) str.prepend(QLatin1Char('-')); - scope.result = scope.engine->newString(str); - return; + return Encode(v4->newString(str)); } } - scope.result = Primitive::fromDouble(num).toString(scope.engine); + return Encode(Primitive::fromDouble(num).toString(v4)); } -void NumberPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toLocaleString(const BuiltinFunction *b, CallData *callData) { - ScopedValue v(scope, thisNumberValue(scope, callData)); - scope.result = v->toString(scope.engine); - CHECK_EXCEPTION(); + Scope scope(b); + ScopedValue v(scope, thisNumberValue(b->engine(), callData)); + return Encode(v->toString(scope.engine)); } -void NumberPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData) { - scope.result = thisNumberValue(scope, callData); + return thisNumberValue(b->engine(), callData); } -void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toFixed(const BuiltinFunction *b, CallData *callData) { - double v = thisNumber(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + double v = thisNumber(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); double fdigits = 0; @@ -297,10 +280,8 @@ void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, Call if (std::isnan(fdigits)) fdigits = 0; - if (fdigits < 0 || fdigits > 20) { - scope.result = scope.engine->throwRangeError(callData->thisObject); - return; - } + if (fdigits < 0 || fdigits > 20) + return v4->throwRangeError(callData->thisObject); QString str; if (std::isnan(v)) @@ -310,49 +291,51 @@ void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, Call else if (v < 1.e21) str = NumberLocale::instance()->toString(v, 'f', int(fdigits)); else { - scope.result = RuntimeHelpers::stringFromNumber(scope.engine, v); - return; + return Encode(RuntimeHelpers::stringFromNumber(v4, v)); } - scope.result = scope.engine->newString(str); + return Encode(v4->newString(str)); } -void NumberPrototype::method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toExponential(const BuiltinFunction *b, CallData *callData) { - double d = thisNumber(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + double d = thisNumber(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); + int fdigits = NumberLocale::instance()->defaultDoublePrecision; if (callData->argc && !callData->args[0].isUndefined()) { fdigits = callData->args[0].toInt32(); if (fdigits < 0 || fdigits > 20) { - ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range"))); - scope.result = scope.engine->throwRangeError(error); - return; + Scope scope(v4); + ScopedString error(scope, v4->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range"))); + return v4->throwRangeError(error); } } QString result = NumberLocale::instance()->toString(d, 'e', fdigits); - scope.result = scope.engine->newString(result); + return Encode(v4->newString(result)); } -void NumberPrototype::method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toPrecision(const BuiltinFunction *b, CallData *callData) { - ScopedValue v(scope, thisNumberValue(scope, callData)); - CHECK_EXCEPTION(); + Scope scope(b); + ScopedValue v(scope, thisNumberValue(scope.engine, callData)); + if (scope.engine->hasException) + return QV4::Encode::undefined(); - if (!callData->argc || callData->args[0].isUndefined()) { - scope.result = v->toString(scope.engine); - return; - } + + if (!callData->argc || callData->args[0].isUndefined()) + return Encode(v->toString(scope.engine)); int precision = callData->args[0].toInt32(); if (precision < 1 || precision > 21) { ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range"))); - scope.result = scope.engine->throwRangeError(error); - return; + return scope.engine->throwRangeError(error); } QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision); - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } |