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