Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/builtins/builtins-utils.h"
6 : #include "src/builtins/builtins.h"
7 : #include "src/code-factory.h"
8 : #include "src/code-stub-assembler.h"
9 : #include "src/counters.h"
10 : #include "src/keys.h"
11 : #include "src/lookup.h"
12 : #include "src/objects-inl.h"
13 : #include "src/property-descriptor.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : // -----------------------------------------------------------------------------
19 : // ES6 section 19.1 Object Objects
20 :
21 : // ES6 19.1.2.1 Object.assign
22 1143 : BUILTIN(ObjectAssign) {
23 : HandleScope scope(isolate);
24 : Handle<Object> target = args.atOrUndefined(isolate, 1);
25 :
26 : // 1. Let to be ? ToObject(target).
27 762 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target,
28 : Object::ToObject(isolate, target));
29 : Handle<JSReceiver> to = Handle<JSReceiver>::cast(target);
30 : // 2. If only one argument was passed, return to.
31 325 : if (args.length() == 2) return *to;
32 : // 3. Let sources be the List of argument values starting with the
33 : // second argument.
34 : // 4. For each element nextSource of sources, in ascending index order,
35 921 : for (int i = 2; i < args.length(); ++i) {
36 354 : Handle<Object> next_source = args.at(i);
37 354 : MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, to, next_source),
38 : isolate->heap()->exception());
39 : }
40 : // 5. Return to.
41 269 : return *to;
42 : }
43 :
44 : // ES6 section 19.1.3.4 Object.prototype.propertyIsEnumerable ( V )
45 26166 : BUILTIN(ObjectPrototypePropertyIsEnumerable) {
46 : HandleScope scope(isolate);
47 : Handle<JSReceiver> object;
48 : Handle<Name> name;
49 17444 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
50 : isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1)));
51 17432 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
52 : isolate, object, JSReceiver::ToObject(isolate, args.receiver()));
53 : Maybe<PropertyAttributes> maybe =
54 8432 : JSReceiver::GetOwnPropertyAttributes(object, name);
55 8432 : if (!maybe.IsJust()) return isolate->heap()->exception();
56 8133 : if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
57 15546 : return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
58 : }
59 :
60 : // ES6 section 19.1.2.3 Object.defineProperties
61 54858 : BUILTIN(ObjectDefineProperties) {
62 : HandleScope scope(isolate);
63 : DCHECK_EQ(3, args.length());
64 18286 : Handle<Object> target = args.at(1);
65 18286 : Handle<Object> properties = args.at(2);
66 :
67 54589 : RETURN_RESULT_OR_FAILURE(
68 : isolate, JSReceiver::DefineProperties(isolate, target, properties));
69 : }
70 :
71 : // ES6 section 19.1.2.4 Object.defineProperty
72 857862 : BUILTIN(ObjectDefineProperty) {
73 : HandleScope scope(isolate);
74 : DCHECK_EQ(4, args.length());
75 285954 : Handle<Object> target = args.at(1);
76 285954 : Handle<Object> key = args.at(2);
77 285954 : Handle<Object> attributes = args.at(3);
78 :
79 571908 : return JSReceiver::DefineProperty(isolate, target, key, attributes);
80 : }
81 :
82 : namespace {
83 :
84 : template <AccessorComponent which_accessor>
85 50566 : Object* ObjectDefineAccessor(Isolate* isolate, Handle<Object> object,
86 : Handle<Object> name, Handle<Object> accessor) {
87 : // 1. Let O be ? ToObject(this value).
88 : Handle<JSReceiver> receiver;
89 101132 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
90 : isolate, receiver,
91 : FLAG_harmony_strict_legacy_accessor_builtins
92 : ? Object::ToObject(isolate, object)
93 : : Object::ConvertReceiver(isolate, object));
94 : // 2. If IsCallable(getter) is false, throw a TypeError exception.
95 50566 : if (!accessor->IsCallable()) {
96 : MessageTemplate::Template message =
97 : which_accessor == ACCESSOR_GETTER
98 : ? MessageTemplate::kObjectGetterExpectingFunction
99 : : MessageTemplate::kObjectSetterExpectingFunction;
100 172 : THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(message));
101 : }
102 : // 3. Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true,
103 : // [[Configurable]]: true}.
104 : PropertyDescriptor desc;
105 : if (which_accessor == ACCESSOR_GETTER) {
106 : desc.set_get(accessor);
107 : } else {
108 : DCHECK(which_accessor == ACCESSOR_SETTER);
109 : desc.set_set(accessor);
110 : }
111 : desc.set_enumerable(true);
112 : desc.set_configurable(true);
113 : // 4. Let key be ? ToPropertyKey(P).
114 100960 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
115 : Object::ToPropertyKey(isolate, name));
116 : // 5. Perform ? DefinePropertyOrThrow(O, key, desc).
117 : // To preserve legacy behavior, we ignore errors silently rather than
118 : // throwing an exception.
119 : Maybe<bool> success = JSReceiver::DefineOwnProperty(
120 : isolate, receiver, name, &desc,
121 : FLAG_harmony_strict_legacy_accessor_builtins ? Object::THROW_ON_ERROR
122 50480 : : Object::DONT_THROW);
123 50480 : MAYBE_RETURN(success, isolate->heap()->exception());
124 50460 : if (!success.FromJust()) {
125 218 : isolate->CountUsage(v8::Isolate::kDefineGetterOrSetterWouldThrow);
126 : }
127 : // 6. Return undefined.
128 50460 : return isolate->heap()->undefined_value();
129 : }
130 :
131 1009 : Object* ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
132 : Handle<Object> key, AccessorComponent component) {
133 2018 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
134 : isolate, object,
135 : FLAG_harmony_strict_legacy_accessor_builtins
136 : ? Object::ToObject(isolate, object)
137 : : Object::ConvertReceiver(isolate, object));
138 2018 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
139 : Object::ToPropertyKey(isolate, key));
140 1009 : bool success = false;
141 : LookupIterator it = LookupIterator::PropertyOrElement(
142 : isolate, object, key, &success,
143 1009 : LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
144 : DCHECK(success);
145 :
146 1009 : for (; it.IsFound(); it.Next()) {
147 897 : switch (it.state()) {
148 : case LookupIterator::INTERCEPTOR:
149 : case LookupIterator::NOT_FOUND:
150 : case LookupIterator::TRANSITION:
151 0 : UNREACHABLE();
152 :
153 : case LookupIterator::ACCESS_CHECK:
154 6 : if (it.HasAccess()) continue;
155 6 : isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
156 6 : RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
157 0 : return isolate->heap()->undefined_value();
158 :
159 : case LookupIterator::JSPROXY: {
160 : PropertyDescriptor desc;
161 : Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
162 448 : isolate, it.GetHolder<JSProxy>(), it.GetName(), &desc);
163 448 : MAYBE_RETURN(found, isolate->heap()->exception());
164 448 : if (found.FromJust()) {
165 378 : if (component == ACCESSOR_GETTER && desc.has_get()) {
166 : return *desc.get();
167 : }
168 294 : if (component == ACCESSOR_SETTER && desc.has_set()) {
169 : return *desc.set();
170 : }
171 84 : return isolate->heap()->undefined_value();
172 : }
173 : Handle<Object> prototype;
174 392 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
175 : isolate, prototype, JSProxy::GetPrototype(it.GetHolder<JSProxy>()));
176 196 : if (prototype->IsNull(isolate)) {
177 28 : return isolate->heap()->undefined_value();
178 : }
179 168 : return ObjectLookupAccessor(isolate, prototype, key, component);
180 : }
181 :
182 : case LookupIterator::INTEGER_INDEXED_EXOTIC:
183 : case LookupIterator::DATA:
184 112 : return isolate->heap()->undefined_value();
185 :
186 : case LookupIterator::ACCESSOR: {
187 331 : Handle<Object> maybe_pair = it.GetAccessors();
188 331 : if (maybe_pair->IsAccessorPair()) {
189 : return *AccessorPair::GetComponent(
190 662 : Handle<AccessorPair>::cast(maybe_pair), component);
191 : }
192 : }
193 : }
194 : }
195 :
196 112 : return isolate->heap()->undefined_value();
197 : }
198 :
199 : } // namespace
200 :
201 : // ES6 B.2.2.2 a.k.a.
202 : // https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__
203 99648 : BUILTIN(ObjectDefineGetter) {
204 : HandleScope scope(isolate);
205 33216 : Handle<Object> object = args.at(0); // Receiver.
206 33216 : Handle<Object> name = args.at(1);
207 33216 : Handle<Object> getter = args.at(2);
208 66432 : return ObjectDefineAccessor<ACCESSOR_GETTER>(isolate, object, name, getter);
209 : }
210 :
211 : // ES6 B.2.2.3 a.k.a.
212 : // https://tc39.github.io/ecma262/#sec-object.prototype.__defineSetter__
213 52050 : BUILTIN(ObjectDefineSetter) {
214 : HandleScope scope(isolate);
215 17350 : Handle<Object> object = args.at(0); // Receiver.
216 17350 : Handle<Object> name = args.at(1);
217 17350 : Handle<Object> setter = args.at(2);
218 34700 : return ObjectDefineAccessor<ACCESSOR_SETTER>(isolate, object, name, setter);
219 : }
220 :
221 : // ES6 B.2.2.4 a.k.a.
222 : // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupGetter__
223 1311 : BUILTIN(ObjectLookupGetter) {
224 : HandleScope scope(isolate);
225 437 : Handle<Object> object = args.at(0);
226 437 : Handle<Object> name = args.at(1);
227 874 : return ObjectLookupAccessor(isolate, object, name, ACCESSOR_GETTER);
228 : }
229 :
230 : // ES6 B.2.2.5 a.k.a.
231 : // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupSetter__
232 1212 : BUILTIN(ObjectLookupSetter) {
233 : HandleScope scope(isolate);
234 404 : Handle<Object> object = args.at(0);
235 404 : Handle<Object> name = args.at(1);
236 808 : return ObjectLookupAccessor(isolate, object, name, ACCESSOR_SETTER);
237 : }
238 :
239 : // ES6 section 19.1.2.5 Object.freeze ( O )
240 494871 : BUILTIN(ObjectFreeze) {
241 : HandleScope scope(isolate);
242 : Handle<Object> object = args.atOrUndefined(isolate, 1);
243 164957 : if (object->IsJSReceiver()) {
244 164845 : MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
245 : FROZEN, Object::THROW_ON_ERROR),
246 : isolate->heap()->exception());
247 : }
248 164907 : return *object;
249 : }
250 :
251 : // ES section 19.1.2.9 Object.getPrototypeOf ( O )
252 1921068 : BUILTIN(ObjectGetPrototypeOf) {
253 : HandleScope scope(isolate);
254 640356 : Handle<Object> object = args.atOrUndefined(isolate, 1);
255 :
256 : Handle<JSReceiver> receiver;
257 1280712 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
258 : Object::ToObject(isolate, object));
259 :
260 1920964 : RETURN_RESULT_OR_FAILURE(isolate,
261 : JSReceiver::GetPrototype(isolate, receiver));
262 : }
263 :
264 : // ES6 section 19.1.2.21 Object.setPrototypeOf ( O, proto )
265 273444 : BUILTIN(ObjectSetPrototypeOf) {
266 : HandleScope scope(isolate);
267 :
268 : // 1. Let O be ? RequireObjectCoercible(O).
269 : Handle<Object> object = args.atOrUndefined(isolate, 1);
270 91148 : if (object->IsNullOrUndefined(isolate)) {
271 84 : THROW_NEW_ERROR_RETURN_FAILURE(
272 : isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
273 : isolate->factory()->NewStringFromAsciiChecked(
274 : "Object.setPrototypeOf")));
275 : }
276 :
277 : // 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
278 : Handle<Object> proto = args.atOrUndefined(isolate, 2);
279 182028 : if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
280 1486 : THROW_NEW_ERROR_RETURN_FAILURE(
281 : isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
282 : }
283 :
284 : // 3. If Type(O) is not Object, return O.
285 90433 : if (!object->IsJSReceiver()) return *object;
286 : Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
287 :
288 : // 4. Let status be ? O.[[SetPrototypeOf]](proto).
289 : // 5. If status is false, throw a TypeError exception.
290 90321 : MAYBE_RETURN(
291 : JSReceiver::SetPrototype(receiver, proto, true, Object::THROW_ON_ERROR),
292 : isolate->heap()->exception());
293 :
294 : // 6. Return O.
295 90040 : return *receiver;
296 : }
297 :
298 : // ES6 section B.2.2.1.1 get Object.prototype.__proto__
299 587844 : BUILTIN(ObjectPrototypeGetProto) {
300 : HandleScope scope(isolate);
301 : // 1. Let O be ? ToObject(this value).
302 : Handle<JSReceiver> receiver;
303 391896 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
304 : isolate, receiver, Object::ToObject(isolate, args.receiver()));
305 :
306 : // 2. Return ? O.[[GetPrototypeOf]]().
307 587754 : RETURN_RESULT_OR_FAILURE(isolate,
308 : JSReceiver::GetPrototype(isolate, receiver));
309 : }
310 :
311 : // ES6 section B.2.2.1.2 set Object.prototype.__proto__
312 205332 : BUILTIN(ObjectPrototypeSetProto) {
313 : HandleScope scope(isolate);
314 : // 1. Let O be ? RequireObjectCoercible(this value).
315 : Handle<Object> object = args.receiver();
316 68444 : if (object->IsNullOrUndefined(isolate)) {
317 90 : THROW_NEW_ERROR_RETURN_FAILURE(
318 : isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
319 : isolate->factory()->NewStringFromAsciiChecked(
320 : "set Object.prototype.__proto__")));
321 : }
322 :
323 : // 2. If Type(proto) is neither Object nor Null, return undefined.
324 : Handle<Object> proto = args.at(1);
325 136390 : if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
326 44502 : return isolate->heap()->undefined_value();
327 : }
328 :
329 : // 3. If Type(O) is not Object, return undefined.
330 23912 : if (!object->IsJSReceiver()) return isolate->heap()->undefined_value();
331 23837 : Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
332 :
333 : // 4. Let status be ? O.[[SetPrototypeOf]](proto).
334 : // 5. If status is false, throw a TypeError exception.
335 23837 : MAYBE_RETURN(
336 : JSReceiver::SetPrototype(receiver, proto, true, Object::THROW_ON_ERROR),
337 : isolate->heap()->exception());
338 :
339 : // Return undefined.
340 23683 : return isolate->heap()->undefined_value();
341 : }
342 :
343 : // ES6 section 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
344 10455657 : BUILTIN(ObjectGetOwnPropertyDescriptor) {
345 : HandleScope scope(isolate);
346 : // 1. Let obj be ? ToObject(O).
347 3485219 : Handle<Object> object = args.atOrUndefined(isolate, 1);
348 : Handle<JSReceiver> receiver;
349 6970438 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
350 : Object::ToObject(isolate, object));
351 : // 2. Let key be ? ToPropertyKey(P).
352 3485189 : Handle<Object> property = args.atOrUndefined(isolate, 2);
353 : Handle<Name> key;
354 6970378 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
355 : Object::ToName(isolate, property));
356 : // 3. Let desc be ? obj.[[GetOwnProperty]](key).
357 : PropertyDescriptor desc;
358 : Maybe<bool> found =
359 3485189 : JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, key, &desc);
360 3485189 : MAYBE_RETURN(found, isolate->heap()->exception());
361 : // 4. Return FromPropertyDescriptor(desc).
362 3484687 : if (!found.FromJust()) return isolate->heap()->undefined_value();
363 6951832 : return *desc.ToObject(isolate);
364 : }
365 :
366 : namespace {
367 :
368 245040 : Object* GetOwnPropertyKeys(Isolate* isolate, BuiltinArguments args,
369 : PropertyFilter filter) {
370 : HandleScope scope(isolate);
371 245040 : Handle<Object> object = args.atOrUndefined(isolate, 1);
372 : Handle<JSReceiver> receiver;
373 490080 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
374 : Object::ToObject(isolate, object));
375 : Handle<FixedArray> keys;
376 490020 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
377 : isolate, keys,
378 : KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
379 : GetKeysConversion::kConvertToString));
380 : return *isolate->factory()->NewJSArrayWithElements(keys);
381 : }
382 :
383 : } // namespace
384 :
385 : // ES6 section 19.1.2.7 Object.getOwnPropertyNames ( O )
386 273324 : BUILTIN(ObjectGetOwnPropertyNames) {
387 136662 : return GetOwnPropertyKeys(isolate, args, SKIP_SYMBOLS);
388 : }
389 :
390 : // ES6 section 19.1.2.8 Object.getOwnPropertySymbols ( O )
391 216756 : BUILTIN(ObjectGetOwnPropertySymbols) {
392 108378 : return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS);
393 : }
394 :
395 : // ES#sec-object.is Object.is ( value1, value2 )
396 105252 : BUILTIN(ObjectIs) {
397 : SealHandleScope shs(isolate);
398 : DCHECK_EQ(3, args.length());
399 : Handle<Object> value1 = args.at(1);
400 : Handle<Object> value2 = args.at(2);
401 70168 : return isolate->heap()->ToBoolean(value1->SameValue(*value2));
402 : }
403 :
404 : // ES6 section 19.1.2.11 Object.isExtensible ( O )
405 1944 : BUILTIN(ObjectIsExtensible) {
406 : HandleScope scope(isolate);
407 : Handle<Object> object = args.atOrUndefined(isolate, 1);
408 : Maybe<bool> result =
409 : object->IsJSReceiver()
410 : ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
411 648 : : Just(false);
412 648 : MAYBE_RETURN(result, isolate->heap()->exception());
413 648 : return isolate->heap()->ToBoolean(result.FromJust());
414 : }
415 :
416 : // ES6 section 19.1.2.12 Object.isFrozen ( O )
417 13395 : BUILTIN(ObjectIsFrozen) {
418 : HandleScope scope(isolate);
419 : Handle<Object> object = args.atOrUndefined(isolate, 1);
420 : Maybe<bool> result = object->IsJSReceiver()
421 : ? JSReceiver::TestIntegrityLevel(
422 : Handle<JSReceiver>::cast(object), FROZEN)
423 4465 : : Just(true);
424 4465 : MAYBE_RETURN(result, isolate->heap()->exception());
425 4465 : return isolate->heap()->ToBoolean(result.FromJust());
426 : }
427 :
428 : // ES6 section 19.1.2.13 Object.isSealed ( O )
429 10290 : BUILTIN(ObjectIsSealed) {
430 : HandleScope scope(isolate);
431 : Handle<Object> object = args.atOrUndefined(isolate, 1);
432 : Maybe<bool> result = object->IsJSReceiver()
433 : ? JSReceiver::TestIntegrityLevel(
434 : Handle<JSReceiver>::cast(object), SEALED)
435 3430 : : Just(true);
436 3430 : MAYBE_RETURN(result, isolate->heap()->exception());
437 3430 : return isolate->heap()->ToBoolean(result.FromJust());
438 : }
439 :
440 : // ES6 section 19.1.2.14 Object.keys ( O )
441 695184 : BUILTIN(ObjectKeys) {
442 : HandleScope scope(isolate);
443 231728 : Handle<Object> object = args.atOrUndefined(isolate, 1);
444 : Handle<JSReceiver> receiver;
445 463456 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
446 : Object::ToObject(isolate, object));
447 :
448 : Handle<FixedArray> keys;
449 : int enum_length = receiver->map()->EnumLength();
450 409046 : if (enum_length != kInvalidEnumCacheSentinel &&
451 : JSObject::cast(*receiver)->elements() ==
452 177361 : isolate->heap()->empty_fixed_array()) {
453 : DCHECK(receiver->IsJSObject());
454 : DCHECK(!JSObject::cast(*receiver)->HasNamedInterceptor());
455 : DCHECK(!JSObject::cast(*receiver)->IsAccessCheckNeeded());
456 : DCHECK(!receiver->map()->has_hidden_prototype());
457 : DCHECK(JSObject::cast(*receiver)->HasFastProperties());
458 165450 : if (enum_length == 0) {
459 : keys = isolate->factory()->empty_fixed_array();
460 : } else {
461 : Handle<FixedArray> cache(
462 150792 : receiver->map()->instance_descriptors()->GetEnumCache());
463 150792 : keys = isolate->factory()->CopyFixedArrayUpTo(cache, enum_length);
464 : }
465 : } else {
466 132470 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
467 : isolate, keys,
468 : KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
469 : ENUMERABLE_STRINGS,
470 : GetKeysConversion::kConvertToString));
471 : }
472 : return *isolate->factory()->NewJSArrayWithElements(keys, FAST_ELEMENTS);
473 : }
474 :
475 1680 : BUILTIN(ObjectValues) {
476 : HandleScope scope(isolate);
477 560 : Handle<Object> object = args.atOrUndefined(isolate, 1);
478 : Handle<JSReceiver> receiver;
479 1120 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
480 : Object::ToObject(isolate, object));
481 : Handle<FixedArray> values;
482 1036 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
483 : isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS));
484 : return *isolate->factory()->NewJSArrayWithElements(values);
485 : }
486 :
487 1764 : BUILTIN(ObjectEntries) {
488 : HandleScope scope(isolate);
489 588 : Handle<Object> object = args.atOrUndefined(isolate, 1);
490 : Handle<JSReceiver> receiver;
491 1176 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
492 : Object::ToObject(isolate, object));
493 : Handle<FixedArray> entries;
494 1092 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
495 : isolate, entries,
496 : JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS));
497 : return *isolate->factory()->NewJSArrayWithElements(entries);
498 : }
499 :
500 420 : BUILTIN(ObjectGetOwnPropertyDescriptors) {
501 : HandleScope scope(isolate);
502 140 : Handle<Object> object = args.atOrUndefined(isolate, 1);
503 :
504 : Handle<JSReceiver> receiver;
505 280 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
506 : Object::ToObject(isolate, object));
507 :
508 : Handle<FixedArray> keys;
509 196 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
510 : isolate, keys, KeyAccumulator::GetKeys(
511 : receiver, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
512 : GetKeysConversion::kConvertToString));
513 :
514 : Handle<JSObject> descriptors =
515 98 : isolate->factory()->NewJSObject(isolate->object_function());
516 :
517 644 : for (int i = 0; i < keys->length(); ++i) {
518 224 : Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate));
519 : PropertyDescriptor descriptor;
520 : Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
521 224 : isolate, receiver, key, &descriptor);
522 224 : MAYBE_RETURN(did_get_descriptor, isolate->heap()->exception());
523 :
524 252 : if (!did_get_descriptor.FromJust()) continue;
525 196 : Handle<Object> from_descriptor = descriptor.ToObject(isolate);
526 :
527 : LookupIterator it = LookupIterator::PropertyOrElement(
528 196 : isolate, descriptors, key, descriptors, LookupIterator::OWN);
529 : Maybe<bool> success = JSReceiver::CreateDataProperty(&it, from_descriptor,
530 196 : Object::DONT_THROW);
531 196 : CHECK(success.FromJust());
532 : }
533 :
534 98 : return *descriptors;
535 : }
536 :
537 : // ES6 section 19.1.2.15 Object.preventExtensions ( O )
538 15399 : BUILTIN(ObjectPreventExtensions) {
539 : HandleScope scope(isolate);
540 : Handle<Object> object = args.atOrUndefined(isolate, 1);
541 5133 : if (object->IsJSReceiver()) {
542 5133 : MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
543 : Object::THROW_ON_ERROR),
544 : isolate->heap()->exception());
545 : }
546 5121 : return *object;
547 : }
548 :
549 : // ES6 section 19.1.2.17 Object.seal ( O )
550 1836 : BUILTIN(ObjectSeal) {
551 : HandleScope scope(isolate);
552 : Handle<Object> object = args.atOrUndefined(isolate, 1);
553 612 : if (object->IsJSReceiver()) {
554 563 : MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
555 : SEALED, Object::THROW_ON_ERROR),
556 : isolate->heap()->exception());
557 : }
558 606 : return *object;
559 : }
560 :
561 : } // namespace internal
562 : } // namespace v8
|