Home | History | Annotate | Download | only in runtime
      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/property-descriptor.h"
     13 #include "src/runtime/runtime.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 
     18 
     19 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
     20                                                Handle<Object> object,
     21                                                Handle<Object> key,
     22                                                LanguageMode language_mode) {
     23   if (object->IsUndefined() || object->IsNull()) {
     24     THROW_NEW_ERROR(
     25         isolate,
     26         NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object),
     27         Object);
     28   }
     29 
     30   bool success = false;
     31   LookupIterator it =
     32       LookupIterator::PropertyOrElement(isolate, object, key, &success);
     33   if (!success) return MaybeHandle<Object>();
     34 
     35   return Object::GetProperty(&it, language_mode);
     36 }
     37 
     38 
     39 static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate,
     40                                                   Handle<Object> receiver_obj,
     41                                                   Handle<Object> key_obj,
     42                                                   LanguageMode language_mode) {
     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   if (receiver_obj->IsJSObject()) {
     55     if (!receiver_obj->IsJSGlobalProxy() &&
     56         !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
     57       DisallowHeapAllocation no_allocation;
     58       Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
     59       Handle<Name> key = Handle<Name>::cast(key_obj);
     60       if (receiver->IsJSGlobalObject()) {
     61         // Attempt dictionary lookup.
     62         GlobalDictionary* dictionary = receiver->global_dictionary();
     63         int entry = dictionary->FindEntry(key);
     64         if (entry != GlobalDictionary::kNotFound) {
     65           DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
     66           PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
     67           if (cell->property_details().type() == DATA) {
     68             Object* value = cell->value();
     69             if (!value->IsTheHole()) return Handle<Object>(value, isolate);
     70             // If value is the hole (meaning, absent) do the general lookup.
     71           }
     72         }
     73       } else if (!receiver->HasFastProperties()) {
     74         // Attempt dictionary lookup.
     75         NameDictionary* dictionary = receiver->property_dictionary();
     76         int entry = dictionary->FindEntry(key);
     77         if ((entry != NameDictionary::kNotFound) &&
     78             (dictionary->DetailsAt(entry).type() == DATA)) {
     79           Object* value = dictionary->ValueAt(entry);
     80           return Handle<Object>(value, isolate);
     81         }
     82       }
     83     } else if (key_obj->IsSmi()) {
     84       // JSObject without a name key. If the key is a Smi, check for a
     85       // definite out-of-bounds access to elements, which is a strong indicator
     86       // that subsequent accesses will also call the runtime. Proactively
     87       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
     88       // doubles for those future calls in the case that the elements would
     89       // become FAST_DOUBLE_ELEMENTS.
     90       Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
     91       ElementsKind elements_kind = js_object->GetElementsKind();
     92       if (IsFastDoubleElementsKind(elements_kind)) {
     93         if (Smi::cast(*key_obj)->value() >= js_object->elements()->length()) {
     94           elements_kind = IsFastHoleyElementsKind(elements_kind)
     95                               ? FAST_HOLEY_ELEMENTS
     96                               : FAST_ELEMENTS;
     97           JSObject::TransitionElementsKind(js_object, elements_kind);
     98         }
     99       } else {
    100         DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
    101                !IsFastElementsKind(elements_kind));
    102       }
    103     }
    104   } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
    105     // Fast case for string indexing using [] with a smi index.
    106     Handle<String> str = Handle<String>::cast(receiver_obj);
    107     int index = Handle<Smi>::cast(key_obj)->value();
    108     if (index >= 0 && index < str->length()) {
    109       Factory* factory = isolate->factory();
    110       return factory->LookupSingleCharacterStringFromCode(
    111           String::Flatten(str)->Get(index));
    112     }
    113   }
    114 
    115   // Fall back to GetObjectProperty.
    116   return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj,
    117                                     language_mode);
    118 }
    119 
    120 
    121 Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
    122                                           Handle<JSReceiver> receiver,
    123                                           Handle<Object> key,
    124                                           LanguageMode language_mode) {
    125   bool success = false;
    126   LookupIterator it = LookupIterator::PropertyOrElement(
    127       isolate, receiver, key, &success, LookupIterator::HIDDEN);
    128   if (!success) return Nothing<bool>();
    129 
    130   return JSReceiver::DeleteProperty(&it, language_mode);
    131 }
    132 
    133 
    134 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
    135                                                Handle<Object> object,
    136                                                Handle<Object> key,
    137                                                Handle<Object> value,
    138                                                LanguageMode language_mode) {
    139   if (object->IsUndefined() || object->IsNull()) {
    140     THROW_NEW_ERROR(
    141         isolate,
    142         NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
    143         Object);
    144   }
    145 
    146   // Check if the given key is an array index.
    147   bool success = false;
    148   LookupIterator it =
    149       LookupIterator::PropertyOrElement(isolate, object, key, &success);
    150   if (!success) return MaybeHandle<Object>();
    151 
    152   MAYBE_RETURN_NULL(Object::SetProperty(&it, value, language_mode,
    153                                         Object::MAY_BE_STORE_FROM_KEYED));
    154   return value;
    155 }
    156 
    157 
    158 RUNTIME_FUNCTION(Runtime_GetPrototype) {
    159   HandleScope scope(isolate);
    160   DCHECK(args.length() == 1);
    161   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
    162   Handle<Object> prototype;
    163   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, prototype,
    164                                      Object::GetPrototype(isolate, obj));
    165   return *prototype;
    166 }
    167 
    168 
    169 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
    170   HandleScope scope(isolate);
    171   DCHECK(args.length() == 2);
    172   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
    173   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
    174   MAYBE_RETURN(
    175       JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR),
    176       isolate->heap()->exception());
    177   return *obj;
    178 }
    179 
    180 
    181 RUNTIME_FUNCTION(Runtime_SetPrototype) {
    182   HandleScope scope(isolate);
    183   DCHECK(args.length() == 2);
    184   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
    185   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
    186   MAYBE_RETURN(
    187       JSReceiver::SetPrototype(obj, prototype, true, Object::THROW_ON_ERROR),
    188       isolate->heap()->exception());
    189   return *obj;
    190 }
    191 
    192 
    193 // Enumerator used as indices into the array returned from GetOwnProperty
    194 enum PropertyDescriptorIndices {
    195   IS_ACCESSOR_INDEX,
    196   VALUE_INDEX,
    197   GETTER_INDEX,
    198   SETTER_INDEX,
    199   WRITABLE_INDEX,
    200   ENUMERABLE_INDEX,
    201   CONFIGURABLE_INDEX,
    202   DESCRIPTOR_SIZE
    203 };
    204 
    205 
    206 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
    207                                                           Handle<JSObject> obj,
    208                                                           Handle<Name> name) {
    209   Heap* heap = isolate->heap();
    210   Factory* factory = isolate->factory();
    211 
    212   // Get attributes.
    213   LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name,
    214                                                         LookupIterator::HIDDEN);
    215   Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
    216 
    217   if (!maybe.IsJust()) return MaybeHandle<Object>();
    218   PropertyAttributes attrs = maybe.FromJust();
    219   if (attrs == ABSENT) return factory->undefined_value();
    220 
    221   DCHECK(!isolate->has_pending_exception());
    222   Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
    223   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
    224   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
    225 
    226   bool is_accessor_pair = it.state() == LookupIterator::ACCESSOR &&
    227                           it.GetAccessors()->IsAccessorPair();
    228   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(is_accessor_pair));
    229 
    230   if (is_accessor_pair) {
    231     Handle<AccessorPair> accessors =
    232         Handle<AccessorPair>::cast(it.GetAccessors());
    233     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
    234     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
    235     elms->set(GETTER_INDEX, *getter);
    236     elms->set(SETTER_INDEX, *setter);
    237   } else {
    238     Handle<Object> value;
    239     ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it),
    240                                Object);
    241     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
    242     elms->set(VALUE_INDEX, *value);
    243   }
    244 
    245   return factory->NewJSArrayWithElements(elms);
    246 }
    247 
    248 
    249 // Returns an array with the property description:
    250 //  if args[1] is not a property on args[0]
    251 //          returns undefined
    252 //  if args[1] is a data property on args[0]
    253 //         [false, value, Writeable, Enumerable, Configurable]
    254 //  if args[1] is an accessor on args[0]
    255 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
    256 // TODO(jkummerow): Deprecated. Remove all callers and delete.
    257 RUNTIME_FUNCTION(Runtime_GetOwnProperty_Legacy) {
    258   HandleScope scope(isolate);
    259   DCHECK(args.length() == 2);
    260   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    261   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    262   Handle<Object> result;
    263   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    264                                      GetOwnProperty(isolate, obj, name));
    265   return *result;
    266 }
    267 
    268 
    269 // ES6 19.1.2.6
    270 RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
    271   HandleScope scope(isolate);
    272   DCHECK(args.length() == 2);
    273   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    274   CONVERT_ARG_HANDLE_CHECKED(Object, raw_name, 1);
    275   // 1. Let obj be ? ToObject(O).
    276   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, object,
    277                                      Execution::ToObject(isolate, object));
    278   // 2. Let key be ? ToPropertyKey(P).
    279   Handle<Name> key;
    280   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
    281                                      Object::ToName(isolate, raw_name));
    282 
    283   // 3. Let desc be ? obj.[[GetOwnProperty]](key).
    284   PropertyDescriptor desc;
    285   Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
    286       isolate, Handle<JSReceiver>::cast(object), key, &desc);
    287   MAYBE_RETURN(found, isolate->heap()->exception());
    288   // 4. Return FromPropertyDescriptor(desc).
    289   if (!found.FromJust()) return isolate->heap()->undefined_value();
    290   return *desc.ToObject(isolate);
    291 }
    292 
    293 
    294 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
    295   HandleScope scope(isolate);
    296   DCHECK(args.length() == 2);
    297   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
    298   CONVERT_SMI_ARG_CHECKED(properties, 1);
    299   // Conservative upper limit to prevent fuzz tests from going OOM.
    300   RUNTIME_ASSERT(properties <= 100000);
    301   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
    302     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
    303                                   "OptimizeForAdding");
    304   }
    305   return *object;
    306 }
    307 
    308 
    309 RUNTIME_FUNCTION(Runtime_LoadGlobalViaContext) {
    310   HandleScope scope(isolate);
    311   DCHECK_EQ(1, args.length());
    312   CONVERT_SMI_ARG_CHECKED(slot, 0);
    313 
    314   // Go up context chain to the script context.
    315   Handle<Context> script_context(isolate->context()->script_context(), isolate);
    316   DCHECK(script_context->IsScriptContext());
    317   DCHECK(script_context->get(slot)->IsPropertyCell());
    318 
    319   // Lookup the named property on the global object.
    320   Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate);
    321   Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
    322   Handle<JSGlobalObject> global_object(script_context->global_object(),
    323                                        isolate);
    324   LookupIterator it(global_object, name, LookupIterator::HIDDEN);
    325 
    326   // Switch to fast mode only if there is a data property and it's not on
    327   // a hidden prototype.
    328   if (it.state() == LookupIterator::DATA &&
    329       it.GetHolder<Object>().is_identical_to(global_object)) {
    330     // Now update the cell in the script context.
    331     Handle<PropertyCell> cell = it.GetPropertyCell();
    332     script_context->set(slot, *cell);
    333   } else {
    334     // This is not a fast case, so keep this access in a slow mode.
    335     // Store empty_property_cell here to release the outdated property cell.
    336     script_context->set(slot, isolate->heap()->empty_property_cell());
    337   }
    338 
    339   Handle<Object> result;
    340   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
    341   return *result;
    342 }
    343 
    344 
    345 namespace {
    346 
    347 Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value,
    348                               LanguageMode language_mode) {
    349   // Go up context chain to the script context.
    350   Handle<Context> script_context(isolate->context()->script_context(), isolate);
    351   DCHECK(script_context->IsScriptContext());
    352   DCHECK(script_context->get(slot)->IsPropertyCell());
    353 
    354   // Lookup the named property on the global object.
    355   Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate);
    356   Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
    357   Handle<JSGlobalObject> global_object(script_context->global_object(),
    358                                        isolate);
    359   LookupIterator it(global_object, name, LookupIterator::HIDDEN);
    360 
    361   // Switch to fast mode only if there is a data property and it's not on
    362   // a hidden prototype.
    363   if (it.state() == LookupIterator::DATA &&
    364       it.GetHolder<Object>().is_identical_to(global_object)) {
    365     // Now update cell in the script context.
    366     Handle<PropertyCell> cell = it.GetPropertyCell();
    367     script_context->set(slot, *cell);
    368   } else {
    369     // This is not a fast case, so keep this access in a slow mode.
    370     // Store empty_property_cell here to release the outdated property cell.
    371     script_context->set(slot, isolate->heap()->empty_property_cell());
    372   }
    373 
    374   MAYBE_RETURN(Object::SetProperty(&it, value, language_mode,
    375                                    Object::CERTAINLY_NOT_STORE_FROM_KEYED),
    376                isolate->heap()->exception());
    377   return *value;
    378 }
    379 
    380 }  // namespace
    381 
    382 
    383 RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Sloppy) {
    384   HandleScope scope(isolate);
    385   DCHECK_EQ(2, args.length());
    386   CONVERT_SMI_ARG_CHECKED(slot, 0);
    387   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    388 
    389   return StoreGlobalViaContext(isolate, slot, value, SLOPPY);
    390 }
    391 
    392 
    393 RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Strict) {
    394   HandleScope scope(isolate);
    395   DCHECK_EQ(2, args.length());
    396   CONVERT_SMI_ARG_CHECKED(slot, 0);
    397   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    398 
    399   return StoreGlobalViaContext(isolate, slot, value, STRICT);
    400 }
    401 
    402 
    403 RUNTIME_FUNCTION(Runtime_GetProperty) {
    404   HandleScope scope(isolate);
    405   DCHECK(args.length() == 2);
    406 
    407   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    408   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
    409 
    410   Handle<Object> result;
    411   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    412       isolate, result,
    413       Runtime::GetObjectProperty(isolate, object, key, SLOPPY));
    414   return *result;
    415 }
    416 
    417 
    418 RUNTIME_FUNCTION(Runtime_GetPropertyStrong) {
    419   HandleScope scope(isolate);
    420   DCHECK(args.length() == 2);
    421 
    422   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    423   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
    424 
    425   Handle<Object> result;
    426   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    427       isolate, result,
    428       Runtime::GetObjectProperty(isolate, object, key, STRONG));
    429   return *result;
    430 }
    431 
    432 
    433 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
    434 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
    435   HandleScope scope(isolate);
    436   DCHECK(args.length() == 2);
    437 
    438   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
    439   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
    440 
    441   Handle<Object> result;
    442   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    443       isolate, result,
    444       KeyedGetObjectProperty(isolate, receiver_obj, key_obj, SLOPPY));
    445   return *result;
    446 }
    447 
    448 
    449 RUNTIME_FUNCTION(Runtime_KeyedGetPropertyStrong) {
    450   HandleScope scope(isolate);
    451   DCHECK(args.length() == 2);
    452 
    453   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
    454   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
    455 
    456   Handle<Object> result;
    457   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    458       isolate, result,
    459       KeyedGetObjectProperty(isolate, receiver_obj, key_obj, STRONG));
    460   return *result;
    461 }
    462 
    463 
    464 RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
    465   HandleScope scope(isolate);
    466   RUNTIME_ASSERT(args.length() == 4);
    467 
    468   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
    469   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    470   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
    471   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
    472 
    473 #ifdef DEBUG
    474   uint32_t index = 0;
    475   DCHECK(!name->ToArrayIndex(&index));
    476   LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    477   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    478   if (!maybe.IsJust()) return isolate->heap()->exception();
    479   RUNTIME_ASSERT(!it.IsFound());
    480 #endif
    481 
    482   Handle<Object> result;
    483   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    484       isolate, result,
    485       JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, attrs));
    486   return *result;
    487 }
    488 
    489 
    490 // Adds an element to an array.
    491 // This is used to create an indexed data property into an array.
    492 RUNTIME_FUNCTION(Runtime_AddElement) {
    493   HandleScope scope(isolate);
    494   RUNTIME_ASSERT(args.length() == 3);
    495 
    496   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
    497   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
    498   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
    499 
    500   uint32_t index = 0;
    501   CHECK(key->ToArrayIndex(&index));
    502 
    503 #ifdef DEBUG
    504   LookupIterator it(isolate, object, index,
    505                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    506   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    507   if (!maybe.IsJust()) return isolate->heap()->exception();
    508   RUNTIME_ASSERT(!it.IsFound());
    509 
    510   if (object->IsJSArray()) {
    511     Handle<JSArray> array = Handle<JSArray>::cast(object);
    512     RUNTIME_ASSERT(!JSArray::WouldChangeReadOnlyLength(array, index));
    513   }
    514 #endif
    515 
    516   Handle<Object> result;
    517   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    518       isolate, result,
    519       JSObject::SetOwnElementIgnoreAttributes(object, index, value, NONE));
    520   return *result;
    521 }
    522 
    523 
    524 RUNTIME_FUNCTION(Runtime_AppendElement) {
    525   HandleScope scope(isolate);
    526   RUNTIME_ASSERT(args.length() == 2);
    527 
    528   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
    529   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    530 
    531   uint32_t index;
    532   CHECK(array->length()->ToArrayIndex(&index));
    533 
    534   Handle<Object> result;
    535   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    536       isolate, result, JSObject::AddDataElement(array, index, value, NONE));
    537   JSObject::ValidateElements(array);
    538   return *array;
    539 }
    540 
    541 
    542 RUNTIME_FUNCTION(Runtime_SetProperty) {
    543   HandleScope scope(isolate);
    544   RUNTIME_ASSERT(args.length() == 4);
    545 
    546   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    547   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
    548   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
    549   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode_arg, 3);
    550   LanguageMode language_mode = language_mode_arg;
    551 
    552   Handle<Object> result;
    553   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    554       isolate, result,
    555       Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
    556   return *result;
    557 }
    558 
    559 
    560 namespace {
    561 
    562 // ES6 section 12.5.4.
    563 Object* DeleteProperty(Isolate* isolate, Handle<Object> object,
    564                        Handle<Object> key, LanguageMode language_mode) {
    565   Handle<JSReceiver> receiver;
    566   if (!JSReceiver::ToObject(isolate, object).ToHandle(&receiver)) {
    567     THROW_NEW_ERROR_RETURN_FAILURE(
    568         isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
    569   }
    570   Maybe<bool> result =
    571       Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
    572   MAYBE_RETURN(result, isolate->heap()->exception());
    573   return isolate->heap()->ToBoolean(result.FromJust());
    574 }
    575 
    576 }  // namespace
    577 
    578 
    579 RUNTIME_FUNCTION(Runtime_DeleteProperty_Sloppy) {
    580   HandleScope scope(isolate);
    581   DCHECK_EQ(2, args.length());
    582   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    583   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
    584   return DeleteProperty(isolate, object, key, SLOPPY);
    585 }
    586 
    587 
    588 RUNTIME_FUNCTION(Runtime_DeleteProperty_Strict) {
    589   HandleScope scope(isolate);
    590   DCHECK_EQ(2, args.length());
    591   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    592   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
    593   return DeleteProperty(isolate, object, key, STRICT);
    594 }
    595 
    596 
    597 static Object* HasOwnPropertyImplementation(Isolate* isolate,
    598                                             Handle<JSObject> object,
    599                                             Handle<Name> key) {
    600   Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
    601   if (!maybe.IsJust()) return isolate->heap()->exception();
    602   if (maybe.FromJust()) return isolate->heap()->true_value();
    603   // Handle hidden prototypes.  If there's a hidden prototype above this thing
    604   // then we have to check it for properties, because they are supposed to
    605   // look like they are on this object.
    606   PrototypeIterator iter(isolate, object);
    607   if (!iter.IsAtEnd() &&
    608       PrototypeIterator::GetCurrent<HeapObject>(iter)
    609           ->map()
    610           ->is_hidden_prototype()) {
    611     // TODO(verwaest): The recursion is not necessary for keys that are array
    612     // indices. Removing this.
    613     // Casting to JSObject is fine because JSProxies are never used as
    614     // hidden prototypes.
    615     return HasOwnPropertyImplementation(
    616         isolate, PrototypeIterator::GetCurrent<JSObject>(iter), key);
    617   }
    618   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    619   return isolate->heap()->false_value();
    620 }
    621 
    622 
    623 RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
    624   HandleScope scope(isolate);
    625   DCHECK(args.length() == 2);
    626   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
    627   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
    628 
    629   uint32_t index;
    630   const bool key_is_array_index = key->AsArrayIndex(&index);
    631 
    632   // Only JS objects can have properties.
    633   if (object->IsJSObject()) {
    634     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
    635     // Fast case: either the key is a real named property or it is not
    636     // an array index and there are no interceptors or hidden
    637     // prototypes.
    638     // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
    639     // handle all cases directly (without this custom fast path).
    640     Maybe<bool> maybe = Nothing<bool>();
    641     if (key_is_array_index) {
    642       LookupIterator it(js_obj->GetIsolate(), js_obj, index,
    643                         LookupIterator::HIDDEN);
    644       maybe = JSReceiver::HasProperty(&it);
    645     } else {
    646       maybe = JSObject::HasRealNamedProperty(js_obj, key);
    647     }
    648     if (!maybe.IsJust()) return isolate->heap()->exception();
    649     DCHECK(!isolate->has_pending_exception());
    650     if (maybe.FromJust()) {
    651       return isolate->heap()->true_value();
    652     }
    653     Map* map = js_obj->map();
    654     if (!key_is_array_index && !map->has_named_interceptor() &&
    655         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
    656       return isolate->heap()->false_value();
    657     }
    658     // Slow case.
    659     return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj),
    660                                         Handle<Name>(key));
    661   } else if (object->IsString() && key_is_array_index) {
    662     // Well, there is one exception:  Handle [] on strings.
    663     Handle<String> string = Handle<String>::cast(object);
    664     if (index < static_cast<uint32_t>(string->length())) {
    665       return isolate->heap()->true_value();
    666     }
    667   } else if (object->IsJSProxy()) {
    668     Maybe<bool> result =
    669         JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
    670     if (!result.IsJust()) return isolate->heap()->exception();
    671     return isolate->heap()->ToBoolean(result.FromJust());
    672   }
    673   return isolate->heap()->false_value();
    674 }
    675 
    676 
    677 // ES6 section 12.9.3, operator in.
    678 RUNTIME_FUNCTION(Runtime_HasProperty) {
    679   HandleScope scope(isolate);
    680   DCHECK_EQ(2, args.length());
    681   CONVERT_ARG_HANDLE_CHECKED(Object, key, 0);
    682   CONVERT_ARG_HANDLE_CHECKED(Object, object, 1);
    683 
    684   // Check that {object} is actually a receiver.
    685   if (!object->IsJSReceiver()) {
    686     THROW_NEW_ERROR_RETURN_FAILURE(
    687         isolate,
    688         NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
    689   }
    690   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
    691 
    692   // Convert the {key} to a name.
    693   Handle<Name> name;
    694   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
    695                                      Object::ToName(isolate, key));
    696 
    697   // Lookup the {name} on {receiver}.
    698   Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
    699   if (!maybe.IsJust()) return isolate->heap()->exception();
    700   return isolate->heap()->ToBoolean(maybe.FromJust());
    701 }
    702 
    703 
    704 RUNTIME_FUNCTION(Runtime_PropertyIsEnumerable) {
    705   HandleScope scope(isolate);
    706   DCHECK(args.length() == 2);
    707 
    708   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
    709   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
    710 
    711   Maybe<PropertyAttributes> maybe =
    712       JSReceiver::GetOwnPropertyAttributes(object, key);
    713   if (!maybe.IsJust()) return isolate->heap()->exception();
    714   if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
    715   return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
    716 }
    717 
    718 
    719 // Returns either a FixedArray or, if the given object has an enum cache that
    720 // contains all enumerable properties of the object and its prototypes have
    721 // none, the map of the object. This is used to speed up the check for
    722 // deletions during a for-in.
    723 RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
    724   SealHandleScope shs(isolate);
    725   DCHECK(args.length() == 1);
    726 
    727   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
    728 
    729   if (raw_object->IsSimpleEnum()) return raw_object->map();
    730 
    731   HandleScope scope(isolate);
    732   Handle<JSReceiver> object(raw_object);
    733   Handle<FixedArray> content;
    734   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    735       isolate, content, JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS,
    736                                             ENUMERABLE_STRINGS));
    737 
    738   // Test again, since cache may have been built by preceding call.
    739   if (object->IsSimpleEnum()) return object->map();
    740 
    741   return *content;
    742 }
    743 
    744 
    745 RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
    746   HandleScope scope(isolate);
    747   DCHECK(args.length() == 2);
    748   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
    749   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
    750   PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
    751 
    752   Handle<FixedArray> keys;
    753   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    754       isolate, keys, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY, filter,
    755                                          CONVERT_TO_STRING));
    756 
    757   return *isolate->factory()->NewJSArrayWithElements(keys);
    758 }
    759 
    760 
    761 // Return information on whether an object has a named or indexed interceptor.
    762 // args[0]: object
    763 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
    764   HandleScope scope(isolate);
    765   DCHECK(args.length() == 1);
    766   if (!args[0]->IsJSObject()) {
    767     return Smi::FromInt(0);
    768   }
    769   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    770 
    771   int result = 0;
    772   if (obj->HasNamedInterceptor()) result |= 2;
    773   if (obj->HasIndexedInterceptor()) result |= 1;
    774 
    775   return Smi::FromInt(result);
    776 }
    777 
    778 
    779 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
    780   HandleScope scope(isolate);
    781   DCHECK(args.length() == 1);
    782   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    783   if (object->IsJSObject() && !object->IsJSGlobalObject()) {
    784     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
    785                                 "RuntimeToFastProperties");
    786   }
    787   return *object;
    788 }
    789 
    790 
    791 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
    792   HandleScope scope(isolate);
    793   DCHECK(args.length() == 0);
    794   return *isolate->factory()->NewHeapNumber(0);
    795 }
    796 
    797 
    798 RUNTIME_FUNCTION(Runtime_NewObject) {
    799   HandleScope scope(isolate);
    800   DCHECK_EQ(2, args.length());
    801   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
    802   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
    803   Handle<JSObject> result;
    804   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    805                                      JSObject::New(target, new_target));
    806   return *result;
    807 }
    808 
    809 
    810 RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
    811   HandleScope scope(isolate);
    812   DCHECK(args.length() == 1);
    813 
    814   CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
    815   initial_map->CompleteInobjectSlackTracking();
    816 
    817   return isolate->heap()->undefined_value();
    818 }
    819 
    820 
    821 RUNTIME_FUNCTION(Runtime_GlobalProxy) {
    822   SealHandleScope shs(isolate);
    823   DCHECK(args.length() == 1);
    824   CONVERT_ARG_CHECKED(JSFunction, function, 0);
    825   return function->context()->global_proxy();
    826 }
    827 
    828 
    829 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
    830   HandleScope scope(isolate);
    831   DCHECK(args.length() == 3);
    832   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
    833   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    834   CONVERT_SMI_ARG_CHECKED(flag, 2);
    835   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
    836   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
    837   Handle<Object> result;
    838   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    839       isolate, result,
    840       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
    841   return *result;
    842 }
    843 
    844 
    845 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
    846   HandleScope scope(isolate);
    847   DCHECK(args.length() == 2);
    848   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
    849   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
    850   RUNTIME_ASSERT((index->value() & 1) == 1);
    851   FieldIndex field_index =
    852       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
    853   if (field_index.is_inobject()) {
    854     RUNTIME_ASSERT(field_index.property_index() <
    855                    object->map()->GetInObjectProperties());
    856   } else {
    857     RUNTIME_ASSERT(field_index.outobject_array_index() <
    858                    object->properties()->length());
    859   }
    860   return *JSObject::FastPropertyAt(object, Representation::Double(),
    861                                    field_index);
    862 }
    863 
    864 
    865 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
    866   HandleScope scope(isolate);
    867   DCHECK(args.length() == 1);
    868   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    869   if (!object->IsJSObject()) return Smi::FromInt(0);
    870   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
    871   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
    872   // This call must not cause lazy deopts, because it's called from deferred
    873   // code where we can't handle lazy deopts for lack of a suitable bailout
    874   // ID. So we just try migration and signal failure if necessary,
    875   // which will also trigger a deopt.
    876   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
    877   return *object;
    878 }
    879 
    880 
    881 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
    882   SealHandleScope shs(isolate);
    883   DCHECK(args.length() == 1);
    884   CONVERT_ARG_CHECKED(Object, obj, 0);
    885   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
    886 }
    887 
    888 
    889 static bool IsValidAccessor(Handle<Object> obj) {
    890   return obj->IsUndefined() || obj->IsCallable() || obj->IsNull();
    891 }
    892 
    893 
    894 // Implements part of 8.12.9 DefineOwnProperty.
    895 // There are 3 cases that lead here:
    896 // Step 4b - define a new accessor property.
    897 // Steps 9c & 12 - replace an existing data property with an accessor property.
    898 // Step 12 - update an existing accessor property with an accessor or generic
    899 //           descriptor.
    900 RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
    901   HandleScope scope(isolate);
    902   DCHECK(args.length() == 5);
    903   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    904   RUNTIME_ASSERT(!obj->IsNull());
    905   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    906   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
    907   RUNTIME_ASSERT(IsValidAccessor(getter));
    908   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
    909   RUNTIME_ASSERT(IsValidAccessor(setter));
    910   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 4);
    911 
    912   RETURN_FAILURE_ON_EXCEPTION(
    913       isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
    914   return isolate->heap()->undefined_value();
    915 }
    916 
    917 
    918 // Implements part of 8.12.9 DefineOwnProperty.
    919 // There are 3 cases that lead here:
    920 // Step 4a - define a new data property.
    921 // Steps 9b & 12 - replace an existing accessor property with a data property.
    922 // Step 12 - update an existing data property with a data or generic
    923 //           descriptor.
    924 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
    925   HandleScope scope(isolate);
    926   DCHECK(args.length() == 4);
    927   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
    928   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    929   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
    930   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
    931 
    932   LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name,
    933                                                         LookupIterator::OWN);
    934   if (it.state() == LookupIterator::ACCESS_CHECK && !it.HasAccess()) {
    935     return isolate->heap()->undefined_value();
    936   }
    937 
    938   Handle<Object> result;
    939   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    940       isolate, result, JSObject::DefineOwnPropertyIgnoreAttributes(
    941                            &it, value, attrs, JSObject::DONT_FORCE_FIELD));
    942 
    943   return *result;
    944 }
    945 
    946 
    947 // Return property without being observable by accessors or interceptors.
    948 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
    949   HandleScope scope(isolate);
    950   DCHECK(args.length() == 2);
    951   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
    952   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    953   return *JSReceiver::GetDataProperty(object, name);
    954 }
    955 
    956 
    957 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
    958   SealHandleScope shs(isolate);
    959   DCHECK(args.length() == 1);
    960   CONVERT_ARG_CHECKED(HeapObject, obj, 0);
    961   return isolate->heap()->ToBoolean(
    962       IsFastPackedElementsKind(obj->map()->elements_kind()));
    963 }
    964 
    965 
    966 RUNTIME_FUNCTION(Runtime_ValueOf) {
    967   SealHandleScope shs(isolate);
    968   DCHECK(args.length() == 1);
    969   CONVERT_ARG_CHECKED(Object, obj, 0);
    970   if (!obj->IsJSValue()) return obj;
    971   return JSValue::cast(obj)->value();
    972 }
    973 
    974 
    975 RUNTIME_FUNCTION(Runtime_SetValueOf) {
    976   SealHandleScope shs(isolate);
    977   DCHECK(args.length() == 2);
    978   CONVERT_ARG_CHECKED(Object, obj, 0);
    979   CONVERT_ARG_CHECKED(Object, value, 1);
    980   if (!obj->IsJSValue()) return value;
    981   JSValue::cast(obj)->set_value(value);
    982   return value;
    983 }
    984 
    985 
    986 RUNTIME_FUNCTION(Runtime_JSValueGetValue) {
    987   SealHandleScope shs(isolate);
    988   DCHECK(args.length() == 1);
    989   CONVERT_ARG_CHECKED(JSValue, obj, 0);
    990   return JSValue::cast(obj)->value();
    991 }
    992 
    993 
    994 RUNTIME_FUNCTION(Runtime_ObjectEquals) {
    995   SealHandleScope shs(isolate);
    996   DCHECK(args.length() == 2);
    997   CONVERT_ARG_CHECKED(Object, obj1, 0);
    998   CONVERT_ARG_CHECKED(Object, obj2, 1);
    999   return isolate->heap()->ToBoolean(obj1 == obj2);
   1000 }
   1001 
   1002 
   1003 RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
   1004   SealHandleScope shs(isolate);
   1005   DCHECK(args.length() == 1);
   1006   CONVERT_ARG_CHECKED(Object, obj, 0);
   1007   return isolate->heap()->ToBoolean(obj->IsJSReceiver());
   1008 }
   1009 
   1010 
   1011 RUNTIME_FUNCTION(Runtime_IsStrong) {
   1012   SealHandleScope shs(isolate);
   1013   DCHECK(args.length() == 1);
   1014   CONVERT_ARG_CHECKED(Object, obj, 0);
   1015   return isolate->heap()->ToBoolean(obj->IsJSReceiver() &&
   1016                                     JSReceiver::cast(obj)->map()->is_strong());
   1017 }
   1018 
   1019 
   1020 RUNTIME_FUNCTION(Runtime_ClassOf) {
   1021   SealHandleScope shs(isolate);
   1022   DCHECK(args.length() == 1);
   1023   CONVERT_ARG_CHECKED(Object, obj, 0);
   1024   if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
   1025   return JSReceiver::cast(obj)->class_name();
   1026 }
   1027 
   1028 
   1029 RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
   1030   HandleScope scope(isolate);
   1031   DCHECK(args.length() == 4);
   1032   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   1033   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   1034   CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
   1035   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
   1036 
   1037   RETURN_FAILURE_ON_EXCEPTION(
   1038       isolate,
   1039       JSObject::DefineAccessor(object, name, getter,
   1040                                isolate->factory()->null_value(), attrs));
   1041   return isolate->heap()->undefined_value();
   1042 }
   1043 
   1044 
   1045 RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
   1046   HandleScope scope(isolate);
   1047   DCHECK(args.length() == 4);
   1048   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   1049   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   1050   CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
   1051   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
   1052 
   1053   RETURN_FAILURE_ON_EXCEPTION(
   1054       isolate,
   1055       JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
   1056                                setter, attrs));
   1057   return isolate->heap()->undefined_value();
   1058 }
   1059 
   1060 
   1061 RUNTIME_FUNCTION(Runtime_ToObject) {
   1062   HandleScope scope(isolate);
   1063   DCHECK_EQ(1, args.length());
   1064   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   1065   Handle<JSReceiver> receiver;
   1066   if (JSReceiver::ToObject(isolate, object).ToHandle(&receiver)) {
   1067     return *receiver;
   1068   }
   1069   THROW_NEW_ERROR_RETURN_FAILURE(
   1070       isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
   1071 }
   1072 
   1073 
   1074 RUNTIME_FUNCTION(Runtime_ToPrimitive) {
   1075   HandleScope scope(isolate);
   1076   DCHECK_EQ(1, args.length());
   1077   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1078   Handle<Object> result;
   1079   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   1080                                      Object::ToPrimitive(input));
   1081   return *result;
   1082 }
   1083 
   1084 
   1085 RUNTIME_FUNCTION(Runtime_ToPrimitive_Number) {
   1086   HandleScope scope(isolate);
   1087   DCHECK_EQ(1, args.length());
   1088   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1089   Handle<Object> result;
   1090   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1091       isolate, result, Object::ToPrimitive(input, ToPrimitiveHint::kNumber));
   1092   return *result;
   1093 }
   1094 
   1095 
   1096 RUNTIME_FUNCTION(Runtime_ToPrimitive_String) {
   1097   HandleScope scope(isolate);
   1098   DCHECK_EQ(1, args.length());
   1099   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1100   Handle<Object> result;
   1101   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1102       isolate, result, Object::ToPrimitive(input, ToPrimitiveHint::kString));
   1103   return *result;
   1104 }
   1105 
   1106 
   1107 RUNTIME_FUNCTION(Runtime_ToNumber) {
   1108   HandleScope scope(isolate);
   1109   DCHECK_EQ(1, args.length());
   1110   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1111   Handle<Object> result;
   1112   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::ToNumber(input));
   1113   return *result;
   1114 }
   1115 
   1116 
   1117 RUNTIME_FUNCTION(Runtime_ToInteger) {
   1118   HandleScope scope(isolate);
   1119   DCHECK_EQ(1, args.length());
   1120   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1121   Handle<Object> result;
   1122   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   1123                                      Object::ToInteger(isolate, input));
   1124   return *result;
   1125 }
   1126 
   1127 
   1128 RUNTIME_FUNCTION(Runtime_ToLength) {
   1129   HandleScope scope(isolate);
   1130   DCHECK_EQ(1, args.length());
   1131   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1132   Handle<Object> result;
   1133   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   1134                                      Object::ToLength(isolate, input));
   1135   return *result;
   1136 }
   1137 
   1138 
   1139 RUNTIME_FUNCTION(Runtime_ToString) {
   1140   HandleScope scope(isolate);
   1141   DCHECK_EQ(1, args.length());
   1142   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1143   Handle<Object> result;
   1144   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   1145                                      Object::ToString(isolate, input));
   1146   return *result;
   1147 }
   1148 
   1149 
   1150 RUNTIME_FUNCTION(Runtime_ToName) {
   1151   HandleScope scope(isolate);
   1152   DCHECK_EQ(1, args.length());
   1153   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   1154   Handle<Object> result;
   1155   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   1156                                      Object::ToName(isolate, input));
   1157   return *result;
   1158 }
   1159 
   1160 
   1161 RUNTIME_FUNCTION(Runtime_Equals) {
   1162   HandleScope scope(isolate);
   1163   DCHECK_EQ(2, args.length());
   1164   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
   1165   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
   1166   Maybe<bool> result = Object::Equals(x, y);
   1167   if (!result.IsJust()) return isolate->heap()->exception();
   1168   // TODO(bmeurer): Change this at some point to return true/false instead.
   1169   return Smi::FromInt(result.FromJust() ? EQUAL : NOT_EQUAL);
   1170 }
   1171 
   1172 
   1173 RUNTIME_FUNCTION(Runtime_StrictEquals) {
   1174   SealHandleScope scope(isolate);
   1175   DCHECK_EQ(2, args.length());
   1176   CONVERT_ARG_CHECKED(Object, x, 0);
   1177   CONVERT_ARG_CHECKED(Object, y, 1);
   1178   // TODO(bmeurer): Change this at some point to return true/false instead.
   1179   return Smi::FromInt(x->StrictEquals(y) ? EQUAL : NOT_EQUAL);
   1180 }
   1181 
   1182 
   1183 // TODO(bmeurer): Kill this special wrapper and use TF compatible LessThan,
   1184 // GreaterThan, etc. which return true or false.
   1185 RUNTIME_FUNCTION(Runtime_Compare) {
   1186   HandleScope scope(isolate);
   1187   DCHECK_EQ(3, args.length());
   1188   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
   1189   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
   1190   CONVERT_ARG_HANDLE_CHECKED(Object, ncr, 2);
   1191   Maybe<ComparisonResult> result = Object::Compare(x, y);
   1192   if (result.IsJust()) {
   1193     switch (result.FromJust()) {
   1194       case ComparisonResult::kLessThan:
   1195         return Smi::FromInt(LESS);
   1196       case ComparisonResult::kEqual:
   1197         return Smi::FromInt(EQUAL);
   1198       case ComparisonResult::kGreaterThan:
   1199         return Smi::FromInt(GREATER);
   1200       case ComparisonResult::kUndefined:
   1201         return *ncr;
   1202     }
   1203     UNREACHABLE();
   1204   }
   1205   return isolate->heap()->exception();
   1206 }
   1207 
   1208 
   1209 // TODO(bmeurer): Kill this special wrapper and use TF compatible LessThan,
   1210 // GreaterThan, etc. which return true or false.
   1211 RUNTIME_FUNCTION(Runtime_Compare_Strong) {
   1212   HandleScope scope(isolate);
   1213   DCHECK_EQ(3, args.length());
   1214   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
   1215   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
   1216   CONVERT_ARG_HANDLE_CHECKED(Object, ncr, 2);
   1217   Maybe<ComparisonResult> result = Object::Compare(x, y, Strength::STRONG);
   1218   if (result.IsJust()) {
   1219     switch (result.FromJust()) {
   1220       case ComparisonResult::kLessThan:
   1221         return Smi::FromInt(LESS);
   1222       case ComparisonResult::kEqual:
   1223         return Smi::FromInt(EQUAL);
   1224       case ComparisonResult::kGreaterThan:
   1225         return Smi::FromInt(GREATER);
   1226       case ComparisonResult::kUndefined:
   1227         return *ncr;
   1228     }
   1229     UNREACHABLE();
   1230   }
   1231   return isolate->heap()->exception();
   1232 }
   1233 
   1234 
   1235 RUNTIME_FUNCTION(Runtime_InstanceOf) {
   1236   // ECMA-262, section 11.8.6, page 54.
   1237   HandleScope shs(isolate);
   1238   DCHECK_EQ(2, args.length());
   1239   DCHECK(args.length() == 2);
   1240   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   1241   CONVERT_ARG_HANDLE_CHECKED(Object, callable, 1);
   1242   // {callable} must have a [[Call]] internal method.
   1243   if (!callable->IsCallable()) {
   1244     THROW_NEW_ERROR_RETURN_FAILURE(
   1245         isolate,
   1246         NewTypeError(MessageTemplate::kInstanceofFunctionExpected, callable));
   1247   }
   1248   // If {object} is not a receiver, return false.
   1249   if (!object->IsJSReceiver()) {
   1250     return isolate->heap()->false_value();
   1251   }
   1252   // Check if {callable} is bound, if so, get [[BoundTargetFunction]] from it
   1253   // and use that instead of {callable}.
   1254   while (callable->IsJSBoundFunction()) {
   1255     callable =
   1256         handle(Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
   1257                isolate);
   1258   }
   1259   DCHECK(callable->IsCallable());
   1260   // Get the "prototype" of {callable}; raise an error if it's not a receiver.
   1261   Handle<Object> prototype;
   1262   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1263       isolate, prototype,
   1264       Object::GetProperty(callable, isolate->factory()->prototype_string()));
   1265   if (!prototype->IsJSReceiver()) {
   1266     THROW_NEW_ERROR_RETURN_FAILURE(
   1267         isolate,
   1268         NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype));
   1269   }
   1270   // Return whether or not {prototype} is in the prototype chain of {object}.
   1271   Maybe<bool> result = Object::HasInPrototypeChain(isolate, object, prototype);
   1272   MAYBE_RETURN(result, isolate->heap()->exception());
   1273   return isolate->heap()->ToBoolean(result.FromJust());
   1274 }
   1275 
   1276 
   1277 RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
   1278   HandleScope scope(isolate);
   1279   DCHECK_EQ(2, args.length());
   1280   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   1281   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   1282   Maybe<bool> result = Object::HasInPrototypeChain(isolate, object, prototype);
   1283   MAYBE_RETURN(result, isolate->heap()->exception());
   1284   return isolate->heap()->ToBoolean(result.FromJust());
   1285 }
   1286 
   1287 
   1288 // ES6 section 7.4.7 CreateIterResultObject ( value, done )
   1289 RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
   1290   HandleScope scope(isolate);
   1291   DCHECK_EQ(2, args.length());
   1292   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
   1293   CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
   1294   return *isolate->factory()->NewJSIteratorResult(value, done);
   1295 }
   1296 
   1297 
   1298 RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) {
   1299   SealHandleScope shs(isolate);
   1300   DCHECK_EQ(1, args.length());
   1301   CONVERT_ARG_CHECKED(Object, object, 0);
   1302   return isolate->heap()->ToBoolean(object->IsAccessCheckNeeded());
   1303 }
   1304 
   1305 
   1306 RUNTIME_FUNCTION(Runtime_ObjectDefineProperty) {
   1307   HandleScope scope(isolate);
   1308   DCHECK(args.length() == 3);
   1309   CONVERT_ARG_HANDLE_CHECKED(Object, o, 0);
   1310   CONVERT_ARG_HANDLE_CHECKED(Object, name, 1);
   1311   CONVERT_ARG_HANDLE_CHECKED(Object, attributes, 2);
   1312   return JSReceiver::DefineProperty(isolate, o, name, attributes);
   1313 }
   1314 
   1315 
   1316 RUNTIME_FUNCTION(Runtime_ObjectDefineProperties) {
   1317   HandleScope scope(isolate);
   1318   DCHECK(args.length() == 2);
   1319   CONVERT_ARG_HANDLE_CHECKED(Object, o, 0);
   1320   CONVERT_ARG_HANDLE_CHECKED(Object, properties, 1);
   1321   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1322       isolate, o, JSReceiver::DefineProperties(isolate, o, properties));
   1323   return *o;
   1324 }
   1325 
   1326 }  // namespace internal
   1327 }  // namespace v8
   1328