Coverage Report

Created: 2026-02-14 08:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3
 * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#include <AK/Function.h>
9
#include <LibJS/Runtime/AbstractOperations.h>
10
#include <LibJS/Runtime/Array.h>
11
#include <LibJS/Runtime/Error.h>
12
#include <LibJS/Runtime/GlobalObject.h>
13
#include <LibJS/Runtime/Iterator.h>
14
#include <LibJS/Runtime/ObjectConstructor.h>
15
#include <LibJS/Runtime/ProxyObject.h>
16
#include <LibJS/Runtime/Shape.h>
17
18
namespace JS {
19
20
JS_DEFINE_ALLOCATOR(ObjectConstructor);
21
22
ObjectConstructor::ObjectConstructor(Realm& realm)
23
0
    : NativeFunction(realm.vm().names.Object.as_string(), realm.intrinsics().function_prototype())
24
0
{
25
0
}
26
27
void ObjectConstructor::initialize(Realm& realm)
28
0
{
29
0
    auto& vm = this->vm();
30
0
    Base::initialize(realm);
31
32
    // 20.1.2.21 Object.prototype, https://tc39.es/ecma262/#sec-object.prototype
33
0
    define_direct_property(vm.names.prototype, realm.intrinsics().object_prototype(), 0);
34
35
0
    u8 attr = Attribute::Writable | Attribute::Configurable;
36
0
    define_native_function(realm, vm.names.defineProperty, define_property, 3, attr);
37
0
    define_native_function(realm, vm.names.defineProperties, define_properties, 2, attr);
38
0
    define_native_function(realm, vm.names.is, is, 2, attr);
39
0
    define_native_function(realm, vm.names.getOwnPropertyDescriptor, get_own_property_descriptor, 2, attr);
40
0
    define_native_function(realm, vm.names.getOwnPropertyDescriptors, get_own_property_descriptors, 1, attr);
41
0
    define_native_function(realm, vm.names.getOwnPropertyNames, get_own_property_names, 1, attr);
42
0
    define_native_function(realm, vm.names.getOwnPropertySymbols, get_own_property_symbols, 1, attr);
43
0
    define_native_function(realm, vm.names.getPrototypeOf, get_prototype_of, 1, attr);
44
0
    define_native_function(realm, vm.names.groupBy, group_by, 2, attr);
45
0
    define_native_function(realm, vm.names.setPrototypeOf, set_prototype_of, 2, attr);
46
0
    define_native_function(realm, vm.names.isExtensible, is_extensible, 1, attr);
47
0
    define_native_function(realm, vm.names.isFrozen, is_frozen, 1, attr);
48
0
    define_native_function(realm, vm.names.isSealed, is_sealed, 1, attr);
49
0
    define_native_function(realm, vm.names.preventExtensions, prevent_extensions, 1, attr);
50
0
    define_native_function(realm, vm.names.freeze, freeze, 1, attr);
51
0
    define_native_function(realm, vm.names.fromEntries, from_entries, 1, attr);
52
0
    define_native_function(realm, vm.names.seal, seal, 1, attr);
53
0
    define_native_function(realm, vm.names.keys, keys, 1, attr);
54
0
    define_native_function(realm, vm.names.values, values, 1, attr);
55
0
    define_native_function(realm, vm.names.entries, entries, 1, attr);
56
0
    define_native_function(realm, vm.names.create, create, 2, attr);
57
0
    define_native_function(realm, vm.names.hasOwn, has_own, 2, attr);
58
0
    define_native_function(realm, vm.names.assign, assign, 2, attr);
59
60
0
    define_direct_property(vm.names.length, Value(1), Attribute::Configurable);
61
0
}
62
63
// 20.1.1.1 Object ( [ value ] ), https://tc39.es/ecma262/#sec-object-value
64
ThrowCompletionOr<Value> ObjectConstructor::call()
65
0
{
66
0
    return TRY(construct(*this));
67
0
}
68
69
// 20.1.1.1 Object ( [ value ] ), https://tc39.es/ecma262/#sec-object-value
70
ThrowCompletionOr<NonnullGCPtr<Object>> ObjectConstructor::construct(FunctionObject& new_target)
71
0
{
72
0
    auto& vm = this->vm();
73
0
    auto& realm = *vm.current_realm();
74
0
    auto value = vm.argument(0);
75
76
    // 1. If NewTarget is neither undefined nor the active function object, then
77
0
    if (&new_target != this) {
78
        // a. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
79
0
        return TRY(ordinary_create_from_constructor<Object>(vm, new_target, &Intrinsics::object_prototype, ConstructWithPrototypeTag::Tag));
80
0
    }
81
82
    // 2. If value is either undefined or null, return OrdinaryObjectCreate(%Object.prototype%).
83
0
    if (value.is_nullish())
84
0
        return Object::create(realm, realm.intrinsics().object_prototype());
85
86
    // 3. Return ! ToObject(value).
87
0
    return MUST(value.to_object(vm));
88
0
}
89
90
enum class GetOwnPropertyKeysType {
91
    String,
92
    Symbol,
93
};
94
95
// 20.1.2.11.1 GetOwnPropertyKeys ( O, type ), https://tc39.es/ecma262/#sec-getownpropertykeys
96
static ThrowCompletionOr<MarkedVector<Value>> get_own_property_keys(VM& vm, Value value, GetOwnPropertyKeysType type)
97
0
{
98
    // 1. Let obj be ? ToObject(O).
99
0
    auto object = TRY(value.to_object(vm));
100
101
    // 2. Let keys be ? obj.[[OwnPropertyKeys]]().
102
0
    auto keys = TRY(object->internal_own_property_keys());
103
104
    // 3. Let nameList be a new empty List.
105
0
    auto name_list = MarkedVector<Value> { vm.heap() };
106
107
    // 4. For each element nextKey of keys, do
108
0
    for (auto& next_key : keys) {
109
        // a. If Type(nextKey) is Symbol and type is symbol or Type(nextKey) is String and type is string, then
110
0
        if ((next_key.is_symbol() && type == GetOwnPropertyKeysType::Symbol) || (next_key.is_string() && type == GetOwnPropertyKeysType::String)) {
111
            // i. Append nextKey as the last element of nameList.
112
0
            name_list.append(next_key);
113
0
        }
114
0
    }
115
116
    // 5. Return nameList.
117
0
    return { move(name_list) };
118
0
}
119
120
// 20.1.2.1 Object.assign ( target, ...sources ), https://tc39.es/ecma262/#sec-object.assign
121
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign)
122
0
{
123
    // 1. Let to be ? ToObject(target).
124
0
    auto to = TRY(vm.argument(0).to_object(vm));
125
126
    // 2. If only one argument was passed, return to.
127
0
    if (vm.argument_count() == 1)
128
0
        return to;
129
130
    // 3. For each element nextSource of sources, do
131
0
    for (size_t i = 1; i < vm.argument_count(); ++i) {
132
0
        auto next_source = vm.argument(i);
133
134
        // a. If nextSource is neither undefined nor null, then
135
0
        if (next_source.is_nullish())
136
0
            continue;
137
138
        // i. Let from be ! ToObject(nextSource).
139
0
        auto from = MUST(next_source.to_object(vm));
140
141
        // ii. Let keys be ? from.[[OwnPropertyKeys]]().
142
0
        auto keys = TRY(from->internal_own_property_keys());
143
144
        // iii. For each element nextKey of keys, do
145
0
        for (auto& next_key : keys) {
146
0
            auto property_key = MUST(PropertyKey::from_value(vm, next_key));
147
148
            // 1. Let desc be ? from.[[GetOwnProperty]](nextKey).
149
0
            auto desc = TRY(from->internal_get_own_property(property_key));
150
151
            // 2. If desc is not undefined and desc.[[Enumerable]] is true, then
152
0
            if (!desc.has_value() || !*desc->enumerable)
153
0
                continue;
154
155
            // a. Let propValue be ? Get(from, nextKey).
156
0
            auto prop_value = TRY(from->get(property_key));
157
158
            // b. Perform ? Set(to, nextKey, propValue, true).
159
0
            TRY(to->set(property_key, prop_value, Object::ShouldThrowExceptions::Yes));
160
0
        }
161
0
    }
162
163
    // 4. Return to.
164
0
    return to;
165
0
}
166
167
// 20.1.2.2 Object.create ( O, Properties ), https://tc39.es/ecma262/#sec-object.create
168
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
169
0
{
170
0
    auto& realm = *vm.current_realm();
171
172
0
    auto proto = vm.argument(0);
173
0
    auto properties = vm.argument(1);
174
175
    // 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
176
0
    if (!proto.is_object() && !proto.is_null())
177
0
        return vm.throw_completion<TypeError>(ErrorType::ObjectPrototypeWrongType);
178
179
    // 2. Let obj be OrdinaryObjectCreate(O).
180
0
    auto object = Object::create(realm, proto.is_null() ? nullptr : &proto.as_object());
181
182
    // 3. If Properties is not undefined, then
183
0
    if (!properties.is_undefined()) {
184
        // a. Return ? ObjectDefineProperties(obj, Properties).
185
0
        return TRY(object->define_properties(properties));
186
0
    }
187
188
    // 4. Return obj.
189
0
    return object;
190
0
}
191
192
// 20.1.2.3 Object.defineProperties ( O, Properties ), https://tc39.es/ecma262/#sec-object.defineproperties
193
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_properties)
194
0
{
195
0
    auto object = vm.argument(0);
196
0
    auto properties = vm.argument(1);
197
198
    // 1. If Type(O) is not Object, throw a TypeError exception.
199
0
    if (!object.is_object())
200
0
        return vm.throw_completion<TypeError>(ErrorType::NotAnObject, "Object argument");
201
202
    // 2. Return ? ObjectDefineProperties(O, Properties).
203
0
    return TRY(object.as_object().define_properties(properties));
204
0
}
205
206
// 20.1.2.4 Object.defineProperty ( O, P, Attributes ), https://tc39.es/ecma262/#sec-object.defineproperty
207
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property)
208
0
{
209
    // 1. If O is not an Object, throw a TypeError exception.
210
0
    if (!vm.argument(0).is_object())
211
0
        return vm.throw_completion<TypeError>(ErrorType::NotAnObject, vm.argument(0).to_string_without_side_effects());
212
213
0
    auto object = MUST(vm.argument(0).to_object(vm));
214
215
    // 2. Let key be ? ToPropertyKey(P).
216
0
    auto key = TRY(vm.argument(1).to_property_key(vm));
217
218
    // 3. Let desc be ? ToPropertyDescriptor(Attributes).
219
0
    auto descriptor = TRY(to_property_descriptor(vm, vm.argument(2)));
220
221
    // 4. Perform ? DefinePropertyOrThrow(O, key, desc).
222
0
    TRY(object->define_property_or_throw(key, descriptor));
223
224
    // 5. Return O.
225
0
    return object;
226
0
}
227
228
// 20.1.2.5 Object.entries ( O ), https://tc39.es/ecma262/#sec-object.entries
229
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
230
0
{
231
0
    auto& realm = *vm.current_realm();
232
233
    // 1. Let obj be ? ToObject(O).
234
0
    auto object = TRY(vm.argument(0).to_object(vm));
235
236
    // 2. Let entryList be ? EnumerableOwnProperties(obj, key+value).
237
0
    auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::KeyAndValue));
238
239
    // 3. Return CreateArrayFromList(entryList).
240
0
    return Array::create_from(realm, name_list);
241
0
}
242
243
// 20.1.2.6 Object.freeze ( O ), https://tc39.es/ecma262/#sec-object.freeze
244
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::freeze)
245
0
{
246
0
    auto argument = vm.argument(0);
247
248
    // 1. If O is not an Object, return O.
249
0
    if (!argument.is_object())
250
0
        return argument;
251
252
    // 2. Let status be ? SetIntegrityLevel(O, frozen).
253
0
    auto status = TRY(argument.as_object().set_integrity_level(Object::IntegrityLevel::Frozen));
254
255
    // 3. If status is false, throw a TypeError exception.
256
0
    if (!status)
257
0
        return vm.throw_completion<TypeError>(ErrorType::ObjectFreezeFailed);
258
259
    // 4. Return O.
260
0
    return argument;
261
0
}
262
263
// 20.1.2.7 Object.fromEntries ( iterable ), https://tc39.es/ecma262/#sec-object.fromentries
264
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries)
265
0
{
266
0
    auto& realm = *vm.current_realm();
267
268
    // 1. Perform ? RequireObjectCoercible(iterable).
269
0
    auto iterable = TRY(require_object_coercible(vm, vm.argument(0)));
270
271
    // 2. Let obj be OrdinaryObjectCreate(%Object.prototype%).
272
0
    auto object = Object::create(realm, realm.intrinsics().object_prototype());
273
274
    // 3. Assert: obj is an extensible ordinary object with no own properties.
275
276
    // 4. Let closure be a new Abstract Closure with parameters (key, value) that captures obj and performs the following steps when called:
277
    // 5. Let adder be CreateBuiltinFunction(closure, 2, "", « »).
278
    // 6. Return ? AddEntriesFromIterable(obj, iterable, adder).
279
0
    (void)TRY(get_iterator_values(vm, iterable, [&](Value iterator_value) -> Optional<Completion> {
280
0
        if (!iterator_value.is_object())
281
0
            return vm.throw_completion<TypeError>(ErrorType::NotAnObject, ByteString::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));
282
283
0
        auto key = TRY(iterator_value.as_object().get(0));
284
0
        auto value = TRY(iterator_value.as_object().get(1));
285
286
        // a. Let propertyKey be ? ToPropertyKey(key).
287
0
        auto property_key = TRY(key.to_property_key(vm));
288
289
        // b. Perform ! CreateDataPropertyOrThrow(obj, propertyKey, value).
290
0
        MUST(object->create_data_property_or_throw(property_key, value));
291
292
        // c. Return undefined.
293
0
        return {};
294
0
    }));
295
296
0
    return object;
297
0
}
298
299
// 20.1.2.8 Object.getOwnPropertyDescriptor ( O, P ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
300
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor)
301
0
{
302
    // 1. Let obj be ? ToObject(O).
303
0
    auto object = TRY(vm.argument(0).to_object(vm));
304
305
    // 2. Let key be ? ToPropertyKey(P).
306
0
    auto key = TRY(vm.argument(1).to_property_key(vm));
307
308
    // 3. Let desc be ? obj.[[GetOwnProperty]](key).
309
0
    auto descriptor = TRY(object->internal_get_own_property(key));
310
311
    // 4. Return FromPropertyDescriptor(desc).
312
0
    return from_property_descriptor(vm, descriptor);
313
0
}
314
315
// 20.1.2.9 Object.getOwnPropertyDescriptors ( O ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
316
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
317
0
{
318
0
    auto& realm = *vm.current_realm();
319
320
    // 1. Let obj be ? ToObject(O).
321
0
    auto object = TRY(vm.argument(0).to_object(vm));
322
323
    // 2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
324
0
    auto own_keys = TRY(object->internal_own_property_keys());
325
326
    // 3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
327
0
    auto descriptors = Object::create(realm, realm.intrinsics().object_prototype());
328
329
    // 4. For each element key of ownKeys, do
330
0
    for (auto& key : own_keys) {
331
0
        auto property_key = MUST(PropertyKey::from_value(vm, key));
332
333
        // a. Let desc be ? obj.[[GetOwnProperty]](key).
334
0
        auto desc = TRY(object->internal_get_own_property(property_key));
335
336
        // b. Let descriptor be FromPropertyDescriptor(desc).
337
0
        auto descriptor = from_property_descriptor(vm, desc);
338
339
        // c. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
340
0
        if (!descriptor.is_undefined())
341
0
            MUST(descriptors->create_data_property_or_throw(property_key, descriptor));
342
0
    }
343
344
    // 5. Return descriptors.
345
0
    return descriptors;
346
0
}
347
348
// 20.1.2.10 Object.getOwnPropertyNames ( O ), https://tc39.es/ecma262/#sec-object.getownpropertynames
349
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
350
0
{
351
0
    auto& realm = *vm.current_realm();
352
353
    // 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, string)).
354
0
    return Array::create_from(realm, TRY(get_own_property_keys(vm, vm.argument(0), GetOwnPropertyKeysType::String)));
355
0
}
356
357
// 20.1.2.11 Object.getOwnPropertySymbols ( O ), https://tc39.es/ecma262/#sec-object.getownpropertysymbols
358
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
359
0
{
360
0
    auto& realm = *vm.current_realm();
361
362
    // 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, symbol)).
363
0
    return Array::create_from(realm, TRY(get_own_property_keys(vm, vm.argument(0), GetOwnPropertyKeysType::Symbol)));
364
0
}
365
366
// 20.1.2.12 Object.getPrototypeOf ( O ), https://tc39.es/ecma262/#sec-object.getprototypeof
367
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of)
368
0
{
369
    // 1. Let obj be ? ToObject(O).
370
0
    auto object = TRY(vm.argument(0).to_object(vm));
371
372
    // 2. Return ? obj.[[GetPrototypeOf]]().
373
0
    return TRY(object->internal_get_prototype_of());
374
0
}
375
376
// 20.1.2.13 Object.groupBy ( items, callbackfn ), https://tc39.es/ecma262/#sec-object.groupby
377
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::group_by)
378
0
{
379
0
    auto& realm = *vm.current_realm();
380
381
0
    auto items = vm.argument(0);
382
0
    auto callback_function = vm.argument(1);
383
384
    // 1. Let groups be ? GroupBy(items, callbackfn, property).
385
0
    auto groups = TRY((JS::group_by<OrderedHashMap<PropertyKey, MarkedVector<Value>>, PropertyKey>(vm, items, callback_function)));
386
387
    // 2. Let obj be OrdinaryObjectCreate(null).
388
0
    auto object = Object::create(realm, nullptr);
389
390
    // 3. For each Record { [[Key]], [[Elements]] } g of groups, do
391
0
    for (auto& group : groups) {
392
        // a. Let elements be CreateArrayFromList(g.[[Elements]]).
393
0
        auto elements = Array::create_from(realm, group.value);
394
395
        // b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
396
0
        MUST(object->create_data_property_or_throw(group.key, elements));
397
0
    }
398
399
    // 4. Return obj.
400
0
    return object;
401
0
}
402
403
// 20.1.2.14 Object.hasOwn ( O, P ), https://tc39.es/ecma262/#sec-object.hasown
404
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::has_own)
405
0
{
406
    // 1. Let obj be ? ToObject(O).
407
0
    auto object = TRY(vm.argument(0).to_object(vm));
408
409
    // 2. Let key be ? ToPropertyKey(P).
410
0
    auto key = TRY(vm.argument(1).to_property_key(vm));
411
412
    // 3. Return ? HasOwnProperty(obj, key).
413
0
    return Value(TRY(object->has_own_property(key)));
414
0
}
415
416
// 20.1.2.15 Object.is ( value1, value2 ), https://tc39.es/ecma262/#sec-object.is
417
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is)
418
0
{
419
    // 1. Return SameValue(value1, value2).
420
0
    return Value(same_value(vm.argument(0), vm.argument(1)));
421
0
}
422
423
// 20.1.2.16 Object.isExtensible ( O ), https://tc39.es/ecma262/#sec-object.isextensible
424
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is_extensible)
425
0
{
426
0
    auto argument = vm.argument(0);
427
428
    // 1. If O is not an Object, return false.
429
0
    if (!argument.is_object())
430
0
        return Value(false);
431
432
    // 2. Return ? IsExtensible(O).
433
0
    return Value(TRY(argument.as_object().is_extensible()));
434
0
}
435
436
// 20.1.2.17 Object.isFrozen ( O ), https://tc39.es/ecma262/#sec-object.isfrozen
437
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is_frozen)
438
0
{
439
0
    auto argument = vm.argument(0);
440
441
    // 1. If O is not an Object, return true.
442
0
    if (!argument.is_object())
443
0
        return Value(true);
444
445
    // 2. Return ? TestIntegrityLevel(O, frozen).
446
0
    return Value(TRY(argument.as_object().test_integrity_level(Object::IntegrityLevel::Frozen)));
447
0
}
448
449
// 20.1.2.18 Object.isSealed ( O ), https://tc39.es/ecma262/#sec-object.issealed
450
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is_sealed)
451
0
{
452
0
    auto argument = vm.argument(0);
453
454
    // 1. If O is not an Object, return true.
455
0
    if (!argument.is_object())
456
0
        return Value(true);
457
458
    // 2. Return ? TestIntegrityLevel(O, sealed).
459
0
    return Value(TRY(argument.as_object().test_integrity_level(Object::IntegrityLevel::Sealed)));
460
0
}
461
462
// 20.1.2.19 Object.keys ( O ), https://tc39.es/ecma262/#sec-object.keys
463
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
464
0
{
465
0
    auto& realm = *vm.current_realm();
466
467
    // 1. Let obj be ? ToObject(O).
468
0
    auto object = TRY(vm.argument(0).to_object(vm));
469
470
    // 2. Let keyList be ? EnumerableOwnProperties(obj, key).
471
0
    auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Key));
472
473
    // 3. Return CreateArrayFromList(keyList).
474
0
    return Array::create_from(realm, name_list);
475
0
}
476
477
// 20.1.2.20 Object.preventExtensions ( O ), https://tc39.es/ecma262/#sec-object.preventextensions
478
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::prevent_extensions)
479
0
{
480
0
    auto argument = vm.argument(0);
481
482
    // 1. If O is not an Object, return O.
483
0
    if (!argument.is_object())
484
0
        return argument;
485
486
    // 2. Let status be ? O.[[PreventExtensions]]().
487
0
    auto status = TRY(argument.as_object().internal_prevent_extensions());
488
489
    // 3. If status is false, throw a TypeError exception.
490
0
    if (!status) {
491
        // FIXME: Improve/contextualize error message
492
0
        return vm.throw_completion<TypeError>(ErrorType::ObjectPreventExtensionsReturnedFalse);
493
0
    }
494
495
    // 4. Return O.
496
0
    return argument;
497
0
}
498
499
// 20.1.2.22 Object.seal ( O ), https://tc39.es/ecma262/#sec-object.seal
500
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::seal)
501
0
{
502
0
    auto argument = vm.argument(0);
503
504
    // 1. If O is not an Object, return O.
505
0
    if (!argument.is_object())
506
0
        return argument;
507
508
    // 2. Let status be ? SetIntegrityLevel(O, sealed).
509
0
    auto status = TRY(argument.as_object().set_integrity_level(Object::IntegrityLevel::Sealed));
510
511
    // 3. If status is false, throw a TypeError exception.
512
0
    if (!status)
513
0
        return vm.throw_completion<TypeError>(ErrorType::ObjectSealFailed);
514
515
    // 4. Return O.
516
0
    return argument;
517
0
}
518
519
// 20.1.2.23 Object.setPrototypeOf ( O, proto ), https://tc39.es/ecma262/#sec-object.setprototypeof
520
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
521
0
{
522
0
    auto proto = vm.argument(1);
523
524
    // 1. Set O to ? RequireObjectCoercible(O).
525
0
    auto object = TRY(require_object_coercible(vm, vm.argument(0)));
526
527
    // 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
528
0
    if (!proto.is_object() && !proto.is_null())
529
0
        return vm.throw_completion<TypeError>(ErrorType::ObjectPrototypeWrongType);
530
531
    // 3. If Type(O) is not Object, return O.
532
0
    if (!object.is_object())
533
0
        return object;
534
535
    // 4. Let status be ? O.[[SetPrototypeOf]](proto).
536
0
    auto status = TRY(object.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object()));
537
538
    // 5. If status is false, throw a TypeError exception.
539
0
    if (!status) {
540
        // FIXME: Improve/contextualize error message
541
0
        return vm.throw_completion<TypeError>(ErrorType::ObjectSetPrototypeOfReturnedFalse);
542
0
    }
543
544
    // 6. Return O.
545
0
    return object;
546
0
}
547
548
// 20.1.2.24 Object.values ( O ), https://tc39.es/ecma262/#sec-object.values
549
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
550
0
{
551
0
    auto& realm = *vm.current_realm();
552
553
    // 1. Let obj be ? ToObject(O).
554
0
    auto object = TRY(vm.argument(0).to_object(vm));
555
556
    // 2. Let valueList be ? EnumerableOwnProperties(obj, value).
557
0
    auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Value));
558
559
    // 3. Return CreateArrayFromList(valueList).
560
0
    return Array::create_from(realm, name_list);
561
0
}
562
563
}