• 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/base/macros.h"
7 #include "src/builtins/builtins.h"
8 #include "src/common/globals.h"
9 #include "src/common/message-template.h"
10 #include "src/debug/debug.h"
11 #include "src/execution/arguments-inl.h"
12 #include "src/execution/frames.h"
13 #include "src/execution/isolate-inl.h"
14 #include "src/execution/messages.h"
15 #include "src/handles/maybe-handles.h"
16 #include "src/heap/heap-inl.h"  // For ToBoolean. TODO(jkummerow): Drop.
17 #include "src/heap/memory-chunk.h"
18 #include "src/init/bootstrapper.h"
19 #include "src/logging/counters.h"
20 #include "src/objects/hash-table-inl.h"
21 #include "src/objects/js-array-inl.h"
22 #include "src/objects/map-updater.h"
23 #include "src/objects/property-descriptor-object.h"
24 #include "src/objects/property-descriptor.h"
25 #include "src/objects/property-details.h"
26 #include "src/objects/swiss-name-dictionary-inl.h"
27 #include "src/runtime/runtime-utils.h"
28 #include "src/runtime/runtime.h"
29 
30 namespace v8 {
31 namespace internal {
32 
GetObjectProperty(Isolate * isolate,Handle<Object> lookup_start_object,Handle<Object> key,Handle<Object> receiver,bool * is_found)33 MaybeHandle<Object> Runtime::GetObjectProperty(
34     Isolate* isolate, Handle<Object> lookup_start_object, Handle<Object> key,
35     Handle<Object> receiver, bool* is_found) {
36   if (receiver.is_null()) {
37     receiver = lookup_start_object;
38   }
39   if (lookup_start_object->IsNullOrUndefined(isolate)) {
40     ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, lookup_start_object, key);
41     return MaybeHandle<Object>();
42   }
43 
44   bool success = false;
45   PropertyKey lookup_key(isolate, key, &success);
46   if (!success) return MaybeHandle<Object>();
47   LookupIterator it =
48       LookupIterator(isolate, receiver, lookup_key, lookup_start_object);
49 
50   MaybeHandle<Object> result = Object::GetProperty(&it);
51   if (result.is_null()) {
52     return result;
53   }
54   if (is_found) *is_found = it.IsFound();
55 
56   if (!it.IsFound() && key->IsSymbol() &&
57       Symbol::cast(*key).is_private_name()) {
58     MessageTemplate message =
59         Symbol::cast(*key).IsPrivateBrand()
60             ? MessageTemplate::kInvalidPrivateBrandInstance
61             : MessageTemplate::kInvalidPrivateMemberRead;
62     THROW_NEW_ERROR(isolate, NewTypeError(message, key, lookup_start_object),
63                     Object);
64   }
65   return result;
66 }
67 
HasProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key)68 MaybeHandle<Object> Runtime::HasProperty(Isolate* isolate,
69                                          Handle<Object> object,
70                                          Handle<Object> key) {
71   // Check that {object} is actually a receiver.
72   if (!object->IsJSReceiver()) {
73     THROW_NEW_ERROR(
74         isolate,
75         NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object),
76         Object);
77   }
78   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
79 
80   // Convert the {key} to a name.
81   Handle<Name> name;
82   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
83                              Object);
84 
85   // Lookup the {name} on {receiver}.
86   Maybe<bool> maybe = JSReceiver::HasProperty(isolate, receiver, name);
87   if (maybe.IsNothing()) return MaybeHandle<Object>();
88   return maybe.FromJust() ? ReadOnlyRoots(isolate).true_value_handle()
89                           : ReadOnlyRoots(isolate).false_value_handle();
90 }
91 
92 namespace {
93 
94 // This function sets the sentinel value in a deleted field. Thes sentinel has
95 // to look like a proper standalone object because the slack tracking may
96 // complete at any time. For this reason we use the filler map word.
97 // If V8_MAP_PACKING is enabled, then the filler map word is a packed filler
98 // map. Otherwise, the filler map word is the same as the filler map.
ClearField(Isolate * isolate,JSObject object,FieldIndex index)99 inline void ClearField(Isolate* isolate, JSObject object, FieldIndex index) {
100   if (index.is_inobject()) {
101     MapWord filler_map_word =
102         ReadOnlyRoots(isolate).one_pointer_filler_map_word();
103 #ifndef V8_MAP_PACKING
104     DCHECK_EQ(filler_map_word.ToMap(),
105               ReadOnlyRoots(isolate).one_pointer_filler_map());
106 #endif
107     int offset = index.offset();
108     TaggedField<MapWord>::Release_Store(object, offset, filler_map_word);
109   } else {
110     object.property_array().set(
111         index.outobject_array_index(),
112         ReadOnlyRoots(isolate).one_pointer_filler_map());
113   }
114 }
115 
GeneralizeAllTransitionsToFieldAsMutable(Isolate * isolate,Handle<Map> map,Handle<Name> name)116 void GeneralizeAllTransitionsToFieldAsMutable(Isolate* isolate, Handle<Map> map,
117                                               Handle<Name> name) {
118   InternalIndex descriptor(map->NumberOfOwnDescriptors());
119 
120   Handle<Map> target_maps[kPropertyAttributesCombinationsCount];
121   int target_maps_count = 0;
122 
123   // Collect all outgoing field transitions.
124   {
125     DisallowGarbageCollection no_gc;
126     TransitionsAccessor transitions(isolate, *map);
127     transitions.ForEachTransitionTo(
128         *name,
129         [&](Map target) {
130           DCHECK_EQ(descriptor, target.LastAdded());
131           DCHECK_EQ(*name, target.GetLastDescriptorName(isolate));
132           PropertyDetails details = target.GetLastDescriptorDetails(isolate);
133           // Currently, we track constness only for fields.
134           if (details.kind() == PropertyKind::kData &&
135               details.constness() == PropertyConstness::kConst) {
136             target_maps[target_maps_count++] = handle(target, isolate);
137           }
138           DCHECK_IMPLIES(details.kind() == PropertyKind::kAccessor,
139                          details.constness() == PropertyConstness::kConst);
140         },
141         &no_gc);
142     CHECK_LE(target_maps_count, kPropertyAttributesCombinationsCount);
143   }
144 
145   for (int i = 0; i < target_maps_count; i++) {
146     Handle<Map> target = target_maps[i];
147     PropertyDetails details =
148         target->instance_descriptors(isolate).GetDetails(descriptor);
149     Handle<FieldType> field_type(
150         target->instance_descriptors(isolate).GetFieldType(descriptor),
151         isolate);
152     MapUpdater::GeneralizeField(isolate, target, descriptor,
153                                 PropertyConstness::kMutable,
154                                 details.representation(), field_type);
155     DCHECK_EQ(PropertyConstness::kMutable, target->instance_descriptors(isolate)
156                                                .GetDetails(descriptor)
157                                                .constness());
158   }
159 }
160 
DeleteObjectPropertyFast(Isolate * isolate,Handle<JSReceiver> receiver,Handle<Object> raw_key)161 bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver,
162                               Handle<Object> raw_key) {
163   // This implements a special case for fast property deletion: when the
164   // last property in an object is deleted, then instead of normalizing
165   // the properties, we can undo the last map transition, with a few
166   // prerequisites:
167   // (1) The receiver must be a regular object and the key a unique name.
168   Handle<Map> receiver_map(receiver->map(), isolate);
169   if (receiver_map->IsSpecialReceiverMap()) return false;
170   DCHECK(receiver_map->IsJSObjectMap());
171 
172   if (!raw_key->IsUniqueName()) return false;
173   Handle<Name> key = Handle<Name>::cast(raw_key);
174   // (2) The property to be deleted must be the last property.
175   int nof = receiver_map->NumberOfOwnDescriptors();
176   if (nof == 0) return false;
177   InternalIndex descriptor(nof - 1);
178   Handle<DescriptorArray> descriptors(
179       receiver_map->instance_descriptors(isolate), isolate);
180   if (descriptors->GetKey(descriptor) != *key) return false;
181   // (3) The property to be deleted must be deletable.
182   PropertyDetails details = descriptors->GetDetails(descriptor);
183   if (!details.IsConfigurable()) return false;
184   // (4) The map must have a back pointer.
185   Handle<Object> backpointer(receiver_map->GetBackPointer(), isolate);
186   if (!backpointer->IsMap()) return false;
187   Handle<Map> parent_map = Handle<Map>::cast(backpointer);
188   // (5) The last transition must have been caused by adding a property
189   // (and not any kind of special transition).
190   if (parent_map->NumberOfOwnDescriptors() != nof - 1) return false;
191 
192   // Preconditions successful. No more bailouts after this point.
193 
194   // Zap the property to avoid keeping objects alive. Zapping is not necessary
195   // for properties stored in the descriptor array.
196   if (details.location() == PropertyLocation::kField) {
197     DisallowGarbageCollection no_gc;
198 
199     // Invalidate slots manually later in case we delete an in-object tagged
200     // property. In this case we might later store an untagged value in the
201     // recorded slot.
202     isolate->heap()->NotifyObjectLayoutChange(*receiver, no_gc,
203                                               InvalidateRecordedSlots::kNo);
204     FieldIndex index =
205         FieldIndex::ForPropertyIndex(*receiver_map, details.field_index());
206     // Special case deleting the last out-of object property.
207     if (!index.is_inobject() && index.outobject_array_index() == 0) {
208       DCHECK(!parent_map->HasOutOfObjectProperties());
209       // Clear out the properties backing store.
210       receiver->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
211     } else {
212       ClearField(isolate, JSObject::cast(*receiver), index);
213       // We must clear any recorded slot for the deleted property, because
214       // subsequent object modifications might put a raw double there.
215       // Slot clearing is the reason why this entire function cannot currently
216       // be implemented in the DeleteProperty stub.
217       if (index.is_inobject()) {
218         // We need to clear the recorded slot in this case because in-object
219         // slack tracking might not be finished. This ensures that we don't
220         // have recorded slots in free space.
221         isolate->heap()->ClearRecordedSlot(*receiver,
222                                            receiver->RawField(index.offset()));
223         if (!FLAG_enable_third_party_heap) {
224           MemoryChunk* chunk = MemoryChunk::FromHeapObject(*receiver);
225           chunk->InvalidateRecordedSlots(*receiver);
226         }
227       }
228     }
229   }
230   // If the {receiver_map} was marked stable before, then there could be
231   // optimized code that depends on the assumption that no object that
232   // reached this {receiver_map} transitions away from it without triggering
233   // the "deoptimize dependent code" mechanism.
234   receiver_map->NotifyLeafMapLayoutChange(isolate);
235   // Finally, perform the map rollback.
236   receiver->set_map(*parent_map, kReleaseStore);
237 #if VERIFY_HEAP
238   receiver->HeapObjectVerify(isolate);
239   receiver->property_array().PropertyArrayVerify(isolate);
240 #endif
241 
242   // If the {descriptor} was "const" so far, we need to update the
243   // {receiver_map} here, otherwise we could get the constants wrong, i.e.
244   //
245   //   o.x = 1;
246   //   [change o.x's attributes or reconfigure property kind]
247   //   delete o.x;
248   //   o.x = 2;
249   //
250   // could trick V8 into thinking that `o.x` is still 1 even after the second
251   // assignment.
252 
253   // Step 1: Migrate object to an up-to-date shape.
254   if (parent_map->is_deprecated()) {
255     JSObject::MigrateInstance(isolate, Handle<JSObject>::cast(receiver));
256     parent_map = handle(receiver->map(), isolate);
257   }
258 
259   // Step 2: Mark outgoing transitions from the up-to-date version of the
260   // parent_map to same property name of any kind or attributes as mutable.
261   // Also migrate object to the up-to-date map to make the object shapes
262   // converge sooner.
263   GeneralizeAllTransitionsToFieldAsMutable(isolate, parent_map, key);
264 
265   return true;
266 }
267 
268 }  // namespace
269 
DeleteObjectProperty(Isolate * isolate,Handle<JSReceiver> receiver,Handle<Object> key,LanguageMode language_mode)270 Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
271                                           Handle<JSReceiver> receiver,
272                                           Handle<Object> key,
273                                           LanguageMode language_mode) {
274   if (DeleteObjectPropertyFast(isolate, receiver, key)) return Just(true);
275 
276   bool success = false;
277   PropertyKey lookup_key(isolate, key, &success);
278   if (!success) return Nothing<bool>();
279   LookupIterator it(isolate, receiver, lookup_key, LookupIterator::OWN);
280 
281   return JSReceiver::DeleteProperty(&it, language_mode);
282 }
283 
284 // ES #sec-object.keys
RUNTIME_FUNCTION(Runtime_ObjectKeys)285 RUNTIME_FUNCTION(Runtime_ObjectKeys) {
286   HandleScope scope(isolate);
287   Handle<Object> object = args.at(0);
288 
289   // Convert the {object} to a proper {receiver}.
290   Handle<JSReceiver> receiver;
291   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
292                                      Object::ToObject(isolate, object));
293 
294   // Collect the own keys for the {receiver}.
295   Handle<FixedArray> keys;
296   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
297       isolate, keys,
298       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
299                               ENUMERABLE_STRINGS,
300                               GetKeysConversion::kConvertToString));
301   return *keys;
302 }
303 
304 // ES #sec-object.getOwnPropertyNames
RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNames)305 RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNames) {
306   HandleScope scope(isolate);
307   Handle<Object> object = args.at(0);
308 
309   // Convert the {object} to a proper {receiver}.
310   Handle<JSReceiver> receiver;
311   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
312                                      Object::ToObject(isolate, object));
313 
314   // Collect the own keys for the {receiver}.
315   // TODO(v8:9401): We should extend the fast path of KeyAccumulator::GetKeys to
316   // also use fast path even when filter = SKIP_SYMBOLS.
317   Handle<FixedArray> keys;
318   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
319       isolate, keys,
320       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
321                               SKIP_SYMBOLS,
322                               GetKeysConversion::kConvertToString));
323   return *keys;
324 }
325 
RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNamesTryFast)326 RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNamesTryFast) {
327   HandleScope scope(isolate);
328   Handle<Object> object = args.at(0);
329 
330   // Convert the {object} to a proper {receiver}.
331   Handle<JSReceiver> receiver;
332   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
333                                      Object::ToObject(isolate, object));
334 
335   Handle<Map> map(receiver->map(), isolate);
336 
337   int nod = map->NumberOfOwnDescriptors();
338   Handle<FixedArray> keys;
339   if (nod != 0 && map->NumberOfEnumerableProperties() == nod) {
340     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
341         isolate, keys,
342         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
343                                 ENUMERABLE_STRINGS,
344                                 GetKeysConversion::kConvertToString));
345   } else {
346     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
347         isolate, keys,
348         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
349                                 SKIP_SYMBOLS,
350                                 GetKeysConversion::kConvertToString));
351   }
352 
353   return *keys;
354 }
355 
356 // ES6 19.1.3.2
RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty)357 RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
358   HandleScope scope(isolate);
359   Handle<Object> property = args.at(1);
360 
361   // TODO(ishell): To improve performance, consider performing the to-string
362   // conversion of {property} before calling into the runtime.
363   bool success;
364   PropertyKey key(isolate, property, &success);
365   if (!success) return ReadOnlyRoots(isolate).exception();
366 
367   Handle<Object> object = args.at(0);
368 
369   if (object->IsJSModuleNamespace()) {
370     LookupIterator it(isolate, object, key, LookupIterator::OWN);
371     PropertyDescriptor desc;
372     Maybe<bool> result = JSReceiver::GetOwnPropertyDescriptor(&it, &desc);
373     if (!result.IsJust()) return ReadOnlyRoots(isolate).exception();
374     return isolate->heap()->ToBoolean(result.FromJust());
375 
376   } else if (object->IsJSObject()) {
377     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
378     // Fast case: either the key is a real named property or it is not
379     // an array index and there are no interceptors or hidden
380     // prototypes.
381     // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
382     // handle all cases directly (without this custom fast path).
383     {
384       LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
385       LookupIterator it(isolate, js_obj, key, js_obj, c);
386       Maybe<bool> maybe = JSReceiver::HasProperty(&it);
387       if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
388       DCHECK(!isolate->has_pending_exception());
389       if (maybe.FromJust()) return ReadOnlyRoots(isolate).true_value();
390     }
391 
392     Map map = js_obj->map();
393     if (!map.IsJSGlobalProxyMap() &&
394         (key.is_element() && key.index() <= JSObject::kMaxElementIndex
395              ? !map.has_indexed_interceptor()
396              : !map.has_named_interceptor())) {
397       return ReadOnlyRoots(isolate).false_value();
398     }
399 
400     // Slow case.
401     LookupIterator it(isolate, js_obj, key, js_obj, LookupIterator::OWN);
402     Maybe<bool> maybe = JSReceiver::HasProperty(&it);
403     if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
404     DCHECK(!isolate->has_pending_exception());
405     return isolate->heap()->ToBoolean(maybe.FromJust());
406 
407   } else if (object->IsJSProxy()) {
408     LookupIterator it(isolate, object, key, Handle<JSProxy>::cast(object),
409                       LookupIterator::OWN);
410     Maybe<PropertyAttributes> attributes =
411         JSReceiver::GetPropertyAttributes(&it);
412     if (attributes.IsNothing()) return ReadOnlyRoots(isolate).exception();
413     return isolate->heap()->ToBoolean(attributes.FromJust() != ABSENT);
414 
415   } else if (object->IsString()) {
416     return isolate->heap()->ToBoolean(
417         key.is_element()
418             ? key.index() < static_cast<size_t>(String::cast(*object).length())
419             : key.name()->Equals(ReadOnlyRoots(isolate).length_string()));
420   } else if (object->IsNullOrUndefined(isolate)) {
421     THROW_NEW_ERROR_RETURN_FAILURE(
422         isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
423   }
424 
425   return ReadOnlyRoots(isolate).false_value();
426 }
427 
RUNTIME_FUNCTION(Runtime_HasOwnConstDataProperty)428 RUNTIME_FUNCTION(Runtime_HasOwnConstDataProperty) {
429   HandleScope scope(isolate);
430   DCHECK_EQ(2, args.length());
431   Handle<Object> object = args.at(0);
432   Handle<Object> property = args.at(1);
433 
434   bool success;
435   PropertyKey key(isolate, property, &success);
436   if (!success) return ReadOnlyRoots(isolate).undefined_value();
437 
438   if (object->IsJSObject()) {
439     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
440     LookupIterator it(isolate, js_obj, key, js_obj, LookupIterator::OWN);
441 
442     switch (it.state()) {
443       case LookupIterator::NOT_FOUND:
444         return isolate->heap()->ToBoolean(false);
445       case LookupIterator::DATA:
446         return isolate->heap()->ToBoolean(it.constness() ==
447                                           PropertyConstness::kConst);
448       default:
449         return ReadOnlyRoots(isolate).undefined_value();
450     }
451   }
452 
453   return ReadOnlyRoots(isolate).undefined_value();
454 }
455 
RUNTIME_FUNCTION(Runtime_IsDictPropertyConstTrackingEnabled)456 RUNTIME_FUNCTION(Runtime_IsDictPropertyConstTrackingEnabled) {
457   return isolate->heap()->ToBoolean(V8_DICT_PROPERTY_CONST_TRACKING_BOOL);
458 }
459 
RUNTIME_FUNCTION(Runtime_AddDictionaryProperty)460 RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
461   HandleScope scope(isolate);
462   Handle<JSObject> receiver = args.at<JSObject>(0);
463   Handle<Name> name = args.at<Name>(1);
464   Handle<Object> value = args.at(2);
465 
466   DCHECK(name->IsUniqueName());
467 
468   PropertyDetails property_details(
469       PropertyKind::kData, NONE,
470       PropertyDetails::kConstIfDictConstnessTracking);
471   if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
472     Handle<SwissNameDictionary> dictionary(
473         receiver->property_dictionary_swiss(), isolate);
474     dictionary = SwissNameDictionary::Add(isolate, dictionary, name, value,
475                                           property_details);
476     receiver->SetProperties(*dictionary);
477   } else {
478     Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
479     dictionary =
480         NameDictionary::Add(isolate, dictionary, name, value, property_details);
481     receiver->SetProperties(*dictionary);
482   }
483 
484   return *value;
485 }
486 
RUNTIME_FUNCTION(Runtime_AddPrivateBrand)487 RUNTIME_FUNCTION(Runtime_AddPrivateBrand) {
488   HandleScope scope(isolate);
489   DCHECK_EQ(args.length(), 4);
490   Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
491   Handle<Symbol> brand = args.at<Symbol>(1);
492   Handle<Context> context = args.at<Context>(2);
493   int depth = args.smi_value_at(3);
494   DCHECK(brand->is_private_name());
495 
496   LookupIterator it(isolate, receiver, brand, LookupIterator::OWN);
497 
498   if (it.IsFound()) {
499     THROW_NEW_ERROR_RETURN_FAILURE(
500         isolate,
501         NewTypeError(MessageTemplate::kInvalidPrivateBrandReinitialization,
502                      brand));
503   }
504 
505   PropertyAttributes attributes =
506       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
507 
508   // Look for the context in |depth| in the context chain to store it
509   // in the instance with the brand variable as key, which is needed by
510   // the debugger for retrieving names of private methods.
511   DCHECK_GE(depth, 0);
512   for (; depth > 0; depth--) {
513     context =
514         handle(Context::cast(context->get(Context::PREVIOUS_INDEX)), isolate);
515   }
516   DCHECK_EQ(context->scope_info().scope_type(), ScopeType::CLASS_SCOPE);
517   CHECK(Object::AddDataProperty(&it, context, attributes, Just(kDontThrow),
518                                 StoreOrigin::kMaybeKeyed)
519             .FromJust());
520   return *receiver;
521 }
522 
523 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
524 // TODO(verwaest): Support the common cases with precached map directly in
525 // an Object.create stub.
RUNTIME_FUNCTION(Runtime_ObjectCreate)526 RUNTIME_FUNCTION(Runtime_ObjectCreate) {
527   HandleScope scope(isolate);
528   Handle<Object> prototype = args.at(0);
529   Handle<Object> properties = args.at(1);
530   Handle<JSObject> obj;
531   // 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
532   if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
533     THROW_NEW_ERROR_RETURN_FAILURE(
534         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
535   }
536   // 2. Let obj be ObjectCreate(O).
537   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
538       isolate, obj, JSObject::ObjectCreate(isolate, prototype));
539 
540   // 3. If Properties is not undefined, then
541   if (!properties->IsUndefined(isolate)) {
542     // a. Return ? ObjectDefineProperties(obj, Properties).
543     // Define the properties if properties was specified and is not undefined.
544     RETURN_RESULT_OR_FAILURE(
545         isolate, JSReceiver::DefineProperties(isolate, obj, properties));
546   }
547   // 4. Return obj.
548   return *obj;
549 }
550 
SetObjectProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key,Handle<Object> value,StoreOrigin store_origin,Maybe<ShouldThrow> should_throw)551 MaybeHandle<Object> Runtime::SetObjectProperty(
552     Isolate* isolate, Handle<Object> object, Handle<Object> key,
553     Handle<Object> value, StoreOrigin store_origin,
554     Maybe<ShouldThrow> should_throw) {
555   if (object->IsNullOrUndefined(isolate)) {
556     MaybeHandle<String> maybe_property =
557         Object::NoSideEffectsToMaybeString(isolate, key);
558     Handle<String> property_name;
559     if (maybe_property.ToHandle(&property_name)) {
560       THROW_NEW_ERROR(
561           isolate,
562           NewTypeError(MessageTemplate::kNonObjectPropertyStoreWithProperty,
563                        object, property_name),
564           Object);
565     } else {
566       THROW_NEW_ERROR(
567           isolate,
568           NewTypeError(MessageTemplate::kNonObjectPropertyStore, object),
569           Object);
570     }
571   }
572 
573   // Check if the given key is an array index.
574   bool success = false;
575   PropertyKey lookup_key(isolate, key, &success);
576   if (!success) return MaybeHandle<Object>();
577   LookupIterator it(isolate, object, lookup_key);
578   if (key->IsSymbol() && Symbol::cast(*key).is_private_name() &&
579       !JSReceiver::CheckPrivateNameStore(&it, false)) {
580     return MaybeHandle<Object>();
581   }
582 
583   MAYBE_RETURN_NULL(
584       Object::SetProperty(&it, value, store_origin, should_throw));
585 
586   return value;
587 }
588 
DefineObjectOwnProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key,Handle<Object> value,StoreOrigin store_origin)589 MaybeHandle<Object> Runtime::DefineObjectOwnProperty(Isolate* isolate,
590                                                      Handle<Object> object,
591                                                      Handle<Object> key,
592                                                      Handle<Object> value,
593                                                      StoreOrigin store_origin) {
594   if (object->IsNullOrUndefined(isolate)) {
595     THROW_NEW_ERROR(
596         isolate,
597         NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
598         Object);
599   }
600 
601   // Check if the given key is an array index.
602   bool success = false;
603   PropertyKey lookup_key(isolate, key, &success);
604   if (!success) return MaybeHandle<Object>();
605   LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
606 
607   if (key->IsSymbol() && Symbol::cast(*key).is_private_name()) {
608     if (!JSReceiver::CheckPrivateNameStore(&it, true)) {
609       return MaybeHandle<Object>();
610     }
611     DCHECK(!it.IsFound());
612     MAYBE_RETURN_NULL(
613         JSReceiver::AddPrivateField(&it, value, Nothing<ShouldThrow>()));
614   } else {
615     MAYBE_RETURN_NULL(
616         JSReceiver::CreateDataProperty(&it, value, Nothing<ShouldThrow>()));
617   }
618 
619   return value;
620 }
621 
RUNTIME_FUNCTION(Runtime_InternalSetPrototype)622 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
623   HandleScope scope(isolate);
624   DCHECK_EQ(2, args.length());
625   Handle<JSReceiver> obj = args.at<JSReceiver>(0);
626   Handle<Object> prototype = args.at(1);
627   MAYBE_RETURN(
628       JSReceiver::SetPrototype(isolate, obj, prototype, false, kThrowOnError),
629       ReadOnlyRoots(isolate).exception());
630   return *obj;
631 }
632 
RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties)633 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
634   HandleScope scope(isolate);
635   DCHECK_EQ(2, args.length());
636   Handle<JSObject> object = args.at<JSObject>(0);
637   int properties = args.smi_value_at(1);
638   // Conservative upper limit to prevent fuzz tests from going OOM.
639   if (properties > 100000) return isolate->ThrowIllegalOperation();
640   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
641     JSObject::NormalizeProperties(isolate, object, KEEP_INOBJECT_PROPERTIES,
642                                   properties, "OptimizeForAdding");
643   }
644   return *object;
645 }
646 
RUNTIME_FUNCTION(Runtime_ObjectValues)647 RUNTIME_FUNCTION(Runtime_ObjectValues) {
648   HandleScope scope(isolate);
649   DCHECK_EQ(1, args.length());
650 
651   Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
652 
653   Handle<FixedArray> values;
654   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
655       isolate, values,
656       JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
657                                true));
658   return *isolate->factory()->NewJSArrayWithElements(values);
659 }
660 
RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath)661 RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath) {
662   HandleScope scope(isolate);
663   DCHECK_EQ(1, args.length());
664 
665   Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
666 
667   Handle<FixedArray> value;
668   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
669       isolate, value,
670       JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
671                                false));
672   return *isolate->factory()->NewJSArrayWithElements(value);
673 }
674 
RUNTIME_FUNCTION(Runtime_ObjectEntries)675 RUNTIME_FUNCTION(Runtime_ObjectEntries) {
676   HandleScope scope(isolate);
677   DCHECK_EQ(1, args.length());
678 
679   Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
680 
681   Handle<FixedArray> entries;
682   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
683       isolate, entries,
684       JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
685                                 true));
686   return *isolate->factory()->NewJSArrayWithElements(entries);
687 }
688 
RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath)689 RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) {
690   HandleScope scope(isolate);
691   DCHECK_EQ(1, args.length());
692 
693   Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
694 
695   Handle<FixedArray> entries;
696   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
697       isolate, entries,
698       JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
699                                 false));
700   return *isolate->factory()->NewJSArrayWithElements(entries);
701 }
702 
RUNTIME_FUNCTION(Runtime_ObjectIsExtensible)703 RUNTIME_FUNCTION(Runtime_ObjectIsExtensible) {
704   HandleScope scope(isolate);
705   DCHECK_EQ(1, args.length());
706   Handle<Object> object = args.at(0);
707 
708   Maybe<bool> result =
709       object->IsJSReceiver()
710           ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
711           : Just(false);
712   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
713   return isolate->heap()->ToBoolean(result.FromJust());
714 }
715 
RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsThrow)716 RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsThrow) {
717   HandleScope scope(isolate);
718   DCHECK_EQ(1, args.length());
719   Handle<JSReceiver> object = args.at<JSReceiver>(0);
720 
721   MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
722                                              kThrowOnError),
723                ReadOnlyRoots(isolate).exception());
724   return *object;
725 }
726 
RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsDontThrow)727 RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsDontThrow) {
728   HandleScope scope(isolate);
729   DCHECK_EQ(1, args.length());
730   Handle<JSReceiver> object = args.at<JSReceiver>(0);
731 
732   Maybe<bool> result = JSReceiver::PreventExtensions(
733       Handle<JSReceiver>::cast(object), kDontThrow);
734   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
735   return *isolate->factory()->ToBoolean(result.FromJust());
736 }
737 
RUNTIME_FUNCTION(Runtime_JSReceiverGetPrototypeOf)738 RUNTIME_FUNCTION(Runtime_JSReceiverGetPrototypeOf) {
739   HandleScope scope(isolate);
740   DCHECK_EQ(1, args.length());
741   Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
742 
743   RETURN_RESULT_OR_FAILURE(isolate,
744                            JSReceiver::GetPrototype(isolate, receiver));
745 }
746 
RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfThrow)747 RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfThrow) {
748   HandleScope scope(isolate);
749 
750   DCHECK_EQ(2, args.length());
751   Handle<JSReceiver> object = args.at<JSReceiver>(0);
752   Handle<Object> proto = args.at(1);
753 
754   MAYBE_RETURN(
755       JSReceiver::SetPrototype(isolate, object, proto, true, kThrowOnError),
756       ReadOnlyRoots(isolate).exception());
757 
758   return *object;
759 }
760 
RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow)761 RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow) {
762   HandleScope scope(isolate);
763 
764   DCHECK_EQ(2, args.length());
765   Handle<JSReceiver> object = args.at<JSReceiver>(0);
766   Handle<Object> proto = args.at(1);
767 
768   Maybe<bool> result =
769       JSReceiver::SetPrototype(isolate, object, proto, true, kDontThrow);
770   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
771   return *isolate->factory()->ToBoolean(result.FromJust());
772 }
773 
RUNTIME_FUNCTION(Runtime_GetProperty)774 RUNTIME_FUNCTION(Runtime_GetProperty) {
775   HandleScope scope(isolate);
776   DCHECK(args.length() == 3 || args.length() == 2);
777   Handle<Object> lookup_start_obj = args.at(0);
778   Handle<Object> key_obj = args.at(1);
779   Handle<Object> receiver_obj = lookup_start_obj;
780   if (args.length() == 3) {
781     receiver_obj = args.at<Object>(2);
782   }
783 
784   // Fast cases for getting named properties of the lookup_start_obj JSObject
785   // itself.
786   //
787   // The global proxy objects has to be excluded since LookupOwn on
788   // the global proxy object can return a valid result even though the
789   // global proxy object never has properties.  This is the case
790   // because the global proxy object forwards everything to its hidden
791   // prototype including own lookups.
792   //
793   // Additionally, we need to make sure that we do not cache results
794   // for objects that require access checks.
795 
796   // Convert string-index keys to their number variant to avoid internalization
797   // below; and speed up subsequent conversion to index.
798   uint32_t index;
799   if (key_obj->IsString() && String::cast(*key_obj).AsArrayIndex(&index)) {
800     key_obj = isolate->factory()->NewNumberFromUint(index);
801   }
802   if (lookup_start_obj->IsJSObject()) {
803     Handle<JSObject> lookup_start_object =
804         Handle<JSObject>::cast(lookup_start_obj);
805     if (!lookup_start_object->IsJSGlobalProxy() &&
806         !lookup_start_object->IsAccessCheckNeeded() && key_obj->IsName()) {
807       Handle<Name> key = Handle<Name>::cast(key_obj);
808       key_obj = key = isolate->factory()->InternalizeName(key);
809 
810       DisallowGarbageCollection no_gc;
811       if (lookup_start_object->IsJSGlobalObject()) {
812         // Attempt dictionary lookup.
813         GlobalDictionary dictionary = JSGlobalObject::cast(*lookup_start_object)
814                                           .global_dictionary(kAcquireLoad);
815         InternalIndex entry = dictionary.FindEntry(isolate, key);
816         if (entry.is_found()) {
817           PropertyCell cell = dictionary.CellAt(entry);
818           if (cell.property_details().kind() == PropertyKind::kData) {
819             Object value = cell.value();
820             if (!value.IsTheHole(isolate)) return value;
821             // If value is the hole (meaning, absent) do the general lookup.
822           }
823         }
824       } else if (!lookup_start_object->HasFastProperties()) {
825         // Attempt dictionary lookup.
826         if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
827           SwissNameDictionary dictionary =
828               lookup_start_object->property_dictionary_swiss();
829           InternalIndex entry = dictionary.FindEntry(isolate, *key);
830           if (entry.is_found() &&
831               (dictionary.DetailsAt(entry).kind() == PropertyKind::kData)) {
832             return dictionary.ValueAt(entry);
833           }
834         } else {
835           NameDictionary dictionary =
836               lookup_start_object->property_dictionary();
837           InternalIndex entry = dictionary.FindEntry(isolate, key);
838           if ((entry.is_found()) &&
839               (dictionary.DetailsAt(entry).kind() == PropertyKind::kData)) {
840             return dictionary.ValueAt(entry);
841           }
842         }
843       }
844     } else if (key_obj->IsSmi()) {
845       // JSObject without a name key. If the key is a Smi, check for a
846       // definite out-of-bounds access to elements, which is a strong indicator
847       // that subsequent accesses will also call the runtime. Proactively
848       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
849       // doubles for those future calls in the case that the elements would
850       // become PACKED_DOUBLE_ELEMENTS.
851       ElementsKind elements_kind = lookup_start_object->GetElementsKind();
852       if (IsDoubleElementsKind(elements_kind)) {
853         if (Smi::ToInt(*key_obj) >= lookup_start_object->elements().length()) {
854           elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
855                                                              : PACKED_ELEMENTS;
856           JSObject::TransitionElementsKind(lookup_start_object, elements_kind);
857         }
858       } else {
859         DCHECK(IsSmiOrObjectElementsKind(elements_kind) ||
860                !IsFastElementsKind(elements_kind));
861       }
862     }
863   } else if (lookup_start_obj->IsString() && key_obj->IsSmi()) {
864     // Fast case for string indexing using [] with a smi index.
865     Handle<String> str = Handle<String>::cast(lookup_start_obj);
866     int smi_index = Handle<Smi>::cast(key_obj)->value();
867     if (smi_index >= 0 && smi_index < str->length()) {
868       Factory* factory = isolate->factory();
869       return *factory->LookupSingleCharacterStringFromCode(
870           String::Flatten(isolate, str)->Get(smi_index));
871     }
872   }
873 
874   // Fall back to GetObjectProperty.
875   RETURN_RESULT_OR_FAILURE(
876       isolate, Runtime::GetObjectProperty(isolate, lookup_start_obj, key_obj,
877                                           receiver_obj));
878 }
879 
RUNTIME_FUNCTION(Runtime_SetKeyedProperty)880 RUNTIME_FUNCTION(Runtime_SetKeyedProperty) {
881   HandleScope scope(isolate);
882   DCHECK_EQ(3, args.length());
883 
884   Handle<Object> object = args.at(0);
885   Handle<Object> key = args.at(1);
886   Handle<Object> value = args.at(2);
887 
888   RETURN_RESULT_OR_FAILURE(
889       isolate, Runtime::SetObjectProperty(isolate, object, key, value,
890                                           StoreOrigin::kMaybeKeyed));
891 }
892 
RUNTIME_FUNCTION(Runtime_DefineObjectOwnProperty)893 RUNTIME_FUNCTION(Runtime_DefineObjectOwnProperty) {
894   HandleScope scope(isolate);
895   DCHECK_EQ(3, args.length());
896 
897   Handle<Object> object = args.at(0);
898   Handle<Object> key = args.at(1);
899   Handle<Object> value = args.at(2);
900 
901   RETURN_RESULT_OR_FAILURE(
902       isolate, Runtime::DefineObjectOwnProperty(isolate, object, key, value,
903                                                 StoreOrigin::kMaybeKeyed));
904 }
905 
RUNTIME_FUNCTION(Runtime_SetNamedProperty)906 RUNTIME_FUNCTION(Runtime_SetNamedProperty) {
907   HandleScope scope(isolate);
908   DCHECK_EQ(3, args.length());
909 
910   Handle<Object> object = args.at(0);
911   Handle<Object> key = args.at(1);
912   Handle<Object> value = args.at(2);
913 
914   RETURN_RESULT_OR_FAILURE(
915       isolate, Runtime::SetObjectProperty(isolate, object, key, value,
916                                           StoreOrigin::kNamed));
917 }
918 
919 // Similar to DefineKeyedOwnPropertyInLiteral, but does not update feedback, and
920 // and does not have a flags parameter for performing SetFunctionName().
921 //
922 // Currently, this is used for ObjectLiteral spread properties in CloneObjectIC
923 // and for array literal creations in StoreInArrayLiteralIC.
924 // TODO(v8:12548): merge this into DefineKeyedOwnPropertyInLiteral.
RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral_Simple)925 RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral_Simple) {
926   HandleScope scope(isolate);
927   DCHECK_EQ(3, args.length());
928 
929   Handle<JSReceiver> object = args.at<JSReceiver>(0);
930   Handle<Object> key = args.at(1);
931   Handle<Object> value = args.at(2);
932 
933   PropertyKey lookup_key(isolate, key);
934   LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
935 
936   Maybe<bool> result = JSObject::DefineOwnPropertyIgnoreAttributes(
937       &it, value, NONE, Just(kDontThrow));
938   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
939   DCHECK(result.IsJust());
940   USE(result);
941 
942   return *value;
943 }
944 
945 namespace {
946 
947 // ES6 section 12.5.4.
DeleteProperty(Isolate * isolate,Handle<Object> object,Handle<Object> key,LanguageMode language_mode)948 Object DeleteProperty(Isolate* isolate, Handle<Object> object,
949                       Handle<Object> key, LanguageMode language_mode) {
950   Handle<JSReceiver> receiver;
951   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
952                                      Object::ToObject(isolate, object));
953   Maybe<bool> result =
954       Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
955   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
956   return isolate->heap()->ToBoolean(result.FromJust());
957 }
958 
959 }  // namespace
960 
RUNTIME_FUNCTION(Runtime_DeleteProperty)961 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
962   HandleScope scope(isolate);
963   DCHECK_EQ(3, args.length());
964   Handle<Object> object = args.at(0);
965   Handle<Object> key = args.at(1);
966   int language_mode = args.smi_value_at(2);
967   return DeleteProperty(isolate, object, key,
968                         static_cast<LanguageMode>(language_mode));
969 }
970 
RUNTIME_FUNCTION(Runtime_ShrinkNameDictionary)971 RUNTIME_FUNCTION(Runtime_ShrinkNameDictionary) {
972   HandleScope scope(isolate);
973   DCHECK_EQ(1, args.length());
974   Handle<NameDictionary> dictionary = args.at<NameDictionary>(0);
975 
976   return *NameDictionary::Shrink(isolate, dictionary);
977 }
978 
RUNTIME_FUNCTION(Runtime_ShrinkSwissNameDictionary)979 RUNTIME_FUNCTION(Runtime_ShrinkSwissNameDictionary) {
980   HandleScope scope(isolate);
981   DCHECK_EQ(1, args.length());
982   Handle<SwissNameDictionary> dictionary = args.at<SwissNameDictionary>(0);
983 
984   return *SwissNameDictionary::Shrink(isolate, dictionary);
985 }
986 
987 // ES6 section 12.9.3, operator in.
RUNTIME_FUNCTION(Runtime_HasProperty)988 RUNTIME_FUNCTION(Runtime_HasProperty) {
989   HandleScope scope(isolate);
990   DCHECK_EQ(2, args.length());
991   Handle<Object> object = args.at(0);
992   Handle<Object> key = args.at(1);
993 
994   // Check that {object} is actually a receiver.
995   if (!object->IsJSReceiver()) {
996     THROW_NEW_ERROR_RETURN_FAILURE(
997         isolate,
998         NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
999   }
1000   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
1001 
1002   // Convert the {key} to a name.
1003   Handle<Name> name;
1004   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
1005                                      Object::ToName(isolate, key));
1006 
1007   // Lookup the {name} on {receiver}.
1008   Maybe<bool> maybe = JSReceiver::HasProperty(isolate, receiver, name);
1009   if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
1010   return isolate->heap()->ToBoolean(maybe.FromJust());
1011 }
1012 
RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys)1013 RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
1014   HandleScope scope(isolate);
1015   DCHECK_EQ(2, args.length());
1016   Handle<JSReceiver> object = args.at<JSReceiver>(0);
1017   int filter_value = args.smi_value_at(1);
1018   PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
1019 
1020   Handle<FixedArray> keys;
1021   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1022       isolate, keys,
1023       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, filter,
1024                               GetKeysConversion::kConvertToString));
1025 
1026   return *isolate->factory()->NewJSArrayWithElements(keys);
1027 }
1028 
RUNTIME_FUNCTION(Runtime_ToFastProperties)1029 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
1030   HandleScope scope(isolate);
1031   DCHECK_EQ(1, args.length());
1032   Handle<Object> object = args.at(0);
1033   if (object->IsJSObject() && !object->IsJSGlobalObject()) {
1034     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
1035                                 "RuntimeToFastProperties");
1036   }
1037   return *object;
1038 }
1039 
RUNTIME_FUNCTION(Runtime_AllocateHeapNumber)1040 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
1041   HandleScope scope(isolate);
1042   DCHECK_EQ(0, args.length());
1043   return *isolate->factory()->NewHeapNumber(0);
1044 }
1045 
RUNTIME_FUNCTION(Runtime_NewObject)1046 RUNTIME_FUNCTION(Runtime_NewObject) {
1047   HandleScope scope(isolate);
1048   DCHECK_EQ(2, args.length());
1049   Handle<JSFunction> target = args.at<JSFunction>(0);
1050   Handle<JSReceiver> new_target = args.at<JSReceiver>(1);
1051   RETURN_RESULT_OR_FAILURE(
1052       isolate,
1053       JSObject::New(target, new_target, Handle<AllocationSite>::null()));
1054 }
1055 
RUNTIME_FUNCTION(Runtime_GetDerivedMap)1056 RUNTIME_FUNCTION(Runtime_GetDerivedMap) {
1057   HandleScope scope(isolate);
1058   DCHECK_EQ(3, args.length());
1059   Handle<JSFunction> target = args.at<JSFunction>(0);
1060   Handle<JSReceiver> new_target = args.at<JSReceiver>(1);
1061   Handle<Object> rab_gsab = args.at(2);
1062   if (rab_gsab->IsTrue()) {
1063     return *JSFunction::GetDerivedRabGsabMap(isolate, target, new_target);
1064   } else {
1065     RETURN_RESULT_OR_FAILURE(
1066         isolate, JSFunction::GetDerivedMap(isolate, target, new_target));
1067   }
1068 }
1069 
RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap)1070 RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) {
1071   DisallowGarbageCollection no_gc;
1072   HandleScope scope(isolate);
1073   DCHECK_EQ(1, args.length());
1074 
1075   Handle<Map> initial_map = args.at<Map>(0);
1076   MapUpdater::CompleteInobjectSlackTracking(isolate, *initial_map);
1077 
1078   return ReadOnlyRoots(isolate).undefined_value();
1079 }
1080 
RUNTIME_FUNCTION(Runtime_TryMigrateInstance)1081 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
1082   HandleScope scope(isolate);
1083   DCHECK_EQ(1, args.length());
1084   Handle<JSObject> js_object = args.at<JSObject>(0);
1085   // It could have been a DCHECK but we call this function directly from tests.
1086   if (!js_object->map().is_deprecated()) return Smi::zero();
1087   // This call must not cause lazy deopts, because it's called from deferred
1088   // code where we can't handle lazy deopts for lack of a suitable bailout
1089   // ID. So we just try migration and signal failure if necessary,
1090   // which will also trigger a deopt.
1091   if (!JSObject::TryMigrateInstance(isolate, js_object)) return Smi::zero();
1092   return *js_object;
1093 }
1094 
IsValidAccessor(Isolate * isolate,Handle<Object> obj)1095 static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) {
1096   return obj->IsNullOrUndefined(isolate) || obj->IsCallable();
1097 }
1098 
1099 // Implements part of 8.12.9 DefineOwnProperty.
1100 // There are 3 cases that lead here:
1101 // Step 4b - define a new accessor property.
1102 // Steps 9c & 12 - replace an existing data property with an accessor property.
1103 // Step 12 - update an existing accessor property with an accessor or generic
1104 //           descriptor.
RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked)1105 RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
1106   HandleScope scope(isolate);
1107   DCHECK_EQ(5, args.length());
1108   Handle<JSObject> obj = args.at<JSObject>(0);
1109   CHECK(!obj->IsNull(isolate));
1110   Handle<Name> name = args.at<Name>(1);
1111   Handle<Object> getter = args.at(2);
1112   CHECK(IsValidAccessor(isolate, getter));
1113   Handle<Object> setter = args.at(3);
1114   CHECK(IsValidAccessor(isolate, setter));
1115   auto attrs = PropertyAttributesFromInt(args.smi_value_at(4));
1116 
1117   RETURN_FAILURE_ON_EXCEPTION(
1118       isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
1119   return ReadOnlyRoots(isolate).undefined_value();
1120 }
1121 
RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral)1122 RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral) {
1123   HandleScope scope(isolate);
1124   DCHECK_EQ(6, args.length());
1125   Handle<JSObject> object = args.at<JSObject>(0);
1126   Handle<Name> name = args.at<Name>(1);
1127   Handle<Object> value = args.at(2);
1128   int flag = args.smi_value_at(3);
1129   Handle<HeapObject> maybe_vector = args.at<HeapObject>(4);
1130   int index = args.tagged_index_value_at(5);
1131 
1132   if (!maybe_vector->IsUndefined()) {
1133     DCHECK(maybe_vector->IsFeedbackVector());
1134     Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(maybe_vector);
1135     FeedbackNexus nexus(vector, FeedbackVector::ToSlot(index));
1136     if (nexus.ic_state() == InlineCacheState::UNINITIALIZED) {
1137       if (name->IsUniqueName()) {
1138         nexus.ConfigureMonomorphic(name, handle(object->map(), isolate),
1139                                    MaybeObjectHandle());
1140       } else {
1141         nexus.ConfigureMegamorphic(IcCheckType::kProperty);
1142       }
1143     } else if (nexus.ic_state() == InlineCacheState::MONOMORPHIC) {
1144       if (nexus.GetFirstMap() != object->map() || nexus.GetName() != *name) {
1145         nexus.ConfigureMegamorphic(IcCheckType::kProperty);
1146       }
1147     }
1148   }
1149 
1150   DefineKeyedOwnPropertyInLiteralFlags flags(flag);
1151   PropertyAttributes attrs =
1152       (flags & DefineKeyedOwnPropertyInLiteralFlag::kDontEnum)
1153           ? PropertyAttributes::DONT_ENUM
1154           : PropertyAttributes::NONE;
1155 
1156   if (flags & DefineKeyedOwnPropertyInLiteralFlag::kSetFunctionName) {
1157     DCHECK(value->IsJSFunction());
1158     Handle<JSFunction> function = Handle<JSFunction>::cast(value);
1159     DCHECK(!function->shared().HasSharedName());
1160     Handle<Map> function_map(function->map(), isolate);
1161     if (!JSFunction::SetName(function, name,
1162                              isolate->factory()->empty_string())) {
1163       return ReadOnlyRoots(isolate).exception();
1164     }
1165     // Class constructors do not reserve in-object space for name field.
1166     CHECK_IMPLIES(!IsClassConstructor(function->shared().kind()),
1167                   *function_map == function->map());
1168   }
1169 
1170   PropertyKey key(isolate, name);
1171   LookupIterator it(isolate, object, key, object, LookupIterator::OWN);
1172   // Cannot fail since this should only be called when
1173   // creating an object literal.
1174   CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
1175                                                     Just(kDontThrow))
1176             .IsJust());
1177 
1178   // Return the value so that
1179   // BaselineCompiler::VisitDefineKeyedOwnPropertyInLiteral doesn't have to
1180   // save the accumulator.
1181   return *value;
1182 }
1183 
RUNTIME_FUNCTION(Runtime_CollectTypeProfile)1184 RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
1185   HandleScope scope(isolate);
1186   DCHECK_EQ(3, args.length());
1187   int position = args.smi_value_at(0);
1188   Handle<Object> value = args.at(1);
1189   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
1190 
1191   if (maybe_vector->IsUndefined()) {
1192     return ReadOnlyRoots(isolate).undefined_value();
1193   }
1194   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
1195 
1196   Handle<String> type = Object::TypeOf(isolate, value);
1197   if (value->IsJSReceiver()) {
1198     Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
1199     type = JSReceiver::GetConstructorName(isolate, object);
1200   } else if (value->IsNull(isolate)) {
1201     // typeof(null) is object. But it's more user-friendly to annotate
1202     // null as type "null".
1203     type = Handle<String>(ReadOnlyRoots(isolate).null_string(), isolate);
1204   }
1205 
1206   DCHECK(vector->metadata().HasTypeProfileSlot());
1207   FeedbackNexus nexus(vector, vector->GetTypeProfileSlot());
1208   nexus.Collect(type, position);
1209 
1210   return ReadOnlyRoots(isolate).undefined_value();
1211 }
1212 
RUNTIME_FUNCTION(Runtime_HasFastPackedElements)1213 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
1214   SealHandleScope shs(isolate);
1215   DCHECK_EQ(1, args.length());
1216   auto obj = HeapObject::cast(args[0]);
1217   return isolate->heap()->ToBoolean(
1218       IsFastPackedElementsKind(obj.map().elements_kind()));
1219 }
1220 
RUNTIME_FUNCTION(Runtime_IsJSReceiver)1221 RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
1222   SealHandleScope shs(isolate);
1223   DCHECK_EQ(1, args.length());
1224   Object obj = args[0];
1225   return isolate->heap()->ToBoolean(obj.IsJSReceiver());
1226 }
1227 
RUNTIME_FUNCTION(Runtime_GetFunctionName)1228 RUNTIME_FUNCTION(Runtime_GetFunctionName) {
1229   HandleScope scope(isolate);
1230   DCHECK_EQ(1, args.length());
1231   Handle<JSFunction> function = args.at<JSFunction>(0);
1232   return *JSFunction::GetName(isolate, function);
1233 }
1234 
RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked)1235 RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
1236   HandleScope scope(isolate);
1237   DCHECK_EQ(4, args.length());
1238   Handle<JSObject> object = args.at<JSObject>(0);
1239   Handle<Name> name = args.at<Name>(1);
1240   Handle<JSFunction> getter = args.at<JSFunction>(2);
1241   auto attrs = PropertyAttributesFromInt(args.smi_value_at(3));
1242 
1243   if (String::cast(getter->shared().Name()).length() == 0) {
1244     Handle<Map> getter_map(getter->map(), isolate);
1245     if (!JSFunction::SetName(getter, name, isolate->factory()->get_string())) {
1246       return ReadOnlyRoots(isolate).exception();
1247     }
1248     CHECK_EQ(*getter_map, getter->map());
1249   }
1250 
1251   RETURN_FAILURE_ON_EXCEPTION(
1252       isolate,
1253       JSObject::DefineAccessor(object, name, getter,
1254                                isolate->factory()->null_value(), attrs));
1255   return ReadOnlyRoots(isolate).undefined_value();
1256 }
1257 
RUNTIME_FUNCTION(Runtime_SetDataProperties)1258 RUNTIME_FUNCTION(Runtime_SetDataProperties) {
1259   HandleScope scope(isolate);
1260   DCHECK_EQ(2, args.length());
1261   Handle<JSReceiver> target = args.at<JSReceiver>(0);
1262   Handle<Object> source = args.at(1);
1263 
1264   // 2. If source is undefined or null, let keys be an empty List.
1265   if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
1266     return ReadOnlyRoots(isolate).undefined_value();
1267   }
1268 
1269   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(
1270                    isolate, target, source,
1271                    PropertiesEnumerationMode::kEnumerationOrder),
1272                ReadOnlyRoots(isolate).exception());
1273   return ReadOnlyRoots(isolate).undefined_value();
1274 }
1275 
RUNTIME_FUNCTION(Runtime_CopyDataProperties)1276 RUNTIME_FUNCTION(Runtime_CopyDataProperties) {
1277   HandleScope scope(isolate);
1278   DCHECK_EQ(2, args.length());
1279   Handle<JSObject> target = args.at<JSObject>(0);
1280   Handle<Object> source = args.at(1);
1281 
1282   // 2. If source is undefined or null, let keys be an empty List.
1283   if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
1284     return ReadOnlyRoots(isolate).undefined_value();
1285   }
1286 
1287   MAYBE_RETURN(
1288       JSReceiver::SetOrCopyDataProperties(
1289           isolate, target, source,
1290           PropertiesEnumerationMode::kPropertyAdditionOrder, nullptr, false),
1291       ReadOnlyRoots(isolate).exception());
1292   return ReadOnlyRoots(isolate).undefined_value();
1293 }
1294 
1295 namespace {
1296 
1297 // Check that the excluded properties are within the stack range of the top of
1298 // the stack, and the start of the JS frame.
CheckExcludedPropertiesAreOnCallerStack(Isolate * isolate,Address base,int count)1299 void CheckExcludedPropertiesAreOnCallerStack(Isolate* isolate, Address base,
1300                                              int count) {
1301 #ifdef DEBUG
1302   StackFrameIterator it(isolate);
1303 
1304   // Don't need to check when there's no excluded properties.
1305   if (count == 0) return;
1306 
1307   DCHECK(!it.done());
1308 
1309   // Properties are pass in order on the stack, which means that their addresses
1310   // are in reverse order in memory (because stacks grow backwards). So, we
1311   // need to check if the _last_ property address is before the stack end...
1312   Address last_property = base - (count - 1) * kSystemPointerSize;
1313   DCHECK_GE(last_property, it.frame()->sp());
1314 
1315   // ... and for the first JS frame, make sure the _first_ property address is
1316   // after that stack frame's start.
1317   for (; !it.done(); it.Advance()) {
1318     if (it.frame()->is_java_script()) {
1319       DCHECK_LT(base, it.frame()->fp());
1320       return;
1321     }
1322   }
1323 
1324   // We should always find a JS frame.
1325   UNREACHABLE();
1326 #endif
1327 }
1328 
1329 }  // namespace
1330 
RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedPropertiesOnStack)1331 RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedPropertiesOnStack) {
1332   HandleScope scope(isolate);
1333   DCHECK_EQ(3, args.length());
1334   Handle<Object> source = args.at(0);
1335   int excluded_property_count = args.smi_value_at(1);
1336   // The excluded_property_base is passed as a raw stack pointer. This is safe
1337   // because the stack pointer is aligned, so it looks like a Smi to the GC.
1338   Address* excluded_property_base = reinterpret_cast<Address*>(args[2].ptr());
1339   DCHECK(HAS_SMI_TAG(reinterpret_cast<intptr_t>(excluded_property_base)));
1340   // Also make sure that the given base pointer points to to on-stack values.
1341   CheckExcludedPropertiesAreOnCallerStack(
1342       isolate, reinterpret_cast<Address>(excluded_property_base),
1343       excluded_property_count);
1344 
1345   // If source is undefined or null, throw a non-coercible error.
1346   if (source->IsNullOrUndefined(isolate)) {
1347     return ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, source,
1348                                                     MaybeHandle<Object>());
1349   }
1350 
1351   base::ScopedVector<Handle<Object>> excluded_properties(
1352       excluded_property_count);
1353   for (int i = 0; i < excluded_property_count; i++) {
1354     // Because the excluded properties on stack is from high address
1355     // to low address, so we need to use sub
1356     Handle<Object> property(excluded_property_base - i);
1357     uint32_t property_num;
1358     // We convert string to number if possible, in cases of computed
1359     // properties resolving to numbers, which would've been strings
1360     // instead because of our call to %ToName() in the desugaring for
1361     // computed properties.
1362     if (property->IsString() &&
1363         String::cast(*property).AsArrayIndex(&property_num)) {
1364       property = isolate->factory()->NewNumberFromUint(property_num);
1365     }
1366 
1367     excluded_properties[i] = property;
1368   }
1369 
1370   Handle<JSObject> target =
1371       isolate->factory()->NewJSObject(isolate->object_function());
1372   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(
1373                    isolate, target, source,
1374                    PropertiesEnumerationMode::kPropertyAdditionOrder,
1375                    &excluded_properties, false),
1376                ReadOnlyRoots(isolate).exception());
1377   return *target;
1378 }
1379 
RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked)1380 RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
1381   HandleScope scope(isolate);
1382   DCHECK_EQ(4, args.length());
1383   Handle<JSObject> object = args.at<JSObject>(0);
1384   Handle<Name> name = args.at<Name>(1);
1385   Handle<JSFunction> setter = args.at<JSFunction>(2);
1386   auto attrs = PropertyAttributesFromInt(args.smi_value_at(3));
1387 
1388   if (String::cast(setter->shared().Name()).length() == 0) {
1389     Handle<Map> setter_map(setter->map(), isolate);
1390     if (!JSFunction::SetName(setter, name, isolate->factory()->set_string())) {
1391       return ReadOnlyRoots(isolate).exception();
1392     }
1393     CHECK_EQ(*setter_map, setter->map());
1394   }
1395 
1396   RETURN_FAILURE_ON_EXCEPTION(
1397       isolate,
1398       JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1399                                setter, attrs));
1400   return ReadOnlyRoots(isolate).undefined_value();
1401 }
1402 
RUNTIME_FUNCTION(Runtime_ToObject)1403 RUNTIME_FUNCTION(Runtime_ToObject) {
1404   // Runtime call is implemented in InterpreterIntrinsics and lowered in
1405   // JSIntrinsicLowering.
1406   UNREACHABLE();
1407 }
1408 
RUNTIME_FUNCTION(Runtime_ToNumber)1409 RUNTIME_FUNCTION(Runtime_ToNumber) {
1410   HandleScope scope(isolate);
1411   DCHECK_EQ(1, args.length());
1412   Handle<Object> input = args.at(0);
1413   RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumber(isolate, input));
1414 }
1415 
RUNTIME_FUNCTION(Runtime_ToNumeric)1416 RUNTIME_FUNCTION(Runtime_ToNumeric) {
1417   HandleScope scope(isolate);
1418   DCHECK_EQ(1, args.length());
1419   Handle<Object> input = args.at(0);
1420   RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumeric(isolate, input));
1421 }
1422 
RUNTIME_FUNCTION(Runtime_ToLength)1423 RUNTIME_FUNCTION(Runtime_ToLength) {
1424   HandleScope scope(isolate);
1425   DCHECK_EQ(1, args.length());
1426   Handle<Object> input = args.at(0);
1427   RETURN_RESULT_OR_FAILURE(isolate, Object::ToLength(isolate, input));
1428 }
1429 
RUNTIME_FUNCTION(Runtime_ToString)1430 RUNTIME_FUNCTION(Runtime_ToString) {
1431   HandleScope scope(isolate);
1432   DCHECK_EQ(1, args.length());
1433   Handle<Object> input = args.at(0);
1434   RETURN_RESULT_OR_FAILURE(isolate, Object::ToString(isolate, input));
1435 }
1436 
RUNTIME_FUNCTION(Runtime_ToName)1437 RUNTIME_FUNCTION(Runtime_ToName) {
1438   HandleScope scope(isolate);
1439   DCHECK_EQ(1, args.length());
1440   Handle<Object> input = args.at(0);
1441   RETURN_RESULT_OR_FAILURE(isolate, Object::ToName(isolate, input));
1442 }
1443 
RUNTIME_FUNCTION(Runtime_HasInPrototypeChain)1444 RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
1445   HandleScope scope(isolate);
1446   DCHECK_EQ(2, args.length());
1447   Handle<Object> object = args.at(0);
1448   Handle<Object> prototype = args.at(1);
1449   if (!object->IsJSReceiver()) return ReadOnlyRoots(isolate).false_value();
1450   Maybe<bool> result = JSReceiver::HasInPrototypeChain(
1451       isolate, Handle<JSReceiver>::cast(object), prototype);
1452   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
1453   return isolate->heap()->ToBoolean(result.FromJust());
1454 }
1455 
1456 // ES6 section 7.4.7 CreateIterResultObject ( value, done )
RUNTIME_FUNCTION(Runtime_CreateIterResultObject)1457 RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
1458   HandleScope scope(isolate);
1459   DCHECK_EQ(2, args.length());
1460   Handle<Object> value = args.at(0);
1461   Handle<Object> done = args.at(1);
1462   return *isolate->factory()->NewJSIteratorResult(value,
1463                                                   done->BooleanValue(isolate));
1464 }
1465 
RUNTIME_FUNCTION(Runtime_CreateDataProperty)1466 RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
1467   HandleScope scope(isolate);
1468   DCHECK_EQ(3, args.length());
1469   Handle<JSReceiver> o = args.at<JSReceiver>(0);
1470   Handle<Object> key = args.at(1);
1471   Handle<Object> value = args.at(2);
1472   bool success;
1473   PropertyKey lookup_key(isolate, key, &success);
1474   if (!success) return ReadOnlyRoots(isolate).exception();
1475   LookupIterator it(isolate, o, lookup_key, LookupIterator::OWN);
1476   MAYBE_RETURN(JSReceiver::CreateDataProperty(&it, value, Just(kThrowOnError)),
1477                ReadOnlyRoots(isolate).exception());
1478   return *value;
1479 }
1480 
RUNTIME_FUNCTION(Runtime_SetOwnPropertyIgnoreAttributes)1481 RUNTIME_FUNCTION(Runtime_SetOwnPropertyIgnoreAttributes) {
1482   HandleScope scope(isolate);
1483   DCHECK_EQ(4, args.length());
1484   Handle<JSObject> o = args.at<JSObject>(0);
1485   Handle<String> key = args.at<String>(1);
1486   Handle<Object> value = args.at(2);
1487   int attributes = args.smi_value_at(3);
1488 
1489   RETURN_RESULT_OR_FAILURE(isolate,
1490                            JSObject::SetOwnPropertyIgnoreAttributes(
1491                                o, key, value, PropertyAttributes(attributes)));
1492 }
1493 
RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor)1494 RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor) {
1495   HandleScope scope(isolate);
1496 
1497   DCHECK_EQ(2, args.length());
1498   Handle<JSReceiver> object = args.at<JSReceiver>(0);
1499   Handle<Name> name = args.at<Name>(1);
1500 
1501   PropertyDescriptor desc;
1502   Maybe<bool> found =
1503       JSReceiver::GetOwnPropertyDescriptor(isolate, object, name, &desc);
1504   MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
1505 
1506   if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
1507   return *desc.ToPropertyDescriptorObject(isolate);
1508 }
1509 
RUNTIME_FUNCTION(Runtime_LoadPrivateSetter)1510 RUNTIME_FUNCTION(Runtime_LoadPrivateSetter) {
1511   HandleScope scope(isolate);
1512   DCHECK_EQ(args.length(), 1);
1513   Handle<AccessorPair> pair = args.at<AccessorPair>(0);
1514   DCHECK(pair->setter().IsJSFunction());
1515   return pair->setter();
1516 }
1517 
RUNTIME_FUNCTION(Runtime_LoadPrivateGetter)1518 RUNTIME_FUNCTION(Runtime_LoadPrivateGetter) {
1519   HandleScope scope(isolate);
1520   DCHECK_EQ(args.length(), 1);
1521   Handle<AccessorPair> pair = args.at<AccessorPair>(0);
1522   DCHECK(pair->getter().IsJSFunction());
1523   return pair->getter();
1524 }
1525 
RUNTIME_FUNCTION(Runtime_CreatePrivateAccessors)1526 RUNTIME_FUNCTION(Runtime_CreatePrivateAccessors) {
1527   HandleScope scope(isolate);
1528   DCHECK_EQ(args.length(), 2);
1529   DCHECK(args[0].IsNull() || args[0].IsJSFunction());
1530   DCHECK(args[1].IsNull() || args[1].IsJSFunction());
1531   Handle<AccessorPair> pair = isolate->factory()->NewAccessorPair();
1532   pair->SetComponents(args[0], args[1]);
1533   return *pair;
1534 }
1535 
1536 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1537 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableAllocate)1538 RUNTIME_FUNCTION(Runtime_SwissTableAllocate) {
1539   HandleScope scope(isolate);
1540   int at_least_space_for = args.smi_value_at(0);
1541 
1542   return *isolate->factory()->NewSwissNameDictionary(at_least_space_for,
1543                                                      AllocationType::kYoung);
1544 }
1545 
1546 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1547 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableAdd)1548 RUNTIME_FUNCTION(Runtime_SwissTableAdd) {
1549   HandleScope scope(isolate);
1550   Handle<SwissNameDictionary> table = args.at<SwissNameDictionary>(0);
1551   Handle<Name> key = args.at<Name>(1);
1552   Handle<Object> value = args.at(2);
1553   PropertyDetails details(Smi::cast(args[3]));
1554 
1555   DCHECK(key->IsUniqueName());
1556 
1557   return *SwissNameDictionary::Add(isolate, table, key, value, details);
1558 }
1559 
1560 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1561 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableFindEntry)1562 RUNTIME_FUNCTION(Runtime_SwissTableFindEntry) {
1563   HandleScope scope(isolate);
1564   DisallowGarbageCollection no_gc;
1565   auto table = SwissNameDictionary::cast(args[0]);
1566   Name key = Name::cast(args[1]);
1567   InternalIndex index = table.FindEntry(isolate, key);
1568   return Smi::FromInt(index.is_found()
1569                           ? index.as_int()
1570                           : SwissNameDictionary::kNotFoundSentinel);
1571 }
1572 
1573 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1574 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableUpdate)1575 RUNTIME_FUNCTION(Runtime_SwissTableUpdate) {
1576   HandleScope scope(isolate);
1577   DisallowGarbageCollection no_gc;
1578   auto table = SwissNameDictionary::cast(args[0]);
1579   InternalIndex index(args.smi_value_at(1));
1580   Object value = args[2];
1581   table.ValueAtPut(index, value);
1582 
1583   PropertyDetails details(Smi::cast(args[3]));
1584   table.DetailsAtPut(index, details);
1585 
1586   return ReadOnlyRoots(isolate).undefined_value();
1587 }
1588 
1589 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1590 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableDelete)1591 RUNTIME_FUNCTION(Runtime_SwissTableDelete) {
1592   HandleScope scope(isolate);
1593   Handle<SwissNameDictionary> table = args.at<SwissNameDictionary>(0);
1594   InternalIndex index(args.smi_value_at(1));
1595 
1596   return *SwissNameDictionary::DeleteEntry(isolate, table, index);
1597 }
1598 
1599 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1600 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableEquals)1601 RUNTIME_FUNCTION(Runtime_SwissTableEquals) {
1602   HandleScope scope(isolate);
1603   DisallowGarbageCollection no_gc;
1604   auto table = SwissNameDictionary::cast(args[0]);
1605   auto other = SwissNameDictionary::cast(args[0]);
1606   return Smi::FromInt(table.EqualsForTesting(other));
1607 }
1608 
1609 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1610 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableElementsCount)1611 RUNTIME_FUNCTION(Runtime_SwissTableElementsCount) {
1612   HandleScope scope(isolate);
1613   DisallowGarbageCollection no_gc;
1614   auto table = SwissNameDictionary::cast(args[0]);
1615   return Smi::FromInt(table.NumberOfElements());
1616 }
1617 
1618 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1619 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableKeyAt)1620 RUNTIME_FUNCTION(Runtime_SwissTableKeyAt) {
1621   HandleScope scope(isolate);
1622   DisallowGarbageCollection no_gc;
1623   auto table = SwissNameDictionary::cast(args[0]);
1624   InternalIndex index(args.smi_value_at(1));
1625   return table.KeyAt(index);
1626 }
1627 
1628 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1629 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableValueAt)1630 RUNTIME_FUNCTION(Runtime_SwissTableValueAt) {
1631   HandleScope scope(isolate);
1632   DisallowGarbageCollection no_gc;
1633   auto table = SwissNameDictionary::cast(args[0]);
1634   InternalIndex index(args.smi_value_at(1));
1635   return table.ValueAt(index);
1636 }
1637 
1638 // TODO(v8:11330) This is only here while the CSA/Torque implementaton of
1639 // SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableDetailsAt)1640 RUNTIME_FUNCTION(Runtime_SwissTableDetailsAt) {
1641   HandleScope scope(isolate);
1642   DisallowGarbageCollection no_gc;
1643   auto table = SwissNameDictionary::cast(args[0]);
1644   InternalIndex index(args.smi_value_at(1));
1645   PropertyDetails d = table.DetailsAt(index);
1646   return d.AsSmi();
1647 }
1648 
1649 }  // namespace internal
1650 }  // namespace v8
1651