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())
227 ScopedObject from(scope, argv[i].toObject(scope.engine));
228 if (scope.hasException())
229 return QV4::Encode::undefined();
230 QV4::ScopedArrayObject keys(scope, QV4::ObjectPrototype::getOwnPropertyNames(scope.engine, from));
231 quint32 length = keys->getLength();
233 ScopedString nextKey(scope);
234 ScopedValue propValue(scope);
235 for (quint32 i = 0; i < length; ++i) {
236 nextKey = Value::fromReturnedValue(keys->get(i)).toString(scope.engine);
238 ScopedProperty prop(scope);
239 PropertyAttributes attrs = from->getOwnProperty(nextKey->toPropertyKey(), prop);
241 if (attrs == PropertyFlag::Attr_Invalid)
244 if (!attrs.isEnumerable())
247 propValue = from->get(nextKey);
248 to->set(nextKey, propValue, Object::DoThrowOnRejection);
249 if (scope.hasException())
250 return QV4::Encode::undefined();
254 return to.asReturnedValue();
257ReturnedValue ObjectPrototype::method_create(
const FunctionObject *builtin,
const Value *thisObject,
const Value *argv,
int argc)
259 Scope scope(builtin);
260 if (!argc || (!argv[0].isObject() && !argv[0].isNull()))
261 return scope.engine->throwTypeError();
263 ScopedObject O(scope, argv[0]);
265 ScopedObject newObject(scope, scope.engine->newObject());
266 newObject->setPrototypeOf(O);
269 if (argc > 1 && !argv[1].isUndefined()) {
270 Value *arguments = scope.constructUndefined(argc);
271 arguments[0] = newObject;
272 memcpy(arguments + 1, argv + 1, (argc - 1)*
sizeof(Value));
273 return method_defineProperties(builtin, thisObject, arguments, argc);
276 return newObject.asReturnedValue();
279ReturnedValue ObjectPrototype::method_defineProperty(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
282 if (!argc || !argv[0].isObject())
283 return scope.engine->throwTypeError();
285 ScopedObject O(scope, argv[0]);
286 ScopedPropertyKey name(scope, (argc > 1 ? argv[1] : Value::undefinedValue()).toPropertyKey(scope.engine));
287 if (scope.hasException())
288 return QV4::Encode::undefined();
290 ScopedValue attributes(scope, argc > 2 ? argv[2] : Value::undefinedValue());
291 ScopedProperty pd(scope);
292 PropertyAttributes attrs;
293 toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
294 if (scope.hasException())
295 return QV4::Encode::undefined();
297 if (!O->defineOwnProperty(name, pd, attrs))
300 return O.asReturnedValue();
303ReturnedValue ObjectPrototype::method_defineProperties(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
306 if (argc < 2 || !argv[0].isObject())
307 return scope.engine->throwTypeError();
309 ScopedObject O(scope, argv[0]);
311 ScopedObject o(scope, argv[1].toObject(scope.engine));
312 if (scope.hasException())
313 return QV4::Encode::undefined();
315 ScopedValue val(scope);
317 ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
318 ScopedProperty pd(scope);
319 ScopedProperty n(scope);
320 ScopedPropertyKey key(scope);
322 PropertyAttributes attrs;
323 key = it.next(pd, &attrs);
326 PropertyAttributes nattrs;
327 val = o->getValue(pd->value, attrs);
328 toPropertyDescriptor(scope.engine, val, n, &nattrs);
329 if (scope.hasException())
330 return QV4::Encode::undefined();
331 bool ok = O->defineOwnProperty(key, n, nattrs);
336 return O.asReturnedValue();
339ReturnedValue ObjectPrototype::method_entries(
const FunctionObject *f,
const Value *,
const Value *argv,
int argc)
343 return scope.engine->throwTypeError();
345 ScopedObject o(scope, argv[0].toObject(scope.engine));
346 if (scope.hasException())
347 return Encode::undefined();
349 ScopedArrayObject a(scope, scope.engine->newArrayObject());
351 ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
352 ScopedString name(scope);
353 ScopedArrayObject entry(scope);
355 name = it.nextPropertyNameAsString();
358 entry = scope.engine->newArrayObject();
359 entry->push_back(name);
364 uint len = a->getLength();
365 ScopedValue value(scope);
366 for (uint i = 0; i < len; ++i) {
367 entry = a->get(PropertyKey::fromArrayIndex(i));
368 name = entry->get(PropertyKey::fromArrayIndex(0));
369 value = o->get(name->toPropertyKey());
370 if (scope.hasException())
371 return Encode::undefined();
372 entry->push_back(value);
375 return a.asReturnedValue();
400ReturnedValue ObjectPrototype::method_freeze(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
402 const Value a = argc ? argv[0] : Value::undefinedValue();
405 return a.asReturnedValue();
408 ScopedObject o(scope, a);
410 if (ArgumentsObject::isNonStrictArgumentsObject(o))
411 static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate();
413 o->setInternalClass(o->internalClass()->cryopreserved());
415 if (o->arrayData()) {
416 ArrayData::ensureAttributes(o);
417 for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
418 if (!o->arrayData()->isEmpty(i))
419 o->arrayData()->attrs[i].setConfigurable(
false);
420 if (o->arrayData()->attrs[i].isData())
421 o->arrayData()->attrs[i].setWritable(
false);
424 return o.asReturnedValue();
560ReturnedValue ObjectPrototype::method_values(
const FunctionObject *f,
const Value *,
const Value *argv,
int argc)
564 return scope.engine->throwTypeError();
566 ScopedObject o(scope, argv[0].toObject(scope.engine));
567 if (scope.hasException())
568 return QV4::Encode::undefined();
570 ScopedArrayObject a(scope, scope.engine->newArrayObject());
572 ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
573 ScopedPropertyKey key(scope);
574 ScopedProperty pd(scope);
575 ScopedValue value(scope);
576 PropertyAttributes attrs;
578 key = it.next(pd, &attrs);
581 value = o->getValue(pd->value, attrs);
585 return a.asReturnedValue();
588ReturnedValue ObjectPrototype::method_toString(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
590 ExecutionEngine *v4 = b->engine();
592 if (thisObject->isUndefined()) {
593 string = QStringLiteral(
"[object Undefined]");
594 }
else if (thisObject->isNull()) {
595 string = QStringLiteral(
"[object Null]");
597 const Object *o = thisObject->as<Object>();
600 if (thisObject->isBoolean())
601 o = v4->booleanPrototype();
602 else if (thisObject->isNumber())
603 o = v4->numberPrototype();
604 else if (thisObject->isString())
605 o = v4->stringPrototype();
606 else if (thisObject->isSymbol())
607 o = v4->symbolPrototype();
610 QString name = o->className();
612 ScopedString toStringTag(scope, o->get(v4->symbol_toStringTag()));
614 name = toStringTag->toQString();
615 string = QStringLiteral(
"[object %1]").arg(name);
617 return Encode(v4->newString(string));
686ReturnedValue ObjectPrototype::method_defineGetter(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
692 ScopedFunctionObject f(scope, argv[1]);
696 ScopedString prop(scope, argv[0], ScopedString::Convert);
697 if (scope.hasException())
698 return QV4::Encode::undefined();
700 ScopedObject o(scope, thisObject);
702 if (!thisObject->isUndefined())
704 o = scope.engine->globalObject;
707 ScopedProperty pd(scope);
709 pd->set = Value::emptyValue();
710 bool ok = o->defineOwnProperty(prop->toPropertyKey(), pd, Attr_Accessor);
716ReturnedValue ObjectPrototype::method_defineSetter(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
722 ScopedFunctionObject f(scope, argv[1]);
726 ScopedString prop(scope, argv[0], ScopedString::Convert);
727 if (scope.hasException())
728 return QV4::Encode::undefined();
730 ScopedObject o(scope, thisObject);
732 if (!thisObject->isUndefined())
734 o = scope.engine->globalObject;
737 ScopedProperty pd(scope);
738 pd->value = Value::emptyValue();
740 bool ok = o->defineOwnProperty(prop->toPropertyKey(), pd, Attr_Accessor);
771void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine,
const Value &v, Property *desc, PropertyAttributes *attrs)
774 ScopedObject o(scope, v);
776 engine->throwTypeError();
781 desc->value = Value::emptyValue();
782 desc->set = Value::emptyValue();
783 ScopedValue tmp(scope);
785 if (o->hasProperty(engine->id_enumerable()->toPropertyKey()))
786 attrs->setEnumerable((tmp = o->get(engine->id_enumerable()))->toBoolean());
788 if (o->hasProperty(engine->id_configurable()->toPropertyKey()))
789 attrs->setConfigurable((tmp = o->get(engine->id_configurable()))->toBoolean());
791 if (o->hasProperty(engine->id_get()->toPropertyKey())) {
792 ScopedValue get(scope, o->get(engine->id_get()));
793 FunctionObject *f = get->as<FunctionObject>();
794 if (f || get->isUndefined()) {
797 engine->throwTypeError();
800 attrs->setType(PropertyAttributes::Accessor);
803 if (o->hasProperty(engine->id_set()->toPropertyKey())) {
804 ScopedValue set(scope, o->get(engine->id_set()));
805 FunctionObject *f = set->as<FunctionObject>();
806 if (f || set->isUndefined()) {
809 engine->throwTypeError();
812 attrs->setType(PropertyAttributes::Accessor);
815 if (o->hasProperty(engine->id_writable()->toPropertyKey())) {
816 if (attrs->isAccessor()) {
817 engine->throwTypeError();
820 attrs->setWritable((tmp = o->get(engine->id_writable()))->toBoolean());
823 if (o->hasProperty(engine->id_value()->toPropertyKey())) {
824 if (attrs->isAccessor()) {
825 engine->throwTypeError();
828 desc->value = o->get(engine->id_value());
829 attrs->setType(PropertyAttributes::Data);
832 if (attrs->isGeneric())
833 desc->value = Value::emptyValue();
837ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionEngine *engine,
const Property *desc, PropertyAttributes attrs)
840 return Encode::undefined();
845 ScopedObject o(scope, engine->newObject());
846 ScopedString s(scope);
847 ScopedValue v(scope);
849 if (attrs.isData()) {
850 s = engine->newString(QStringLiteral(
"value"));
851 o->put(s, desc->value);
852 v = Value::fromBoolean(attrs.isWritable());
853 s = engine->newString(QStringLiteral(
"writable"));
856 v = desc->getter() ? desc->getter()->asReturnedValue() : Encode::undefined();
857 s = engine->newString(QStringLiteral(
"get"));
859 v = desc->setter() ? desc->setter()->asReturnedValue() : Encode::undefined();
860 s = engine->newString(QStringLiteral(
"set"));
863 v = Value::fromBoolean(attrs.isEnumerable());
864 s = engine->newString(QStringLiteral(
"enumerable"));
866 v = Value::fromBoolean(attrs.isConfigurable());
867 s = engine->newString(QStringLiteral(
"configurable"));
870 return o.asReturnedValue();