• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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/ast/prettyprinter.h"
6 #include "src/common/message-template.h"
7 #include "src/debug/debug.h"
8 #include "src/execution/arguments-inl.h"
9 #include "src/execution/isolate-inl.h"
10 #include "src/execution/messages.h"
11 #include "src/handles/maybe-handles.h"
12 #include "src/heap/heap-inl.h"  // For ToBoolean. TODO(jkummerow): Drop.
13 #include "src/heap/memory-chunk.h"
14 #include "src/init/bootstrapper.h"
15 #include "src/logging/counters.h"
16 #include "src/objects/hash-table-inl.h"
17 #include "src/objects/js-array-inl.h"
18 #include "src/objects/property-descriptor-object.h"
19 #include "src/objects/property-descriptor.h"
20 #include "src/runtime/runtime-utils.h"
21 #include "src/runtime/runtime.h"
22 
23 namespace v8 {
24 namespace internal {
25 
GetObjectProperty(Isolate * isolate,Handle<Object> holder,Handle<Object> key,Handle<Object> receiver,bool * is_found)26 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
27                                                Handle<Object> holder,
28                                                Handle<Object> key,
29                                                Handle<Object> receiver,
30                                                bool* is_found) {
31   if (receiver.is_null()) {
32     receiver = holder;
33   }
34   if (holder->IsNullOrUndefined(isolate)) {
35     ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, holder, key);
36     return MaybeHandle<Object>();
37   }
38 
39   bool success = false;
40   LookupIterator::Key lookup_key(isolate, key, &success);
41   if (!success) return MaybeHandle<Object>();
42   LookupIterator it = LookupIterator(isolate, receiver, lookup_key, holder);
43 
44   MaybeHandle<Object> result = Object::GetProperty(&it);
45   if (is_found) *is_found = it.IsFound();
46 
47   if (!it.IsFound() && key->IsSymbol() &&
48       Symbol::cast(*key).is_private_name()) {
49     Handle<Symbol> sym = Handle<Symbol>::cast(key);
50     Handle<Object> name(sym->description(), isolate);
51     DCHECK(name->IsString());
52     Handle<String> name_string = Handle<String>::cast(name);
53     if (sym->IsPrivateBrand()) {
54       Handle<String> class_name = (name_string->length() == 0)
55                                       ? isolate->factory()->anonymous_string()
56                                       : name_string;
57       THROW_NEW_ERROR(isolate,
58                       NewTypeError(MessageTemplate::kInvalidPrivateBrand,
59                                    class_name, holder),
60                       Object);
61     }
62     THROW_NEW_ERROR(isolate,
63                     NewTypeError(MessageTemplate::kInvalidPrivateMemberRead,
64                                  name_string, holder),
65                     Object);
66   }
67   return result;
68 }
69 
HasProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key)70 MaybeHandle<Object> Runtime::HasProperty(Isolate* isolate,
71                                          Handle<Object> object,
72                                          Handle<Object> key) {
73   // Check that {object} is actually a receiver.
74   if (!object->IsJSReceiver()) {
75     THROW_NEW_ERROR(
76         isolate,
77         NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object),
78         Object);
79   }
80   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
81 
82   // Convert the {key} to a name.
83   Handle<Name> name;
84   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
85                              Object);
86 
87   // Lookup the {name} on {receiver}.
88   Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
89   if (maybe.IsNothing()) return MaybeHandle<Object>();
90   return maybe.FromJust() ? ReadOnlyRoots(isolate).true_value_handle()
91                           : ReadOnlyRoots(isolate).false_value_handle();
92 }
93 
94 namespace {
95 
DeleteObjectPropertyFast(Isolate * isolate,Handle<JSReceiver> receiver,Handle<Object> raw_key)96 bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver,
97                               Handle<Object> raw_key) {
98   // This implements a special case for fast property deletion: when the
99   // last property in an object is deleted, then instead of normalizing
100   // the properties, we can undo the last map transition, with a few
101   // prerequisites:
102   // (1) The receiver must be a regular object and the key a unique name.
103   Handle<Map> receiver_map(receiver->map(), isolate);
104   if (receiver_map->IsSpecialReceiverMap()) return false;
105   if (!raw_key->IsUniqueName()) return false;
106   Handle<Name> key = Handle<Name>::cast(raw_key);
107   // (2) The property to be deleted must be the last property.
108   int nof = receiver_map->NumberOfOwnDescriptors();
109   if (nof == 0) return false;
110   InternalIndex descriptor(nof - 1);
111   Handle<DescriptorArray> descriptors(
112       receiver_map->instance_descriptors(kRelaxedLoad), isolate);
113   if (descriptors->GetKey(descriptor) != *key) return false;
114   // (3) The property to be deleted must be deletable.
115   PropertyDetails details = descriptors->GetDetails(descriptor);
116   if (!details.IsConfigurable()) return false;
117   // (4) The map must have a back pointer.
118   Handle<Object> backpointer(receiver_map->GetBackPointer(), isolate);
119   if (!backpointer->IsMap()) return false;
120   Handle<Map> parent_map = Handle<Map>::cast(backpointer);
121   // (5) The last transition must have been caused by adding a property
122   // (and not any kind of special transition).
123   if (parent_map->NumberOfOwnDescriptors() != nof - 1) return false;
124 
125   // Preconditions successful. No more bailouts after this point.
126 
127   // If the {descriptor} was "const" so far, we need to update the
128   // {receiver_map} here, otherwise we could get the constants wrong, i.e.
129   //
130   //   o.x = 1;
131   //   delete o.x;
132   //   o.x = 2;
133   //
134   // could trick V8 into thinking that `o.x` is still 1 even after the second
135   // assignment.
136   if (details.constness() == PropertyConstness::kConst &&
137       details.location() == kField) {
138     Handle<FieldType> field_type(descriptors->GetFieldType(descriptor),
139                                  isolate);
140     Map::GeneralizeField(isolate, receiver_map, descriptor,
141                          PropertyConstness::kMutable, details.representation(),
142                          field_type);
143     DCHECK_EQ(PropertyConstness::kMutable,
144               descriptors->GetDetails(descriptor).constness());
145   }
146 
147   // Zap the property to avoid keeping objects alive. Zapping is not necessary
148   // for properties stored in the descriptor array.
149   if (details.location() == kField) {
150     DisallowHeapAllocation no_allocation;
151 
152     // Invalidate slots manually later in case we delete an in-object tagged
153     // property. In this case we might later store an untagged value in the
154     // recorded slot.
155     isolate->heap()->NotifyObjectLayoutChange(*receiver, no_allocation,
156                                               InvalidateRecordedSlots::kNo);
157     FieldIndex index =
158         FieldIndex::ForPropertyIndex(*receiver_map, details.field_index());
159     // Special case deleting the last out-of object property.
160     if (!index.is_inobject() && index.outobject_array_index() == 0) {
161       DCHECK(!parent_map->HasOutOfObjectProperties());
162       // Clear out the properties backing store.
163       receiver->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
164     } else {
165       Object filler = ReadOnlyRoots(isolate).one_pointer_filler_map();
166       JSObject::cast(*receiver).RawFastPropertyAtPut(index, filler);
167       // We must clear any recorded slot for the deleted property, because
168       // subsequent object modifications might put a raw double there.
169       // Slot clearing is the reason why this entire function cannot currently
170       // be implemented in the DeleteProperty stub.
171       if (index.is_inobject() && !receiver_map->IsUnboxedDoubleField(index)) {
172         // We need to clear the recorded slot in this case because in-object
173         // slack tracking might not be finished. This ensures that we don't
174         // have recorded slots in free space.
175         isolate->heap()->ClearRecordedSlot(*receiver,
176                                            receiver->RawField(index.offset()));
177         MemoryChunk* chunk = MemoryChunk::FromHeapObject(*receiver);
178         chunk->InvalidateRecordedSlots(*receiver);
179       }
180     }
181   }
182   // If the {receiver_map} was marked stable before, then there could be
183   // optimized code that depends on the assumption that no object that
184   // reached this {receiver_map} transitions away from it without triggering
185   // the "deoptimize dependent code" mechanism.
186   receiver_map->NotifyLeafMapLayoutChange(isolate);
187   // Finally, perform the map rollback.
188   receiver->synchronized_set_map(*parent_map);
189 #if VERIFY_HEAP
190   receiver->HeapObjectVerify(isolate);
191   receiver->property_array().PropertyArrayVerify(isolate);
192 #endif
193   return true;
194 }
195 
196 }  // namespace
197 
DeleteObjectProperty(Isolate * isolate,Handle<JSReceiver> receiver,Handle<Object> key,LanguageMode language_mode)198 Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
199                                           Handle<JSReceiver> receiver,
200                                           Handle<Object> key,
201                                           LanguageMode language_mode) {
202   if (DeleteObjectPropertyFast(isolate, receiver, key)) return Just(true);
203 
204   bool success = false;
205   LookupIterator::Key lookup_key(isolate, key, &success);
206   if (!success) return Nothing<bool>();
207   LookupIterator it(isolate, receiver, lookup_key, LookupIterator::OWN);
208 
209   return JSReceiver::DeleteProperty(&it, language_mode);
210 }
211 
212 // ES #sec-object.keys
RUNTIME_FUNCTION(Runtime_ObjectKeys)213 RUNTIME_FUNCTION(Runtime_ObjectKeys) {
214   HandleScope scope(isolate);
215   Handle<Object> object = args.at(0);
216 
217   // Convert the {object} to a proper {receiver}.
218   Handle<JSReceiver> receiver;
219   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
220                                      Object::ToObject(isolate, object));
221 
222   // Collect the own keys for the {receiver}.
223   Handle<FixedArray> keys;
224   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
225       isolate, keys,
226       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
227                               ENUMERABLE_STRINGS,
228                               GetKeysConversion::kConvertToString));
229   return *keys;
230 }
231 
232 // ES #sec-object.getOwnPropertyNames
RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNames)233 RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNames) {
234   HandleScope scope(isolate);
235   Handle<Object> object = args.at(0);
236 
237   // Convert the {object} to a proper {receiver}.
238   Handle<JSReceiver> receiver;
239   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
240                                      Object::ToObject(isolate, object));
241 
242   // Collect the own keys for the {receiver}.
243   // TODO(v8:9401): We should extend the fast path of KeyAccumulator::GetKeys to
244   // also use fast path even when filter = SKIP_SYMBOLS.
245   Handle<FixedArray> keys;
246   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
247       isolate, keys,
248       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
249                               SKIP_SYMBOLS,
250                               GetKeysConversion::kConvertToString));
251   return *keys;
252 }
253 
RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNamesTryFast)254 RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNamesTryFast) {
255   HandleScope scope(isolate);
256   Handle<Object> object = args.at(0);
257 
258   // Convert the {object} to a proper {receiver}.
259   Handle<JSReceiver> receiver;
260   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
261                                      Object::ToObject(isolate, object));
262 
263   Handle<Map> map(receiver->map(), isolate);
264 
265   int nod = map->NumberOfOwnDescriptors();
266   Handle<FixedArray> keys;
267   if (nod != 0 && map->NumberOfEnumerableProperties() == nod) {
268     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
269         isolate, keys,
270         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
271                                 ENUMERABLE_STRINGS,
272                                 GetKeysConversion::kConvertToString));
273   } else {
274     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
275         isolate, keys,
276         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
277                                 SKIP_SYMBOLS,
278                                 GetKeysConversion::kConvertToString));
279   }
280 
281   return *keys;
282 }
283 
284 // ES6 19.1.3.2
RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty)285 RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
286   HandleScope scope(isolate);
287   Handle<Object> property = args.at(1);
288 
289   // TODO(ishell): To improve performance, consider performing the to-string
290   // conversion of {property} before calling into the runtime.
291   bool success;
292   LookupIterator::Key key(isolate, property, &success);
293   if (!success) return ReadOnlyRoots(isolate).exception();
294 
295   Handle<Object> object = args.at(0);
296 
297   if (object->IsJSModuleNamespace()) {
298     if (key.is_element()) {
299       // Namespace objects can't have indexed properties.
300       return ReadOnlyRoots(isolate).false_value();
301     }
302     LookupIterator it(isolate, object, key, LookupIterator::OWN);
303     PropertyDescriptor desc;
304     Maybe<bool> result = JSReceiver::GetOwnPropertyDescriptor(&it, &desc);
305     if (!result.IsJust()) return ReadOnlyRoots(isolate).exception();
306     return isolate->heap()->ToBoolean(result.FromJust());
307 
308   } else if (object->IsJSObject()) {
309     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
310     // Fast case: either the key is a real named property or it is not
311     // an array index and there are no interceptors or hidden
312     // prototypes.
313     // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
314     // handle all cases directly (without this custom fast path).
315     {
316       LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
317       LookupIterator it(isolate, js_obj, key, js_obj, c);
318       Maybe<bool> maybe = JSReceiver::HasProperty(&it);
319       if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
320       DCHECK(!isolate->has_pending_exception());
321       if (maybe.FromJust()) return ReadOnlyRoots(isolate).true_value();
322     }
323 
324     Map map = js_obj->map();
325     if (!map.IsJSGlobalProxyMap() &&
326         (key.is_element() && key.index() <= JSArray::kMaxArrayIndex
327              ? !map.has_indexed_interceptor()
328              : !map.has_named_interceptor())) {
329       return ReadOnlyRoots(isolate).false_value();
330     }
331 
332     // Slow case.
333     LookupIterator it(isolate, js_obj, key, js_obj, LookupIterator::OWN);
334     Maybe<bool> maybe = JSReceiver::HasProperty(&it);
335     if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
336     DCHECK(!isolate->has_pending_exception());
337     return isolate->heap()->ToBoolean(maybe.FromJust());
338 
339   } else if (object->IsJSProxy()) {
340     LookupIterator it(isolate, object, key, Handle<JSProxy>::cast(object),
341                       LookupIterator::OWN);
342     Maybe<PropertyAttributes> attributes =
343         JSReceiver::GetPropertyAttributes(&it);
344     if (attributes.IsNothing()) return ReadOnlyRoots(isolate).exception();
345     return isolate->heap()->ToBoolean(attributes.FromJust() != ABSENT);
346 
347   } else if (object->IsString()) {
348     return isolate->heap()->ToBoolean(
349         key.is_element()
350             ? key.index() < static_cast<size_t>(String::cast(*object).length())
351             : key.name()->Equals(ReadOnlyRoots(isolate).length_string()));
352   } else if (object->IsNullOrUndefined(isolate)) {
353     THROW_NEW_ERROR_RETURN_FAILURE(
354         isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
355   }
356 
357   return ReadOnlyRoots(isolate).false_value();
358 }
359 
RUNTIME_FUNCTION(Runtime_AddDictionaryProperty)360 RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
361   HandleScope scope(isolate);
362   Handle<JSObject> receiver = args.at<JSObject>(0);
363   Handle<Name> name = args.at<Name>(1);
364   Handle<Object> value = args.at(2);
365 
366   DCHECK(name->IsUniqueName());
367 
368   Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
369   PropertyDetails property_details(kData, NONE, PropertyCellType::kNoCell);
370   dictionary =
371       NameDictionary::Add(isolate, dictionary, name, value, property_details);
372   receiver->SetProperties(*dictionary);
373   return *value;
374 }
375 
376 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
377 // TODO(verwaest): Support the common cases with precached map directly in
378 // an Object.create stub.
RUNTIME_FUNCTION(Runtime_ObjectCreate)379 RUNTIME_FUNCTION(Runtime_ObjectCreate) {
380   HandleScope scope(isolate);
381   Handle<Object> prototype = args.at(0);
382   Handle<Object> properties = args.at(1);
383   Handle<JSObject> obj;
384   // 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
385   if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
386     THROW_NEW_ERROR_RETURN_FAILURE(
387         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
388   }
389   // 2. Let obj be ObjectCreate(O).
390   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
391       isolate, obj, JSObject::ObjectCreate(isolate, prototype));
392 
393   // 3. If Properties is not undefined, then
394   if (!properties->IsUndefined(isolate)) {
395     // a. Return ? ObjectDefineProperties(obj, Properties).
396     // Define the properties if properties was specified and is not undefined.
397     RETURN_RESULT_OR_FAILURE(
398         isolate, JSReceiver::DefineProperties(isolate, obj, properties));
399   }
400   // 4. Return obj.
401   return *obj;
402 }
403 
SetObjectProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key,Handle<Object> value,StoreOrigin store_origin,Maybe<ShouldThrow> should_throw)404 MaybeHandle<Object> Runtime::SetObjectProperty(
405     Isolate* isolate, Handle<Object> object, Handle<Object> key,
406     Handle<Object> value, StoreOrigin store_origin,
407     Maybe<ShouldThrow> should_throw) {
408   if (object->IsNullOrUndefined(isolate)) {
409     THROW_NEW_ERROR(
410         isolate,
411         NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
412         Object);
413   }
414 
415   // Check if the given key is an array index.
416   bool success = false;
417   LookupIterator::Key lookup_key(isolate, key, &success);
418   if (!success) return MaybeHandle<Object>();
419   LookupIterator it(isolate, object, lookup_key);
420 
421   if (!it.IsFound() && key->IsSymbol() &&
422       Symbol::cast(*key).is_private_name()) {
423     Handle<Object> name_string(Symbol::cast(*key).description(), isolate);
424     DCHECK(name_string->IsString());
425     THROW_NEW_ERROR(isolate,
426                     NewTypeError(MessageTemplate::kInvalidPrivateMemberWrite,
427                                  name_string, object),
428                     Object);
429   }
430 
431   MAYBE_RETURN_NULL(
432       Object::SetProperty(&it, value, store_origin, should_throw));
433 
434   return value;
435 }
436 
RUNTIME_FUNCTION(Runtime_InternalSetPrototype)437 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
438   HandleScope scope(isolate);
439   DCHECK_EQ(2, args.length());
440   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
441   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
442   MAYBE_RETURN(JSReceiver::SetPrototype(obj, prototype, false, kThrowOnError),
443                ReadOnlyRoots(isolate).exception());
444   return *obj;
445 }
446 
RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties)447 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
448   HandleScope scope(isolate);
449   DCHECK_EQ(2, args.length());
450   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
451   CONVERT_SMI_ARG_CHECKED(properties, 1);
452   // Conservative upper limit to prevent fuzz tests from going OOM.
453   if (properties > 100000) return isolate->ThrowIllegalOperation();
454   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
455     JSObject::NormalizeProperties(isolate, object, KEEP_INOBJECT_PROPERTIES,
456                                   properties, "OptimizeForAdding");
457   }
458   return *object;
459 }
460 
RUNTIME_FUNCTION(Runtime_ObjectValues)461 RUNTIME_FUNCTION(Runtime_ObjectValues) {
462   HandleScope scope(isolate);
463   DCHECK_EQ(1, args.length());
464 
465   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
466 
467   Handle<FixedArray> values;
468   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
469       isolate, values,
470       JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
471                                true));
472   return *isolate->factory()->NewJSArrayWithElements(values);
473 }
474 
RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath)475 RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath) {
476   HandleScope scope(isolate);
477   DCHECK_EQ(1, args.length());
478 
479   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
480 
481   Handle<FixedArray> value;
482   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
483       isolate, value,
484       JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
485                                false));
486   return *isolate->factory()->NewJSArrayWithElements(value);
487 }
488 
RUNTIME_FUNCTION(Runtime_ObjectEntries)489 RUNTIME_FUNCTION(Runtime_ObjectEntries) {
490   HandleScope scope(isolate);
491   DCHECK_EQ(1, args.length());
492 
493   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
494 
495   Handle<FixedArray> entries;
496   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
497       isolate, entries,
498       JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
499                                 true));
500   return *isolate->factory()->NewJSArrayWithElements(entries);
501 }
502 
RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath)503 RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) {
504   HandleScope scope(isolate);
505   DCHECK_EQ(1, args.length());
506 
507   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
508 
509   Handle<FixedArray> entries;
510   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
511       isolate, entries,
512       JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
513                                 false));
514   return *isolate->factory()->NewJSArrayWithElements(entries);
515 }
516 
RUNTIME_FUNCTION(Runtime_ObjectIsExtensible)517 RUNTIME_FUNCTION(Runtime_ObjectIsExtensible) {
518   HandleScope scope(isolate);
519   DCHECK_EQ(1, args.length());
520   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
521 
522   Maybe<bool> result =
523       object->IsJSReceiver()
524           ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
525           : Just(false);
526   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
527   return isolate->heap()->ToBoolean(result.FromJust());
528 }
529 
RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsThrow)530 RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsThrow) {
531   HandleScope scope(isolate);
532   DCHECK_EQ(1, args.length());
533   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
534 
535   MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
536                                              kThrowOnError),
537                ReadOnlyRoots(isolate).exception());
538   return *object;
539 }
540 
RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsDontThrow)541 RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsDontThrow) {
542   HandleScope scope(isolate);
543   DCHECK_EQ(1, args.length());
544   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
545 
546   Maybe<bool> result = JSReceiver::PreventExtensions(
547       Handle<JSReceiver>::cast(object), kDontThrow);
548   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
549   return *isolate->factory()->ToBoolean(result.FromJust());
550 }
551 
RUNTIME_FUNCTION(Runtime_JSReceiverGetPrototypeOf)552 RUNTIME_FUNCTION(Runtime_JSReceiverGetPrototypeOf) {
553   HandleScope scope(isolate);
554   DCHECK_EQ(1, args.length());
555   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
556 
557   RETURN_RESULT_OR_FAILURE(isolate,
558                            JSReceiver::GetPrototype(isolate, receiver));
559 }
560 
RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfThrow)561 RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfThrow) {
562   HandleScope scope(isolate);
563 
564   DCHECK_EQ(2, args.length());
565   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
566   CONVERT_ARG_HANDLE_CHECKED(Object, proto, 1);
567 
568   MAYBE_RETURN(JSReceiver::SetPrototype(object, proto, true, kThrowOnError),
569                ReadOnlyRoots(isolate).exception());
570 
571   return *object;
572 }
573 
RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow)574 RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow) {
575   HandleScope scope(isolate);
576 
577   DCHECK_EQ(2, args.length());
578   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
579   CONVERT_ARG_HANDLE_CHECKED(Object, proto, 1);
580 
581   Maybe<bool> result =
582       JSReceiver::SetPrototype(object, proto, true, kDontThrow);
583   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
584   return *isolate->factory()->ToBoolean(result.FromJust());
585 }
586 
RUNTIME_FUNCTION(Runtime_GetProperty)587 RUNTIME_FUNCTION(Runtime_GetProperty) {
588   HandleScope scope(isolate);
589   DCHECK(args.length() == 3 || args.length() == 2);
590   CONVERT_ARG_HANDLE_CHECKED(Object, holder_obj, 0);
591   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
592   Handle<Object> receiver_obj = holder_obj;
593   if (args.length() == 3) {
594     CHECK(args[2].IsObject());
595     receiver_obj = args.at<Object>(2);
596   }
597 
598   // Fast cases for getting named properties of the holder JSObject
599   // itself.
600   //
601   // The global proxy objects has to be excluded since LookupOwn on
602   // the global proxy object can return a valid result even though the
603   // global proxy object never has properties.  This is the case
604   // because the global proxy object forwards everything to its hidden
605   // prototype including own lookups.
606   //
607   // Additionally, we need to make sure that we do not cache results
608   // for objects that require access checks.
609 
610   // Convert string-index keys to their number variant to avoid internalization
611   // below; and speed up subsequent conversion to index.
612   uint32_t index;
613   if (key_obj->IsString() && String::cast(*key_obj).AsArrayIndex(&index)) {
614     key_obj = isolate->factory()->NewNumberFromUint(index);
615   }
616   if (holder_obj->IsJSObject()) {
617     if (!holder_obj->IsJSGlobalProxy() && !holder_obj->IsAccessCheckNeeded() &&
618         key_obj->IsName()) {
619       Handle<JSObject> holder = Handle<JSObject>::cast(holder_obj);
620       Handle<Name> key = Handle<Name>::cast(key_obj);
621       key_obj = key = isolate->factory()->InternalizeName(key);
622 
623       DisallowHeapAllocation no_allocation;
624       if (holder->IsJSGlobalObject()) {
625         // Attempt dictionary lookup.
626         GlobalDictionary dictionary =
627             JSGlobalObject::cast(*holder).global_dictionary();
628         InternalIndex entry = dictionary.FindEntry(isolate, key);
629         if (entry.is_found()) {
630           PropertyCell cell = dictionary.CellAt(entry);
631           if (cell.property_details().kind() == kData) {
632             Object value = cell.value();
633             if (!value.IsTheHole(isolate)) return value;
634             // If value is the hole (meaning, absent) do the general lookup.
635           }
636         }
637       } else if (!holder->HasFastProperties()) {
638         // Attempt dictionary lookup.
639         NameDictionary dictionary = holder->property_dictionary();
640         InternalIndex entry = dictionary.FindEntry(isolate, key);
641         if ((entry.is_found()) &&
642             (dictionary.DetailsAt(entry).kind() == kData)) {
643           return dictionary.ValueAt(entry);
644         }
645       }
646     } else if (key_obj->IsSmi()) {
647       // JSObject without a name key. If the key is a Smi, check for a
648       // definite out-of-bounds access to elements, which is a strong indicator
649       // that subsequent accesses will also call the runtime. Proactively
650       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
651       // doubles for those future calls in the case that the elements would
652       // become PACKED_DOUBLE_ELEMENTS.
653       Handle<JSObject> js_object = Handle<JSObject>::cast(holder_obj);
654       ElementsKind elements_kind = js_object->GetElementsKind();
655       if (IsDoubleElementsKind(elements_kind)) {
656         if (Smi::ToInt(*key_obj) >= js_object->elements().length()) {
657           elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
658                                                              : PACKED_ELEMENTS;
659           JSObject::TransitionElementsKind(js_object, elements_kind);
660         }
661       } else {
662         DCHECK(IsSmiOrObjectElementsKind(elements_kind) ||
663                !IsFastElementsKind(elements_kind));
664       }
665     }
666   } else if (holder_obj->IsString() && key_obj->IsSmi()) {
667     // Fast case for string indexing using [] with a smi index.
668     Handle<String> str = Handle<String>::cast(holder_obj);
669     int index = Handle<Smi>::cast(key_obj)->value();
670     if (index >= 0 && index < str->length()) {
671       Factory* factory = isolate->factory();
672       return *factory->LookupSingleCharacterStringFromCode(
673           String::Flatten(isolate, str)->Get(index));
674     }
675   }
676 
677   // Fall back to GetObjectProperty.
678   RETURN_RESULT_OR_FAILURE(
679       isolate,
680       Runtime::GetObjectProperty(isolate, holder_obj, key_obj, receiver_obj));
681 }
682 
RUNTIME_FUNCTION(Runtime_SetKeyedProperty)683 RUNTIME_FUNCTION(Runtime_SetKeyedProperty) {
684   HandleScope scope(isolate);
685   DCHECK_EQ(3, args.length());
686 
687   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
688   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
689   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
690 
691   RETURN_RESULT_OR_FAILURE(
692       isolate, Runtime::SetObjectProperty(isolate, object, key, value,
693                                           StoreOrigin::kMaybeKeyed));
694 }
695 
RUNTIME_FUNCTION(Runtime_SetNamedProperty)696 RUNTIME_FUNCTION(Runtime_SetNamedProperty) {
697   HandleScope scope(isolate);
698   DCHECK_EQ(3, args.length());
699 
700   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
701   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
702   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
703 
704   RETURN_RESULT_OR_FAILURE(
705       isolate, Runtime::SetObjectProperty(isolate, object, key, value,
706                                           StoreOrigin::kNamed));
707 }
708 
709 // Similar to DefineDataPropertyInLiteral, but does not update feedback, and
710 // and does not have a flags parameter for performing SetFunctionName().
711 //
712 // Currently, this is used for ObjectLiteral spread properties.
RUNTIME_FUNCTION(Runtime_StoreDataPropertyInLiteral)713 RUNTIME_FUNCTION(Runtime_StoreDataPropertyInLiteral) {
714   HandleScope scope(isolate);
715   DCHECK_EQ(3, args.length());
716 
717   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
718   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
719   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
720 
721   LookupIterator::Key lookup_key(isolate, key);
722   LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
723 
724   Maybe<bool> result = JSObject::DefineOwnPropertyIgnoreAttributes(
725       &it, value, NONE, Just(kDontThrow));
726   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
727   DCHECK(result.IsJust());
728   USE(result);
729 
730   return *value;
731 }
732 
733 namespace {
734 
735 // ES6 section 12.5.4.
DeleteProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key,LanguageMode language_mode)736 Object DeleteProperty(Isolate* isolate, Handle<Object> object,
737                       Handle<Object> key, LanguageMode language_mode) {
738   Handle<JSReceiver> receiver;
739   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
740                                      Object::ToObject(isolate, object));
741   Maybe<bool> result =
742       Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
743   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
744   return isolate->heap()->ToBoolean(result.FromJust());
745 }
746 
747 }  // namespace
748 
RUNTIME_FUNCTION(Runtime_DeleteProperty)749 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
750   HandleScope scope(isolate);
751   DCHECK_EQ(3, args.length());
752   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
753   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
754   CONVERT_SMI_ARG_CHECKED(language_mode, 2);
755   return DeleteProperty(isolate, object, key,
756                         static_cast<LanguageMode>(language_mode));
757 }
758 
RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary)759 RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary) {
760   HandleScope scope(isolate);
761   DCHECK_EQ(1, args.length());
762   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
763   Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
764   Handle<NameDictionary> new_properties =
765       NameDictionary::Shrink(isolate, dictionary);
766   receiver->SetProperties(*new_properties);
767   return Smi::zero();
768 }
769 
770 // ES6 section 12.9.3, operator in.
RUNTIME_FUNCTION(Runtime_HasProperty)771 RUNTIME_FUNCTION(Runtime_HasProperty) {
772   HandleScope scope(isolate);
773   DCHECK_EQ(2, args.length());
774   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
775   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
776 
777   // Check that {object} is actually a receiver.
778   if (!object->IsJSReceiver()) {
779     THROW_NEW_ERROR_RETURN_FAILURE(
780         isolate,
781         NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
782   }
783   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
784 
785   // Convert the {key} to a name.
786   Handle<Name> name;
787   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
788                                      Object::ToName(isolate, key));
789 
790   // Lookup the {name} on {receiver}.
791   Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
792   if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
793   return isolate->heap()->ToBoolean(maybe.FromJust());
794 }
795 
RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys)796 RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
797   HandleScope scope(isolate);
798   DCHECK_EQ(2, args.length());
799   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
800   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
801   PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
802 
803   Handle<FixedArray> keys;
804   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
805       isolate, keys,
806       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, filter,
807                               GetKeysConversion::kConvertToString));
808 
809   return *isolate->factory()->NewJSArrayWithElements(keys);
810 }
811 
RUNTIME_FUNCTION(Runtime_ToFastProperties)812 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
813   HandleScope scope(isolate);
814   DCHECK_EQ(1, args.length());
815   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
816   if (object->IsJSObject() && !object->IsJSGlobalObject()) {
817     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
818                                 "RuntimeToFastProperties");
819   }
820   return *object;
821 }
822 
RUNTIME_FUNCTION(Runtime_AllocateHeapNumber)823 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
824   HandleScope scope(isolate);
825   DCHECK_EQ(0, args.length());
826   return *isolate->factory()->NewHeapNumber(0);
827 }
828 
RUNTIME_FUNCTION(Runtime_NewObject)829 RUNTIME_FUNCTION(Runtime_NewObject) {
830   HandleScope scope(isolate);
831   DCHECK_EQ(2, args.length());
832   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
833   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
834   RETURN_RESULT_OR_FAILURE(
835       isolate,
836       JSObject::New(target, new_target, Handle<AllocationSite>::null()));
837 }
838 
RUNTIME_FUNCTION(Runtime_GetDerivedMap)839 RUNTIME_FUNCTION(Runtime_GetDerivedMap) {
840   HandleScope scope(isolate);
841   DCHECK_EQ(2, args.length());
842   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
843   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
844   RETURN_RESULT_OR_FAILURE(
845       isolate, JSFunction::GetDerivedMap(isolate, target, new_target));
846 }
847 
RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap)848 RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) {
849   DisallowHeapAllocation no_gc;
850   HandleScope scope(isolate);
851   DCHECK_EQ(1, args.length());
852 
853   CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
854   initial_map->CompleteInobjectSlackTracking(isolate);
855 
856   return ReadOnlyRoots(isolate).undefined_value();
857 }
858 
RUNTIME_FUNCTION(Runtime_TryMigrateInstance)859 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
860   HandleScope scope(isolate);
861   DCHECK_EQ(1, args.length());
862   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
863   // It could have been a DCHECK but we call this function directly from tests.
864   if (!js_object->map().is_deprecated()) return Smi::zero();
865   // This call must not cause lazy deopts, because it's called from deferred
866   // code where we can't handle lazy deopts for lack of a suitable bailout
867   // ID. So we just try migration and signal failure if necessary,
868   // which will also trigger a deopt.
869   if (!JSObject::TryMigrateInstance(isolate, js_object)) return Smi::zero();
870   return *js_object;
871 }
872 
IsValidAccessor(Isolate * isolate,Handle<Object> obj)873 static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) {
874   return obj->IsNullOrUndefined(isolate) || obj->IsCallable();
875 }
876 
877 // Implements part of 8.12.9 DefineOwnProperty.
878 // There are 3 cases that lead here:
879 // Step 4b - define a new accessor property.
880 // Steps 9c & 12 - replace an existing data property with an accessor property.
881 // Step 12 - update an existing accessor property with an accessor or generic
882 //           descriptor.
RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked)883 RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
884   HandleScope scope(isolate);
885   DCHECK_EQ(5, args.length());
886   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
887   CHECK(!obj->IsNull(isolate));
888   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
889   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
890   CHECK(IsValidAccessor(isolate, getter));
891   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
892   CHECK(IsValidAccessor(isolate, setter));
893   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 4);
894 
895   RETURN_FAILURE_ON_EXCEPTION(
896       isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
897   return ReadOnlyRoots(isolate).undefined_value();
898 }
899 
RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral)900 RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
901   HandleScope scope(isolate);
902   DCHECK_EQ(6, args.length());
903   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
904   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
905   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
906   CONVERT_SMI_ARG_CHECKED(flag, 3);
907   CONVERT_ARG_HANDLE_CHECKED(HeapObject, maybe_vector, 4);
908   CONVERT_TAGGED_INDEX_ARG_CHECKED(index, 5);
909 
910   if (!maybe_vector->IsUndefined()) {
911     DCHECK(maybe_vector->IsFeedbackVector());
912     Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(maybe_vector);
913     FeedbackNexus nexus(vector, FeedbackVector::ToSlot(index));
914     if (nexus.ic_state() == UNINITIALIZED) {
915       if (name->IsUniqueName()) {
916         nexus.ConfigureMonomorphic(name, handle(object->map(), isolate),
917                                    MaybeObjectHandle());
918       } else {
919         nexus.ConfigureMegamorphic(PROPERTY);
920       }
921     } else if (nexus.ic_state() == MONOMORPHIC) {
922       if (nexus.GetFirstMap() != object->map() || nexus.GetName() != *name) {
923         nexus.ConfigureMegamorphic(PROPERTY);
924       }
925     }
926   }
927 
928   DataPropertyInLiteralFlags flags(flag);
929   PropertyAttributes attrs = (flags & DataPropertyInLiteralFlag::kDontEnum)
930                                  ? PropertyAttributes::DONT_ENUM
931                                  : PropertyAttributes::NONE;
932 
933   if (flags & DataPropertyInLiteralFlag::kSetFunctionName) {
934     DCHECK(value->IsJSFunction());
935     Handle<JSFunction> function = Handle<JSFunction>::cast(value);
936     DCHECK(!function->shared().HasSharedName());
937     Handle<Map> function_map(function->map(), isolate);
938     if (!JSFunction::SetName(function, name,
939                              isolate->factory()->empty_string())) {
940       return ReadOnlyRoots(isolate).exception();
941     }
942     // Class constructors do not reserve in-object space for name field.
943     CHECK_IMPLIES(!IsClassConstructor(function->shared().kind()),
944                   *function_map == function->map());
945   }
946 
947   LookupIterator::Key key(isolate, name);
948   LookupIterator it(isolate, object, key, object, LookupIterator::OWN);
949   // Cannot fail since this should only be called when
950   // creating an object literal.
951   CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
952                                                     Just(kDontThrow))
953             .IsJust());
954   return *object;
955 }
956 
RUNTIME_FUNCTION(Runtime_CollectTypeProfile)957 RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
958   HandleScope scope(isolate);
959   DCHECK_EQ(3, args.length());
960   CONVERT_ARG_HANDLE_CHECKED(Smi, position, 0);
961   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
962   CONVERT_ARG_HANDLE_CHECKED(HeapObject, maybe_vector, 2);
963 
964   if (maybe_vector->IsUndefined()) {
965     return ReadOnlyRoots(isolate).undefined_value();
966   }
967   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 2);
968 
969   Handle<String> type = Object::TypeOf(isolate, value);
970   if (value->IsJSReceiver()) {
971     Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
972     type = JSReceiver::GetConstructorName(object);
973   } else if (value->IsNull(isolate)) {
974     // typeof(null) is object. But it's more user-friendly to annotate
975     // null as type "null".
976     type = Handle<String>(ReadOnlyRoots(isolate).null_string(), isolate);
977   }
978 
979   DCHECK(vector->metadata().HasTypeProfileSlot());
980   FeedbackNexus nexus(vector, vector->GetTypeProfileSlot());
981   nexus.Collect(type, position->value());
982 
983   return ReadOnlyRoots(isolate).undefined_value();
984 }
985 
RUNTIME_FUNCTION(Runtime_HasFastPackedElements)986 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
987   SealHandleScope shs(isolate);
988   DCHECK_EQ(1, args.length());
989   CONVERT_ARG_CHECKED(HeapObject, obj, 0);
990   return isolate->heap()->ToBoolean(
991       IsFastPackedElementsKind(obj.map().elements_kind()));
992 }
993 
RUNTIME_FUNCTION(Runtime_IsJSReceiver)994 RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
995   SealHandleScope shs(isolate);
996   DCHECK_EQ(1, args.length());
997   CONVERT_ARG_CHECKED(Object, obj, 0);
998   return isolate->heap()->ToBoolean(obj.IsJSReceiver());
999 }
1000 
RUNTIME_FUNCTION(Runtime_GetFunctionName)1001 RUNTIME_FUNCTION(Runtime_GetFunctionName) {
1002   HandleScope scope(isolate);
1003   DCHECK_EQ(1, args.length());
1004   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
1005   return *JSFunction::GetName(isolate, function);
1006 }
1007 
RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked)1008 RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
1009   HandleScope scope(isolate);
1010   DCHECK_EQ(4, args.length());
1011   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
1012   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1013   CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
1014   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1015 
1016   if (String::cast(getter->shared().Name()).length() == 0) {
1017     Handle<Map> getter_map(getter->map(), isolate);
1018     if (!JSFunction::SetName(getter, name, isolate->factory()->get_string())) {
1019       return ReadOnlyRoots(isolate).exception();
1020     }
1021     CHECK_EQ(*getter_map, getter->map());
1022   }
1023 
1024   RETURN_FAILURE_ON_EXCEPTION(
1025       isolate,
1026       JSObject::DefineAccessor(object, name, getter,
1027                                isolate->factory()->null_value(), attrs));
1028   return ReadOnlyRoots(isolate).undefined_value();
1029 }
1030 
RUNTIME_FUNCTION(Runtime_SetDataProperties)1031 RUNTIME_FUNCTION(Runtime_SetDataProperties) {
1032   HandleScope scope(isolate);
1033   DCHECK_EQ(2, args.length());
1034   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
1035   CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
1036 
1037   // 2. If source is undefined or null, let keys be an empty List.
1038   if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
1039     return ReadOnlyRoots(isolate).undefined_value();
1040   }
1041 
1042   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source),
1043                ReadOnlyRoots(isolate).exception());
1044   return ReadOnlyRoots(isolate).undefined_value();
1045 }
1046 
RUNTIME_FUNCTION(Runtime_CopyDataProperties)1047 RUNTIME_FUNCTION(Runtime_CopyDataProperties) {
1048   HandleScope scope(isolate);
1049   DCHECK_EQ(2, args.length());
1050   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
1051   CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
1052 
1053   // 2. If source is undefined or null, let keys be an empty List.
1054   if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
1055     return ReadOnlyRoots(isolate).undefined_value();
1056   }
1057 
1058   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source,
1059                                                    nullptr, false),
1060                ReadOnlyRoots(isolate).exception());
1061   return ReadOnlyRoots(isolate).undefined_value();
1062 }
1063 
RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties)1064 RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) {
1065   HandleScope scope(isolate);
1066   DCHECK_LE(1, args.length());
1067   CONVERT_ARG_HANDLE_CHECKED(Object, source, 0);
1068 
1069   // If source is undefined or null, throw a non-coercible error.
1070   if (source->IsNullOrUndefined(isolate)) {
1071     return ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, source,
1072                                                     MaybeHandle<Object>());
1073   }
1074 
1075   ScopedVector<Handle<Object>> excluded_properties(args.length() - 1);
1076   for (int i = 1; i < args.length(); i++) {
1077     Handle<Object> property = args.at(i);
1078     uint32_t property_num;
1079     // We convert string to number if possible, in cases of computed
1080     // properties resolving to numbers, which would've been strings
1081     // instead because of our call to %ToName() in the desugaring for
1082     // computed properties.
1083     if (property->IsString() &&
1084         String::cast(*property).AsArrayIndex(&property_num)) {
1085       property = isolate->factory()->NewNumberFromUint(property_num);
1086     }
1087 
1088     excluded_properties[i - 1] = property;
1089   }
1090 
1091   Handle<JSObject> target =
1092       isolate->factory()->NewJSObject(isolate->object_function());
1093   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source,
1094                                                    &excluded_properties, false),
1095                ReadOnlyRoots(isolate).exception());
1096   return *target;
1097 }
1098 
RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked)1099 RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
1100   HandleScope scope(isolate);
1101   DCHECK_EQ(4, args.length());
1102   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
1103   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1104   CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
1105   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1106 
1107   if (String::cast(setter->shared().Name()).length() == 0) {
1108     Handle<Map> setter_map(setter->map(), isolate);
1109     if (!JSFunction::SetName(setter, name, isolate->factory()->set_string())) {
1110       return ReadOnlyRoots(isolate).exception();
1111     }
1112     CHECK_EQ(*setter_map, setter->map());
1113   }
1114 
1115   RETURN_FAILURE_ON_EXCEPTION(
1116       isolate,
1117       JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1118                                setter, attrs));
1119   return ReadOnlyRoots(isolate).undefined_value();
1120 }
1121 
RUNTIME_FUNCTION(Runtime_ToObject)1122 RUNTIME_FUNCTION(Runtime_ToObject) {
1123   // Runtime call is implemented in InterpreterIntrinsics and lowered in
1124   // JSIntrinsicLowering.
1125   UNREACHABLE();
1126 }
1127 
RUNTIME_FUNCTION(Runtime_ToNumber)1128 RUNTIME_FUNCTION(Runtime_ToNumber) {
1129   HandleScope scope(isolate);
1130   DCHECK_EQ(1, args.length());
1131   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1132   RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumber(isolate, input));
1133 }
1134 
RUNTIME_FUNCTION(Runtime_ToNumeric)1135 RUNTIME_FUNCTION(Runtime_ToNumeric) {
1136   HandleScope scope(isolate);
1137   DCHECK_EQ(1, args.length());
1138   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1139   RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumeric(isolate, input));
1140 }
1141 
RUNTIME_FUNCTION(Runtime_ToLength)1142 RUNTIME_FUNCTION(Runtime_ToLength) {
1143   HandleScope scope(isolate);
1144   DCHECK_EQ(1, args.length());
1145   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1146   RETURN_RESULT_OR_FAILURE(isolate, Object::ToLength(isolate, input));
1147 }
1148 
RUNTIME_FUNCTION(Runtime_ToString)1149 RUNTIME_FUNCTION(Runtime_ToString) {
1150   HandleScope scope(isolate);
1151   DCHECK_EQ(1, args.length());
1152   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1153   RETURN_RESULT_OR_FAILURE(isolate, Object::ToString(isolate, input));
1154 }
1155 
RUNTIME_FUNCTION(Runtime_ToName)1156 RUNTIME_FUNCTION(Runtime_ToName) {
1157   HandleScope scope(isolate);
1158   DCHECK_EQ(1, args.length());
1159   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1160   RETURN_RESULT_OR_FAILURE(isolate, Object::ToName(isolate, input));
1161 }
1162 
RUNTIME_FUNCTION(Runtime_HasInPrototypeChain)1163 RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
1164   HandleScope scope(isolate);
1165   DCHECK_EQ(2, args.length());
1166   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
1167   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1168   if (!object->IsJSReceiver()) return ReadOnlyRoots(isolate).false_value();
1169   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
1170       isolate, Handle<JSReceiver>::cast(object), prototype);
1171   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
1172   return isolate->heap()->ToBoolean(result.FromJust());
1173 }
1174 
1175 // ES6 section 7.4.7 CreateIterResultObject ( value, done )
RUNTIME_FUNCTION(Runtime_CreateIterResultObject)1176 RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
1177   HandleScope scope(isolate);
1178   DCHECK_EQ(2, args.length());
1179   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
1180   CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
1181   return *isolate->factory()->NewJSIteratorResult(value,
1182                                                   done->BooleanValue(isolate));
1183 }
1184 
RUNTIME_FUNCTION(Runtime_CreateDataProperty)1185 RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
1186   HandleScope scope(isolate);
1187   DCHECK_EQ(3, args.length());
1188   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
1189   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1190   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1191   bool success;
1192   LookupIterator::Key lookup_key(isolate, key, &success);
1193   if (!success) return ReadOnlyRoots(isolate).exception();
1194   LookupIterator it(isolate, o, lookup_key, LookupIterator::OWN);
1195   MAYBE_RETURN(JSReceiver::CreateDataProperty(&it, value, Just(kThrowOnError)),
1196                ReadOnlyRoots(isolate).exception());
1197   return *value;
1198 }
1199 
RUNTIME_FUNCTION(Runtime_SetOwnPropertyIgnoreAttributes)1200 RUNTIME_FUNCTION(Runtime_SetOwnPropertyIgnoreAttributes) {
1201   HandleScope scope(isolate);
1202   DCHECK_EQ(4, args.length());
1203   CONVERT_ARG_HANDLE_CHECKED(JSObject, o, 0);
1204   CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
1205   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1206   CONVERT_ARG_HANDLE_CHECKED(Smi, attributes, 3);
1207 
1208   RETURN_RESULT_OR_FAILURE(
1209       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
1210                    o, key, value, PropertyAttributes(attributes->value())));
1211 }
1212 
RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor)1213 RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor) {
1214   HandleScope scope(isolate);
1215 
1216   DCHECK_EQ(2, args.length());
1217   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
1218   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1219 
1220   PropertyDescriptor desc;
1221   Maybe<bool> found =
1222       JSReceiver::GetOwnPropertyDescriptor(isolate, object, name, &desc);
1223   MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
1224 
1225   if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
1226   return *desc.ToPropertyDescriptorObject(isolate);
1227 }
1228 
RUNTIME_FUNCTION(Runtime_LoadPrivateSetter)1229 RUNTIME_FUNCTION(Runtime_LoadPrivateSetter) {
1230   HandleScope scope(isolate);
1231   DCHECK_EQ(args.length(), 1);
1232   CONVERT_ARG_HANDLE_CHECKED(AccessorPair, pair, 0);
1233   DCHECK(pair->setter().IsJSFunction());
1234   return pair->setter();
1235 }
1236 
RUNTIME_FUNCTION(Runtime_LoadPrivateGetter)1237 RUNTIME_FUNCTION(Runtime_LoadPrivateGetter) {
1238   HandleScope scope(isolate);
1239   DCHECK_EQ(args.length(), 1);
1240   CONVERT_ARG_HANDLE_CHECKED(AccessorPair, pair, 0);
1241   DCHECK(pair->getter().IsJSFunction());
1242   return pair->getter();
1243 }
1244 
RUNTIME_FUNCTION(Runtime_CreatePrivateAccessors)1245 RUNTIME_FUNCTION(Runtime_CreatePrivateAccessors) {
1246   HandleScope scope(isolate);
1247   DCHECK_EQ(args.length(), 2);
1248   DCHECK(args[0].IsNull() || args[0].IsJSFunction());
1249   DCHECK(args[1].IsNull() || args[1].IsJSFunction());
1250   Handle<AccessorPair> pair = isolate->factory()->NewAccessorPair();
1251   pair->SetComponents(args[0], args[1]);
1252   return *pair;
1253 }
1254 
RUNTIME_FUNCTION(Runtime_AddPrivateBrand)1255 RUNTIME_FUNCTION(Runtime_AddPrivateBrand) {
1256   HandleScope scope(isolate);
1257   DCHECK_EQ(args.length(), 3);
1258   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
1259   CONVERT_ARG_HANDLE_CHECKED(Symbol, brand, 1);
1260   CONVERT_ARG_HANDLE_CHECKED(Context, context, 2);
1261   DCHECK(brand->is_private_name());
1262 
1263   LookupIterator it(isolate, receiver, brand, LookupIterator::OWN);
1264 
1265   if (it.IsFound()) {
1266     THROW_NEW_ERROR_RETURN_FAILURE(
1267         isolate, NewTypeError(MessageTemplate::kVarRedeclaration, brand));
1268   }
1269 
1270   PropertyAttributes attributes =
1271       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1272   CHECK(Object::AddDataProperty(&it, context, attributes, Just(kDontThrow),
1273                                 StoreOrigin::kMaybeKeyed)
1274             .FromJust());
1275   return *receiver;
1276 }
1277 
RUNTIME_FUNCTION(Runtime_AddPrivateField)1278 RUNTIME_FUNCTION(Runtime_AddPrivateField) {
1279   HandleScope scope(isolate);
1280   DCHECK_EQ(3, args.length());
1281   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
1282   CONVERT_ARG_HANDLE_CHECKED(Symbol, key, 1);
1283   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1284   DCHECK(key->is_private_name());
1285 
1286   LookupIterator it(isolate, o, key, LookupIterator::OWN);
1287 
1288   if (it.IsFound()) {
1289     THROW_NEW_ERROR_RETURN_FAILURE(
1290         isolate, NewTypeError(MessageTemplate::kVarRedeclaration, key));
1291   }
1292 
1293   CHECK(Object::AddDataProperty(&it, value, NONE, Just(kDontThrow),
1294                                 StoreOrigin::kMaybeKeyed)
1295             .FromJust());
1296   return ReadOnlyRoots(isolate).undefined_value();
1297 }
1298 
1299 }  // namespace internal
1300 }  // namespace v8
1301