LCOV - code coverage report
Current view: top level - src/runtime - runtime-object.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 466 548 85.0 %
Date: 2017-10-20 Functions: 55 121 45.5 %

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

Generated by: LCOV version 1.10