Home | History | Annotate | Download | only in src
      1 // Copyright 2012 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/builtins.h"
      6 
      7 #include "src/api-arguments.h"
      8 #include "src/api-natives.h"
      9 #include "src/api.h"
     10 #include "src/base/ieee754.h"
     11 #include "src/base/once.h"
     12 #include "src/bootstrapper.h"
     13 #include "src/code-factory.h"
     14 #include "src/code-stub-assembler.h"
     15 #include "src/dateparser-inl.h"
     16 #include "src/elements.h"
     17 #include "src/frames-inl.h"
     18 #include "src/gdb-jit.h"
     19 #include "src/ic/handler-compiler.h"
     20 #include "src/ic/ic.h"
     21 #include "src/isolate-inl.h"
     22 #include "src/json-parser.h"
     23 #include "src/json-stringifier.h"
     24 #include "src/messages.h"
     25 #include "src/property-descriptor.h"
     26 #include "src/prototype.h"
     27 #include "src/string-builder.h"
     28 #include "src/uri.h"
     29 #include "src/vm-state-inl.h"
     30 
     31 namespace v8 {
     32 namespace internal {
     33 
     34 namespace {
     35 
     36 // Arguments object passed to C++ builtins.
     37 class BuiltinArguments : public Arguments {
     38  public:
     39   BuiltinArguments(int length, Object** arguments)
     40       : Arguments(length, arguments) {
     41     // Check we have at least the receiver.
     42     DCHECK_LE(1, this->length());
     43   }
     44 
     45   Object*& operator[] (int index) {
     46     DCHECK_LT(index, length());
     47     return Arguments::operator[](index);
     48   }
     49 
     50   template <class S> Handle<S> at(int index) {
     51     DCHECK_LT(index, length());
     52     return Arguments::at<S>(index);
     53   }
     54 
     55   Handle<Object> atOrUndefined(Isolate* isolate, int index) {
     56     if (index >= length()) {
     57       return isolate->factory()->undefined_value();
     58     }
     59     return at<Object>(index);
     60   }
     61 
     62   Handle<Object> receiver() {
     63     return Arguments::at<Object>(0);
     64   }
     65 
     66   template <class S>
     67   Handle<S> target() {
     68     return Arguments::at<S>(Arguments::length() - 2);
     69   }
     70   Handle<HeapObject> new_target() {
     71     return Arguments::at<HeapObject>(Arguments::length() - 1);
     72   }
     73 
     74   // Gets the total number of arguments including the receiver (but
     75   // excluding extra arguments).
     76   int length() const { return Arguments::length() - 2; }
     77 };
     78 
     79 
     80 // ----------------------------------------------------------------------------
     81 // Support macro for defining builtins in C++.
     82 // ----------------------------------------------------------------------------
     83 //
     84 // A builtin function is defined by writing:
     85 //
     86 //   BUILTIN(name) {
     87 //     ...
     88 //   }
     89 //
     90 // In the body of the builtin function the arguments can be accessed
     91 // through the BuiltinArguments object args.
     92 // TODO(cbruni): add global flag to check whether any tracing events have been
     93 // enabled.
     94 #define BUILTIN(name)                                                        \
     95   MUST_USE_RESULT static Object* Builtin_Impl_##name(BuiltinArguments args,  \
     96                                                      Isolate* isolate);      \
     97                                                                              \
     98   V8_NOINLINE static Object* Builtin_Impl_Stats_##name(                      \
     99       int args_length, Object** args_object, Isolate* isolate) {             \
    100     BuiltinArguments args(args_length, args_object);                         \
    101     RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Builtin_##name); \
    102     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"),                    \
    103                  "V8.Builtin_" #name);                                       \
    104     return Builtin_Impl_##name(args, isolate);                               \
    105   }                                                                          \
    106                                                                              \
    107   MUST_USE_RESULT static Object* Builtin_##name(                             \
    108       int args_length, Object** args_object, Isolate* isolate) {             \
    109     if (FLAG_runtime_call_stats) {                                           \
    110       return Builtin_Impl_Stats_##name(args_length, args_object, isolate);   \
    111     }                                                                        \
    112     BuiltinArguments args(args_length, args_object);                         \
    113     return Builtin_Impl_##name(args, isolate);                               \
    114   }                                                                          \
    115                                                                              \
    116   MUST_USE_RESULT static Object* Builtin_Impl_##name(BuiltinArguments args,  \
    117                                                      Isolate* isolate)
    118 
    119 // ----------------------------------------------------------------------------
    120 
    121 #define CHECK_RECEIVER(Type, name, method)                                  \
    122   if (!args.receiver()->Is##Type()) {                                       \
    123     THROW_NEW_ERROR_RETURN_FAILURE(                                         \
    124         isolate,                                                            \
    125         NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,          \
    126                      isolate->factory()->NewStringFromAsciiChecked(method), \
    127                      args.receiver()));                                     \
    128   }                                                                         \
    129   Handle<Type> name = Handle<Type>::cast(args.receiver())
    130 
    131 // Throws a TypeError for {method} if the receiver is not coercible to Object,
    132 // or converts the receiver to a String otherwise and assigns it to a new var
    133 // with the given {name}.
    134 #define TO_THIS_STRING(name, method)                                          \
    135   if (args.receiver()->IsNull(isolate) ||                                     \
    136       args.receiver()->IsUndefined(isolate)) {                                \
    137     THROW_NEW_ERROR_RETURN_FAILURE(                                           \
    138         isolate,                                                              \
    139         NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,               \
    140                      isolate->factory()->NewStringFromAsciiChecked(method))); \
    141   }                                                                           \
    142   Handle<String> name;                                                        \
    143   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(                                         \
    144       isolate, name, Object::ToString(isolate, args.receiver()))
    145 
    146 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) {
    147   // This is an extended version of ECMA-262 7.1.11 handling signed values
    148   // Try to convert object to a number and clamp values to [kMinInt, kMaxInt]
    149   if (object->IsSmi()) {
    150     *out = Smi::cast(object)->value();
    151     return true;
    152   } else if (object->IsHeapNumber()) {
    153     double value = HeapNumber::cast(object)->value();
    154     if (std::isnan(value)) {
    155       *out = 0;
    156     } else if (value > kMaxInt) {
    157       *out = kMaxInt;
    158     } else if (value < kMinInt) {
    159       *out = kMinInt;
    160     } else {
    161       *out = static_cast<int>(value);
    162     }
    163     return true;
    164   } else if (object->IsUndefined(isolate) || object->IsNull(isolate)) {
    165     *out = 0;
    166     return true;
    167   } else if (object->IsBoolean()) {
    168     *out = object->IsTrue(isolate);
    169     return true;
    170   }
    171   return false;
    172 }
    173 
    174 
    175 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object,
    176                                      int* out) {
    177   Context* context = *isolate->native_context();
    178   Map* map = object->map();
    179   if (map != context->sloppy_arguments_map() &&
    180       map != context->strict_arguments_map() &&
    181       map != context->fast_aliased_arguments_map()) {
    182     return false;
    183   }
    184   DCHECK(object->HasFastElements() || object->HasFastArgumentsElements());
    185   Object* len_obj = object->InObjectPropertyAt(JSArgumentsObject::kLengthIndex);
    186   if (!len_obj->IsSmi()) return false;
    187   *out = Max(0, Smi::cast(len_obj)->value());
    188   return *out <= object->elements()->length();
    189 }
    190 
    191 inline bool PrototypeHasNoElements(Isolate* isolate, JSObject* object) {
    192   DisallowHeapAllocation no_gc;
    193   HeapObject* prototype = HeapObject::cast(object->map()->prototype());
    194   HeapObject* null = isolate->heap()->null_value();
    195   HeapObject* empty = isolate->heap()->empty_fixed_array();
    196   while (prototype != null) {
    197     Map* map = prototype->map();
    198     if (map->instance_type() <= LAST_CUSTOM_ELEMENTS_RECEIVER) return false;
    199     if (JSObject::cast(prototype)->elements() != empty) return false;
    200     prototype = HeapObject::cast(map->prototype());
    201   }
    202   return true;
    203 }
    204 
    205 inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate,
    206                                               JSArray* receiver) {
    207   return PrototypeHasNoElements(isolate, receiver);
    208 }
    209 
    210 inline bool HasSimpleElements(JSObject* current) {
    211   return current->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
    212          !current->GetElementsAccessor()->HasAccessors(current);
    213 }
    214 
    215 inline bool HasOnlySimpleReceiverElements(Isolate* isolate,
    216                                           JSObject* receiver) {
    217   // Check that we have no accessors on the receiver's elements.
    218   if (!HasSimpleElements(receiver)) return false;
    219   return PrototypeHasNoElements(isolate, receiver);
    220 }
    221 
    222 inline bool HasOnlySimpleElements(Isolate* isolate, JSReceiver* receiver) {
    223   DisallowHeapAllocation no_gc;
    224   PrototypeIterator iter(isolate, receiver, kStartAtReceiver);
    225   for (; !iter.IsAtEnd(); iter.Advance()) {
    226     if (iter.GetCurrent()->IsJSProxy()) return false;
    227     JSObject* current = iter.GetCurrent<JSObject>();
    228     if (!HasSimpleElements(current)) return false;
    229   }
    230   return true;
    231 }
    232 
    233 // Returns |false| if not applicable.
    234 MUST_USE_RESULT
    235 inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
    236                                                   Handle<Object> receiver,
    237                                                   BuiltinArguments* args,
    238                                                   int first_added_arg) {
    239   if (!receiver->IsJSArray()) return false;
    240   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    241   ElementsKind origin_kind = array->GetElementsKind();
    242   if (IsDictionaryElementsKind(origin_kind)) return false;
    243   if (!array->map()->is_extensible()) return false;
    244   if (args == nullptr) return true;
    245 
    246   // If there may be elements accessors in the prototype chain, the fast path
    247   // cannot be used if there arguments to add to the array.
    248   if (!IsJSArrayFastElementMovingAllowed(isolate, *array)) return false;
    249 
    250   // Adding elements to the array prototype would break code that makes sure
    251   // it has no elements. Handle that elsewhere.
    252   if (isolate->IsAnyInitialArrayPrototype(array)) return false;
    253 
    254   // Need to ensure that the arguments passed in args can be contained in
    255   // the array.
    256   int args_length = args->length();
    257   if (first_added_arg >= args_length) return true;
    258 
    259   if (IsFastObjectElementsKind(origin_kind)) return true;
    260   ElementsKind target_kind = origin_kind;
    261   {
    262     DisallowHeapAllocation no_gc;
    263     for (int i = first_added_arg; i < args_length; i++) {
    264       Object* arg = (*args)[i];
    265       if (arg->IsHeapObject()) {
    266         if (arg->IsHeapNumber()) {
    267           target_kind = FAST_DOUBLE_ELEMENTS;
    268         } else {
    269           target_kind = FAST_ELEMENTS;
    270           break;
    271         }
    272       }
    273     }
    274   }
    275   if (target_kind != origin_kind) {
    276     // Use a short-lived HandleScope to avoid creating several copies of the
    277     // elements handle which would cause issues when left-trimming later-on.
    278     HandleScope scope(isolate);
    279     JSObject::TransitionElementsKind(array, target_kind);
    280   }
    281   return true;
    282 }
    283 
    284 MUST_USE_RESULT static Object* CallJsIntrinsic(Isolate* isolate,
    285                                                Handle<JSFunction> function,
    286                                                BuiltinArguments args) {
    287   HandleScope handleScope(isolate);
    288   int argc = args.length() - 1;
    289   ScopedVector<Handle<Object> > argv(argc);
    290   for (int i = 0; i < argc; ++i) {
    291     argv[i] = args.at<Object>(i + 1);
    292   }
    293   RETURN_RESULT_OR_FAILURE(
    294       isolate,
    295       Execution::Call(isolate, function, args.receiver(), argc, argv.start()));
    296 }
    297 
    298 
    299 }  // namespace
    300 
    301 
    302 BUILTIN(Illegal) {
    303   UNREACHABLE();
    304   return isolate->heap()->undefined_value();  // Make compiler happy.
    305 }
    306 
    307 
    308 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); }
    309 
    310 void Builtins::Generate_ArrayIsArray(CodeStubAssembler* assembler) {
    311   typedef compiler::Node Node;
    312   typedef CodeStubAssembler::Label Label;
    313 
    314   Node* object = assembler->Parameter(1);
    315   Node* context = assembler->Parameter(4);
    316 
    317   Label call_runtime(assembler), return_true(assembler),
    318       return_false(assembler);
    319 
    320   assembler->GotoIf(assembler->WordIsSmi(object), &return_false);
    321   Node* instance_type = assembler->LoadInstanceType(object);
    322 
    323   assembler->GotoIf(assembler->Word32Equal(
    324                         instance_type, assembler->Int32Constant(JS_ARRAY_TYPE)),
    325                     &return_true);
    326 
    327   // TODO(verwaest): Handle proxies in-place.
    328   assembler->Branch(assembler->Word32Equal(
    329                         instance_type, assembler->Int32Constant(JS_PROXY_TYPE)),
    330                     &call_runtime, &return_false);
    331 
    332   assembler->Bind(&return_true);
    333   assembler->Return(assembler->BooleanConstant(true));
    334 
    335   assembler->Bind(&return_false);
    336   assembler->Return(assembler->BooleanConstant(false));
    337 
    338   assembler->Bind(&call_runtime);
    339   assembler->Return(
    340       assembler->CallRuntime(Runtime::kArrayIsArray, context, object));
    341 }
    342 
    343 void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) {
    344   typedef compiler::Node Node;
    345   typedef CodeStubAssembler::Label Label;
    346   typedef CodeStubAssembler::Variable Variable;
    347 
    348   Node* object = assembler->Parameter(0);
    349   Node* key = assembler->Parameter(1);
    350   Node* context = assembler->Parameter(4);
    351 
    352   Label call_runtime(assembler), return_true(assembler),
    353       return_false(assembler);
    354 
    355   // Smi receivers do not have own properties.
    356   Label if_objectisnotsmi(assembler);
    357   assembler->Branch(assembler->WordIsSmi(object), &return_false,
    358                     &if_objectisnotsmi);
    359   assembler->Bind(&if_objectisnotsmi);
    360 
    361   Node* map = assembler->LoadMap(object);
    362   Node* instance_type = assembler->LoadMapInstanceType(map);
    363 
    364   Variable var_index(assembler, MachineRepresentation::kWord32);
    365 
    366   Label keyisindex(assembler), if_iskeyunique(assembler);
    367   assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique,
    368                        &call_runtime);
    369 
    370   assembler->Bind(&if_iskeyunique);
    371   assembler->TryHasOwnProperty(object, map, instance_type, key, &return_true,
    372                                &return_false, &call_runtime);
    373 
    374   assembler->Bind(&keyisindex);
    375   assembler->TryLookupElement(object, map, instance_type, var_index.value(),
    376                               &return_true, &return_false, &call_runtime);
    377 
    378   assembler->Bind(&return_true);
    379   assembler->Return(assembler->BooleanConstant(true));
    380 
    381   assembler->Bind(&return_false);
    382   assembler->Return(assembler->BooleanConstant(false));
    383 
    384   assembler->Bind(&call_runtime);
    385   assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty,
    386                                            context, object, key));
    387 }
    388 
    389 namespace {
    390 
    391 Object* DoArrayPush(Isolate* isolate, BuiltinArguments args) {
    392   HandleScope scope(isolate);
    393   Handle<Object> receiver = args.receiver();
    394   if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
    395     return CallJsIntrinsic(isolate, isolate->array_push(), args);
    396   }
    397   // Fast Elements Path
    398   int to_add = args.length() - 1;
    399   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    400   int len = Smi::cast(array->length())->value();
    401   if (to_add == 0) return Smi::FromInt(len);
    402 
    403   // Currently fixed arrays cannot grow too big, so we should never hit this.
    404   DCHECK_LE(to_add, Smi::kMaxValue - Smi::cast(array->length())->value());
    405 
    406   if (JSArray::HasReadOnlyLength(array)) {
    407     return CallJsIntrinsic(isolate, isolate->array_push(), args);
    408   }
    409 
    410   ElementsAccessor* accessor = array->GetElementsAccessor();
    411   int new_length = accessor->Push(array, &args, to_add);
    412   return Smi::FromInt(new_length);
    413 }
    414 
    415 }  // namespace
    416 
    417 BUILTIN(ArrayPush) { return DoArrayPush(isolate, args); }
    418 
    419 // TODO(verwaest): This is a temporary helper until the FastArrayPush stub can
    420 // tailcall to the builtin directly.
    421 RUNTIME_FUNCTION(Runtime_ArrayPush) {
    422   DCHECK_EQ(2, args.length());
    423   Arguments* incoming = reinterpret_cast<Arguments*>(args[0]);
    424   // Rewrap the arguments as builtins arguments.
    425   BuiltinArguments caller_args(incoming->length() + 3,
    426                                incoming->arguments() + 1);
    427   return DoArrayPush(isolate, caller_args);
    428 }
    429 
    430 BUILTIN(ArrayPop) {
    431   HandleScope scope(isolate);
    432   Handle<Object> receiver = args.receiver();
    433   if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) {
    434     return CallJsIntrinsic(isolate, isolate->array_pop(), args);
    435   }
    436 
    437   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    438 
    439   uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value());
    440   if (len == 0) return isolate->heap()->undefined_value();
    441 
    442   if (JSArray::HasReadOnlyLength(array)) {
    443     return CallJsIntrinsic(isolate, isolate->array_pop(), args);
    444   }
    445 
    446   Handle<Object> result;
    447   if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
    448     // Fast Elements Path
    449     result = array->GetElementsAccessor()->Pop(array);
    450   } else {
    451     // Use Slow Lookup otherwise
    452     uint32_t new_length = len - 1;
    453     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    454         isolate, result, JSReceiver::GetElement(isolate, array, new_length));
    455     JSArray::SetLength(array, new_length);
    456   }
    457   return *result;
    458 }
    459 
    460 
    461 BUILTIN(ArrayShift) {
    462   HandleScope scope(isolate);
    463   Heap* heap = isolate->heap();
    464   Handle<Object> receiver = args.receiver();
    465   if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0) ||
    466       !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
    467     return CallJsIntrinsic(isolate, isolate->array_shift(), args);
    468   }
    469   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    470 
    471   int len = Smi::cast(array->length())->value();
    472   if (len == 0) return heap->undefined_value();
    473 
    474   if (JSArray::HasReadOnlyLength(array)) {
    475     return CallJsIntrinsic(isolate, isolate->array_shift(), args);
    476   }
    477 
    478   Handle<Object> first = array->GetElementsAccessor()->Shift(array);
    479   return *first;
    480 }
    481 
    482 
    483 BUILTIN(ArrayUnshift) {
    484   HandleScope scope(isolate);
    485   Handle<Object> receiver = args.receiver();
    486   if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
    487     return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
    488   }
    489   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    490   int to_add = args.length() - 1;
    491   if (to_add == 0) return array->length();
    492 
    493   // Currently fixed arrays cannot grow too big, so we should never hit this.
    494   DCHECK_LE(to_add, Smi::kMaxValue - Smi::cast(array->length())->value());
    495 
    496   if (JSArray::HasReadOnlyLength(array)) {
    497     return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
    498   }
    499 
    500   ElementsAccessor* accessor = array->GetElementsAccessor();
    501   int new_length = accessor->Unshift(array, &args, to_add);
    502   return Smi::FromInt(new_length);
    503 }
    504 
    505 
    506 BUILTIN(ArraySlice) {
    507   HandleScope scope(isolate);
    508   Handle<Object> receiver = args.receiver();
    509   int len = -1;
    510   int relative_start = 0;
    511   int relative_end = 0;
    512 
    513   if (receiver->IsJSArray()) {
    514     DisallowHeapAllocation no_gc;
    515     JSArray* array = JSArray::cast(*receiver);
    516     if (V8_UNLIKELY(!array->HasFastElements() ||
    517                     !IsJSArrayFastElementMovingAllowed(isolate, array) ||
    518                     !isolate->IsArraySpeciesLookupChainIntact() ||
    519                     // If this is a subclass of Array, then call out to JS
    520                     !array->HasArrayPrototype(isolate))) {
    521       AllowHeapAllocation allow_allocation;
    522       return CallJsIntrinsic(isolate, isolate->array_slice(), args);
    523     }
    524     len = Smi::cast(array->length())->value();
    525   } else if (receiver->IsJSObject() &&
    526              GetSloppyArgumentsLength(isolate, Handle<JSObject>::cast(receiver),
    527                                       &len)) {
    528     // Array.prototype.slice.call(arguments, ...) is quite a common idiom
    529     // (notably more than 50% of invocations in Web apps).
    530     // Treat it in C++ as well.
    531     DCHECK(JSObject::cast(*receiver)->HasFastElements() ||
    532            JSObject::cast(*receiver)->HasFastArgumentsElements());
    533   } else {
    534     AllowHeapAllocation allow_allocation;
    535     return CallJsIntrinsic(isolate, isolate->array_slice(), args);
    536   }
    537   DCHECK_LE(0, len);
    538   int argument_count = args.length() - 1;
    539   // Note carefully chosen defaults---if argument is missing,
    540   // it's undefined which gets converted to 0 for relative_start
    541   // and to len for relative_end.
    542   relative_start = 0;
    543   relative_end = len;
    544   if (argument_count > 0) {
    545     DisallowHeapAllocation no_gc;
    546     if (!ClampedToInteger(isolate, args[1], &relative_start)) {
    547       AllowHeapAllocation allow_allocation;
    548       return CallJsIntrinsic(isolate, isolate->array_slice(), args);
    549     }
    550     if (argument_count > 1) {
    551       Object* end_arg = args[2];
    552       // slice handles the end_arg specially
    553       if (end_arg->IsUndefined(isolate)) {
    554         relative_end = len;
    555       } else if (!ClampedToInteger(isolate, end_arg, &relative_end)) {
    556         AllowHeapAllocation allow_allocation;
    557         return CallJsIntrinsic(isolate, isolate->array_slice(), args);
    558       }
    559     }
    560   }
    561 
    562   // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
    563   uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
    564                                                : Min(relative_start, len);
    565 
    566   // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
    567   uint32_t actual_end =
    568       (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len);
    569 
    570   Handle<JSObject> object = Handle<JSObject>::cast(receiver);
    571   ElementsAccessor* accessor = object->GetElementsAccessor();
    572   return *accessor->Slice(object, actual_start, actual_end);
    573 }
    574 
    575 
    576 BUILTIN(ArraySplice) {
    577   HandleScope scope(isolate);
    578   Handle<Object> receiver = args.receiver();
    579   if (V8_UNLIKELY(
    580           !EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3) ||
    581           // If this is a subclass of Array, then call out to JS.
    582           !Handle<JSArray>::cast(receiver)->HasArrayPrototype(isolate) ||
    583           // If anything with @@species has been messed with, call out to JS.
    584           !isolate->IsArraySpeciesLookupChainIntact())) {
    585     return CallJsIntrinsic(isolate, isolate->array_splice(), args);
    586   }
    587   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
    588 
    589   int argument_count = args.length() - 1;
    590   int relative_start = 0;
    591   if (argument_count > 0) {
    592     DisallowHeapAllocation no_gc;
    593     if (!ClampedToInteger(isolate, args[1], &relative_start)) {
    594       AllowHeapAllocation allow_allocation;
    595       return CallJsIntrinsic(isolate, isolate->array_splice(), args);
    596     }
    597   }
    598   int len = Smi::cast(array->length())->value();
    599   // clip relative start to [0, len]
    600   int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
    601                                           : Min(relative_start, len);
    602 
    603   int actual_delete_count;
    604   if (argument_count == 1) {
    605     // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
    606     // given as a request to delete all the elements from the start.
    607     // And it differs from the case of undefined delete count.
    608     // This does not follow ECMA-262, but we do the same for compatibility.
    609     DCHECK(len - actual_start >= 0);
    610     actual_delete_count = len - actual_start;
    611   } else {
    612     int delete_count = 0;
    613     DisallowHeapAllocation no_gc;
    614     if (argument_count > 1) {
    615       if (!ClampedToInteger(isolate, args[2], &delete_count)) {
    616         AllowHeapAllocation allow_allocation;
    617         return CallJsIntrinsic(isolate, isolate->array_splice(), args);
    618       }
    619     }
    620     actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
    621   }
    622 
    623   int add_count = (argument_count > 1) ? (argument_count - 2) : 0;
    624   int new_length = len - actual_delete_count + add_count;
    625 
    626   if (new_length != len && JSArray::HasReadOnlyLength(array)) {
    627     AllowHeapAllocation allow_allocation;
    628     return CallJsIntrinsic(isolate, isolate->array_splice(), args);
    629   }
    630   ElementsAccessor* accessor = array->GetElementsAccessor();
    631   Handle<JSArray> result_array = accessor->Splice(
    632       array, actual_start, actual_delete_count, &args, add_count);
    633   return *result_array;
    634 }
    635 
    636 
    637 // Array Concat -------------------------------------------------------------
    638 
    639 namespace {
    640 
    641 /**
    642  * A simple visitor visits every element of Array's.
    643  * The backend storage can be a fixed array for fast elements case,
    644  * or a dictionary for sparse array. Since Dictionary is a subtype
    645  * of FixedArray, the class can be used by both fast and slow cases.
    646  * The second parameter of the constructor, fast_elements, specifies
    647  * whether the storage is a FixedArray or Dictionary.
    648  *
    649  * An index limit is used to deal with the situation that a result array
    650  * length overflows 32-bit non-negative integer.
    651  */
    652 class ArrayConcatVisitor {
    653  public:
    654   ArrayConcatVisitor(Isolate* isolate, Handle<Object> storage,
    655                      bool fast_elements)
    656       : isolate_(isolate),
    657         storage_(isolate->global_handles()->Create(*storage)),
    658         index_offset_(0u),
    659         bit_field_(FastElementsField::encode(fast_elements) |
    660                    ExceedsLimitField::encode(false) |
    661                    IsFixedArrayField::encode(storage->IsFixedArray())) {
    662     DCHECK(!(this->fast_elements() && !is_fixed_array()));
    663   }
    664 
    665   ~ArrayConcatVisitor() { clear_storage(); }
    666 
    667   MUST_USE_RESULT bool visit(uint32_t i, Handle<Object> elm) {
    668     uint32_t index = index_offset_ + i;
    669 
    670     if (i >= JSObject::kMaxElementCount - index_offset_) {
    671       set_exceeds_array_limit(true);
    672       // Exception hasn't been thrown at this point. Return true to
    673       // break out, and caller will throw. !visit would imply that
    674       // there is already a pending exception.
    675       return true;
    676     }
    677 
    678     if (!is_fixed_array()) {
    679       LookupIterator it(isolate_, storage_, index, LookupIterator::OWN);
    680       MAYBE_RETURN(
    681           JSReceiver::CreateDataProperty(&it, elm, Object::THROW_ON_ERROR),
    682           false);
    683       return true;
    684     }
    685 
    686     if (fast_elements()) {
    687       if (index < static_cast<uint32_t>(storage_fixed_array()->length())) {
    688         storage_fixed_array()->set(index, *elm);
    689         return true;
    690       }
    691       // Our initial estimate of length was foiled, possibly by
    692       // getters on the arrays increasing the length of later arrays
    693       // during iteration.
    694       // This shouldn't happen in anything but pathological cases.
    695       SetDictionaryMode();
    696       // Fall-through to dictionary mode.
    697     }
    698     DCHECK(!fast_elements());
    699     Handle<SeededNumberDictionary> dict(
    700         SeededNumberDictionary::cast(*storage_));
    701     // The object holding this backing store has just been allocated, so
    702     // it cannot yet be used as a prototype.
    703     Handle<SeededNumberDictionary> result =
    704         SeededNumberDictionary::AtNumberPut(dict, index, elm, false);
    705     if (!result.is_identical_to(dict)) {
    706       // Dictionary needed to grow.
    707       clear_storage();
    708       set_storage(*result);
    709     }
    710     return true;
    711   }
    712 
    713   void increase_index_offset(uint32_t delta) {
    714     if (JSObject::kMaxElementCount - index_offset_ < delta) {
    715       index_offset_ = JSObject::kMaxElementCount;
    716     } else {
    717       index_offset_ += delta;
    718     }
    719     // If the initial length estimate was off (see special case in visit()),
    720     // but the array blowing the limit didn't contain elements beyond the
    721     // provided-for index range, go to dictionary mode now.
    722     if (fast_elements() &&
    723         index_offset_ >
    724             static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
    725       SetDictionaryMode();
    726     }
    727   }
    728 
    729   bool exceeds_array_limit() const {
    730     return ExceedsLimitField::decode(bit_field_);
    731   }
    732 
    733   Handle<JSArray> ToArray() {
    734     DCHECK(is_fixed_array());
    735     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
    736     Handle<Object> length =
    737         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
    738     Handle<Map> map = JSObject::GetElementsTransitionMap(
    739         array, fast_elements() ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
    740     array->set_map(*map);
    741     array->set_length(*length);
    742     array->set_elements(*storage_fixed_array());
    743     return array;
    744   }
    745 
    746   // Storage is either a FixedArray (if is_fixed_array()) or a JSReciever
    747   // (otherwise)
    748   Handle<FixedArray> storage_fixed_array() {
    749     DCHECK(is_fixed_array());
    750     return Handle<FixedArray>::cast(storage_);
    751   }
    752   Handle<JSReceiver> storage_jsreceiver() {
    753     DCHECK(!is_fixed_array());
    754     return Handle<JSReceiver>::cast(storage_);
    755   }
    756 
    757  private:
    758   // Convert storage to dictionary mode.
    759   void SetDictionaryMode() {
    760     DCHECK(fast_elements() && is_fixed_array());
    761     Handle<FixedArray> current_storage = storage_fixed_array();
    762     Handle<SeededNumberDictionary> slow_storage(
    763         SeededNumberDictionary::New(isolate_, current_storage->length()));
    764     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
    765     FOR_WITH_HANDLE_SCOPE(
    766         isolate_, uint32_t, i = 0, i, i < current_length, i++, {
    767           Handle<Object> element(current_storage->get(i), isolate_);
    768           if (!element->IsTheHole(isolate_)) {
    769             // The object holding this backing store has just been allocated, so
    770             // it cannot yet be used as a prototype.
    771             Handle<SeededNumberDictionary> new_storage =
    772                 SeededNumberDictionary::AtNumberPut(slow_storage, i, element,
    773                                                     false);
    774             if (!new_storage.is_identical_to(slow_storage)) {
    775               slow_storage = loop_scope.CloseAndEscape(new_storage);
    776             }
    777           }
    778         });
    779     clear_storage();
    780     set_storage(*slow_storage);
    781     set_fast_elements(false);
    782   }
    783 
    784   inline void clear_storage() { GlobalHandles::Destroy(storage_.location()); }
    785 
    786   inline void set_storage(FixedArray* storage) {
    787     DCHECK(is_fixed_array());
    788     storage_ = isolate_->global_handles()->Create(storage);
    789   }
    790 
    791   class FastElementsField : public BitField<bool, 0, 1> {};
    792   class ExceedsLimitField : public BitField<bool, 1, 1> {};
    793   class IsFixedArrayField : public BitField<bool, 2, 1> {};
    794 
    795   bool fast_elements() const { return FastElementsField::decode(bit_field_); }
    796   void set_fast_elements(bool fast) {
    797     bit_field_ = FastElementsField::update(bit_field_, fast);
    798   }
    799   void set_exceeds_array_limit(bool exceeds) {
    800     bit_field_ = ExceedsLimitField::update(bit_field_, exceeds);
    801   }
    802   bool is_fixed_array() const { return IsFixedArrayField::decode(bit_field_); }
    803 
    804   Isolate* isolate_;
    805   Handle<Object> storage_;  // Always a global handle.
    806   // Index after last seen index. Always less than or equal to
    807   // JSObject::kMaxElementCount.
    808   uint32_t index_offset_;
    809   uint32_t bit_field_;
    810 };
    811 
    812 
    813 uint32_t EstimateElementCount(Handle<JSArray> array) {
    814   DisallowHeapAllocation no_gc;
    815   uint32_t length = static_cast<uint32_t>(array->length()->Number());
    816   int element_count = 0;
    817   switch (array->GetElementsKind()) {
    818     case FAST_SMI_ELEMENTS:
    819     case FAST_HOLEY_SMI_ELEMENTS:
    820     case FAST_ELEMENTS:
    821     case FAST_HOLEY_ELEMENTS: {
    822       // Fast elements can't have lengths that are not representable by
    823       // a 32-bit signed integer.
    824       DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
    825       int fast_length = static_cast<int>(length);
    826       Isolate* isolate = array->GetIsolate();
    827       FixedArray* elements = FixedArray::cast(array->elements());
    828       for (int i = 0; i < fast_length; i++) {
    829         if (!elements->get(i)->IsTheHole(isolate)) element_count++;
    830       }
    831       break;
    832     }
    833     case FAST_DOUBLE_ELEMENTS:
    834     case FAST_HOLEY_DOUBLE_ELEMENTS: {
    835       // Fast elements can't have lengths that are not representable by
    836       // a 32-bit signed integer.
    837       DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
    838       int fast_length = static_cast<int>(length);
    839       if (array->elements()->IsFixedArray()) {
    840         DCHECK(FixedArray::cast(array->elements())->length() == 0);
    841         break;
    842       }
    843       FixedDoubleArray* elements = FixedDoubleArray::cast(array->elements());
    844       for (int i = 0; i < fast_length; i++) {
    845         if (!elements->is_the_hole(i)) element_count++;
    846       }
    847       break;
    848     }
    849     case DICTIONARY_ELEMENTS: {
    850       SeededNumberDictionary* dictionary =
    851           SeededNumberDictionary::cast(array->elements());
    852       Isolate* isolate = dictionary->GetIsolate();
    853       int capacity = dictionary->Capacity();
    854       for (int i = 0; i < capacity; i++) {
    855         Object* key = dictionary->KeyAt(i);
    856         if (dictionary->IsKey(isolate, key)) {
    857           element_count++;
    858         }
    859       }
    860       break;
    861     }
    862 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
    863 
    864       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    865 #undef TYPED_ARRAY_CASE
    866       // External arrays are always dense.
    867       return length;
    868     case NO_ELEMENTS:
    869       return 0;
    870     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    871     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    872     case FAST_STRING_WRAPPER_ELEMENTS:
    873     case SLOW_STRING_WRAPPER_ELEMENTS:
    874       UNREACHABLE();
    875       return 0;
    876   }
    877   // As an estimate, we assume that the prototype doesn't contain any
    878   // inherited elements.
    879   return element_count;
    880 }
    881 
    882 
    883 // Used for sorting indices in a List<uint32_t>.
    884 int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
    885   uint32_t a = *ap;
    886   uint32_t b = *bp;
    887   return (a == b) ? 0 : (a < b) ? -1 : 1;
    888 }
    889 
    890 
    891 void CollectElementIndices(Handle<JSObject> object, uint32_t range,
    892                            List<uint32_t>* indices) {
    893   Isolate* isolate = object->GetIsolate();
    894   ElementsKind kind = object->GetElementsKind();
    895   switch (kind) {
    896     case FAST_SMI_ELEMENTS:
    897     case FAST_ELEMENTS:
    898     case FAST_HOLEY_SMI_ELEMENTS:
    899     case FAST_HOLEY_ELEMENTS: {
    900       DisallowHeapAllocation no_gc;
    901       FixedArray* elements = FixedArray::cast(object->elements());
    902       uint32_t length = static_cast<uint32_t>(elements->length());
    903       if (range < length) length = range;
    904       for (uint32_t i = 0; i < length; i++) {
    905         if (!elements->get(i)->IsTheHole(isolate)) {
    906           indices->Add(i);
    907         }
    908       }
    909       break;
    910     }
    911     case FAST_HOLEY_DOUBLE_ELEMENTS:
    912     case FAST_DOUBLE_ELEMENTS: {
    913       if (object->elements()->IsFixedArray()) {
    914         DCHECK(object->elements()->length() == 0);
    915         break;
    916       }
    917       Handle<FixedDoubleArray> elements(
    918           FixedDoubleArray::cast(object->elements()));
    919       uint32_t length = static_cast<uint32_t>(elements->length());
    920       if (range < length) length = range;
    921       for (uint32_t i = 0; i < length; i++) {
    922         if (!elements->is_the_hole(i)) {
    923           indices->Add(i);
    924         }
    925       }
    926       break;
    927     }
    928     case DICTIONARY_ELEMENTS: {
    929       DisallowHeapAllocation no_gc;
    930       SeededNumberDictionary* dict =
    931           SeededNumberDictionary::cast(object->elements());
    932       uint32_t capacity = dict->Capacity();
    933       FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, {
    934         Object* k = dict->KeyAt(j);
    935         if (!dict->IsKey(isolate, k)) continue;
    936         DCHECK(k->IsNumber());
    937         uint32_t index = static_cast<uint32_t>(k->Number());
    938         if (index < range) {
    939           indices->Add(index);
    940         }
    941       });
    942       break;
    943     }
    944 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
    945 
    946       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    947 #undef TYPED_ARRAY_CASE
    948       {
    949         uint32_t length = static_cast<uint32_t>(
    950             FixedArrayBase::cast(object->elements())->length());
    951         if (range <= length) {
    952           length = range;
    953           // We will add all indices, so we might as well clear it first
    954           // and avoid duplicates.
    955           indices->Clear();
    956         }
    957         for (uint32_t i = 0; i < length; i++) {
    958           indices->Add(i);
    959         }
    960         if (length == range) return;  // All indices accounted for already.
    961         break;
    962       }
    963     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    964     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
    965       ElementsAccessor* accessor = object->GetElementsAccessor();
    966       for (uint32_t i = 0; i < range; i++) {
    967         if (accessor->HasElement(object, i)) {
    968           indices->Add(i);
    969         }
    970       }
    971       break;
    972     }
    973     case FAST_STRING_WRAPPER_ELEMENTS:
    974     case SLOW_STRING_WRAPPER_ELEMENTS: {
    975       DCHECK(object->IsJSValue());
    976       Handle<JSValue> js_value = Handle<JSValue>::cast(object);
    977       DCHECK(js_value->value()->IsString());
    978       Handle<String> string(String::cast(js_value->value()), isolate);
    979       uint32_t length = static_cast<uint32_t>(string->length());
    980       uint32_t i = 0;
    981       uint32_t limit = Min(length, range);
    982       for (; i < limit; i++) {
    983         indices->Add(i);
    984       }
    985       ElementsAccessor* accessor = object->GetElementsAccessor();
    986       for (; i < range; i++) {
    987         if (accessor->HasElement(object, i)) {
    988           indices->Add(i);
    989         }
    990       }
    991       break;
    992     }
    993     case NO_ELEMENTS:
    994       break;
    995   }
    996 
    997   PrototypeIterator iter(isolate, object);
    998   if (!iter.IsAtEnd()) {
    999     // The prototype will usually have no inherited element indices,
   1000     // but we have to check.
   1001     CollectElementIndices(PrototypeIterator::GetCurrent<JSObject>(iter), range,
   1002                           indices);
   1003   }
   1004 }
   1005 
   1006 
   1007 bool IterateElementsSlow(Isolate* isolate, Handle<JSReceiver> receiver,
   1008                          uint32_t length, ArrayConcatVisitor* visitor) {
   1009   FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, i = 0, i, i < length, ++i, {
   1010     Maybe<bool> maybe = JSReceiver::HasElement(receiver, i);
   1011     if (!maybe.IsJust()) return false;
   1012     if (maybe.FromJust()) {
   1013       Handle<Object> element_value;
   1014       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1015           isolate, element_value, JSReceiver::GetElement(isolate, receiver, i),
   1016           false);
   1017       if (!visitor->visit(i, element_value)) return false;
   1018     }
   1019   });
   1020   visitor->increase_index_offset(length);
   1021   return true;
   1022 }
   1023 
   1024 
   1025 /**
   1026  * A helper function that visits "array" elements of a JSReceiver in numerical
   1027  * order.
   1028  *
   1029  * The visitor argument called for each existing element in the array
   1030  * with the element index and the element's value.
   1031  * Afterwards it increments the base-index of the visitor by the array
   1032  * length.
   1033  * Returns false if any access threw an exception, otherwise true.
   1034  */
   1035 bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
   1036                      ArrayConcatVisitor* visitor) {
   1037   uint32_t length = 0;
   1038 
   1039   if (receiver->IsJSArray()) {
   1040     Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   1041     length = static_cast<uint32_t>(array->length()->Number());
   1042   } else {
   1043     Handle<Object> val;
   1044     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1045         isolate, val, Object::GetLengthFromArrayLike(isolate, receiver), false);
   1046     // TODO(caitp): Support larger element indexes (up to 2^53-1).
   1047     if (!val->ToUint32(&length)) {
   1048       length = 0;
   1049     }
   1050     // TODO(cbruni): handle other element kind as well
   1051     return IterateElementsSlow(isolate, receiver, length, visitor);
   1052   }
   1053 
   1054   if (!HasOnlySimpleElements(isolate, *receiver)) {
   1055     return IterateElementsSlow(isolate, receiver, length, visitor);
   1056   }
   1057   Handle<JSObject> array = Handle<JSObject>::cast(receiver);
   1058 
   1059   switch (array->GetElementsKind()) {
   1060     case FAST_SMI_ELEMENTS:
   1061     case FAST_ELEMENTS:
   1062     case FAST_HOLEY_SMI_ELEMENTS:
   1063     case FAST_HOLEY_ELEMENTS: {
   1064       // Run through the elements FixedArray and use HasElement and GetElement
   1065       // to check the prototype for missing elements.
   1066       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
   1067       int fast_length = static_cast<int>(length);
   1068       DCHECK(fast_length <= elements->length());
   1069       FOR_WITH_HANDLE_SCOPE(isolate, int, j = 0, j, j < fast_length, j++, {
   1070         Handle<Object> element_value(elements->get(j), isolate);
   1071         if (!element_value->IsTheHole(isolate)) {
   1072           if (!visitor->visit(j, element_value)) return false;
   1073         } else {
   1074           Maybe<bool> maybe = JSReceiver::HasElement(array, j);
   1075           if (!maybe.IsJust()) return false;
   1076           if (maybe.FromJust()) {
   1077             // Call GetElement on array, not its prototype, or getters won't
   1078             // have the correct receiver.
   1079             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1080                 isolate, element_value,
   1081                 JSReceiver::GetElement(isolate, array, j), false);
   1082             if (!visitor->visit(j, element_value)) return false;
   1083           }
   1084         }
   1085       });
   1086       break;
   1087     }
   1088     case FAST_HOLEY_DOUBLE_ELEMENTS:
   1089     case FAST_DOUBLE_ELEMENTS: {
   1090       // Empty array is FixedArray but not FixedDoubleArray.
   1091       if (length == 0) break;
   1092       // Run through the elements FixedArray and use HasElement and GetElement
   1093       // to check the prototype for missing elements.
   1094       if (array->elements()->IsFixedArray()) {
   1095         DCHECK(array->elements()->length() == 0);
   1096         break;
   1097       }
   1098       Handle<FixedDoubleArray> elements(
   1099           FixedDoubleArray::cast(array->elements()));
   1100       int fast_length = static_cast<int>(length);
   1101       DCHECK(fast_length <= elements->length());
   1102       FOR_WITH_HANDLE_SCOPE(isolate, int, j = 0, j, j < fast_length, j++, {
   1103         if (!elements->is_the_hole(j)) {
   1104           double double_value = elements->get_scalar(j);
   1105           Handle<Object> element_value =
   1106               isolate->factory()->NewNumber(double_value);
   1107           if (!visitor->visit(j, element_value)) return false;
   1108         } else {
   1109           Maybe<bool> maybe = JSReceiver::HasElement(array, j);
   1110           if (!maybe.IsJust()) return false;
   1111           if (maybe.FromJust()) {
   1112             // Call GetElement on array, not its prototype, or getters won't
   1113             // have the correct receiver.
   1114             Handle<Object> element_value;
   1115             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1116                 isolate, element_value,
   1117                 JSReceiver::GetElement(isolate, array, j), false);
   1118             if (!visitor->visit(j, element_value)) return false;
   1119           }
   1120         }
   1121       });
   1122       break;
   1123     }
   1124 
   1125     case DICTIONARY_ELEMENTS: {
   1126       Handle<SeededNumberDictionary> dict(array->element_dictionary());
   1127       List<uint32_t> indices(dict->Capacity() / 2);
   1128       // Collect all indices in the object and the prototypes less
   1129       // than length. This might introduce duplicates in the indices list.
   1130       CollectElementIndices(array, length, &indices);
   1131       indices.Sort(&compareUInt32);
   1132       int n = indices.length();
   1133       FOR_WITH_HANDLE_SCOPE(isolate, int, j = 0, j, j < n, (void)0, {
   1134         uint32_t index = indices[j];
   1135         Handle<Object> element;
   1136         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1137             isolate, element, JSReceiver::GetElement(isolate, array, index),
   1138             false);
   1139         if (!visitor->visit(index, element)) return false;
   1140         // Skip to next different index (i.e., omit duplicates).
   1141         do {
   1142           j++;
   1143         } while (j < n && indices[j] == index);
   1144       });
   1145       break;
   1146     }
   1147     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
   1148     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
   1149       FOR_WITH_HANDLE_SCOPE(
   1150           isolate, uint32_t, index = 0, index, index < length, index++, {
   1151             Handle<Object> element;
   1152             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1153                 isolate, element, JSReceiver::GetElement(isolate, array, index),
   1154                 false);
   1155             if (!visitor->visit(index, element)) return false;
   1156           });
   1157       break;
   1158     }
   1159     case NO_ELEMENTS:
   1160       break;
   1161 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
   1162       TYPED_ARRAYS(TYPED_ARRAY_CASE)
   1163 #undef TYPED_ARRAY_CASE
   1164       return IterateElementsSlow(isolate, receiver, length, visitor);
   1165     case FAST_STRING_WRAPPER_ELEMENTS:
   1166     case SLOW_STRING_WRAPPER_ELEMENTS:
   1167       // |array| is guaranteed to be an array or typed array.
   1168       UNREACHABLE();
   1169       break;
   1170   }
   1171   visitor->increase_index_offset(length);
   1172   return true;
   1173 }
   1174 
   1175 static Maybe<bool> IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) {
   1176   HandleScope handle_scope(isolate);
   1177   if (!obj->IsJSReceiver()) return Just(false);
   1178   if (!isolate->IsIsConcatSpreadableLookupChainIntact()) {
   1179     // Slow path if @@isConcatSpreadable has been used.
   1180     Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
   1181     Handle<Object> value;
   1182     MaybeHandle<Object> maybeValue =
   1183         i::Runtime::GetObjectProperty(isolate, obj, key);
   1184     if (!maybeValue.ToHandle(&value)) return Nothing<bool>();
   1185     if (!value->IsUndefined(isolate)) return Just(value->BooleanValue());
   1186   }
   1187   return Object::IsArray(obj);
   1188 }
   1189 
   1190 Object* Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species,
   1191                          Isolate* isolate) {
   1192   int argument_count = args->length();
   1193 
   1194   bool is_array_species = *species == isolate->context()->array_function();
   1195 
   1196   // Pass 1: estimate the length and number of elements of the result.
   1197   // The actual length can be larger if any of the arguments have getters
   1198   // that mutate other arguments (but will otherwise be precise).
   1199   // The number of elements is precise if there are no inherited elements.
   1200 
   1201   ElementsKind kind = FAST_SMI_ELEMENTS;
   1202 
   1203   uint32_t estimate_result_length = 0;
   1204   uint32_t estimate_nof_elements = 0;
   1205   FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < argument_count, i++, {
   1206     Handle<Object> obj((*args)[i], isolate);
   1207     uint32_t length_estimate;
   1208     uint32_t element_estimate;
   1209     if (obj->IsJSArray()) {
   1210       Handle<JSArray> array(Handle<JSArray>::cast(obj));
   1211       length_estimate = static_cast<uint32_t>(array->length()->Number());
   1212       if (length_estimate != 0) {
   1213         ElementsKind array_kind =
   1214             GetPackedElementsKind(array->GetElementsKind());
   1215         kind = GetMoreGeneralElementsKind(kind, array_kind);
   1216       }
   1217       element_estimate = EstimateElementCount(array);
   1218     } else {
   1219       if (obj->IsHeapObject()) {
   1220         kind = GetMoreGeneralElementsKind(
   1221             kind, obj->IsNumber() ? FAST_DOUBLE_ELEMENTS : FAST_ELEMENTS);
   1222       }
   1223       length_estimate = 1;
   1224       element_estimate = 1;
   1225     }
   1226     // Avoid overflows by capping at kMaxElementCount.
   1227     if (JSObject::kMaxElementCount - estimate_result_length < length_estimate) {
   1228       estimate_result_length = JSObject::kMaxElementCount;
   1229     } else {
   1230       estimate_result_length += length_estimate;
   1231     }
   1232     if (JSObject::kMaxElementCount - estimate_nof_elements < element_estimate) {
   1233       estimate_nof_elements = JSObject::kMaxElementCount;
   1234     } else {
   1235       estimate_nof_elements += element_estimate;
   1236     }
   1237   });
   1238 
   1239   // If estimated number of elements is more than half of length, a
   1240   // fixed array (fast case) is more time and space-efficient than a
   1241   // dictionary.
   1242   bool fast_case =
   1243       is_array_species && (estimate_nof_elements * 2) >= estimate_result_length;
   1244 
   1245   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
   1246     Handle<FixedArrayBase> storage =
   1247         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
   1248     int j = 0;
   1249     bool failure = false;
   1250     if (estimate_result_length > 0) {
   1251       Handle<FixedDoubleArray> double_storage =
   1252           Handle<FixedDoubleArray>::cast(storage);
   1253       for (int i = 0; i < argument_count; i++) {
   1254         Handle<Object> obj((*args)[i], isolate);
   1255         if (obj->IsSmi()) {
   1256           double_storage->set(j, Smi::cast(*obj)->value());
   1257           j++;
   1258         } else if (obj->IsNumber()) {
   1259           double_storage->set(j, obj->Number());
   1260           j++;
   1261         } else {
   1262           DisallowHeapAllocation no_gc;
   1263           JSArray* array = JSArray::cast(*obj);
   1264           uint32_t length = static_cast<uint32_t>(array->length()->Number());
   1265           switch (array->GetElementsKind()) {
   1266             case FAST_HOLEY_DOUBLE_ELEMENTS:
   1267             case FAST_DOUBLE_ELEMENTS: {
   1268               // Empty array is FixedArray but not FixedDoubleArray.
   1269               if (length == 0) break;
   1270               FixedDoubleArray* elements =
   1271                   FixedDoubleArray::cast(array->elements());
   1272               for (uint32_t i = 0; i < length; i++) {
   1273                 if (elements->is_the_hole(i)) {
   1274                   // TODO(jkummerow/verwaest): We could be a bit more clever
   1275                   // here: Check if there are no elements/getters on the
   1276                   // prototype chain, and if so, allow creation of a holey
   1277                   // result array.
   1278                   // Same thing below (holey smi case).
   1279                   failure = true;
   1280                   break;
   1281                 }
   1282                 double double_value = elements->get_scalar(i);
   1283                 double_storage->set(j, double_value);
   1284                 j++;
   1285               }
   1286               break;
   1287             }
   1288             case FAST_HOLEY_SMI_ELEMENTS:
   1289             case FAST_SMI_ELEMENTS: {
   1290               Object* the_hole = isolate->heap()->the_hole_value();
   1291               FixedArray* elements(FixedArray::cast(array->elements()));
   1292               for (uint32_t i = 0; i < length; i++) {
   1293                 Object* element = elements->get(i);
   1294                 if (element == the_hole) {
   1295                   failure = true;
   1296                   break;
   1297                 }
   1298                 int32_t int_value = Smi::cast(element)->value();
   1299                 double_storage->set(j, int_value);
   1300                 j++;
   1301               }
   1302               break;
   1303             }
   1304             case FAST_HOLEY_ELEMENTS:
   1305             case FAST_ELEMENTS:
   1306             case DICTIONARY_ELEMENTS:
   1307             case NO_ELEMENTS:
   1308               DCHECK_EQ(0u, length);
   1309               break;
   1310             default:
   1311               UNREACHABLE();
   1312           }
   1313         }
   1314         if (failure) break;
   1315       }
   1316     }
   1317     if (!failure) {
   1318       return *isolate->factory()->NewJSArrayWithElements(storage, kind, j);
   1319     }
   1320     // In case of failure, fall through.
   1321   }
   1322 
   1323   Handle<Object> storage;
   1324   if (fast_case) {
   1325     // The backing storage array must have non-existing elements to preserve
   1326     // holes across concat operations.
   1327     storage =
   1328         isolate->factory()->NewFixedArrayWithHoles(estimate_result_length);
   1329   } else if (is_array_species) {
   1330     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
   1331     uint32_t at_least_space_for =
   1332         estimate_nof_elements + (estimate_nof_elements >> 2);
   1333     storage = SeededNumberDictionary::New(isolate, at_least_space_for);
   1334   } else {
   1335     DCHECK(species->IsConstructor());
   1336     Handle<Object> length(Smi::FromInt(0), isolate);
   1337     Handle<Object> storage_object;
   1338     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1339         isolate, storage_object,
   1340         Execution::New(isolate, species, species, 1, &length));
   1341     storage = storage_object;
   1342   }
   1343 
   1344   ArrayConcatVisitor visitor(isolate, storage, fast_case);
   1345 
   1346   for (int i = 0; i < argument_count; i++) {
   1347     Handle<Object> obj((*args)[i], isolate);
   1348     Maybe<bool> spreadable = IsConcatSpreadable(isolate, obj);
   1349     MAYBE_RETURN(spreadable, isolate->heap()->exception());
   1350     if (spreadable.FromJust()) {
   1351       Handle<JSReceiver> object = Handle<JSReceiver>::cast(obj);
   1352       if (!IterateElements(isolate, object, &visitor)) {
   1353         return isolate->heap()->exception();
   1354       }
   1355     } else {
   1356       if (!visitor.visit(0, obj)) return isolate->heap()->exception();
   1357       visitor.increase_index_offset(1);
   1358     }
   1359   }
   1360 
   1361   if (visitor.exceeds_array_limit()) {
   1362     THROW_NEW_ERROR_RETURN_FAILURE(
   1363         isolate, NewRangeError(MessageTemplate::kInvalidArrayLength));
   1364   }
   1365 
   1366   if (is_array_species) {
   1367     return *visitor.ToArray();
   1368   } else {
   1369     return *visitor.storage_jsreceiver();
   1370   }
   1371 }
   1372 
   1373 bool IsSimpleArray(Isolate* isolate, Handle<JSArray> obj) {
   1374   DisallowHeapAllocation no_gc;
   1375   Map* map = obj->map();
   1376   // If there is only the 'length' property we are fine.
   1377   if (map->prototype() ==
   1378           isolate->native_context()->initial_array_prototype() &&
   1379       map->NumberOfOwnDescriptors() == 1) {
   1380     return true;
   1381   }
   1382   // TODO(cbruni): slower lookup for array subclasses and support slow
   1383   // @@IsConcatSpreadable lookup.
   1384   return false;
   1385 }
   1386 
   1387 MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate,
   1388                                       BuiltinArguments* args) {
   1389   if (!isolate->IsIsConcatSpreadableLookupChainIntact()) {
   1390     return MaybeHandle<JSArray>();
   1391   }
   1392   // We shouldn't overflow when adding another len.
   1393   const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
   1394   STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
   1395   STATIC_ASSERT(FixedDoubleArray::kMaxLength < kHalfOfMaxInt);
   1396   USE(kHalfOfMaxInt);
   1397 
   1398   int n_arguments = args->length();
   1399   int result_len = 0;
   1400   {
   1401     DisallowHeapAllocation no_gc;
   1402     // Iterate through all the arguments performing checks
   1403     // and calculating total length.
   1404     for (int i = 0; i < n_arguments; i++) {
   1405       Object* arg = (*args)[i];
   1406       if (!arg->IsJSArray()) return MaybeHandle<JSArray>();
   1407       if (!HasOnlySimpleReceiverElements(isolate, JSObject::cast(arg))) {
   1408         return MaybeHandle<JSArray>();
   1409       }
   1410       // TODO(cbruni): support fast concatenation of DICTIONARY_ELEMENTS.
   1411       if (!JSObject::cast(arg)->HasFastElements()) {
   1412         return MaybeHandle<JSArray>();
   1413       }
   1414       Handle<JSArray> array(JSArray::cast(arg), isolate);
   1415       if (!IsSimpleArray(isolate, array)) {
   1416         return MaybeHandle<JSArray>();
   1417       }
   1418       // The Array length is guaranted to be <= kHalfOfMaxInt thus we won't
   1419       // overflow.
   1420       result_len += Smi::cast(array->length())->value();
   1421       DCHECK(result_len >= 0);
   1422       // Throw an Error if we overflow the FixedArray limits
   1423       if (FixedDoubleArray::kMaxLength < result_len ||
   1424           FixedArray::kMaxLength < result_len) {
   1425         AllowHeapAllocation gc;
   1426         THROW_NEW_ERROR(isolate,
   1427                         NewRangeError(MessageTemplate::kInvalidArrayLength),
   1428                         JSArray);
   1429       }
   1430     }
   1431   }
   1432   return ElementsAccessor::Concat(isolate, args, n_arguments, result_len);
   1433 }
   1434 
   1435 }  // namespace
   1436 
   1437 
   1438 // ES6 22.1.3.1 Array.prototype.concat
   1439 BUILTIN(ArrayConcat) {
   1440   HandleScope scope(isolate);
   1441 
   1442   Handle<Object> receiver = args.receiver();
   1443   // TODO(bmeurer): Do we really care about the exact exception message here?
   1444   if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) {
   1445     THROW_NEW_ERROR_RETURN_FAILURE(
   1446         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
   1447                               isolate->factory()->NewStringFromAsciiChecked(
   1448                                   "Array.prototype.concat")));
   1449   }
   1450   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1451       isolate, receiver, Object::ToObject(isolate, args.receiver()));
   1452   args[0] = *receiver;
   1453 
   1454   Handle<JSArray> result_array;
   1455 
   1456   // Avoid a real species read to avoid extra lookups to the array constructor
   1457   if (V8_LIKELY(receiver->IsJSArray() &&
   1458                 Handle<JSArray>::cast(receiver)->HasArrayPrototype(isolate) &&
   1459                 isolate->IsArraySpeciesLookupChainIntact())) {
   1460     if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) {
   1461       return *result_array;
   1462     }
   1463     if (isolate->has_pending_exception()) return isolate->heap()->exception();
   1464   }
   1465   // Reading @@species happens before anything else with a side effect, so
   1466   // we can do it here to determine whether to take the fast path.
   1467   Handle<Object> species;
   1468   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1469       isolate, species, Object::ArraySpeciesConstructor(isolate, receiver));
   1470   if (*species == *isolate->array_function()) {
   1471     if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) {
   1472       return *result_array;
   1473     }
   1474     if (isolate->has_pending_exception()) return isolate->heap()->exception();
   1475   }
   1476   return Slow_ArrayConcat(&args, species, isolate);
   1477 }
   1478 
   1479 
   1480 namespace {
   1481 
   1482 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to,
   1483                                        Handle<Object> next_source) {
   1484   // Non-empty strings are the only non-JSReceivers that need to be handled
   1485   // explicitly by Object.assign.
   1486   if (!next_source->IsJSReceiver()) {
   1487     return Just(!next_source->IsString() ||
   1488                 String::cast(*next_source)->length() == 0);
   1489   }
   1490 
   1491   // If the target is deprecated, the object will be updated on first store. If
   1492   // the source for that store equals the target, this will invalidate the
   1493   // cached representation of the source. Preventively upgrade the target.
   1494   // Do this on each iteration since any property load could cause deprecation.
   1495   if (to->map()->is_deprecated()) {
   1496     JSObject::MigrateInstance(Handle<JSObject>::cast(to));
   1497   }
   1498 
   1499   Isolate* isolate = to->GetIsolate();
   1500   Handle<Map> map(JSReceiver::cast(*next_source)->map(), isolate);
   1501 
   1502   if (!map->IsJSObjectMap()) return Just(false);
   1503   if (!map->OnlyHasSimpleProperties()) return Just(false);
   1504 
   1505   Handle<JSObject> from = Handle<JSObject>::cast(next_source);
   1506   if (from->elements() != isolate->heap()->empty_fixed_array()) {
   1507     return Just(false);
   1508   }
   1509 
   1510   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
   1511   int length = map->NumberOfOwnDescriptors();
   1512 
   1513   bool stable = true;
   1514 
   1515   for (int i = 0; i < length; i++) {
   1516     Handle<Name> next_key(descriptors->GetKey(i), isolate);
   1517     Handle<Object> prop_value;
   1518     // Directly decode from the descriptor array if |from| did not change shape.
   1519     if (stable) {
   1520       PropertyDetails details = descriptors->GetDetails(i);
   1521       if (!details.IsEnumerable()) continue;
   1522       if (details.kind() == kData) {
   1523         if (details.location() == kDescriptor) {
   1524           prop_value = handle(descriptors->GetValue(i), isolate);
   1525         } else {
   1526           Representation representation = details.representation();
   1527           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
   1528           prop_value = JSObject::FastPropertyAt(from, representation, index);
   1529         }
   1530       } else {
   1531         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1532             isolate, prop_value, JSReceiver::GetProperty(from, next_key),
   1533             Nothing<bool>());
   1534         stable = from->map() == *map;
   1535       }
   1536     } else {
   1537       // If the map did change, do a slower lookup. We are still guaranteed that
   1538       // the object has a simple shape, and that the key is a name.
   1539       LookupIterator it(from, next_key, from,
   1540                         LookupIterator::OWN_SKIP_INTERCEPTOR);
   1541       if (!it.IsFound()) continue;
   1542       DCHECK(it.state() == LookupIterator::DATA ||
   1543              it.state() == LookupIterator::ACCESSOR);
   1544       if (!it.IsEnumerable()) continue;
   1545       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1546           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
   1547     }
   1548     LookupIterator it(to, next_key, to);
   1549     bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA;
   1550     Maybe<bool> result = Object::SetProperty(
   1551         &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
   1552     if (result.IsNothing()) return result;
   1553     if (stable && call_to_js) stable = from->map() == *map;
   1554   }
   1555 
   1556   return Just(true);
   1557 }
   1558 
   1559 }  // namespace
   1560 
   1561 // ES6 19.1.2.1 Object.assign
   1562 BUILTIN(ObjectAssign) {
   1563   HandleScope scope(isolate);
   1564   Handle<Object> target = args.atOrUndefined(isolate, 1);
   1565 
   1566   // 1. Let to be ? ToObject(target).
   1567   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target,
   1568                                      Object::ToObject(isolate, target));
   1569   Handle<JSReceiver> to = Handle<JSReceiver>::cast(target);
   1570   // 2. If only one argument was passed, return to.
   1571   if (args.length() == 2) return *to;
   1572   // 3. Let sources be the List of argument values starting with the
   1573   //    second argument.
   1574   // 4. For each element nextSource of sources, in ascending index order,
   1575   for (int i = 2; i < args.length(); ++i) {
   1576     Handle<Object> next_source = args.at<Object>(i);
   1577     Maybe<bool> fast_assign = FastAssign(to, next_source);
   1578     if (fast_assign.IsNothing()) return isolate->heap()->exception();
   1579     if (fast_assign.FromJust()) continue;
   1580     // 4a. If nextSource is undefined or null, let keys be an empty List.
   1581     // 4b. Else,
   1582     // 4b i. Let from be ToObject(nextSource).
   1583     // Only non-empty strings and JSReceivers have enumerable properties.
   1584     Handle<JSReceiver> from =
   1585         Object::ToObject(isolate, next_source).ToHandleChecked();
   1586     // 4b ii. Let keys be ? from.[[OwnPropertyKeys]]().
   1587     Handle<FixedArray> keys;
   1588     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1589         isolate, keys, KeyAccumulator::GetKeys(
   1590                            from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
   1591                            GetKeysConversion::kKeepNumbers));
   1592     // 4c. Repeat for each element nextKey of keys in List order,
   1593     for (int j = 0; j < keys->length(); ++j) {
   1594       Handle<Object> next_key(keys->get(j), isolate);
   1595       // 4c i. Let desc be ? from.[[GetOwnProperty]](nextKey).
   1596       PropertyDescriptor desc;
   1597       Maybe<bool> found =
   1598           JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
   1599       if (found.IsNothing()) return isolate->heap()->exception();
   1600       // 4c ii. If desc is not undefined and desc.[[Enumerable]] is true, then
   1601       if (found.FromJust() && desc.enumerable()) {
   1602         // 4c ii 1. Let propValue be ? Get(from, nextKey).
   1603         Handle<Object> prop_value;
   1604         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1605             isolate, prop_value,
   1606             Runtime::GetObjectProperty(isolate, from, next_key));
   1607         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
   1608         Handle<Object> status;
   1609         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1610             isolate, status, Runtime::SetObjectProperty(isolate, to, next_key,
   1611                                                         prop_value, STRICT));
   1612       }
   1613     }
   1614   }
   1615   // 5. Return to.
   1616   return *to;
   1617 }
   1618 
   1619 
   1620 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
   1621 // TODO(verwaest): Support the common cases with precached map directly in
   1622 // an Object.create stub.
   1623 BUILTIN(ObjectCreate) {
   1624   HandleScope scope(isolate);
   1625   Handle<Object> prototype = args.atOrUndefined(isolate, 1);
   1626   if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
   1627     THROW_NEW_ERROR_RETURN_FAILURE(
   1628         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
   1629   }
   1630 
   1631   // Generate the map with the specified {prototype} based on the Object
   1632   // function's initial map from the current native context.
   1633   // TODO(bmeurer): Use a dedicated cache for Object.create; think about
   1634   // slack tracking for Object.create.
   1635   Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
   1636                   isolate);
   1637   if (map->prototype() != *prototype) {
   1638     if (prototype->IsNull(isolate)) {
   1639       map = isolate->object_with_null_prototype_map();
   1640     } else if (prototype->IsJSObject()) {
   1641       Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
   1642       if (!js_prototype->map()->is_prototype_map()) {
   1643         JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE);
   1644       }
   1645       Handle<PrototypeInfo> info =
   1646           Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
   1647       // TODO(verwaest): Use inobject slack tracking for this map.
   1648       if (info->HasObjectCreateMap()) {
   1649         map = handle(info->ObjectCreateMap(), isolate);
   1650       } else {
   1651         map = Map::CopyInitialMap(map);
   1652         Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
   1653         PrototypeInfo::SetObjectCreateMap(info, map);
   1654       }
   1655     } else {
   1656       map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
   1657     }
   1658   }
   1659 
   1660   // Actually allocate the object.
   1661   Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map);
   1662 
   1663   // Define the properties if properties was specified and is not undefined.
   1664   Handle<Object> properties = args.atOrUndefined(isolate, 2);
   1665   if (!properties->IsUndefined(isolate)) {
   1666     RETURN_FAILURE_ON_EXCEPTION(
   1667         isolate, JSReceiver::DefineProperties(isolate, object, properties));
   1668   }
   1669 
   1670   return *object;
   1671 }
   1672 
   1673 // ES6 section 19.1.2.3 Object.defineProperties
   1674 BUILTIN(ObjectDefineProperties) {
   1675   HandleScope scope(isolate);
   1676   DCHECK_EQ(3, args.length());
   1677   Handle<Object> target = args.at<Object>(1);
   1678   Handle<Object> properties = args.at<Object>(2);
   1679 
   1680   RETURN_RESULT_OR_FAILURE(
   1681       isolate, JSReceiver::DefineProperties(isolate, target, properties));
   1682 }
   1683 
   1684 // ES6 section 19.1.2.4 Object.defineProperty
   1685 BUILTIN(ObjectDefineProperty) {
   1686   HandleScope scope(isolate);
   1687   DCHECK_EQ(4, args.length());
   1688   Handle<Object> target = args.at<Object>(1);
   1689   Handle<Object> key = args.at<Object>(2);
   1690   Handle<Object> attributes = args.at<Object>(3);
   1691 
   1692   return JSReceiver::DefineProperty(isolate, target, key, attributes);
   1693 }
   1694 
   1695 namespace {
   1696 
   1697 template <AccessorComponent which_accessor>
   1698 Object* ObjectDefineAccessor(Isolate* isolate, Handle<Object> object,
   1699                              Handle<Object> name, Handle<Object> accessor) {
   1700   // 1. Let O be ? ToObject(this value).
   1701   Handle<JSReceiver> receiver;
   1702   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   1703                                      Object::ConvertReceiver(isolate, object));
   1704   // 2. If IsCallable(getter) is false, throw a TypeError exception.
   1705   if (!accessor->IsCallable()) {
   1706     MessageTemplate::Template message =
   1707         which_accessor == ACCESSOR_GETTER
   1708             ? MessageTemplate::kObjectGetterExpectingFunction
   1709             : MessageTemplate::kObjectSetterExpectingFunction;
   1710     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(message));
   1711   }
   1712   // 3. Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true,
   1713   //                                   [[Configurable]]: true}.
   1714   PropertyDescriptor desc;
   1715   if (which_accessor == ACCESSOR_GETTER) {
   1716     desc.set_get(accessor);
   1717   } else {
   1718     DCHECK(which_accessor == ACCESSOR_SETTER);
   1719     desc.set_set(accessor);
   1720   }
   1721   desc.set_enumerable(true);
   1722   desc.set_configurable(true);
   1723   // 4. Let key be ? ToPropertyKey(P).
   1724   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   1725                                      Object::ToPropertyKey(isolate, name));
   1726   // 5. Perform ? DefinePropertyOrThrow(O, key, desc).
   1727   // To preserve legacy behavior, we ignore errors silently rather than
   1728   // throwing an exception.
   1729   Maybe<bool> success = JSReceiver::DefineOwnProperty(
   1730       isolate, receiver, name, &desc, Object::DONT_THROW);
   1731   MAYBE_RETURN(success, isolate->heap()->exception());
   1732   if (!success.FromJust()) {
   1733     isolate->CountUsage(v8::Isolate::kDefineGetterOrSetterWouldThrow);
   1734   }
   1735   // 6. Return undefined.
   1736   return isolate->heap()->undefined_value();
   1737 }
   1738 
   1739 Object* ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
   1740                              Handle<Object> key, AccessorComponent component) {
   1741   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, object,
   1742                                      Object::ConvertReceiver(isolate, object));
   1743   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
   1744                                      Object::ToPropertyKey(isolate, key));
   1745   bool success = false;
   1746   LookupIterator it = LookupIterator::PropertyOrElement(
   1747       isolate, object, key, &success,
   1748       LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
   1749   DCHECK(success);
   1750 
   1751   for (; it.IsFound(); it.Next()) {
   1752     switch (it.state()) {
   1753       case LookupIterator::INTERCEPTOR:
   1754       case LookupIterator::NOT_FOUND:
   1755       case LookupIterator::TRANSITION:
   1756         UNREACHABLE();
   1757 
   1758       case LookupIterator::ACCESS_CHECK:
   1759         if (it.HasAccess()) continue;
   1760         isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
   1761         RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   1762         return isolate->heap()->undefined_value();
   1763 
   1764       case LookupIterator::JSPROXY:
   1765         return isolate->heap()->undefined_value();
   1766 
   1767       case LookupIterator::INTEGER_INDEXED_EXOTIC:
   1768         return isolate->heap()->undefined_value();
   1769       case LookupIterator::DATA:
   1770         continue;
   1771       case LookupIterator::ACCESSOR: {
   1772         Handle<Object> maybe_pair = it.GetAccessors();
   1773         if (maybe_pair->IsAccessorPair()) {
   1774           return *AccessorPair::GetComponent(
   1775               Handle<AccessorPair>::cast(maybe_pair), component);
   1776         }
   1777       }
   1778     }
   1779   }
   1780 
   1781   return isolate->heap()->undefined_value();
   1782 }
   1783 
   1784 }  // namespace
   1785 
   1786 // ES6 B.2.2.2 a.k.a.
   1787 // https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__
   1788 BUILTIN(ObjectDefineGetter) {
   1789   HandleScope scope(isolate);
   1790   Handle<Object> object = args.at<Object>(0);  // Receiver.
   1791   Handle<Object> name = args.at<Object>(1);
   1792   Handle<Object> getter = args.at<Object>(2);
   1793   return ObjectDefineAccessor<ACCESSOR_GETTER>(isolate, object, name, getter);
   1794 }
   1795 
   1796 // ES6 B.2.2.3 a.k.a.
   1797 // https://tc39.github.io/ecma262/#sec-object.prototype.__defineSetter__
   1798 BUILTIN(ObjectDefineSetter) {
   1799   HandleScope scope(isolate);
   1800   Handle<Object> object = args.at<Object>(0);  // Receiver.
   1801   Handle<Object> name = args.at<Object>(1);
   1802   Handle<Object> setter = args.at<Object>(2);
   1803   return ObjectDefineAccessor<ACCESSOR_SETTER>(isolate, object, name, setter);
   1804 }
   1805 
   1806 // ES6 B.2.2.4 a.k.a.
   1807 // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupGetter__
   1808 BUILTIN(ObjectLookupGetter) {
   1809   HandleScope scope(isolate);
   1810   Handle<Object> object = args.at<Object>(0);
   1811   Handle<Object> name = args.at<Object>(1);
   1812   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_GETTER);
   1813 }
   1814 
   1815 // ES6 B.2.2.5 a.k.a.
   1816 // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupSetter__
   1817 BUILTIN(ObjectLookupSetter) {
   1818   HandleScope scope(isolate);
   1819   Handle<Object> object = args.at<Object>(0);
   1820   Handle<Object> name = args.at<Object>(1);
   1821   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_SETTER);
   1822 }
   1823 
   1824 // ES6 section 19.1.2.5 Object.freeze ( O )
   1825 BUILTIN(ObjectFreeze) {
   1826   HandleScope scope(isolate);
   1827   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1828   if (object->IsJSReceiver()) {
   1829     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
   1830                                                FROZEN, Object::THROW_ON_ERROR),
   1831                  isolate->heap()->exception());
   1832   }
   1833   return *object;
   1834 }
   1835 
   1836 
   1837 // ES section 19.1.2.9 Object.getPrototypeOf ( O )
   1838 BUILTIN(ObjectGetPrototypeOf) {
   1839   HandleScope scope(isolate);
   1840   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1841 
   1842   Handle<JSReceiver> receiver;
   1843   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1844       isolate, receiver, Object::ToObject(isolate, object));
   1845 
   1846   RETURN_RESULT_OR_FAILURE(isolate,
   1847                            JSReceiver::GetPrototype(isolate, receiver));
   1848 }
   1849 
   1850 
   1851 // ES6 section 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
   1852 BUILTIN(ObjectGetOwnPropertyDescriptor) {
   1853   HandleScope scope(isolate);
   1854   // 1. Let obj be ? ToObject(O).
   1855   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1856   Handle<JSReceiver> receiver;
   1857   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   1858                                      Object::ToObject(isolate, object));
   1859   // 2. Let key be ? ToPropertyKey(P).
   1860   Handle<Object> property = args.atOrUndefined(isolate, 2);
   1861   Handle<Name> key;
   1862   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
   1863                                      Object::ToName(isolate, property));
   1864   // 3. Let desc be ? obj.[[GetOwnProperty]](key).
   1865   PropertyDescriptor desc;
   1866   Maybe<bool> found =
   1867       JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, key, &desc);
   1868   MAYBE_RETURN(found, isolate->heap()->exception());
   1869   // 4. Return FromPropertyDescriptor(desc).
   1870   if (!found.FromJust()) return isolate->heap()->undefined_value();
   1871   return *desc.ToObject(isolate);
   1872 }
   1873 
   1874 
   1875 namespace {
   1876 
   1877 Object* GetOwnPropertyKeys(Isolate* isolate, BuiltinArguments args,
   1878                            PropertyFilter filter) {
   1879   HandleScope scope(isolate);
   1880   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1881   Handle<JSReceiver> receiver;
   1882   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   1883                                      Object::ToObject(isolate, object));
   1884   Handle<FixedArray> keys;
   1885   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1886       isolate, keys,
   1887       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
   1888                               GetKeysConversion::kConvertToString));
   1889   return *isolate->factory()->NewJSArrayWithElements(keys);
   1890 }
   1891 
   1892 }  // namespace
   1893 
   1894 
   1895 // ES6 section 19.1.2.7 Object.getOwnPropertyNames ( O )
   1896 BUILTIN(ObjectGetOwnPropertyNames) {
   1897   return GetOwnPropertyKeys(isolate, args, SKIP_SYMBOLS);
   1898 }
   1899 
   1900 
   1901 // ES6 section 19.1.2.8 Object.getOwnPropertySymbols ( O )
   1902 BUILTIN(ObjectGetOwnPropertySymbols) {
   1903   return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS);
   1904 }
   1905 
   1906 
   1907 // ES#sec-object.is Object.is ( value1, value2 )
   1908 BUILTIN(ObjectIs) {
   1909   SealHandleScope shs(isolate);
   1910   DCHECK_EQ(3, args.length());
   1911   Handle<Object> value1 = args.at<Object>(1);
   1912   Handle<Object> value2 = args.at<Object>(2);
   1913   return isolate->heap()->ToBoolean(value1->SameValue(*value2));
   1914 }
   1915 
   1916 
   1917 // ES6 section 19.1.2.11 Object.isExtensible ( O )
   1918 BUILTIN(ObjectIsExtensible) {
   1919   HandleScope scope(isolate);
   1920   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1921   Maybe<bool> result =
   1922       object->IsJSReceiver()
   1923           ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
   1924           : Just(false);
   1925   MAYBE_RETURN(result, isolate->heap()->exception());
   1926   return isolate->heap()->ToBoolean(result.FromJust());
   1927 }
   1928 
   1929 
   1930 // ES6 section 19.1.2.12 Object.isFrozen ( O )
   1931 BUILTIN(ObjectIsFrozen) {
   1932   HandleScope scope(isolate);
   1933   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1934   Maybe<bool> result = object->IsJSReceiver()
   1935                            ? JSReceiver::TestIntegrityLevel(
   1936                                  Handle<JSReceiver>::cast(object), FROZEN)
   1937                            : Just(true);
   1938   MAYBE_RETURN(result, isolate->heap()->exception());
   1939   return isolate->heap()->ToBoolean(result.FromJust());
   1940 }
   1941 
   1942 
   1943 // ES6 section 19.1.2.13 Object.isSealed ( O )
   1944 BUILTIN(ObjectIsSealed) {
   1945   HandleScope scope(isolate);
   1946   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1947   Maybe<bool> result = object->IsJSReceiver()
   1948                            ? JSReceiver::TestIntegrityLevel(
   1949                                  Handle<JSReceiver>::cast(object), SEALED)
   1950                            : Just(true);
   1951   MAYBE_RETURN(result, isolate->heap()->exception());
   1952   return isolate->heap()->ToBoolean(result.FromJust());
   1953 }
   1954 
   1955 
   1956 // ES6 section 19.1.2.14 Object.keys ( O )
   1957 BUILTIN(ObjectKeys) {
   1958   HandleScope scope(isolate);
   1959   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1960   Handle<JSReceiver> receiver;
   1961   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   1962                                      Object::ToObject(isolate, object));
   1963 
   1964   Handle<FixedArray> keys;
   1965   int enum_length = receiver->map()->EnumLength();
   1966   if (enum_length != kInvalidEnumCacheSentinel &&
   1967       JSObject::cast(*receiver)->elements() ==
   1968           isolate->heap()->empty_fixed_array()) {
   1969     DCHECK(receiver->IsJSObject());
   1970     DCHECK(!JSObject::cast(*receiver)->HasNamedInterceptor());
   1971     DCHECK(!JSObject::cast(*receiver)->IsAccessCheckNeeded());
   1972     DCHECK(!receiver->map()->has_hidden_prototype());
   1973     DCHECK(JSObject::cast(*receiver)->HasFastProperties());
   1974     if (enum_length == 0) {
   1975       keys = isolate->factory()->empty_fixed_array();
   1976     } else {
   1977       Handle<FixedArray> cache(
   1978           receiver->map()->instance_descriptors()->GetEnumCache());
   1979       keys = isolate->factory()->CopyFixedArrayUpTo(cache, enum_length);
   1980     }
   1981   } else {
   1982     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1983         isolate, keys,
   1984         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
   1985                                 ENUMERABLE_STRINGS,
   1986                                 GetKeysConversion::kConvertToString));
   1987   }
   1988   return *isolate->factory()->NewJSArrayWithElements(keys, FAST_ELEMENTS);
   1989 }
   1990 
   1991 BUILTIN(ObjectValues) {
   1992   HandleScope scope(isolate);
   1993   Handle<Object> object = args.atOrUndefined(isolate, 1);
   1994   Handle<JSReceiver> receiver;
   1995   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   1996                                      Object::ToObject(isolate, object));
   1997   Handle<FixedArray> values;
   1998   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1999       isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS));
   2000   return *isolate->factory()->NewJSArrayWithElements(values);
   2001 }
   2002 
   2003 
   2004 BUILTIN(ObjectEntries) {
   2005   HandleScope scope(isolate);
   2006   Handle<Object> object = args.atOrUndefined(isolate, 1);
   2007   Handle<JSReceiver> receiver;
   2008   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   2009                                      Object::ToObject(isolate, object));
   2010   Handle<FixedArray> entries;
   2011   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2012       isolate, entries,
   2013       JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS));
   2014   return *isolate->factory()->NewJSArrayWithElements(entries);
   2015 }
   2016 
   2017 BUILTIN(ObjectGetOwnPropertyDescriptors) {
   2018   HandleScope scope(isolate);
   2019   Handle<Object> object = args.atOrUndefined(isolate, 1);
   2020   Handle<Object> undefined = isolate->factory()->undefined_value();
   2021 
   2022   Handle<JSReceiver> receiver;
   2023   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
   2024                                      Object::ToObject(isolate, object));
   2025 
   2026   Handle<FixedArray> keys;
   2027   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2028       isolate, keys, KeyAccumulator::GetKeys(
   2029                          receiver, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
   2030                          GetKeysConversion::kConvertToString));
   2031 
   2032   Handle<JSObject> descriptors =
   2033       isolate->factory()->NewJSObject(isolate->object_function());
   2034 
   2035   for (int i = 0; i < keys->length(); ++i) {
   2036     Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate));
   2037     PropertyDescriptor descriptor;
   2038     Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
   2039         isolate, receiver, key, &descriptor);
   2040     MAYBE_RETURN(did_get_descriptor, isolate->heap()->exception());
   2041 
   2042     Handle<Object> from_descriptor = did_get_descriptor.FromJust()
   2043                                          ? descriptor.ToObject(isolate)
   2044                                          : undefined;
   2045 
   2046     LookupIterator it = LookupIterator::PropertyOrElement(
   2047         isolate, descriptors, key, descriptors, LookupIterator::OWN);
   2048     Maybe<bool> success = JSReceiver::CreateDataProperty(&it, from_descriptor,
   2049                                                          Object::DONT_THROW);
   2050     CHECK(success.FromJust());
   2051   }
   2052 
   2053   return *descriptors;
   2054 }
   2055 
   2056 // ES6 section 19.1.2.15 Object.preventExtensions ( O )
   2057 BUILTIN(ObjectPreventExtensions) {
   2058   HandleScope scope(isolate);
   2059   Handle<Object> object = args.atOrUndefined(isolate, 1);
   2060   if (object->IsJSReceiver()) {
   2061     MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
   2062                                                Object::THROW_ON_ERROR),
   2063                  isolate->heap()->exception());
   2064   }
   2065   return *object;
   2066 }
   2067 
   2068 
   2069 // ES6 section 19.1.2.17 Object.seal ( O )
   2070 BUILTIN(ObjectSeal) {
   2071   HandleScope scope(isolate);
   2072   Handle<Object> object = args.atOrUndefined(isolate, 1);
   2073   if (object->IsJSReceiver()) {
   2074     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
   2075                                                SEALED, Object::THROW_ON_ERROR),
   2076                  isolate->heap()->exception());
   2077   }
   2078   return *object;
   2079 }
   2080 
   2081 // ES6 section 18.2.6.2 decodeURI (encodedURI)
   2082 BUILTIN(GlobalDecodeURI) {
   2083   HandleScope scope(isolate);
   2084   Handle<String> encoded_uri;
   2085   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2086       isolate, encoded_uri,
   2087       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   2088 
   2089   RETURN_RESULT_OR_FAILURE(isolate, Uri::DecodeUri(isolate, encoded_uri));
   2090 }
   2091 
   2092 // ES6 section 18.2.6.3 decodeURIComponent (encodedURIComponent)
   2093 BUILTIN(GlobalDecodeURIComponent) {
   2094   HandleScope scope(isolate);
   2095   Handle<String> encoded_uri_component;
   2096   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2097       isolate, encoded_uri_component,
   2098       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   2099 
   2100   RETURN_RESULT_OR_FAILURE(
   2101       isolate, Uri::DecodeUriComponent(isolate, encoded_uri_component));
   2102 }
   2103 
   2104 // ES6 section 18.2.6.4 encodeURI (uri)
   2105 BUILTIN(GlobalEncodeURI) {
   2106   HandleScope scope(isolate);
   2107   Handle<String> uri;
   2108   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2109       isolate, uri, Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   2110 
   2111   RETURN_RESULT_OR_FAILURE(isolate, Uri::EncodeUri(isolate, uri));
   2112 }
   2113 
   2114 // ES6 section 18.2.6.5 encodeURIComponenet (uriComponent)
   2115 BUILTIN(GlobalEncodeURIComponent) {
   2116   HandleScope scope(isolate);
   2117   Handle<String> uri_component;
   2118   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2119       isolate, uri_component,
   2120       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   2121 
   2122   RETURN_RESULT_OR_FAILURE(isolate,
   2123                            Uri::EncodeUriComponent(isolate, uri_component));
   2124 }
   2125 
   2126 // ES6 section B.2.1.1 escape (string)
   2127 BUILTIN(GlobalEscape) {
   2128   HandleScope scope(isolate);
   2129   Handle<String> string;
   2130   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2131       isolate, string,
   2132       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   2133 
   2134   RETURN_RESULT_OR_FAILURE(isolate, Uri::Escape(isolate, string));
   2135 }
   2136 
   2137 // ES6 section B.2.1.2 unescape (string)
   2138 BUILTIN(GlobalUnescape) {
   2139   HandleScope scope(isolate);
   2140   Handle<String> string;
   2141   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2142       isolate, string,
   2143       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   2144 
   2145   RETURN_RESULT_OR_FAILURE(isolate, Uri::Unescape(isolate, string));
   2146 }
   2147 
   2148 namespace {
   2149 
   2150 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   2151                                       Handle<Context> context) {
   2152   DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate));
   2153   // Check with callback if set.
   2154   AllowCodeGenerationFromStringsCallback callback =
   2155       isolate->allow_code_gen_callback();
   2156   if (callback == NULL) {
   2157     // No callback set and code generation disallowed.
   2158     return false;
   2159   } else {
   2160     // Callback set. Let it decide if code generation is allowed.
   2161     VMState<EXTERNAL> state(isolate);
   2162     return callback(v8::Utils::ToLocal(context));
   2163   }
   2164 }
   2165 
   2166 
   2167 MaybeHandle<JSFunction> CompileString(Handle<Context> context,
   2168                                       Handle<String> source,
   2169                                       ParseRestriction restriction) {
   2170   Isolate* const isolate = context->GetIsolate();
   2171   Handle<Context> native_context(context->native_context(), isolate);
   2172 
   2173   // Check if native context allows code generation from
   2174   // strings. Throw an exception if it doesn't.
   2175   if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) &&
   2176       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
   2177     Handle<Object> error_message =
   2178         native_context->ErrorMessageForCodeGenerationFromStrings();
   2179     THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings,
   2180                                           error_message),
   2181                     JSFunction);
   2182   }
   2183 
   2184   // Compile source string in the native context.
   2185   int eval_scope_position = 0;
   2186   int eval_position = RelocInfo::kNoPosition;
   2187   Handle<SharedFunctionInfo> outer_info(native_context->closure()->shared());
   2188   return Compiler::GetFunctionFromEval(source, outer_info, native_context,
   2189                                        SLOPPY, restriction, eval_scope_position,
   2190                                        eval_position);
   2191 }
   2192 
   2193 }  // namespace
   2194 
   2195 
   2196 // ES6 section 18.2.1 eval (x)
   2197 BUILTIN(GlobalEval) {
   2198   HandleScope scope(isolate);
   2199   Handle<Object> x = args.atOrUndefined(isolate, 1);
   2200   Handle<JSFunction> target = args.target<JSFunction>();
   2201   Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
   2202   if (!x->IsString()) return *x;
   2203   Handle<JSFunction> function;
   2204   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2205       isolate, function,
   2206       CompileString(handle(target->native_context(), isolate),
   2207                     Handle<String>::cast(x), NO_PARSE_RESTRICTION));
   2208   RETURN_RESULT_OR_FAILURE(
   2209       isolate,
   2210       Execution::Call(isolate, function, target_global_proxy, 0, nullptr));
   2211 }
   2212 
   2213 // ES6 section 24.3.1 JSON.parse.
   2214 BUILTIN(JsonParse) {
   2215   HandleScope scope(isolate);
   2216   Handle<Object> source = args.atOrUndefined(isolate, 1);
   2217   Handle<Object> reviver = args.atOrUndefined(isolate, 2);
   2218   Handle<String> string;
   2219   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
   2220                                      Object::ToString(isolate, source));
   2221   string = String::Flatten(string);
   2222   RETURN_RESULT_OR_FAILURE(
   2223       isolate, string->IsSeqOneByteString()
   2224                    ? JsonParser<true>::Parse(isolate, string, reviver)
   2225                    : JsonParser<false>::Parse(isolate, string, reviver));
   2226 }
   2227 
   2228 // ES6 section 24.3.2 JSON.stringify.
   2229 BUILTIN(JsonStringify) {
   2230   HandleScope scope(isolate);
   2231   JsonStringifier stringifier(isolate);
   2232   Handle<Object> object = args.atOrUndefined(isolate, 1);
   2233   Handle<Object> replacer = args.atOrUndefined(isolate, 2);
   2234   Handle<Object> indent = args.atOrUndefined(isolate, 3);
   2235   RETURN_RESULT_OR_FAILURE(isolate,
   2236                            stringifier.Stringify(object, replacer, indent));
   2237 }
   2238 
   2239 // -----------------------------------------------------------------------------
   2240 // ES6 section 20.2.2 Function Properties of the Math Object
   2241 
   2242 
   2243 // ES6 section 20.2.2.2 Math.acos ( x )
   2244 BUILTIN(MathAcos) {
   2245   HandleScope scope(isolate);
   2246   DCHECK_EQ(2, args.length());
   2247   Handle<Object> x = args.at<Object>(1);
   2248   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
   2249   return *isolate->factory()->NewHeapNumber(std::acos(x->Number()));
   2250 }
   2251 
   2252 
   2253 // ES6 section 20.2.2.4 Math.asin ( x )
   2254 BUILTIN(MathAsin) {
   2255   HandleScope scope(isolate);
   2256   DCHECK_EQ(2, args.length());
   2257   Handle<Object> x = args.at<Object>(1);
   2258   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
   2259   return *isolate->factory()->NewHeapNumber(std::asin(x->Number()));
   2260 }
   2261 
   2262 // ES6 section 20.2.2.6 Math.atan ( x )
   2263 void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) {
   2264   using compiler::Node;
   2265 
   2266   Node* x = assembler->Parameter(1);
   2267   Node* context = assembler->Parameter(4);
   2268   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2269   Node* value = assembler->Float64Atan(x_value);
   2270   Node* result = assembler->ChangeFloat64ToTagged(value);
   2271   assembler->Return(result);
   2272 }
   2273 
   2274 // ES6 section 20.2.2.8 Math.atan2 ( y, x )
   2275 void Builtins::Generate_MathAtan2(CodeStubAssembler* assembler) {
   2276   using compiler::Node;
   2277 
   2278   Node* y = assembler->Parameter(1);
   2279   Node* x = assembler->Parameter(2);
   2280   Node* context = assembler->Parameter(5);
   2281   Node* y_value = assembler->TruncateTaggedToFloat64(context, y);
   2282   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2283   Node* value = assembler->Float64Atan2(y_value, x_value);
   2284   Node* result = assembler->ChangeFloat64ToTagged(value);
   2285   assembler->Return(result);
   2286 }
   2287 
   2288 // ES6 section 20.2.2.7 Math.atanh ( x )
   2289 void Builtins::Generate_MathAtanh(CodeStubAssembler* assembler) {
   2290   using compiler::Node;
   2291 
   2292   Node* x = assembler->Parameter(1);
   2293   Node* context = assembler->Parameter(4);
   2294   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2295   Node* value = assembler->Float64Atanh(x_value);
   2296   Node* result = assembler->ChangeFloat64ToTagged(value);
   2297   assembler->Return(result);
   2298 }
   2299 
   2300 namespace {
   2301 
   2302 void Generate_MathRoundingOperation(
   2303     CodeStubAssembler* assembler,
   2304     compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) {
   2305   typedef CodeStubAssembler::Label Label;
   2306   typedef compiler::Node Node;
   2307   typedef CodeStubAssembler::Variable Variable;
   2308 
   2309   Node* context = assembler->Parameter(4);
   2310 
   2311   // We might need to loop once for ToNumber conversion.
   2312   Variable var_x(assembler, MachineRepresentation::kTagged);
   2313   Label loop(assembler, &var_x);
   2314   var_x.Bind(assembler->Parameter(1));
   2315   assembler->Goto(&loop);
   2316   assembler->Bind(&loop);
   2317   {
   2318     // Load the current {x} value.
   2319     Node* x = var_x.value();
   2320 
   2321     // Check if {x} is a Smi or a HeapObject.
   2322     Label if_xissmi(assembler), if_xisnotsmi(assembler);
   2323     assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi);
   2324 
   2325     assembler->Bind(&if_xissmi);
   2326     {
   2327       // Nothing to do when {x} is a Smi.
   2328       assembler->Return(x);
   2329     }
   2330 
   2331     assembler->Bind(&if_xisnotsmi);
   2332     {
   2333       // Check if {x} is a HeapNumber.
   2334       Label if_xisheapnumber(assembler),
   2335           if_xisnotheapnumber(assembler, Label::kDeferred);
   2336       assembler->Branch(
   2337           assembler->WordEqual(assembler->LoadMap(x),
   2338                                assembler->HeapNumberMapConstant()),
   2339           &if_xisheapnumber, &if_xisnotheapnumber);
   2340 
   2341       assembler->Bind(&if_xisheapnumber);
   2342       {
   2343         Node* x_value = assembler->LoadHeapNumberValue(x);
   2344         Node* value = (assembler->*float64op)(x_value);
   2345         Node* result = assembler->ChangeFloat64ToTagged(value);
   2346         assembler->Return(result);
   2347       }
   2348 
   2349       assembler->Bind(&if_xisnotheapnumber);
   2350       {
   2351         // Need to convert {x} to a Number first.
   2352         Callable callable =
   2353             CodeFactory::NonNumberToNumber(assembler->isolate());
   2354         var_x.Bind(assembler->CallStub(callable, context, x));
   2355         assembler->Goto(&loop);
   2356       }
   2357     }
   2358   }
   2359 }
   2360 
   2361 }  // namespace
   2362 
   2363 // ES6 section 20.2.2.10 Math.ceil ( x )
   2364 void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) {
   2365   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Ceil);
   2366 }
   2367 
   2368 // ES6 section 20.2.2.9 Math.cbrt ( x )
   2369 void Builtins::Generate_MathCbrt(CodeStubAssembler* assembler) {
   2370   using compiler::Node;
   2371 
   2372   Node* x = assembler->Parameter(1);
   2373   Node* context = assembler->Parameter(4);
   2374   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2375   Node* value = assembler->Float64Cbrt(x_value);
   2376   Node* result = assembler->ChangeFloat64ToTagged(value);
   2377   assembler->Return(result);
   2378 }
   2379 
   2380 // ES6 section 20.2.2.11 Math.clz32 ( x )
   2381 void Builtins::Generate_MathClz32(CodeStubAssembler* assembler) {
   2382   typedef CodeStubAssembler::Label Label;
   2383   typedef compiler::Node Node;
   2384   typedef CodeStubAssembler::Variable Variable;
   2385 
   2386   Node* context = assembler->Parameter(4);
   2387 
   2388   // Shared entry point for the clz32 operation.
   2389   Variable var_clz32_x(assembler, MachineRepresentation::kWord32);
   2390   Label do_clz32(assembler);
   2391 
   2392   // We might need to loop once for ToNumber conversion.
   2393   Variable var_x(assembler, MachineRepresentation::kTagged);
   2394   Label loop(assembler, &var_x);
   2395   var_x.Bind(assembler->Parameter(1));
   2396   assembler->Goto(&loop);
   2397   assembler->Bind(&loop);
   2398   {
   2399     // Load the current {x} value.
   2400     Node* x = var_x.value();
   2401 
   2402     // Check if {x} is a Smi or a HeapObject.
   2403     Label if_xissmi(assembler), if_xisnotsmi(assembler);
   2404     assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi);
   2405 
   2406     assembler->Bind(&if_xissmi);
   2407     {
   2408       var_clz32_x.Bind(assembler->SmiToWord32(x));
   2409       assembler->Goto(&do_clz32);
   2410     }
   2411 
   2412     assembler->Bind(&if_xisnotsmi);
   2413     {
   2414       // Check if {x} is a HeapNumber.
   2415       Label if_xisheapnumber(assembler),
   2416           if_xisnotheapnumber(assembler, Label::kDeferred);
   2417       assembler->Branch(
   2418           assembler->WordEqual(assembler->LoadMap(x),
   2419                                assembler->HeapNumberMapConstant()),
   2420           &if_xisheapnumber, &if_xisnotheapnumber);
   2421 
   2422       assembler->Bind(&if_xisheapnumber);
   2423       {
   2424         var_clz32_x.Bind(assembler->TruncateHeapNumberValueToWord32(x));
   2425         assembler->Goto(&do_clz32);
   2426       }
   2427 
   2428       assembler->Bind(&if_xisnotheapnumber);
   2429       {
   2430         // Need to convert {x} to a Number first.
   2431         Callable callable =
   2432             CodeFactory::NonNumberToNumber(assembler->isolate());
   2433         var_x.Bind(assembler->CallStub(callable, context, x));
   2434         assembler->Goto(&loop);
   2435       }
   2436     }
   2437   }
   2438 
   2439   assembler->Bind(&do_clz32);
   2440   {
   2441     Node* x_value = var_clz32_x.value();
   2442     Node* value = assembler->Word32Clz(x_value);
   2443     Node* result = assembler->ChangeInt32ToTagged(value);
   2444     assembler->Return(result);
   2445   }
   2446 }
   2447 
   2448 // ES6 section 20.2.2.12 Math.cos ( x )
   2449 void Builtins::Generate_MathCos(CodeStubAssembler* assembler) {
   2450   using compiler::Node;
   2451 
   2452   Node* x = assembler->Parameter(1);
   2453   Node* context = assembler->Parameter(4);
   2454   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2455   Node* value = assembler->Float64Cos(x_value);
   2456   Node* result = assembler->ChangeFloat64ToTagged(value);
   2457   assembler->Return(result);
   2458 }
   2459 
   2460 // ES6 section 20.2.2.14 Math.exp ( x )
   2461 void Builtins::Generate_MathExp(CodeStubAssembler* assembler) {
   2462   using compiler::Node;
   2463 
   2464   Node* x = assembler->Parameter(1);
   2465   Node* context = assembler->Parameter(4);
   2466   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2467   Node* value = assembler->Float64Exp(x_value);
   2468   Node* result = assembler->ChangeFloat64ToTagged(value);
   2469   assembler->Return(result);
   2470 }
   2471 
   2472 // ES6 section 20.2.2.16 Math.floor ( x )
   2473 void Builtins::Generate_MathFloor(CodeStubAssembler* assembler) {
   2474   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Floor);
   2475 }
   2476 
   2477 // ES6 section 20.2.2.17 Math.fround ( x )
   2478 BUILTIN(MathFround) {
   2479   HandleScope scope(isolate);
   2480   DCHECK_EQ(2, args.length());
   2481   Handle<Object> x = args.at<Object>(1);
   2482   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
   2483   float x32 = DoubleToFloat32(x->Number());
   2484   return *isolate->factory()->NewNumber(x32);
   2485 }
   2486 
   2487 // ES6 section 20.2.2.19 Math.imul ( x, y )
   2488 BUILTIN(MathImul) {
   2489   HandleScope scope(isolate);
   2490   DCHECK_EQ(3, args.length());
   2491   Handle<Object> x = args.at<Object>(1);
   2492   Handle<Object> y = args.at<Object>(2);
   2493   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
   2494   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, y, Object::ToNumber(y));
   2495   int product = static_cast<int>(NumberToUint32(*x) * NumberToUint32(*y));
   2496   return *isolate->factory()->NewNumberFromInt(product);
   2497 }
   2498 
   2499 // ES6 section 20.2.2.20 Math.log ( x )
   2500 void Builtins::Generate_MathLog(CodeStubAssembler* assembler) {
   2501   using compiler::Node;
   2502 
   2503   Node* x = assembler->Parameter(1);
   2504   Node* context = assembler->Parameter(4);
   2505   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2506   Node* value = assembler->Float64Log(x_value);
   2507   Node* result = assembler->ChangeFloat64ToTagged(value);
   2508   assembler->Return(result);
   2509 }
   2510 
   2511 // ES6 section 20.2.2.21 Math.log1p ( x )
   2512 void Builtins::Generate_MathLog1p(CodeStubAssembler* assembler) {
   2513   using compiler::Node;
   2514 
   2515   Node* x = assembler->Parameter(1);
   2516   Node* context = assembler->Parameter(4);
   2517   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2518   Node* value = assembler->Float64Log1p(x_value);
   2519   Node* result = assembler->ChangeFloat64ToTagged(value);
   2520   assembler->Return(result);
   2521 }
   2522 
   2523 // ES6 section 20.2.2.23 Math.log2 ( x )
   2524 void Builtins::Generate_MathLog2(CodeStubAssembler* assembler) {
   2525   using compiler::Node;
   2526 
   2527   Node* x = assembler->Parameter(1);
   2528   Node* context = assembler->Parameter(4);
   2529   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2530   Node* value = assembler->Float64Log2(x_value);
   2531   Node* result = assembler->ChangeFloat64ToTagged(value);
   2532   assembler->Return(result);
   2533 }
   2534 
   2535 // ES6 section 20.2.2.22 Math.log10 ( x )
   2536 void Builtins::Generate_MathLog10(CodeStubAssembler* assembler) {
   2537   using compiler::Node;
   2538 
   2539   Node* x = assembler->Parameter(1);
   2540   Node* context = assembler->Parameter(4);
   2541   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2542   Node* value = assembler->Float64Log10(x_value);
   2543   Node* result = assembler->ChangeFloat64ToTagged(value);
   2544   assembler->Return(result);
   2545 }
   2546 
   2547 // ES6 section 20.2.2.15 Math.expm1 ( x )
   2548 void Builtins::Generate_MathExpm1(CodeStubAssembler* assembler) {
   2549   using compiler::Node;
   2550 
   2551   Node* x = assembler->Parameter(1);
   2552   Node* context = assembler->Parameter(4);
   2553   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2554   Node* value = assembler->Float64Expm1(x_value);
   2555   Node* result = assembler->ChangeFloat64ToTagged(value);
   2556   assembler->Return(result);
   2557 }
   2558 
   2559 // ES6 section 20.2.2.28 Math.round ( x )
   2560 void Builtins::Generate_MathRound(CodeStubAssembler* assembler) {
   2561   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Round);
   2562 }
   2563 
   2564 // ES6 section 20.2.2.30 Math.sin ( x )
   2565 void Builtins::Generate_MathSin(CodeStubAssembler* assembler) {
   2566   using compiler::Node;
   2567 
   2568   Node* x = assembler->Parameter(1);
   2569   Node* context = assembler->Parameter(4);
   2570   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2571   Node* value = assembler->Float64Sin(x_value);
   2572   Node* result = assembler->ChangeFloat64ToTagged(value);
   2573   assembler->Return(result);
   2574 }
   2575 
   2576 // ES6 section 20.2.2.32 Math.sqrt ( x )
   2577 void Builtins::Generate_MathSqrt(CodeStubAssembler* assembler) {
   2578   using compiler::Node;
   2579 
   2580   Node* x = assembler->Parameter(1);
   2581   Node* context = assembler->Parameter(4);
   2582   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2583   Node* value = assembler->Float64Sqrt(x_value);
   2584   Node* result = assembler->ChangeFloat64ToTagged(value);
   2585   assembler->Return(result);
   2586 }
   2587 
   2588 // ES6 section 20.2.2.33 Math.tan ( x )
   2589 void Builtins::Generate_MathTan(CodeStubAssembler* assembler) {
   2590   using compiler::Node;
   2591 
   2592   Node* x = assembler->Parameter(1);
   2593   Node* context = assembler->Parameter(4);
   2594   Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
   2595   Node* value = assembler->Float64Tan(x_value);
   2596   Node* result = assembler->ChangeFloat64ToTagged(value);
   2597   assembler->Return(result);
   2598 }
   2599 
   2600 // ES6 section 20.2.2.35 Math.trunc ( x )
   2601 void Builtins::Generate_MathTrunc(CodeStubAssembler* assembler) {
   2602   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Trunc);
   2603 }
   2604 
   2605 // -----------------------------------------------------------------------------
   2606 // ES6 section 19.2 Function Objects
   2607 
   2608 // ES6 section 19.2.3.6 Function.prototype [ @@hasInstance ] ( V )
   2609 void Builtins::Generate_FunctionPrototypeHasInstance(
   2610     CodeStubAssembler* assembler) {
   2611   using compiler::Node;
   2612 
   2613   Node* f = assembler->Parameter(0);
   2614   Node* v = assembler->Parameter(1);
   2615   Node* context = assembler->Parameter(4);
   2616   Node* result = assembler->OrdinaryHasInstance(context, f, v);
   2617   assembler->Return(result);
   2618 }
   2619 
   2620 // -----------------------------------------------------------------------------
   2621 // ES6 section 25.3 Generator Objects
   2622 
   2623 namespace {
   2624 
   2625 void Generate_GeneratorPrototypeResume(
   2626     CodeStubAssembler* assembler, JSGeneratorObject::ResumeMode resume_mode,
   2627     char const* const method_name) {
   2628   typedef CodeStubAssembler::Label Label;
   2629   typedef compiler::Node Node;
   2630 
   2631   Node* receiver = assembler->Parameter(0);
   2632   Node* value = assembler->Parameter(1);
   2633   Node* context = assembler->Parameter(4);
   2634   Node* closed = assembler->SmiConstant(
   2635       Smi::FromInt(JSGeneratorObject::kGeneratorClosed));
   2636 
   2637   // Check if the {receiver} is actually a JSGeneratorObject.
   2638   Label if_receiverisincompatible(assembler, Label::kDeferred);
   2639   assembler->GotoIf(assembler->WordIsSmi(receiver), &if_receiverisincompatible);
   2640   Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
   2641   assembler->GotoUnless(assembler->Word32Equal(
   2642                             receiver_instance_type,
   2643                             assembler->Int32Constant(JS_GENERATOR_OBJECT_TYPE)),
   2644                         &if_receiverisincompatible);
   2645 
   2646   // Check if the {receiver} is running or already closed.
   2647   Node* receiver_continuation = assembler->LoadObjectField(
   2648       receiver, JSGeneratorObject::kContinuationOffset);
   2649   Label if_receiverisclosed(assembler, Label::kDeferred),
   2650       if_receiverisrunning(assembler, Label::kDeferred);
   2651   assembler->GotoIf(assembler->SmiEqual(receiver_continuation, closed),
   2652                     &if_receiverisclosed);
   2653   DCHECK_LT(JSGeneratorObject::kGeneratorExecuting,
   2654             JSGeneratorObject::kGeneratorClosed);
   2655   assembler->GotoIf(assembler->SmiLessThan(receiver_continuation, closed),
   2656                     &if_receiverisrunning);
   2657 
   2658   // Resume the {receiver} using our trampoline.
   2659   Node* result = assembler->CallStub(
   2660       CodeFactory::ResumeGenerator(assembler->isolate()), context, value,
   2661       receiver, assembler->SmiConstant(Smi::FromInt(resume_mode)));
   2662   assembler->Return(result);
   2663 
   2664   assembler->Bind(&if_receiverisincompatible);
   2665   {
   2666     // The {receiver} is not a valid JSGeneratorObject.
   2667     Node* result = assembler->CallRuntime(
   2668         Runtime::kThrowIncompatibleMethodReceiver, context,
   2669         assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
   2670             method_name, TENURED)),
   2671         receiver);
   2672     assembler->Return(result);  // Never reached.
   2673   }
   2674 
   2675   assembler->Bind(&if_receiverisclosed);
   2676   {
   2677     // The {receiver} is closed already.
   2678     Node* result = nullptr;
   2679     switch (resume_mode) {
   2680       case JSGeneratorObject::kNext:
   2681         result = assembler->CallRuntime(Runtime::kCreateIterResultObject,
   2682                                         context, assembler->UndefinedConstant(),
   2683                                         assembler->BooleanConstant(true));
   2684         break;
   2685       case JSGeneratorObject::kReturn:
   2686         result =
   2687             assembler->CallRuntime(Runtime::kCreateIterResultObject, context,
   2688                                    value, assembler->BooleanConstant(true));
   2689         break;
   2690       case JSGeneratorObject::kThrow:
   2691         result = assembler->CallRuntime(Runtime::kThrow, context, value);
   2692         break;
   2693     }
   2694     assembler->Return(result);
   2695   }
   2696 
   2697   assembler->Bind(&if_receiverisrunning);
   2698   {
   2699     Node* result =
   2700         assembler->CallRuntime(Runtime::kThrowGeneratorRunning, context);
   2701     assembler->Return(result);  // Never reached.
   2702   }
   2703 }
   2704 
   2705 }  // namespace
   2706 
   2707 // ES6 section 25.3.1.2 Generator.prototype.next ( value )
   2708 void Builtins::Generate_GeneratorPrototypeNext(CodeStubAssembler* assembler) {
   2709   Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kNext,
   2710                                     "[Generator].prototype.next");
   2711 }
   2712 
   2713 // ES6 section 25.3.1.3 Generator.prototype.return ( value )
   2714 void Builtins::Generate_GeneratorPrototypeReturn(CodeStubAssembler* assembler) {
   2715   Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kReturn,
   2716                                     "[Generator].prototype.return");
   2717 }
   2718 
   2719 // ES6 section 25.3.1.4 Generator.prototype.throw ( exception )
   2720 void Builtins::Generate_GeneratorPrototypeThrow(CodeStubAssembler* assembler) {
   2721   Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kThrow,
   2722                                     "[Generator].prototype.throw");
   2723 }
   2724 
   2725 // -----------------------------------------------------------------------------
   2726 // ES6 section 26.1 The Reflect Object
   2727 
   2728 // ES6 section 26.1.3 Reflect.defineProperty
   2729 BUILTIN(ReflectDefineProperty) {
   2730   HandleScope scope(isolate);
   2731   DCHECK_EQ(4, args.length());
   2732   Handle<Object> target = args.at<Object>(1);
   2733   Handle<Object> key = args.at<Object>(2);
   2734   Handle<Object> attributes = args.at<Object>(3);
   2735 
   2736   if (!target->IsJSReceiver()) {
   2737     THROW_NEW_ERROR_RETURN_FAILURE(
   2738         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2739                               isolate->factory()->NewStringFromAsciiChecked(
   2740                                   "Reflect.defineProperty")));
   2741   }
   2742 
   2743   Handle<Name> name;
   2744   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   2745                                      Object::ToName(isolate, key));
   2746 
   2747   PropertyDescriptor desc;
   2748   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
   2749     return isolate->heap()->exception();
   2750   }
   2751 
   2752   Maybe<bool> result =
   2753       JSReceiver::DefineOwnProperty(isolate, Handle<JSReceiver>::cast(target),
   2754                                     name, &desc, Object::DONT_THROW);
   2755   MAYBE_RETURN(result, isolate->heap()->exception());
   2756   return *isolate->factory()->ToBoolean(result.FromJust());
   2757 }
   2758 
   2759 
   2760 // ES6 section 26.1.4 Reflect.deleteProperty
   2761 BUILTIN(ReflectDeleteProperty) {
   2762   HandleScope scope(isolate);
   2763   DCHECK_EQ(3, args.length());
   2764   Handle<Object> target = args.at<Object>(1);
   2765   Handle<Object> key = args.at<Object>(2);
   2766 
   2767   if (!target->IsJSReceiver()) {
   2768     THROW_NEW_ERROR_RETURN_FAILURE(
   2769         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2770                               isolate->factory()->NewStringFromAsciiChecked(
   2771                                   "Reflect.deleteProperty")));
   2772   }
   2773 
   2774   Handle<Name> name;
   2775   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   2776                                      Object::ToName(isolate, key));
   2777 
   2778   Maybe<bool> result = JSReceiver::DeletePropertyOrElement(
   2779       Handle<JSReceiver>::cast(target), name, SLOPPY);
   2780   MAYBE_RETURN(result, isolate->heap()->exception());
   2781   return *isolate->factory()->ToBoolean(result.FromJust());
   2782 }
   2783 
   2784 
   2785 // ES6 section 26.1.6 Reflect.get
   2786 BUILTIN(ReflectGet) {
   2787   HandleScope scope(isolate);
   2788   Handle<Object> target = args.atOrUndefined(isolate, 1);
   2789   Handle<Object> key = args.atOrUndefined(isolate, 2);
   2790   Handle<Object> receiver = args.length() > 3 ? args.at<Object>(3) : target;
   2791 
   2792   if (!target->IsJSReceiver()) {
   2793     THROW_NEW_ERROR_RETURN_FAILURE(
   2794         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2795                               isolate->factory()->NewStringFromAsciiChecked(
   2796                                   "Reflect.get")));
   2797   }
   2798 
   2799   Handle<Name> name;
   2800   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   2801                                      Object::ToName(isolate, key));
   2802 
   2803   RETURN_RESULT_OR_FAILURE(
   2804       isolate, Object::GetPropertyOrElement(receiver, name,
   2805                                             Handle<JSReceiver>::cast(target)));
   2806 }
   2807 
   2808 
   2809 // ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor
   2810 BUILTIN(ReflectGetOwnPropertyDescriptor) {
   2811   HandleScope scope(isolate);
   2812   DCHECK_EQ(3, args.length());
   2813   Handle<Object> target = args.at<Object>(1);
   2814   Handle<Object> key = args.at<Object>(2);
   2815 
   2816   if (!target->IsJSReceiver()) {
   2817     THROW_NEW_ERROR_RETURN_FAILURE(
   2818         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2819                               isolate->factory()->NewStringFromAsciiChecked(
   2820                                   "Reflect.getOwnPropertyDescriptor")));
   2821   }
   2822 
   2823   Handle<Name> name;
   2824   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   2825                                      Object::ToName(isolate, key));
   2826 
   2827   PropertyDescriptor desc;
   2828   Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
   2829       isolate, Handle<JSReceiver>::cast(target), name, &desc);
   2830   MAYBE_RETURN(found, isolate->heap()->exception());
   2831   if (!found.FromJust()) return isolate->heap()->undefined_value();
   2832   return *desc.ToObject(isolate);
   2833 }
   2834 
   2835 
   2836 // ES6 section 26.1.8 Reflect.getPrototypeOf
   2837 BUILTIN(ReflectGetPrototypeOf) {
   2838   HandleScope scope(isolate);
   2839   DCHECK_EQ(2, args.length());
   2840   Handle<Object> target = args.at<Object>(1);
   2841 
   2842   if (!target->IsJSReceiver()) {
   2843     THROW_NEW_ERROR_RETURN_FAILURE(
   2844         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2845                               isolate->factory()->NewStringFromAsciiChecked(
   2846                                   "Reflect.getPrototypeOf")));
   2847   }
   2848   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(target);
   2849   RETURN_RESULT_OR_FAILURE(isolate,
   2850                            JSReceiver::GetPrototype(isolate, receiver));
   2851 }
   2852 
   2853 
   2854 // ES6 section 26.1.9 Reflect.has
   2855 BUILTIN(ReflectHas) {
   2856   HandleScope scope(isolate);
   2857   DCHECK_EQ(3, args.length());
   2858   Handle<Object> target = args.at<Object>(1);
   2859   Handle<Object> key = args.at<Object>(2);
   2860 
   2861   if (!target->IsJSReceiver()) {
   2862     THROW_NEW_ERROR_RETURN_FAILURE(
   2863         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2864                               isolate->factory()->NewStringFromAsciiChecked(
   2865                                   "Reflect.has")));
   2866   }
   2867 
   2868   Handle<Name> name;
   2869   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   2870                                      Object::ToName(isolate, key));
   2871 
   2872   Maybe<bool> result =
   2873       JSReceiver::HasProperty(Handle<JSReceiver>::cast(target), name);
   2874   return result.IsJust() ? *isolate->factory()->ToBoolean(result.FromJust())
   2875                          : isolate->heap()->exception();
   2876 }
   2877 
   2878 
   2879 // ES6 section 26.1.10 Reflect.isExtensible
   2880 BUILTIN(ReflectIsExtensible) {
   2881   HandleScope scope(isolate);
   2882   DCHECK_EQ(2, args.length());
   2883   Handle<Object> target = args.at<Object>(1);
   2884 
   2885   if (!target->IsJSReceiver()) {
   2886     THROW_NEW_ERROR_RETURN_FAILURE(
   2887         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2888                               isolate->factory()->NewStringFromAsciiChecked(
   2889                                   "Reflect.isExtensible")));
   2890   }
   2891 
   2892   Maybe<bool> result =
   2893       JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target));
   2894   MAYBE_RETURN(result, isolate->heap()->exception());
   2895   return *isolate->factory()->ToBoolean(result.FromJust());
   2896 }
   2897 
   2898 
   2899 // ES6 section 26.1.11 Reflect.ownKeys
   2900 BUILTIN(ReflectOwnKeys) {
   2901   HandleScope scope(isolate);
   2902   DCHECK_EQ(2, args.length());
   2903   Handle<Object> target = args.at<Object>(1);
   2904 
   2905   if (!target->IsJSReceiver()) {
   2906     THROW_NEW_ERROR_RETURN_FAILURE(
   2907         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2908                               isolate->factory()->NewStringFromAsciiChecked(
   2909                                   "Reflect.ownKeys")));
   2910   }
   2911 
   2912   Handle<FixedArray> keys;
   2913   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2914       isolate, keys,
   2915       KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target),
   2916                               KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
   2917                               GetKeysConversion::kConvertToString));
   2918   return *isolate->factory()->NewJSArrayWithElements(keys);
   2919 }
   2920 
   2921 
   2922 // ES6 section 26.1.12 Reflect.preventExtensions
   2923 BUILTIN(ReflectPreventExtensions) {
   2924   HandleScope scope(isolate);
   2925   DCHECK_EQ(2, args.length());
   2926   Handle<Object> target = args.at<Object>(1);
   2927 
   2928   if (!target->IsJSReceiver()) {
   2929     THROW_NEW_ERROR_RETURN_FAILURE(
   2930         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2931                               isolate->factory()->NewStringFromAsciiChecked(
   2932                                   "Reflect.preventExtensions")));
   2933   }
   2934 
   2935   Maybe<bool> result = JSReceiver::PreventExtensions(
   2936       Handle<JSReceiver>::cast(target), Object::DONT_THROW);
   2937   MAYBE_RETURN(result, isolate->heap()->exception());
   2938   return *isolate->factory()->ToBoolean(result.FromJust());
   2939 }
   2940 
   2941 
   2942 // ES6 section 26.1.13 Reflect.set
   2943 BUILTIN(ReflectSet) {
   2944   HandleScope scope(isolate);
   2945   Handle<Object> target = args.atOrUndefined(isolate, 1);
   2946   Handle<Object> key = args.atOrUndefined(isolate, 2);
   2947   Handle<Object> value = args.atOrUndefined(isolate, 3);
   2948   Handle<Object> receiver = args.length() > 4 ? args.at<Object>(4) : target;
   2949 
   2950   if (!target->IsJSReceiver()) {
   2951     THROW_NEW_ERROR_RETURN_FAILURE(
   2952         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2953                               isolate->factory()->NewStringFromAsciiChecked(
   2954                                   "Reflect.set")));
   2955   }
   2956 
   2957   Handle<Name> name;
   2958   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
   2959                                      Object::ToName(isolate, key));
   2960 
   2961   LookupIterator it = LookupIterator::PropertyOrElement(
   2962       isolate, receiver, name, Handle<JSReceiver>::cast(target));
   2963   Maybe<bool> result = Object::SetSuperProperty(
   2964       &it, value, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED);
   2965   MAYBE_RETURN(result, isolate->heap()->exception());
   2966   return *isolate->factory()->ToBoolean(result.FromJust());
   2967 }
   2968 
   2969 
   2970 // ES6 section 26.1.14 Reflect.setPrototypeOf
   2971 BUILTIN(ReflectSetPrototypeOf) {
   2972   HandleScope scope(isolate);
   2973   DCHECK_EQ(3, args.length());
   2974   Handle<Object> target = args.at<Object>(1);
   2975   Handle<Object> proto = args.at<Object>(2);
   2976 
   2977   if (!target->IsJSReceiver()) {
   2978     THROW_NEW_ERROR_RETURN_FAILURE(
   2979         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
   2980                               isolate->factory()->NewStringFromAsciiChecked(
   2981                                   "Reflect.setPrototypeOf")));
   2982   }
   2983 
   2984   if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) {
   2985     THROW_NEW_ERROR_RETURN_FAILURE(
   2986         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
   2987   }
   2988 
   2989   Maybe<bool> result = JSReceiver::SetPrototype(
   2990       Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW);
   2991   MAYBE_RETURN(result, isolate->heap()->exception());
   2992   return *isolate->factory()->ToBoolean(result.FromJust());
   2993 }
   2994 
   2995 
   2996 // -----------------------------------------------------------------------------
   2997 // ES6 section 19.3 Boolean Objects
   2998 
   2999 
   3000 // ES6 section 19.3.1.1 Boolean ( value ) for the [[Call]] case.
   3001 BUILTIN(BooleanConstructor) {
   3002   HandleScope scope(isolate);
   3003   Handle<Object> value = args.atOrUndefined(isolate, 1);
   3004   return isolate->heap()->ToBoolean(value->BooleanValue());
   3005 }
   3006 
   3007 
   3008 // ES6 section 19.3.1.1 Boolean ( value ) for the [[Construct]] case.
   3009 BUILTIN(BooleanConstructor_ConstructStub) {
   3010   HandleScope scope(isolate);
   3011   Handle<Object> value = args.atOrUndefined(isolate, 1);
   3012   Handle<JSFunction> target = args.target<JSFunction>();
   3013   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
   3014   DCHECK(*target == target->native_context()->boolean_function());
   3015   Handle<JSObject> result;
   3016   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   3017                                      JSObject::New(target, new_target));
   3018   Handle<JSValue>::cast(result)->set_value(
   3019       isolate->heap()->ToBoolean(value->BooleanValue()));
   3020   return *result;
   3021 }
   3022 
   3023 
   3024 // ES6 section 19.3.3.2 Boolean.prototype.toString ( )
   3025 BUILTIN(BooleanPrototypeToString) {
   3026   HandleScope scope(isolate);
   3027   Handle<Object> receiver = args.receiver();
   3028   if (receiver->IsJSValue()) {
   3029     receiver = handle(Handle<JSValue>::cast(receiver)->value(), isolate);
   3030   }
   3031   if (!receiver->IsBoolean()) {
   3032     THROW_NEW_ERROR_RETURN_FAILURE(
   3033         isolate, NewTypeError(MessageTemplate::kNotGeneric,
   3034                               isolate->factory()->NewStringFromAsciiChecked(
   3035                                   "Boolean.prototype.toString")));
   3036   }
   3037   return Handle<Oddball>::cast(receiver)->to_string();
   3038 }
   3039 
   3040 
   3041 // ES6 section 19.3.3.3 Boolean.prototype.valueOf ( )
   3042 BUILTIN(BooleanPrototypeValueOf) {
   3043   HandleScope scope(isolate);
   3044   Handle<Object> receiver = args.receiver();
   3045   if (receiver->IsJSValue()) {
   3046     receiver = handle(Handle<JSValue>::cast(receiver)->value(), isolate);
   3047   }
   3048   if (!receiver->IsBoolean()) {
   3049     THROW_NEW_ERROR_RETURN_FAILURE(
   3050         isolate, NewTypeError(MessageTemplate::kNotGeneric,
   3051                               isolate->factory()->NewStringFromAsciiChecked(
   3052                                   "Boolean.prototype.valueOf")));
   3053   }
   3054   return *receiver;
   3055 }
   3056 
   3057 
   3058 // -----------------------------------------------------------------------------
   3059 // ES6 section 24.2 DataView Objects
   3060 
   3061 
   3062 // ES6 section 24.2.2 The DataView Constructor for the [[Call]] case.
   3063 BUILTIN(DataViewConstructor) {
   3064   HandleScope scope(isolate);
   3065   THROW_NEW_ERROR_RETURN_FAILURE(
   3066       isolate,
   3067       NewTypeError(MessageTemplate::kConstructorNotFunction,
   3068                    isolate->factory()->NewStringFromAsciiChecked("DataView")));
   3069 }
   3070 
   3071 
   3072 // ES6 section 24.2.2 The DataView Constructor for the [[Construct]] case.
   3073 BUILTIN(DataViewConstructor_ConstructStub) {
   3074   HandleScope scope(isolate);
   3075   Handle<JSFunction> target = args.target<JSFunction>();
   3076   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
   3077   Handle<Object> buffer = args.atOrUndefined(isolate, 1);
   3078   Handle<Object> byte_offset = args.atOrUndefined(isolate, 2);
   3079   Handle<Object> byte_length = args.atOrUndefined(isolate, 3);
   3080 
   3081   // 2. If Type(buffer) is not Object, throw a TypeError exception.
   3082   // 3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a
   3083   //    TypeError exception.
   3084   if (!buffer->IsJSArrayBuffer()) {
   3085     THROW_NEW_ERROR_RETURN_FAILURE(
   3086         isolate, NewTypeError(MessageTemplate::kDataViewNotArrayBuffer));
   3087   }
   3088   Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(buffer);
   3089 
   3090   // 4. Let numberOffset be ? ToNumber(byteOffset).
   3091   Handle<Object> number_offset;
   3092   if (byte_offset->IsUndefined(isolate)) {
   3093     // We intentionally violate the specification at this point to allow
   3094     // for new DataView(buffer) invocations to be equivalent to the full
   3095     // new DataView(buffer, 0) invocation.
   3096     number_offset = handle(Smi::FromInt(0), isolate);
   3097   } else {
   3098     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_offset,
   3099                                        Object::ToNumber(byte_offset));
   3100   }
   3101 
   3102   // 5. Let offset be ToInteger(numberOffset).
   3103   Handle<Object> offset;
   3104   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, offset,
   3105                                      Object::ToInteger(isolate, number_offset));
   3106 
   3107   // 6. If numberOffset  offset or offset < 0, throw a RangeError exception.
   3108   if (number_offset->Number() != offset->Number() || offset->Number() < 0.0) {
   3109     THROW_NEW_ERROR_RETURN_FAILURE(
   3110         isolate, NewRangeError(MessageTemplate::kInvalidDataViewOffset));
   3111   }
   3112 
   3113   // 7. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
   3114   // We currently violate the specification at this point.
   3115 
   3116   // 8. Let bufferByteLength be the value of buffer's [[ArrayBufferByteLength]]
   3117   // internal slot.
   3118   double const buffer_byte_length = array_buffer->byte_length()->Number();
   3119 
   3120   // 9. If offset > bufferByteLength, throw a RangeError exception
   3121   if (offset->Number() > buffer_byte_length) {
   3122     THROW_NEW_ERROR_RETURN_FAILURE(
   3123         isolate, NewRangeError(MessageTemplate::kInvalidDataViewOffset));
   3124   }
   3125 
   3126   Handle<Object> view_byte_length;
   3127   if (byte_length->IsUndefined(isolate)) {
   3128     // 10. If byteLength is undefined, then
   3129     //       a. Let viewByteLength be bufferByteLength - offset.
   3130     view_byte_length =
   3131         isolate->factory()->NewNumber(buffer_byte_length - offset->Number());
   3132   } else {
   3133     // 11. Else,
   3134     //       a. Let viewByteLength be ? ToLength(byteLength).
   3135     //       b. If offset+viewByteLength > bufferByteLength, throw a RangeError
   3136     //          exception
   3137     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3138         isolate, view_byte_length, Object::ToLength(isolate, byte_length));
   3139     if (offset->Number() + view_byte_length->Number() > buffer_byte_length) {
   3140       THROW_NEW_ERROR_RETURN_FAILURE(
   3141           isolate, NewRangeError(MessageTemplate::kInvalidDataViewLength));
   3142     }
   3143   }
   3144 
   3145   // 12. Let O be ? OrdinaryCreateFromConstructor(NewTarget,
   3146   //     "%DataViewPrototype%", [[DataView]], [[ViewedArrayBuffer]],
   3147   //     [[ByteLength]], [[ByteOffset]]).
   3148   // 13. Set O's [[DataView]] internal slot to true.
   3149   Handle<JSObject> result;
   3150   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   3151                                      JSObject::New(target, new_target));
   3152   for (int i = 0; i < ArrayBufferView::kInternalFieldCount; ++i) {
   3153     Handle<JSDataView>::cast(result)->SetInternalField(i, Smi::FromInt(0));
   3154   }
   3155 
   3156   // 14. Set O's [[ViewedArrayBuffer]] internal slot to buffer.
   3157   Handle<JSDataView>::cast(result)->set_buffer(*array_buffer);
   3158 
   3159   // 15. Set O's [[ByteLength]] internal slot to viewByteLength.
   3160   Handle<JSDataView>::cast(result)->set_byte_length(*view_byte_length);
   3161 
   3162   // 16. Set O's [[ByteOffset]] internal slot to offset.
   3163   Handle<JSDataView>::cast(result)->set_byte_offset(*offset);
   3164 
   3165   // 17. Return O.
   3166   return *result;
   3167 }
   3168 
   3169 // ES6 section 24.2.4.1 get DataView.prototype.buffer
   3170 BUILTIN(DataViewPrototypeGetBuffer) {
   3171   HandleScope scope(isolate);
   3172   CHECK_RECEIVER(JSDataView, data_view, "get DataView.prototype.buffer");
   3173   return data_view->buffer();
   3174 }
   3175 
   3176 // ES6 section 24.2.4.2 get DataView.prototype.byteLength
   3177 BUILTIN(DataViewPrototypeGetByteLength) {
   3178   HandleScope scope(isolate);
   3179   CHECK_RECEIVER(JSDataView, data_view, "get DataView.prototype.byteLength");
   3180   // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError
   3181   // here if the JSArrayBuffer of the {data_view} was neutered.
   3182   return data_view->byte_length();
   3183 }
   3184 
   3185 // ES6 section 24.2.4.3 get DataView.prototype.byteOffset
   3186 BUILTIN(DataViewPrototypeGetByteOffset) {
   3187   HandleScope scope(isolate);
   3188   CHECK_RECEIVER(JSDataView, data_view, "get DataView.prototype.byteOffset");
   3189   // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError
   3190   // here if the JSArrayBuffer of the {data_view} was neutered.
   3191   return data_view->byte_offset();
   3192 }
   3193 
   3194 // -----------------------------------------------------------------------------
   3195 // ES6 section 22.2 TypedArray Objects
   3196 
   3197 // ES6 section 22.2.3.1 get %TypedArray%.prototype.buffer
   3198 BUILTIN(TypedArrayPrototypeBuffer) {
   3199   HandleScope scope(isolate);
   3200   CHECK_RECEIVER(JSTypedArray, typed_array, "get TypedArray.prototype.buffer");
   3201   return *typed_array->GetBuffer();
   3202 }
   3203 
   3204 namespace {
   3205 
   3206 void Generate_TypedArrayProtoypeGetter(CodeStubAssembler* assembler,
   3207                                        const char* method_name,
   3208                                        int object_offset) {
   3209   typedef CodeStubAssembler::Label Label;
   3210   typedef compiler::Node Node;
   3211 
   3212   Node* receiver = assembler->Parameter(0);
   3213   Node* context = assembler->Parameter(3);
   3214 
   3215   // Check if the {receiver} is actually a JSTypedArray.
   3216   Label if_receiverisincompatible(assembler, Label::kDeferred);
   3217   assembler->GotoIf(assembler->WordIsSmi(receiver), &if_receiverisincompatible);
   3218   Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
   3219   assembler->GotoUnless(
   3220       assembler->Word32Equal(receiver_instance_type,
   3221                              assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)),
   3222       &if_receiverisincompatible);
   3223 
   3224   // Check if the {receiver}'s JSArrayBuffer was neutered.
   3225   Node* receiver_buffer =
   3226       assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset);
   3227   Node* receiver_buffer_bit_field = assembler->LoadObjectField(
   3228       receiver_buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
   3229   Label if_receiverisneutered(assembler, Label::kDeferred);
   3230   assembler->GotoUnless(
   3231       assembler->Word32Equal(
   3232           assembler->Word32And(
   3233               receiver_buffer_bit_field,
   3234               assembler->Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
   3235           assembler->Int32Constant(0)),
   3236       &if_receiverisneutered);
   3237   assembler->Return(assembler->LoadObjectField(receiver, object_offset));
   3238 
   3239   assembler->Bind(&if_receiverisneutered);
   3240   {
   3241     // The {receiver}s buffer was neutered, default to zero.
   3242     assembler->Return(assembler->SmiConstant(0));
   3243   }
   3244 
   3245   assembler->Bind(&if_receiverisincompatible);
   3246   {
   3247     // The {receiver} is not a valid JSGeneratorObject.
   3248     Node* result = assembler->CallRuntime(
   3249         Runtime::kThrowIncompatibleMethodReceiver, context,
   3250         assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
   3251             method_name, TENURED)),
   3252         receiver);
   3253     assembler->Return(result);  // Never reached.
   3254   }
   3255 }
   3256 
   3257 }  // namespace
   3258 
   3259 // ES6 section 22.2.3.2 get %TypedArray%.prototype.byteLength
   3260 void Builtins::Generate_TypedArrayPrototypeByteLength(
   3261     CodeStubAssembler* assembler) {
   3262   Generate_TypedArrayProtoypeGetter(assembler,
   3263                                     "get TypedArray.prototype.byteLength",
   3264                                     JSTypedArray::kByteLengthOffset);
   3265 }
   3266 
   3267 // ES6 section 22.2.3.3 get %TypedArray%.prototype.byteOffset
   3268 void Builtins::Generate_TypedArrayPrototypeByteOffset(
   3269     CodeStubAssembler* assembler) {
   3270   Generate_TypedArrayProtoypeGetter(assembler,
   3271                                     "get TypedArray.prototype.byteOffset",
   3272                                     JSTypedArray::kByteOffsetOffset);
   3273 }
   3274 
   3275 // ES6 section 22.2.3.18 get %TypedArray%.prototype.length
   3276 void Builtins::Generate_TypedArrayPrototypeLength(
   3277     CodeStubAssembler* assembler) {
   3278   Generate_TypedArrayProtoypeGetter(assembler,
   3279                                     "get TypedArray.prototype.length",
   3280                                     JSTypedArray::kLengthOffset);
   3281 }
   3282 
   3283 // -----------------------------------------------------------------------------
   3284 // ES6 section 20.3 Date Objects
   3285 
   3286 
   3287 namespace {
   3288 
   3289 // ES6 section 20.3.1.1 Time Values and Time Range
   3290 const double kMinYear = -1000000.0;
   3291 const double kMaxYear = -kMinYear;
   3292 const double kMinMonth = -10000000.0;
   3293 const double kMaxMonth = -kMinMonth;
   3294 
   3295 
   3296 // 20.3.1.2 Day Number and Time within Day
   3297 const double kMsPerDay = 86400000.0;
   3298 
   3299 
   3300 // ES6 section 20.3.1.11 Hours, Minutes, Second, and Milliseconds
   3301 const double kMsPerSecond = 1000.0;
   3302 const double kMsPerMinute = 60000.0;
   3303 const double kMsPerHour = 3600000.0;
   3304 
   3305 
   3306 // ES6 section 20.3.1.14 MakeDate (day, time)
   3307 double MakeDate(double day, double time) {
   3308   if (std::isfinite(day) && std::isfinite(time)) {
   3309     return time + day * kMsPerDay;
   3310   }
   3311   return std::numeric_limits<double>::quiet_NaN();
   3312 }
   3313 
   3314 
   3315 // ES6 section 20.3.1.13 MakeDay (year, month, date)
   3316 double MakeDay(double year, double month, double date) {
   3317   if ((kMinYear <= year && year <= kMaxYear) &&
   3318       (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) {
   3319     int y = FastD2I(year);
   3320     int m = FastD2I(month);
   3321     y += m / 12;
   3322     m %= 12;
   3323     if (m < 0) {
   3324       m += 12;
   3325       y -= 1;
   3326     }
   3327     DCHECK_LE(0, m);
   3328     DCHECK_LT(m, 12);
   3329 
   3330     // kYearDelta is an arbitrary number such that:
   3331     // a) kYearDelta = -1 (mod 400)
   3332     // b) year + kYearDelta > 0 for years in the range defined by
   3333     //    ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
   3334     //    Jan 1 1970. This is required so that we don't run into integer
   3335     //    division of negative numbers.
   3336     // c) there shouldn't be an overflow for 32-bit integers in the following
   3337     //    operations.
   3338     static const int kYearDelta = 399999;
   3339     static const int kBaseDay =
   3340         365 * (1970 + kYearDelta) + (1970 + kYearDelta) / 4 -
   3341         (1970 + kYearDelta) / 100 + (1970 + kYearDelta) / 400;
   3342     int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 -
   3343                         (y + kYearDelta) / 100 + (y + kYearDelta) / 400 -
   3344                         kBaseDay;
   3345     if ((y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) {
   3346       static const int kDayFromMonth[] = {0,   31,  59,  90,  120, 151,
   3347                                           181, 212, 243, 273, 304, 334};
   3348       day_from_year += kDayFromMonth[m];
   3349     } else {
   3350       static const int kDayFromMonth[] = {0,   31,  60,  91,  121, 152,
   3351                                           182, 213, 244, 274, 305, 335};
   3352       day_from_year += kDayFromMonth[m];
   3353     }
   3354     return static_cast<double>(day_from_year - 1) + date;
   3355   }
   3356   return std::numeric_limits<double>::quiet_NaN();
   3357 }
   3358 
   3359 
   3360 // ES6 section 20.3.1.12 MakeTime (hour, min, sec, ms)
   3361 double MakeTime(double hour, double min, double sec, double ms) {
   3362   if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) &&
   3363       std::isfinite(ms)) {
   3364     double const h = DoubleToInteger(hour);
   3365     double const m = DoubleToInteger(min);
   3366     double const s = DoubleToInteger(sec);
   3367     double const milli = DoubleToInteger(ms);
   3368     return h * kMsPerHour + m * kMsPerMinute + s * kMsPerSecond + milli;
   3369   }
   3370   return std::numeric_limits<double>::quiet_NaN();
   3371 }
   3372 
   3373 
   3374 // ES6 section 20.3.1.15 TimeClip (time)
   3375 double TimeClip(double time) {
   3376   if (-DateCache::kMaxTimeInMs <= time && time <= DateCache::kMaxTimeInMs) {
   3377     return DoubleToInteger(time) + 0.0;
   3378   }
   3379   return std::numeric_limits<double>::quiet_NaN();
   3380 }
   3381 
   3382 
   3383 const char* kShortWeekDays[] = {"Sun", "Mon", "Tue", "Wed",
   3384                                 "Thu", "Fri", "Sat"};
   3385 const char* kShortMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
   3386                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
   3387 
   3388 
   3389 // ES6 section 20.3.1.16 Date Time String Format
   3390 double ParseDateTimeString(Handle<String> str) {
   3391   Isolate* const isolate = str->GetIsolate();
   3392   str = String::Flatten(str);
   3393   // TODO(bmeurer): Change DateParser to not use the FixedArray.
   3394   Handle<FixedArray> tmp =
   3395       isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE);
   3396   DisallowHeapAllocation no_gc;
   3397   String::FlatContent str_content = str->GetFlatContent();
   3398   bool result;
   3399   if (str_content.IsOneByte()) {
   3400     result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp);
   3401   } else {
   3402     result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp);
   3403   }
   3404   if (!result) return std::numeric_limits<double>::quiet_NaN();
   3405   double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(),
   3406                              tmp->get(2)->Number());
   3407   double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(),
   3408                                tmp->get(5)->Number(), tmp->get(6)->Number());
   3409   double date = MakeDate(day, time);
   3410   if (tmp->get(7)->IsNull(isolate)) {
   3411     if (!std::isnan(date)) {
   3412       date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date));
   3413     }
   3414   } else {
   3415     date -= tmp->get(7)->Number() * 1000.0;
   3416   }
   3417   return date;
   3418 }
   3419 
   3420 
   3421 enum ToDateStringMode { kDateOnly, kTimeOnly, kDateAndTime };
   3422 
   3423 
   3424 // ES6 section 20.3.4.41.1 ToDateString(tv)
   3425 void ToDateString(double time_val, Vector<char> str, DateCache* date_cache,
   3426                   ToDateStringMode mode = kDateAndTime) {
   3427   if (std::isnan(time_val)) {
   3428     SNPrintF(str, "Invalid Date");
   3429     return;
   3430   }
   3431   int64_t time_ms = static_cast<int64_t>(time_val);
   3432   int64_t local_time_ms = date_cache->ToLocal(time_ms);
   3433   int year, month, day, weekday, hour, min, sec, ms;
   3434   date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday, &hour,
   3435                             &min, &sec, &ms);
   3436   int timezone_offset = -date_cache->TimezoneOffset(time_ms);
   3437   int timezone_hour = std::abs(timezone_offset) / 60;
   3438   int timezone_min = std::abs(timezone_offset) % 60;
   3439   const char* local_timezone = date_cache->LocalTimezone(time_ms);
   3440   switch (mode) {
   3441     case kDateOnly:
   3442       SNPrintF(str, "%s %s %02d %4d", kShortWeekDays[weekday],
   3443                kShortMonths[month], day, year);
   3444       return;
   3445     case kTimeOnly:
   3446       SNPrintF(str, "%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
   3447                (timezone_offset < 0) ? '-' : '+', timezone_hour, timezone_min,
   3448                local_timezone);
   3449       return;
   3450     case kDateAndTime:
   3451       SNPrintF(str, "%s %s %02d %4d %02d:%02d:%02d GMT%c%02d%02d (%s)",
   3452                kShortWeekDays[weekday], kShortMonths[month], day, year, hour,
   3453                min, sec, (timezone_offset < 0) ? '-' : '+', timezone_hour,
   3454                timezone_min, local_timezone);
   3455       return;
   3456   }
   3457   UNREACHABLE();
   3458 }
   3459 
   3460 
   3461 Object* SetLocalDateValue(Handle<JSDate> date, double time_val) {
   3462   if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
   3463       time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
   3464     Isolate* const isolate = date->GetIsolate();
   3465     time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
   3466   } else {
   3467     time_val = std::numeric_limits<double>::quiet_NaN();
   3468   }
   3469   return *JSDate::SetValue(date, TimeClip(time_val));
   3470 }
   3471 
   3472 }  // namespace
   3473 
   3474 
   3475 // ES6 section 20.3.2 The Date Constructor for the [[Call]] case.
   3476 BUILTIN(DateConstructor) {
   3477   HandleScope scope(isolate);
   3478   double const time_val = JSDate::CurrentTimeValue(isolate);
   3479   char buffer[128];
   3480   ToDateString(time_val, ArrayVector(buffer), isolate->date_cache());
   3481   RETURN_RESULT_OR_FAILURE(
   3482       isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
   3483 }
   3484 
   3485 
   3486 // ES6 section 20.3.2 The Date Constructor for the [[Construct]] case.
   3487 BUILTIN(DateConstructor_ConstructStub) {
   3488   HandleScope scope(isolate);
   3489   int const argc = args.length() - 1;
   3490   Handle<JSFunction> target = args.target<JSFunction>();
   3491   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
   3492   double time_val;
   3493   if (argc == 0) {
   3494     time_val = JSDate::CurrentTimeValue(isolate);
   3495   } else if (argc == 1) {
   3496     Handle<Object> value = args.at<Object>(1);
   3497     if (value->IsJSDate()) {
   3498       time_val = Handle<JSDate>::cast(value)->value()->Number();
   3499     } else {
   3500       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
   3501                                          Object::ToPrimitive(value));
   3502       if (value->IsString()) {
   3503         time_val = ParseDateTimeString(Handle<String>::cast(value));
   3504       } else {
   3505         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
   3506                                            Object::ToNumber(value));
   3507         time_val = value->Number();
   3508       }
   3509     }
   3510   } else {
   3511     Handle<Object> year_object;
   3512     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
   3513                                        Object::ToNumber(args.at<Object>(1)));
   3514     Handle<Object> month_object;
   3515     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
   3516                                        Object::ToNumber(args.at<Object>(2)));
   3517     double year = year_object->Number();
   3518     double month = month_object->Number();
   3519     double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
   3520     if (argc >= 3) {
   3521       Handle<Object> date_object;
   3522       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
   3523                                          Object::ToNumber(args.at<Object>(3)));
   3524       date = date_object->Number();
   3525       if (argc >= 4) {
   3526         Handle<Object> hours_object;
   3527         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3528             isolate, hours_object, Object::ToNumber(args.at<Object>(4)));
   3529         hours = hours_object->Number();
   3530         if (argc >= 5) {
   3531           Handle<Object> minutes_object;
   3532           ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3533               isolate, minutes_object, Object::ToNumber(args.at<Object>(5)));
   3534           minutes = minutes_object->Number();
   3535           if (argc >= 6) {
   3536             Handle<Object> seconds_object;
   3537             ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3538                 isolate, seconds_object, Object::ToNumber(args.at<Object>(6)));
   3539             seconds = seconds_object->Number();
   3540             if (argc >= 7) {
   3541               Handle<Object> ms_object;
   3542               ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3543                   isolate, ms_object, Object::ToNumber(args.at<Object>(7)));
   3544               ms = ms_object->Number();
   3545             }
   3546           }
   3547         }
   3548       }
   3549     }
   3550     if (!std::isnan(year)) {
   3551       double const y = DoubleToInteger(year);
   3552       if (0.0 <= y && y <= 99) year = 1900 + y;
   3553     }
   3554     double const day = MakeDay(year, month, date);
   3555     double const time = MakeTime(hours, minutes, seconds, ms);
   3556     time_val = MakeDate(day, time);
   3557     if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
   3558         time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
   3559       time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
   3560     } else {
   3561       time_val = std::numeric_limits<double>::quiet_NaN();
   3562     }
   3563   }
   3564   RETURN_RESULT_OR_FAILURE(isolate, JSDate::New(target, new_target, time_val));
   3565 }
   3566 
   3567 
   3568 // ES6 section 20.3.3.1 Date.now ( )
   3569 BUILTIN(DateNow) {
   3570   HandleScope scope(isolate);
   3571   return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
   3572 }
   3573 
   3574 
   3575 // ES6 section 20.3.3.2 Date.parse ( string )
   3576 BUILTIN(DateParse) {
   3577   HandleScope scope(isolate);
   3578   Handle<String> string;
   3579   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3580       isolate, string,
   3581       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
   3582   return *isolate->factory()->NewNumber(ParseDateTimeString(string));
   3583 }
   3584 
   3585 
   3586 // ES6 section 20.3.3.4 Date.UTC (year,month,date,hours,minutes,seconds,ms)
   3587 BUILTIN(DateUTC) {
   3588   HandleScope scope(isolate);
   3589   int const argc = args.length() - 1;
   3590   double year = std::numeric_limits<double>::quiet_NaN();
   3591   double month = std::numeric_limits<double>::quiet_NaN();
   3592   double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
   3593   if (argc >= 1) {
   3594     Handle<Object> year_object;
   3595     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
   3596                                        Object::ToNumber(args.at<Object>(1)));
   3597     year = year_object->Number();
   3598     if (argc >= 2) {
   3599       Handle<Object> month_object;
   3600       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
   3601                                          Object::ToNumber(args.at<Object>(2)));
   3602       month = month_object->Number();
   3603       if (argc >= 3) {
   3604         Handle<Object> date_object;
   3605         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3606             isolate, date_object, Object::ToNumber(args.at<Object>(3)));
   3607         date = date_object->Number();
   3608         if (argc >= 4) {
   3609           Handle<Object> hours_object;
   3610           ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3611               isolate, hours_object, Object::ToNumber(args.at<Object>(4)));
   3612           hours = hours_object->Number();
   3613           if (argc >= 5) {
   3614             Handle<Object> minutes_object;
   3615             ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3616                 isolate, minutes_object, Object::ToNumber(args.at<Object>(5)));
   3617             minutes = minutes_object->Number();
   3618             if (argc >= 6) {
   3619               Handle<Object> seconds_object;
   3620               ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3621                   isolate, seconds_object,
   3622                   Object::ToNumber(args.at<Object>(6)));
   3623               seconds = seconds_object->Number();
   3624               if (argc >= 7) {
   3625                 Handle<Object> ms_object;
   3626                 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   3627                     isolate, ms_object, Object::ToNumber(args.at<Object>(7)));
   3628                 ms = ms_object->Number();
   3629               }
   3630             }
   3631           }
   3632         }
   3633       }
   3634     }
   3635   }
   3636   if (!std::isnan(year)) {
   3637     double const y = DoubleToInteger(year);
   3638     if (0.0 <= y && y <= 99) year = 1900 + y;
   3639   }
   3640   double const day = MakeDay(year, month, date);
   3641   double const time = MakeTime(hours, minutes, seconds, ms);
   3642   return *isolate->factory()->NewNumber(TimeClip(MakeDate(day, time)));
   3643 }
   3644 
   3645 
   3646 // ES6 section 20.3.4.20 Date.prototype.setDate ( date )
   3647 BUILTIN(DatePrototypeSetDate) {
   3648   HandleScope scope(isolate);
   3649   CHECK_RECEIVER(JSDate, date, "Date.prototype.setDate");
   3650   Handle<Object> value = args.atOrUndefined(isolate, 1);
   3651   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
   3652   double time_val = date->value()->Number();
   3653   if (!std::isnan(time_val)) {
   3654     int64_t const time_ms = static_cast<int64_t>(time_val);
   3655     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3656     int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
   3657     int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
   3658     int year, month, day;
   3659     isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
   3660     time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
   3661   }
   3662   return SetLocalDateValue(date, time_val);
   3663 }
   3664 
   3665 
   3666 // ES6 section 20.3.4.21 Date.prototype.setFullYear (year, month, date)
   3667 BUILTIN(DatePrototypeSetFullYear) {
   3668   HandleScope scope(isolate);
   3669   CHECK_RECEIVER(JSDate, date, "Date.prototype.setFullYear");
   3670   int const argc = args.length() - 1;
   3671   Handle<Object> year = args.atOrUndefined(isolate, 1);
   3672   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
   3673   double y = year->Number(), m = 0.0, dt = 1.0;
   3674   int time_within_day = 0;
   3675   if (!std::isnan(date->value()->Number())) {
   3676     int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
   3677     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3678     int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
   3679     time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
   3680     int year, month, day;
   3681     isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
   3682     m = month;
   3683     dt = day;
   3684   }
   3685   if (argc >= 2) {
   3686     Handle<Object> month = args.at<Object>(2);
   3687     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
   3688     m = month->Number();
   3689     if (argc >= 3) {
   3690       Handle<Object> date = args.at<Object>(3);
   3691       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
   3692       dt = date->Number();
   3693     }
   3694   }
   3695   double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
   3696   return SetLocalDateValue(date, time_val);
   3697 }
   3698 
   3699 
   3700 // ES6 section 20.3.4.22 Date.prototype.setHours(hour, min, sec, ms)
   3701 BUILTIN(DatePrototypeSetHours) {
   3702   HandleScope scope(isolate);
   3703   CHECK_RECEIVER(JSDate, date, "Date.prototype.setHours");
   3704   int const argc = args.length() - 1;
   3705   Handle<Object> hour = args.atOrUndefined(isolate, 1);
   3706   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
   3707   double h = hour->Number();
   3708   double time_val = date->value()->Number();
   3709   if (!std::isnan(time_val)) {
   3710     int64_t const time_ms = static_cast<int64_t>(time_val);
   3711     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3712     int day = isolate->date_cache()->DaysFromTime(local_time_ms);
   3713     int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
   3714     double m = (time_within_day / (60 * 1000)) % 60;
   3715     double s = (time_within_day / 1000) % 60;
   3716     double milli = time_within_day % 1000;
   3717     if (argc >= 2) {
   3718       Handle<Object> min = args.at<Object>(2);
   3719       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
   3720       m = min->Number();
   3721       if (argc >= 3) {
   3722         Handle<Object> sec = args.at<Object>(3);
   3723         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
   3724         s = sec->Number();
   3725         if (argc >= 4) {
   3726           Handle<Object> ms = args.at<Object>(4);
   3727           ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3728           milli = ms->Number();
   3729         }
   3730       }
   3731     }
   3732     time_val = MakeDate(day, MakeTime(h, m, s, milli));
   3733   }
   3734   return SetLocalDateValue(date, time_val);
   3735 }
   3736 
   3737 
   3738 // ES6 section 20.3.4.23 Date.prototype.setMilliseconds(ms)
   3739 BUILTIN(DatePrototypeSetMilliseconds) {
   3740   HandleScope scope(isolate);
   3741   CHECK_RECEIVER(JSDate, date, "Date.prototype.setMilliseconds");
   3742   Handle<Object> ms = args.atOrUndefined(isolate, 1);
   3743   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3744   double time_val = date->value()->Number();
   3745   if (!std::isnan(time_val)) {
   3746     int64_t const time_ms = static_cast<int64_t>(time_val);
   3747     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3748     int day = isolate->date_cache()->DaysFromTime(local_time_ms);
   3749     int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
   3750     int h = time_within_day / (60 * 60 * 1000);
   3751     int m = (time_within_day / (60 * 1000)) % 60;
   3752     int s = (time_within_day / 1000) % 60;
   3753     time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
   3754   }
   3755   return SetLocalDateValue(date, time_val);
   3756 }
   3757 
   3758 
   3759 // ES6 section 20.3.4.24 Date.prototype.setMinutes ( min, sec, ms )
   3760 BUILTIN(DatePrototypeSetMinutes) {
   3761   HandleScope scope(isolate);
   3762   CHECK_RECEIVER(JSDate, date, "Date.prototype.setMinutes");
   3763   int const argc = args.length() - 1;
   3764   Handle<Object> min = args.atOrUndefined(isolate, 1);
   3765   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
   3766   double time_val = date->value()->Number();
   3767   if (!std::isnan(time_val)) {
   3768     int64_t const time_ms = static_cast<int64_t>(time_val);
   3769     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3770     int day = isolate->date_cache()->DaysFromTime(local_time_ms);
   3771     int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
   3772     int h = time_within_day / (60 * 60 * 1000);
   3773     double m = min->Number();
   3774     double s = (time_within_day / 1000) % 60;
   3775     double milli = time_within_day % 1000;
   3776     if (argc >= 2) {
   3777       Handle<Object> sec = args.at<Object>(2);
   3778       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
   3779       s = sec->Number();
   3780       if (argc >= 3) {
   3781         Handle<Object> ms = args.at<Object>(3);
   3782         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3783         milli = ms->Number();
   3784       }
   3785     }
   3786     time_val = MakeDate(day, MakeTime(h, m, s, milli));
   3787   }
   3788   return SetLocalDateValue(date, time_val);
   3789 }
   3790 
   3791 
   3792 // ES6 section 20.3.4.25 Date.prototype.setMonth ( month, date )
   3793 BUILTIN(DatePrototypeSetMonth) {
   3794   HandleScope scope(isolate);
   3795   CHECK_RECEIVER(JSDate, date, "Date.prototype.setMonth");
   3796   int const argc = args.length() - 1;
   3797   Handle<Object> month = args.atOrUndefined(isolate, 1);
   3798   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
   3799   double time_val = date->value()->Number();
   3800   if (!std::isnan(time_val)) {
   3801     int64_t const time_ms = static_cast<int64_t>(time_val);
   3802     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3803     int days = isolate->date_cache()->DaysFromTime(local_time_ms);
   3804     int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
   3805     int year, unused, day;
   3806     isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
   3807     double m = month->Number();
   3808     double dt = day;
   3809     if (argc >= 2) {
   3810       Handle<Object> date = args.at<Object>(2);
   3811       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
   3812       dt = date->Number();
   3813     }
   3814     time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
   3815   }
   3816   return SetLocalDateValue(date, time_val);
   3817 }
   3818 
   3819 
   3820 // ES6 section 20.3.4.26 Date.prototype.setSeconds ( sec, ms )
   3821 BUILTIN(DatePrototypeSetSeconds) {
   3822   HandleScope scope(isolate);
   3823   CHECK_RECEIVER(JSDate, date, "Date.prototype.setSeconds");
   3824   int const argc = args.length() - 1;
   3825   Handle<Object> sec = args.atOrUndefined(isolate, 1);
   3826   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
   3827   double time_val = date->value()->Number();
   3828   if (!std::isnan(time_val)) {
   3829     int64_t const time_ms = static_cast<int64_t>(time_val);
   3830     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   3831     int day = isolate->date_cache()->DaysFromTime(local_time_ms);
   3832     int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
   3833     int h = time_within_day / (60 * 60 * 1000);
   3834     double m = (time_within_day / (60 * 1000)) % 60;
   3835     double s = sec->Number();
   3836     double milli = time_within_day % 1000;
   3837     if (argc >= 2) {
   3838       Handle<Object> ms = args.at<Object>(2);
   3839       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3840       milli = ms->Number();
   3841     }
   3842     time_val = MakeDate(day, MakeTime(h, m, s, milli));
   3843   }
   3844   return SetLocalDateValue(date, time_val);
   3845 }
   3846 
   3847 
   3848 // ES6 section 20.3.4.27 Date.prototype.setTime ( time )
   3849 BUILTIN(DatePrototypeSetTime) {
   3850   HandleScope scope(isolate);
   3851   CHECK_RECEIVER(JSDate, date, "Date.prototype.setTime");
   3852   Handle<Object> value = args.atOrUndefined(isolate, 1);
   3853   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
   3854   return *JSDate::SetValue(date, TimeClip(value->Number()));
   3855 }
   3856 
   3857 
   3858 // ES6 section 20.3.4.28 Date.prototype.setUTCDate ( date )
   3859 BUILTIN(DatePrototypeSetUTCDate) {
   3860   HandleScope scope(isolate);
   3861   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCDate");
   3862   Handle<Object> value = args.atOrUndefined(isolate, 1);
   3863   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
   3864   if (std::isnan(date->value()->Number())) return date->value();
   3865   int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
   3866   int const days = isolate->date_cache()->DaysFromTime(time_ms);
   3867   int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
   3868   int year, month, day;
   3869   isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
   3870   double const time_val =
   3871       MakeDate(MakeDay(year, month, value->Number()), time_within_day);
   3872   return *JSDate::SetValue(date, TimeClip(time_val));
   3873 }
   3874 
   3875 
   3876 // ES6 section 20.3.4.29 Date.prototype.setUTCFullYear (year, month, date)
   3877 BUILTIN(DatePrototypeSetUTCFullYear) {
   3878   HandleScope scope(isolate);
   3879   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCFullYear");
   3880   int const argc = args.length() - 1;
   3881   Handle<Object> year = args.atOrUndefined(isolate, 1);
   3882   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
   3883   double y = year->Number(), m = 0.0, dt = 1.0;
   3884   int time_within_day = 0;
   3885   if (!std::isnan(date->value()->Number())) {
   3886     int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
   3887     int const days = isolate->date_cache()->DaysFromTime(time_ms);
   3888     time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
   3889     int year, month, day;
   3890     isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
   3891     m = month;
   3892     dt = day;
   3893   }
   3894   if (argc >= 2) {
   3895     Handle<Object> month = args.at<Object>(2);
   3896     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
   3897     m = month->Number();
   3898     if (argc >= 3) {
   3899       Handle<Object> date = args.at<Object>(3);
   3900       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
   3901       dt = date->Number();
   3902     }
   3903   }
   3904   double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
   3905   return *JSDate::SetValue(date, TimeClip(time_val));
   3906 }
   3907 
   3908 
   3909 // ES6 section 20.3.4.30 Date.prototype.setUTCHours(hour, min, sec, ms)
   3910 BUILTIN(DatePrototypeSetUTCHours) {
   3911   HandleScope scope(isolate);
   3912   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCHours");
   3913   int const argc = args.length() - 1;
   3914   Handle<Object> hour = args.atOrUndefined(isolate, 1);
   3915   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
   3916   double h = hour->Number();
   3917   double time_val = date->value()->Number();
   3918   if (!std::isnan(time_val)) {
   3919     int64_t const time_ms = static_cast<int64_t>(time_val);
   3920     int day = isolate->date_cache()->DaysFromTime(time_ms);
   3921     int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
   3922     double m = (time_within_day / (60 * 1000)) % 60;
   3923     double s = (time_within_day / 1000) % 60;
   3924     double milli = time_within_day % 1000;
   3925     if (argc >= 2) {
   3926       Handle<Object> min = args.at<Object>(2);
   3927       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
   3928       m = min->Number();
   3929       if (argc >= 3) {
   3930         Handle<Object> sec = args.at<Object>(3);
   3931         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
   3932         s = sec->Number();
   3933         if (argc >= 4) {
   3934           Handle<Object> ms = args.at<Object>(4);
   3935           ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3936           milli = ms->Number();
   3937         }
   3938       }
   3939     }
   3940     time_val = MakeDate(day, MakeTime(h, m, s, milli));
   3941   }
   3942   return *JSDate::SetValue(date, TimeClip(time_val));
   3943 }
   3944 
   3945 
   3946 // ES6 section 20.3.4.31 Date.prototype.setUTCMilliseconds(ms)
   3947 BUILTIN(DatePrototypeSetUTCMilliseconds) {
   3948   HandleScope scope(isolate);
   3949   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMilliseconds");
   3950   Handle<Object> ms = args.atOrUndefined(isolate, 1);
   3951   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3952   double time_val = date->value()->Number();
   3953   if (!std::isnan(time_val)) {
   3954     int64_t const time_ms = static_cast<int64_t>(time_val);
   3955     int day = isolate->date_cache()->DaysFromTime(time_ms);
   3956     int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
   3957     int h = time_within_day / (60 * 60 * 1000);
   3958     int m = (time_within_day / (60 * 1000)) % 60;
   3959     int s = (time_within_day / 1000) % 60;
   3960     time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
   3961   }
   3962   return *JSDate::SetValue(date, TimeClip(time_val));
   3963 }
   3964 
   3965 
   3966 // ES6 section 20.3.4.32 Date.prototype.setUTCMinutes ( min, sec, ms )
   3967 BUILTIN(DatePrototypeSetUTCMinutes) {
   3968   HandleScope scope(isolate);
   3969   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMinutes");
   3970   int const argc = args.length() - 1;
   3971   Handle<Object> min = args.atOrUndefined(isolate, 1);
   3972   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
   3973   double time_val = date->value()->Number();
   3974   if (!std::isnan(time_val)) {
   3975     int64_t const time_ms = static_cast<int64_t>(time_val);
   3976     int day = isolate->date_cache()->DaysFromTime(time_ms);
   3977     int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
   3978     int h = time_within_day / (60 * 60 * 1000);
   3979     double m = min->Number();
   3980     double s = (time_within_day / 1000) % 60;
   3981     double milli = time_within_day % 1000;
   3982     if (argc >= 2) {
   3983       Handle<Object> sec = args.at<Object>(2);
   3984       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
   3985       s = sec->Number();
   3986       if (argc >= 3) {
   3987         Handle<Object> ms = args.at<Object>(3);
   3988         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   3989         milli = ms->Number();
   3990       }
   3991     }
   3992     time_val = MakeDate(day, MakeTime(h, m, s, milli));
   3993   }
   3994   return *JSDate::SetValue(date, TimeClip(time_val));
   3995 }
   3996 
   3997 
   3998 // ES6 section 20.3.4.31 Date.prototype.setUTCMonth ( month, date )
   3999 BUILTIN(DatePrototypeSetUTCMonth) {
   4000   HandleScope scope(isolate);
   4001   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMonth");
   4002   int const argc = args.length() - 1;
   4003   Handle<Object> month = args.atOrUndefined(isolate, 1);
   4004   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
   4005   double time_val = date->value()->Number();
   4006   if (!std::isnan(time_val)) {
   4007     int64_t const time_ms = static_cast<int64_t>(time_val);
   4008     int days = isolate->date_cache()->DaysFromTime(time_ms);
   4009     int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
   4010     int year, unused, day;
   4011     isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
   4012     double m = month->Number();
   4013     double dt = day;
   4014     if (argc >= 2) {
   4015       Handle<Object> date = args.at<Object>(2);
   4016       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
   4017       dt = date->Number();
   4018     }
   4019     time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
   4020   }
   4021   return *JSDate::SetValue(date, TimeClip(time_val));
   4022 }
   4023 
   4024 
   4025 // ES6 section 20.3.4.34 Date.prototype.setUTCSeconds ( sec, ms )
   4026 BUILTIN(DatePrototypeSetUTCSeconds) {
   4027   HandleScope scope(isolate);
   4028   CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCSeconds");
   4029   int const argc = args.length() - 1;
   4030   Handle<Object> sec = args.atOrUndefined(isolate, 1);
   4031   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
   4032   double time_val = date->value()->Number();
   4033   if (!std::isnan(time_val)) {
   4034     int64_t const time_ms = static_cast<int64_t>(time_val);
   4035     int day = isolate->date_cache()->DaysFromTime(time_ms);
   4036     int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
   4037     int h = time_within_day / (60 * 60 * 1000);
   4038     double m = (time_within_day / (60 * 1000)) % 60;
   4039     double s = sec->Number();
   4040     double milli = time_within_day % 1000;
   4041     if (argc >= 2) {
   4042       Handle<Object> ms = args.at<Object>(2);
   4043       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
   4044       milli = ms->Number();
   4045     }
   4046     time_val = MakeDate(day, MakeTime(h, m, s, milli));
   4047   }
   4048   return *JSDate::SetValue(date, TimeClip(time_val));
   4049 }
   4050 
   4051 
   4052 // ES6 section 20.3.4.35 Date.prototype.toDateString ( )
   4053 BUILTIN(DatePrototypeToDateString) {
   4054   HandleScope scope(isolate);
   4055   CHECK_RECEIVER(JSDate, date, "Date.prototype.toDateString");
   4056   char buffer[128];
   4057   ToDateString(date->value()->Number(), ArrayVector(buffer),
   4058                isolate->date_cache(), kDateOnly);
   4059   RETURN_RESULT_OR_FAILURE(
   4060       isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
   4061 }
   4062 
   4063 
   4064 // ES6 section 20.3.4.36 Date.prototype.toISOString ( )
   4065 BUILTIN(DatePrototypeToISOString) {
   4066   HandleScope scope(isolate);
   4067   CHECK_RECEIVER(JSDate, date, "Date.prototype.toISOString");
   4068   double const time_val = date->value()->Number();
   4069   if (std::isnan(time_val)) {
   4070     THROW_NEW_ERROR_RETURN_FAILURE(
   4071         isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
   4072   }
   4073   int64_t const time_ms = static_cast<int64_t>(time_val);
   4074   int year, month, day, weekday, hour, min, sec, ms;
   4075   isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
   4076                                        &hour, &min, &sec, &ms);
   4077   char buffer[128];
   4078   if (year >= 0 && year <= 9999) {
   4079     SNPrintF(ArrayVector(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
   4080              month + 1, day, hour, min, sec, ms);
   4081   } else if (year < 0) {
   4082     SNPrintF(ArrayVector(buffer), "-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year,
   4083              month + 1, day, hour, min, sec, ms);
   4084   } else {
   4085     SNPrintF(ArrayVector(buffer), "+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
   4086              month + 1, day, hour, min, sec, ms);
   4087   }
   4088   return *isolate->factory()->NewStringFromAsciiChecked(buffer);
   4089 }
   4090 
   4091 
   4092 // ES6 section 20.3.4.41 Date.prototype.toString ( )
   4093 BUILTIN(DatePrototypeToString) {
   4094   HandleScope scope(isolate);
   4095   CHECK_RECEIVER(JSDate, date, "Date.prototype.toString");
   4096   char buffer[128];
   4097   ToDateString(date->value()->Number(), ArrayVector(buffer),
   4098                isolate->date_cache());
   4099   RETURN_RESULT_OR_FAILURE(
   4100       isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
   4101 }
   4102 
   4103 
   4104 // ES6 section 20.3.4.42 Date.prototype.toTimeString ( )
   4105 BUILTIN(DatePrototypeToTimeString) {
   4106   HandleScope scope(isolate);
   4107   CHECK_RECEIVER(JSDate, date, "Date.prototype.toTimeString");
   4108   char buffer[128];
   4109   ToDateString(date->value()->Number(), ArrayVector(buffer),
   4110                isolate->date_cache(), kTimeOnly);
   4111   RETURN_RESULT_OR_FAILURE(
   4112       isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
   4113 }
   4114 
   4115 
   4116 // ES6 section 20.3.4.43 Date.prototype.toUTCString ( )
   4117 BUILTIN(DatePrototypeToUTCString) {
   4118   HandleScope scope(isolate);
   4119   CHECK_RECEIVER(JSDate, date, "Date.prototype.toUTCString");
   4120   double const time_val = date->value()->Number();
   4121   if (std::isnan(time_val)) {
   4122     return *isolate->factory()->NewStringFromAsciiChecked("Invalid Date");
   4123   }
   4124   char buffer[128];
   4125   int64_t time_ms = static_cast<int64_t>(time_val);
   4126   int year, month, day, weekday, hour, min, sec, ms;
   4127   isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
   4128                                        &hour, &min, &sec, &ms);
   4129   SNPrintF(ArrayVector(buffer), "%s, %02d %s %4d %02d:%02d:%02d GMT",
   4130            kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min,
   4131            sec);
   4132   return *isolate->factory()->NewStringFromAsciiChecked(buffer);
   4133 }
   4134 
   4135 
   4136 // ES6 section 20.3.4.44 Date.prototype.valueOf ( )
   4137 BUILTIN(DatePrototypeValueOf) {
   4138   HandleScope scope(isolate);
   4139   CHECK_RECEIVER(JSDate, date, "Date.prototype.valueOf");
   4140   return date->value();
   4141 }
   4142 
   4143 
   4144 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint )
   4145 BUILTIN(DatePrototypeToPrimitive) {
   4146   HandleScope scope(isolate);
   4147   DCHECK_EQ(2, args.length());
   4148   CHECK_RECEIVER(JSReceiver, receiver, "Date.prototype [ @@toPrimitive ]");
   4149   Handle<Object> hint = args.at<Object>(1);
   4150   RETURN_RESULT_OR_FAILURE(isolate, JSDate::ToPrimitive(receiver, hint));
   4151 }
   4152 
   4153 
   4154 // ES6 section B.2.4.1 Date.prototype.getYear ( )
   4155 BUILTIN(DatePrototypeGetYear) {
   4156   HandleScope scope(isolate);
   4157   CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear");
   4158   double time_val = date->value()->Number();
   4159   if (std::isnan(time_val)) return date->value();
   4160   int64_t time_ms = static_cast<int64_t>(time_val);
   4161   int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   4162   int days = isolate->date_cache()->DaysFromTime(local_time_ms);
   4163   int year, month, day;
   4164   isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
   4165   return Smi::FromInt(year - 1900);
   4166 }
   4167 
   4168 
   4169 // ES6 section B.2.4.2 Date.prototype.setYear ( year )
   4170 BUILTIN(DatePrototypeSetYear) {
   4171   HandleScope scope(isolate);
   4172   CHECK_RECEIVER(JSDate, date, "Date.prototype.setYear");
   4173   Handle<Object> year = args.atOrUndefined(isolate, 1);
   4174   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
   4175   double m = 0.0, dt = 1.0, y = year->Number();
   4176   if (0.0 <= y && y <= 99.0) {
   4177     y = 1900.0 + DoubleToInteger(y);
   4178   }
   4179   int time_within_day = 0;
   4180   if (!std::isnan(date->value()->Number())) {
   4181     int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
   4182     int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
   4183     int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
   4184     time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
   4185     int year, month, day;
   4186     isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
   4187     m = month;
   4188     dt = day;
   4189   }
   4190   double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
   4191   return SetLocalDateValue(date, time_val);
   4192 }
   4193 
   4194 // ES6 section 20.3.4.37 Date.prototype.toJSON ( key )
   4195 BUILTIN(DatePrototypeToJson) {
   4196   HandleScope scope(isolate);
   4197   Handle<Object> receiver = args.atOrUndefined(isolate, 0);
   4198   Handle<JSReceiver> receiver_obj;
   4199   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_obj,
   4200                                      Object::ToObject(isolate, receiver));
   4201   Handle<Object> primitive;
   4202   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4203       isolate, primitive,
   4204       Object::ToPrimitive(receiver_obj, ToPrimitiveHint::kNumber));
   4205   if (primitive->IsNumber() && !std::isfinite(primitive->Number())) {
   4206     return isolate->heap()->null_value();
   4207   } else {
   4208     Handle<String> name =
   4209         isolate->factory()->NewStringFromAsciiChecked("toISOString");
   4210     Handle<Object> function;
   4211     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, function,
   4212                                        Object::GetProperty(receiver_obj, name));
   4213     if (!function->IsCallable()) {
   4214       THROW_NEW_ERROR_RETURN_FAILURE(
   4215           isolate, NewTypeError(MessageTemplate::kCalledNonCallable, name));
   4216     }
   4217     RETURN_RESULT_OR_FAILURE(
   4218         isolate, Execution::Call(isolate, function, receiver_obj, 0, NULL));
   4219   }
   4220 }
   4221 
   4222 // static
   4223 void Builtins::Generate_DatePrototypeGetDate(MacroAssembler* masm) {
   4224   Generate_DatePrototype_GetField(masm, JSDate::kDay);
   4225 }
   4226 
   4227 
   4228 // static
   4229 void Builtins::Generate_DatePrototypeGetDay(MacroAssembler* masm) {
   4230   Generate_DatePrototype_GetField(masm, JSDate::kWeekday);
   4231 }
   4232 
   4233 
   4234 // static
   4235 void Builtins::Generate_DatePrototypeGetFullYear(MacroAssembler* masm) {
   4236   Generate_DatePrototype_GetField(masm, JSDate::kYear);
   4237 }
   4238 
   4239 
   4240 // static
   4241 void Builtins::Generate_DatePrototypeGetHours(MacroAssembler* masm) {
   4242   Generate_DatePrototype_GetField(masm, JSDate::kHour);
   4243 }
   4244 
   4245 
   4246 // static
   4247 void Builtins::Generate_DatePrototypeGetMilliseconds(MacroAssembler* masm) {
   4248   Generate_DatePrototype_GetField(masm, JSDate::kMillisecond);
   4249 }
   4250 
   4251 
   4252 // static
   4253 void Builtins::Generate_DatePrototypeGetMinutes(MacroAssembler* masm) {
   4254   Generate_DatePrototype_GetField(masm, JSDate::kMinute);
   4255 }
   4256 
   4257 
   4258 // static
   4259 void Builtins::Generate_DatePrototypeGetMonth(MacroAssembler* masm) {
   4260   Generate_DatePrototype_GetField(masm, JSDate::kMonth);
   4261 }
   4262 
   4263 
   4264 // static
   4265 void Builtins::Generate_DatePrototypeGetSeconds(MacroAssembler* masm) {
   4266   Generate_DatePrototype_GetField(masm, JSDate::kSecond);
   4267 }
   4268 
   4269 
   4270 // static
   4271 void Builtins::Generate_DatePrototypeGetTime(MacroAssembler* masm) {
   4272   Generate_DatePrototype_GetField(masm, JSDate::kDateValue);
   4273 }
   4274 
   4275 
   4276 // static
   4277 void Builtins::Generate_DatePrototypeGetTimezoneOffset(MacroAssembler* masm) {
   4278   Generate_DatePrototype_GetField(masm, JSDate::kTimezoneOffset);
   4279 }
   4280 
   4281 
   4282 // static
   4283 void Builtins::Generate_DatePrototypeGetUTCDate(MacroAssembler* masm) {
   4284   Generate_DatePrototype_GetField(masm, JSDate::kDayUTC);
   4285 }
   4286 
   4287 
   4288 // static
   4289 void Builtins::Generate_DatePrototypeGetUTCDay(MacroAssembler* masm) {
   4290   Generate_DatePrototype_GetField(masm, JSDate::kWeekdayUTC);
   4291 }
   4292 
   4293 
   4294 // static
   4295 void Builtins::Generate_DatePrototypeGetUTCFullYear(MacroAssembler* masm) {
   4296   Generate_DatePrototype_GetField(masm, JSDate::kYearUTC);
   4297 }
   4298 
   4299 
   4300 // static
   4301 void Builtins::Generate_DatePrototypeGetUTCHours(MacroAssembler* masm) {
   4302   Generate_DatePrototype_GetField(masm, JSDate::kHourUTC);
   4303 }
   4304 
   4305 
   4306 // static
   4307 void Builtins::Generate_DatePrototypeGetUTCMilliseconds(MacroAssembler* masm) {
   4308   Generate_DatePrototype_GetField(masm, JSDate::kMillisecondUTC);
   4309 }
   4310 
   4311 
   4312 // static
   4313 void Builtins::Generate_DatePrototypeGetUTCMinutes(MacroAssembler* masm) {
   4314   Generate_DatePrototype_GetField(masm, JSDate::kMinuteUTC);
   4315 }
   4316 
   4317 
   4318 // static
   4319 void Builtins::Generate_DatePrototypeGetUTCMonth(MacroAssembler* masm) {
   4320   Generate_DatePrototype_GetField(masm, JSDate::kMonthUTC);
   4321 }
   4322 
   4323 
   4324 // static
   4325 void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) {
   4326   Generate_DatePrototype_GetField(masm, JSDate::kSecondUTC);
   4327 }
   4328 
   4329 
   4330 namespace {
   4331 
   4332 // ES6 section 19.2.1.1.1 CreateDynamicFunction
   4333 MaybeHandle<JSFunction> CreateDynamicFunction(Isolate* isolate,
   4334                                               BuiltinArguments args,
   4335                                               const char* token) {
   4336   // Compute number of arguments, ignoring the receiver.
   4337   DCHECK_LE(1, args.length());
   4338   int const argc = args.length() - 1;
   4339 
   4340   // Build the source string.
   4341   Handle<String> source;
   4342   {
   4343     IncrementalStringBuilder builder(isolate);
   4344     builder.AppendCharacter('(');
   4345     builder.AppendCString(token);
   4346     builder.AppendCharacter('(');
   4347     bool parenthesis_in_arg_string = false;
   4348     if (argc > 1) {
   4349       for (int i = 1; i < argc; ++i) {
   4350         if (i > 1) builder.AppendCharacter(',');
   4351         Handle<String> param;
   4352         ASSIGN_RETURN_ON_EXCEPTION(
   4353             isolate, param, Object::ToString(isolate, args.at<Object>(i)),
   4354             JSFunction);
   4355         param = String::Flatten(param);
   4356         builder.AppendString(param);
   4357         // If the formal parameters string include ) - an illegal
   4358         // character - it may make the combined function expression
   4359         // compile. We avoid this problem by checking for this early on.
   4360         DisallowHeapAllocation no_gc;  // Ensure vectors stay valid.
   4361         String::FlatContent param_content = param->GetFlatContent();
   4362         for (int i = 0, length = param->length(); i < length; ++i) {
   4363           if (param_content.Get(i) == ')') {
   4364             parenthesis_in_arg_string = true;
   4365             break;
   4366           }
   4367         }
   4368       }
   4369       // If the formal parameters include an unbalanced block comment, the
   4370       // function must be rejected. Since JavaScript does not allow nested
   4371       // comments we can include a trailing block comment to catch this.
   4372       builder.AppendCString("\n/**/");
   4373     }
   4374     builder.AppendCString(") {\n");
   4375     if (argc > 0) {
   4376       Handle<String> body;
   4377       ASSIGN_RETURN_ON_EXCEPTION(
   4378           isolate, body, Object::ToString(isolate, args.at<Object>(argc)),
   4379           JSFunction);
   4380       builder.AppendString(body);
   4381     }
   4382     builder.AppendCString("\n})");
   4383     ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), JSFunction);
   4384 
   4385     // The SyntaxError must be thrown after all the (observable) ToString
   4386     // conversions are done.
   4387     if (parenthesis_in_arg_string) {
   4388       THROW_NEW_ERROR(isolate,
   4389                       NewSyntaxError(MessageTemplate::kParenthesisInArgString),
   4390                       JSFunction);
   4391     }
   4392   }
   4393 
   4394   // Compile the string in the constructor and not a helper so that errors to
   4395   // come from here.
   4396   Handle<JSFunction> target = args.target<JSFunction>();
   4397   Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
   4398   Handle<JSFunction> function;
   4399   {
   4400     ASSIGN_RETURN_ON_EXCEPTION(
   4401         isolate, function,
   4402         CompileString(handle(target->native_context(), isolate), source,
   4403                       ONLY_SINGLE_FUNCTION_LITERAL),
   4404         JSFunction);
   4405     Handle<Object> result;
   4406     ASSIGN_RETURN_ON_EXCEPTION(
   4407         isolate, result,
   4408         Execution::Call(isolate, function, target_global_proxy, 0, nullptr),
   4409         JSFunction);
   4410     function = Handle<JSFunction>::cast(result);
   4411     function->shared()->set_name_should_print_as_anonymous(true);
   4412   }
   4413 
   4414   // If new.target is equal to target then the function created
   4415   // is already correctly setup and nothing else should be done
   4416   // here. But if new.target is not equal to target then we are
   4417   // have a Function builtin subclassing case and therefore the
   4418   // function has wrong initial map. To fix that we create a new
   4419   // function object with correct initial map.
   4420   Handle<Object> unchecked_new_target = args.new_target();
   4421   if (!unchecked_new_target->IsUndefined(isolate) &&
   4422       !unchecked_new_target.is_identical_to(target)) {
   4423     Handle<JSReceiver> new_target =
   4424         Handle<JSReceiver>::cast(unchecked_new_target);
   4425     Handle<Map> initial_map;
   4426     ASSIGN_RETURN_ON_EXCEPTION(
   4427         isolate, initial_map,
   4428         JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction);
   4429 
   4430     Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
   4431     Handle<Map> map = Map::AsLanguageMode(
   4432         initial_map, shared_info->language_mode(), shared_info->kind());
   4433 
   4434     Handle<Context> context(function->context(), isolate);
   4435     function = isolate->factory()->NewFunctionFromSharedFunctionInfo(
   4436         map, shared_info, context, NOT_TENURED);
   4437   }
   4438   return function;
   4439 }
   4440 
   4441 }  // namespace
   4442 
   4443 
   4444 // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body )
   4445 BUILTIN(FunctionConstructor) {
   4446   HandleScope scope(isolate);
   4447   Handle<JSFunction> result;
   4448   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4449       isolate, result, CreateDynamicFunction(isolate, args, "function"));
   4450   return *result;
   4451 }
   4452 
   4453 namespace {
   4454 
   4455 Object* DoFunctionBind(Isolate* isolate, BuiltinArguments args) {
   4456   HandleScope scope(isolate);
   4457   DCHECK_LE(1, args.length());
   4458   if (!args.receiver()->IsCallable()) {
   4459     THROW_NEW_ERROR_RETURN_FAILURE(
   4460         isolate, NewTypeError(MessageTemplate::kFunctionBind));
   4461   }
   4462 
   4463   // Allocate the bound function with the given {this_arg} and {args}.
   4464   Handle<JSReceiver> target = args.at<JSReceiver>(0);
   4465   Handle<Object> this_arg = isolate->factory()->undefined_value();
   4466   ScopedVector<Handle<Object>> argv(std::max(0, args.length() - 2));
   4467   if (args.length() > 1) {
   4468     this_arg = args.at<Object>(1);
   4469     for (int i = 2; i < args.length(); ++i) {
   4470       argv[i - 2] = args.at<Object>(i);
   4471     }
   4472   }
   4473   Handle<JSBoundFunction> function;
   4474   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4475       isolate, function,
   4476       isolate->factory()->NewJSBoundFunction(target, this_arg, argv));
   4477 
   4478   LookupIterator length_lookup(target, isolate->factory()->length_string(),
   4479                                target, LookupIterator::OWN);
   4480   // Setup the "length" property based on the "length" of the {target}.
   4481   // If the targets length is the default JSFunction accessor, we can keep the
   4482   // accessor that's installed by default on the JSBoundFunction. It lazily
   4483   // computes the value from the underlying internal length.
   4484   if (!target->IsJSFunction() ||
   4485       length_lookup.state() != LookupIterator::ACCESSOR ||
   4486       !length_lookup.GetAccessors()->IsAccessorInfo()) {
   4487     Handle<Object> length(Smi::FromInt(0), isolate);
   4488     Maybe<PropertyAttributes> attributes =
   4489         JSReceiver::GetPropertyAttributes(&length_lookup);
   4490     if (!attributes.IsJust()) return isolate->heap()->exception();
   4491     if (attributes.FromJust() != ABSENT) {
   4492       Handle<Object> target_length;
   4493       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_length,
   4494                                          Object::GetProperty(&length_lookup));
   4495       if (target_length->IsNumber()) {
   4496         length = isolate->factory()->NewNumber(std::max(
   4497             0.0, DoubleToInteger(target_length->Number()) - argv.length()));
   4498       }
   4499     }
   4500     LookupIterator it(function, isolate->factory()->length_string(), function);
   4501     DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
   4502     RETURN_FAILURE_ON_EXCEPTION(isolate,
   4503                                 JSObject::DefineOwnPropertyIgnoreAttributes(
   4504                                     &it, length, it.property_attributes()));
   4505   }
   4506 
   4507   // Setup the "name" property based on the "name" of the {target}.
   4508   // If the targets name is the default JSFunction accessor, we can keep the
   4509   // accessor that's installed by default on the JSBoundFunction. It lazily
   4510   // computes the value from the underlying internal name.
   4511   LookupIterator name_lookup(target, isolate->factory()->name_string(), target,
   4512                              LookupIterator::OWN);
   4513   if (!target->IsJSFunction() ||
   4514       name_lookup.state() != LookupIterator::ACCESSOR ||
   4515       !name_lookup.GetAccessors()->IsAccessorInfo()) {
   4516     Handle<Object> target_name;
   4517     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_name,
   4518                                        Object::GetProperty(&name_lookup));
   4519     Handle<String> name;
   4520     if (target_name->IsString()) {
   4521       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4522           isolate, name,
   4523           Name::ToFunctionName(Handle<String>::cast(target_name)));
   4524       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4525           isolate, name, isolate->factory()->NewConsString(
   4526                              isolate->factory()->bound__string(), name));
   4527     } else {
   4528       name = isolate->factory()->bound__string();
   4529     }
   4530     LookupIterator it(function, isolate->factory()->name_string());
   4531     DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
   4532     RETURN_FAILURE_ON_EXCEPTION(isolate,
   4533                                 JSObject::DefineOwnPropertyIgnoreAttributes(
   4534                                     &it, name, it.property_attributes()));
   4535   }
   4536   return *function;
   4537 }
   4538 
   4539 }  // namespace
   4540 
   4541 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args )
   4542 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); }
   4543 
   4544 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub
   4545 // can tailcall to the builtin directly.
   4546 RUNTIME_FUNCTION(Runtime_FunctionBind) {
   4547   DCHECK_EQ(2, args.length());
   4548   Arguments* incoming = reinterpret_cast<Arguments*>(args[0]);
   4549   // Rewrap the arguments as builtins arguments.
   4550   BuiltinArguments caller_args(incoming->length() + 3,
   4551                                incoming->arguments() + 1);
   4552   return DoFunctionBind(isolate, caller_args);
   4553 }
   4554 
   4555 // ES6 section 19.2.3.5 Function.prototype.toString ( )
   4556 BUILTIN(FunctionPrototypeToString) {
   4557   HandleScope scope(isolate);
   4558   Handle<Object> receiver = args.receiver();
   4559   if (receiver->IsJSBoundFunction()) {
   4560     return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver));
   4561   } else if (receiver->IsJSFunction()) {
   4562     return *JSFunction::ToString(Handle<JSFunction>::cast(receiver));
   4563   }
   4564   THROW_NEW_ERROR_RETURN_FAILURE(
   4565       isolate, NewTypeError(MessageTemplate::kNotGeneric,
   4566                             isolate->factory()->NewStringFromAsciiChecked(
   4567                                 "Function.prototype.toString")));
   4568 }
   4569 
   4570 
   4571 // ES6 section 25.2.1.1 GeneratorFunction (p1, p2, ... , pn, body)
   4572 BUILTIN(GeneratorFunctionConstructor) {
   4573   HandleScope scope(isolate);
   4574   RETURN_RESULT_OR_FAILURE(isolate,
   4575                            CreateDynamicFunction(isolate, args, "function*"));
   4576 }
   4577 
   4578 BUILTIN(AsyncFunctionConstructor) {
   4579   HandleScope scope(isolate);
   4580   Handle<JSFunction> func;
   4581   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4582       isolate, func, CreateDynamicFunction(isolate, args, "async function"));
   4583 
   4584   // Do not lazily compute eval position for AsyncFunction, as they may not be
   4585   // determined after the function is resumed.
   4586   Handle<Script> script = handle(Script::cast(func->shared()->script()));
   4587   int position = script->GetEvalPosition();
   4588   USE(position);
   4589 
   4590   return *func;
   4591 }
   4592 
   4593 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case.
   4594 BUILTIN(SymbolConstructor) {
   4595   HandleScope scope(isolate);
   4596   Handle<Symbol> result = isolate->factory()->NewSymbol();
   4597   Handle<Object> description = args.atOrUndefined(isolate, 1);
   4598   if (!description->IsUndefined(isolate)) {
   4599     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description,
   4600                                        Object::ToString(isolate, description));
   4601     result->set_name(*description);
   4602   }
   4603   return *result;
   4604 }
   4605 
   4606 
   4607 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Construct]] case.
   4608 BUILTIN(SymbolConstructor_ConstructStub) {
   4609   HandleScope scope(isolate);
   4610   THROW_NEW_ERROR_RETURN_FAILURE(
   4611       isolate, NewTypeError(MessageTemplate::kNotConstructor,
   4612                             isolate->factory()->Symbol_string()));
   4613 }
   4614 
   4615 
   4616 // ES6 19.1.3.6 Object.prototype.toString
   4617 BUILTIN(ObjectProtoToString) {
   4618   HandleScope scope(isolate);
   4619   Handle<Object> object = args.at<Object>(0);
   4620   RETURN_RESULT_OR_FAILURE(isolate,
   4621                            Object::ObjectProtoToString(isolate, object));
   4622 }
   4623 
   4624 // -----------------------------------------------------------------------------
   4625 // ES6 section 21.1 String Objects
   4626 
   4627 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits )
   4628 void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) {
   4629   typedef CodeStubAssembler::Label Label;
   4630   typedef compiler::Node Node;
   4631   typedef CodeStubAssembler::Variable Variable;
   4632 
   4633   Node* code = assembler->Parameter(1);
   4634   Node* context = assembler->Parameter(4);
   4635 
   4636   // Check if we have exactly one argument (plus the implicit receiver), i.e.
   4637   // if the parent frame is not an arguments adaptor frame.
   4638   Label if_oneargument(assembler), if_notoneargument(assembler);
   4639   Node* parent_frame_pointer = assembler->LoadParentFramePointer();
   4640   Node* parent_frame_type =
   4641       assembler->Load(MachineType::Pointer(), parent_frame_pointer,
   4642                       assembler->IntPtrConstant(
   4643                           CommonFrameConstants::kContextOrFrameTypeOffset));
   4644   assembler->Branch(
   4645       assembler->WordEqual(
   4646           parent_frame_type,
   4647           assembler->SmiConstant(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))),
   4648       &if_notoneargument, &if_oneargument);
   4649 
   4650   assembler->Bind(&if_oneargument);
   4651   {
   4652     // Single argument case, perform fast single character string cache lookup
   4653     // for one-byte code units, or fall back to creating a single character
   4654     // string on the fly otherwise.
   4655     Node* code32 = assembler->TruncateTaggedToWord32(context, code);
   4656     Node* code16 = assembler->Word32And(
   4657         code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
   4658     Node* result = assembler->StringFromCharCode(code16);
   4659     assembler->Return(result);
   4660   }
   4661 
   4662   assembler->Bind(&if_notoneargument);
   4663   {
   4664     // Determine the resulting string length.
   4665     Node* parent_frame_length =
   4666         assembler->Load(MachineType::Pointer(), parent_frame_pointer,
   4667                         assembler->IntPtrConstant(
   4668                             ArgumentsAdaptorFrameConstants::kLengthOffset));
   4669     Node* length = assembler->SmiToWord(parent_frame_length);
   4670 
   4671     // Assume that the resulting string contains only one-byte characters.
   4672     Node* result = assembler->AllocateSeqOneByteString(context, length);
   4673 
   4674     // Truncate all input parameters and append them to the resulting string.
   4675     Variable var_offset(assembler, MachineType::PointerRepresentation());
   4676     Label loop(assembler, &var_offset), done_loop(assembler);
   4677     var_offset.Bind(assembler->IntPtrConstant(0));
   4678     assembler->Goto(&loop);
   4679     assembler->Bind(&loop);
   4680     {
   4681       // Load the current {offset}.
   4682       Node* offset = var_offset.value();
   4683 
   4684       // Check if we're done with the string.
   4685       assembler->GotoIf(assembler->WordEqual(offset, length), &done_loop);
   4686 
   4687       // Load the next code point and truncate it to a 16-bit value.
   4688       Node* code = assembler->Load(
   4689           MachineType::AnyTagged(), parent_frame_pointer,
   4690           assembler->IntPtrAdd(
   4691               assembler->WordShl(assembler->IntPtrSub(length, offset),
   4692                                  assembler->IntPtrConstant(kPointerSizeLog2)),
   4693               assembler->IntPtrConstant(
   4694                   CommonFrameConstants::kFixedFrameSizeAboveFp -
   4695                   kPointerSize)));
   4696       Node* code32 = assembler->TruncateTaggedToWord32(context, code);
   4697       Node* code16 = assembler->Word32And(
   4698           code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
   4699 
   4700       // Check if {code16} fits into a one-byte string.
   4701       Label if_codeisonebyte(assembler), if_codeistwobyte(assembler);
   4702       assembler->Branch(
   4703           assembler->Int32LessThanOrEqual(
   4704               code16, assembler->Int32Constant(String::kMaxOneByteCharCode)),
   4705           &if_codeisonebyte, &if_codeistwobyte);
   4706 
   4707       assembler->Bind(&if_codeisonebyte);
   4708       {
   4709         // The {code16} fits into the SeqOneByteString {result}.
   4710         assembler->StoreNoWriteBarrier(
   4711             MachineRepresentation::kWord8, result,
   4712             assembler->IntPtrAdd(
   4713                 assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
   4714                                           kHeapObjectTag),
   4715                 offset),
   4716             code16);
   4717         var_offset.Bind(
   4718             assembler->IntPtrAdd(offset, assembler->IntPtrConstant(1)));
   4719         assembler->Goto(&loop);
   4720       }
   4721 
   4722       assembler->Bind(&if_codeistwobyte);
   4723       {
   4724         // Allocate a SeqTwoByteString to hold the resulting string.
   4725         Node* cresult = assembler->AllocateSeqTwoByteString(context, length);
   4726 
   4727         // Copy all characters that were previously written to the
   4728         // SeqOneByteString in {result} over to the new {cresult}.
   4729         Variable var_coffset(assembler, MachineType::PointerRepresentation());
   4730         Label cloop(assembler, &var_coffset), done_cloop(assembler);
   4731         var_coffset.Bind(assembler->IntPtrConstant(0));
   4732         assembler->Goto(&cloop);
   4733         assembler->Bind(&cloop);
   4734         {
   4735           Node* coffset = var_coffset.value();
   4736           assembler->GotoIf(assembler->WordEqual(coffset, offset), &done_cloop);
   4737           Node* ccode = assembler->Load(
   4738               MachineType::Uint8(), result,
   4739               assembler->IntPtrAdd(
   4740                   assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
   4741                                             kHeapObjectTag),
   4742                   coffset));
   4743           assembler->StoreNoWriteBarrier(
   4744               MachineRepresentation::kWord16, cresult,
   4745               assembler->IntPtrAdd(
   4746                   assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
   4747                                             kHeapObjectTag),
   4748                   assembler->WordShl(coffset, 1)),
   4749               ccode);
   4750           var_coffset.Bind(
   4751               assembler->IntPtrAdd(coffset, assembler->IntPtrConstant(1)));
   4752           assembler->Goto(&cloop);
   4753         }
   4754 
   4755         // Write the pending {code16} to {offset}.
   4756         assembler->Bind(&done_cloop);
   4757         assembler->StoreNoWriteBarrier(
   4758             MachineRepresentation::kWord16, cresult,
   4759             assembler->IntPtrAdd(
   4760                 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
   4761                                           kHeapObjectTag),
   4762                 assembler->WordShl(offset, 1)),
   4763             code16);
   4764 
   4765         // Copy the remaining parameters to the SeqTwoByteString {cresult}.
   4766         Label floop(assembler, &var_offset), done_floop(assembler);
   4767         assembler->Goto(&floop);
   4768         assembler->Bind(&floop);
   4769         {
   4770           // Compute the next {offset}.
   4771           Node* offset = assembler->IntPtrAdd(var_offset.value(),
   4772                                               assembler->IntPtrConstant(1));
   4773 
   4774           // Check if we're done with the string.
   4775           assembler->GotoIf(assembler->WordEqual(offset, length), &done_floop);
   4776 
   4777           // Load the next code point and truncate it to a 16-bit value.
   4778           Node* code = assembler->Load(
   4779               MachineType::AnyTagged(), parent_frame_pointer,
   4780               assembler->IntPtrAdd(
   4781                   assembler->WordShl(
   4782                       assembler->IntPtrSub(length, offset),
   4783                       assembler->IntPtrConstant(kPointerSizeLog2)),
   4784                   assembler->IntPtrConstant(
   4785                       CommonFrameConstants::kFixedFrameSizeAboveFp -
   4786                       kPointerSize)));
   4787           Node* code32 = assembler->TruncateTaggedToWord32(context, code);
   4788           Node* code16 = assembler->Word32And(
   4789               code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
   4790 
   4791           // Store the truncated {code} point at the next offset.
   4792           assembler->StoreNoWriteBarrier(
   4793               MachineRepresentation::kWord16, cresult,
   4794               assembler->IntPtrAdd(
   4795                   assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
   4796                                             kHeapObjectTag),
   4797                   assembler->WordShl(offset, 1)),
   4798               code16);
   4799           var_offset.Bind(offset);
   4800           assembler->Goto(&floop);
   4801         }
   4802 
   4803         // Return the SeqTwoByteString.
   4804         assembler->Bind(&done_floop);
   4805         assembler->Return(cresult);
   4806       }
   4807     }
   4808 
   4809     assembler->Bind(&done_loop);
   4810     assembler->Return(result);
   4811   }
   4812 }
   4813 
   4814 namespace {  // for String.fromCodePoint
   4815 
   4816 bool IsValidCodePoint(Isolate* isolate, Handle<Object> value) {
   4817   if (!value->IsNumber() && !Object::ToNumber(value).ToHandle(&value)) {
   4818     return false;
   4819   }
   4820 
   4821   if (Object::ToInteger(isolate, value).ToHandleChecked()->Number() !=
   4822       value->Number()) {
   4823     return false;
   4824   }
   4825 
   4826   if (value->Number() < 0 || value->Number() > 0x10FFFF) {
   4827     return false;
   4828   }
   4829 
   4830   return true;
   4831 }
   4832 
   4833 uc32 NextCodePoint(Isolate* isolate, BuiltinArguments args, int index) {
   4834   Handle<Object> value = args.at<Object>(1 + index);
   4835   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, value, Object::ToNumber(value), -1);
   4836   if (!IsValidCodePoint(isolate, value)) {
   4837     isolate->Throw(*isolate->factory()->NewRangeError(
   4838         MessageTemplate::kInvalidCodePoint, value));
   4839     return -1;
   4840   }
   4841   return DoubleToUint32(value->Number());
   4842 }
   4843 
   4844 }  // namespace
   4845 
   4846 // ES6 section 21.1.2.2 String.fromCodePoint ( ...codePoints )
   4847 BUILTIN(StringFromCodePoint) {
   4848   HandleScope scope(isolate);
   4849   int const length = args.length() - 1;
   4850   if (length == 0) return isolate->heap()->empty_string();
   4851   DCHECK_LT(0, length);
   4852 
   4853   // Optimistically assume that the resulting String contains only one byte
   4854   // characters.
   4855   List<uint8_t> one_byte_buffer(length);
   4856   uc32 code = 0;
   4857   int index;
   4858   for (index = 0; index < length; index++) {
   4859     code = NextCodePoint(isolate, args, index);
   4860     if (code < 0) {
   4861       return isolate->heap()->exception();
   4862     }
   4863     if (code > String::kMaxOneByteCharCode) {
   4864       break;
   4865     }
   4866     one_byte_buffer.Add(code);
   4867   }
   4868 
   4869   if (index == length) {
   4870     RETURN_RESULT_OR_FAILURE(isolate, isolate->factory()->NewStringFromOneByte(
   4871                                           one_byte_buffer.ToConstVector()));
   4872   }
   4873 
   4874   List<uc16> two_byte_buffer(length - index);
   4875 
   4876   while (true) {
   4877     if (code <= unibrow::Utf16::kMaxNonSurrogateCharCode) {
   4878       two_byte_buffer.Add(code);
   4879     } else {
   4880       two_byte_buffer.Add(unibrow::Utf16::LeadSurrogate(code));
   4881       two_byte_buffer.Add(unibrow::Utf16::TrailSurrogate(code));
   4882     }
   4883 
   4884     if (++index == length) {
   4885       break;
   4886     }
   4887     code = NextCodePoint(isolate, args, index);
   4888     if (code < 0) {
   4889       return isolate->heap()->exception();
   4890     }
   4891   }
   4892 
   4893   Handle<SeqTwoByteString> result;
   4894   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4895       isolate, result,
   4896       isolate->factory()->NewRawTwoByteString(one_byte_buffer.length() +
   4897                                               two_byte_buffer.length()));
   4898 
   4899   CopyChars(result->GetChars(), one_byte_buffer.ToConstVector().start(),
   4900             one_byte_buffer.length());
   4901   CopyChars(result->GetChars() + one_byte_buffer.length(),
   4902             two_byte_buffer.ToConstVector().start(), two_byte_buffer.length());
   4903 
   4904   return *result;
   4905 }
   4906 
   4907 // ES6 section 21.1.3.1 String.prototype.charAt ( pos )
   4908 void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) {
   4909   typedef CodeStubAssembler::Label Label;
   4910   typedef compiler::Node Node;
   4911   typedef CodeStubAssembler::Variable Variable;
   4912 
   4913   Node* receiver = assembler->Parameter(0);
   4914   Node* position = assembler->Parameter(1);
   4915   Node* context = assembler->Parameter(4);
   4916 
   4917   // Check that {receiver} is coercible to Object and convert it to a String.
   4918   receiver =
   4919       assembler->ToThisString(context, receiver, "String.prototype.charAt");
   4920 
   4921   // Convert the {position} to a Smi and check that it's in bounds of the
   4922   // {receiver}.
   4923   // TODO(bmeurer): Find an abstraction for this!
   4924   {
   4925     // Check if the {position} is already a Smi.
   4926     Variable var_position(assembler, MachineRepresentation::kTagged);
   4927     var_position.Bind(position);
   4928     Label if_positionissmi(assembler),
   4929         if_positionisnotsmi(assembler, Label::kDeferred);
   4930     assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi,
   4931                       &if_positionisnotsmi);
   4932     assembler->Bind(&if_positionisnotsmi);
   4933     {
   4934       // Convert the {position} to an Integer via the ToIntegerStub.
   4935       Callable callable = CodeFactory::ToInteger(assembler->isolate());
   4936       Node* index = assembler->CallStub(callable, context, position);
   4937 
   4938       // Check if the resulting {index} is now a Smi.
   4939       Label if_indexissmi(assembler, Label::kDeferred),
   4940           if_indexisnotsmi(assembler, Label::kDeferred);
   4941       assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi,
   4942                         &if_indexisnotsmi);
   4943 
   4944       assembler->Bind(&if_indexissmi);
   4945       {
   4946         var_position.Bind(index);
   4947         assembler->Goto(&if_positionissmi);
   4948       }
   4949 
   4950       assembler->Bind(&if_indexisnotsmi);
   4951       {
   4952         // The ToIntegerStub canonicalizes everything in Smi range to Smi
   4953         // representation, so any HeapNumber returned is not in Smi range.
   4954         // The only exception here is -0.0, which we treat as 0.
   4955         Node* index_value = assembler->LoadHeapNumberValue(index);
   4956         Label if_indexiszero(assembler, Label::kDeferred),
   4957             if_indexisnotzero(assembler, Label::kDeferred);
   4958         assembler->Branch(assembler->Float64Equal(
   4959                               index_value, assembler->Float64Constant(0.0)),
   4960                           &if_indexiszero, &if_indexisnotzero);
   4961 
   4962         assembler->Bind(&if_indexiszero);
   4963         {
   4964           var_position.Bind(assembler->SmiConstant(Smi::FromInt(0)));
   4965           assembler->Goto(&if_positionissmi);
   4966         }
   4967 
   4968         assembler->Bind(&if_indexisnotzero);
   4969         {
   4970           // The {index} is some other integral Number, that is definitely
   4971           // neither -0.0 nor in Smi range.
   4972           assembler->Return(assembler->EmptyStringConstant());
   4973         }
   4974       }
   4975     }
   4976     assembler->Bind(&if_positionissmi);
   4977     position = var_position.value();
   4978 
   4979     // Determine the actual length of the {receiver} String.
   4980     Node* receiver_length =
   4981         assembler->LoadObjectField(receiver, String::kLengthOffset);
   4982 
   4983     // Return "" if the Smi {position} is outside the bounds of the {receiver}.
   4984     Label if_positioninbounds(assembler),
   4985         if_positionnotinbounds(assembler, Label::kDeferred);
   4986     assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length),
   4987                       &if_positionnotinbounds, &if_positioninbounds);
   4988     assembler->Bind(&if_positionnotinbounds);
   4989     assembler->Return(assembler->EmptyStringConstant());
   4990     assembler->Bind(&if_positioninbounds);
   4991   }
   4992 
   4993   // Load the character code at the {position} from the {receiver}.
   4994   Node* code = assembler->StringCharCodeAt(receiver, position);
   4995 
   4996   // And return the single character string with only that {code}.
   4997   Node* result = assembler->StringFromCharCode(code);
   4998   assembler->Return(result);
   4999 }
   5000 
   5001 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos )
   5002 void Builtins::Generate_StringPrototypeCharCodeAt(
   5003     CodeStubAssembler* assembler) {
   5004   typedef CodeStubAssembler::Label Label;
   5005   typedef compiler::Node Node;
   5006   typedef CodeStubAssembler::Variable Variable;
   5007 
   5008   Node* receiver = assembler->Parameter(0);
   5009   Node* position = assembler->Parameter(1);
   5010   Node* context = assembler->Parameter(4);
   5011 
   5012   // Check that {receiver} is coercible to Object and convert it to a String.
   5013   receiver =
   5014       assembler->ToThisString(context, receiver, "String.prototype.charCodeAt");
   5015 
   5016   // Convert the {position} to a Smi and check that it's in bounds of the
   5017   // {receiver}.
   5018   // TODO(bmeurer): Find an abstraction for this!
   5019   {
   5020     // Check if the {position} is already a Smi.
   5021     Variable var_position(assembler, MachineRepresentation::kTagged);
   5022     var_position.Bind(position);
   5023     Label if_positionissmi(assembler),
   5024         if_positionisnotsmi(assembler, Label::kDeferred);
   5025     assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi,
   5026                       &if_positionisnotsmi);
   5027     assembler->Bind(&if_positionisnotsmi);
   5028     {
   5029       // Convert the {position} to an Integer via the ToIntegerStub.
   5030       Callable callable = CodeFactory::ToInteger(assembler->isolate());
   5031       Node* index = assembler->CallStub(callable, context, position);
   5032 
   5033       // Check if the resulting {index} is now a Smi.
   5034       Label if_indexissmi(assembler, Label::kDeferred),
   5035           if_indexisnotsmi(assembler, Label::kDeferred);
   5036       assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi,
   5037                         &if_indexisnotsmi);
   5038 
   5039       assembler->Bind(&if_indexissmi);
   5040       {
   5041         var_position.Bind(index);
   5042         assembler->Goto(&if_positionissmi);
   5043       }
   5044 
   5045       assembler->Bind(&if_indexisnotsmi);
   5046       {
   5047         // The ToIntegerStub canonicalizes everything in Smi range to Smi
   5048         // representation, so any HeapNumber returned is not in Smi range.
   5049         // The only exception here is -0.0, which we treat as 0.
   5050         Node* index_value = assembler->LoadHeapNumberValue(index);
   5051         Label if_indexiszero(assembler, Label::kDeferred),
   5052             if_indexisnotzero(assembler, Label::kDeferred);
   5053         assembler->Branch(assembler->Float64Equal(
   5054                               index_value, assembler->Float64Constant(0.0)),
   5055                           &if_indexiszero, &if_indexisnotzero);
   5056 
   5057         assembler->Bind(&if_indexiszero);
   5058         {
   5059           var_position.Bind(assembler->SmiConstant(Smi::FromInt(0)));
   5060           assembler->Goto(&if_positionissmi);
   5061         }
   5062 
   5063         assembler->Bind(&if_indexisnotzero);
   5064         {
   5065           // The {index} is some other integral Number, that is definitely
   5066           // neither -0.0 nor in Smi range.
   5067           assembler->Return(assembler->NaNConstant());
   5068         }
   5069       }
   5070     }
   5071     assembler->Bind(&if_positionissmi);
   5072     position = var_position.value();
   5073 
   5074     // Determine the actual length of the {receiver} String.
   5075     Node* receiver_length =
   5076         assembler->LoadObjectField(receiver, String::kLengthOffset);
   5077 
   5078     // Return NaN if the Smi {position} is outside the bounds of the {receiver}.
   5079     Label if_positioninbounds(assembler),
   5080         if_positionnotinbounds(assembler, Label::kDeferred);
   5081     assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length),
   5082                       &if_positionnotinbounds, &if_positioninbounds);
   5083     assembler->Bind(&if_positionnotinbounds);
   5084     assembler->Return(assembler->NaNConstant());
   5085     assembler->Bind(&if_positioninbounds);
   5086   }
   5087 
   5088   // Load the character at the {position} from the {receiver}.
   5089   Node* value = assembler->StringCharCodeAt(receiver, position);
   5090   Node* result = assembler->SmiFromWord32(value);
   5091   assembler->Return(result);
   5092 }
   5093 
   5094 // ES6 section 21.1.3.25 String.prototype.trim ()
   5095 BUILTIN(StringPrototypeTrim) {
   5096   HandleScope scope(isolate);
   5097   TO_THIS_STRING(string, "String.prototype.trim");
   5098   return *String::Trim(string, String::kTrim);
   5099 }
   5100 
   5101 // Non-standard WebKit extension
   5102 BUILTIN(StringPrototypeTrimLeft) {
   5103   HandleScope scope(isolate);
   5104   TO_THIS_STRING(string, "String.prototype.trimLeft");
   5105   return *String::Trim(string, String::kTrimLeft);
   5106 }
   5107 
   5108 // Non-standard WebKit extension
   5109 BUILTIN(StringPrototypeTrimRight) {
   5110   HandleScope scope(isolate);
   5111   TO_THIS_STRING(string, "String.prototype.trimRight");
   5112   return *String::Trim(string, String::kTrimRight);
   5113 }
   5114 
   5115 // -----------------------------------------------------------------------------
   5116 // ES6 section 21.1 ArrayBuffer Objects
   5117 
   5118 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
   5119 BUILTIN(ArrayBufferConstructor) {
   5120   HandleScope scope(isolate);
   5121   Handle<JSFunction> target = args.target<JSFunction>();
   5122   DCHECK(*target == target->native_context()->array_buffer_fun() ||
   5123          *target == target->native_context()->shared_array_buffer_fun());
   5124   THROW_NEW_ERROR_RETURN_FAILURE(
   5125       isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
   5126                             handle(target->shared()->name(), isolate)));
   5127 }
   5128 
   5129 
   5130 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Construct]] case.
   5131 BUILTIN(ArrayBufferConstructor_ConstructStub) {
   5132   HandleScope scope(isolate);
   5133   Handle<JSFunction> target = args.target<JSFunction>();
   5134   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
   5135   Handle<Object> length = args.atOrUndefined(isolate, 1);
   5136   DCHECK(*target == target->native_context()->array_buffer_fun() ||
   5137          *target == target->native_context()->shared_array_buffer_fun());
   5138   Handle<Object> number_length;
   5139   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_length,
   5140                                      Object::ToInteger(isolate, length));
   5141   if (number_length->Number() < 0.0) {
   5142     THROW_NEW_ERROR_RETURN_FAILURE(
   5143         isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength));
   5144   }
   5145   Handle<JSObject> result;
   5146   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   5147                                      JSObject::New(target, new_target));
   5148   size_t byte_length;
   5149   if (!TryNumberToSize(isolate, *number_length, &byte_length)) {
   5150     THROW_NEW_ERROR_RETURN_FAILURE(
   5151         isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength));
   5152   }
   5153   SharedFlag shared_flag =
   5154       (*target == target->native_context()->array_buffer_fun())
   5155           ? SharedFlag::kNotShared
   5156           : SharedFlag::kShared;
   5157   if (!JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer>::cast(result),
   5158                                           isolate, byte_length, true,
   5159                                           shared_flag)) {
   5160     THROW_NEW_ERROR_RETURN_FAILURE(
   5161         isolate, NewRangeError(MessageTemplate::kArrayBufferAllocationFailed));
   5162   }
   5163   return *result;
   5164 }
   5165 
   5166 
   5167 // ES6 section 24.1.3.1 ArrayBuffer.isView ( arg )
   5168 BUILTIN(ArrayBufferIsView) {
   5169   SealHandleScope shs(isolate);
   5170   DCHECK_EQ(2, args.length());
   5171   Object* arg = args[1];
   5172   return isolate->heap()->ToBoolean(arg->IsJSArrayBufferView());
   5173 }
   5174 
   5175 
   5176 // ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Call]] case.
   5177 BUILTIN(ProxyConstructor) {
   5178   HandleScope scope(isolate);
   5179   THROW_NEW_ERROR_RETURN_FAILURE(
   5180       isolate,
   5181       NewTypeError(MessageTemplate::kConstructorNotFunction,
   5182                    isolate->factory()->NewStringFromAsciiChecked("Proxy")));
   5183 }
   5184 
   5185 
   5186 // ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Construct]] case.
   5187 BUILTIN(ProxyConstructor_ConstructStub) {
   5188   HandleScope scope(isolate);
   5189   DCHECK(isolate->proxy_function()->IsConstructor());
   5190   Handle<Object> target = args.atOrUndefined(isolate, 1);
   5191   Handle<Object> handler = args.atOrUndefined(isolate, 2);
   5192   RETURN_RESULT_OR_FAILURE(isolate, JSProxy::New(isolate, target, handler));
   5193 }
   5194 
   5195 
   5196 // -----------------------------------------------------------------------------
   5197 // Throwers for restricted function properties and strict arguments object
   5198 // properties
   5199 
   5200 
   5201 BUILTIN(RestrictedFunctionPropertiesThrower) {
   5202   HandleScope scope(isolate);
   5203   THROW_NEW_ERROR_RETURN_FAILURE(
   5204       isolate, NewTypeError(MessageTemplate::kRestrictedFunctionProperties));
   5205 }
   5206 
   5207 
   5208 BUILTIN(RestrictedStrictArgumentsPropertiesThrower) {
   5209   HandleScope scope(isolate);
   5210   THROW_NEW_ERROR_RETURN_FAILURE(
   5211       isolate, NewTypeError(MessageTemplate::kStrictPoisonPill));
   5212 }
   5213 
   5214 
   5215 // -----------------------------------------------------------------------------
   5216 //
   5217 
   5218 
   5219 namespace {
   5220 
   5221 // Returns the holder JSObject if the function can legally be called with this
   5222 // receiver.  Returns nullptr if the call is illegal.
   5223 // TODO(dcarney): CallOptimization duplicates this logic, merge.
   5224 JSObject* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
   5225                                 JSObject* receiver) {
   5226   Object* recv_type = info->signature();
   5227   // No signature, return holder.
   5228   if (!recv_type->IsFunctionTemplateInfo()) return receiver;
   5229   FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
   5230 
   5231   // Check the receiver. Fast path for receivers with no hidden prototypes.
   5232   if (signature->IsTemplateFor(receiver)) return receiver;
   5233   if (!receiver->map()->has_hidden_prototype()) return nullptr;
   5234   for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype,
   5235                               PrototypeIterator::END_AT_NON_HIDDEN);
   5236        !iter.IsAtEnd(); iter.Advance()) {
   5237     JSObject* current = iter.GetCurrent<JSObject>();
   5238     if (signature->IsTemplateFor(current)) return current;
   5239   }
   5240   return nullptr;
   5241 }
   5242 
   5243 template <bool is_construct>
   5244 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
   5245     Isolate* isolate, Handle<HeapObject> function,
   5246     Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
   5247     Handle<Object> receiver, BuiltinArguments args) {
   5248   Handle<JSObject> js_receiver;
   5249   JSObject* raw_holder;
   5250   if (is_construct) {
   5251     DCHECK(args.receiver()->IsTheHole(isolate));
   5252     if (fun_data->instance_template()->IsUndefined(isolate)) {
   5253       v8::Local<ObjectTemplate> templ =
   5254           ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate),
   5255                               ToApiHandle<v8::FunctionTemplate>(fun_data));
   5256       fun_data->set_instance_template(*Utils::OpenHandle(*templ));
   5257     }
   5258     Handle<ObjectTemplateInfo> instance_template(
   5259         ObjectTemplateInfo::cast(fun_data->instance_template()), isolate);
   5260     ASSIGN_RETURN_ON_EXCEPTION(
   5261         isolate, js_receiver,
   5262         ApiNatives::InstantiateObject(instance_template,
   5263                                       Handle<JSReceiver>::cast(new_target)),
   5264         Object);
   5265     args[0] = *js_receiver;
   5266     DCHECK_EQ(*js_receiver, *args.receiver());
   5267 
   5268     raw_holder = *js_receiver;
   5269   } else {
   5270     DCHECK(receiver->IsJSReceiver());
   5271 
   5272     if (!receiver->IsJSObject()) {
   5273       // This function cannot be called with the given receiver.  Abort!
   5274       THROW_NEW_ERROR(
   5275           isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
   5276     }
   5277 
   5278     js_receiver = Handle<JSObject>::cast(receiver);
   5279 
   5280     if (!fun_data->accept_any_receiver() &&
   5281         js_receiver->IsAccessCheckNeeded() &&
   5282         !isolate->MayAccess(handle(isolate->context()), js_receiver)) {
   5283       isolate->ReportFailedAccessCheck(js_receiver);
   5284       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   5285     }
   5286 
   5287     raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver);
   5288 
   5289     if (raw_holder == nullptr) {
   5290       // This function cannot be called with the given receiver.  Abort!
   5291       THROW_NEW_ERROR(
   5292           isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
   5293     }
   5294   }
   5295 
   5296   Object* raw_call_data = fun_data->call_code();
   5297   if (!raw_call_data->IsUndefined(isolate)) {
   5298     DCHECK(raw_call_data->IsCallHandlerInfo());
   5299     CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
   5300     Object* callback_obj = call_data->callback();
   5301     v8::FunctionCallback callback =
   5302         v8::ToCData<v8::FunctionCallback>(callback_obj);
   5303     Object* data_obj = call_data->data();
   5304 
   5305     LOG(isolate, ApiObjectAccess("call", JSObject::cast(*js_receiver)));
   5306 
   5307     FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
   5308                                      *new_target, &args[0] - 1,
   5309                                      args.length() - 1);
   5310 
   5311     Handle<Object> result = custom.Call(callback);
   5312 
   5313     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   5314     if (result.is_null()) {
   5315       if (is_construct) return js_receiver;
   5316       return isolate->factory()->undefined_value();
   5317     }
   5318     // Rebox the result.
   5319     result->VerifyApiCallResultType();
   5320     if (!is_construct || result->IsJSObject()) return handle(*result, isolate);
   5321   }
   5322 
   5323   return js_receiver;
   5324 }
   5325 
   5326 }  // namespace
   5327 
   5328 
   5329 BUILTIN(HandleApiCall) {
   5330   HandleScope scope(isolate);
   5331   Handle<JSFunction> function = args.target<JSFunction>();
   5332   Handle<Object> receiver = args.receiver();
   5333   Handle<HeapObject> new_target = args.new_target();
   5334   Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(),
   5335                                         isolate);
   5336   if (new_target->IsJSReceiver()) {
   5337     RETURN_RESULT_OR_FAILURE(
   5338         isolate, HandleApiCallHelper<true>(isolate, function, new_target,
   5339                                            fun_data, receiver, args));
   5340   } else {
   5341     RETURN_RESULT_OR_FAILURE(
   5342         isolate, HandleApiCallHelper<false>(isolate, function, new_target,
   5343                                             fun_data, receiver, args));
   5344   }
   5345 }
   5346 
   5347 
   5348 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode,
   5349                                     TailCallMode tail_call_mode) {
   5350   switch (tail_call_mode) {
   5351     case TailCallMode::kDisallow:
   5352       switch (mode) {
   5353         case ConvertReceiverMode::kNullOrUndefined:
   5354           return CallFunction_ReceiverIsNullOrUndefined();
   5355         case ConvertReceiverMode::kNotNullOrUndefined:
   5356           return CallFunction_ReceiverIsNotNullOrUndefined();
   5357         case ConvertReceiverMode::kAny:
   5358           return CallFunction_ReceiverIsAny();
   5359       }
   5360       break;
   5361     case TailCallMode::kAllow:
   5362       switch (mode) {
   5363         case ConvertReceiverMode::kNullOrUndefined:
   5364           return TailCallFunction_ReceiverIsNullOrUndefined();
   5365         case ConvertReceiverMode::kNotNullOrUndefined:
   5366           return TailCallFunction_ReceiverIsNotNullOrUndefined();
   5367         case ConvertReceiverMode::kAny:
   5368           return TailCallFunction_ReceiverIsAny();
   5369       }
   5370       break;
   5371   }
   5372   UNREACHABLE();
   5373   return Handle<Code>::null();
   5374 }
   5375 
   5376 Handle<Code> Builtins::Call(ConvertReceiverMode mode,
   5377                             TailCallMode tail_call_mode) {
   5378   switch (tail_call_mode) {
   5379     case TailCallMode::kDisallow:
   5380       switch (mode) {
   5381         case ConvertReceiverMode::kNullOrUndefined:
   5382           return Call_ReceiverIsNullOrUndefined();
   5383         case ConvertReceiverMode::kNotNullOrUndefined:
   5384           return Call_ReceiverIsNotNullOrUndefined();
   5385         case ConvertReceiverMode::kAny:
   5386           return Call_ReceiverIsAny();
   5387       }
   5388       break;
   5389     case TailCallMode::kAllow:
   5390       switch (mode) {
   5391         case ConvertReceiverMode::kNullOrUndefined:
   5392           return TailCall_ReceiverIsNullOrUndefined();
   5393         case ConvertReceiverMode::kNotNullOrUndefined:
   5394           return TailCall_ReceiverIsNotNullOrUndefined();
   5395         case ConvertReceiverMode::kAny:
   5396           return TailCall_ReceiverIsAny();
   5397       }
   5398       break;
   5399   }
   5400   UNREACHABLE();
   5401   return Handle<Code>::null();
   5402 }
   5403 
   5404 Handle<Code> Builtins::CallBoundFunction(TailCallMode tail_call_mode) {
   5405   switch (tail_call_mode) {
   5406     case TailCallMode::kDisallow:
   5407       return CallBoundFunction();
   5408     case TailCallMode::kAllow:
   5409       return TailCallBoundFunction();
   5410   }
   5411   UNREACHABLE();
   5412   return Handle<Code>::null();
   5413 }
   5414 
   5415 Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode) {
   5416   switch (tail_call_mode) {
   5417     case TailCallMode::kDisallow:
   5418       return InterpreterPushArgsAndCall();
   5419     case TailCallMode::kAllow:
   5420       return InterpreterPushArgsAndTailCall();
   5421   }
   5422   UNREACHABLE();
   5423   return Handle<Code>::null();
   5424 }
   5425 
   5426 namespace {
   5427 
   5428 class RelocatableArguments : public BuiltinArguments, public Relocatable {
   5429  public:
   5430   RelocatableArguments(Isolate* isolate, int length, Object** arguments)
   5431       : BuiltinArguments(length, arguments), Relocatable(isolate) {}
   5432 
   5433   virtual inline void IterateInstance(ObjectVisitor* v) {
   5434     if (length() == 0) return;
   5435     v->VisitPointers(lowest_address(), highest_address() + 1);
   5436   }
   5437 
   5438  private:
   5439   DISALLOW_COPY_AND_ASSIGN(RelocatableArguments);
   5440 };
   5441 
   5442 }  // namespace
   5443 
   5444 MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate,
   5445                                                 Handle<HeapObject> function,
   5446                                                 Handle<Object> receiver,
   5447                                                 int argc,
   5448                                                 Handle<Object> args[]) {
   5449   DCHECK(function->IsFunctionTemplateInfo() ||
   5450          (function->IsJSFunction() &&
   5451           JSFunction::cast(*function)->shared()->IsApiFunction()));
   5452 
   5453   // Do proper receiver conversion for non-strict mode api functions.
   5454   if (!receiver->IsJSReceiver()) {
   5455     if (function->IsFunctionTemplateInfo() ||
   5456         is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
   5457       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
   5458                                  Object::ConvertReceiver(isolate, receiver),
   5459                                  Object);
   5460     }
   5461   }
   5462 
   5463   Handle<FunctionTemplateInfo> fun_data =
   5464       function->IsFunctionTemplateInfo()
   5465           ? Handle<FunctionTemplateInfo>::cast(function)
   5466           : handle(JSFunction::cast(*function)->shared()->get_api_func_data(),
   5467                    isolate);
   5468   Handle<HeapObject> new_target = isolate->factory()->undefined_value();
   5469   // Construct BuiltinArguments object:
   5470   // new target, function, arguments reversed, receiver.
   5471   const int kBufferSize = 32;
   5472   Object* small_argv[kBufferSize];
   5473   Object** argv;
   5474   if (argc + 3 <= kBufferSize) {
   5475     argv = small_argv;
   5476   } else {
   5477     argv = new Object*[argc + 3];
   5478   }
   5479   argv[argc + 2] = *receiver;
   5480   for (int i = 0; i < argc; ++i) {
   5481     argv[argc - i + 1] = *args[i];
   5482   }
   5483   argv[1] = *function;
   5484   argv[0] = *new_target;
   5485   MaybeHandle<Object> result;
   5486   {
   5487     RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2);
   5488     result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data,
   5489                                         receiver, arguments);
   5490   }
   5491   if (argv != small_argv) delete[] argv;
   5492   return result;
   5493 }
   5494 
   5495 
   5496 // Helper function to handle calls to non-function objects created through the
   5497 // API. The object can be called as either a constructor (using new) or just as
   5498 // a function (without new).
   5499 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
   5500     Isolate* isolate, bool is_construct_call, BuiltinArguments args) {
   5501   Handle<Object> receiver = args.receiver();
   5502 
   5503   // Get the object called.
   5504   JSObject* obj = JSObject::cast(*receiver);
   5505 
   5506   // Set the new target.
   5507   HeapObject* new_target;
   5508   if (is_construct_call) {
   5509     // TODO(adamk): This should be passed through in args instead of
   5510     // being patched in here. We need to set a non-undefined value
   5511     // for v8::FunctionCallbackInfo::IsConstructCall() to get the
   5512     // right answer.
   5513     new_target = obj;
   5514   } else {
   5515     new_target = isolate->heap()->undefined_value();
   5516   }
   5517 
   5518   // Get the invocation callback from the function descriptor that was
   5519   // used to create the called object.
   5520   DCHECK(obj->map()->is_callable());
   5521   JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor());
   5522   // TODO(ishell): turn this back to a DCHECK.
   5523   CHECK(constructor->shared()->IsApiFunction());
   5524   Object* handler =
   5525       constructor->shared()->get_api_func_data()->instance_call_handler();
   5526   DCHECK(!handler->IsUndefined(isolate));
   5527   // TODO(ishell): remove this debugging code.
   5528   CHECK(handler->IsCallHandlerInfo());
   5529   CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
   5530   Object* callback_obj = call_data->callback();
   5531   v8::FunctionCallback callback =
   5532       v8::ToCData<v8::FunctionCallback>(callback_obj);
   5533 
   5534   // Get the data for the call and perform the callback.
   5535   Object* result;
   5536   {
   5537     HandleScope scope(isolate);
   5538     LOG(isolate, ApiObjectAccess("call non-function", obj));
   5539 
   5540     FunctionCallbackArguments custom(isolate, call_data->data(), constructor,
   5541                                      obj, new_target, &args[0] - 1,
   5542                                      args.length() - 1);
   5543     Handle<Object> result_handle = custom.Call(callback);
   5544     if (result_handle.is_null()) {
   5545       result = isolate->heap()->undefined_value();
   5546     } else {
   5547       result = *result_handle;
   5548     }
   5549   }
   5550   // Check for exceptions and return result.
   5551   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5552   return result;
   5553 }
   5554 
   5555 
   5556 // Handle calls to non-function objects created through the API. This delegate
   5557 // function is used when the call is a normal function call.
   5558 BUILTIN(HandleApiCallAsFunction) {
   5559   return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
   5560 }
   5561 
   5562 
   5563 // Handle calls to non-function objects created through the API. This delegate
   5564 // function is used when the call is a construct call.
   5565 BUILTIN(HandleApiCallAsConstructor) {
   5566   return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
   5567 }
   5568 
   5569 namespace {
   5570 
   5571 void Generate_LoadIC_Miss(CodeStubAssembler* assembler) {
   5572   typedef compiler::Node Node;
   5573 
   5574   Node* receiver = assembler->Parameter(0);
   5575   Node* name = assembler->Parameter(1);
   5576   Node* slot = assembler->Parameter(2);
   5577   Node* vector = assembler->Parameter(3);
   5578   Node* context = assembler->Parameter(4);
   5579 
   5580   assembler->TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name,
   5581                              slot, vector);
   5582 }
   5583 
   5584 void Generate_LoadGlobalIC_Miss(CodeStubAssembler* assembler) {
   5585   typedef compiler::Node Node;
   5586 
   5587   Node* slot = assembler->Parameter(0);
   5588   Node* vector = assembler->Parameter(1);
   5589   Node* context = assembler->Parameter(2);
   5590 
   5591   assembler->TailCallRuntime(Runtime::kLoadGlobalIC_Miss, context, slot,
   5592                              vector);
   5593 }
   5594 
   5595 void Generate_LoadIC_Normal(MacroAssembler* masm) {
   5596   LoadIC::GenerateNormal(masm);
   5597 }
   5598 
   5599 void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
   5600   NamedLoadHandlerCompiler::GenerateLoadViaGetterForDeopt(masm);
   5601 }
   5602 
   5603 void Generate_LoadIC_Slow(CodeStubAssembler* assembler) {
   5604   typedef compiler::Node Node;
   5605 
   5606   Node* receiver = assembler->Parameter(0);
   5607   Node* name = assembler->Parameter(1);
   5608   // Node* slot = assembler->Parameter(2);
   5609   // Node* vector = assembler->Parameter(3);
   5610   Node* context = assembler->Parameter(4);
   5611 
   5612   assembler->TailCallRuntime(Runtime::kGetProperty, context, receiver, name);
   5613 }
   5614 
   5615 void Generate_LoadGlobalIC_Slow(CodeStubAssembler* assembler) {
   5616   typedef compiler::Node Node;
   5617 
   5618   Node* slot = assembler->Parameter(0);
   5619   Node* vector = assembler->Parameter(1);
   5620   Node* context = assembler->Parameter(2);
   5621 
   5622   assembler->TailCallRuntime(Runtime::kLoadGlobalIC_Slow, context, slot,
   5623                              vector);
   5624 }
   5625 
   5626 void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
   5627   KeyedLoadIC::GenerateRuntimeGetProperty(masm);
   5628 }
   5629 
   5630 void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
   5631   KeyedLoadIC::GenerateMiss(masm);
   5632 }
   5633 
   5634 void Generate_KeyedLoadIC_Megamorphic(MacroAssembler* masm) {
   5635   KeyedLoadIC::GenerateMegamorphic(masm);
   5636 }
   5637 
   5638 void Generate_StoreIC_Miss(MacroAssembler* masm) {
   5639   StoreIC::GenerateMiss(masm);
   5640 }
   5641 
   5642 void Generate_StoreIC_Normal(MacroAssembler* masm) {
   5643   StoreIC::GenerateNormal(masm);
   5644 }
   5645 
   5646 void Generate_StoreIC_Slow(MacroAssembler* masm) {
   5647   NamedStoreHandlerCompiler::GenerateSlow(masm);
   5648 }
   5649 
   5650 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
   5651   ElementHandlerCompiler::GenerateStoreSlow(masm);
   5652 }
   5653 
   5654 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
   5655   NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
   5656 }
   5657 
   5658 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) {
   5659   KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY);
   5660 }
   5661 
   5662 void Generate_KeyedStoreIC_Megamorphic_Strict(MacroAssembler* masm) {
   5663   KeyedStoreIC::GenerateMegamorphic(masm, STRICT);
   5664 }
   5665 
   5666 void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
   5667   KeyedStoreIC::GenerateMiss(masm);
   5668 }
   5669 
   5670 void Generate_Return_DebugBreak(MacroAssembler* masm) {
   5671   DebugCodegen::GenerateDebugBreakStub(masm,
   5672                                        DebugCodegen::SAVE_RESULT_REGISTER);
   5673 }
   5674 
   5675 void Generate_Slot_DebugBreak(MacroAssembler* masm) {
   5676   DebugCodegen::GenerateDebugBreakStub(masm,
   5677                                        DebugCodegen::IGNORE_RESULT_REGISTER);
   5678 }
   5679 
   5680 void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
   5681   DebugCodegen::GenerateFrameDropperLiveEdit(masm);
   5682 }
   5683 
   5684 }  // namespace
   5685 
   5686 Builtins::Builtins() : initialized_(false) {
   5687   memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
   5688   memset(names_, 0, sizeof(names_[0]) * builtin_count);
   5689 }
   5690 
   5691 
   5692 Builtins::~Builtins() {
   5693 }
   5694 
   5695 #define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name),
   5696 Address const Builtins::c_functions_[cfunction_count] = {
   5697   BUILTIN_LIST_C(DEF_ENUM_C)
   5698 };
   5699 #undef DEF_ENUM_C
   5700 
   5701 
   5702 struct BuiltinDesc {
   5703   Handle<Code> (*builder)(Isolate*, struct BuiltinDesc const*);
   5704   byte* generator;
   5705   byte* c_code;
   5706   const char* s_name;  // name is only used for generating log information.
   5707   int name;
   5708   Code::Flags flags;
   5709   int argc;
   5710 };
   5711 
   5712 #define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} }
   5713 
   5714 class BuiltinFunctionTable {
   5715  public:
   5716   BuiltinDesc* functions() {
   5717     base::CallOnce(&once_, &Builtins::InitBuiltinFunctionTable);
   5718     return functions_;
   5719   }
   5720 
   5721   base::OnceType once_;
   5722   BuiltinDesc functions_[Builtins::builtin_count + 1];
   5723 
   5724   friend class Builtins;
   5725 };
   5726 
   5727 namespace {
   5728 
   5729 BuiltinFunctionTable builtin_function_table = BUILTIN_FUNCTION_TABLE_INIT;
   5730 
   5731 Handle<Code> MacroAssemblerBuilder(Isolate* isolate,
   5732                                    BuiltinDesc const* builtin_desc) {
   5733 // For now we generate builtin adaptor code into a stack-allocated
   5734 // buffer, before copying it into individual code objects. Be careful
   5735 // with alignment, some platforms don't like unaligned code.
   5736 #ifdef DEBUG
   5737   // We can generate a lot of debug code on Arm64.
   5738   const size_t buffer_size = 32 * KB;
   5739 #elif V8_TARGET_ARCH_PPC64
   5740   // 8 KB is insufficient on PPC64 when FLAG_debug_code is on.
   5741   const size_t buffer_size = 10 * KB;
   5742 #else
   5743   const size_t buffer_size = 8 * KB;
   5744 #endif
   5745   union {
   5746     int force_alignment;
   5747     byte buffer[buffer_size];  // NOLINT(runtime/arrays)
   5748   } u;
   5749 
   5750   MacroAssembler masm(isolate, u.buffer, sizeof(u.buffer),
   5751                       CodeObjectRequired::kYes);
   5752   // Generate the code/adaptor.
   5753   typedef void (*Generator)(MacroAssembler*, int);
   5754   Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator);
   5755   // We pass all arguments to the generator, but it may not use all of
   5756   // them.  This works because the first arguments are on top of the
   5757   // stack.
   5758   DCHECK(!masm.has_frame());
   5759   g(&masm, builtin_desc->name);
   5760   // Move the code into the object heap.
   5761   CodeDesc desc;
   5762   masm.GetCode(&desc);
   5763   Code::Flags flags = builtin_desc->flags;
   5764   return isolate->factory()->NewCode(desc, flags, masm.CodeObject());
   5765 }
   5766 
   5767 // Builder for builtins implemented in TurboFan with JS linkage.
   5768 Handle<Code> CodeStubAssemblerBuilderJS(Isolate* isolate,
   5769                                         BuiltinDesc const* builtin_desc) {
   5770   Zone zone(isolate->allocator());
   5771   CodeStubAssembler assembler(isolate, &zone, builtin_desc->argc,
   5772                               builtin_desc->flags, builtin_desc->s_name);
   5773   // Generate the code/adaptor.
   5774   typedef void (*Generator)(CodeStubAssembler*);
   5775   Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator);
   5776   g(&assembler);
   5777   return assembler.GenerateCode();
   5778 }
   5779 
   5780 // Builder for builtins implemented in TurboFan with CallStub linkage.
   5781 Handle<Code> CodeStubAssemblerBuilderCS(Isolate* isolate,
   5782                                         BuiltinDesc const* builtin_desc) {
   5783   Zone zone(isolate->allocator());
   5784   // The interface descriptor with given key must be initialized at this point
   5785   // and this construction just queries the details from the descriptors table.
   5786   CallInterfaceDescriptor descriptor(
   5787       isolate, static_cast<CallDescriptors::Key>(builtin_desc->argc));
   5788   // Ensure descriptor is already initialized.
   5789   DCHECK_NOT_NULL(descriptor.GetFunctionType());
   5790   CodeStubAssembler assembler(isolate, &zone, descriptor, builtin_desc->flags,
   5791                               builtin_desc->s_name);
   5792   // Generate the code/adaptor.
   5793   typedef void (*Generator)(CodeStubAssembler*);
   5794   Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator);
   5795   g(&assembler);
   5796   return assembler.GenerateCode();
   5797 }
   5798 
   5799 }  // namespace
   5800 
   5801 // Define array of pointers to generators and C builtin functions.
   5802 // We do this in a sort of roundabout way so that we can do the initialization
   5803 // within the lexical scope of Builtins:: and within a context where
   5804 // Code::Flags names a non-abstract type.
   5805 void Builtins::InitBuiltinFunctionTable() {
   5806   BuiltinDesc* functions = builtin_function_table.functions_;
   5807   functions[builtin_count].builder = nullptr;
   5808   functions[builtin_count].generator = nullptr;
   5809   functions[builtin_count].c_code = nullptr;
   5810   functions[builtin_count].s_name = nullptr;
   5811   functions[builtin_count].name = builtin_count;
   5812   functions[builtin_count].flags = static_cast<Code::Flags>(0);
   5813   functions[builtin_count].argc = 0;
   5814 
   5815 #define DEF_FUNCTION_PTR_C(aname)                         \
   5816   functions->builder = &MacroAssemblerBuilder;            \
   5817   functions->generator = FUNCTION_ADDR(Generate_Adaptor); \
   5818   functions->c_code = FUNCTION_ADDR(Builtin_##aname);     \
   5819   functions->s_name = #aname;                             \
   5820   functions->name = c_##aname;                            \
   5821   functions->flags = Code::ComputeFlags(Code::BUILTIN);   \
   5822   functions->argc = 0;                                    \
   5823   ++functions;
   5824 
   5825 #define DEF_FUNCTION_PTR_A(aname, kind, extra)              \
   5826   functions->builder = &MacroAssemblerBuilder;              \
   5827   functions->generator = FUNCTION_ADDR(Generate_##aname);   \
   5828   functions->c_code = NULL;                                 \
   5829   functions->s_name = #aname;                               \
   5830   functions->name = k##aname;                               \
   5831   functions->flags = Code::ComputeFlags(Code::kind, extra); \
   5832   functions->argc = 0;                                      \
   5833   ++functions;
   5834 
   5835 #define DEF_FUNCTION_PTR_T(aname, aargc)                  \
   5836   functions->builder = &CodeStubAssemblerBuilderJS;       \
   5837   functions->generator = FUNCTION_ADDR(Generate_##aname); \
   5838   functions->c_code = NULL;                               \
   5839   functions->s_name = #aname;                             \
   5840   functions->name = k##aname;                             \
   5841   functions->flags = Code::ComputeFlags(Code::BUILTIN);   \
   5842   functions->argc = aargc;                                \
   5843   ++functions;
   5844 
   5845 #define DEF_FUNCTION_PTR_S(aname, kind, extra, interface_descriptor) \
   5846   functions->builder = &CodeStubAssemblerBuilderCS;                  \
   5847   functions->generator = FUNCTION_ADDR(Generate_##aname);            \
   5848   functions->c_code = NULL;                                          \
   5849   functions->s_name = #aname;                                        \
   5850   functions->name = k##aname;                                        \
   5851   functions->flags = Code::ComputeFlags(Code::kind, extra);          \
   5852   functions->argc = CallDescriptors::interface_descriptor;           \
   5853   ++functions;
   5854 
   5855 #define DEF_FUNCTION_PTR_H(aname, kind)                     \
   5856   functions->builder = &MacroAssemblerBuilder;              \
   5857   functions->generator = FUNCTION_ADDR(Generate_##aname);   \
   5858   functions->c_code = NULL;                                 \
   5859   functions->s_name = #aname;                               \
   5860   functions->name = k##aname;                               \
   5861   functions->flags = Code::ComputeHandlerFlags(Code::kind); \
   5862   functions->argc = 0;                                      \
   5863   ++functions;
   5864 
   5865   BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
   5866   BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
   5867   BUILTIN_LIST_T(DEF_FUNCTION_PTR_T)
   5868   BUILTIN_LIST_S(DEF_FUNCTION_PTR_S)
   5869   BUILTIN_LIST_H(DEF_FUNCTION_PTR_H)
   5870   BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
   5871 
   5872 #undef DEF_FUNCTION_PTR_C
   5873 #undef DEF_FUNCTION_PTR_A
   5874 #undef DEF_FUNCTION_PTR_T
   5875 #undef DEF_FUNCTION_PTR_S
   5876 #undef DEF_FUNCTION_PTR_H
   5877 }
   5878 
   5879 
   5880 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
   5881   DCHECK(!initialized_);
   5882 
   5883   // Create a scope for the handles in the builtins.
   5884   HandleScope scope(isolate);
   5885 
   5886 #define INITIALIZE_CALL_DESCRIPTOR(name, kind, extra, interface_descriptor) \
   5887   { interface_descriptor##Descriptor descriptor(isolate); }
   5888   BUILTIN_LIST_S(INITIALIZE_CALL_DESCRIPTOR)
   5889 #undef INITIALIZE_CALL_DESCRIPTOR
   5890 
   5891   const BuiltinDesc* functions = builtin_function_table.functions();
   5892 
   5893   // Traverse the list of builtins and generate an adaptor in a
   5894   // separate code object for each one.
   5895   for (int i = 0; i < builtin_count; i++) {
   5896     if (create_heap_objects) {
   5897       Handle<Code> code = (*functions[i].builder)(isolate, functions + i);
   5898       // Log the event and add the code to the builtins array.
   5899       PROFILE(isolate,
   5900               CodeCreateEvent(CodeEventListener::BUILTIN_TAG,
   5901                               AbstractCode::cast(*code), functions[i].s_name));
   5902       builtins_[i] = *code;
   5903       code->set_builtin_index(i);
   5904 #ifdef ENABLE_DISASSEMBLER
   5905       if (FLAG_print_builtin_code) {
   5906         CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
   5907         OFStream os(trace_scope.file());
   5908         os << "Builtin: " << functions[i].s_name << "\n";
   5909         code->Disassemble(functions[i].s_name, os);
   5910         os << "\n";
   5911       }
   5912 #endif
   5913     } else {
   5914       // Deserializing. The values will be filled in during IterateBuiltins.
   5915       builtins_[i] = NULL;
   5916     }
   5917     names_[i] = functions[i].s_name;
   5918   }
   5919 
   5920   // Mark as initialized.
   5921   initialized_ = true;
   5922 }
   5923 
   5924 
   5925 void Builtins::TearDown() {
   5926   initialized_ = false;
   5927 }
   5928 
   5929 
   5930 void Builtins::IterateBuiltins(ObjectVisitor* v) {
   5931   v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);
   5932 }
   5933 
   5934 
   5935 const char* Builtins::Lookup(byte* pc) {
   5936   // may be called during initialization (disassembler!)
   5937   if (initialized_) {
   5938     for (int i = 0; i < builtin_count; i++) {
   5939       Code* entry = Code::cast(builtins_[i]);
   5940       if (entry->contains(pc)) {
   5941         return names_[i];
   5942       }
   5943     }
   5944   }
   5945   return NULL;
   5946 }
   5947 
   5948 
   5949 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) {
   5950   masm->TailCallRuntime(Runtime::kInterrupt);
   5951 }
   5952 
   5953 
   5954 void Builtins::Generate_StackCheck(MacroAssembler* masm) {
   5955   masm->TailCallRuntime(Runtime::kStackGuard);
   5956 }
   5957 
   5958 namespace {
   5959 
   5960 void ValidateSharedTypedArray(CodeStubAssembler* a, compiler::Node* tagged,
   5961                               compiler::Node* context,
   5962                               compiler::Node** out_instance_type,
   5963                               compiler::Node** out_backing_store) {
   5964   using namespace compiler;
   5965   CodeStubAssembler::Label is_smi(a), not_smi(a), is_typed_array(a),
   5966       not_typed_array(a), is_shared(a), not_shared(a), is_float_or_clamped(a),
   5967       not_float_or_clamped(a), invalid(a);
   5968 
   5969   // Fail if it is not a heap object.
   5970   a->Branch(a->WordIsSmi(tagged), &is_smi, &not_smi);
   5971   a->Bind(&is_smi);
   5972   a->Goto(&invalid);
   5973 
   5974   // Fail if the array's instance type is not JSTypedArray.
   5975   a->Bind(&not_smi);
   5976   a->Branch(a->WordEqual(a->LoadInstanceType(tagged),
   5977                          a->Int32Constant(JS_TYPED_ARRAY_TYPE)),
   5978             &is_typed_array, &not_typed_array);
   5979   a->Bind(&not_typed_array);
   5980   a->Goto(&invalid);
   5981 
   5982   // Fail if the array's JSArrayBuffer is not shared.
   5983   a->Bind(&is_typed_array);
   5984   Node* array_buffer = a->LoadObjectField(tagged, JSTypedArray::kBufferOffset);
   5985   Node* is_buffer_shared = a->BitFieldDecode<JSArrayBuffer::IsShared>(
   5986       a->LoadObjectField(array_buffer, JSArrayBuffer::kBitFieldSlot));
   5987   a->Branch(is_buffer_shared, &is_shared, &not_shared);
   5988   a->Bind(&not_shared);
   5989   a->Goto(&invalid);
   5990 
   5991   // Fail if the array's element type is float32, float64 or clamped.
   5992   a->Bind(&is_shared);
   5993   Node* elements_instance_type = a->LoadInstanceType(
   5994       a->LoadObjectField(tagged, JSObject::kElementsOffset));
   5995   STATIC_ASSERT(FIXED_INT8_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
   5996   STATIC_ASSERT(FIXED_INT16_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
   5997   STATIC_ASSERT(FIXED_INT32_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
   5998   STATIC_ASSERT(FIXED_UINT8_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
   5999   STATIC_ASSERT(FIXED_UINT16_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
   6000   STATIC_ASSERT(FIXED_UINT32_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
   6001   a->Branch(a->Int32LessThan(elements_instance_type,
   6002                              a->Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)),
   6003             &not_float_or_clamped, &is_float_or_clamped);
   6004   a->Bind(&is_float_or_clamped);
   6005   a->Goto(&invalid);
   6006 
   6007   a->Bind(&invalid);
   6008   a->CallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context,
   6009                  tagged);
   6010   a->Return(a->UndefinedConstant());
   6011 
   6012   a->Bind(&not_float_or_clamped);
   6013   *out_instance_type = elements_instance_type;
   6014 
   6015   Node* backing_store =
   6016       a->LoadObjectField(array_buffer, JSArrayBuffer::kBackingStoreOffset);
   6017   Node* byte_offset = a->ChangeUint32ToWord(a->TruncateTaggedToWord32(
   6018       context,
   6019       a->LoadObjectField(tagged, JSArrayBufferView::kByteOffsetOffset)));
   6020   *out_backing_store = a->IntPtrAdd(backing_store, byte_offset);
   6021 }
   6022 
   6023 // https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess
   6024 compiler::Node* ConvertTaggedAtomicIndexToWord32(CodeStubAssembler* a,
   6025                                                  compiler::Node* tagged,
   6026                                                  compiler::Node* context) {
   6027   using namespace compiler;
   6028   CodeStubAssembler::Variable var_result(a, MachineRepresentation::kWord32);
   6029 
   6030   Callable to_number = CodeFactory::ToNumber(a->isolate());
   6031   Node* number_index = a->CallStub(to_number, context, tagged);
   6032   CodeStubAssembler::Label done(a, &var_result);
   6033 
   6034   CodeStubAssembler::Label if_numberissmi(a), if_numberisnotsmi(a);
   6035   a->Branch(a->WordIsSmi(number_index), &if_numberissmi, &if_numberisnotsmi);
   6036 
   6037   a->Bind(&if_numberissmi);
   6038   {
   6039     var_result.Bind(a->SmiToWord32(number_index));
   6040     a->Goto(&done);
   6041   }
   6042 
   6043   a->Bind(&if_numberisnotsmi);
   6044   {
   6045     Node* number_index_value = a->LoadHeapNumberValue(number_index);
   6046     Node* access_index = a->TruncateFloat64ToWord32(number_index_value);
   6047     Node* test_index = a->ChangeInt32ToFloat64(access_index);
   6048 
   6049     CodeStubAssembler::Label if_indexesareequal(a), if_indexesarenotequal(a);
   6050     a->Branch(a->Float64Equal(number_index_value, test_index),
   6051               &if_indexesareequal, &if_indexesarenotequal);
   6052 
   6053     a->Bind(&if_indexesareequal);
   6054     {
   6055       var_result.Bind(access_index);
   6056       a->Goto(&done);
   6057     }
   6058 
   6059     a->Bind(&if_indexesarenotequal);
   6060     a->Return(
   6061         a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context));
   6062   }
   6063 
   6064   a->Bind(&done);
   6065   return var_result.value();
   6066 }
   6067 
   6068 void ValidateAtomicIndex(CodeStubAssembler* a, compiler::Node* index_word,
   6069                          compiler::Node* array_length_word,
   6070                          compiler::Node* context) {
   6071   using namespace compiler;
   6072   // Check if the index is in bounds. If not, throw RangeError.
   6073   CodeStubAssembler::Label if_inbounds(a), if_notinbounds(a);
   6074   a->Branch(
   6075       a->WordOr(a->Int32LessThan(index_word, a->Int32Constant(0)),
   6076                 a->Int32GreaterThanOrEqual(index_word, array_length_word)),
   6077       &if_notinbounds, &if_inbounds);
   6078   a->Bind(&if_notinbounds);
   6079   a->Return(
   6080       a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context));
   6081   a->Bind(&if_inbounds);
   6082 }
   6083 
   6084 }  // anonymous namespace
   6085 
   6086 void Builtins::Generate_AtomicsLoad(CodeStubAssembler* a) {
   6087   using namespace compiler;
   6088   Node* array = a->Parameter(1);
   6089   Node* index = a->Parameter(2);
   6090   Node* context = a->Parameter(3 + 2);
   6091 
   6092   Node* instance_type;
   6093   Node* backing_store;
   6094   ValidateSharedTypedArray(a, array, context, &instance_type, &backing_store);
   6095 
   6096   Node* index_word32 = ConvertTaggedAtomicIndexToWord32(a, index, context);
   6097   Node* array_length_word32 = a->TruncateTaggedToWord32(
   6098       context, a->LoadObjectField(array, JSTypedArray::kLengthOffset));
   6099   ValidateAtomicIndex(a, index_word32, array_length_word32, context);
   6100   Node* index_word = a->ChangeUint32ToWord(index_word32);
   6101 
   6102   CodeStubAssembler::Label i8(a), u8(a), i16(a), u16(a), i32(a), u32(a),
   6103       other(a);
   6104   int32_t case_values[] = {
   6105       FIXED_INT8_ARRAY_TYPE,   FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
   6106       FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
   6107   };
   6108   CodeStubAssembler::Label* case_labels[] = {
   6109       &i8, &u8, &i16, &u16, &i32, &u32,
   6110   };
   6111   a->Switch(instance_type, &other, case_values, case_labels,
   6112             arraysize(case_labels));
   6113 
   6114   a->Bind(&i8);
   6115   a->Return(
   6116       a->SmiTag(a->AtomicLoad(MachineType::Int8(), backing_store, index_word)));
   6117 
   6118   a->Bind(&u8);
   6119   a->Return(a->SmiTag(
   6120       a->AtomicLoad(MachineType::Uint8(), backing_store, index_word)));
   6121 
   6122   a->Bind(&i16);
   6123   a->Return(a->SmiTag(a->AtomicLoad(MachineType::Int16(), backing_store,
   6124                                     a->WordShl(index_word, 1))));
   6125 
   6126   a->Bind(&u16);
   6127   a->Return(a->SmiTag(a->AtomicLoad(MachineType::Uint16(), backing_store,
   6128                                     a->WordShl(index_word, 1))));
   6129 
   6130   a->Bind(&i32);
   6131   a->Return(a->ChangeInt32ToTagged(a->AtomicLoad(
   6132       MachineType::Int32(), backing_store, a->WordShl(index_word, 2))));
   6133 
   6134   a->Bind(&u32);
   6135   a->Return(a->ChangeUint32ToTagged(a->AtomicLoad(
   6136       MachineType::Uint32(), backing_store, a->WordShl(index_word, 2))));
   6137 
   6138   // This shouldn't happen, we've already validated the type.
   6139   a->Bind(&other);
   6140   a->Return(a->Int32Constant(0));
   6141 }
   6142 
   6143 void Builtins::Generate_AtomicsStore(CodeStubAssembler* a) {
   6144   using namespace compiler;
   6145   Node* array = a->Parameter(1);
   6146   Node* index = a->Parameter(2);
   6147   Node* value = a->Parameter(3);
   6148   Node* context = a->Parameter(4 + 2);
   6149 
   6150   Node* instance_type;
   6151   Node* backing_store;
   6152   ValidateSharedTypedArray(a, array, context, &instance_type, &backing_store);
   6153 
   6154   Node* index_word32 = ConvertTaggedAtomicIndexToWord32(a, index, context);
   6155   Node* array_length_word32 = a->TruncateTaggedToWord32(
   6156       context, a->LoadObjectField(array, JSTypedArray::kLengthOffset));
   6157   ValidateAtomicIndex(a, index_word32, array_length_word32, context);
   6158   Node* index_word = a->ChangeUint32ToWord(index_word32);
   6159 
   6160   Callable to_integer = CodeFactory::ToInteger(a->isolate());
   6161   Node* value_integer = a->CallStub(to_integer, context, value);
   6162   Node* value_word32 = a->TruncateTaggedToWord32(context, value_integer);
   6163 
   6164   CodeStubAssembler::Label u8(a), u16(a), u32(a), other(a);
   6165   int32_t case_values[] = {
   6166       FIXED_INT8_ARRAY_TYPE,   FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
   6167       FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
   6168   };
   6169   CodeStubAssembler::Label* case_labels[] = {
   6170       &u8, &u8, &u16, &u16, &u32, &u32,
   6171   };
   6172   a->Switch(instance_type, &other, case_values, case_labels,
   6173             arraysize(case_labels));
   6174 
   6175   a->Bind(&u8);
   6176   a->AtomicStore(MachineRepresentation::kWord8, backing_store, index_word,
   6177                  value_word32);
   6178   a->Return(value_integer);
   6179 
   6180   a->Bind(&u16);
   6181   a->SmiTag(a->AtomicStore(MachineRepresentation::kWord16, backing_store,
   6182                            a->WordShl(index_word, 1), value_word32));
   6183   a->Return(value_integer);
   6184 
   6185   a->Bind(&u32);
   6186   a->AtomicStore(MachineRepresentation::kWord32, backing_store,
   6187                  a->WordShl(index_word, 2), value_word32);
   6188   a->Return(value_integer);
   6189 
   6190   // This shouldn't happen, we've already validated the type.
   6191   a->Bind(&other);
   6192   a->Return(a->Int32Constant(0));
   6193 }
   6194 
   6195 #define DEFINE_BUILTIN_ACCESSOR_C(name)                                       \
   6196   Handle<Code> Builtins::name() {                                             \
   6197     Code** code_address = reinterpret_cast<Code**>(builtin_address(k##name)); \
   6198     return Handle<Code>(code_address);                                        \
   6199   }
   6200 #define DEFINE_BUILTIN_ACCESSOR_A(name, kind, extra)                          \
   6201   Handle<Code> Builtins::name() {                                             \
   6202     Code** code_address = reinterpret_cast<Code**>(builtin_address(k##name)); \
   6203     return Handle<Code>(code_address);                                        \
   6204   }
   6205 #define DEFINE_BUILTIN_ACCESSOR_T(name, argc)                                 \
   6206   Handle<Code> Builtins::name() {                                             \
   6207     Code** code_address = reinterpret_cast<Code**>(builtin_address(k##name)); \
   6208     return Handle<Code>(code_address);                                        \
   6209   }
   6210 #define DEFINE_BUILTIN_ACCESSOR_S(name, kind, extra, interface_descriptor)    \
   6211   Handle<Code> Builtins::name() {                                             \
   6212     Code** code_address = reinterpret_cast<Code**>(builtin_address(k##name)); \
   6213     return Handle<Code>(code_address);                                        \
   6214   }
   6215 #define DEFINE_BUILTIN_ACCESSOR_H(name, kind)               \
   6216 Handle<Code> Builtins::name() {                             \
   6217   Code** code_address =                                     \
   6218       reinterpret_cast<Code**>(builtin_address(k##name));   \
   6219   return Handle<Code>(code_address);                        \
   6220 }
   6221 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
   6222 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
   6223 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T)
   6224 BUILTIN_LIST_S(DEFINE_BUILTIN_ACCESSOR_S)
   6225 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
   6226 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
   6227 #undef DEFINE_BUILTIN_ACCESSOR_C
   6228 #undef DEFINE_BUILTIN_ACCESSOR_A
   6229 #undef DEFINE_BUILTIN_ACCESSOR_T
   6230 #undef DEFINE_BUILTIN_ACCESSOR_S
   6231 #undef DEFINE_BUILTIN_ACCESSOR_H
   6232 
   6233 }  // namespace internal
   6234 }  // namespace v8
   6235