aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-08-21 17:31:22 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-02 17:27:36 +0200
commit6f472680ebecb3a4d700eedcf62cb423b05c4fd1 (patch)
treebc732911a9c353dbac232ebda5a94468e3e261fe /src
parentda2f24d8e5c32fe4ed45dcb89aa357465f85fc1e (diff)
change calling convention for JS function calls
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>
Diffstat (limited to 'src')
-rw-r--r--src/imports/localstorage/plugin.cpp18
-rw-r--r--src/qml/jsapi/qjsvalue.cpp20
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp17
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp97
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4context.cpp39
-rw-r--r--src/qml/jsruntime/qv4context_p.h4
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp34
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp32
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h16
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp114
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h36
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4include.cpp6
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp54
-rw-r--r--src/qml/jsruntime/qv4managed.cpp4
-rw-r--r--src/qml/jsruntime/qv4managed_p.h32
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp12
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4object.cpp25
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp16
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp21
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp21
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp66
-rw-r--r--src/qml/jsruntime/qv4script.cpp8
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp44
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4value_p.h8
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp9
-rw-r--r--src/qml/qml/qqmlcomponent.cpp27
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp9
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp7
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp11
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp4
-rw-r--r--src/qml/qml/v8/qv8engine.cpp6
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp8
-rw-r--r--src/qml/types/qquickworkerscript.cpp20
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp8
49 files changed, 549 insertions, 385 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 0bee6d1198..6fc7d1db7f 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -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));
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index ec8cc2a1b3..cff760b49b 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -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();
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 1670f6951c..40ae29de82 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -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();
}
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 097bc4c31f..f48db1f2e6 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index d7f4babbb2..c316a3196e 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -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;
}
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 13c3882f4f..f5c256669f 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 24678d23dc..25c105210a 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -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);
}
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 3e5e7663f2..0cdcdec1f1 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 7353d69d32..7d7f5dda25 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -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;
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 0c1dfb1d71..331c5aa990 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -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);
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 47730f2f2e..87d93add6e 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -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()
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 4e833e143f..89ca057a1b 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 0b6756466c..8f6e47e5f1 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -314,8 +314,6 @@ inline void ExecutionEngine::pushContext(SimpleCallContext *context)
inline ExecutionContext *ExecutionEngine::popContext()
{
- CallContext *c = current->asCallContext();
-
current = current->parent;
return current;
}
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 68f6f56a18..6c7c290452 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -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)
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 798f86fdc6..c51023205f 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 950a5a5dbf..a4533edc9c 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -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)
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 89e2b14ca7..fdfb1e6a2b 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -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 *);
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 53d43dbc7c..3b06a6d884 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -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);
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index 11d034b5b4..4ac531c27b 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 4fd7bb14c7..9068d573f6 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -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);
}
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index e5a8582d19..68a4c5ca71 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -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()) {
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 345611d46c..b7a6f73822 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -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;
}
}
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index 19adb354e3..955d12a3d0 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -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();
}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 227cd4bdb0..b77b1cd638 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -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);
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 6d3b6220cc..88c61489db 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -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)
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 0c06451c98..224840ebb7 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 01be2d7091..ab33764142 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -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;
}
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index add26867a8..ec60a9b343 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -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)
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index ca2e77ca42..afa0ce09f5 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index f79675845b..70413489aa 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -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 {
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 6580d19fe9..39af02f38b 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -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)
{
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 0dc14e5722..16b23e2edb 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -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;
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 0b9b7122a9..2179dbdb7d 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 8d28979b60..f145050f17 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -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;
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 80cca830f5..17bd9b5eed 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -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);
}
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index c248c9c524..1d5c271069 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -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;
}
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index e0c6bb5a17..ab802cabce 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -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));
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index 0ef6596235..cf489eb05c 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 20b78a4da1..73d5d0479d 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -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
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 0c922294b4..08344c4c60 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -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.
}
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 8f1233555b..5c26f689de 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -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;
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 3b703c9c2a..41be44a0a7 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -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();
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 327b638068..3d2d54ccfa 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -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);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index fb6733ee58..5045d700ed 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -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();
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index ed972b64c1..ac1cdef30e 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -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)
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 75ed18ce15..96c92c4c7c 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -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()
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 40e33ceef8..91b20e6d81 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -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);
}
};
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 1ec6a45fe0..8822eaecd0 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -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;
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index c1df858310..2538cad211 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -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 {