54void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
57 ScopedObject o(scope,
this);
59 ctor->defineReadonlyProperty(v4->id_prototype(), o);
60 ctor->defineReadonlyConfigurableProperty(v4->id_length(), Value::fromInt32(1));
61 ctor->defineDefaultProperty(QStringLiteral(
"getPrototypeOf"), method_getPrototypeOf, 1);
62 ctor->defineDefaultProperty(QStringLiteral(
"getOwnPropertyDescriptor"), method_getOwnPropertyDescriptor, 2);
63 ctor->defineDefaultProperty(QStringLiteral(
"getOwnPropertyDescriptors"), method_getOwnPropertyDescriptors, 1);
64 ctor->defineDefaultProperty(QStringLiteral(
"getOwnPropertyNames"), method_getOwnPropertyNames, 1);
65 ctor->defineDefaultProperty(QStringLiteral(
"getOwnPropertySymbols"), method_getOwnPropertySymbols, 1);
66 ctor->defineDefaultProperty(QStringLiteral(
"assign"), method_assign, 2);
67 ctor->defineDefaultProperty(QStringLiteral(
"create"), method_create, 2);
68 ctor->defineDefaultProperty(QStringLiteral(
"defineProperty"), method_defineProperty, 3);
69 ctor->defineDefaultProperty(QStringLiteral(
"defineProperties"), method_defineProperties, 2);
70 ctor->defineDefaultProperty(QStringLiteral(
"entries"), method_entries, 1);
71 ctor->defineDefaultProperty(QStringLiteral(
"seal"), method_seal, 1);
72 ctor->defineDefaultProperty(QStringLiteral(
"freeze"), method_freeze, 1);
73 ctor->defineDefaultProperty(QStringLiteral(
"preventExtensions"), method_preventExtensions, 1);
74 ctor->defineDefaultProperty(QStringLiteral(
"is"), method_is, 2);
75 ctor->defineDefaultProperty(QStringLiteral(
"isSealed"), method_isSealed, 1);
76 ctor->defineDefaultProperty(QStringLiteral(
"isFrozen"), method_isFrozen, 1);
77 ctor->defineDefaultProperty(QStringLiteral(
"isExtensible"), method_isExtensible, 1);
78 ctor->defineDefaultProperty(QStringLiteral(
"keys"), method_keys, 1);
79 ctor->defineDefaultProperty(QStringLiteral(
"setPrototypeOf"), method_setPrototypeOf, 2);
80 ctor->defineDefaultProperty(QStringLiteral(
"values"), method_values, 1);
82 defineDefaultProperty(QStringLiteral(
"constructor"), (o = ctor));
83 defineDefaultProperty(v4->id_toString(), method_toString, 0);
84 defineDefaultProperty(v4->id_toLocaleString(), method_toLocaleString, 0);
85 defineDefaultProperty(v4->id_valueOf(), method_valueOf, 0);
86 defineDefaultProperty(QStringLiteral(
"hasOwnProperty"), method_hasOwnProperty, 1);
87 defineDefaultProperty(QStringLiteral(
"isPrototypeOf"), method_isPrototypeOf, 1);
88 defineDefaultProperty(QStringLiteral(
"propertyIsEnumerable"), method_propertyIsEnumerable, 1);
89 defineDefaultProperty(QStringLiteral(
"__defineGetter__"), method_defineGetter, 2);
90 defineDefaultProperty(QStringLiteral(
"__defineSetter__"), method_defineSetter, 2);
92 defineAccessorProperty(v4->id___proto__(), method_get_proto, method_set_proto);
118ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
122 return scope.engine->throwTypeError();
124 ScopedObject O(scope, argv[0].toObject(scope.engine));
125 if (scope.hasException())
126 return QV4::Encode::undefined();
128 if (ArgumentsObject::isNonStrictArgumentsObject(O))
129 static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate();
131 ScopedValue v(scope, argc > 1 ? argv[1] : Value::undefinedValue());
132 ScopedPropertyKey name(scope, v->toPropertyKey(scope.engine));
133 if (scope.hasException())
134 return QV4::Encode::undefined();
136 ScopedProperty desc(scope);
137 PropertyAttributes attrs = O->getOwnProperty(name, desc);
138 return fromPropertyDescriptor(scope.engine, desc, attrs);
141ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptors(
const FunctionObject *f,
const Value *,
const Value *argv,
int argc)
145 return scope.engine->throwTypeError();
147 ScopedObject o(scope, argv[0].toObject(scope.engine));
148 if (scope.hasException())
149 return Encode::undefined();
151 ScopedObject descriptors(scope, scope.engine->newObject());
153 ObjectIterator it(scope, o, ObjectIterator::WithSymbols);
154 ScopedProperty pd(scope);
155 PropertyAttributes attrs;
156 ScopedPropertyKey key(scope);
157 ScopedObject entry(scope);
159 key = it.next(pd, &attrs);
162 entry = fromPropertyDescriptor(scope.engine, pd, attrs);
163 descriptors->put(key, entry);
166 return descriptors.asReturnedValue();
210ReturnedValue ObjectPrototype::method_assign(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
214 return scope.engine->throwTypeError();
216 ScopedObject to(scope, argv[0].toObject(scope.engine));
217 if (scope.hasException())
218 return QV4::Encode::undefined();
221 return to.asReturnedValue();
223 for (
int i = 1, ei = argc; i < ei; ++i) {
224 if (argv[i].isUndefined() || argv[i].isNull())
228 ScopedObject from(loopScope, argv[i].toObject(loopScope.engine));
229 if (loopScope.hasException())
230 return QV4::Encode::undefined();
231 QV4::ScopedArrayObject keys(loopScope, QV4::ObjectPrototype::getOwnPropertyNames(loopScope.engine, from));
232 quint32 length = keys->getLength();
234 ScopedString nextKey(loopScope);
235 ScopedValue propValue(loopScope);
236 ScopedProperty prop(loopScope);
237 for (quint32 i = 0; i < length; ++i) {
238 nextKey = Value::fromReturnedValue(keys->get(i)).toString(loopScope.engine);
240 PropertyAttributes attrs = from->getOwnProperty(nextKey->toPropertyKey(), prop);
242 if (attrs == PropertyFlag::Attr_Invalid)
245 if (!attrs.isEnumerable())
248 propValue = from->get(nextKey);
249 to->set(nextKey, propValue, Object::DoThrowOnRejection);
250 if (loopScope.hasException())
251 return QV4::Encode::undefined();
255 return to.asReturnedValue();
258ReturnedValue ObjectPrototype::method_create(
const FunctionObject *builtin,
const Value *thisObject,
const Value *argv,
int argc)
260 Scope scope(builtin);
261 if (!argc || (!argv[0].isObject() && !argv[0].isNull()))
262 return scope.engine->throwTypeError();
264 ScopedObject O(scope, argv[0]);
266 ScopedObject newObject(scope, scope.engine->newObject());
267 newObject->setPrototypeOf(O);
270 if (argc > 1 && !argv[1].isUndefined()) {
271 Value *arguments = scope.constructUndefined(argc);
272 arguments[0] = newObject;
273 memcpy(arguments + 1, argv + 1, (argc - 1)*
sizeof(Value));
274 return method_defineProperties(builtin, thisObject, arguments, argc);
277 return newObject.asReturnedValue();
280ReturnedValue ObjectPrototype::method_defineProperty(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
283 if (!argc || !argv[0].isObject())
284 return scope.engine->throwTypeError();
286 ScopedObject O(scope, argv[0]);
287 ScopedPropertyKey name(scope, (argc > 1 ? argv[1] : Value::undefinedValue()).toPropertyKey(scope.engine));
288 if (scope.hasException())
289 return QV4::Encode::undefined();
291 ScopedValue attributes(scope, argc > 2 ? argv[2] : Value::undefinedValue());
292 ScopedProperty pd(scope);
293 PropertyAttributes attrs;
294 toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
295 if (scope.hasException())
296 return QV4::Encode::undefined();
298 if (!O->defineOwnProperty(name, pd, attrs))
301 return O.asReturnedValue();
304ReturnedValue ObjectPrototype::method_defineProperties(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
307 if (argc < 2 || !argv[0].isObject())
308 return scope.engine->throwTypeError();
310 ScopedObject O(scope, argv[0]);
312 ScopedObject o(scope, argv[1].toObject(scope.engine));
313 if (scope.hasException())
314 return QV4::Encode::undefined();
316 ScopedValue val(scope);
318 ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
319 ScopedProperty pd(scope);
320 ScopedProperty n(scope);
321 ScopedPropertyKey key(scope);
323 PropertyAttributes attrs;
324 key = it.next(pd, &attrs);
327 PropertyAttributes nattrs;
328 val = o->getValue(pd->value, attrs);
329 toPropertyDescriptor(scope.engine, val, n, &nattrs);
330 if (scope.hasException())
331 return QV4::Encode::undefined();
332 bool ok = O->defineOwnProperty(key, n, nattrs);
337 return O.asReturnedValue();
340ReturnedValue ObjectPrototype::method_entries(
const FunctionObject *f,
const Value *,
const Value *argv,
int argc)
344 return scope.engine->throwTypeError();
346 ScopedObject o(scope, argv[0].toObject(scope.engine));
347 if (scope.hasException())
348 return Encode::undefined();
350 ScopedArrayObject a(scope, scope.engine->newArrayObject());
352 ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
353 ScopedString name(scope);
354 ScopedArrayObject entry(scope);
356 name = it.nextPropertyNameAsString();
359 entry = scope.engine->newArrayObject();
360 entry->push_back(name);
365 uint len = a->getLength();
366 ScopedValue value(scope);
367 for (uint i = 0; i < len; ++i) {
368 entry = a->get(PropertyKey::fromArrayIndex(i));
369 name = entry->get(PropertyKey::fromArrayIndex(0));
370 value = o->get(name->toPropertyKey());
371 if (scope.hasException())
372 return Encode::undefined();
373 entry->push_back(value);
376 return a.asReturnedValue();
401ReturnedValue ObjectPrototype::method_freeze(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
403 const Value a = argc ? argv[0] : Value::undefinedValue();
406 return a.asReturnedValue();
409 ScopedObject o(scope, a);
411 if (ArgumentsObject::isNonStrictArgumentsObject(o))
412 static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate();
414 o->setInternalClass(o->internalClass()->cryopreserved());
416 if (o->arrayData()) {
417 ArrayData::ensureAttributes(o);
418 for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
419 if (!o->arrayData()->isEmpty(i))
420 o->arrayData()->attrs[i].setConfigurable(
false);
421 if (o->arrayData()->attrs[i].isData())
422 o->arrayData()->attrs[i].setWritable(
false);
425 return o.asReturnedValue();
561ReturnedValue ObjectPrototype::method_values(
const FunctionObject *f,
const Value *,
const Value *argv,
int argc)
565 return scope.engine->throwTypeError();
567 ScopedObject o(scope, argv[0].toObject(scope.engine));
568 if (scope.hasException())
569 return QV4::Encode::undefined();
571 ScopedArrayObject a(scope, scope.engine->newArrayObject());
573 ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
574 ScopedPropertyKey key(scope);
575 ScopedProperty pd(scope);
576 ScopedValue value(scope);
577 PropertyAttributes attrs;
579 key = it.next(pd, &attrs);
582 value = o->getValue(pd->value, attrs);
586 return a.asReturnedValue();
589ReturnedValue ObjectPrototype::method_toString(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
591 ExecutionEngine *v4 = b->engine();
593 if (thisObject->isUndefined()) {
594 string = QStringLiteral(
"[object Undefined]");
595 }
else if (thisObject->isNull()) {
596 string = QStringLiteral(
"[object Null]");
598 const Object *o = thisObject->as<Object>();
601 if (thisObject->isBoolean())
602 o = v4->booleanPrototype();
603 else if (thisObject->isNumber())
604 o = v4->numberPrototype();
605 else if (thisObject->isString())
606 o = v4->stringPrototype();
607 else if (thisObject->isSymbol())
608 o = v4->symbolPrototype();
611 QString name = o->className();
613 ScopedString toStringTag(scope, o->get(v4->symbol_toStringTag()));
615 name = toStringTag->toQString();
616 string = QStringLiteral(
"[object %1]").arg(name);
618 return Encode(v4->newString(string));
687ReturnedValue ObjectPrototype::method_defineGetter(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
693 ScopedFunctionObject f(scope, argv[1]);
697 ScopedString prop(scope, argv[0], ScopedString::Convert);
698 if (scope.hasException())
699 return QV4::Encode::undefined();
701 ScopedObject o(scope, thisObject);
703 if (!thisObject->isUndefined())
705 o = scope.engine->globalObject;
708 ScopedProperty pd(scope);
710 pd->set = Value::emptyValue();
711 bool ok = o->defineOwnProperty(prop->toPropertyKey(), pd, Attr_Accessor);
717ReturnedValue ObjectPrototype::method_defineSetter(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
723 ScopedFunctionObject f(scope, argv[1]);
727 ScopedString prop(scope, argv[0], ScopedString::Convert);
728 if (scope.hasException())
729 return QV4::Encode::undefined();
731 ScopedObject o(scope, thisObject);
733 if (!thisObject->isUndefined())
735 o = scope.engine->globalObject;
738 ScopedProperty pd(scope);
739 pd->value = Value::emptyValue();
741 bool ok = o->defineOwnProperty(prop->toPropertyKey(), pd, Attr_Accessor);
772void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine,
const Value &v, Property *desc, PropertyAttributes *attrs)
775 ScopedObject o(scope, v);
777 engine->throwTypeError();
782 desc->value = Value::emptyValue();
783 desc->set = Value::emptyValue();
784 ScopedValue tmp(scope);
786 if (o->hasProperty(engine->id_enumerable()->toPropertyKey()))
787 attrs->setEnumerable((tmp = o->get(engine->id_enumerable()))->toBoolean());
789 if (o->hasProperty(engine->id_configurable()->toPropertyKey()))
790 attrs->setConfigurable((tmp = o->get(engine->id_configurable()))->toBoolean());
792 if (o->hasProperty(engine->id_get()->toPropertyKey())) {
793 ScopedValue get(scope, o->get(engine->id_get()));
794 FunctionObject *f = get->as<FunctionObject>();
795 if (f || get->isUndefined()) {
798 engine->throwTypeError();
801 attrs->setType(PropertyAttributes::Accessor);
804 if (o->hasProperty(engine->id_set()->toPropertyKey())) {
805 ScopedValue set(scope, o->get(engine->id_set()));
806 FunctionObject *f = set->as<FunctionObject>();
807 if (f || set->isUndefined()) {
810 engine->throwTypeError();
813 attrs->setType(PropertyAttributes::Accessor);
816 if (o->hasProperty(engine->id_writable()->toPropertyKey())) {
817 if (attrs->isAccessor()) {
818 engine->throwTypeError();
821 attrs->setWritable((tmp = o->get(engine->id_writable()))->toBoolean());
824 if (o->hasProperty(engine->id_value()->toPropertyKey())) {
825 if (attrs->isAccessor()) {
826 engine->throwTypeError();
829 desc->value = o->get(engine->id_value());
830 attrs->setType(PropertyAttributes::Data);
833 if (attrs->isGeneric())
834 desc->value = Value::emptyValue();
838ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionEngine *engine,
const Property *desc, PropertyAttributes attrs)
841 return Encode::undefined();
846 ScopedObject o(scope, engine->newObject());
847 ScopedString s(scope);
848 ScopedValue v(scope);
850 if (attrs.isData()) {
851 s = engine->newString(QStringLiteral(
"value"));
852 o->put(s, desc->value);
853 v = Value::fromBoolean(attrs.isWritable());
854 s = engine->newString(QStringLiteral(
"writable"));
857 v = desc->getter() ? desc->getter()->asReturnedValue() : Encode::undefined();
858 s = engine->newString(QStringLiteral(
"get"));
860 v = desc->setter() ? desc->setter()->asReturnedValue() : Encode::undefined();
861 s = engine->newString(QStringLiteral(
"set"));
864 v = Value::fromBoolean(attrs.isEnumerable());
865 s = engine->newString(QStringLiteral(
"enumerable"));
867 v = Value::fromBoolean(attrs.isConfigurable());
868 s = engine->newString(QStringLiteral(
"configurable"));
871 return o.asReturnedValue();