aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4objectproto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4objectproto.cpp')
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp196
1 files changed, 101 insertions, 95 deletions
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 2f8f6375f0..073d588e56 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -79,24 +79,25 @@ ObjectCtor::ObjectCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value ObjectCtor::construct(Managed *that, CallData *callData)
+ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
{
- ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
ExecutionEngine *v4 = that->engine();
+ Scope scope(v4);
+ ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) {
Object *obj = v4->newObject();
- Value proto = ctor->get(v4->id_prototype);
- if (proto.isObject())
- obj->setPrototype(proto.objectValue());
- return Value::fromObject(obj);
+ Scoped<Object> proto(scope, ctor->get(v4->id_prototype));
+ if (!!proto)
+ obj->setPrototype(proto.getPointer());
+ return Value::fromObject(obj).asReturnedValue();
}
- return __qmljs_to_object(v4->current, ValueRef(&callData->args[0]));
+ return Value::fromReturnedValue(__qmljs_to_object(v4->current, ValueRef(&callData->args[0]))).asReturnedValue();
}
-Value ObjectCtor::call(Managed *m, CallData *callData)
+ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
{
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull())
- return Value::fromObject(m->engine()->newObject());
+ return Value::fromObject(m->engine()->newObject()).asReturnedValue();
return __qmljs_to_object(m->engine()->current, ValueRef(&callData->args[0]));
}
@@ -134,17 +135,17 @@ void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor)
p->setSetter(v4->newBuiltinFunction(v4->rootContext, v4->id___proto__, method_set_proto));
}
-Value ObjectPrototype::method_getPrototypeOf(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_getPrototypeOf(SimpleCallContext *ctx)
{
Value o = ctx->argument(0);
if (! o.isObject())
ctx->throwTypeError();
Object *p = o.objectValue()->prototype();
- return p ? Value::fromObject(p) : Value::nullValue();
+ return p ? Value::fromObject(p).asReturnedValue() : Encode::null();
}
-Value ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject())
@@ -156,17 +157,17 @@ Value ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
return fromPropertyDescriptor(ctx, desc, attrs);
}
-Value ObjectPrototype::method_getOwnPropertyNames(SimpleCallContext *context)
+ReturnedValue ObjectPrototype::method_getOwnPropertyNames(SimpleCallContext *context)
{
Object *O = context->argumentCount ? context->arguments[0].asObject() : 0;
if (!O)
context->throwTypeError();
ArrayObject *array = getOwnPropertyNames(context->engine, context->arguments[0]);
- return Value::fromObject(array);
+ return Value::fromObject(array).asReturnedValue();
}
-Value ObjectPrototype::method_create(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_create(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject() && !O.isNull())
@@ -181,10 +182,10 @@ Value ObjectPrototype::method_create(SimpleCallContext *ctx)
method_defineProperties(ctx);
}
- return objValue;
+ return objValue.asReturnedValue();
}
-Value ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject())
@@ -200,10 +201,10 @@ Value ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
if (!O.objectValue()->__defineOwnProperty__(ctx, name, pd, attrs))
ctx->throwTypeError();
- return O;
+ return O.asReturnedValue();
}
-Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject())
@@ -221,7 +222,7 @@ Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
break;
Property n;
PropertyAttributes nattrs;
- toPropertyDescriptor(ctx, o->getValue(pd, attrs), &n, &nattrs);
+ toPropertyDescriptor(ctx, Value::fromReturnedValue(o->getValue(pd, attrs)), &n, &nattrs);
bool ok;
if (name)
ok = O.objectValue()->__defineOwnProperty__(ctx, name, n, nattrs);
@@ -231,10 +232,10 @@ Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
ctx->throwTypeError();
}
- return O;
+ return O.asReturnedValue();
}
-Value ObjectPrototype::method_seal(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_seal(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
@@ -250,10 +251,10 @@ Value ObjectPrototype::method_seal(SimpleCallContext *ctx)
o->arrayAttributes[i].setConfigurable(false);
}
- return ctx->argument(0);
+ return ctx->argument(0).asReturnedValue();
}
-Value ObjectPrototype::method_freeze(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_freeze(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
@@ -270,169 +271,171 @@ Value ObjectPrototype::method_freeze(SimpleCallContext *ctx)
if (o->arrayAttributes[i].isData())
o->arrayAttributes[i].setWritable(false);
}
- return ctx->argument(0);
+ return ctx->argument(0).asReturnedValue();
}
-Value ObjectPrototype::method_preventExtensions(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_preventExtensions(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
- return ctx->argument(0);
+ return ctx->argument(0).asReturnedValue();
}
-Value ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
if (o->extensible)
- return Value::fromBoolean(false);
+ return Encode(false);
if (o->internalClass != o->internalClass->sealed())
- return Value::fromBoolean(false);
+ return Encode(false);
if (!o->arrayDataLen)
- return Value::fromBoolean(true);
+ return Encode(true);
if (!o->arrayAttributes)
- return Value::fromBoolean(false);
+ return Encode(false);
for (uint i = 0; i < o->arrayDataLen; ++i) {
if (!o->arrayAttributes[i].isGeneric())
if (o->arrayAttributes[i].isConfigurable())
- return Value::fromBoolean(false);
+ return Encode(false);
}
- return Value::fromBoolean(true);
+ return Encode(true);
}
-Value ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
if (o->extensible)
- return Value::fromBoolean(false);
+ return Encode(false);
if (o->internalClass != o->internalClass->frozen())
- return Value::fromBoolean(false);
+ return Encode(false);
if (!o->arrayDataLen)
- return Value::fromBoolean(true);
+ return Encode(true);
if (!o->arrayAttributes)
- return Value::fromBoolean(false);
+ return Encode(false);
for (uint i = 0; i < o->arrayDataLen; ++i) {
if (!o->arrayAttributes[i].isGeneric())
if (o->arrayAttributes[i].isConfigurable() || o->arrayAttributes[i].isWritable())
- return Value::fromBoolean(false);
+ return Encode(false);
}
- return Value::fromBoolean(true);
+ return Encode(true);
}
-Value ObjectPrototype::method_isExtensible(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isExtensible(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
- return Value::fromBoolean(o->extensible);
+ return Encode((bool)o->extensible);
}
-Value ObjectPrototype::method_keys(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
+ Scope scope(ctx);
Object *o = ctx->argument(0).objectValue();
- ArrayObject *a = ctx->engine->newArrayObject();
+ Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
ObjectIterator it(o, ObjectIterator::EnumerableOnly);
+ ScopedValue name(scope);
while (1) {
- Value name = it.nextPropertyNameAsString();
- if (name.isNull())
+ name = it.nextPropertyNameAsString();
+ if (name->isNull())
break;
a->push_back(name);
}
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
-Value ObjectPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_toString(SimpleCallContext *ctx)
{
if (ctx->thisObject.isUndefined()) {
- return Value::fromString(ctx, QStringLiteral("[object Undefined]"));
+ return Value::fromString(ctx, QStringLiteral("[object Undefined]")).asReturnedValue();
} else if (ctx->thisObject.isNull()) {
- return Value::fromString(ctx, QStringLiteral("[object Null]"));
+ return Value::fromString(ctx, QStringLiteral("[object Null]")).asReturnedValue();
} else {
- Value obj = __qmljs_to_object(ctx, ValueRef(&ctx->thisObject));
+ Value obj = Value::fromReturnedValue(__qmljs_to_object(ctx, ValueRef(&ctx->thisObject)));
QString className = obj.objectValue()->className();
- return Value::fromString(ctx, QString::fromUtf8("[object %1]").arg(className));
+ return Value::fromString(ctx, QString::fromUtf8("[object %1]").arg(className)).asReturnedValue();
}
}
-Value ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *o = ctx->thisObject.toObject(ctx);
- Value ts = o->get(ctx->engine->newString(QStringLiteral("toString")));
- FunctionObject *f = ts.asFunctionObject();
+ Scoped<FunctionObject> f(scope, o->get(ctx->engine->newString(QStringLiteral("toString"))));
if (!f)
ctx->throwTypeError();
- ScopedCallData callData(ctx->engine, 0);
+ ScopedCallData callData(scope, 0);
callData->thisObject = Value::fromObject(o);
return f->call(callData);
}
-Value ObjectPrototype::method_valueOf(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_valueOf(SimpleCallContext *ctx)
{
- return Value::fromObject(ctx->thisObject.toObject(ctx));
+ return Value::fromObject(ctx->thisObject.toObject(ctx)).asReturnedValue();
}
-Value ObjectPrototype::method_hasOwnProperty(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_hasOwnProperty(SimpleCallContext *ctx)
{
String *P = ctx->argument(0).toString(ctx);
Object *O = ctx->thisObject.toObject(ctx);
bool r = O->__getOwnProperty__(P) != 0;
if (!r)
r = !O->query(P).isEmpty();
- return Value::fromBoolean(r);
+ return Encode(r);
}
-Value ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
{
Value V = ctx->argument(0);
if (! V.isObject())
- return Value::fromBoolean(false);
+ return Encode(false);
Object *O = ctx->thisObject.toObject(ctx);
Object *proto = V.objectValue()->prototype();
while (proto) {
if (O == proto)
- return Value::fromBoolean(true);
+ return Encode(true);
proto = proto->prototype();
}
- return Value::fromBoolean(false);
+ return Encode(false);
}
-Value ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ctx)
{
String *p = ctx->argument(0).toString(ctx);
Object *o = ctx->thisObject.toObject(ctx);
PropertyAttributes attrs;
o->__getOwnProperty__(p, &attrs);
- return Value::fromBoolean(attrs.isEnumerable());
+ return Encode(attrs.isEnumerable());
}
-Value ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
ctx->throwTypeError();
@@ -445,16 +448,16 @@ Value ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
Object *o = ctx->thisObject.asObject();
if (!o) {
if (!ctx->thisObject.isUndefined())
- return Value::undefinedValue();
+ return Encode::undefined();
o = ctx->engine->globalObject;
}
Property pd = Property::fromAccessor(f, 0);
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
ctx->throwTypeError();
@@ -467,25 +470,25 @@ Value ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
Object *o = ctx->thisObject.asObject();
if (!o) {
if (!ctx->thisObject.isUndefined())
- return Value::undefinedValue();
+ return Encode::undefined();
o = ctx->engine->globalObject;
}
Property pd = Property::fromAccessor(0, f);
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value ObjectPrototype::method_get_proto(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_get_proto(SimpleCallContext *ctx)
{
Object *o = ctx->thisObject.asObject();
if (!o)
ctx->throwTypeError();
- return Value::fromObject(o->prototype());
+ return Value::fromObject(o->prototype()).asReturnedValue();
}
-Value ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
{
Object *o = ctx->thisObject.asObject();
if (!o)
@@ -505,7 +508,7 @@ Value ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
}
if (!ok)
ctx->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
- return Value::undefinedValue();
+ return Encode::undefined();
}
void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Property *desc, PropertyAttributes *attrs)
@@ -513,6 +516,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (!v.isObject())
ctx->throwTypeError();
+ Scope scope(ctx);
Object *o = v.objectValue();
attrs->clear();
@@ -520,17 +524,17 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
desc->setSetter(0);
if (o->__hasProperty__(ctx->engine->id_enumerable))
- attrs->setEnumerable(o->get(ctx->engine->id_enumerable).toBoolean());
+ attrs->setEnumerable(Value::fromReturnedValue(o->get(ctx->engine->id_enumerable)).toBoolean());
if (o->__hasProperty__(ctx->engine->id_configurable))
- attrs->setConfigurable(o->get(ctx->engine->id_configurable).toBoolean());
+ attrs->setConfigurable(Value::fromReturnedValue(o->get(ctx->engine->id_configurable)).toBoolean());
if (o->__hasProperty__(ctx->engine->id_get)) {
- Value get = o->get(ctx->engine->id_get);
- FunctionObject *f = get.asFunctionObject();
+ ScopedValue get(scope, o->get(ctx->engine->id_get));
+ FunctionObject *f = get->asFunctionObject();
if (f) {
desc->setGetter(f);
- } else if (get.isUndefined()) {
+ } else if (get->isUndefined()) {
desc->setGetter((FunctionObject *)0x1);
} else {
ctx->throwTypeError();
@@ -539,11 +543,11 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
}
if (o->__hasProperty__(ctx->engine->id_set)) {
- Value set = o->get(ctx->engine->id_set);
- FunctionObject *f = set.asFunctionObject();
+ ScopedValue set(scope, o->get(ctx->engine->id_set));
+ FunctionObject *f = set->asFunctionObject();
if (f) {
desc->setSetter(f);
- } else if (set.isUndefined()) {
+ } else if (set->isUndefined()) {
desc->setSetter((FunctionObject *)0x1);
} else {
ctx->throwTypeError();
@@ -554,7 +558,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx->engine->id_writable)) {
if (attrs->isAccessor())
ctx->throwTypeError();
- attrs->setWritable(o->get(ctx->engine->id_writable).toBoolean());
+ attrs->setWritable(Value::fromReturnedValue(o->get(ctx->engine->id_writable)).toBoolean());
// writable forces it to be a data descriptor
desc->value = Value::undefinedValue();
}
@@ -562,7 +566,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx->engine->id_value)) {
if (attrs->isAccessor())
ctx->throwTypeError();
- desc->value = o->get(ctx->engine->id_value);
+ desc->value = Value::fromReturnedValue(o->get(ctx->engine->id_value));
attrs->setType(PropertyAttributes::Data);
}
@@ -571,10 +575,10 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
}
-Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Property *desc, PropertyAttributes attrs)
+ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Property *desc, PropertyAttributes attrs)
{
if (!desc)
- return Value::undefinedValue();
+ return Encode::undefined();
ExecutionEngine *engine = ctx->engine;
// Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
@@ -597,23 +601,25 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope
pd.value = Value::fromBoolean(attrs.isConfigurable());
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), pd, Attr_Data);
- return Value::fromObject(o);
+ return Value::fromObject(o).asReturnedValue();
}
ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o)
{
- ArrayObject *array = v4->newArrayObject();
+ Scope scope(v4);
+ Scoped<ArrayObject> array(scope, v4->newArrayObject());
Object *O = o.asObject();
if (!O)
- return array;
+ return array.getPointer();
ObjectIterator it(O, ObjectIterator::NoFlags);
+ ScopedValue name(scope);
while (1) {
- Value name = it.nextPropertyNameAsString();
- if (name.isNull())
+ name = it.nextPropertyNameAsString();
+ if (name->isNull())
break;
array->push_back(name);
}
- return array;
+ return array.getPointer();
}