if (typeHint == NUMBER_HINT)
qSwap(meth1, meth2);
- Object *oo = object.asObject();
- assert(oo != 0);
+ assert(object.isObject());
+ Object *oo = object.objectValue();
Value conv = oo->getProperty(ctx, meth1);
- if (!conv.isUndefined() && conv.isFunctionObject()) {
- Value r = __qmljs_call_value(ctx, object, conv, 0, 0);
- if (r.isPrimitive())
- return r;
+ if (!conv.isUndefined()) {
+ if (FunctionObject *f = conv.asFunctionObject()) {
+ Value r = __qmljs_call_function(ctx, object, f, 0, 0);
+ if (r.isPrimitive())
+ return r;
+ }
}
conv = oo->getProperty(ctx, meth2);
- if (!conv.isUndefined() && conv.isFunctionObject()) {
- Value r = __qmljs_call_value(ctx, object, conv, 0, 0);
- if (r.isPrimitive())
- return r;
+ if (!conv.isUndefined()) {
+ if (FunctionObject *f = conv.asFunctionObject()) {
+ Value r = __qmljs_call_function(ctx, object, f, 0, 0);
+ if (r.isPrimitive())
+ return r;
+ }
}
return Value::undefinedValue();
Value __qmljs_get_element(Context *ctx, Value object, Value index)
{
- if (object.isString() && index.isNumber()) {
- const QString s = object.stringValue()->toQString().mid(index.toUInt32(ctx), 1);
- if (s.isNull())
- return Value::undefinedValue();
- else
- return Value::fromString(ctx, s);
- } else if (object.isArrayObject() && index.isNumber()) {
- return object.asArrayObject()->value.at(index.toUInt32(ctx));
- } else {
- String *name = index.toString(ctx);
-
- if (! object.isObject())
- object = __qmljs_to_object(object, ctx);
+ if (index.isNumber()) {
+ if (object.isString()) {
+ const QString s = object.stringValue()->toQString().mid(index.toUInt32(ctx), 1);
+ if (s.isNull())
+ return Value::undefinedValue();
+ else
+ return Value::fromString(ctx, s);
+ }
- return object.property(ctx, name);
+ if (ArrayObject *a = object.asArrayObject())
+ return a->value.at(index.toUInt32(ctx));
}
+
+ String *name = index.toString(ctx);
+
+ if (! object.isObject())
+ object = __qmljs_to_object(object, ctx);
+
+ return object.property(ctx, name);
}
void __qmljs_set_element(Context *ctx, Value object, Value index, Value value)
{
- if (object.isArrayObject() && index.isNumber()) {
- object.asArrayObject()->value.assign(index.toUInt32(ctx), value);
- } else {
- String *name = index.toString(ctx);
+ if (index.isNumber()) {
+ if (ArrayObject *a = object.asArrayObject()) {
+ a->value.assign(index.toUInt32(ctx), value);
+ return;
+ }
+ }
- if (! object.isObject())
- object = __qmljs_to_object(object, ctx);
+ String *name = index.toString(ctx);
- object.objectValue()->setProperty(ctx, name, value, /*flags*/ 0);
- }
-}
+ if (! object.isObject())
+ object = __qmljs_to_object(object, ctx);
-void __qmljs_set_element_number(Context *ctx, Value *object, Value *index, double number)
-{
- Value v = Value::fromDouble(number);
- __qmljs_set_element(ctx, *object, *index, v);
+ object.objectValue()->setProperty(ctx, name, value, /*flags*/ 0);
}
void __qmljs_set_activation_property(Context *ctx, String *name, Value value)
Value __qmljs_get_property(Context *ctx, Value object, String *name)
{
if (object.isObject()) {
- return object.property(ctx, name);
+ return object.objectValue()->getProperty(ctx, name);
} else if (object.isString() && name->isEqualTo(ctx->engine->id_length)) {
- return Value::fromDouble(object.stringValue()->toQString().length());
+ return Value::fromInt32(object.stringValue()->toQString().length());
} else {
object = __qmljs_to_object(object, ctx);
if (object.isObject()) {
- return __qmljs_get_property(ctx, object, name);
+ return object.objectValue()->getProperty(ctx, name);
} else {
ctx->throwTypeError(); // ### not necessary.
return Value::undefinedValue();
return result;
}
+Value __qmljs_call_function(Context *context, Value thisObject, FunctionObject *f, Value *args, int argc)
+{
+ Context k;
+ Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
+ const Value *that = thisObject.isUndefined() ? 0 : &thisObject;
+ ctx->initCallContext(context->engine, that, f, args, argc);
+ f->call(ctx);
+ if (ctx->hasUncaughtException) {
+ context->hasUncaughtException = ctx->hasUncaughtException; // propagate the exception
+ context->result = ctx->result;
+ }
+ ctx->leaveCallContext(f);
+ return ctx->result;
+}
+
Value __qmljs_call_value(Context *context, Value thisObject, Value func, Value *args, int argc)
{
- Value result;
if (FunctionObject *f = func.asFunctionObject()) {
- Context k;
- Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
- const Value *that = thisObject.isUndefined() ? 0 : &thisObject;
- ctx->initCallContext(context->engine, that, f, args, argc);
- f->call(ctx);
- if (ctx->hasUncaughtException) {
- context->hasUncaughtException = ctx->hasUncaughtException; // propagate the exception
- context->result = ctx->result;
- }
- ctx->leaveCallContext(f);
- result = ctx->result;
+ return __qmljs_call_function(context, thisObject, f, args, argc);
} else {
context->throwTypeError();
+ return Value::undefinedValue();
}
- return result;
}
Value __qmljs_construct_activation_property(Context *context, String *name, Value *args, int argc)
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- if (callback.isFunctionObject()) {
+ if (FunctionObject *f = callback.asFunctionObject()) {
Value thisArg = ctx->argument(1);
bool ok = true;
for (uint k = 0; ok && k < instance->value.size(); ++k) {
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- Value r = __qmljs_call_value(ctx, thisArg, callback, args, 3);
+ Value r = __qmljs_call_function(ctx, thisArg, f, args, 3);
ok = __qmljs_to_boolean(r, ctx);
}
ctx->result = Value::fromBoolean(ok);
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- if (callback.isFunctionObject()) {
+ if (FunctionObject *f = callback.asFunctionObject()) {
Value thisArg = ctx->argument(1);
bool ok = false;
for (uint k = 0; !ok && k < instance->value.size(); ++k) {
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- Value r = __qmljs_call_value(ctx, thisArg, callback, args, 3);
+ Value r = __qmljs_call_function(ctx, thisArg, f, args, 3);
ok = __qmljs_to_boolean(r, ctx);
}
ctx->result = Value::fromBoolean(ok);
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- if (! callback.isFunctionObject())
- ctx->throwTypeError();
- else {
+ if (FunctionObject *f = callback.asFunctionObject()) {
Value thisArg = ctx->argument(1);
for (quint32 k = 0; k < instance->value.size(); ++k) {
Value v = instance->value.at(k);
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- /*Value r =*/ __qmljs_call_value(ctx, thisArg, callback, args, 3);
+ /*Value r =*/ __qmljs_call_function(ctx, thisArg, f, args, 3);
}
+ } else {
+ ctx->throwTypeError();
}
} else {
ctx->throwUnimplemented(QStringLiteral("Array.prototype.forEach"));
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- if (! callback.isFunctionObject())
- ctx->throwTypeError();
- else {
+ if (FunctionObject *f = callback.asFunctionObject()) {
Value thisArg = ctx->argument(1);
ArrayObject *a = ctx->engine->newArrayObject()->asArrayObject();
a->value.resize(instance->value.size());
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- Value r = __qmljs_call_value(ctx, thisArg, callback, args, 3);
+ Value r = __qmljs_call_function(ctx, thisArg, f, args, 3);
a->value.assign(k, r);
}
ctx->result = Value::fromObject(a);
+ } else {
+ ctx->throwTypeError();
}
} else {
ctx->throwUnimplemented(QStringLiteral("Array.prototype.map"));
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- if (! callback.isFunctionObject())
- ctx->throwTypeError();
- else {
+ if (FunctionObject *f = callback.asFunctionObject()) {
Value thisArg = ctx->argument(1);
ArrayObject *a = ctx->engine->newArrayObject()->asArrayObject();
for (quint32 k = 0; k < instance->value.size(); ++k) {
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- Value r = __qmljs_call_value(ctx, thisArg, callback, args, 3);
+ Value r = __qmljs_call_function(ctx, thisArg, f, args, 3);
if (__qmljs_to_boolean(r, ctx)) {
const uint index = a->value.size();
a->value.resize(index + 1);
}
}
ctx->result = Value::fromObject(a);
+ } else {
+ ctx->throwTypeError();
}
} else {
ctx->throwUnimplemented(QStringLiteral("Array.prototype.filter"));
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- Value initialValue = ctx->argument(1);
- Value acc = initialValue;
- for (quint32 k = 0; k < instance->value.size(); ++k) {
- Value v = instance->value.at(k);
- if (v.isUndefined())
- continue;
-
- if (acc.isUndefined()) {
- acc = v;
- continue;
- }
+ if (FunctionObject *f = callback.asFunctionObject()) {
+ Value initialValue = ctx->argument(1);
+ Value acc = initialValue;
+ for (quint32 k = 0; k < instance->value.size(); ++k) {
+ Value v = instance->value.at(k);
+ if (v.isUndefined())
+ continue;
+
+ if (acc.isUndefined()) {
+ acc = v;
+ continue;
+ }
- Value args[4];
- args[0] = acc;
- args[1] = v;
- args[2] = Value::fromDouble(k);
- args[3] = ctx->thisObject;
- Value r = __qmljs_call_value(ctx, Value::undefinedValue(), callback, args, 4);
- acc = r;
+ Value args[4];
+ args[0] = acc;
+ args[1] = v;
+ args[2] = Value::fromDouble(k);
+ args[3] = ctx->thisObject;
+ Value r = __qmljs_call_function(ctx, Value::undefinedValue(), f, args, 4);
+ acc = r;
+ }
+ ctx->result = acc;
+ } else {
+ ctx->throwTypeError();
}
- ctx->result = acc;
} else {
ctx->throwUnimplemented(QStringLiteral("Array.prototype.reduce"));
}
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
Value callback = ctx->argument(0);
- Value initialValue = ctx->argument(1);
- Value acc = initialValue;
- for (int k = instance->value.size() - 1; k != -1; --k) {
- Value v = instance->value.at(k);
- if (v.isUndefined())
- continue;
-
- if (acc.isUndefined()) {
- acc = v;
- continue;
- }
+ if (FunctionObject *f = callback.asFunctionObject()) {
+ Value initialValue = ctx->argument(1);
+ Value acc = initialValue;
+ for (int k = instance->value.size() - 1; k != -1; --k) {
+ Value v = instance->value.at(k);
+ if (v.isUndefined())
+ continue;
- Value args[4];
- args[0] = acc;
- args[1] = v;
- args[2] = Value::fromDouble(k);
- args[3] = ctx->thisObject;
- Value r = __qmljs_call_value(ctx, Value::undefinedValue(), callback, args, 4);
- acc = r;
+ if (acc.isUndefined()) {
+ acc = v;
+ continue;
+ }
+
+ Value args[4];
+ args[0] = acc;
+ args[1] = v;
+ args[2] = Value::fromDouble(k);
+ args[3] = ctx->thisObject;
+ Value r = __qmljs_call_function(ctx, Value::undefinedValue(), f, args, 4);
+ acc = r;
+ }
+ ctx->result = acc;
+ } else {
+ ctx->throwTypeError();
}
- ctx->result = acc;
} else {
ctx->throwUnimplemented(QStringLiteral("Array.prototype.reduceRight"));
}
void FunctionPrototype::method_apply(Context *ctx)
{
- if (/*FunctionObject *fun =*/ ctx->thisObject.asFunctionObject()) {
+ if (FunctionObject *f = ctx->thisObject.asFunctionObject()) {
Value thisObject = ctx->argument(0).toObject(ctx);
if (thisObject.isNull() || thisObject.isUndefined())
return;
}
- ctx->result = __qmljs_call_value(ctx, thisObject, ctx->thisObject, args.data(), args.size());
+ ctx->result = __qmljs_call_function(ctx, thisObject, f, args.data(), args.size());
} else {
ctx->throwTypeError();
}
void FunctionPrototype::method_call(Context *ctx)
{
- if (FunctionObject *fun = ctx->thisObject.asFunctionObject()) {
- Q_UNUSED(fun);
+ if (FunctionObject *f = ctx->thisObject.asFunctionObject()) {
Value thisArg = ctx->argument(0);
QVector<Value> args(ctx->argumentCount ? ctx->argumentCount - 1 : 0);
if (ctx->argumentCount)
qCopy(ctx->arguments + 1, ctx->arguments + ctx->argumentCount, args.begin());
- ctx->result = __qmljs_call_value(ctx, thisArg, ctx->thisObject, args.data(), args.size());
+ ctx->result = __qmljs_call_function(ctx, thisArg, f, args.data(), args.size());
} else {
ctx->throwTypeError();
}