Use faster calling path for more builtin methods
authorLars Knoll <lars.knoll@digia.com>
Tue, 29 Jan 2013 21:08:35 +0000 (22:08 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 29 Jan 2013 23:27:06 +0000 (00:27 +0100)
This speeds up some test cases I have by a factor of 2.

Change-Id: Ief9e2845c974d701fa032937cafced323279e9ec
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4globalobject.cpp
qv4globalobject.h
qv4mathobject.cpp
qv4mathobject.h
qv4stringobject.cpp
qv4stringobject.h

index bdf010f..d538cfd 100644 (file)
@@ -592,63 +592,63 @@ Value GlobalFunctions::method_isFinite(ExecutionContext *context)
 }
 
 /// decodeURI [15.1.3.1]
-Value GlobalFunctions::method_decodeURI(ExecutionContext *context)
+Value GlobalFunctions::method_decodeURI(ExecutionContext *parentCtx, Value, Value *argv, int argc)
 {
-    if (context->argumentCount == 0)
+    if (argc == 0)
         return Value::undefinedValue();
 
-    QString uriString = context->argument(0).toString(context)->toQString();
+    QString uriString = argv[0].toString(parentCtx)->toQString();
     bool ok;
     QString out = decode(uriString, QString::fromUtf8(uriReserved) + QString::fromUtf8("#"), &ok);
     if (!ok)
-        context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
+        parentCtx->throwURIError(Value::fromString(parentCtx, QStringLiteral("malformed URI sequence")));
 
-    return Value::fromString(context, out);
+    return Value::fromString(parentCtx, out);
 }
 
 /// decodeURIComponent [15.1.3.2]
-Value GlobalFunctions::method_decodeURIComponent(ExecutionContext *context)
+Value GlobalFunctions::method_decodeURIComponent(ExecutionContext *parentCtx, Value, Value *argv, int argc)
 {
-    if (context->argumentCount == 0)
+    if (argc == 0)
         return Value::undefinedValue();
 
-    QString uriString = context->argument(0).toString(context)->toQString();
+    QString uriString = argv[0].toString(parentCtx)->toQString();
     bool ok;
     QString out = decode(uriString, QString(), &ok);
     if (!ok)
-        context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
+        parentCtx->throwURIError(Value::fromString(parentCtx, QStringLiteral("malformed URI sequence")));
 
-    return Value::fromString(context, out);
+    return Value::fromString(parentCtx, out);
 }
 
 /// encodeURI [15.1.3.3]
-Value GlobalFunctions::method_encodeURI(ExecutionContext *context)
+Value GlobalFunctions::method_encodeURI(ExecutionContext *parentCtx, Value, Value *argv, int argc)
 {
-    if (context->argumentCount == 0)
+    if (argc == 0)
         return Value::undefinedValue();
 
-    QString uriString = context->argument(0).toString(context)->toQString();
+    QString uriString = argv[0].toString(parentCtx)->toQString();
     bool ok;
     QString out = encode(uriString, QLatin1String(uriReserved) + QLatin1String(uriUnescaped) + QString::fromUtf8("#"), &ok);
     if (!ok)
-        context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
+        parentCtx->throwURIError(Value::fromString(parentCtx, QStringLiteral("malformed URI sequence")));
 
-    return Value::fromString(context, out);
+    return Value::fromString(parentCtx, out);
 }
 
 /// encodeURIComponent [15.1.3.4]
-Value GlobalFunctions::method_encodeURIComponent(ExecutionContext *context)
+Value GlobalFunctions::method_encodeURIComponent(ExecutionContext *parentCtx, Value, Value *argv, int argc)
 {
-    if (context->argumentCount == 0)
+    if (argc == 0)
         return Value::undefinedValue();
 
-    QString uriString = context->argument(0).toString(context)->toQString();
+    QString uriString = argv[0].toString(parentCtx)->toQString();
     bool ok;
     QString out = encode(uriString, QString(uriUnescaped), &ok);
     if (!ok)
-        context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
+        parentCtx->throwURIError(Value::fromString(parentCtx, QStringLiteral("malformed URI sequence")));
 
-    return Value::fromString(context, out);
+    return Value::fromString(parentCtx, out);
 }
 
 Value GlobalFunctions::method_escape(ExecutionContext *context)
index 1ad76cf..fecad46 100644 (file)
@@ -69,10 +69,10 @@ struct GlobalFunctions
     static Value method_parseFloat(ExecutionContext *context);
     static Value method_isNaN(ExecutionContext *context);
     static Value method_isFinite(ExecutionContext *context);
-    static Value method_decodeURI(ExecutionContext *context);
-    static Value method_decodeURIComponent(ExecutionContext *context);
-    static Value method_encodeURI(ExecutionContext *context);
-    static Value method_encodeURIComponent(ExecutionContext *context);
+    static Value method_decodeURI(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value method_decodeURIComponent(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value method_encodeURI(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value method_encodeURIComponent(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
     static Value method_escape(ExecutionContext *context);
     static Value method_unescape(ExecutionContext *context);
 };
index 8076e16..e40faba 100644 (file)
@@ -214,10 +214,10 @@ Value MathObject::method_min(ExecutionContext *ctx)
     return Value::fromDouble(mx);
 }
 
-Value MathObject::method_pow(ExecutionContext *ctx)
+Value MathObject::method_pow(ExecutionContext *parentCtx, Value, Value *argv, int argc)
 {
-    double x = ctx->argument(0).toNumber(ctx);
-    double y = ctx->argument(1).toNumber(ctx);
+    double x = argc > 0 ? argv[0].toNumber(parentCtx) : qSNaN();
+    double y = argc > 1 ? argv[1].toNumber(parentCtx) : qSNaN();
 
     if (std::isnan(y))
         return Value::fromDouble(qSNaN());
@@ -246,14 +246,14 @@ Value MathObject::method_pow(ExecutionContext *ctx)
     else if (qIsInf(x) && copySign(1.0, x) == -1.0) {
         if (y > 0) {
             if (::fmod(y, 2.0) == 1.0)
-                return Value::number(ctx, -qInf());
+                return Value::fromDouble(-qInf());
             else
-                return Value::number(ctx, qInf());
+                return Value::fromDouble(qInf());
         } else if (y < 0) {
             if (::fmod(-y, 2.0) == 1.0)
-                return Value::number(ctx, copySign(0, -1.0));
+                return Value::fromDouble(copySign(0, -1.0));
             else
-                return Value::number(ctx, 0);
+                return Value::fromDouble(0);
         }
     }
 #endif
index c2b26ef..c8428d2 100644 (file)
@@ -64,7 +64,7 @@ struct MathObject: Object
     static Value method_log(ExecutionContext *ctx);
     static Value method_max(ExecutionContext *ctx);
     static Value method_min(ExecutionContext *ctx);
-    static Value method_pow(ExecutionContext *ctx);
+    static Value method_pow(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
     static Value method_random(ExecutionContext *ctx);
     static Value method_round(ExecutionContext *ctx);
     static Value method_sin(ExecutionContext *ctx);
index ced905d..81968cc 100644 (file)
@@ -234,7 +234,7 @@ Value StringPrototype::method_concat(ExecutionContext *parentCtx, Value thisObje
 {
     QString value = getThisString(parentCtx, thisObject);
 
-    for (unsigned i = 0; i < argc; ++i) {
+    for (int i = 0; i < argc; ++i) {
         Value v = __qmljs_to_string(argv[i], parentCtx);
         assert(v.isString());
         value += v.stringValue()->toQString();
@@ -607,17 +607,17 @@ Value StringPrototype::method_split(ExecutionContext *ctx)
     return result;
 }
 
-Value StringPrototype::method_substr(ExecutionContext *ctx)
+Value StringPrototype::method_substr(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc)
 {
-    const QString value = getThisString(ctx);
+    const QString value = getThisString(parentCtx, thisObject);
 
     double start = 0;
-    if (ctx->argumentCount > 0)
-        start = ctx->argument(0).toInteger(ctx);
+    if (argc > 0)
+        start = argv[0].toInteger(parentCtx);
 
     double length = +qInf();
-    if (ctx->argumentCount > 1)
-        length = ctx->argument(1).toInteger(ctx);
+    if (argc > 1)
+        length = argv[1].toInteger(parentCtx);
 
     double count = value.length();
     if (start < 0)
@@ -627,23 +627,23 @@ Value StringPrototype::method_substr(ExecutionContext *ctx)
 
     qint32 x = Value::toInt32(start);
     qint32 y = Value::toInt32(length);
-    return Value::fromString(ctx, value.mid(x, y));
+    return Value::fromString(parentCtx, value.mid(x, y));
 }
 
-Value StringPrototype::method_substring(ExecutionContext *ctx)
+Value StringPrototype::method_substring(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc)
 {
-    QString value = getThisString(ctx);
+    QString value = getThisString(parentCtx, thisObject);
     int length = value.length();
 
     double start = 0;
     double end = length;
 
-    if (ctx->argumentCount > 0)
-        start = ctx->argument(0).toInteger(ctx);
+    if (argc > 0)
+        start = argv[0].toInteger(parentCtx);
 
-    Value endValue = ctx->argument(1);
+    Value endValue = argc > 1 ? argv[1] : Value::undefinedValue();
     if (!endValue.isUndefined())
-        end = endValue.toInteger(ctx);
+        end = endValue.toInteger(parentCtx);
 
     if (std::isnan(start) || start < 0)
         start = 0;
@@ -665,7 +665,7 @@ Value StringPrototype::method_substring(ExecutionContext *ctx)
 
     qint32 x = (int)start;
     qint32 y = (int)(end - start);
-    return Value::fromString(ctx, value.mid(x, y));
+    return Value::fromString(parentCtx, value.mid(x, y));
 }
 
 Value StringPrototype::method_toLowerCase(ExecutionContext *ctx)
@@ -690,14 +690,15 @@ Value StringPrototype::method_toLocaleUpperCase(ExecutionContext *ctx)
     return method_toUpperCase(ctx);
 }
 
-Value StringPrototype::method_fromCharCode(ExecutionContext *ctx)
+Value StringPrototype::method_fromCharCode(ExecutionContext *parentCtx, Value, Value *argv, int argc)
 {
-    QString str;
-    for (unsigned i = 0; i < ctx->argumentCount; ++i) {
-        QChar c(ctx->argument(i).toUInt16(ctx));
-        str += c;
+    QString str(argc, Qt::Uninitialized);
+    QChar *ch = str.data();
+    for (int i = 0; i < argc; ++i) {
+        *ch = QChar(argv[i].toUInt16(parentCtx));
+        ++ch;
     }
-    return Value::fromString(ctx, str);
+    return Value::fromString(parentCtx, str);
 }
 
 Value StringPrototype::method_trim(ExecutionContext *ctx)
index f799c76..1becd97 100644 (file)
@@ -84,13 +84,13 @@ struct StringPrototype: StringObject
     static Value method_search(ExecutionContext *ctx);
     static Value method_slice(ExecutionContext *ctx);
     static Value method_split(ExecutionContext *ctx);
-    static Value method_substr(ExecutionContext *ctx);
-    static Value method_substring(ExecutionContext *ctx);
+    static Value method_substr(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value method_substring(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
     static Value method_toLowerCase(ExecutionContext *ctx);
     static Value method_toLocaleLowerCase(ExecutionContext *ctx);
     static Value method_toUpperCase(ExecutionContext *ctx);
     static Value method_toLocaleUpperCase(ExecutionContext *ctx);
-    static Value method_fromCharCode(ExecutionContext *ctx);
+    static Value method_fromCharCode(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
     static Value method_trim(ExecutionContext *ctx);
 };