aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp18
-rw-r--r--tools/v4/main.cpp8
51 files changed, 565 insertions, 395 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 {
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 5d02f7985b..1db3bc3fe8 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -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);
diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp
index 225a4f11fb..845f78117a 100644
--- a/tools/v4/main.cpp
+++ b/tools/v4/main.cpp
@@ -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();