Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4objectproto.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 Crimson AS <info@crimson.no>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5
6#include "qv4objectproto_p.h"
8#include <private/qv4mm_p.h>
9#include "qv4scopedvalue_p.h"
10#include "qv4objectiterator_p.h"
11#include "qv4symbol_p.h"
12#include "qv4propertykey_p.h"
13
14#include <QtCore/QDateTime>
15#include <QtCore/QStringList>
16
17using namespace QV4;
18
19
21
23{
24 Heap::FunctionObject::init(engine, QStringLiteral("Object"));
25}
26
27ReturnedValue ObjectCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
28{
29 ExecutionEngine *v4 = f->engine();
30 const ObjectCtor *nt = static_cast<const ObjectCtor *>(newTarget);
31 if (!argc || argv[0].isUndefined() || argv[0].isNull()) {
32 Scope scope(v4);
33 ScopedObject obj(scope, scope.engine->newObject());
34 ScopedObject proto(scope, nt->get(scope.engine->id_prototype()));
35 if (!!proto)
36 obj->setPrototypeOf(proto);
37 return obj.asReturnedValue();
38 } else {
39 return argv[0].toObject(v4)->asReturnedValue();
40 }
41}
42
43ReturnedValue ObjectCtor::virtualCall(const FunctionObject *m, const Value *, const Value *argv, int argc)
44{
45 ExecutionEngine *v4 = m->engine();
46 if (!argc || argv[0].isUndefined() || argv[0].isNull()) {
47 return v4->newObject()->asReturnedValue();
48 } else {
49 return argv[0].toObject(v4)->asReturnedValue();
50 }
51}
52
54{
55 Scope scope(v4);
56 ScopedObject o(scope, this);
57
58 ctor->defineReadonlyProperty(v4->id_prototype(), o);
59 ctor->defineReadonlyConfigurableProperty(v4->id_length(), Value::fromInt32(1));
60 ctor->defineDefaultProperty(QStringLiteral("getPrototypeOf"), method_getPrototypeOf, 1);
61 ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyDescriptor"), method_getOwnPropertyDescriptor, 2);
62 ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyDescriptors"), method_getOwnPropertyDescriptors, 1);
63 ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyNames"), method_getOwnPropertyNames, 1);
64 ctor->defineDefaultProperty(QStringLiteral("getOwnPropertySymbols"), method_getOwnPropertySymbols, 1);
65 ctor->defineDefaultProperty(QStringLiteral("assign"), method_assign, 2);
66 ctor->defineDefaultProperty(QStringLiteral("create"), method_create, 2);
67 ctor->defineDefaultProperty(QStringLiteral("defineProperty"), method_defineProperty, 3);
68 ctor->defineDefaultProperty(QStringLiteral("defineProperties"), method_defineProperties, 2);
69 ctor->defineDefaultProperty(QStringLiteral("entries"), method_entries, 1);
70 ctor->defineDefaultProperty(QStringLiteral("seal"), method_seal, 1);
71 ctor->defineDefaultProperty(QStringLiteral("freeze"), method_freeze, 1);
72 ctor->defineDefaultProperty(QStringLiteral("preventExtensions"), method_preventExtensions, 1);
73 ctor->defineDefaultProperty(QStringLiteral("is"), method_is, 2);
74 ctor->defineDefaultProperty(QStringLiteral("isSealed"), method_isSealed, 1);
75 ctor->defineDefaultProperty(QStringLiteral("isFrozen"), method_isFrozen, 1);
76 ctor->defineDefaultProperty(QStringLiteral("isExtensible"), method_isExtensible, 1);
77 ctor->defineDefaultProperty(QStringLiteral("keys"), method_keys, 1);
78 ctor->defineDefaultProperty(QStringLiteral("setPrototypeOf"), method_setPrototypeOf, 2);
79 ctor->defineDefaultProperty(QStringLiteral("values"), method_values, 1);
80
81 defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
82 defineDefaultProperty(v4->id_toString(), method_toString, 0);
83 defineDefaultProperty(v4->id_toLocaleString(), method_toLocaleString, 0);
84 defineDefaultProperty(v4->id_valueOf(), method_valueOf, 0);
85 defineDefaultProperty(QStringLiteral("hasOwnProperty"), method_hasOwnProperty, 1);
86 defineDefaultProperty(QStringLiteral("isPrototypeOf"), method_isPrototypeOf, 1);
87 defineDefaultProperty(QStringLiteral("propertyIsEnumerable"), method_propertyIsEnumerable, 1);
88 defineDefaultProperty(QStringLiteral("__defineGetter__"), method_defineGetter, 2);
89 defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
90
91 defineAccessorProperty(v4->id___proto__(), method_get_proto, method_set_proto);
92}
93
95{
96 Scope scope(b);
97 if (argc < 1)
98 return scope.engine->throwTypeError();
99
100 ScopedObject o(scope, argv[0].toObject(scope.engine));
101 if (scope.hasException())
102 return QV4::Encode::undefined();
103
104 ScopedObject p(scope, o->getPrototypeOf());
105 return (!!p ? p->asReturnedValue() : Encode::null());
106}
107
108ReturnedValue ObjectPrototype::method_is(const FunctionObject *, const Value *, const Value *argv, int argc)
109{
110 if (!argc)
111 return Encode(true);
112 if (argc == 1)
113 return Encode((argv[0].isUndefined() ? true : false));
114 return Encode(argv[0].sameValue(argv[1]));
115}
116
118{
119 Scope scope(b);
120 if (argc < 1)
121 return scope.engine->throwTypeError();
122
123 ScopedObject O(scope, argv[0].toObject(scope.engine));
124 if (scope.hasException())
125 return QV4::Encode::undefined();
126
128 static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate();
129
130 ScopedValue v(scope, argc > 1 ? argv[1] : Value::undefinedValue());
131 ScopedPropertyKey name(scope, v->toPropertyKey(scope.engine));
132 if (scope.hasException())
133 return QV4::Encode::undefined();
134
135 ScopedProperty desc(scope);
136 PropertyAttributes attrs = O->getOwnProperty(name, desc);
137 return fromPropertyDescriptor(scope.engine, desc, attrs);
138}
139
141{
142 Scope scope(f);
143 if (!argc)
144 return scope.engine->throwTypeError();
145
146 ScopedObject o(scope, argv[0].toObject(scope.engine));
147 if (scope.hasException())
148 return Encode::undefined();
149
150 ScopedObject descriptors(scope, scope.engine->newObject());
151
153 ScopedProperty pd(scope);
155 ScopedPropertyKey key(scope);
156 ScopedObject entry(scope);
157 while (1) {
158 key = it.next(pd, &attrs);
159 if (!key->isValid())
160 break;
161 entry = fromPropertyDescriptor(scope.engine, pd, attrs);
162 descriptors->put(key, entry);
163 }
164
165 return descriptors.asReturnedValue();
166
167}
168
170{
171 Scope scope(b);
172 if (argc < 1)
173 return scope.engine->throwTypeError();
174
175 ScopedObject O(scope, argv[0].toObject(scope.engine));
176 if (scope.hasException())
177 return QV4::Encode::undefined();
178
179 return Encode(getOwnPropertyNames(scope.engine, argv[0]));
180}
181
183{
184 Scope scope(f);
185 if (!argc)
186 return scope.engine->throwTypeError();
187
188 ScopedObject O(scope, argv[0].toObject(scope.engine));
189 if (!O)
190 return Encode::undefined();
191
193 if (O) {
195 ScopedValue name(scope);
196 while (1) {
197 name = it.nextPropertyNameAsString();
198 if (name->isNull())
199 break;
200 if (!name->isSymbol())
201 continue;
202 array->push_back(name);
203 }
204 }
205 return array->asReturnedValue();
206}
207
208// 19.1.2.1
210{
211 Scope scope(b);
212 if (argc < 1)
213 return scope.engine->throwTypeError();
214
215 ScopedObject to(scope, argv[0].toObject(scope.engine));
216 if (scope.hasException())
217 return QV4::Encode::undefined();
218
219 if (argc == 1)
220 return to.asReturnedValue();
221
222 for (int i = 1, ei = argc; i < ei; ++i) {
223 if (argv[i].isUndefined() || argv[i].isNull())
224 continue;
225
226 ScopedObject from(scope, argv[i].toObject(scope.engine));
227 if (scope.hasException())
228 return QV4::Encode::undefined();
230 quint32 length = keys->getLength();
231
232 ScopedString nextKey(scope);
233 ScopedValue propValue(scope);
234 for (quint32 i = 0; i < length; ++i) {
235 nextKey = Value::fromReturnedValue(keys->get(i)).toString(scope.engine);
236
237 ScopedProperty prop(scope);
238 PropertyAttributes attrs = from->getOwnProperty(nextKey->toPropertyKey(), prop);
239
241 continue;
242
243 if (!attrs.isEnumerable())
244 continue;
245
246 propValue = from->get(nextKey);
247 to->set(nextKey, propValue, Object::DoThrowOnRejection);
248 if (scope.hasException())
249 return QV4::Encode::undefined();
250 }
251 }
252
253 return to.asReturnedValue();
254}
255
256ReturnedValue ObjectPrototype::method_create(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
257{
258 Scope scope(builtin);
259 if (!argc || (!argv[0].isObject() && !argv[0].isNull()))
260 return scope.engine->throwTypeError();
261
262 ScopedObject O(scope, argv[0]);
263
264 ScopedObject newObject(scope, scope.engine->newObject());
265 newObject->setPrototypeOf(O);
266
267
268 if (argc > 1 && !argv[1].isUndefined()) {
269 Value *arguments = scope.alloc(argc);
270 arguments[0] = newObject;
271 memcpy(arguments + 1, argv + 1, (argc - 1)*sizeof(Value));
272 return method_defineProperties(builtin, thisObject, arguments, argc);
273 }
274
275 return newObject.asReturnedValue();
276}
277
279{
280 Scope scope(b);
281 if (!argc || !argv[0].isObject())
282 return scope.engine->throwTypeError();
283
284 ScopedObject O(scope, argv[0]);
285 ScopedPropertyKey name(scope, (argc > 1 ? argv[1] : Value::undefinedValue()).toPropertyKey(scope.engine));
286 if (scope.hasException())
287 return QV4::Encode::undefined();
288
289 ScopedValue attributes(scope, argc > 2 ? argv[2] : Value::undefinedValue());
290 ScopedProperty pd(scope);
292 toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
293 if (scope.hasException())
294 return QV4::Encode::undefined();
295
296 if (!O->defineOwnProperty(name, pd, attrs))
298
299 return O.asReturnedValue();
300}
301
303{
304 Scope scope(b);
305 if (argc < 2 || !argv[0].isObject())
306 return scope.engine->throwTypeError();
307
308 ScopedObject O(scope, argv[0]);
309
310 ScopedObject o(scope, argv[1].toObject(scope.engine));
311 if (scope.hasException())
312 return QV4::Encode::undefined();
313
314 ScopedValue val(scope);
315
317 ScopedProperty pd(scope);
318 ScopedProperty n(scope);
319 ScopedPropertyKey key(scope);
320 while (1) {
322 key = it.next(pd, &attrs);
323 if (!key->isValid())
324 break;
325 PropertyAttributes nattrs;
326 val = o->getValue(pd->value, attrs);
327 toPropertyDescriptor(scope.engine, val, n, &nattrs);
328 if (scope.hasException())
329 return QV4::Encode::undefined();
330 bool ok = O->defineOwnProperty(key, n, nattrs);
331 if (!ok)
333 }
334
335 return O.asReturnedValue();
336}
337
339{
340 Scope scope(f);
341 if (!argc)
342 return scope.engine->throwTypeError();
343
344 ScopedObject o(scope, argv[0].toObject(scope.engine));
345 if (scope.hasException())
346 return Encode::undefined();
347
348 ScopedArrayObject a(scope, scope.engine->newArrayObject());
349
351 ScopedString name(scope);
353 while (1) {
354 name = it.nextPropertyNameAsString();
355 if (!name)
356 break;
357 entry = scope.engine->newArrayObject();
359 a->push_back(entry);
360 }
361
362 // now add values, do this after the loop above as reading out the values can have side effects
363 uint len = a->getLength();
364 ScopedValue value(scope);
365 for (uint i = 0; i < len; ++i) {
368 value = o->get(name->toPropertyKey());
369 if (scope.hasException())
370 return Encode::undefined();
371 entry->push_back(value);
372 }
373
374 return a.asReturnedValue();
375}
376
378{
379 const Value a = argc ? argv[0] : Value::undefinedValue();
380 if (!a.isObject())
381 // 19.1.2.17, 1
382 return a.asReturnedValue();
383
384 Scope scope(b);
385 ScopedObject o(scope, a);
386 o->setInternalClass(o->internalClass()->canned());
387
388 if (o->arrayData()) {
390 for (uint i = 0; i < o->d()->arrayData->values.alloc; ++i) {
391 if (!o->arrayData()->isEmpty(i))
392 o->d()->arrayData->attrs[i].setConfigurable(false);
393 }
394 }
395
396 return o.asReturnedValue();
397}
398
400{
401 const Value a = argc ? argv[0] : Value::undefinedValue();
402 if (!a.isObject())
403 // 19.1.2.5, 1
404 return a.asReturnedValue();
405
406 Scope scope(b);
407 ScopedObject o(scope, a);
408
410 static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate();
411
412 o->setInternalClass(o->internalClass()->cryopreserved());
413
414 if (o->arrayData()) {
416 for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
417 if (!o->arrayData()->isEmpty(i))
418 o->arrayData()->attrs[i].setConfigurable(false);
419 if (o->arrayData()->attrs[i].isData())
420 o->arrayData()->attrs[i].setWritable(false);
421 }
422 }
423 return o.asReturnedValue();
424}
425
427{
428 Scope scope(b);
429 if (!argc)
430 return Encode::undefined();
431
432 ScopedObject o(scope, argv[0]);
433 if (!o)
434 return argv[0].asReturnedValue();
435
436 o->preventExtensions();
437 return o.asReturnedValue();
438}
439
441{
442 Scope scope(b);
443 if (!argc)
444 return Encode(true);
445
446 ScopedObject o(scope, argv[0]);
447 if (!o)
448 return Encode(true);
449
450 if (o->isExtensible())
451 return Encode(false);
452
453 if (o->internalClass() != o->internalClass()->canned())
454 return Encode(false);
455
456 if (!o->arrayData() || !o->arrayData()->length())
457 return Encode(true);
458
459 Q_ASSERT(o->arrayData() && o->arrayData()->length());
460 if (!o->arrayData()->attrs)
461 return Encode(false);
462
463 for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
464 if (!o->arrayData()->isEmpty(i))
465 if (o->arrayData()->attributes(i).isConfigurable())
466 return Encode(false);
467 }
468
469 return Encode(true);
470}
471
473{
474 Scope scope(b);
475 if (!argc)
476 return Encode(true);
477
478 ScopedObject o(scope, argv[0]);
479 if (!o)
480 return Encode(true);
481
482 if (o->isExtensible())
483 return Encode(false);
484
485 if (!o->internalClass()->isImplicitlyFrozen())
486 return Encode(false);
487
488 if (!o->arrayData() || !o->arrayData()->length())
489 return Encode(true);
490
491 Q_ASSERT(o->arrayData() && o->arrayData()->length());
492 if (!o->arrayData()->attrs)
493 return Encode(false);
494
495 for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
496 if (!o->arrayData()->isEmpty(i))
497 if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable())
498 return Encode(false);
499 }
500
501 return Encode(true);
502}
503
505{
506 Scope scope(b);
507 if (!argc)
508 return Encode(false);
509
510 ScopedObject o(scope, argv[0]);
511 if (!o)
512 return Encode(false);
513
514 return Encode((bool)o->isExtensible());
515}
516
518{
519 Scope scope(b);
520 if (!argc)
521 return scope.engine->throwTypeError();
522
523 ScopedObject o(scope, argv[0].toObject(scope.engine));
524 if (scope.hasException())
525 return QV4::Encode::undefined();
526
527 ScopedArrayObject a(scope, scope.engine->newArrayObject());
528
530 ScopedValue name(scope);
531 ScopedValue value(scope);
532 while (1) {
533 name = it.nextPropertyNameAsString(value);
534 if (name->isNull())
535 break;
536 a->push_back(name);
537 }
538
539 return a.asReturnedValue();
540}
541
543{
544 Scope scope(f->engine());
545 if (argc < 2 || argv[0].isNullOrUndefined() || !(argv[1].isObject() || argv[1].isNull()))
546 return scope.engine->throwTypeError();
547
548 if (!argv[0].isObject())
549 return argv[0].asReturnedValue();
550
551 ScopedObject o(scope, argv[0]);
552 const Object *p = argv[1].isNull() ? nullptr : static_cast<const Object *>(argv + 1);
553 bool ok = o->setPrototypeOf(p);
554 if (!ok)
555 return scope.engine->throwTypeError(QStringLiteral("Could not change prototype."));
556 return o->asReturnedValue();
557}
558
560{
561 Scope scope(f);
562 if (!argc)
563 return scope.engine->throwTypeError();
564
565 ScopedObject o(scope, argv[0].toObject(scope.engine));
566 if (scope.hasException())
567 return QV4::Encode::undefined();
568
569 ScopedArrayObject a(scope, scope.engine->newArrayObject());
570
572 ScopedPropertyKey key(scope);
573 ScopedProperty pd(scope);
574 ScopedValue value(scope);
576 while (1) {
577 key = it.next(pd, &attrs);
578 if (!key->isValid())
579 break;
580 value = o->getValue(pd->value, attrs);
581 a->push_back(value);
582 }
583
584 return a.asReturnedValue();
585}
586
588{
589 ExecutionEngine *v4 = b->engine();
591 if (thisObject->isUndefined()) {
592 string = QStringLiteral("[object Undefined]");
593 } else if (thisObject->isNull()) {
594 string = QStringLiteral("[object Null]");
595 } else {
596 const Object *o = thisObject->as<Object>();
597 if (!o) {
598 // primitive, get the proper prototype
599 if (thisObject->isBoolean())
600 o = v4->booleanPrototype();
601 else if (thisObject->isNumber())
602 o = v4->numberPrototype();
603 else if (thisObject->isString())
604 o = v4->stringPrototype();
605 else if (thisObject->isSymbol())
606 o = v4->symbolPrototype();
607 Q_ASSERT(o);
608 }
609 QString name = o->className();
610 Scope scope(v4);
611 ScopedString toStringTag(scope, o->get(v4->symbol_toStringTag()));
612 if (toStringTag)
613 name = toStringTag->toQString();
614 string = QStringLiteral("[object %1]").arg(name);
615 }
616 return Encode(v4->newString(string));
617}
618
619ReturnedValue ObjectPrototype::method_toLocaleString(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
620{
621 Scope scope(b);
623 ScopedObject o(scope, thisObject->toObject(scope.engine));
624 if (!o)
626
627 ScopedFunctionObject f(scope, o->get(scope.engine->id_toString()));
628 if (!f)
630
631 return checkedResult(scope.engine, f->call(thisObject, argv, argc));
632}
633
635{
636 return Encode(thisObject->toObject(b->engine()));
637}
638
639ReturnedValue ObjectPrototype::method_hasOwnProperty(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
640{
641 Scope scope(b);
642 ScopedPropertyKey P(scope, (argc ? argv[0] : Value::undefinedValue()).toPropertyKey(scope.engine));
643 if (scope.hasException())
644 return QV4::Encode::undefined();
645 ScopedObject O(scope, thisObject->toObject(scope.engine));
646 if (scope.hasException())
647 return QV4::Encode::undefined();
648 bool r = O->getOwnProperty(P) != Attr_Invalid;
649 return Encode(r);
650}
651
652ReturnedValue ObjectPrototype::method_isPrototypeOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
653{
654 Scope scope(b);
655 if (!argc || !argv[0].isObject())
656 return Encode(false);
657
658 ScopedObject V(scope, argv[0]);
659 ScopedObject O(scope, thisObject->toObject(scope.engine));
660 if (scope.hasException())
661 return QV4::Encode::undefined();
662 ScopedObject proto(scope, V->getPrototypeOf());
663 while (proto) {
664 if (O->d() == proto->d())
665 return Encode(true);
666 proto = proto->getPrototypeOf();
667 }
668 return Encode(false);
669}
670
672{
673 Scope scope(b);
674 ScopedPropertyKey p(scope, (argc ? argv[0] : Value::undefinedValue()).toPropertyKey(scope.engine));
675 if (scope.hasException())
676 return QV4::Encode::undefined();
677
678 ScopedObject o(scope, thisObject->toObject(scope.engine));
679 if (scope.hasException())
680 return QV4::Encode::undefined();
681 PropertyAttributes attrs = o->getOwnProperty(p);
682 return Encode(attrs.isEnumerable());
683}
684
685ReturnedValue ObjectPrototype::method_defineGetter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
686{
687 Scope scope(b);
688 if (argc < 2)
690
691 ScopedFunctionObject f(scope, argv[1]);
692 if (!f)
694
695 ScopedString prop(scope, argv[0], ScopedString::Convert);
696 if (scope.hasException())
697 return QV4::Encode::undefined();
698
699 ScopedObject o(scope, thisObject);
700 if (!o) {
701 if (!thisObject->isUndefined())
703 o = scope.engine->globalObject;
704 }
705
706 ScopedProperty pd(scope);
707 pd->value = f;
708 pd->set = Value::emptyValue();
709 bool ok = o->defineOwnProperty(prop->toPropertyKey(), pd, Attr_Accessor);
710 if (!ok)
713}
714
715ReturnedValue ObjectPrototype::method_defineSetter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
716{
717 Scope scope(b);
718 if (argc < 2)
720
721 ScopedFunctionObject f(scope, argv[1]);
722 if (!f)
724
725 ScopedString prop(scope, argv[0], ScopedString::Convert);
726 if (scope.hasException())
727 return QV4::Encode::undefined();
728
729 ScopedObject o(scope, thisObject);
730 if (!o) {
731 if (!thisObject->isUndefined())
733 o = scope.engine->globalObject;
734 }
735
736 ScopedProperty pd(scope);
737 pd->value = Value::emptyValue();
738 pd->set = f;
739 bool ok = o->defineOwnProperty(prop->toPropertyKey(), pd, Attr_Accessor);
740 if (!ok)
743}
744
746{
747 Scope scope(b);
748 ScopedObject o(scope, thisObject->as<Object>());
749 if (!o)
751
752 return Encode(o->getPrototypeOf());
753}
754
755ReturnedValue ObjectPrototype::method_set_proto(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
756{
757 Scope scope(b);
758 ScopedObject o(scope, thisObject);
759 if (!o || !argc || (!argv[0].isObject() && !argv[0].isNull()))
761
762 const Object *p = argv[0].isNull() ? nullptr : static_cast<const Object *>(argv);
763 bool ok = o->setPrototypeOf(p);
764 if (!ok)
765 return scope.engine->throwTypeError(QStringLiteral("Could not change prototype."));
766 return Encode::undefined();
768}
769
771{
772 Scope scope(engine);
773 ScopedObject o(scope, v);
774 if (!o) {
775 engine->throwTypeError();
776 return;
777 }
778
779 attrs->clear();
780 desc->value = Value::emptyValue();
781 desc->set = Value::emptyValue();
782 ScopedValue tmp(scope);
783
784 if (o->hasProperty(engine->id_enumerable()->toPropertyKey()))
785 attrs->setEnumerable((tmp = o->get(engine->id_enumerable()))->toBoolean());
786
787 if (o->hasProperty(engine->id_configurable()->toPropertyKey()))
788 attrs->setConfigurable((tmp = o->get(engine->id_configurable()))->toBoolean());
789
790 if (o->hasProperty(engine->id_get()->toPropertyKey())) {
791 ScopedValue get(scope, o->get(engine->id_get()));
793 if (f || get->isUndefined()) {
794 desc->value = get;
795 } else {
796 engine->throwTypeError();
797 return;
798 }
800 }
801
802 if (o->hasProperty(engine->id_set()->toPropertyKey())) {
803 ScopedValue set(scope, o->get(engine->id_set()));
805 if (f || set->isUndefined()) {
806 desc->set = set;
807 } else {
808 engine->throwTypeError();
809 return;
810 }
812 }
813
814 if (o->hasProperty(engine->id_writable()->toPropertyKey())) {
815 if (attrs->isAccessor()) {
816 engine->throwTypeError();
817 return;
818 }
819 attrs->setWritable((tmp = o->get(engine->id_writable()))->toBoolean());
820 }
821
822 if (o->hasProperty(engine->id_value()->toPropertyKey())) {
823 if (attrs->isAccessor()) {
824 engine->throwTypeError();
825 return;
826 }
827 desc->value = o->get(engine->id_value());
829 }
830
831 if (attrs->isGeneric())
832 desc->value = Value::emptyValue();
833}
834
835
837{
838 if (attrs.isEmpty())
839 return Encode::undefined();
840
841 Scope scope(engine);
842 // Let obj be the result of creating a new object as if by the expression new Object() where Object
843 // is the standard built-in constructor with that name.
844 ScopedObject o(scope, engine->newObject());
845 ScopedString s(scope);
846 ScopedValue v(scope);
847
848 if (attrs.isData()) {
849 s = engine->newString(QStringLiteral("value"));
850 o->put(s, desc->value);
851 v = Value::fromBoolean(attrs.isWritable());
852 s = engine->newString(QStringLiteral("writable"));
853 o->put(s, v);
854 } else {
855 v = desc->getter() ? desc->getter()->asReturnedValue() : Encode::undefined();
856 s = engine->newString(QStringLiteral("get"));
857 o->put(s, v);
858 v = desc->setter() ? desc->setter()->asReturnedValue() : Encode::undefined();
859 s = engine->newString(QStringLiteral("set"));
860 o->put(s, v);
861 }
862 v = Value::fromBoolean(attrs.isEnumerable());
863 s = engine->newString(QStringLiteral("enumerable"));
864 o->put(s, v);
865 v = Value::fromBoolean(attrs.isConfigurable());
866 s = engine->newString(QStringLiteral("configurable"));
867 o->put(s, v);
868
869 return o.asReturnedValue();
870}
871
872// es6: GetOwnPropertyKeys
874{
875 Scope scope(v4);
877 ScopedObject O(scope, o.toObject(v4));
878 if (O) {
880 ScopedValue name(scope);
881 while (1) {
882 name = it.nextPropertyNameAsString();
883 if (name->isNull())
884 break;
885 if (name->isSymbol())
886 continue;
887 array->push_back(name);
888 }
889 }
890 return array->d();
891}
QJSValue newObject()
Creates a JavaScript object of class Object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QSet< QString >::iterator it
QList< QVariant > arguments
Scoped< FunctionObject > ScopedFunctionObject
quint64 ReturnedValue
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
Scoped< String > ScopedString
@ Attr_Invalid
@ Attr_Accessor
static QDBusError::ErrorType get(const char *name)
static struct AttrInfo attrs[]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLenum GLuint GLenum GLsizei length
GLfloat GLfloat f
GLuint name
GLfloat n
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLfloat * val
GLuint entry
GLenum array
GLfloat GLfloat p
[1]
GLenum GLsizei len
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
unsigned int quint32
Definition qtypes.h:50
unsigned int uint
Definition qtypes.h:34
#define CHECK_STACK_LIMITS(v4)
#define THROW_TYPE_ERROR()
#define RETURN_UNDEFINED()
#define DEFINE_OBJECT_VTABLE(classname)
QFuture< QSet< QChar > > set
[10]
QStringList keys
QObject::connect nullptr
QJSEngine engine
[0]
static bool isNonStrictArgumentsObject(Managed *m)
static void ensureAttributes(Object *o)
static constexpr ReturnedValue undefined()
static constexpr ReturnedValue null()
Object * stringPrototype() const
String * id_length() const
String * id_toString() const
String * id_prototype() const
Object * numberPrototype() const
Heap::Object * newObject()
String * id___proto__() const
String * id_toLocaleString() const
Symbol * symbol_toStringTag() const
Heap::String * newString(char16_t c)
Object * booleanPrototype() const
Object * symbolPrototype() const
Heap::ArrayObject * newArrayObject(int count=0)
String * id_valueOf() const
ReturnedValue throwTypeError()
void init(ExecutionEngine *engine)
ExecutionEngine * engine() const
static ReturnedValue method_defineProperties(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_set_proto(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_propertyIsEnumerable(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_entries(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getOwnPropertyNames(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getOwnPropertyDescriptor(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_defineProperty(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getPrototypeOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_create(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getOwnPropertyDescriptors(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_hasOwnProperty(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_seal(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static void toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs)
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_proto(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getOwnPropertySymbols(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_isSealed(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_isExtensible(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_keys(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_values(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_preventExtensions(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue fromPropertyDescriptor(ExecutionEngine *engine, const Property *desc, PropertyAttributes attrs)
static Heap::ArrayObject * getOwnPropertyNames(ExecutionEngine *v4, const Value &o)
static ReturnedValue method_assign(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_isFrozen(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_defineSetter(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_defineGetter(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_is(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setPrototypeOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_isPrototypeOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_freeze(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
PropertyAttributes getOwnProperty(PropertyKey id, Property *p=nullptr) const
bool put(StringOrSymbol *name, const Value &v, Value *receiver=nullptr)
bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
bool setPrototypeOf(const Object *p)
void push_back(const Value &v)
Heap::Object * getPrototypeOf() const
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
static PropertyKey fromArrayIndex(uint idx)
Value * alloc(qint64 nValues) const =delete
bool hasException() const
ExecutionEngine * engine
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
bool isNumber() const
constexpr ReturnedValue asReturnedValue() const
bool isBoolean() const
bool isUndefined() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
bool isString() const
Definition qv4value_p.h:284
static constexpr Value fromBoolean(bool b)
Definition qv4value_p.h:183
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
const T * as() const
Definition qv4value_p.h:132
static constexpr Value emptyValue()
Definition qv4value_p.h:179
bool isSymbol() const
Definition qv4value_p.h:296
Heap::Object * toObject(ExecutionEngine *e) const
Definition qv4value_p.h:122