change calling convention for JS function calls
authorLars Knoll <lars.knoll@digia.com>
Wed, 21 Aug 2013 15:31:22 +0000 (17:31 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 2 Sep 2013 15:27:36 +0000 (17:27 +0200)
This allows faster pass through of the data if we have
nested calls.

Also make sure we always reserve at least
QV4::Global::ReservedArgumentCount Values on the
stack to avoid stack corruption.

Change-Id: I42976460f1ef11a333d4adda70fba8daac66acf3
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
51 files changed:
src/imports/localstorage/plugin.cpp
src/qml/jsapi/qjsvalue.cpp
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4argumentsobject_p.h
src/qml/jsruntime/qv4arrayobject.cpp
src/qml/jsruntime/qv4arrayobject_p.h
src/qml/jsruntime/qv4booleanobject.cpp
src/qml/jsruntime/qv4booleanobject_p.h
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4context_p.h
src/qml/jsruntime/qv4dateobject.cpp
src/qml/jsruntime/qv4dateobject_p.h
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4errorobject.cpp
src/qml/jsruntime/qv4errorobject_p.h
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4functionobject_p.h
src/qml/jsruntime/qv4globalobject.cpp
src/qml/jsruntime/qv4globalobject_p.h
src/qml/jsruntime/qv4include.cpp
src/qml/jsruntime/qv4jsonobject.cpp
src/qml/jsruntime/qv4lookup.cpp
src/qml/jsruntime/qv4managed.cpp
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4numberobject.cpp
src/qml/jsruntime/qv4numberobject_p.h
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4objectproto.cpp
src/qml/jsruntime/qv4objectproto_p.h
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/jsruntime/qv4qobjectwrapper_p.h
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4regexpobject_p.h
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4script.cpp
src/qml/jsruntime/qv4sequenceobject.cpp
src/qml/jsruntime/qv4stringobject.cpp
src/qml/jsruntime/qv4stringobject_p.h
src/qml/jsruntime/qv4value_p.h
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlcomponent.cpp
src/qml/qml/qqmljavascriptexpression.cpp
src/qml/qml/qqmlvmemetaobject.cpp
src/qml/qml/qqmlxmlhttprequest.cpp
src/qml/qml/v8/qqmlbuiltinfunctions.cpp
src/qml/qml/v8/qv8engine.cpp
src/qml/types/qqmldelegatemodel.cpp
src/qml/types/qquickworkerscript.cpp
src/quick/items/context2d/qquickcanvasitem.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
tools/v4/main.cpp

index 0bee6d1..6fc7d1d 100644 (file)
@@ -341,9 +341,11 @@ static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
         ok = false;
         db.transaction();
 
-        Value callbackArgs[] = { Value::fromObject(w) };
+        CALLDATA(1);
+        d.thisObject = engine->global();
+        d.args[0] = Value::fromObject(w);
         try {
-            f->call(engine->global(), callbackArgs, 1);
+            f->call(d);
         } catch (Exception &) {
             db.rollback();
             throw;
@@ -393,9 +395,11 @@ static Value qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool read
 
     db.transaction();
     if (callback) {
-        Value callbackArgs[] = { Value::fromObject(w) };
+        CALLDATA(1);
+        d.thisObject = engine->global();
+        d.args[0] = Value::fromObject(w);
         try {
-            callback->call(engine->global(), callbackArgs, 1);
+            callback->call(d);
         } catch (Exception &) {
             w->inTransaction = false;
             db.rollback();
@@ -674,8 +678,10 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
     db->version = version;
 
     if (created && dbcreationCallback) {
-        Value args[] = { Value::fromObject(db) };
-        dbcreationCallback->call(engine->global(), args, 1);
+        CALLDATA(1);
+        d.thisObject = engine->global();
+        d.args[0] = Value::fromObject(db);
+        dbcreationCallback->call(d);
     }
 
     args->setReturnValue(Value::fromObject(db));
index ec8cc2a..cff760b 100644 (file)
@@ -505,19 +505,20 @@ QJSValue QJSValue::call(const QJSValueList &args)
     ExecutionEngine *engine = d->engine;
     assert(engine);
 
-    QVarLengthArray<Value, 9> arguments(args.length());
+    CALLDATA(args.length());
+    d.thisObject = Value::fromObject(engine->globalObject);
     for (int i = 0; i < args.size(); ++i) {
         if (!args.at(i).d->checkEngine(engine)) {
             qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
             return QJSValue();
         }
-        arguments[i] = args.at(i).d->getValue(engine);
+        d.args[i] = args.at(i).d->getValue(engine);
     }
 
     Value result;
     QV4::ExecutionContext *ctx = engine->current;
     try {
-        result = f->call(Value::fromObject(engine->globalObject), arguments.data(), arguments.size());
+        result = f->call(d);
     } catch (Exception &e) {
         e.accept(ctx);
         result = e.value();
@@ -560,19 +561,20 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
         return QJSValue();
     }
 
-    QVarLengthArray<Value, 9> arguments(args.length());
+    CALLDATA(args.size());
+    d.thisObject = instance.d->getValue(engine);
     for (int i = 0; i < args.size(); ++i) {
         if (!args.at(i).d->checkEngine(engine)) {
             qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
             return QJSValue();
         }
-        arguments[i] = args.at(i).d->getValue(engine);
+        d.args[i] = args.at(i).d->getValue(engine);
     }
 
     Value result;
     QV4::ExecutionContext *ctx = engine->current;
     try {
-        result = f->call(instance.d->getValue(engine), arguments.data(), arguments.size());
+        result = f->call(d);
     } catch (Exception &e) {
         e.accept(ctx);
         result = e.value();
@@ -608,19 +610,19 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
     ExecutionEngine *engine = d->engine;
     assert(engine);
 
-    QVarLengthArray<Value, 9> arguments(args.length());
+    CALLDATA(args.size());
     for (int i = 0; i < args.size(); ++i) {
         if (!args.at(i).d->checkEngine(engine)) {
             qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
             return QJSValue();
         }
-        arguments[i] = args.at(i).d->getValue(engine);
+        d.args[i] = args.at(i).d->getValue(engine);
     }
 
     Value result;
     QV4::ExecutionContext *ctx = engine->current;
     try {
-        result = f->construct(arguments.data(), arguments.size());
+        result = f->construct(d);
     } catch (Exception &e) {
         e.accept(ctx);
         result = e.value();
index 1670f69..40ae29d 100644 (file)
@@ -39,6 +39,7 @@
 **
 ****************************************************************************/
 #include <qv4argumentsobject_p.h>
+#include <qv4alloca_p.h>
 
 using namespace QV4;
 
@@ -128,8 +129,10 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
 
     if (isMapped && attrs.isData()) {
         if (!attrs.isGeneric()) {
-            Value arg = desc.value;
-            map.setter()->call(Value::fromObject(this), &arg, 1);
+            CALLDATA(1);
+            d.thisObject = Value::fromObject(this);
+            d.args[0] = desc.value;
+            map.setter()->call(d);
         }
         if (attrs.isWritable()) {
             *pd = map;
@@ -144,10 +147,10 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
 
 DEFINE_MANAGED_VTABLE(ArgumentsGetterFunction);
 
-Value ArgumentsGetterFunction::call(Managed *getter, const Value &thisObject, Value *, int)
+Value ArgumentsGetterFunction::call(Managed *getter, const CallData &d)
 {
     ArgumentsGetterFunction *g = static_cast<ArgumentsGetterFunction *>(getter);
-    Object *that = thisObject.asObject();
+    Object *that = d.thisObject.asObject();
     if (!that)
         getter->engine()->current->throwTypeError();
     ArgumentsObject *o = that->asArgumentsObject();
@@ -160,10 +163,10 @@ Value ArgumentsGetterFunction::call(Managed *getter, const Value &thisObject, Va
 
 DEFINE_MANAGED_VTABLE(ArgumentsSetterFunction);
 
-Value ArgumentsSetterFunction::call(Managed *setter, const Value &thisObject, Value *args, int argc)
+Value ArgumentsSetterFunction::call(Managed *setter, const CallData &d)
 {
     ArgumentsSetterFunction *s = static_cast<ArgumentsSetterFunction *>(setter);
-    Object *that = thisObject.asObject();
+    Object *that = d.thisObject.asObject();
     if (!that)
         setter->engine()->current->throwTypeError();
     ArgumentsObject *o = that->asArgumentsObject();
@@ -171,7 +174,7 @@ Value ArgumentsSetterFunction::call(Managed *setter, const Value &thisObject, Va
         setter->engine()->current->throwTypeError();
 
     assert(s->index < o->context->argumentCount);
-    o->context->arguments[s->index] = argc ? args[0] : Value::undefinedValue();
+    o->context->arguments[s->index] = d.argc ? d.args[0] : Value::undefinedValue();
     return Value::undefinedValue();
 }
 
index 097bc4c..f48db1f 100644 (file)
@@ -55,7 +55,7 @@ struct ArgumentsGetterFunction: FunctionObject
     ArgumentsGetterFunction(ExecutionContext *scope, uint index)
         : FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
 
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -68,7 +68,7 @@ struct ArgumentsSetterFunction: FunctionObject
     ArgumentsSetterFunction(ExecutionContext *scope, uint index)
         : FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
 
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index d7f4bab..c316a31 100644 (file)
@@ -52,25 +52,25 @@ ArrayCtor::ArrayCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value ArrayCtor::construct(Managed *m, Value *argv, int argc)
+Value ArrayCtor::construct(Managed *m, const CallData &d)
 {
     ExecutionEngine *v4 = m->engine();
     ArrayObject *a = v4->newArrayObject();
     uint len;
-    if (argc == 1 && argv[0].isNumber()) {
+    if (d.argc == 1 && d.args[0].isNumber()) {
         bool ok;
-        len = argv[0].asArrayLength(&ok);
+        len = d.args[0].asArrayLength(&ok);
 
         if (!ok)
-            v4->current->throwRangeError(argv[0]);
+            v4->current->throwRangeError(d.args[0]);
 
         if (len < 0x1000)
             a->arrayReserve(len);
     } else {
-        len = argc;
+        len = d.argc;
         a->arrayReserve(len);
         for (unsigned int i = 0; i < len; ++i)
-            a->arrayData[i].value = argv[i];
+            a->arrayData[i].value = d.args[i];
         a->arrayDataLen = len;
     }
     a->setArrayLengthUnchecked(len);
@@ -78,9 +78,9 @@ Value ArrayCtor::construct(Managed *m, Value *argv, int argc)
     return Value::fromObject(a);
 }
 
-Value ArrayCtor::call(Managed *that, const Value &, Value *argv, int argc)
+Value ArrayCtor::call(Managed *that, const CallData &d)
 {
-    return construct(that, argv, argc);
+    return construct(that, d);
 }
 
 ArrayPrototype::ArrayPrototype(ExecutionContext *context)
@@ -628,11 +628,12 @@ Value ArrayPrototype::method_every(SimpleCallContext *ctx)
         if (!exists)
             continue;
 
-        Value args[3];
-        args[0] = v;
-        args[1] = Value::fromDouble(k);
-        args[2] = Value::fromObject(instance);
-        Value r = callback->call(thisArg, args, 3);
+        CALLDATA(3);
+        d.args[0] = v;
+        d.args[1] = Value::fromDouble(k);
+        d.args[2] = Value::fromObject(instance);
+        d.thisObject = thisArg;
+        Value r = callback->call(d);
         ok = r.toBoolean();
     }
     return Value::fromBoolean(ok);
@@ -656,11 +657,12 @@ Value ArrayPrototype::method_some(SimpleCallContext *ctx)
         if (!exists)
             continue;
 
-        Value args[3];
-        args[0] = v;
-        args[1] = Value::fromDouble(k);
-        args[2] = Value::fromObject(instance);
-        Value r = callback->call(thisArg, args, 3);
+        CALLDATA(3);
+        d.args[0] = v;
+        d.args[1] = Value::fromDouble(k);
+        d.args[2] = Value::fromObject(instance);
+        d.thisObject = thisArg;
+        Value r = callback->call(d);
         if (r.toBoolean())
             return Value::fromBoolean(true);
     }
@@ -685,11 +687,12 @@ Value ArrayPrototype::method_forEach(SimpleCallContext *ctx)
         if (!exists)
             continue;
 
-        Value args[3];
-        args[0] = v;
-        args[1] = Value::fromDouble(k);
-        args[2] = Value::fromObject(instance);
-        callback->call(thisArg, args, 3);
+        CALLDATA(3);
+        d.args[0] = v;
+        d.args[1] = Value::fromDouble(k);
+        d.args[2] = Value::fromObject(instance);
+        d.thisObject = thisArg;
+        callback->call(d);
     }
     return Value::undefinedValue();
 }
@@ -716,11 +719,12 @@ Value ArrayPrototype::method_map(SimpleCallContext *ctx)
         if (!exists)
             continue;
 
-        Value args[3];
-        args[0] = v;
-        args[1] = Value::fromDouble(k);
-        args[2] = Value::fromObject(instance);
-        Value mapped = callback->call(thisArg, args, 3);
+        CALLDATA(3);
+        d.args[0] = v;
+        d.args[1] = Value::fromDouble(k);
+        d.args[2] = Value::fromObject(instance);
+        d.thisObject = thisArg;
+        Value mapped = callback->call(d);
         a->arraySet(k, mapped);
     }
     return Value::fromObject(a);
@@ -748,11 +752,12 @@ Value ArrayPrototype::method_filter(SimpleCallContext *ctx)
         if (!exists)
             continue;
 
-        Value args[3];
-        args[0] = v;
-        args[1] = Value::fromDouble(k);
-        args[2] = Value::fromObject(instance);
-        Value selected = callback->call(thisArg, args, 3);
+        CALLDATA(3);
+        d.args[0] = v;
+        d.args[1] = Value::fromDouble(k);
+        d.args[2] = Value::fromObject(instance);
+        d.thisObject = thisArg;
+        Value selected = callback->call(d);
         if (selected.toBoolean()) {
             a->arraySet(to, v);
             ++to;
@@ -791,12 +796,13 @@ Value ArrayPrototype::method_reduce(SimpleCallContext *ctx)
         bool kPresent;
         Value v = instance->getIndexed(k, &kPresent);
         if (kPresent) {
-            Value args[4];
-            args[0] = acc;
-            args[1] = v;
-            args[2] = Value::fromDouble(k);
-            args[3] = Value::fromObject(instance);
-            acc = callback->call(Value::undefinedValue(), args, 4);
+            CALLDATA(4);
+            d.args[0] = acc;
+            d.args[1] = v;
+            d.args[2] = Value::fromDouble(k);
+            d.args[3] = Value::fromObject(instance);
+            d.thisObject = Value::undefinedValue();
+            acc = callback->call(d);
         }
         ++k;
     }
@@ -839,12 +845,13 @@ Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
         bool kPresent;
         Value v = instance->getIndexed(k - 1, &kPresent);
         if (kPresent) {
-            Value args[4];
-            args[0] = acc;
-            args[1] = v;
-            args[2] = Value::fromDouble(k - 1);
-            args[3] = Value::fromObject(instance);
-            acc = callback->call(Value::undefinedValue(), args, 4);
+            CALLDATA(4);
+            d.args[0] = acc;
+            d.args[1] = v;
+            d.args[2] = Value::fromDouble(k - 1);
+            d.args[3] = Value::fromObject(instance);
+            d.thisObject = Value::undefinedValue();
+            acc = callback->call(d);
         }
         --k;
     }
index 13c3882..f5c2566 100644 (file)
@@ -53,8 +53,8 @@ struct ArrayCtor: FunctionObject
 {
     ArrayCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *m, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 24678d2..25c1052 100644 (file)
@@ -51,15 +51,15 @@ BooleanCtor::BooleanCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value BooleanCtor::construct(Managed *m, Value *args, int argc)
+Value BooleanCtor::construct(Managed *m, const CallData &d)
 {
-    bool n = argc ? args[0].toBoolean() : false;
+    bool n = d.argc ? d.args[0].toBoolean() : false;
     return Value::fromObject(m->engine()->newBooleanObject(Value::fromBoolean(n)));
 }
 
-Value BooleanCtor::call(Managed *, const Value &, Value *argv, int argc)
+Value BooleanCtor::call(Managed *, const CallData &d)
 {
-    bool value = argc ? argv[0].toBoolean() : 0;
+    bool value = d.argc ? d.args[0].toBoolean() : 0;
     return Value::fromBoolean(value);
 }
 
index 3e5e766..0cdcdec 100644 (file)
@@ -53,8 +53,8 @@ struct BooleanCtor: FunctionObject
 {
     BooleanCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 7353d69..7d7f5dd 100644 (file)
@@ -51,7 +51,7 @@
 
 using namespace QV4;
 
-CallContext *ExecutionContext::newCallContext(void *stackSpace, FunctionObject *function, const Value &thisObject, Value *args, int argc)
+CallContext *ExecutionContext::newCallContext(void *stackSpace, FunctionObject *function, const CallData &d)
 {
     CallContext *c = (CallContext *)stackSpace;
 #ifndef QT_NO_DEBUG
@@ -63,10 +63,10 @@ CallContext *ExecutionContext::newCallContext(void *stackSpace, FunctionObject *
     c->initBaseContext(Type_CallContext, engine, this);
 
     c->function = function;
-    c->arguments = args;
-    c->realArgumentCount = argc;
-    c->argumentCount = argc;
-    c->thisObject = thisObject;
+    c->arguments = d.args;
+    c->realArgumentCount = d.argc;
+    c->argumentCount = d.argc;
+    c->thisObject = d.thisObject;
 
     c->strictMode = function->strictMode;
     c->marked = false;
@@ -89,27 +89,30 @@ CallContext *ExecutionContext::newCallContext(void *stackSpace, FunctionObject *
     if (function->varCount)
         std::fill(c->locals, c->locals + function->varCount, Value::undefinedValue());
 
-    if (argc < function->formalParameterCount) {
-        std::fill(c->arguments + argc, c->arguments + function->formalParameterCount, Value::undefinedValue());
+    if (d.argc < function->formalParameterCount) {
+#ifndef QT_NO_DEBUG
+        Q_ASSERT(function->formalParameterCount <= QV4::Global::ReservedArgumentCount);
+#endif
+        std::fill(c->arguments + d.argc, c->arguments + function->formalParameterCount, Value::undefinedValue());
         c->argumentCount = function->formalParameterCount;
     }
 
     return c;
 }
 
-CallContext *ExecutionContext::newCallContext(FunctionObject *function, const Value &thisObject, Value *args, int argc)
+CallContext *ExecutionContext::newCallContext(FunctionObject *function, const CallData &d)
 {
-    CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocContext(requiredMemoryForExecutionContect(function, argc)));
+    CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocContext(requiredMemoryForExecutionContect(function, d.argc)));
 
     engine->current = c;
 
     c->initBaseContext(Type_CallContext, engine, this);
 
     c->function = function;
-    c->arguments = args;
-    c->realArgumentCount = argc;
-    c->argumentCount = argc;
-    c->thisObject = thisObject;
+    c->arguments = d.args;
+    c->realArgumentCount = d.argc;
+    c->argumentCount = d.argc;
+    c->thisObject = d.thisObject;
 
     c->strictMode = function->strictMode;
     c->marked = false;
@@ -132,12 +135,12 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, const Va
     if (function->varCount)
         std::fill(c->locals, c->locals + function->varCount, Value::undefinedValue());
 
-    c->argumentCount = qMax((uint)argc, function->formalParameterCount);
+    c->argumentCount = qMax((uint)d.argc, function->formalParameterCount);
     c->arguments = c->locals + function->varCount;
-    if (argc)
-        ::memcpy(c->arguments, args, argc * sizeof(Value));
-    if (argc < function->formalParameterCount)
-        std::fill(c->arguments + argc, c->arguments + function->formalParameterCount, Value::undefinedValue());
+    if (d.argc)
+        ::memcpy(c->arguments, d.args, c->realArgumentCount * sizeof(Value));
+    if (d.argc < function->formalParameterCount)
+        std::fill(c->arguments + d.argc, c->arguments + function->formalParameterCount, Value::undefinedValue());
 
     return c;
 }
index 0c1dfb1..331c5aa 100644 (file)
@@ -114,8 +114,8 @@ struct Q_QML_EXPORT ExecutionContext
         interpreterInstructionPointer = 0;
     }
 
-    CallContext *newCallContext(void *stackSpace, FunctionObject *f, const QV4::Value &thisObject, QV4::Value *args, int argc);
-    CallContext *newCallContext(FunctionObject *f, const QV4::Value &thisObject, QV4::Value *args, int argc);
+    CallContext *newCallContext(void *stackSpace, FunctionObject *f, const CallData &d);
+    CallContext *newCallContext(FunctionObject *f, const CallData &d);
     WithContext *newWithContext(Object *with);
     CatchContext *newCatchContext(String* exceptionVarName, const QV4::Value &exceptionValue);
     CallContext *newQmlContext(FunctionObject *f, Object *qml);
index 47730f2..87d93ad 100644 (file)
@@ -659,15 +659,15 @@ DateCtor::DateCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value DateCtor::construct(Managed *m, Value *args, int argc)
+Value DateCtor::construct(Managed *m, const CallData &d)
 {
     double t = 0;
 
-    if (argc == 0)
+    if (d.argc == 0)
         t = currentTime();
 
-    else if (argc == 1) {
-        Value arg = args[0];
+    else if (d.argc == 1) {
+        Value arg = d.args[0];
         if (DateObject *d = arg.asDateObject())
             arg = d->value;
         else
@@ -679,25 +679,25 @@ Value DateCtor::construct(Managed *m, Value *args, int argc)
             t = TimeClip(arg.toNumber());
     }
 
-    else { // argc > 1
-        double year  = args[0].toNumber();
-        double month = args[1].toNumber();
-        double day  = argc >= 3 ? args[2].toNumber() : 1;
-        double hours = argc >= 4 ? args[3].toNumber() : 0;
-        double mins = argc >= 5 ? args[4].toNumber() : 0;
-        double secs = argc >= 6 ? args[5].toNumber() : 0;
-        double ms    = argc >= 7 ? args[6].toNumber() : 0;
+    else { // d.argc > 1
+        double year  = d.args[0].toNumber();
+        double month = d.args[1].toNumber();
+        double day  = d.argc >= 3 ? d.args[2].toNumber() : 1;
+        double hours = d.argc >= 4 ? d.args[3].toNumber() : 0;
+        double mins = d.argc >= 5 ? d.args[4].toNumber() : 0;
+        double secs = d.argc >= 6 ? d.args[5].toNumber() : 0;
+        double ms    = d.argc >= 7 ? d.args[6].toNumber() : 0;
         if (year >= 0 && year <= 99)
             year += 1900;
         t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms));
         t = TimeClip(UTC(t));
     }
 
-    Object *d = m->engine()->newDateObject(Value::fromDouble(t));
-    return Value::fromObject(d);
+    Object *o = m->engine()->newDateObject(Value::fromDouble(t));
+    return Value::fromObject(o);
 }
 
-Value DateCtor::call(Managed *m, const Value &, Value *, int)
+Value DateCtor::call(Managed *m, const CallData &)
 {
     double t = currentTime();
     return Value::fromString(m->engine()->current, ToString(t));
@@ -1306,7 +1306,9 @@ Value DatePrototype::method_toJSON(SimpleCallContext *ctx)
     if (!toIso)
         ctx->throwTypeError();
 
-    return toIso->call(ctx->thisObject, 0, 0);
+    CALLDATA(0);
+    d.thisObject = ctx->thisObject;
+    return toIso->call(d);
 }
 
 void DatePrototype::timezoneUpdated()
index 4e833e1..89ca057 100644 (file)
@@ -63,8 +63,8 @@ struct DateCtor: FunctionObject
 {
     DateCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &);
 
 protected:
     static const ManagedVTable static_vtbl;
index 0b67564..8f6e47e 100644 (file)
@@ -314,8 +314,6 @@ inline void ExecutionEngine::pushContext(SimpleCallContext *context)
 
 inline ExecutionContext *ExecutionEngine::popContext()
 {
-    CallContext *c = current->asCallContext();
-
     current = current->parent;
     return current;
 }
index 68f6f56..6c7c290 100644 (file)
@@ -242,14 +242,14 @@ ErrorCtor::ErrorCtor(ExecutionContext *scope, String *name)
     vtbl = &static_vtbl;
 }
 
-Value ErrorCtor::construct(Managed *m, Value *args, int argc)
+Value ErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(m->engine()->newErrorObject(argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(m->engine()->newErrorObject(d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
-Value ErrorCtor::call(Managed *that, const Value &, Value *args, int argc)
+Value ErrorCtor::call(Managed *that, const CallData &d)
 {
-    return that->construct(args, argc);
+    return that->construct(d);
 }
 
 EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope)
@@ -258,9 +258,9 @@ EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value EvalErrorCtor::construct(Managed *m, Value *args, int argc)
+Value EvalErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(new (m->engine()->memoryManager) EvalErrorObject(m->engine(), argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(new (m->engine()->memoryManager) EvalErrorObject(m->engine(), d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
 RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
@@ -269,9 +269,9 @@ RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value RangeErrorCtor::construct(Managed *m, Value *args, int argc)
+Value RangeErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(new (m->engine()->memoryManager) RangeErrorObject(m->engine(), argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(new (m->engine()->memoryManager) RangeErrorObject(m->engine(), d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
 ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
@@ -280,9 +280,9 @@ ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value ReferenceErrorCtor::construct(Managed *m, Value *args, int argc)
+Value ReferenceErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(new (m->engine()->memoryManager) ReferenceErrorObject(m->engine(), argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(new (m->engine()->memoryManager) ReferenceErrorObject(m->engine(), d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
 SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
@@ -291,9 +291,9 @@ SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value SyntaxErrorCtor::construct(Managed *m, Value *args, int argc)
+Value SyntaxErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(new (m->engine()->memoryManager) SyntaxErrorObject(m->engine(), argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(new (m->engine()->memoryManager) SyntaxErrorObject(m->engine(), d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
 TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
@@ -302,9 +302,9 @@ TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value TypeErrorCtor::construct(Managed *m, Value *args, int argc)
+Value TypeErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(new (m->engine()->memoryManager) TypeErrorObject(m->engine(), argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(new (m->engine()->memoryManager) TypeErrorObject(m->engine(), d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
 URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
@@ -313,9 +313,9 @@ URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value URIErrorCtor::construct(Managed *m, Value *args, int argc)
+Value URIErrorCtor::construct(Managed *m, const CallData &d)
 {
-    return Value::fromObject(new (m->engine()->memoryManager) URIErrorObject(m->engine(), argc ? args[0] : Value::undefinedValue()));
+    return Value::fromObject(new (m->engine()->memoryManager) URIErrorObject(m->engine(), d.argc ? d.args[0] : Value::undefinedValue()));
 }
 
 void ErrorPrototype::init(ExecutionEngine *engine, const Value &ctor, Object *obj)
index 798f86f..c510232 100644 (file)
@@ -113,8 +113,8 @@ struct ErrorCtor: FunctionObject
     ErrorCtor(ExecutionContext *scope);
     ErrorCtor(ExecutionContext *scope, String *name);
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -124,7 +124,7 @@ struct EvalErrorCtor: ErrorCtor
 {
     EvalErrorCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
+    static Value construct(Managed *m, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -134,7 +134,7 @@ struct RangeErrorCtor: ErrorCtor
 {
     RangeErrorCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
+    static Value construct(Managed *m, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -144,7 +144,7 @@ struct ReferenceErrorCtor: ErrorCtor
 {
     ReferenceErrorCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
+    static Value construct(Managed *m, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -154,7 +154,7 @@ struct SyntaxErrorCtor: ErrorCtor
 {
     SyntaxErrorCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
+    static Value construct(Managed *m, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -164,7 +164,7 @@ struct TypeErrorCtor: ErrorCtor
 {
     TypeErrorCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
+    static Value construct(Managed *m, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -174,7 +174,7 @@ struct URIErrorCtor: ErrorCtor
 {
     URIErrorCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
+    static Value construct(Managed *m, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 950a5a5..a4533ed 100644 (file)
@@ -102,7 +102,8 @@ FunctionObject::~FunctionObject()
 
 Value FunctionObject::newInstance()
 {
-    return construct(0, 0);
+    CALLDATA(0);
+    return construct(d);
 }
 
 bool FunctionObject::hasInstance(Managed *that, const Value &value)
@@ -130,7 +131,7 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value)
     return false;
 }
 
-Value FunctionObject::construct(Managed *that, Value *, int)
+Value FunctionObject::construct(Managed *that, const CallData &)
 {
     FunctionObject *f = static_cast<FunctionObject *>(that);
     ExecutionEngine *v4 = f->engine();
@@ -142,7 +143,7 @@ Value FunctionObject::construct(Managed *that, Value *, int)
     return Value::fromObject(obj);
 }
 
-Value FunctionObject::call(Managed *, const Value &, Value *, int)
+Value FunctionObject::call(Managed *, const CallData &)
 {
     return Value::undefinedValue();
 }
@@ -181,7 +182,7 @@ FunctionCtor::FunctionCtor(ExecutionContext *scope)
 }
 
 // 15.3.2
-Value FunctionCtor::construct(Managed *that, Value *args, int argc)
+Value FunctionCtor::construct(Managed *that, const CallData &d)
 {
     FunctionCtor *f = static_cast<FunctionCtor *>(that);
     MemoryManager::GCBlocker gcBlocker(f->engine()->memoryManager);
@@ -189,13 +190,13 @@ Value FunctionCtor::construct(Managed *that, Value *args, int argc)
     ExecutionContext *ctx = f->engine()->current;
     QString arguments;
     QString body;
-    if (argc > 0) {
-        for (uint i = 0; i < argc - 1; ++i) {
+    if (d.argc > 0) {
+        for (uint i = 0; i < d.argc - 1; ++i) {
             if (i)
                 arguments += QLatin1String(", ");
-            arguments += args[i].toString(ctx)->toQString();
+            arguments += d.args[i].toString(ctx)->toQString();
         }
-        body = args[argc - 1].toString(ctx)->toQString();
+        body = d.args[d.argc - 1].toString(ctx)->toQString();
     }
 
     QString function = QLatin1String("function(") + arguments + QLatin1String("){") + body + QLatin1String("}");
@@ -229,9 +230,9 @@ Value FunctionCtor::construct(Managed *that, Value *args, int argc)
 }
 
 // 15.3.1: This is equivalent to new Function(...)
-Value FunctionCtor::call(Managed *that, const Value &, Value *args, int argc)
+Value FunctionCtor::call(Managed *that, const CallData &d)
 {
-    return construct(that, args, argc);
+    return construct(that, d);
 }
 
 FunctionPrototype::FunctionPrototype(ExecutionContext *ctx)
@@ -281,28 +282,27 @@ Value FunctionPrototype::method_apply(SimpleCallContext *ctx)
     }
     quint32 len = arr ? arr->get(ctx->engine->id_length).toUInt32() : 0;
 
-    QVarLengthArray<Value, 32> args(len);
+    CALLDATA(len);
     for (quint32 i = 0; i < len; ++i)
-        args[i] = arr->getIndexed(i);
-
-
-    return o->call(thisArg, len ? args.data() : 0, len);
+        d.args[i] = arr->getIndexed(i);
+    d.thisObject = thisArg;
+    return o->call(d);
 }
 
 Value FunctionPrototype::method_call(SimpleCallContext *ctx)
 {
     Value thisArg = ctx->argument(0);
 
-    QVarLengthArray<Value, 32> args(ctx->argumentCount ? ctx->argumentCount - 1 : 0);
-    if (ctx->argumentCount)
-        qCopy(ctx->arguments + 1,
-              ctx->arguments + ctx->argumentCount, args.begin());
-
     FunctionObject *o = ctx->thisObject.asFunctionObject();
     if (!o)
         ctx->throwTypeError();
 
-    return o->call(thisArg, args.data(), args.size());
+    CALLDATA(ctx->argumentCount ? ctx->argumentCount - 1 : 0);
+    if (ctx->argumentCount)
+        qCopy(ctx->arguments + 1,
+              ctx->arguments + ctx->argumentCount, d.args);
+    d.thisObject = thisArg;
+    return o->call(d);
 }
 
 Value FunctionPrototype::method_bind(SimpleCallContext *ctx)
@@ -368,7 +368,7 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
     }
 }
 
-Value ScriptFunction::construct(Managed *that, Value *args, int argc)
+Value ScriptFunction::construct(Managed *that, const CallData &d)
 {
     ScriptFunction *f = static_cast<ScriptFunction *>(that);
     ExecutionEngine *v4 = f->engine();
@@ -378,7 +378,9 @@ Value ScriptFunction::construct(Managed *that, Value *args, int argc)
         obj->prototype = proto.objectValue();
 
     ExecutionContext *context = v4->current;
-    ExecutionContext *ctx = context->newCallContext(f, Value::fromObject(obj), args, argc);
+    CallData dd = d;
+    dd.thisObject = Value::fromObject(obj);
+    ExecutionContext *ctx = context->newCallContext(f, dd);
 
     Value result;
     try {
@@ -394,18 +396,18 @@ Value ScriptFunction::construct(Managed *that, Value *args, int argc)
     return Value::fromObject(obj);
 }
 
-Value ScriptFunction::call(Managed *that, const Value &thisObject, Value *args, int argc)
+Value ScriptFunction::call(Managed *that, const CallData &d)
 {
     ScriptFunction *f = static_cast<ScriptFunction *>(that);
     void *stackSpace;
     ExecutionContext *context = f->engine()->current;
-    ExecutionContext *ctx = context->newCallContext(f, thisObject, args, argc);
+    ExecutionContext *ctx = context->newCallContext(f, d);
 
-    if (!f->strictMode && !thisObject.isObject()) {
-        if (thisObject.isUndefined() || thisObject.isNull()) {
+    if (!f->strictMode && !d.thisObject.isObject()) {
+        if (d.thisObject.isUndefined() || d.thisObject.isNull()) {
             ctx->thisObject = Value::fromObject(f->engine()->globalObject);
         } else {
-            ctx->thisObject = Value::fromObject(thisObject.toObject(context));
+            ctx->thisObject = Value::fromObject(d.thisObject.toObject(context));
         }
     }
 
@@ -460,7 +462,7 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu
     }
 }
 
-Value SimpleScriptFunction::construct(Managed *that, Value *args, int argc)
+Value SimpleScriptFunction::construct(Managed *that, const CallData &d)
 {
     SimpleScriptFunction *f = static_cast<SimpleScriptFunction *>(that);
     ExecutionEngine *v4 = f->engine();
@@ -471,7 +473,9 @@ Value SimpleScriptFunction::construct(Managed *that, Value *args, int argc)
 
     ExecutionContext *context = v4->current;
     void *stackSpace = alloca(requiredMemoryForExecutionContectSimple(f));
-    ExecutionContext *ctx = context->newCallContext(stackSpace, f, Value::fromObject(obj), args, argc);
+    CallData dd = d;
+    dd.thisObject = Value::fromObject(obj);
+    ExecutionContext *ctx = context->newCallContext(stackSpace, f, dd);
 
     Value result;
     try {
@@ -487,18 +491,18 @@ Value SimpleScriptFunction::construct(Managed *that, Value *args, int argc)
     return Value::fromObject(obj);
 }
 
-Value SimpleScriptFunction::call(Managed *that, const Value &thisObject, Value *args, int argc)
+Value SimpleScriptFunction::call(Managed *that, const CallData &d)
 {
     SimpleScriptFunction *f = static_cast<SimpleScriptFunction *>(that);
     void *stackSpace = alloca(requiredMemoryForExecutionContectSimple(f));
     ExecutionContext *context = f->engine()->current;
-    ExecutionContext *ctx = context->newCallContext(stackSpace, f, thisObject, args, argc);
+    ExecutionContext *ctx = context->newCallContext(stackSpace, f, d);
 
-    if (!f->strictMode && !thisObject.isObject()) {
-        if (thisObject.isUndefined() || thisObject.isNull()) {
+    if (!f->strictMode && !d.thisObject.isObject()) {
+        if (d.thisObject.isUndefined() || d.thisObject.isNull()) {
             ctx->thisObject = Value::fromObject(f->engine()->globalObject);
         } else {
-            ctx->thisObject = Value::fromObject(thisObject.toObject(context));
+            ctx->thisObject = Value::fromObject(d.thisObject.toObject(context));
         }
     }
 
@@ -526,13 +530,13 @@ BuiltinFunctionOld::BuiltinFunctionOld(ExecutionContext *scope, String *name, Va
     isBuiltinFunction = true;
 }
 
-Value BuiltinFunctionOld::construct(Managed *f, Value *, int)
+Value BuiltinFunctionOld::construct(Managed *f, const CallData &d)
 {
     f->engine()->current->throwTypeError();
     return Value::undefinedValue();
 }
 
-Value BuiltinFunctionOld::call(Managed *that, const Value &thisObject, Value *args, int argc)
+Value BuiltinFunctionOld::call(Managed *that, const CallData &d)
 {
     BuiltinFunctionOld *f = static_cast<BuiltinFunctionOld *>(that);
     ExecutionEngine *v4 = f->engine();
@@ -541,9 +545,9 @@ Value BuiltinFunctionOld::call(Managed *that, const Value &thisObject, Value *ar
     SimpleCallContext ctx;
     ctx.initSimpleCallContext(f->scope->engine);
     ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context?
-    ctx.thisObject = thisObject;
-    ctx.arguments = args;
-    ctx.argumentCount = argc;
+    ctx.thisObject = d.thisObject;
+    ctx.arguments = d.args;
+    ctx.argumentCount = d.argc;
     v4->pushContext(&ctx);
 
     Value result;
@@ -558,7 +562,7 @@ Value BuiltinFunctionOld::call(Managed *that, const Value &thisObject, Value *ar
     return result;
 }
 
-Value IndexedBuiltinFunction::call(Managed *that, const Value &thisObject, Value *args, int argc)
+Value IndexedBuiltinFunction::call(Managed *that, const CallData &d)
 {
     IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that);
     ExecutionEngine *v4 = f->engine();
@@ -567,9 +571,9 @@ Value IndexedBuiltinFunction::call(Managed *that, const Value &thisObject, Value
     SimpleCallContext ctx;
     ctx.initSimpleCallContext(f->scope->engine);
     ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context?
-    ctx.thisObject = thisObject;
-    ctx.arguments = args;
-    ctx.argumentCount = argc;
+    ctx.thisObject = d.thisObject;
+    ctx.arguments = d.args;
+    ctx.argumentCount = d.argc;
     v4->pushContext(&ctx);
 
     Value result;
@@ -612,24 +616,24 @@ void BoundFunction::destroy(Managed *that)
     static_cast<BoundFunction *>(that)->~BoundFunction();
 }
 
-Value BoundFunction::call(Managed *that, const Value &, Value *args, int argc)
+Value BoundFunction::call(Managed *that, const CallData &dd)
 {
     BoundFunction *f = static_cast<BoundFunction *>(that);
-    Value *newArgs = static_cast<Value *>(alloca(sizeof(Value)*(f->boundArgs.size() + argc)));
-    memcpy(newArgs, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
-    memcpy(newArgs + f->boundArgs.size(), args, argc*sizeof(Value));
 
-    return f->target->call(f->boundThis, newArgs, f->boundArgs.size() + argc);
+    CALLDATA(f->boundArgs.size() + dd.argc);
+    d.thisObject = f->boundThis;
+    memcpy(d.args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
+    memcpy(d.args + f->boundArgs.size(), dd.args, dd.argc*sizeof(Value));
+    return f->target->call(d);
 }
 
-Value BoundFunction::construct(Managed *that, Value *args, int argc)
+Value BoundFunction::construct(Managed *that, const CallData &dd)
 {
     BoundFunction *f = static_cast<BoundFunction *>(that);
-    Value *newArgs = static_cast<Value *>(alloca(sizeof(Value)*(f->boundArgs.size() + argc)));
-    memcpy(newArgs, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
-    memcpy(newArgs + f->boundArgs.size(), args, argc*sizeof(Value));
-
-    return f->target->construct(newArgs, f->boundArgs.size() + argc);
+    CALLDATA(f->boundArgs.size() + dd.argc);
+    memcpy(d.args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
+    memcpy(d.args + f->boundArgs.size(), dd.args, dd.argc*sizeof(Value));
+    return f->target->construct(d);
 }
 
 bool BoundFunction::hasInstance(Managed *that, const Value &value)
index 89e2b14..fdfb1e6 100644 (file)
@@ -112,13 +112,13 @@ struct Q_QML_EXPORT FunctionObject: Object {
 
     Value newInstance();
 
-    static Value construct(Managed *that, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
-    inline Value construct(Value *args, int argc) {
-        return vtbl->construct(this, args, argc);
+    static Value construct(Managed *that, const CallData &);
+    static Value call(Managed *that, const CallData &d);
+    inline Value construct(const CallData &d) {
+        return vtbl->construct(this, d);
     }
-    inline Value call(const Value &thisObject, Value *args, int argc) {
-        return vtbl->call(this, thisObject, args, argc);
+    inline Value call(const CallData &d) {
+        return vtbl->call(this, d);
     }
 
     static FunctionObject *creatScriptFunction(ExecutionContext *scope, Function *function);
@@ -135,8 +135,8 @@ struct FunctionCtor: FunctionObject
 {
     FunctionCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *that, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *that, const CallData &);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -158,8 +158,8 @@ struct BuiltinFunctionOld: FunctionObject {
 
     BuiltinFunctionOld(ExecutionContext *scope, String *name, Value (*code)(SimpleCallContext *));
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -181,21 +181,21 @@ struct IndexedBuiltinFunction: FunctionObject
         isBuiltinFunction = true;
     }
 
-    static Value construct(Managed *m, Value *, int)
+    static Value construct(Managed *m, const CallData &)
     {
         m->engine()->current->throwTypeError();
         return Value::undefinedValue();
     }
 
-    static Value call(Managed *that, const Value &thisObject, Value *args, int argc);
+    static Value call(Managed *that, const CallData &d);
 };
 
 
 struct ScriptFunction: FunctionObject {
     ScriptFunction(ExecutionContext *scope, Function *function);
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -204,8 +204,8 @@ protected:
 struct SimpleScriptFunction: FunctionObject {
     SimpleScriptFunction(ExecutionContext *scope, Function *function);
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -220,8 +220,8 @@ struct BoundFunction: FunctionObject {
     ~BoundFunction() {}
 
 
-    static Value construct(Managed *, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
     static const ManagedVTable static_vtbl;
     static void destroy(Managed *);
index 53d43db..3b06a6d 100644 (file)
@@ -390,7 +390,9 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
 
     if (strictMode) {
         FunctionObject *e = FunctionObject::creatScriptFunction(ctx, function);
-        return e->call(ctx->thisObject, 0, 0);
+        CALLDATA(0);
+        d.thisObject = ctx->thisObject;
+        return e->call(d);
     }
 
     ExecutionContext::EvalCode evalCode;
@@ -436,10 +438,10 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
 }
 
 
-Value EvalFunction::call(Managed *that, const Value &thisObject, Value *args, int argc)
+Value EvalFunction::call(Managed *that, const CallData &d)
 {
     // indirect call
-    return static_cast<EvalFunction *>(that)->evalCall(thisObject, args, argc, false);
+    return static_cast<EvalFunction *>(that)->evalCall(d.thisObject, d.args, d.argc, false);
 }
 
 
index 11d034b..4ac531c 100644 (file)
@@ -55,7 +55,7 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject
     Value evalCall(Value thisObject, Value *args, int argc, bool directCall);
 
     using Managed::construct;
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 4fd7bb1..9068d57 100644 (file)
@@ -102,10 +102,12 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
     if (!f)
         return;
 
-    QV4::Value args[] = { status };
     QV4::ExecutionContext *ctx = f->engine()->current;
     try {
-        f->call(QV4::Value::fromObject(f->engine()->globalObject), args, 1);
+        CALLDATA(1);
+        d.thisObject = QV4::Value::fromObject(f->engine()->globalObject);
+        d.args[0] = status;
+        f->call(d);
     } catch (QV4::Exception &e) {
         e.accept(ctx);
     }
index e5a8582..68a4c5c 100644 (file)
@@ -702,8 +702,10 @@ QString Stringify::Str(const QString &key, Value value)
     if (Object *o = value.asObject()) {
         FunctionObject *toJSON = o->get(ctx->engine->newString(QStringLiteral("toJSON"))).asFunctionObject();
         if (toJSON) {
-            Value arg = Value::fromString(ctx, key);
-            value = toJSON->call(value, &arg, 1);
+            CALLDATA(1);
+            d.thisObject = value;
+            d.args[0] = Value::fromString(ctx, key);
+            value = toJSON->call(d);
         }
     }
 
@@ -711,10 +713,11 @@ QString Stringify::Str(const QString &key, Value value)
         Object *holder = ctx->engine->newObject();
         Value holderValue = Value::fromObject(holder);
         holder->put(ctx, QString(), value);
-        Value args[2];
-        args[0] = Value::fromString(ctx, key);
-        args[1] = value;
-        value = replacerFunction->call(holderValue, args, 2);
+        CALLDATA(2);
+        d.args[0] = Value::fromString(ctx, key);
+        d.args[1] = value;
+        d.thisObject = holderValue;
+        value = replacerFunction->call(d);
     }
 
     if (Object *o = value.asObject()) {
index 345611d..b7a6f73 100644 (file)
@@ -157,10 +157,13 @@ void Lookup::getterAccessor0(Lookup *l, Value *result, const Value &object)
         if (l->classList[0] == o->internalClass) {
             Value res;
             FunctionObject *getter = o->memberData[l->index].getter();
-            if (!getter)
+            if (!getter) {
                 res = Value::undefinedValue();
-            else
-                res = getter->call(object, 0, 0);
+            } else {
+                CALLDATA(0);
+                d.thisObject = object;
+                res = getter->call(d);
+            }
             if (result)
                 *result = res;
             return;
@@ -177,10 +180,13 @@ void Lookup::getterAccessor1(Lookup *l, Value *result, const Value &object)
             l->classList[1] == o->prototype->internalClass) {
             Value res;
             FunctionObject *getter = o->prototype->memberData[l->index].getter();
-            if (!getter)
+            if (!getter) {
                 res = Value::undefinedValue();
-            else
-                res = getter->call(object, 0, 0);
+            } else {
+                CALLDATA(0);
+                d.thisObject = object;
+                res = getter->call(d);
+            }
             if (result)
                 *result = res;
             return;
@@ -200,10 +206,13 @@ void Lookup::getterAccessor2(Lookup *l, Value *result, const Value &object)
                 if (l->classList[2] == o->internalClass) {
                     Value res;
                     FunctionObject *getter = o->memberData[l->index].getter();
-                    if (!getter)
+                    if (!getter) {
                         res = Value::undefinedValue();
-                    else
-                        res = getter->call(object, 0, 0);
+                    } else {
+                        CALLDATA(0);
+                        d.thisObject = object;
+                        res = getter->call(d);
+                    }
                     if (result)
                         *result = res;
                     return;
@@ -292,10 +301,13 @@ void Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx, Value *resu
     Object *o = ctx->engine->globalObject;
     if (l->classList[0] == o->internalClass) {
         FunctionObject *getter = o->memberData[l->index].getter();
-        if (!getter)
+        if (!getter) {
             *result = Value::undefinedValue();
-        else
-            *result = getter->call(Value::undefinedValue(), 0, 0);
+        } else {
+            CALLDATA(0);
+            d.thisObject = Value::undefinedValue();
+            *result = getter->call(d);
+        }
         return;
     }
     l->globalGetter = globalGetterGeneric;
@@ -308,10 +320,13 @@ void Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx, Value *resu
     if (l->classList[0] == o->internalClass &&
         l->classList[1] == o->prototype->internalClass) {
         FunctionObject *getter = o->prototype->memberData[l->index].getter();
-        if (!getter)
+        if (!getter) {
             *result = Value::undefinedValue();
-        else
-            *result = getter->call(Value::undefinedValue(), 0, 0);
+        } else {
+            CALLDATA(0);
+            d.thisObject = Value::undefinedValue();
+            *result = getter->call(d);
+        }
         return;
     }
     l->globalGetter = globalGetterGeneric;
@@ -327,10 +342,13 @@ void Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx, Value *resu
             o = o->prototype;
             if (l->classList[2] == o->internalClass) {
                 FunctionObject *getter = o->memberData[l->index].getter();
-                if (!getter)
+                if (!getter) {
                     *result = Value::undefinedValue();
-                else
-                    *result = getter->call(Value::undefinedValue(), 0, 0);
+                } else {
+                    CALLDATA(0);
+                    d.thisObject = Value::undefinedValue();
+                    *result = getter->call(d);
+                }
                 return;
             }
         }
index 19adb35..955d12a 100644 (file)
@@ -176,12 +176,12 @@ bool Managed::hasInstance(Managed *m, const Value &)
     m->engine()->current->throwTypeError();
 }
 
-Value Managed::construct(Managed *m, Value *, int)
+Value Managed::construct(Managed *m, const CallData &)
 {
     m->engine()->current->throwTypeError();
 }
 
-Value Managed::call(Managed *m, const Value &, Value *, int)
+Value Managed::call(Managed *m, const CallData &)
 {
     m->engine()->current->throwTypeError();
 }
index 227cd4b..b77b1cd 100644 (file)
@@ -74,10 +74,30 @@ struct GCDeletable
     bool lastCall;
 };
 
+struct CallData
+{
+    Value thisObject;
+    Value *args;
+    int argc;
+};
+
+#ifdef QT_NO_DEBUG
+#define CALLDATA(argc_) \
+    QV4::CallData d; \
+    d.argc = argc_; \
+    d.args = (QV4::Value *)alloca(qMax((int)(argc_), (int)QV4::Global::ReservedArgumentCount)*sizeof(QV4::Value))
+#else
+#define CALLDATA(argc_) \
+    QV4::CallData d; \
+    d.argc = argc_; \
+    d.args = (QV4::Value *)alloca(qMax((int)(argc_), (int)QV4::Global::ReservedArgumentCount)*sizeof(QV4::Value)); \
+    for (int iii = 0; iii < qMax((int)(argc_), (int)QV4::Global::ReservedArgumentCount); ++iii) d.args[iii] = QV4::Value::undefinedValue()
+#endif
+
 struct ManagedVTable
 {
-    Value (*call)(Managed *, const Value &thisObject, Value *args, int argc);
-    Value (*construct)(Managed *, Value *args, int argc);
+    Value (*call)(Managed *, const CallData &data);
+    Value (*construct)(Managed *, const CallData &data);
     void (*markObjects)(Managed *);
     void (*destroy)(Managed *);
     void (*collectDeletables)(Managed *, GCDeletable **deletable);
@@ -237,8 +257,8 @@ public:
     inline bool hasInstance(const Value &v) {
         return vtbl->hasInstance(this, v);
     }
-    Value construct(Value *args, int argc);
-    Value call(const Value &thisObject, Value *args, int argc);
+    Value construct(const CallData &d);
+    Value call(const CallData &d);
     Value get(String *name, bool *hasProperty = 0);
     Value getIndexed(uint index, bool *hasProperty = 0);
     void put(String *name, const Value &value)
@@ -266,8 +286,8 @@ public:
 
     static void destroy(Managed *that) { that->_data = 0; }
     static bool hasInstance(Managed *that, const Value &value);
-    static Value construct(Managed *m, Value *, int);
-    static Value call(Managed *m, const Value &, Value *, int);
+    static Value construct(Managed *m, const CallData &d);
+    static Value call(Managed *m, const CallData &);
     static void getLookup(Managed *m, Lookup *, Value *);
     static void setLookup(Managed *m, Lookup *l, const Value &v);
     static bool isEqualTo(Managed *m, Managed *other);
index 6d3b622..88c6148 100644 (file)
@@ -56,16 +56,16 @@ NumberCtor::NumberCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value NumberCtor::construct(Managed *m, Value *args, int argc)
+Value NumberCtor::construct(Managed *m, const CallData &d)
 {
-    double d = argc ? args[0].toNumber() : 0.;
-    return Value::fromObject(m->engine()->newNumberObject(Value::fromDouble(d)));
+    double dbl = d.argc ? d.args[0].toNumber() : 0.;
+    return Value::fromObject(m->engine()->newNumberObject(Value::fromDouble(dbl)));
 }
 
-Value NumberCtor::call(Managed *, const Value &, Value *argv, int argc)
+Value NumberCtor::call(Managed *, const CallData &d)
 {
-    double d = argc ? argv[0].toNumber() : 0.;
-    return Value::fromDouble(d);
+    double dbl = d.argc ? d.args[0].toNumber() : 0.;
+    return Value::fromDouble(dbl);
 }
 
 void NumberPrototype::init(ExecutionContext *ctx, const Value &ctor)
index 0c06451..224840e 100644 (file)
@@ -53,8 +53,8 @@ struct NumberCtor: FunctionObject
 {
     NumberCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *that, Value *args, int argc);
-    static Value call(Managed *, const Value &, Value *, int);
+    static Value construct(Managed *that, const CallData &d);
+    static Value call(Managed *, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 01be2d7..ab33764 100644 (file)
@@ -135,16 +135,19 @@ Value Object::getValue(const Value &thisObject, const Property *p, PropertyAttri
     if (!getter)
         return Value::undefinedValue();
 
-    return getter->call(thisObject, 0, 0);
+    CALLDATA(0);
+    d.thisObject = thisObject;
+    return getter->call(d);
 }
 
 void Object::putValue(Property *pd, PropertyAttributes attrs, const Value &value)
 {
     if (attrs.isAccessor()) {
         if (pd->set) {
-            Value args[1];
-            args[0] = value;
-            pd->set->call(Value::fromObject(this), args, 1);
+            CALLDATA(1);
+            d.args[0] = value;
+            d.thisObject = Value::fromObject(this);
+            pd->set->call(d);
             return;
         }
         goto reject;
@@ -773,9 +776,10 @@ void Object::internalPut(String *name, const Value &value)
     if (pd && attrs.isAccessor()) {
         assert(pd->setter() != 0);
 
-        Value args[1];
-        args[0] = value;
-        pd->setter()->call(Value::fromObject(this), args, 1);
+        CALLDATA(1);
+        d.args[0] = value;
+        d.thisObject = Value::fromObject(this);
+        pd->setter()->call(d);
         return;
     }
 
@@ -850,9 +854,10 @@ void Object::internalPutIndexed(uint index, const Value &value)
     if (pd && attrs.isAccessor()) {
         assert(pd->setter() != 0);
 
-        Value args[1];
-        args[0] = value;
-        pd->setter()->call(Value::fromObject(this), args, 1);
+        CALLDATA(1);
+        d.args[0] = value;
+        d.thisObject = Value::fromObject(this);
+        pd->setter()->call(d);
         return;
     }
 
index add2686..ec60a9b 100644 (file)
@@ -78,25 +78,25 @@ ObjectCtor::ObjectCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value ObjectCtor::construct(Managed *that, Value *args, int argc)
+Value ObjectCtor::construct(Managed *that, const CallData &d)
 {
     ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
     ExecutionEngine *v4 = that->engine();
-    if (!argc || args[0].isUndefined() || args[0].isNull()) {
+    if (!d.argc || d.args[0].isUndefined() || d.args[0].isNull()) {
         Object *obj = v4->newObject();
         Value proto = ctor->get(v4->id_prototype);
         if (proto.isObject())
             obj->prototype = proto.objectValue();
         return Value::fromObject(obj);
     }
-    return __qmljs_to_object(v4->current, args[0]);
+    return __qmljs_to_object(v4->current, d.args[0]);
 }
 
-Value ObjectCtor::call(Managed *m, const Value &/*thisObject*/, Value *args, int argc)
+Value ObjectCtor::call(Managed *m, const CallData &d)
 {
-    if (!argc || args[0].isUndefined() || args[0].isNull())
+    if (!d.argc || d.args[0].isUndefined() || d.args[0].isNull())
         return Value::fromObject(m->engine()->newObject());
-    return __qmljs_to_object(m->engine()->current, args[0]);
+    return __qmljs_to_object(m->engine()->current, d.args[0]);
 }
 
 void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor)
@@ -385,7 +385,9 @@ Value ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx)
     FunctionObject *f = ts.asFunctionObject();
     if (!f)
         ctx->throwTypeError();
-    return f->call(Value::fromObject(o), 0, 0);
+    CALLDATA(0);
+    d.thisObject = Value::fromObject(o);
+    return f->call(d);
 }
 
 Value ObjectPrototype::method_valueOf(SimpleCallContext *ctx)
index ca2e77c..afa0ce0 100644 (file)
@@ -53,8 +53,8 @@ struct ObjectCtor: FunctionObject
 {
     ObjectCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *that, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *that, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index f796758..7041348 100644 (file)
@@ -701,18 +701,19 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
             QV4::ExecutionEngine *v4 = f->internalClass->engine;
             QV4::ExecutionContext *ctx = v4->current;
 
-            QVarLengthArray<QV4::Value, 9> args(argCount);
+            CALLDATA(argCount);
+            d.thisObject = This->thisObject.isEmpty() ?  Value::fromObject(v4->globalObject) : This->thisObject.value();
             for (int ii = 0; ii < argCount; ++ii) {
                 int type = argsTypes[ii + 1];
                 if (type == qMetaTypeId<QVariant>()) {
-                    args[ii] = v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1]));
+                    d.args[ii] = v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1]));
                 } else {
-                    args[ii] = v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1]));
+                    d.args[ii] = v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1]));
                 }
             }
 
             try {
-                f->call(This->thisObject.isEmpty() ?  Value::fromObject(v4->globalObject) : This->thisObject.value(), args.data(), argCount);
+                f->call(d);
             } catch (QV4::Exception &e) {
                 e.accept(ctx);
                 QQmlError error;
@@ -1686,17 +1687,17 @@ QV4::Value QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, Value *args
     return QV4::Value::undefinedValue();
 }
 
-Value QObjectMethod::call(Managed *m, const Value &thisObject, Value *args, int argc)
+Value QObjectMethod::call(Managed *m, const CallData &d)
 {
     QObjectMethod *This = static_cast<QObjectMethod*>(m);
-    return This->callInternal(thisObject, args, argc);
+    return This->callInternal(d);
 }
 
-Value QObjectMethod::callInternal(const Value &, Value *args, int argc)
+Value QObjectMethod::callInternal(const CallData &d)
 {
     ExecutionContext *context = engine()->current;
     if (m_index == DestroyMethod)
-        return method_destroy(context, args, argc);
+        return method_destroy(context, d.args, d.argc);
     else if (m_index == ToStringMethod)
         return method_toString(context);
 
@@ -1731,7 +1732,7 @@ Value QObjectMethod::callInternal(const Value &, Value *args, int argc)
     if (method.isV4Function()) {
         QV4::Value rv = QV4::Value::undefinedValue();
 
-        QQmlV4Function func(argc, args, &rv, m_qmlGlobal.value(),
+        QQmlV4Function func(d.argc, d.args, &rv, m_qmlGlobal.value(),
                             QmlContextWrapper::getContext(m_qmlGlobal.value()),
                             v8Engine);
         QQmlV4Function *funcptr = &func;
@@ -1742,7 +1743,7 @@ Value QObjectMethod::callInternal(const Value &, Value *args, int argc)
         return rv;
     }
 
-    CallArgs callArgs(argc, args);
+    CallArgs callArgs(d.argc, d.args);
     if (!method.isOverload()) {
         return CallPrecise(object, method, v8Engine, callArgs);
     } else {
index 6580d19..39af02f 100644 (file)
@@ -141,9 +141,9 @@ private:
     int m_index;
     QV4::PersistentValue m_qmlGlobal;
 
-    static Value call(Managed *, const Value &thisObject, Value *args, int argc);
+    static Value call(Managed *, const CallData &d);
 
-    Value callInternal(const Value &, Value *args, int argc);
+    Value callInternal(const CallData &d);
 
     static void destroy(Managed *that)
     {
index 0dc14e5..16b23e2 100644 (file)
@@ -220,10 +220,10 @@ RegExpCtor::RegExpCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value RegExpCtor::construct(Managed *m, Value *argv, int argc)
+Value RegExpCtor::construct(Managed *m, const CallData &d)
 {
-    Value r = argc > 0 ? argv[0] : Value::undefinedValue();
-    Value f = argc > 1 ? argv[1] : Value::undefinedValue();
+    Value r = d.argc > 0 ? d.args[0] : Value::undefinedValue();
+    Value f = d.argc > 1 ? d.args[1] : Value::undefinedValue();
     ExecutionContext *ctx = m->engine()->current;
     if (RegExpObject *re = r.as<RegExpObject>()) {
         if (!f.isUndefined())
@@ -264,14 +264,14 @@ Value RegExpCtor::construct(Managed *m, Value *argv, int argc)
     return Value::fromObject(o);
 }
 
-Value RegExpCtor::call(Managed *that, const Value &, Value *argv, int argc)
+Value RegExpCtor::call(Managed *that, const CallData &d)
 {
-    if (argc > 0 && argv[0].as<RegExpObject>()) {
-        if (argc == 1 || argv[1].isUndefined())
-            return argv[0];
+    if (d.argc > 0 && d.args[0].as<RegExpObject>()) {
+        if (d.argc == 1 || d.args[1].isUndefined())
+            return d.args[0];
     }
 
-    return construct(that, argv, argc);
+    return construct(that, d);
 }
 
 void RegExpPrototype::init(ExecutionContext *ctx, const Value &ctor)
@@ -349,7 +349,10 @@ Value RegExpPrototype::method_compile(SimpleCallContext *ctx)
     if (!r)
         ctx->throwTypeError();
 
-    RegExpObject *re = ctx->engine->regExpCtor.asFunctionObject()->construct(ctx->arguments, ctx->argumentCount).as<RegExpObject>();
+    CallData d;
+    d.args = ctx->arguments;
+    d.argc = ctx->argumentCount;
+    RegExpObject *re = ctx->engine->regExpCtor.asFunctionObject()->construct(d).as<RegExpObject>();
 
     r->value = re->value;
     r->global = re->global;
index 0b9b712..2179dbd 100644 (file)
@@ -98,8 +98,8 @@ struct RegExpCtor: FunctionObject
 {
     RegExpCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *m, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 8d28979..f145050 100644 (file)
@@ -446,14 +446,18 @@ Value __qmljs_object_default_value(Object *object, int typeHint)
 
     Value conv = object->get(meth1);
     if (FunctionObject *o = conv.asFunctionObject()) {
-        Value r = o->call(Value::fromObject(object), 0, 0);
+        CALLDATA(0);
+        d.thisObject = Value::fromObject(object);
+        Value r = o->call(d);
         if (r.isPrimitive())
             return r;
     }
 
     conv = object->get(meth2);
     if (FunctionObject *o = conv.asFunctionObject()) {
-        Value r = o->call(Value::fromObject(object), 0, 0);
+        CALLDATA(0);
+        d.thisObject = Value::fromObject(object);
+        Value r = o->call(d);
         if (r.isPrimitive())
             return r;
     }
@@ -600,9 +604,10 @@ void __qmljs_set_element(ExecutionContext *ctx, const Value &object, const Value
                     return;
                 }
 
-                Value args[1];
-                args[0] = value;
-                setter->call(Value::fromObject(o), args, 1);
+                CALLDATA(1);
+                d.args[0] = value;
+                d.thisObject = Value::fromObject(o);
+                setter->call(d);
                 return;
             }
         }
@@ -730,7 +735,11 @@ void __qmljs_call_global_lookup(ExecutionContext *context, Value *result, uint i
         return;
     }
 
-    Value res = o->call(thisObject, args, argc);
+    CallData d;
+    d.thisObject = thisObject;
+    d.args = args;
+    d.argc = argc;
+    Value res = o->call(d);
     if (result)
         *result = res;
 }
@@ -758,7 +767,11 @@ void __qmljs_call_activation_property(ExecutionContext *context, Value *result,
         return;
     }
 
-    Value res = o->call(thisObject, args, argc);
+    CallData d;
+    d.thisObject = thisObject;
+    d.args = args;
+    d.argc = argc;
+    Value res = o->call(d);
     if (result)
         *result = res;
 }
@@ -784,7 +797,11 @@ void __qmljs_call_property(ExecutionContext *context, Value *result, const Value
         context->throwTypeError(error);
     }
 
-    Value res = o->call(thisObject, args, argc);
+    CallData d;
+    d.thisObject = thisObject;
+    d.args = args;
+    d.argc = argc;
+    Value res = o->call(d);
     if (result)
         *result = res;
 }
@@ -807,7 +824,11 @@ void __qmljs_call_property_lookup(ExecutionContext *context, Value *result, cons
     if (!o)
         context->throwTypeError();
 
-    Value res = o->call(thisObject, args, argc);
+    CallData d;
+    d.thisObject = thisObject;
+    d.args = args;
+    d.argc = argc;
+    Value res = o->call(d);
     if (result)
         *result = res;
 }
@@ -822,7 +843,11 @@ void __qmljs_call_element(ExecutionContext *context, Value *result, const Value
     if (!o)
         context->throwTypeError();
 
-    Value res = o->call(thisObject, args, argc);
+    CallData d;
+    d.thisObject = thisObject;
+    d.args = args;
+    d.argc = argc;
+    Value res = o->call(d);
     if (result)
         *result = res;
 }
@@ -832,7 +857,11 @@ void __qmljs_call_value(ExecutionContext *context, Value *result, const Value *t
     Object *o = func.asObject();
     if (!o)
         context->throwTypeError();
-    Value res = o->call(thisObject ? *thisObject : Value::undefinedValue(), args, argc);
+    CallData d;
+    d.thisObject = thisObject ? *thisObject : Value::undefinedValue();
+    d.args = args;
+    d.argc = argc;
+    Value res = o->call(d);
     if (result)
         *result = res;
 }
@@ -845,7 +874,10 @@ void __qmljs_construct_global_lookup(ExecutionContext *context, Value *result, u
     l->globalGetter(l, context, &func);
 
     if (Object *f = func.asObject()) {
-        Value res = f->construct(args, argc);
+        CallData d;
+        d.args = args;
+        d.argc = argc;
+        Value res = f->construct(d);
         if (result)
             *result = res;
         return;
@@ -864,7 +896,10 @@ void __qmljs_construct_activation_property(ExecutionContext *context, Value *res
 void __qmljs_construct_value(ExecutionContext *context, Value *result, const Value &func, Value *args, int argc)
 {
     if (Object *f = func.asObject()) {
-        Value res = f->construct(args, argc);
+        CallData d;
+        d.args = args;
+        d.argc = argc;
+        Value res = f->construct(d);
         if (result)
             *result = res;
         return;
@@ -879,7 +914,10 @@ void __qmljs_construct_property(ExecutionContext *context, Value *result, const
 
     Value func = thisObject->get(name);
     if (Object *f = func.asObject()) {
-        Value res = f->construct(args, argc);
+        CallData d;
+        d.args = args;
+        d.argc = argc;
+        Value res = f->construct(d);
         if (result)
             *result = res;
         return;
index 80cca83..17bd9b5 100644 (file)
@@ -78,7 +78,7 @@ struct QmlBindingWrapper : FunctionObject
         scope->engine->popContext();
     }
 
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value call(Managed *that, const CallData &);
     static void markObjects(Managed *m)
     {
         QmlBindingWrapper *wrapper = static_cast<QmlBindingWrapper*>(m);
@@ -121,7 +121,7 @@ struct CompilationUnitHolder : public QV4::Object
 
 DEFINE_MANAGED_VTABLE(CompilationUnitHolder);
 
-Value QmlBindingWrapper::call(Managed *that, const Value &, Value *, int)
+Value QmlBindingWrapper::call(Managed *that, const CallData &)
 {
     ExecutionEngine *engine = that->engine();
     QmlBindingWrapper *This = static_cast<QmlBindingWrapper *>(that);
@@ -247,7 +247,9 @@ Value Script::run()
 
     } else {
         FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject());
-        return f->call(Value::undefinedValue(), 0, 0);
+        CALLDATA(0);
+        d.thisObject = Value::undefinedValue();
+        return f->call(d);
     }
 }
 
index c248c9c..1d5c271 100644 (file)
@@ -353,11 +353,11 @@ public:
         bool operator()(typename Container::value_type lhs, typename Container::value_type rhs)
         {
             QV4::Managed *fun = this->m_compareFn.asManaged();
-            QV4::Value argv[2] = {
-                convertElementToValue(this->m_ctx->engine, lhs),
-                convertElementToValue(this->m_ctx->engine, rhs)
-            };
-            QV4::Value result = fun->call(QV4::Value::fromObject(this->m_ctx->engine->globalObject), argv, 2);
+            CALLDATA(2);
+            d.args[0] = convertElementToValue(this->m_ctx->engine, lhs);
+            d.args[1] = convertElementToValue(this->m_ctx->engine, rhs);
+            d.thisObject = QV4::Value::fromObject(this->m_ctx->engine->globalObject);
+            QV4::Value result = fun->call(d);
             return result.toNumber() < 0;
         }
 
index e0c6bb5..ab802ca 100644 (file)
@@ -148,21 +148,21 @@ StringCtor::StringCtor(ExecutionContext *scope)
     vtbl = &static_vtbl;
 }
 
-Value StringCtor::construct(Managed *m, Value *argv, int argc)
+Value StringCtor::construct(Managed *m, const CallData &d)
 {
     Value value;
-    if (argc)
-        value = Value::fromString(argv[0].toString(m->engine()->current));
+    if (d.argc)
+        value = Value::fromString(d.args[0].toString(m->engine()->current));
     else
         value = Value::fromString(m->engine()->current, QString());
     return Value::fromObject(m->engine()->newStringObject(value));
 }
 
-Value StringCtor::call(Managed *m, const Value &, Value *argv, int argc)
+Value StringCtor::call(Managed *m, const CallData &d)
 {
     Value value;
-    if (argc)
-        value = Value::fromString(argv[0].toString(m->engine()->current));
+    if (d.argc)
+        value = Value::fromString(d.args[0].toString(m->engine()->current));
     else
         value = Value::fromString(m->engine()->current, QString());
     return value;
@@ -340,8 +340,11 @@ Value StringPrototype::method_match(SimpleCallContext *context)
 
     Value regexp = context->argumentCount ? context->arguments[0] : Value::undefinedValue();
     RegExpObject *rx = regexp.as<RegExpObject>();
-    if (!rx)
-        rx = context->engine->regExpCtor.asFunctionObject()->construct(&regexp, 1).as<RegExpObject>();
+    if (!rx) {
+        CALLDATA(1);
+        d.args[0] = regexp;
+        rx = context->engine->regExpCtor.asFunctionObject()->construct(d).as<RegExpObject>();
+    }
 
     if (!rx)
         // ### CHECK
@@ -352,9 +355,11 @@ Value StringPrototype::method_match(SimpleCallContext *context)
     // ### use the standard builtin function, not the one that might be redefined in the proto
     FunctionObject *exec = context->engine->regExpPrototype->get(context->engine->newString(QStringLiteral("exec")), 0).asFunctionObject();
 
-    Value arg = Value::fromString(s);
+    CALLDATA(1);
+    d.thisObject = Value::fromObject(rx);
+    d.args[0] = Value::fromString(s);
     if (!global)
-        return exec->call(Value::fromObject(rx), &arg, 1);
+        return exec->call(d);
 
     String *lastIndex = context->engine->newString(QStringLiteral("lastIndex"));
     rx->put(lastIndex, Value::fromInt32(0));
@@ -363,7 +368,7 @@ Value StringPrototype::method_match(SimpleCallContext *context)
     double previousLastIndex = 0;
     uint n = 0;
     while (1) {
-        Value result = exec->call(Value::fromObject(rx), &arg, 1);
+        Value result = exec->call(d);
         if (result.isNull())
             break;
         assert(result.isObject());
@@ -477,8 +482,8 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx)
     Value replaceValue = ctx->argument(1);
     if (FunctionObject* searchCallback = replaceValue.asFunctionObject()) {
         int replacementDelta = 0;
-        int argc = numCaptures + 2;
-        Value *args = (Value*)alloca((numCaptures + 2) * sizeof(Value));
+        CALLDATA(numCaptures + 2);
+        d.thisObject = Value::undefinedValue();
         for (int i = 0; i < numStringMatches; ++i) {
             for (int k = 0; k < numCaptures; ++k) {
                 int idx = (i * numCaptures + k) * 2;
@@ -487,13 +492,14 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx)
                 Value entry = Value::undefinedValue();
                 if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
                     entry = Value::fromString(ctx, string.mid(start, end - start));
-                args[k] = entry;
+                d.args[k] = entry;
             }
             uint matchStart = matchOffsets[i * numCaptures * 2];
             uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
-            args[numCaptures] = Value::fromUInt32(matchStart);
-            args[numCaptures + 1] = Value::fromString(ctx, string);
-            Value replacement = searchCallback->call(Value::undefinedValue(), args, argc);
+            d.args[numCaptures] = Value::fromUInt32(matchStart);
+            d.args[numCaptures + 1] = Value::fromString(ctx, string);
+
+            Value replacement = searchCallback->call(d);
             QString replacementString = replacement.toString(ctx)->toQString();
             result.replace(replacementDelta + matchStart, matchEnd - matchStart, replacementString);
             replacementDelta += replacementString.length() - matchEnd + matchStart;
@@ -529,7 +535,9 @@ Value StringPrototype::method_search(SimpleCallContext *ctx)
     Value regExpValue = ctx->argument(0);
     RegExpObject *regExp = regExpValue.as<RegExpObject>();
     if (!regExp) {
-        regExpValue = ctx->engine->regExpCtor.asFunctionObject()->construct(&regExpValue, 1);
+        CALLDATA(1);
+        d.args[0] = regExpValue;
+        regExpValue = ctx->engine->regExpCtor.asFunctionObject()->construct(d);
         regExp = regExpValue.as<RegExpObject>();
     }
     uint* matchOffsets = (uint*)alloca(regExp->value->captureCount() * 2 * sizeof(uint));
index 0ef6596..cf489eb 100644 (file)
@@ -69,8 +69,8 @@ struct StringCtor: FunctionObject
 {
     StringCtor(ExecutionContext *scope);
 
-    static Value construct(Managed *m, Value *args, int argc);
-    static Value call(Managed *that, const Value &, Value *, int);
+    static Value construct(Managed *m, const CallData &d);
+    static Value call(Managed *that, const CallData &d);
 
 protected:
     static const ManagedVTable static_vtbl;
index 20b78a4..73d5d04 100644 (file)
@@ -320,11 +320,11 @@ inline ErrorObject *Value::asErrorObject() const
 }
 
 // ###
-inline Value Managed::construct(Value *args, int argc) {
-    return vtbl->construct(this, args, argc);
+inline Value Managed::construct(const CallData &d) {
+    return vtbl->construct(this, d);
 }
-inline Value Managed::call(const Value &thisObject, Value *args, int argc) {
-    return vtbl->call(this, thisObject, args, argc);
+inline Value Managed::call(const CallData &d) {
+    return vtbl->call(this, d);
 }
 
 struct Q_QML_PRIVATE_EXPORT PersistentValuePrivate
index 0c92229..08344c4 100644 (file)
@@ -183,8 +183,11 @@ void QQmlBoundSignalExpression::evaluate(void **a)
         int *argsTypes = QQmlPropertyCache::methodParameterTypes(m_target, methodIndex, dummy, 0);
         int argCount = argsTypes ? *argsTypes : 0;
 
-        QVarLengthArray<QV4::Value, 9> args(argCount);
-
+        QV4::Value *args = (QV4::Value *)alloca(qMax(argCount, (int)QV4::Global::ReservedArgumentCount)*sizeof(QV4::Value));
+#ifndef QT_NO_DEBUG
+        for (int ii = 0; ii < qMax(argCount, (int)QV4::Global::ReservedArgumentCount); ++ii)
+            args[ii] = QV4::Value::undefinedValue();
+#endif
         for (int ii = 0; ii < argCount; ++ii) {
             int type = argsTypes[ii + 1];
             //### ideally we would use metaTypeToJS, however it currently gives different results
@@ -207,7 +210,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
             }
         }
 
-        QQmlJavaScriptExpression::evaluate(context(), m_v8function.value(), argCount, args.data(), 0);
+        QQmlJavaScriptExpression::evaluate(context(), m_v8function.value(), argCount, args, 0);
     }
     ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
 }
index 8f12335..5c26f68 100644 (file)
@@ -1225,8 +1225,11 @@ void QQmlComponent::createObject(QQmlV4Function *args)
     if (!valuemap.isEmpty()) {
         QQmlComponentExtension *e = componentExtension(v8engine);
         QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject());
-        QV4::Value args[] = { object, valuemap };
-        f.asFunctionObject()->call(QV4::Value::fromObject(v4engine->globalObject), args, 2);
+        CALLDATA(2);
+        d.thisObject = QV4::Value::fromObject(v4engine->globalObject);
+        d.args[0] = object;
+        d.args[1] = valuemap;
+        f.asFunctionObject()->call(d);
     }
 
     d->completeCreate();
@@ -1369,8 +1372,11 @@ 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::Value args[] = { object, valuemap };
-        f.asFunctionObject()->call(QV4::Value::fromObject(v4engine->globalObject), args, 2);
+        CALLDATA(2);
+        d.thisObject = QV4::Value::fromObject(v4engine->globalObject);
+        d.args[0] = object;
+        d.args[1] = valuemap;
+        f.asFunctionObject()->call(d);
     }
 }
 
@@ -1465,8 +1471,11 @@ void QmlIncubatorObject::setInitialState(QObject *o)
         QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8);
 
         QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject());
-        QV4::Value args[] = { QV4::QObjectWrapper::wrap(v4, o), valuemap };
-        f.asFunctionObject()->call(QV4::Value::fromObject(v4->globalObject), args, 2);
+        CALLDATA(2);
+        d.thisObject = QV4::Value::fromObject(v4->globalObject);
+        d.args[0] = QV4::QObjectWrapper::wrap(v4, o);
+        d.args[1] = valuemap;
+        f.asFunctionObject()->call(d);
     }
 }
 
@@ -1498,9 +1507,11 @@ void QmlIncubatorObject::statusChanged(Status s)
 
     if (QV4::FunctionObject *f = callback.asFunctionObject()) {
         QV4::ExecutionContext *ctx = f->engine()->current;
-        QV4::Value args[] = { QV4::Value::fromUInt32(s) };
         try {
-            f->call(QV4::Value::fromObject(this), args, 1);
+            CALLDATA(1);
+            d.thisObject = QV4::Value::fromObject(this);
+            d.args[0] = QV4::Value::fromUInt32(s);
+            f->call(d);
         } catch (QV4::Exception &e) {
             e.accept(ctx);
             QQmlError error;
index 3b703c9..41be44a 100644 (file)
@@ -125,7 +125,8 @@ QV4::Value
 QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
                                    const QV4::Value &function, bool *isUndefined)
 {
-    return evaluate(context, function, 0, 0, isUndefined);
+    QV4::Value args[QV4::Global::ReservedArgumentCount];
+    return evaluate(context, function, 0, args, isUndefined);
 }
 
 QV4::Value
@@ -172,7 +173,11 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
                 This = value;
         }
 
-        result = function.asFunctionObject()->call(This, args, argc);
+        QV4::CallData d;
+        d.thisObject = This;
+        d.args = args;
+        d.argc = argc;
+        result = function.asFunctionObject()->call(d);
 
         if (isUndefined)
             *isUndefined = result.isUndefined();
index 327b638..3d2d54c 100644 (file)
@@ -926,15 +926,16 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
 
                 QQmlVMEMetaData::MethodData *data = metaData->methodData() + id;
 
-                QVarLengthArray<QV4::Value, 9> args(data->parameterCount);
+                CALLDATA(data->parameterCount);
+                d.thisObject = ep->v8engine()->global();
 
                 for (int ii = 0; ii < data->parameterCount; ++ii)
-                    args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]);
+                    d.args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]);
 
                 QV4::Value result = QV4::Value::undefinedValue();
                 QV4::ExecutionContext *ctx = function->engine()->current;
                 try {
-                    result = function->call(ep->v8engine()->global(), args.data(), data->parameterCount);
+                    result = function->call(d);
                     if (a[0]) *(QVariant *)a[0] = ep->v8engine()->toVariant(result, 0);
                 } catch (QV4::Exception &e) {
                     e.accept(ctx);
index fb6733e..5045d70 100644 (file)
@@ -1482,8 +1482,11 @@ void QQmlXMLHttpRequest::dispatchCallback(const Value &me)
             v4->current->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject"));
 
         QQmlContextData *callingContext = QmlContextWrapper::getContext(activationObject);
-        if (callingContext)
-            callback->call(activationObject, 0, 0);
+        if (callingContext) {
+            CALLDATA(0);
+            d.thisObject = activationObject;
+            callback->call(d);
+        }
 
         // if the callingContext object is no longer valid, then it has been
         // deleted explicitly (e.g., by a Loader deleting the itemContext when
@@ -1562,7 +1565,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
         if (c->proto)
             c->proto->mark();
     }
-    static Value construct(Managed *that, Value *, int)
+    static Value construct(Managed *that, const QV4::CallData &)
     {
         QQmlXMLHttpRequestCtor *ctor = that->as<QQmlXMLHttpRequestCtor>();
         if (!ctor)
@@ -1575,7 +1578,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
         return Value::fromObject(w);
     }
 
-    static Value call(Managed *, const Value &, Value *, int) {
+    static Value call(Managed *, const QV4::CallData &) {
         return Value::undefinedValue();
     }
 
index ed972b6..ac1cdef 100644 (file)
@@ -1184,10 +1184,10 @@ struct BindingFunction : public QV4::FunctionObject
         bindingKeyFlag = true;
     }
 
-    static Value call(Managed *that, const Value &thisObject, Value *argv, int argc)
+    static Value call(Managed *that, const CallData &d)
     {
         BindingFunction *This = static_cast<BindingFunction*>(that);
-        return This->originalFunction->call(thisObject, argv, argc);
+        return This->originalFunction->call(d);
     }
 
     static void markObjects(Managed *that)
index 75ed18c..96c92c4 100644 (file)
@@ -440,8 +440,10 @@ void QV8Engine::initializeGlobal()
 
 void QV8Engine::freezeObject(const QV4::Value &value)
 {
-    QV4::Value args = value;
-    m_freezeObject.value().asFunctionObject()->call(QV4::Value::fromObject(m_v4Engine->globalObject), &args, 1);
+    CALLDATA(1);
+    d.args[0] = value;
+    d.thisObject = QV4::Value::fromObject(m_v4Engine->globalObject);
+    m_freezeObject.value().asFunctionObject()->call(d);
 }
 
 void QV8Engine::gc()
index 40e33ce..91b20e6 100644 (file)
@@ -75,20 +75,20 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
         isBuiltinFunction = true;
     }
 
-    static QV4::Value construct(QV4::Managed *m, QV4::Value *, int)
+    static QV4::Value construct(QV4::Managed *m, const QV4::CallData &)
     {
         m->engine()->current->throwTypeError();
         return QV4::Value::undefinedValue();
     }
 
-    static QV4::Value call(QV4::Managed *that, const QV4::Value &thisObject, QV4::Value *args, int argc)
+    static QV4::Value call(QV4::Managed *that, const QV4::CallData &d)
     {
         DelegateModelGroupFunction *f = static_cast<DelegateModelGroupFunction *>(that);
-        QQmlDelegateModelItemObject *o = thisObject.as<QQmlDelegateModelItemObject>();
+        QQmlDelegateModelItemObject *o = d.thisObject.as<QQmlDelegateModelItemObject>();
         if (!o)
             that->engine()->current->throwTypeError(QStringLiteral("Not a valid VisualData object"));
 
-        QV4::Value v = argc ? args[0] : QV4::Value::undefinedValue();
+        QV4::Value v = d.argc ? d.args[0] : QV4::Value::undefinedValue();
         return f->code(o->item, f->flag, v);
     }
 };
index 1ec6a45..8822eae 100644 (file)
@@ -233,19 +233,23 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
 
     QV4::Value function = QV4::Value::fromObject(m_v4Engine->newBuiltinFunction(m_v4Engine->rootContext, m_v4Engine->newString(QStringLiteral("sendMessage")),
                                                           QQuickWorkerScriptEnginePrivate::sendMessage));
-    QV4::Value args[] = { function };
-    createsend = createsendconstructor->call(global(), args, 1);
+    CALLDATA(1);
+    d.args[0] = function;
+    d.thisObject = global();
+    createsend = createsendconstructor->call(d);
 }
 
 // Requires handle and context scope
 QV4::Value QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id)
 {
-    QV4::Value args[] = { QV4::Value::fromInt32(id) };
     QV4::FunctionObject *f = createsend.value().asFunctionObject();
     QV4::Value v = QV4::Value::undefinedValue();
     QV4::ExecutionContext *ctx = f->internalClass->engine->current;
     try {
-        v = f->call(global(), args, 1);
+        CALLDATA(1);
+        d.args[0] = QV4::Value::fromInt32(id);
+        d.thisObject = global();
+        v = f->call(d);
     } catch (QV4::Exception &e) {
         e.accept(ctx);
         v = e.value();
@@ -343,11 +347,15 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
 
     QV4::Value value = QV4::Serialize::deserialize(data, workerEngine);
 
-    QV4::Value args[] = { script->object.value(), value };
     QV4::FunctionObject *f = workerEngine->onmessage.value().asFunctionObject();
     QV4::ExecutionContext *ctx = f->internalClass->engine->current;
+
     try {
-        workerEngine->onmessage.value().asFunctionObject()->call(workerEngine->global(), args, 2);
+        CALLDATA(2);
+        d.thisObject = workerEngine->global();
+        d.args[0] = script->object.value();
+        d.args[1] = value;
+        f->call(d);
     } catch (QV4::Exception &e) {
         e.accept(ctx);
         QQmlError error;
index c1df858..2538cad 100644 (file)
@@ -661,10 +661,12 @@ void QQuickCanvasItem::updatePolish()
 
         foreach (int key, animationCallbacks.keys()) {
             QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this));
-            QV4::Value self = QV4::QObjectWrapper::wrap(v4, this);
-            QV4::Value args[] = { QV4::Value::fromUInt32(QDateTime::currentDateTimeUtc().toTime_t()) };
             QV4::FunctionObject *f = animationCallbacks.value(key).value().asFunctionObject();
-            f->call(self, args, 1);
+
+            CALLDATA(1);
+            d.thisObject = QV4::QObjectWrapper::wrap(v4, this);
+            d.args[0] = QV4::Value::fromUInt32(QDateTime::currentDateTimeUtc().toTime_t());
+            f->call(d);
         }
     }
     else {
index 5d02f79..1db3bc3 100644 (file)
@@ -2260,8 +2260,10 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
         QV4::FunctionObject *function = program.run().asFunctionObject();
         if (!function)
             return false;
-        QV4::Value args[] = { o };
-        function->call(engine->global(), args, 1);
+        CALLDATA(1);
+        d.args[0] = o;
+        d.thisObject = engine->global();
+        function->call(d);
     } catch (QV4::Exception &e) {
         e.accept(ctx);
         return true;
@@ -2283,8 +2285,10 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
         QV4::FunctionObject *function = program.run().asFunctionObject();
         if (!function)
             return false;
-        QV4::Value args[] = { o };
-        QV4::Value value = function->call(engine->global(), args, 1);
+        CALLDATA(1);
+        d.args[0] = o;
+        d.thisObject = engine->global();
+        QV4::Value value = function->call(d);
         return __qmljs_strict_equal(value, result);
     } catch (QV4::Exception &e) {
         e.accept(ctx);
@@ -2305,8 +2309,10 @@ static inline QV4::Value evaluate(QV8Engine *engine, const QV4::Value & o,
         QV4::FunctionObject *function = program.run().asFunctionObject();
         if (!function)
             return QV4::Value::emptyValue();
-        QV4::Value args[] = { o };
-        QV4::Value value = function->call(engine->global(), args, 1);
+        CALLDATA(1);
+        d.args[0] = o;
+        d.thisObject = engine->global();
+        QV4::Value value = function->call(d);
         return value;
     } catch (QV4::Exception &e) {
         e.accept(ctx);
index 225a4f1..845f781 100644 (file)
@@ -77,10 +77,10 @@ struct Print: FunctionObject
         name = scope->engine->newString("print");
     }
 
-    static Value call(Managed *, const Value &, Value *args, int argc)
+    static Value call(Managed *, const CallData &d)
     {
-        for (int i = 0; i < argc; ++i) {
-            QString s = args[i].toQString();
+        for (int i = 0; i < d.argc; ++i) {
+            QString s = d.args[i].toQString();
             if (i)
                 std::cout << ' ';
             std::cout << qPrintable(s);
@@ -102,7 +102,7 @@ struct GC: public FunctionObject
         vtbl = &static_vtbl;
         name = scope->engine->newString("gc");
     }
-    static Value call(Managed *m, const Value &, Value *, int)
+    static Value call(Managed *m, const CallData &)
     {
         m->engine()->memoryManager->runGC();
         return Value::undefinedValue();