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 <stdlib.h>
      6 #include <limits>
      7 
      8 #include "src/v8.h"
      9 
     10 #include "src/accessors.h"
     11 #include "src/allocation-site-scopes.h"
     12 #include "src/api.h"
     13 #include "src/arguments.h"
     14 #include "src/bailout-reason.h"
     15 #include "src/base/cpu.h"
     16 #include "src/base/platform/platform.h"
     17 #include "src/bootstrapper.h"
     18 #include "src/codegen.h"
     19 #include "src/compilation-cache.h"
     20 #include "src/compiler.h"
     21 #include "src/conversions.h"
     22 #include "src/cpu-profiler.h"
     23 #include "src/date.h"
     24 #include "src/dateparser-inl.h"
     25 #include "src/debug.h"
     26 #include "src/deoptimizer.h"
     27 #include "src/execution.h"
     28 #include "src/full-codegen.h"
     29 #include "src/global-handles.h"
     30 #include "src/isolate-inl.h"
     31 #include "src/json-parser.h"
     32 #include "src/json-stringifier.h"
     33 #include "src/jsregexp-inl.h"
     34 #include "src/jsregexp.h"
     35 #include "src/liveedit.h"
     36 #include "src/misc-intrinsics.h"
     37 #include "src/parser.h"
     38 #include "src/prototype.h"
     39 #include "src/runtime.h"
     40 #include "src/runtime-profiler.h"
     41 #include "src/scopeinfo.h"
     42 #include "src/smart-pointers.h"
     43 #include "src/string-search.h"
     44 #include "src/uri.h"
     45 #include "src/utils.h"
     46 #include "src/v8threads.h"
     47 #include "src/vm-state-inl.h"
     48 #include "third_party/fdlibm/fdlibm.h"
     49 
     50 #ifdef V8_I18N_SUPPORT
     51 #include "src/i18n.h"
     52 #include "unicode/brkiter.h"
     53 #include "unicode/calendar.h"
     54 #include "unicode/coll.h"
     55 #include "unicode/curramt.h"
     56 #include "unicode/datefmt.h"
     57 #include "unicode/dcfmtsym.h"
     58 #include "unicode/decimfmt.h"
     59 #include "unicode/dtfmtsym.h"
     60 #include "unicode/dtptngen.h"
     61 #include "unicode/locid.h"
     62 #include "unicode/numfmt.h"
     63 #include "unicode/numsys.h"
     64 #include "unicode/rbbi.h"
     65 #include "unicode/smpdtfmt.h"
     66 #include "unicode/timezone.h"
     67 #include "unicode/uchar.h"
     68 #include "unicode/ucol.h"
     69 #include "unicode/ucurr.h"
     70 #include "unicode/uloc.h"
     71 #include "unicode/unum.h"
     72 #include "unicode/uversion.h"
     73 #endif
     74 
     75 #ifndef _STLP_VENDOR_CSTD
     76 // STLPort doesn't import fpclassify and isless into the std namespace.
     77 using std::fpclassify;
     78 using std::isless;
     79 #endif
     80 
     81 namespace v8 {
     82 namespace internal {
     83 
     84 
     85 #define RUNTIME_ASSERT(value) \
     86   if (!(value)) return isolate->ThrowIllegalOperation();
     87 
     88 #define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
     89   if (!(value)) {                                                    \
     90     isolate->ThrowIllegalOperation();                                \
     91     return MaybeHandle<T>();                                         \
     92   }
     93 
     94 // Cast the given object to a value of the specified type and store
     95 // it in a variable with the given name.  If the object is not of the
     96 // expected type call IllegalOperation and return.
     97 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
     98   RUNTIME_ASSERT(args[index]->Is##Type());                           \
     99   Type* name = Type::cast(args[index]);
    100 
    101 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
    102   RUNTIME_ASSERT(args[index]->Is##Type());                           \
    103   Handle<Type> name = args.at<Type>(index);
    104 
    105 #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
    106   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    107   Handle<Object> name = args.at<Object>(index);
    108 
    109 // Cast the given object to a boolean and store it in a variable with
    110 // the given name.  If the object is not a boolean call IllegalOperation
    111 // and return.
    112 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
    113   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
    114   bool name = args[index]->IsTrue();
    115 
    116 // Cast the given argument to a Smi and store its value in an int variable
    117 // with the given name.  If the argument is not a Smi call IllegalOperation
    118 // and return.
    119 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
    120   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    121   int name = args.smi_at(index);
    122 
    123 // Cast the given argument to a double and store it in a variable with
    124 // the given name.  If the argument is not a number (as opposed to
    125 // the number not-a-number) call IllegalOperation and return.
    126 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
    127   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    128   double name = args.number_at(index);
    129 
    130 // Call the specified converter on the object *comand store the result in
    131 // a variable of the specified type with the given name.  If the
    132 // object is not a Number call IllegalOperation and return.
    133 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
    134   RUNTIME_ASSERT(obj->IsNumber());                                   \
    135   type name = NumberTo##Type(obj);
    136 
    137 
    138 // Cast the given argument to PropertyDetails and store its value in a
    139 // variable with the given name.  If the argument is not a Smi call
    140 // IllegalOperation and return.
    141 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
    142   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    143   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
    144 
    145 
    146 // Assert that the given argument has a valid value for a StrictMode
    147 // and store it in a StrictMode variable with the given name.
    148 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
    149   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    150   RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
    151                  args.smi_at(index) == SLOPPY);                      \
    152   StrictMode name = static_cast<StrictMode>(args.smi_at(index));
    153 
    154 
    155 // Assert that the given argument is a number within the Int32 range
    156 // and convert it to int32_t.  If the argument is not an Int32 call
    157 // IllegalOperation and return.
    158 #define CONVERT_INT32_ARG_CHECKED(name, index)                       \
    159   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    160   int32_t name = 0;                                                  \
    161   RUNTIME_ASSERT(args[index]->ToInt32(&name));
    162 
    163 
    164 static Handle<Map> ComputeObjectLiteralMap(
    165     Handle<Context> context,
    166     Handle<FixedArray> constant_properties,
    167     bool* is_result_from_cache) {
    168   Isolate* isolate = context->GetIsolate();
    169   int properties_length = constant_properties->length();
    170   int number_of_properties = properties_length / 2;
    171   // Check that there are only internal strings and array indices among keys.
    172   int number_of_string_keys = 0;
    173   for (int p = 0; p != properties_length; p += 2) {
    174     Object* key = constant_properties->get(p);
    175     uint32_t element_index = 0;
    176     if (key->IsInternalizedString()) {
    177       number_of_string_keys++;
    178     } else if (key->ToArrayIndex(&element_index)) {
    179       // An index key does not require space in the property backing store.
    180       number_of_properties--;
    181     } else {
    182       // Bail out as a non-internalized-string non-index key makes caching
    183       // impossible.
    184       // DCHECK to make sure that the if condition after the loop is false.
    185       DCHECK(number_of_string_keys != number_of_properties);
    186       break;
    187     }
    188   }
    189   // If we only have internalized strings and array indices among keys then we
    190   // can use the map cache in the native context.
    191   const int kMaxKeys = 10;
    192   if ((number_of_string_keys == number_of_properties) &&
    193       (number_of_string_keys < kMaxKeys)) {
    194     // Create the fixed array with the key.
    195     Handle<FixedArray> keys =
    196         isolate->factory()->NewFixedArray(number_of_string_keys);
    197     if (number_of_string_keys > 0) {
    198       int index = 0;
    199       for (int p = 0; p < properties_length; p += 2) {
    200         Object* key = constant_properties->get(p);
    201         if (key->IsInternalizedString()) {
    202           keys->set(index++, key);
    203         }
    204       }
    205       DCHECK(index == number_of_string_keys);
    206     }
    207     *is_result_from_cache = true;
    208     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
    209   }
    210   *is_result_from_cache = false;
    211   return Map::Create(isolate, number_of_properties);
    212 }
    213 
    214 
    215 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
    216     Isolate* isolate,
    217     Handle<FixedArray> literals,
    218     Handle<FixedArray> constant_properties);
    219 
    220 
    221 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
    222     Isolate* isolate,
    223     Handle<FixedArray> literals,
    224     Handle<FixedArray> constant_properties,
    225     bool should_have_fast_elements,
    226     bool has_function_literal) {
    227   // Get the native context from the literals array.  This is the
    228   // context in which the function was created and we use the object
    229   // function from this context to create the object literal.  We do
    230   // not use the object function from the current native context
    231   // because this might be the object function from another context
    232   // which we should not have access to.
    233   Handle<Context> context =
    234       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
    235 
    236   // In case we have function literals, we want the object to be in
    237   // slow properties mode for now. We don't go in the map cache because
    238   // maps with constant functions can't be shared if the functions are
    239   // not the same (which is the common case).
    240   bool is_result_from_cache = false;
    241   Handle<Map> map = has_function_literal
    242       ? Handle<Map>(context->object_function()->initial_map())
    243       : ComputeObjectLiteralMap(context,
    244                                 constant_properties,
    245                                 &is_result_from_cache);
    246 
    247   PretenureFlag pretenure_flag =
    248       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
    249 
    250   Handle<JSObject> boilerplate =
    251       isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
    252 
    253   // Normalize the elements of the boilerplate to save space if needed.
    254   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
    255 
    256   // Add the constant properties to the boilerplate.
    257   int length = constant_properties->length();
    258   bool should_transform =
    259       !is_result_from_cache && boilerplate->HasFastProperties();
    260   bool should_normalize = should_transform || has_function_literal;
    261   if (should_normalize) {
    262     // TODO(verwaest): We might not want to ever normalize here.
    263     JSObject::NormalizeProperties(
    264         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
    265   }
    266   // TODO(verwaest): Support tracking representations in the boilerplate.
    267   for (int index = 0; index < length; index +=2) {
    268     Handle<Object> key(constant_properties->get(index+0), isolate);
    269     Handle<Object> value(constant_properties->get(index+1), isolate);
    270     if (value->IsFixedArray()) {
    271       // The value contains the constant_properties of a
    272       // simple object or array literal.
    273       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
    274       ASSIGN_RETURN_ON_EXCEPTION(
    275           isolate, value,
    276           CreateLiteralBoilerplate(isolate, literals, array),
    277           Object);
    278     }
    279     MaybeHandle<Object> maybe_result;
    280     uint32_t element_index = 0;
    281     if (key->IsInternalizedString()) {
    282       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
    283         // Array index as string (uint32).
    284         if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
    285         maybe_result =
    286             JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
    287       } else {
    288         Handle<String> name(String::cast(*key));
    289         DCHECK(!name->AsArrayIndex(&element_index));
    290         maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
    291             boilerplate, name, value, NONE);
    292       }
    293     } else if (key->ToArrayIndex(&element_index)) {
    294       // Array index (uint32).
    295       if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
    296       maybe_result =
    297           JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
    298     } else {
    299       // Non-uint32 number.
    300       DCHECK(key->IsNumber());
    301       double num = key->Number();
    302       char arr[100];
    303       Vector<char> buffer(arr, arraysize(arr));
    304       const char* str = DoubleToCString(num, buffer);
    305       Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
    306       maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name,
    307                                                               value, NONE);
    308     }
    309     // If setting the property on the boilerplate throws an
    310     // exception, the exception is converted to an empty handle in
    311     // the handle based operations.  In that case, we need to
    312     // convert back to an exception.
    313     RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
    314   }
    315 
    316   // Transform to fast properties if necessary. For object literals with
    317   // containing function literals we defer this operation until after all
    318   // computed properties have been assigned so that we can generate
    319   // constant function properties.
    320   if (should_transform && !has_function_literal) {
    321     JSObject::MigrateSlowToFast(
    322         boilerplate, boilerplate->map()->unused_property_fields());
    323   }
    324 
    325   return boilerplate;
    326 }
    327 
    328 
    329 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
    330     Handle<Object> object,
    331     ElementsKind to_kind,
    332     Isolate* isolate) {
    333   HandleScope scope(isolate);
    334   if (!object->IsJSObject()) {
    335     isolate->ThrowIllegalOperation();
    336     return MaybeHandle<Object>();
    337   }
    338   ElementsKind from_kind =
    339       Handle<JSObject>::cast(object)->map()->elements_kind();
    340   if (Map::IsValidElementsTransition(from_kind, to_kind)) {
    341     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
    342     return object;
    343   }
    344   isolate->ThrowIllegalOperation();
    345   return MaybeHandle<Object>();
    346 }
    347 
    348 
    349 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
    350     Isolate* isolate,
    351     Handle<FixedArray> literals,
    352     Handle<FixedArray> elements) {
    353   // Create the JSArray.
    354   Handle<JSFunction> constructor(
    355       JSFunction::NativeContextFromLiterals(*literals)->array_function());
    356 
    357   PretenureFlag pretenure_flag =
    358       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
    359 
    360   Handle<JSArray> object = Handle<JSArray>::cast(
    361       isolate->factory()->NewJSObject(constructor, pretenure_flag));
    362 
    363   ElementsKind constant_elements_kind =
    364       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
    365   Handle<FixedArrayBase> constant_elements_values(
    366       FixedArrayBase::cast(elements->get(1)));
    367 
    368   { DisallowHeapAllocation no_gc;
    369     DCHECK(IsFastElementsKind(constant_elements_kind));
    370     Context* native_context = isolate->context()->native_context();
    371     Object* maps_array = native_context->js_array_maps();
    372     DCHECK(!maps_array->IsUndefined());
    373     Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
    374     object->set_map(Map::cast(map));
    375   }
    376 
    377   Handle<FixedArrayBase> copied_elements_values;
    378   if (IsFastDoubleElementsKind(constant_elements_kind)) {
    379     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
    380         Handle<FixedDoubleArray>::cast(constant_elements_values));
    381   } else {
    382     DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
    383     const bool is_cow =
    384         (constant_elements_values->map() ==
    385          isolate->heap()->fixed_cow_array_map());
    386     if (is_cow) {
    387       copied_elements_values = constant_elements_values;
    388 #if DEBUG
    389       Handle<FixedArray> fixed_array_values =
    390           Handle<FixedArray>::cast(copied_elements_values);
    391       for (int i = 0; i < fixed_array_values->length(); i++) {
    392         DCHECK(!fixed_array_values->get(i)->IsFixedArray());
    393       }
    394 #endif
    395     } else {
    396       Handle<FixedArray> fixed_array_values =
    397           Handle<FixedArray>::cast(constant_elements_values);
    398       Handle<FixedArray> fixed_array_values_copy =
    399           isolate->factory()->CopyFixedArray(fixed_array_values);
    400       copied_elements_values = fixed_array_values_copy;
    401       for (int i = 0; i < fixed_array_values->length(); i++) {
    402         if (fixed_array_values->get(i)->IsFixedArray()) {
    403           // The value contains the constant_properties of a
    404           // simple object or array literal.
    405           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
    406           Handle<Object> result;
    407           ASSIGN_RETURN_ON_EXCEPTION(
    408               isolate, result,
    409               CreateLiteralBoilerplate(isolate, literals, fa),
    410               Object);
    411           fixed_array_values_copy->set(i, *result);
    412         }
    413       }
    414     }
    415   }
    416   object->set_elements(*copied_elements_values);
    417   object->set_length(Smi::FromInt(copied_elements_values->length()));
    418 
    419   JSObject::ValidateElements(object);
    420   return object;
    421 }
    422 
    423 
    424 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
    425     Isolate* isolate,
    426     Handle<FixedArray> literals,
    427     Handle<FixedArray> array) {
    428   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
    429   const bool kHasNoFunctionLiteral = false;
    430   switch (CompileTimeValue::GetLiteralType(array)) {
    431     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
    432       return CreateObjectLiteralBoilerplate(isolate,
    433                                             literals,
    434                                             elements,
    435                                             true,
    436                                             kHasNoFunctionLiteral);
    437     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
    438       return CreateObjectLiteralBoilerplate(isolate,
    439                                             literals,
    440                                             elements,
    441                                             false,
    442                                             kHasNoFunctionLiteral);
    443     case CompileTimeValue::ARRAY_LITERAL:
    444       return Runtime::CreateArrayLiteralBoilerplate(
    445           isolate, literals, elements);
    446     default:
    447       UNREACHABLE();
    448       return MaybeHandle<Object>();
    449   }
    450 }
    451 
    452 
    453 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
    454   HandleScope scope(isolate);
    455   DCHECK(args.length() == 4);
    456   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    457   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    458   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    459   CONVERT_SMI_ARG_CHECKED(flags, 3);
    460   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    461   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    462 
    463   RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
    464 
    465   // Check if boilerplate exists. If not, create it first.
    466   Handle<Object> literal_site(literals->get(literals_index), isolate);
    467   Handle<AllocationSite> site;
    468   Handle<JSObject> boilerplate;
    469   if (*literal_site == isolate->heap()->undefined_value()) {
    470     Handle<Object> raw_boilerplate;
    471     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    472         isolate, raw_boilerplate,
    473         CreateObjectLiteralBoilerplate(
    474             isolate,
    475             literals,
    476             constant_properties,
    477             should_have_fast_elements,
    478             has_function_literal));
    479     boilerplate = Handle<JSObject>::cast(raw_boilerplate);
    480 
    481     AllocationSiteCreationContext creation_context(isolate);
    482     site = creation_context.EnterNewScope();
    483     RETURN_FAILURE_ON_EXCEPTION(
    484         isolate,
    485         JSObject::DeepWalk(boilerplate, &creation_context));
    486     creation_context.ExitScope(site, boilerplate);
    487 
    488     // Update the functions literal and return the boilerplate.
    489     literals->set(literals_index, *site);
    490   } else {
    491     site = Handle<AllocationSite>::cast(literal_site);
    492     boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
    493                                    isolate);
    494   }
    495 
    496   AllocationSiteUsageContext usage_context(isolate, site, true);
    497   usage_context.EnterNewScope();
    498   MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
    499       boilerplate, &usage_context);
    500   usage_context.ExitScope(site, boilerplate);
    501   Handle<Object> copy;
    502   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
    503   return *copy;
    504 }
    505 
    506 
    507 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
    508     Isolate* isolate,
    509     Handle<FixedArray> literals,
    510     int literals_index,
    511     Handle<FixedArray> elements) {
    512   // Check if boilerplate exists. If not, create it first.
    513   Handle<Object> literal_site(literals->get(literals_index), isolate);
    514   Handle<AllocationSite> site;
    515   if (*literal_site == isolate->heap()->undefined_value()) {
    516     DCHECK(*elements != isolate->heap()->empty_fixed_array());
    517     Handle<Object> boilerplate;
    518     ASSIGN_RETURN_ON_EXCEPTION(
    519         isolate, boilerplate,
    520         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
    521         AllocationSite);
    522 
    523     AllocationSiteCreationContext creation_context(isolate);
    524     site = creation_context.EnterNewScope();
    525     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
    526                            &creation_context).is_null()) {
    527       return Handle<AllocationSite>::null();
    528     }
    529     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
    530 
    531     literals->set(literals_index, *site);
    532   } else {
    533     site = Handle<AllocationSite>::cast(literal_site);
    534   }
    535 
    536   return site;
    537 }
    538 
    539 
    540 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
    541                                            Handle<FixedArray> literals,
    542                                            int literals_index,
    543                                            Handle<FixedArray> elements,
    544                                            int flags) {
    545   RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
    546                             literals_index < literals->length(), JSObject);
    547   Handle<AllocationSite> site;
    548   ASSIGN_RETURN_ON_EXCEPTION(
    549       isolate, site,
    550       GetLiteralAllocationSite(isolate, literals, literals_index, elements),
    551       JSObject);
    552 
    553   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
    554   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
    555   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
    556   usage_context.EnterNewScope();
    557   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
    558                                       ? JSObject::kNoHints
    559                                       : JSObject::kObjectIsShallow;
    560   MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
    561                                                   hints);
    562   usage_context.ExitScope(site, boilerplate);
    563   return copy;
    564 }
    565 
    566 
    567 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
    568   HandleScope scope(isolate);
    569   DCHECK(args.length() == 4);
    570   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    571   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    572   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    573   CONVERT_SMI_ARG_CHECKED(flags, 3);
    574 
    575   Handle<JSObject> result;
    576   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    577       CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
    578                              flags));
    579   return *result;
    580 }
    581 
    582 
    583 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
    584   HandleScope scope(isolate);
    585   DCHECK(args.length() == 3);
    586   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    587   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    588   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    589 
    590   Handle<JSObject> result;
    591   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    592      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
    593                             ArrayLiteral::kShallowElements));
    594   return *result;
    595 }
    596 
    597 
    598 RUNTIME_FUNCTION(Runtime_CreateSymbol) {
    599   HandleScope scope(isolate);
    600   DCHECK(args.length() == 1);
    601   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
    602   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    603   Handle<Symbol> symbol = isolate->factory()->NewSymbol();
    604   if (name->IsString()) symbol->set_name(*name);
    605   return *symbol;
    606 }
    607 
    608 
    609 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
    610   HandleScope scope(isolate);
    611   DCHECK(args.length() == 1);
    612   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
    613   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    614   Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
    615   if (name->IsString()) symbol->set_name(*name);
    616   return *symbol;
    617 }
    618 
    619 
    620 RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) {
    621   HandleScope scope(isolate);
    622   DCHECK(args.length() == 1);
    623   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
    624   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    625   Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol();
    626   if (name->IsString()) symbol->set_name(*name);
    627   return *symbol;
    628 }
    629 
    630 
    631 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateOwnSymbol) {
    632   HandleScope scope(isolate);
    633   DCHECK(args.length() == 1);
    634   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    635   Handle<JSObject> registry = isolate->GetSymbolRegistry();
    636   Handle<String> part = isolate->factory()->private_intern_string();
    637   Handle<Object> privates;
    638   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    639       isolate, privates, Object::GetPropertyOrElement(registry, part));
    640   Handle<Object> symbol;
    641   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    642       isolate, symbol, Object::GetPropertyOrElement(privates, name));
    643   if (!symbol->IsSymbol()) {
    644     DCHECK(symbol->IsUndefined());
    645     symbol = isolate->factory()->NewPrivateSymbol();
    646     Handle<Symbol>::cast(symbol)->set_name(*name);
    647     Handle<Symbol>::cast(symbol)->set_is_own(true);
    648     JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol,
    649                           STRICT).Assert();
    650   }
    651   return *symbol;
    652 }
    653 
    654 
    655 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
    656   HandleScope scope(isolate);
    657   DCHECK(args.length() == 1);
    658   CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
    659   return *Object::ToObject(isolate, symbol).ToHandleChecked();
    660 }
    661 
    662 
    663 RUNTIME_FUNCTION(Runtime_SymbolDescription) {
    664   SealHandleScope shs(isolate);
    665   DCHECK(args.length() == 1);
    666   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    667   return symbol->name();
    668 }
    669 
    670 
    671 RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
    672   HandleScope scope(isolate);
    673   DCHECK(args.length() == 0);
    674   return *isolate->GetSymbolRegistry();
    675 }
    676 
    677 
    678 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
    679   SealHandleScope shs(isolate);
    680   DCHECK(args.length() == 1);
    681   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    682   return isolate->heap()->ToBoolean(symbol->is_private());
    683 }
    684 
    685 
    686 RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
    687   HandleScope scope(isolate);
    688   DCHECK(args.length() == 2);
    689   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
    690   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
    691   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
    692   return *isolate->factory()->NewJSProxy(handler, prototype);
    693 }
    694 
    695 
    696 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
    697   HandleScope scope(isolate);
    698   DCHECK(args.length() == 4);
    699   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
    700   CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
    701   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
    702   CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
    703   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
    704   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
    705   return *isolate->factory()->NewJSFunctionProxy(
    706       handler, call_trap, construct_trap, prototype);
    707 }
    708 
    709 
    710 RUNTIME_FUNCTION(Runtime_IsJSProxy) {
    711   SealHandleScope shs(isolate);
    712   DCHECK(args.length() == 1);
    713   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
    714   return isolate->heap()->ToBoolean(obj->IsJSProxy());
    715 }
    716 
    717 
    718 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
    719   SealHandleScope shs(isolate);
    720   DCHECK(args.length() == 1);
    721   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
    722   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
    723 }
    724 
    725 
    726 RUNTIME_FUNCTION(Runtime_GetHandler) {
    727   SealHandleScope shs(isolate);
    728   DCHECK(args.length() == 1);
    729   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    730   return proxy->handler();
    731 }
    732 
    733 
    734 RUNTIME_FUNCTION(Runtime_GetCallTrap) {
    735   SealHandleScope shs(isolate);
    736   DCHECK(args.length() == 1);
    737   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    738   return proxy->call_trap();
    739 }
    740 
    741 
    742 RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
    743   SealHandleScope shs(isolate);
    744   DCHECK(args.length() == 1);
    745   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    746   return proxy->construct_trap();
    747 }
    748 
    749 
    750 RUNTIME_FUNCTION(Runtime_Fix) {
    751   HandleScope scope(isolate);
    752   DCHECK(args.length() == 1);
    753   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
    754   JSProxy::Fix(proxy);
    755   return isolate->heap()->undefined_value();
    756 }
    757 
    758 
    759 void Runtime::FreeArrayBuffer(Isolate* isolate,
    760                               JSArrayBuffer* phantom_array_buffer) {
    761   if (phantom_array_buffer->should_be_freed()) {
    762     DCHECK(phantom_array_buffer->is_external());
    763     free(phantom_array_buffer->backing_store());
    764   }
    765   if (phantom_array_buffer->is_external()) return;
    766 
    767   size_t allocated_length = NumberToSize(
    768       isolate, phantom_array_buffer->byte_length());
    769 
    770   reinterpret_cast<v8::Isolate*>(isolate)
    771       ->AdjustAmountOfExternalAllocatedMemory(
    772           -static_cast<int64_t>(allocated_length));
    773   CHECK(V8::ArrayBufferAllocator() != NULL);
    774   V8::ArrayBufferAllocator()->Free(
    775       phantom_array_buffer->backing_store(),
    776       allocated_length);
    777 }
    778 
    779 
    780 void Runtime::SetupArrayBuffer(Isolate* isolate,
    781                                Handle<JSArrayBuffer> array_buffer,
    782                                bool is_external,
    783                                void* data,
    784                                size_t allocated_length) {
    785   DCHECK(array_buffer->GetInternalFieldCount() ==
    786       v8::ArrayBuffer::kInternalFieldCount);
    787   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
    788     array_buffer->SetInternalField(i, Smi::FromInt(0));
    789   }
    790   array_buffer->set_backing_store(data);
    791   array_buffer->set_flag(Smi::FromInt(0));
    792   array_buffer->set_is_external(is_external);
    793 
    794   Handle<Object> byte_length =
    795       isolate->factory()->NewNumberFromSize(allocated_length);
    796   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
    797   array_buffer->set_byte_length(*byte_length);
    798 
    799   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
    800   isolate->heap()->set_array_buffers_list(*array_buffer);
    801   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
    802 }
    803 
    804 
    805 bool Runtime::SetupArrayBufferAllocatingData(
    806     Isolate* isolate,
    807     Handle<JSArrayBuffer> array_buffer,
    808     size_t allocated_length,
    809     bool initialize) {
    810   void* data;
    811   CHECK(V8::ArrayBufferAllocator() != NULL);
    812   if (allocated_length != 0) {
    813     if (initialize) {
    814       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
    815     } else {
    816       data =
    817           V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
    818     }
    819     if (data == NULL) return false;
    820   } else {
    821     data = NULL;
    822   }
    823 
    824   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
    825 
    826   reinterpret_cast<v8::Isolate*>(isolate)
    827       ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
    828 
    829   return true;
    830 }
    831 
    832 
    833 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
    834   Isolate* isolate = array_buffer->GetIsolate();
    835   for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
    836        !view_obj->IsUndefined();) {
    837     Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
    838     if (view->IsJSTypedArray()) {
    839       JSTypedArray::cast(*view)->Neuter();
    840     } else if (view->IsJSDataView()) {
    841       JSDataView::cast(*view)->Neuter();
    842     } else {
    843       UNREACHABLE();
    844     }
    845     view_obj = handle(view->weak_next(), isolate);
    846   }
    847   array_buffer->Neuter();
    848 }
    849 
    850 
    851 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
    852   HandleScope scope(isolate);
    853   DCHECK(args.length() == 2);
    854   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
    855   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
    856   if (!holder->byte_length()->IsUndefined()) {
    857     // ArrayBuffer is already initialized; probably a fuzz test.
    858     return *holder;
    859   }
    860   size_t allocated_length = 0;
    861   if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
    862     THROW_NEW_ERROR_RETURN_FAILURE(
    863         isolate, NewRangeError("invalid_array_buffer_length",
    864                                HandleVector<Object>(NULL, 0)));
    865   }
    866   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
    867                                                holder, allocated_length)) {
    868     THROW_NEW_ERROR_RETURN_FAILURE(
    869         isolate, NewRangeError("invalid_array_buffer_length",
    870                                HandleVector<Object>(NULL, 0)));
    871   }
    872   return *holder;
    873 }
    874 
    875 
    876 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
    877   SealHandleScope shs(isolate);
    878   DCHECK(args.length() == 1);
    879   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
    880   return holder->byte_length();
    881 }
    882 
    883 
    884 RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
    885   HandleScope scope(isolate);
    886   DCHECK(args.length() == 3);
    887   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
    888   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
    889   CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
    890   RUNTIME_ASSERT(!source.is_identical_to(target));
    891   size_t start = 0;
    892   RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
    893   size_t target_length = NumberToSize(isolate, target->byte_length());
    894 
    895   if (target_length == 0) return isolate->heap()->undefined_value();
    896 
    897   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
    898   RUNTIME_ASSERT(start <= source_byte_length);
    899   RUNTIME_ASSERT(source_byte_length - start >= target_length);
    900   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
    901   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
    902   CopyBytes(target_data, source_data + start, target_length);
    903   return isolate->heap()->undefined_value();
    904 }
    905 
    906 
    907 RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
    908   HandleScope scope(isolate);
    909   DCHECK(args.length() == 1);
    910   CONVERT_ARG_CHECKED(Object, object, 0);
    911   return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
    912 }
    913 
    914 
    915 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
    916   HandleScope scope(isolate);
    917   DCHECK(args.length() == 1);
    918   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
    919   if (array_buffer->backing_store() == NULL) {
    920     CHECK(Smi::FromInt(0) == array_buffer->byte_length());
    921     return isolate->heap()->undefined_value();
    922   }
    923   DCHECK(!array_buffer->is_external());
    924   void* backing_store = array_buffer->backing_store();
    925   size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
    926   array_buffer->set_is_external(true);
    927   Runtime::NeuterArrayBuffer(array_buffer);
    928   V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
    929   return isolate->heap()->undefined_value();
    930 }
    931 
    932 
    933 void Runtime::ArrayIdToTypeAndSize(
    934     int arrayId,
    935     ExternalArrayType* array_type,
    936     ElementsKind* external_elements_kind,
    937     ElementsKind* fixed_elements_kind,
    938     size_t* element_size) {
    939   switch (arrayId) {
    940 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
    941     case ARRAY_ID_##TYPE:                                                      \
    942       *array_type = kExternal##Type##Array;                                    \
    943       *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
    944       *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
    945       *element_size = size;                                                    \
    946       break;
    947 
    948     TYPED_ARRAYS(ARRAY_ID_CASE)
    949 #undef ARRAY_ID_CASE
    950 
    951     default:
    952       UNREACHABLE();
    953   }
    954 }
    955 
    956 
    957 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
    958   HandleScope scope(isolate);
    959   DCHECK(args.length() == 5);
    960   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
    961   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
    962   CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
    963   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
    964   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
    965 
    966   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
    967                  arrayId <= Runtime::ARRAY_ID_LAST);
    968 
    969   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
    970   size_t element_size = 1;  // Bogus initialization.
    971   ElementsKind external_elements_kind =
    972       EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
    973   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
    974   Runtime::ArrayIdToTypeAndSize(arrayId,
    975       &array_type,
    976       &external_elements_kind,
    977       &fixed_elements_kind,
    978       &element_size);
    979   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
    980 
    981   size_t byte_offset = 0;
    982   size_t byte_length = 0;
    983   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
    984   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
    985 
    986   if (maybe_buffer->IsJSArrayBuffer()) {
    987     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
    988     size_t array_buffer_byte_length =
    989         NumberToSize(isolate, buffer->byte_length());
    990     RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
    991     RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
    992   } else {
    993     RUNTIME_ASSERT(maybe_buffer->IsNull());
    994   }
    995 
    996   RUNTIME_ASSERT(byte_length % element_size == 0);
    997   size_t length = byte_length / element_size;
    998 
    999   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
   1000     THROW_NEW_ERROR_RETURN_FAILURE(
   1001         isolate, NewRangeError("invalid_typed_array_length",
   1002                                HandleVector<Object>(NULL, 0)));
   1003   }
   1004 
   1005   // All checks are done, now we can modify objects.
   1006 
   1007   DCHECK(holder->GetInternalFieldCount() ==
   1008       v8::ArrayBufferView::kInternalFieldCount);
   1009   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1010     holder->SetInternalField(i, Smi::FromInt(0));
   1011   }
   1012   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
   1013   holder->set_length(*length_obj);
   1014   holder->set_byte_offset(*byte_offset_object);
   1015   holder->set_byte_length(*byte_length_object);
   1016 
   1017   if (!maybe_buffer->IsNull()) {
   1018     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
   1019     holder->set_buffer(*buffer);
   1020     holder->set_weak_next(buffer->weak_first_view());
   1021     buffer->set_weak_first_view(*holder);
   1022 
   1023     Handle<ExternalArray> elements =
   1024         isolate->factory()->NewExternalArray(
   1025             static_cast<int>(length), array_type,
   1026             static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
   1027     Handle<Map> map =
   1028         JSObject::GetElementsTransitionMap(holder, external_elements_kind);
   1029     JSObject::SetMapAndElements(holder, map, elements);
   1030     DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
   1031   } else {
   1032     holder->set_buffer(Smi::FromInt(0));
   1033     holder->set_weak_next(isolate->heap()->undefined_value());
   1034     Handle<FixedTypedArrayBase> elements =
   1035         isolate->factory()->NewFixedTypedArray(
   1036             static_cast<int>(length), array_type);
   1037     holder->set_elements(*elements);
   1038   }
   1039   return isolate->heap()->undefined_value();
   1040 }
   1041 
   1042 
   1043 // Initializes a typed array from an array-like object.
   1044 // If an array-like object happens to be a typed array of the same type,
   1045 // initializes backing store using memove.
   1046 //
   1047 // Returns true if backing store was initialized or false otherwise.
   1048 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
   1049   HandleScope scope(isolate);
   1050   DCHECK(args.length() == 4);
   1051   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
   1052   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
   1053   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
   1054   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
   1055 
   1056   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
   1057                  arrayId <= Runtime::ARRAY_ID_LAST);
   1058 
   1059   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
   1060   size_t element_size = 1;  // Bogus initialization.
   1061   ElementsKind external_elements_kind =
   1062       EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
   1063   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
   1064   Runtime::ArrayIdToTypeAndSize(arrayId,
   1065       &array_type,
   1066       &external_elements_kind,
   1067       &fixed_elements_kind,
   1068       &element_size);
   1069 
   1070   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
   1071 
   1072   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
   1073   if (source->IsJSTypedArray() &&
   1074       JSTypedArray::cast(*source)->type() == array_type) {
   1075     length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
   1076   }
   1077   size_t length = 0;
   1078   RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
   1079 
   1080   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
   1081       (length > (kMaxInt / element_size))) {
   1082     THROW_NEW_ERROR_RETURN_FAILURE(
   1083         isolate, NewRangeError("invalid_typed_array_length",
   1084                                HandleVector<Object>(NULL, 0)));
   1085   }
   1086   size_t byte_length = length * element_size;
   1087 
   1088   DCHECK(holder->GetInternalFieldCount() ==
   1089       v8::ArrayBufferView::kInternalFieldCount);
   1090   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1091     holder->SetInternalField(i, Smi::FromInt(0));
   1092   }
   1093 
   1094   // NOTE: not initializing backing store.
   1095   // We assume that the caller of this function will initialize holder
   1096   // with the loop
   1097   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
   1098   // We assume that the caller of this function is always a typed array
   1099   // constructor.
   1100   // If source is a typed array, this loop will always run to completion,
   1101   // so we are sure that the backing store will be initialized.
   1102   // Otherwise, the indexing operation might throw, so the loop will not
   1103   // run to completion and the typed array might remain partly initialized.
   1104   // However we further assume that the caller of this function is a typed array
   1105   // constructor, and the exception will propagate out of the constructor,
   1106   // therefore uninitialized memory will not be accessible by a user program.
   1107   //
   1108   // TODO(dslomov): revise this once we support subclassing.
   1109 
   1110   if (!Runtime::SetupArrayBufferAllocatingData(
   1111         isolate, buffer, byte_length, false)) {
   1112     THROW_NEW_ERROR_RETURN_FAILURE(
   1113         isolate, NewRangeError("invalid_array_buffer_length",
   1114                                HandleVector<Object>(NULL, 0)));
   1115   }
   1116 
   1117   holder->set_buffer(*buffer);
   1118   holder->set_byte_offset(Smi::FromInt(0));
   1119   Handle<Object> byte_length_obj(
   1120       isolate->factory()->NewNumberFromSize(byte_length));
   1121   holder->set_byte_length(*byte_length_obj);
   1122   holder->set_length(*length_obj);
   1123   holder->set_weak_next(buffer->weak_first_view());
   1124   buffer->set_weak_first_view(*holder);
   1125 
   1126   Handle<ExternalArray> elements =
   1127       isolate->factory()->NewExternalArray(
   1128           static_cast<int>(length), array_type,
   1129           static_cast<uint8_t*>(buffer->backing_store()));
   1130   Handle<Map> map = JSObject::GetElementsTransitionMap(
   1131       holder, external_elements_kind);
   1132   JSObject::SetMapAndElements(holder, map, elements);
   1133 
   1134   if (source->IsJSTypedArray()) {
   1135     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
   1136 
   1137     if (typed_array->type() == holder->type()) {
   1138       uint8_t* backing_store =
   1139         static_cast<uint8_t*>(
   1140           typed_array->GetBuffer()->backing_store());
   1141       size_t source_byte_offset =
   1142           NumberToSize(isolate, typed_array->byte_offset());
   1143       memcpy(
   1144           buffer->backing_store(),
   1145           backing_store + source_byte_offset,
   1146           byte_length);
   1147       return isolate->heap()->true_value();
   1148     }
   1149   }
   1150 
   1151   return isolate->heap()->false_value();
   1152 }
   1153 
   1154 
   1155 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
   1156   RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
   1157     HandleScope scope(isolate);                                               \
   1158     DCHECK(args.length() == 1);                                               \
   1159     CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
   1160     return holder->accessor();                                                \
   1161   }
   1162 
   1163 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
   1164 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
   1165 BUFFER_VIEW_GETTER(TypedArray, Length, length)
   1166 BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
   1167 
   1168 #undef BUFFER_VIEW_GETTER
   1169 
   1170 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
   1171   HandleScope scope(isolate);
   1172   DCHECK(args.length() == 1);
   1173   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
   1174   return *holder->GetBuffer();
   1175 }
   1176 
   1177 
   1178 // Return codes for Runtime_TypedArraySetFastCases.
   1179 // Should be synchronized with typedarray.js natives.
   1180 enum TypedArraySetResultCodes {
   1181   // Set from typed array of the same type.
   1182   // This is processed by TypedArraySetFastCases
   1183   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
   1184   // Set from typed array of the different type, overlapping in memory.
   1185   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
   1186   // Set from typed array of the different type, non-overlapping.
   1187   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
   1188   // Set from non-typed array.
   1189   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
   1190 };
   1191 
   1192 
   1193 RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
   1194   HandleScope scope(isolate);
   1195   DCHECK(args.length() == 3);
   1196   if (!args[0]->IsJSTypedArray()) {
   1197     THROW_NEW_ERROR_RETURN_FAILURE(
   1198         isolate,
   1199         NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
   1200   }
   1201 
   1202   if (!args[1]->IsJSTypedArray())
   1203     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
   1204 
   1205   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
   1206   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
   1207   CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
   1208 
   1209   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
   1210   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
   1211   size_t offset = 0;
   1212   RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
   1213   size_t target_length = NumberToSize(isolate, target->length());
   1214   size_t source_length = NumberToSize(isolate, source->length());
   1215   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
   1216   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
   1217   if (offset > target_length || offset + source_length > target_length ||
   1218       offset + source_length < offset) {  // overflow
   1219     THROW_NEW_ERROR_RETURN_FAILURE(
   1220         isolate, NewRangeError("typed_array_set_source_too_large",
   1221                                HandleVector<Object>(NULL, 0)));
   1222   }
   1223 
   1224   size_t target_offset = NumberToSize(isolate, target->byte_offset());
   1225   size_t source_offset = NumberToSize(isolate, source->byte_offset());
   1226   uint8_t* target_base =
   1227       static_cast<uint8_t*>(
   1228         target->GetBuffer()->backing_store()) + target_offset;
   1229   uint8_t* source_base =
   1230       static_cast<uint8_t*>(
   1231         source->GetBuffer()->backing_store()) + source_offset;
   1232 
   1233   // Typed arrays of the same type: use memmove.
   1234   if (target->type() == source->type()) {
   1235     memmove(target_base + offset * target->element_size(),
   1236         source_base, source_byte_length);
   1237     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
   1238   }
   1239 
   1240   // Typed arrays of different types over the same backing store
   1241   if ((source_base <= target_base &&
   1242         source_base + source_byte_length > target_base) ||
   1243       (target_base <= source_base &&
   1244         target_base + target_byte_length > source_base)) {
   1245     // We do not support overlapping ArrayBuffers
   1246     DCHECK(
   1247       target->GetBuffer()->backing_store() ==
   1248       source->GetBuffer()->backing_store());
   1249     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
   1250   } else {  // Non-overlapping typed arrays
   1251     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
   1252   }
   1253 }
   1254 
   1255 
   1256 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
   1257   DCHECK(args.length() == 0);
   1258   DCHECK_OBJECT_SIZE(
   1259       FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
   1260   return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
   1261 }
   1262 
   1263 
   1264 RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
   1265   HandleScope scope(isolate);
   1266   DCHECK(args.length() == 4);
   1267   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
   1268   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
   1269   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
   1270   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
   1271 
   1272   DCHECK(holder->GetInternalFieldCount() ==
   1273       v8::ArrayBufferView::kInternalFieldCount);
   1274   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1275     holder->SetInternalField(i, Smi::FromInt(0));
   1276   }
   1277   size_t buffer_length = 0;
   1278   size_t offset = 0;
   1279   size_t length = 0;
   1280   RUNTIME_ASSERT(
   1281       TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
   1282   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
   1283   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
   1284 
   1285   // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
   1286   // Entire range [offset, offset + length] must be in bounds.
   1287   RUNTIME_ASSERT(offset <= buffer_length);
   1288   RUNTIME_ASSERT(offset + length <= buffer_length);
   1289   // No overflow.
   1290   RUNTIME_ASSERT(offset + length >= offset);
   1291 
   1292   holder->set_buffer(*buffer);
   1293   holder->set_byte_offset(*byte_offset);
   1294   holder->set_byte_length(*byte_length);
   1295 
   1296   holder->set_weak_next(buffer->weak_first_view());
   1297   buffer->set_weak_first_view(*holder);
   1298 
   1299   return isolate->heap()->undefined_value();
   1300 }
   1301 
   1302 
   1303 inline static bool NeedToFlipBytes(bool is_little_endian) {
   1304 #ifdef V8_TARGET_LITTLE_ENDIAN
   1305   return !is_little_endian;
   1306 #else
   1307   return is_little_endian;
   1308 #endif
   1309 }
   1310 
   1311 
   1312 template<int n>
   1313 inline void CopyBytes(uint8_t* target, uint8_t* source) {
   1314   for (int i = 0; i < n; i++) {
   1315     *(target++) = *(source++);
   1316   }
   1317 }
   1318 
   1319 
   1320 template<int n>
   1321 inline void FlipBytes(uint8_t* target, uint8_t* source) {
   1322   source = source + (n-1);
   1323   for (int i = 0; i < n; i++) {
   1324     *(target++) = *(source--);
   1325   }
   1326 }
   1327 
   1328 
   1329 template<typename T>
   1330 inline static bool DataViewGetValue(
   1331     Isolate* isolate,
   1332     Handle<JSDataView> data_view,
   1333     Handle<Object> byte_offset_obj,
   1334     bool is_little_endian,
   1335     T* result) {
   1336   size_t byte_offset = 0;
   1337   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
   1338     return false;
   1339   }
   1340   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1341 
   1342   size_t data_view_byte_offset =
   1343       NumberToSize(isolate, data_view->byte_offset());
   1344   size_t data_view_byte_length =
   1345       NumberToSize(isolate, data_view->byte_length());
   1346   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1347       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1348     return false;
   1349   }
   1350 
   1351   union Value {
   1352     T data;
   1353     uint8_t bytes[sizeof(T)];
   1354   };
   1355 
   1356   Value value;
   1357   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1358   DCHECK(
   1359       NumberToSize(isolate, buffer->byte_length())
   1360       >= buffer_offset + sizeof(T));
   1361   uint8_t* source =
   1362         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1363   if (NeedToFlipBytes(is_little_endian)) {
   1364     FlipBytes<sizeof(T)>(value.bytes, source);
   1365   } else {
   1366     CopyBytes<sizeof(T)>(value.bytes, source);
   1367   }
   1368   *result = value.data;
   1369   return true;
   1370 }
   1371 
   1372 
   1373 template<typename T>
   1374 static bool DataViewSetValue(
   1375     Isolate* isolate,
   1376     Handle<JSDataView> data_view,
   1377     Handle<Object> byte_offset_obj,
   1378     bool is_little_endian,
   1379     T data) {
   1380   size_t byte_offset = 0;
   1381   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
   1382     return false;
   1383   }
   1384   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1385 
   1386   size_t data_view_byte_offset =
   1387       NumberToSize(isolate, data_view->byte_offset());
   1388   size_t data_view_byte_length =
   1389       NumberToSize(isolate, data_view->byte_length());
   1390   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1391       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1392     return false;
   1393   }
   1394 
   1395   union Value {
   1396     T data;
   1397     uint8_t bytes[sizeof(T)];
   1398   };
   1399 
   1400   Value value;
   1401   value.data = data;
   1402   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1403   DCHECK(
   1404       NumberToSize(isolate, buffer->byte_length())
   1405       >= buffer_offset + sizeof(T));
   1406   uint8_t* target =
   1407         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1408   if (NeedToFlipBytes(is_little_endian)) {
   1409     FlipBytes<sizeof(T)>(target, value.bytes);
   1410   } else {
   1411     CopyBytes<sizeof(T)>(target, value.bytes);
   1412   }
   1413   return true;
   1414 }
   1415 
   1416 
   1417 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                   \
   1418   RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                   \
   1419     HandleScope scope(isolate);                                       \
   1420     DCHECK(args.length() == 3);                                       \
   1421     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                \
   1422     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                     \
   1423     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                 \
   1424     Type result;                                                      \
   1425     if (DataViewGetValue(isolate, holder, offset, is_little_endian,   \
   1426                          &result)) {                                  \
   1427       return *isolate->factory()->Converter(result);                  \
   1428     } else {                                                          \
   1429       THROW_NEW_ERROR_RETURN_FAILURE(                                 \
   1430           isolate, NewRangeError("invalid_data_view_accessor_offset", \
   1431                                  HandleVector<Object>(NULL, 0)));     \
   1432     }                                                                 \
   1433   }
   1434 
   1435 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
   1436 DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
   1437 DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
   1438 DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
   1439 DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
   1440 DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
   1441 DATA_VIEW_GETTER(Float32, float, NewNumber)
   1442 DATA_VIEW_GETTER(Float64, double, NewNumber)
   1443 
   1444 #undef DATA_VIEW_GETTER
   1445 
   1446 
   1447 template <typename T>
   1448 static T DataViewConvertValue(double value);
   1449 
   1450 
   1451 template <>
   1452 int8_t DataViewConvertValue<int8_t>(double value) {
   1453   return static_cast<int8_t>(DoubleToInt32(value));
   1454 }
   1455 
   1456 
   1457 template <>
   1458 int16_t DataViewConvertValue<int16_t>(double value) {
   1459   return static_cast<int16_t>(DoubleToInt32(value));
   1460 }
   1461 
   1462 
   1463 template <>
   1464 int32_t DataViewConvertValue<int32_t>(double value) {
   1465   return DoubleToInt32(value);
   1466 }
   1467 
   1468 
   1469 template <>
   1470 uint8_t DataViewConvertValue<uint8_t>(double value) {
   1471   return static_cast<uint8_t>(DoubleToUint32(value));
   1472 }
   1473 
   1474 
   1475 template <>
   1476 uint16_t DataViewConvertValue<uint16_t>(double value) {
   1477   return static_cast<uint16_t>(DoubleToUint32(value));
   1478 }
   1479 
   1480 
   1481 template <>
   1482 uint32_t DataViewConvertValue<uint32_t>(double value) {
   1483   return DoubleToUint32(value);
   1484 }
   1485 
   1486 
   1487 template <>
   1488 float DataViewConvertValue<float>(double value) {
   1489   return static_cast<float>(value);
   1490 }
   1491 
   1492 
   1493 template <>
   1494 double DataViewConvertValue<double>(double value) {
   1495   return value;
   1496 }
   1497 
   1498 
   1499 #define DATA_VIEW_SETTER(TypeName, Type)                                  \
   1500   RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                       \
   1501     HandleScope scope(isolate);                                           \
   1502     DCHECK(args.length() == 4);                                           \
   1503     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                    \
   1504     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                         \
   1505     CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                          \
   1506     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                     \
   1507     Type v = DataViewConvertValue<Type>(value->Number());                 \
   1508     if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
   1509       return isolate->heap()->undefined_value();                          \
   1510     } else {                                                              \
   1511       THROW_NEW_ERROR_RETURN_FAILURE(                                     \
   1512           isolate, NewRangeError("invalid_data_view_accessor_offset",     \
   1513                                  HandleVector<Object>(NULL, 0)));         \
   1514     }                                                                     \
   1515   }
   1516 
   1517 DATA_VIEW_SETTER(Uint8, uint8_t)
   1518 DATA_VIEW_SETTER(Int8, int8_t)
   1519 DATA_VIEW_SETTER(Uint16, uint16_t)
   1520 DATA_VIEW_SETTER(Int16, int16_t)
   1521 DATA_VIEW_SETTER(Uint32, uint32_t)
   1522 DATA_VIEW_SETTER(Int32, int32_t)
   1523 DATA_VIEW_SETTER(Float32, float)
   1524 DATA_VIEW_SETTER(Float64, double)
   1525 
   1526 #undef DATA_VIEW_SETTER
   1527 
   1528 
   1529 RUNTIME_FUNCTION(Runtime_SetInitialize) {
   1530   HandleScope scope(isolate);
   1531   DCHECK(args.length() == 1);
   1532   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1533   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
   1534   holder->set_table(*table);
   1535   return *holder;
   1536 }
   1537 
   1538 
   1539 RUNTIME_FUNCTION(Runtime_SetAdd) {
   1540   HandleScope scope(isolate);
   1541   DCHECK(args.length() == 2);
   1542   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1543   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1544   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1545   table = OrderedHashSet::Add(table, key);
   1546   holder->set_table(*table);
   1547   return *holder;
   1548 }
   1549 
   1550 
   1551 RUNTIME_FUNCTION(Runtime_SetHas) {
   1552   HandleScope scope(isolate);
   1553   DCHECK(args.length() == 2);
   1554   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1555   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1556   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1557   return isolate->heap()->ToBoolean(table->Contains(key));
   1558 }
   1559 
   1560 
   1561 RUNTIME_FUNCTION(Runtime_SetDelete) {
   1562   HandleScope scope(isolate);
   1563   DCHECK(args.length() == 2);
   1564   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1565   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1566   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1567   bool was_present = false;
   1568   table = OrderedHashSet::Remove(table, key, &was_present);
   1569   holder->set_table(*table);
   1570   return isolate->heap()->ToBoolean(was_present);
   1571 }
   1572 
   1573 
   1574 RUNTIME_FUNCTION(Runtime_SetClear) {
   1575   HandleScope scope(isolate);
   1576   DCHECK(args.length() == 1);
   1577   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1578   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1579   table = OrderedHashSet::Clear(table);
   1580   holder->set_table(*table);
   1581   return isolate->heap()->undefined_value();
   1582 }
   1583 
   1584 
   1585 RUNTIME_FUNCTION(Runtime_SetGetSize) {
   1586   HandleScope scope(isolate);
   1587   DCHECK(args.length() == 1);
   1588   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1589   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1590   return Smi::FromInt(table->NumberOfElements());
   1591 }
   1592 
   1593 
   1594 RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
   1595   HandleScope scope(isolate);
   1596   DCHECK(args.length() == 3);
   1597   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
   1598   CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
   1599   CONVERT_SMI_ARG_CHECKED(kind, 2)
   1600   RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
   1601                  kind == JSSetIterator::kKindEntries);
   1602   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
   1603   holder->set_table(*table);
   1604   holder->set_index(Smi::FromInt(0));
   1605   holder->set_kind(Smi::FromInt(kind));
   1606   return isolate->heap()->undefined_value();
   1607 }
   1608 
   1609 
   1610 RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
   1611   SealHandleScope shs(isolate);
   1612   DCHECK(args.length() == 2);
   1613   CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
   1614   CONVERT_ARG_CHECKED(JSArray, value_array, 1);
   1615   return holder->Next(value_array);
   1616 }
   1617 
   1618 
   1619 RUNTIME_FUNCTION(Runtime_MapInitialize) {
   1620   HandleScope scope(isolate);
   1621   DCHECK(args.length() == 1);
   1622   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1623   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
   1624   holder->set_table(*table);
   1625   return *holder;
   1626 }
   1627 
   1628 
   1629 RUNTIME_FUNCTION(Runtime_MapGet) {
   1630   HandleScope scope(isolate);
   1631   DCHECK(args.length() == 2);
   1632   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1633   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1634   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1635   Handle<Object> lookup(table->Lookup(key), isolate);
   1636   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1637 }
   1638 
   1639 
   1640 RUNTIME_FUNCTION(Runtime_MapHas) {
   1641   HandleScope scope(isolate);
   1642   DCHECK(args.length() == 2);
   1643   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1644   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1645   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1646   Handle<Object> lookup(table->Lookup(key), isolate);
   1647   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1648 }
   1649 
   1650 
   1651 RUNTIME_FUNCTION(Runtime_MapDelete) {
   1652   HandleScope scope(isolate);
   1653   DCHECK(args.length() == 2);
   1654   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1655   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1656   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1657   bool was_present = false;
   1658   Handle<OrderedHashMap> new_table =
   1659       OrderedHashMap::Remove(table, key, &was_present);
   1660   holder->set_table(*new_table);
   1661   return isolate->heap()->ToBoolean(was_present);
   1662 }
   1663 
   1664 
   1665 RUNTIME_FUNCTION(Runtime_MapClear) {
   1666   HandleScope scope(isolate);
   1667   DCHECK(args.length() == 1);
   1668   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1669   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1670   table = OrderedHashMap::Clear(table);
   1671   holder->set_table(*table);
   1672   return isolate->heap()->undefined_value();
   1673 }
   1674 
   1675 
   1676 RUNTIME_FUNCTION(Runtime_MapSet) {
   1677   HandleScope scope(isolate);
   1678   DCHECK(args.length() == 3);
   1679   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1680   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1681   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   1682   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1683   Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
   1684   holder->set_table(*new_table);
   1685   return *holder;
   1686 }
   1687 
   1688 
   1689 RUNTIME_FUNCTION(Runtime_MapGetSize) {
   1690   HandleScope scope(isolate);
   1691   DCHECK(args.length() == 1);
   1692   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1693   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1694   return Smi::FromInt(table->NumberOfElements());
   1695 }
   1696 
   1697 
   1698 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
   1699   HandleScope scope(isolate);
   1700   DCHECK(args.length() == 3);
   1701   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
   1702   CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
   1703   CONVERT_SMI_ARG_CHECKED(kind, 2)
   1704   RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
   1705       || kind == JSMapIterator::kKindValues
   1706       || kind == JSMapIterator::kKindEntries);
   1707   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
   1708   holder->set_table(*table);
   1709   holder->set_index(Smi::FromInt(0));
   1710   holder->set_kind(Smi::FromInt(kind));
   1711   return isolate->heap()->undefined_value();
   1712 }
   1713 
   1714 
   1715 RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
   1716   HandleScope scope(isolate);
   1717   DCHECK(args.length() == 1);
   1718   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
   1719   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1720   Handle<FixedArray> entries =
   1721       isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
   1722   {
   1723     DisallowHeapAllocation no_gc;
   1724     int number_of_non_hole_elements = 0;
   1725     for (int i = 0; i < table->Capacity(); i++) {
   1726       Handle<Object> key(table->KeyAt(i), isolate);
   1727       if (table->IsKey(*key)) {
   1728         entries->set(number_of_non_hole_elements++, *key);
   1729         Object* value = table->Lookup(key);
   1730         entries->set(number_of_non_hole_elements++, value);
   1731       }
   1732     }
   1733     DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
   1734   }
   1735   return *isolate->factory()->NewJSArrayWithElements(entries);
   1736 }
   1737 
   1738 
   1739 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
   1740   SealHandleScope shs(isolate);
   1741   DCHECK(args.length() == 2);
   1742   CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
   1743   CONVERT_ARG_CHECKED(JSArray, value_array, 1);
   1744   return holder->Next(value_array);
   1745 }
   1746 
   1747 
   1748 static Handle<JSWeakCollection> WeakCollectionInitialize(
   1749     Isolate* isolate,
   1750     Handle<JSWeakCollection> weak_collection) {
   1751   DCHECK(weak_collection->map()->inobject_properties() == 0);
   1752   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   1753   weak_collection->set_table(*table);
   1754   return weak_collection;
   1755 }
   1756 
   1757 
   1758 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
   1759   HandleScope scope(isolate);
   1760   DCHECK(args.length() == 1);
   1761   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1762   return *WeakCollectionInitialize(isolate, weak_collection);
   1763 }
   1764 
   1765 
   1766 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
   1767   HandleScope scope(isolate);
   1768   DCHECK(args.length() == 2);
   1769   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1770   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1771   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1772   Handle<ObjectHashTable> table(
   1773       ObjectHashTable::cast(weak_collection->table()));
   1774   RUNTIME_ASSERT(table->IsKey(*key));
   1775   Handle<Object> lookup(table->Lookup(key), isolate);
   1776   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1777 }
   1778 
   1779 
   1780 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
   1781   HandleScope scope(isolate);
   1782   DCHECK(args.length() == 2);
   1783   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1784   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1785   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1786   Handle<ObjectHashTable> table(
   1787       ObjectHashTable::cast(weak_collection->table()));
   1788   RUNTIME_ASSERT(table->IsKey(*key));
   1789   Handle<Object> lookup(table->Lookup(key), isolate);
   1790   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1791 }
   1792 
   1793 
   1794 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
   1795   HandleScope scope(isolate);
   1796   DCHECK(args.length() == 2);
   1797   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1798   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1799   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1800   Handle<ObjectHashTable> table(ObjectHashTable::cast(
   1801       weak_collection->table()));
   1802   RUNTIME_ASSERT(table->IsKey(*key));
   1803   bool was_present = false;
   1804   Handle<ObjectHashTable> new_table =
   1805       ObjectHashTable::Remove(table, key, &was_present);
   1806   weak_collection->set_table(*new_table);
   1807   return isolate->heap()->ToBoolean(was_present);
   1808 }
   1809 
   1810 
   1811 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
   1812   HandleScope scope(isolate);
   1813   DCHECK(args.length() == 3);
   1814   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1815   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1816   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1817   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   1818   Handle<ObjectHashTable> table(
   1819       ObjectHashTable::cast(weak_collection->table()));
   1820   RUNTIME_ASSERT(table->IsKey(*key));
   1821   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
   1822   weak_collection->set_table(*new_table);
   1823   return *weak_collection;
   1824 }
   1825 
   1826 
   1827 RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
   1828   HandleScope scope(isolate);
   1829   DCHECK(args.length() == 1);
   1830   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
   1831   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1832   Handle<FixedArray> values =
   1833       isolate->factory()->NewFixedArray(table->NumberOfElements());
   1834   {
   1835     DisallowHeapAllocation no_gc;
   1836     int number_of_non_hole_elements = 0;
   1837     for (int i = 0; i < table->Capacity(); i++) {
   1838       Handle<Object> key(table->KeyAt(i), isolate);
   1839       if (table->IsKey(*key)) {
   1840         values->set(number_of_non_hole_elements++, *key);
   1841       }
   1842     }
   1843     DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
   1844   }
   1845   return *isolate->factory()->NewJSArrayWithElements(values);
   1846 }
   1847 
   1848 
   1849 RUNTIME_FUNCTION(Runtime_GetPrototype) {
   1850   HandleScope scope(isolate);
   1851   DCHECK(args.length() == 1);
   1852   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
   1853   // We don't expect access checks to be needed on JSProxy objects.
   1854   DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
   1855   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
   1856   do {
   1857     if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
   1858         !isolate->MayNamedAccess(
   1859             Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
   1860             isolate->factory()->proto_string(), v8::ACCESS_GET)) {
   1861       isolate->ReportFailedAccessCheck(
   1862           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
   1863           v8::ACCESS_GET);
   1864       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   1865       return isolate->heap()->undefined_value();
   1866     }
   1867     iter.AdvanceIgnoringProxies();
   1868     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
   1869       return *PrototypeIterator::GetCurrent(iter);
   1870     }
   1871   } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
   1872   return *PrototypeIterator::GetCurrent(iter);
   1873 }
   1874 
   1875 
   1876 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
   1877     Isolate* isolate, Handle<Object> receiver) {
   1878   PrototypeIterator iter(isolate, receiver);
   1879   while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
   1880     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
   1881       return PrototypeIterator::GetCurrent(iter);
   1882     }
   1883     iter.Advance();
   1884   }
   1885   return PrototypeIterator::GetCurrent(iter);
   1886 }
   1887 
   1888 
   1889 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
   1890   HandleScope scope(isolate);
   1891   DCHECK(args.length() == 2);
   1892   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1893   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   1894   DCHECK(!obj->IsAccessCheckNeeded());
   1895   DCHECK(!obj->map()->is_observed());
   1896   Handle<Object> result;
   1897   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1898       isolate, result, JSObject::SetPrototype(obj, prototype, false));
   1899   return *result;
   1900 }
   1901 
   1902 
   1903 RUNTIME_FUNCTION(Runtime_SetPrototype) {
   1904   HandleScope scope(isolate);
   1905   DCHECK(args.length() == 2);
   1906   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1907   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   1908   if (obj->IsAccessCheckNeeded() &&
   1909       !isolate->MayNamedAccess(
   1910           obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
   1911     isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
   1912     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   1913     return isolate->heap()->undefined_value();
   1914   }
   1915   if (obj->map()->is_observed()) {
   1916     Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
   1917     Handle<Object> result;
   1918     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1919         isolate, result,
   1920         JSObject::SetPrototype(obj, prototype, true));
   1921 
   1922     Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
   1923     if (!new_value->SameValue(*old_value)) {
   1924       JSObject::EnqueueChangeRecord(obj, "setPrototype",
   1925                                     isolate->factory()->proto_string(),
   1926                                     old_value);
   1927     }
   1928     return *result;
   1929   }
   1930   Handle<Object> result;
   1931   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1932       isolate, result,
   1933       JSObject::SetPrototype(obj, prototype, true));
   1934   return *result;
   1935 }
   1936 
   1937 
   1938 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
   1939   HandleScope shs(isolate);
   1940   DCHECK(args.length() == 2);
   1941   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
   1942   CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
   1943   CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
   1944   PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
   1945   while (true) {
   1946     iter.AdvanceIgnoringProxies();
   1947     if (iter.IsAtEnd()) return isolate->heap()->false_value();
   1948     if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
   1949   }
   1950 }
   1951 
   1952 
   1953 // Enumerator used as indices into the array returned from GetOwnProperty
   1954 enum PropertyDescriptorIndices {
   1955   IS_ACCESSOR_INDEX,
   1956   VALUE_INDEX,
   1957   GETTER_INDEX,
   1958   SETTER_INDEX,
   1959   WRITABLE_INDEX,
   1960   ENUMERABLE_INDEX,
   1961   CONFIGURABLE_INDEX,
   1962   DESCRIPTOR_SIZE
   1963 };
   1964 
   1965 
   1966 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
   1967                                                           Handle<JSObject> obj,
   1968                                                           Handle<Name> name) {
   1969   Heap* heap = isolate->heap();
   1970   Factory* factory = isolate->factory();
   1971 
   1972   PropertyAttributes attrs;
   1973   uint32_t index = 0;
   1974   Handle<Object> value;
   1975   MaybeHandle<AccessorPair> maybe_accessors;
   1976   // TODO(verwaest): Unify once indexed properties can be handled by the
   1977   // LookupIterator.
   1978   if (name->AsArrayIndex(&index)) {
   1979     // Get attributes.
   1980     Maybe<PropertyAttributes> maybe =
   1981         JSReceiver::GetOwnElementAttribute(obj, index);
   1982     if (!maybe.has_value) return MaybeHandle<Object>();
   1983     attrs = maybe.value;
   1984     if (attrs == ABSENT) return factory->undefined_value();
   1985 
   1986     // Get AccessorPair if present.
   1987     maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
   1988 
   1989     // Get value if not an AccessorPair.
   1990     if (maybe_accessors.is_null()) {
   1991       ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
   1992           Runtime::GetElementOrCharAt(isolate, obj, index), Object);
   1993     }
   1994   } else {
   1995     // Get attributes.
   1996     LookupIterator it(obj, name, LookupIterator::HIDDEN);
   1997     Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
   1998     if (!maybe.has_value) return MaybeHandle<Object>();
   1999     attrs = maybe.value;
   2000     if (attrs == ABSENT) return factory->undefined_value();
   2001 
   2002     // Get AccessorPair if present.
   2003     if (it.state() == LookupIterator::ACCESSOR &&
   2004         it.GetAccessors()->IsAccessorPair()) {
   2005       maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
   2006     }
   2007 
   2008     // Get value if not an AccessorPair.
   2009     if (maybe_accessors.is_null()) {
   2010       ASSIGN_RETURN_ON_EXCEPTION(
   2011           isolate, value, Object::GetProperty(&it), Object);
   2012     }
   2013   }
   2014   DCHECK(!isolate->has_pending_exception());
   2015   Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
   2016   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
   2017   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
   2018   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
   2019 
   2020   Handle<AccessorPair> accessors;
   2021   if (maybe_accessors.ToHandle(&accessors)) {
   2022     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
   2023     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
   2024     elms->set(GETTER_INDEX, *getter);
   2025     elms->set(SETTER_INDEX, *setter);
   2026   } else {
   2027     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
   2028     elms->set(VALUE_INDEX, *value);
   2029   }
   2030 
   2031   return factory->NewJSArrayWithElements(elms);
   2032 }
   2033 
   2034 
   2035 // Returns an array with the property description:
   2036 //  if args[1] is not a property on args[0]
   2037 //          returns undefined
   2038 //  if args[1] is a data property on args[0]
   2039 //         [false, value, Writeable, Enumerable, Configurable]
   2040 //  if args[1] is an accessor on args[0]
   2041 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
   2042 RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
   2043   HandleScope scope(isolate);
   2044   DCHECK(args.length() == 2);
   2045   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   2046   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   2047   Handle<Object> result;
   2048   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2049       isolate, result, GetOwnProperty(isolate, obj, name));
   2050   return *result;
   2051 }
   2052 
   2053 
   2054 RUNTIME_FUNCTION(Runtime_PreventExtensions) {
   2055   HandleScope scope(isolate);
   2056   DCHECK(args.length() == 1);
   2057   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   2058   Handle<Object> result;
   2059   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2060       isolate, result, JSObject::PreventExtensions(obj));
   2061   return *result;
   2062 }
   2063 
   2064 
   2065 RUNTIME_FUNCTION(Runtime_ToMethod) {
   2066   HandleScope scope(isolate);
   2067   DCHECK(args.length() == 2);
   2068   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   2069   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
   2070   Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
   2071   Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
   2072   JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
   2073                                            home_object, DONT_ENUM).Assert();
   2074   return *clone;
   2075 }
   2076 
   2077 
   2078 RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
   2079   DCHECK(args.length() == 0);
   2080   return isolate->heap()->home_object_symbol();
   2081 }
   2082 
   2083 
   2084 RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
   2085   HandleScope scope(isolate);
   2086   DCHECK(args.length() == 3);
   2087   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 0);
   2088   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
   2089   CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
   2090 
   2091   if (home_object->IsAccessCheckNeeded() &&
   2092       !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
   2093     isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
   2094     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   2095   }
   2096 
   2097   PrototypeIterator iter(isolate, home_object);
   2098   Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
   2099   if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
   2100 
   2101   LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
   2102   Handle<Object> result;
   2103   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
   2104   return *result;
   2105 }
   2106 
   2107 
   2108 RUNTIME_FUNCTION(Runtime_IsExtensible) {
   2109   SealHandleScope shs(isolate);
   2110   DCHECK(args.length() == 1);
   2111   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   2112   if (obj->IsJSGlobalProxy()) {
   2113     PrototypeIterator iter(isolate, obj);
   2114     if (iter.IsAtEnd()) return isolate->heap()->false_value();
   2115     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
   2116     obj = JSObject::cast(iter.GetCurrent());
   2117   }
   2118   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
   2119 }
   2120 
   2121 
   2122 RUNTIME_FUNCTION(Runtime_RegExpCompile) {
   2123   HandleScope scope(isolate);
   2124   DCHECK(args.length() == 3);
   2125   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
   2126   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   2127   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
   2128   Handle<Object> result;
   2129   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2130       isolate, result, RegExpImpl::Compile(re, pattern, flags));
   2131   return *result;
   2132 }
   2133 
   2134 
   2135 RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
   2136   HandleScope scope(isolate);
   2137   DCHECK(args.length() == 2);
   2138   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
   2139   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   2140   return *isolate->factory()->CreateApiFunction(data, prototype);
   2141 }
   2142 
   2143 
   2144 RUNTIME_FUNCTION(Runtime_IsTemplate) {
   2145   SealHandleScope shs(isolate);
   2146   DCHECK(args.length() == 1);
   2147   CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
   2148   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
   2149   return isolate->heap()->ToBoolean(result);
   2150 }
   2151 
   2152 
   2153 RUNTIME_FUNCTION(Runtime_GetTemplateField) {
   2154   SealHandleScope shs(isolate);
   2155   DCHECK(args.length() == 2);
   2156   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
   2157   CONVERT_SMI_ARG_CHECKED(index, 1);
   2158   int offset = index * kPointerSize + HeapObject::kHeaderSize;
   2159   InstanceType type = templ->map()->instance_type();
   2160   RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
   2161                  type == OBJECT_TEMPLATE_INFO_TYPE);
   2162   RUNTIME_ASSERT(offset > 0);
   2163   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
   2164     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
   2165   } else {
   2166     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
   2167   }
   2168   return *HeapObject::RawField(templ, offset);
   2169 }
   2170 
   2171 
   2172 RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
   2173   HandleScope scope(isolate);
   2174   DCHECK(args.length() == 1);
   2175   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
   2176   Handle<Map> old_map(object->map());
   2177   bool needs_access_checks = old_map->is_access_check_needed();
   2178   if (needs_access_checks) {
   2179     // Copy map so it won't interfere constructor's initial map.
   2180     Handle<Map> new_map = Map::Copy(old_map);
   2181     new_map->set_is_access_check_needed(false);
   2182     JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
   2183   }
   2184   return isolate->heap()->ToBoolean(needs_access_checks);
   2185 }
   2186 
   2187 
   2188 RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
   2189   HandleScope scope(isolate);
   2190   DCHECK(args.length() == 1);
   2191   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2192   Handle<Map> old_map(object->map());
   2193   RUNTIME_ASSERT(!old_map->is_access_check_needed());
   2194   // Copy map so it won't interfere constructor's initial map.
   2195   Handle<Map> new_map = Map::Copy(old_map);
   2196   new_map->set_is_access_check_needed(true);
   2197   JSObject::MigrateToMap(object, new_map);
   2198   return isolate->heap()->undefined_value();
   2199 }
   2200 
   2201 
   2202 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
   2203   HandleScope scope(isolate);
   2204   Handle<Object> args[1] = { name };
   2205   THROW_NEW_ERROR_RETURN_FAILURE(
   2206       isolate, NewTypeError("var_redeclaration", HandleVector(args, 1)));
   2207 }
   2208 
   2209 
   2210 // May throw a RedeclarationError.
   2211 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
   2212                               Handle<String> name, Handle<Object> value,
   2213                               PropertyAttributes attr, bool is_var,
   2214                               bool is_const, bool is_function) {
   2215   // Do the lookup own properties only, see ES5 erratum.
   2216   LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
   2217   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   2218   if (!maybe.has_value) return isolate->heap()->exception();
   2219 
   2220   if (it.IsFound()) {
   2221     PropertyAttributes old_attributes = maybe.value;
   2222     // The name was declared before; check for conflicting re-declarations.
   2223     if (is_const) return ThrowRedeclarationError(isolate, name);
   2224 
   2225     // Skip var re-declarations.
   2226     if (is_var) return isolate->heap()->undefined_value();
   2227 
   2228     DCHECK(is_function);
   2229     if ((old_attributes & DONT_DELETE) != 0) {
   2230       // Only allow reconfiguring globals to functions in user code (no
   2231       // natives, which are marked as read-only).
   2232       DCHECK((attr & READ_ONLY) == 0);
   2233 
   2234       // Check whether we can reconfigure the existing property into a
   2235       // function.
   2236       PropertyDetails old_details = it.property_details();
   2237       // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
   2238       // which are actually data properties, not accessor properties.
   2239       if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
   2240           old_details.type() == CALLBACKS) {
   2241         return ThrowRedeclarationError(isolate, name);
   2242       }
   2243       // If the existing property is not configurable, keep its attributes. Do
   2244       attr = old_attributes;
   2245     }
   2246   }
   2247 
   2248   // Define or redefine own property.
   2249   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
   2250                                            global, name, value, attr));
   2251 
   2252   return isolate->heap()->undefined_value();
   2253 }
   2254 
   2255 
   2256 RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
   2257   HandleScope scope(isolate);
   2258   DCHECK(args.length() == 3);
   2259   Handle<GlobalObject> global(isolate->global_object());
   2260 
   2261   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   2262   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
   2263   CONVERT_SMI_ARG_CHECKED(flags, 2);
   2264 
   2265   // Traverse the name/value pairs and set the properties.
   2266   int length = pairs->length();
   2267   for (int i = 0; i < length; i += 2) {
   2268     HandleScope scope(isolate);
   2269     Handle<String> name(String::cast(pairs->get(i)));
   2270     Handle<Object> initial_value(pairs->get(i + 1), isolate);
   2271 
   2272     // We have to declare a global const property. To capture we only
   2273     // assign to it when evaluating the assignment for "const x =
   2274     // <expr>" the initial value is the hole.
   2275     bool is_var = initial_value->IsUndefined();
   2276     bool is_const = initial_value->IsTheHole();
   2277     bool is_function = initial_value->IsSharedFunctionInfo();
   2278     DCHECK(is_var + is_const + is_function == 1);
   2279 
   2280     Handle<Object> value;
   2281     if (is_function) {
   2282       // Copy the function and update its context. Use it as value.
   2283       Handle<SharedFunctionInfo> shared =
   2284           Handle<SharedFunctionInfo>::cast(initial_value);
   2285       Handle<JSFunction> function =
   2286           isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
   2287                                                                 TENURED);
   2288       value = function;
   2289     } else {
   2290       value = isolate->factory()->undefined_value();
   2291     }
   2292 
   2293     // Compute the property attributes. According to ECMA-262,
   2294     // the property must be non-configurable except in eval.
   2295     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
   2296     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
   2297     int attr = NONE;
   2298     if (is_const) attr |= READ_ONLY;
   2299     if (is_function && is_native) attr |= READ_ONLY;
   2300     if (!is_const && !is_eval) attr |= DONT_DELETE;
   2301 
   2302     Object* result = DeclareGlobals(isolate, global, name, value,
   2303                                     static_cast<PropertyAttributes>(attr),
   2304                                     is_var, is_const, is_function);
   2305     if (isolate->has_pending_exception()) return result;
   2306   }
   2307 
   2308   return isolate->heap()->undefined_value();
   2309 }
   2310 
   2311 
   2312 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
   2313   HandleScope scope(isolate);
   2314   // args[0] == name
   2315   // args[1] == language_mode
   2316   // args[2] == value (optional)
   2317 
   2318   // Determine if we need to assign to the variable if it already
   2319   // exists (based on the number of arguments).
   2320   RUNTIME_ASSERT(args.length() == 3);
   2321 
   2322   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2323   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
   2324   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   2325 
   2326   Handle<GlobalObject> global(isolate->context()->global_object());
   2327   Handle<Object> result;
   2328   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2329       isolate, result, Object::SetProperty(global, name, value, strict_mode));
   2330   return *result;
   2331 }
   2332 
   2333 
   2334 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
   2335   HandleScope handle_scope(isolate);
   2336   // All constants are declared with an initial value. The name
   2337   // of the constant is the first argument and the initial value
   2338   // is the second.
   2339   RUNTIME_ASSERT(args.length() == 2);
   2340   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2341   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
   2342 
   2343   Handle<GlobalObject> global = isolate->global_object();
   2344 
   2345   // Lookup the property as own on the global object.
   2346   LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
   2347   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   2348   DCHECK(maybe.has_value);
   2349   PropertyAttributes old_attributes = maybe.value;
   2350 
   2351   PropertyAttributes attr =
   2352       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
   2353   // Set the value if the property is either missing, or the property attributes
   2354   // allow setting the value without invoking an accessor.
   2355   if (it.IsFound()) {
   2356     // Ignore if we can't reconfigure the value.
   2357     if ((old_attributes & DONT_DELETE) != 0) {
   2358       if ((old_attributes & READ_ONLY) != 0 ||
   2359           it.state() == LookupIterator::ACCESSOR) {
   2360         return *value;
   2361       }
   2362       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
   2363     }
   2364   }
   2365 
   2366   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
   2367                                            global, name, value, attr));
   2368 
   2369   return *value;
   2370 }
   2371 
   2372 
   2373 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
   2374   HandleScope scope(isolate);
   2375   DCHECK(args.length() == 4);
   2376 
   2377   // Declarations are always made in a function, native, or global context. In
   2378   // the case of eval code, the context passed is the context of the caller,
   2379   // which may be some nested context and not the declaration context.
   2380   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
   2381   Handle<Context> context(context_arg->declaration_context());
   2382   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   2383   CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
   2384   PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
   2385   RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
   2386   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
   2387 
   2388   // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
   2389   bool is_var = *initial_value == NULL;
   2390   bool is_const = initial_value->IsTheHole();
   2391   bool is_function = initial_value->IsJSFunction();
   2392   DCHECK(is_var + is_const + is_function == 1);
   2393 
   2394   int index;
   2395   PropertyAttributes attributes;
   2396   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   2397   BindingFlags binding_flags;
   2398   Handle<Object> holder =
   2399       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2400 
   2401   Handle<JSObject> object;
   2402   Handle<Object> value =
   2403       is_function ? initial_value
   2404                   : Handle<Object>::cast(isolate->factory()->undefined_value());
   2405 
   2406   // TODO(verwaest): This case should probably not be covered by this function,
   2407   // but by DeclareGlobals instead.
   2408   if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
   2409       (context_arg->has_extension() &&
   2410        context_arg->extension()->IsJSGlobalObject())) {
   2411     return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
   2412                           value, attr, is_var, is_const, is_function);
   2413   }
   2414 
   2415   if (attributes != ABSENT) {
   2416     // The name was declared before; check for conflicting re-declarations.
   2417     if (is_const || (attributes & READ_ONLY) != 0) {
   2418       return ThrowRedeclarationError(isolate, name);
   2419     }
   2420 
   2421     // Skip var re-declarations.
   2422     if (is_var) return isolate->heap()->undefined_value();
   2423 
   2424     DCHECK(is_function);
   2425     if (index >= 0) {
   2426       DCHECK(holder.is_identical_to(context));
   2427       context->set(index, *initial_value);
   2428       return isolate->heap()->undefined_value();
   2429     }
   2430 
   2431     object = Handle<JSObject>::cast(holder);
   2432 
   2433   } else if (context->has_extension()) {
   2434     object = handle(JSObject::cast(context->extension()));
   2435     DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
   2436   } else {
   2437     DCHECK(context->IsFunctionContext());
   2438     object =
   2439         isolate->factory()->NewJSObject(isolate->context_extension_function());
   2440     context->set_extension(*object);
   2441   }
   2442 
   2443   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
   2444                                            object, name, value, attr));
   2445 
   2446   return isolate->heap()->undefined_value();
   2447 }
   2448 
   2449 
   2450 RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
   2451   HandleScope scope(isolate);
   2452   DCHECK(args.length() == 3);
   2453 
   2454   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
   2455   DCHECK(!value->IsTheHole());
   2456   // Initializations are always done in a function or native context.
   2457   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
   2458   Handle<Context> context(context_arg->declaration_context());
   2459   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   2460 
   2461   int index;
   2462   PropertyAttributes attributes;
   2463   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   2464   BindingFlags binding_flags;
   2465   Handle<Object> holder =
   2466       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2467 
   2468   if (index >= 0) {
   2469     DCHECK(holder->IsContext());
   2470     // Property was found in a context.  Perform the assignment if the constant
   2471     // was uninitialized.
   2472     Handle<Context> context = Handle<Context>::cast(holder);
   2473     DCHECK((attributes & READ_ONLY) != 0);
   2474     if (context->get(index)->IsTheHole()) context->set(index, *value);
   2475     return *value;
   2476   }
   2477 
   2478   PropertyAttributes attr =
   2479       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
   2480 
   2481   // Strict mode handling not needed (legacy const is disallowed in strict
   2482   // mode).
   2483 
   2484   // The declared const was configurable, and may have been deleted in the
   2485   // meanwhile. If so, re-introduce the variable in the context extension.
   2486   DCHECK(context_arg->has_extension());
   2487   if (attributes == ABSENT) {
   2488     holder = handle(context_arg->extension(), isolate);
   2489   } else {
   2490     // For JSContextExtensionObjects, the initializer can be run multiple times
   2491     // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
   2492     // first assignment should go through. For JSGlobalObjects, additionally any
   2493     // code can run in between that modifies the declared property.
   2494     DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
   2495 
   2496     LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
   2497     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   2498     if (!maybe.has_value) return isolate->heap()->exception();
   2499     PropertyAttributes old_attributes = maybe.value;
   2500 
   2501     // Ignore if we can't reconfigure the value.
   2502     if ((old_attributes & DONT_DELETE) != 0) {
   2503       if ((old_attributes & READ_ONLY) != 0 ||
   2504           it.state() == LookupIterator::ACCESSOR) {
   2505         return *value;
   2506       }
   2507       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
   2508     }
   2509   }
   2510 
   2511   RETURN_FAILURE_ON_EXCEPTION(
   2512       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
   2513                    Handle<JSObject>::cast(holder), name, value, attr));
   2514 
   2515   return *value;
   2516 }
   2517 
   2518 
   2519 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
   2520   HandleScope scope(isolate);
   2521   DCHECK(args.length() == 2);
   2522   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2523   CONVERT_SMI_ARG_CHECKED(properties, 1);
   2524   // Conservative upper limit to prevent fuzz tests from going OOM.
   2525   RUNTIME_ASSERT(properties <= 100000);
   2526   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
   2527     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
   2528   }
   2529   return *object;
   2530 }
   2531 
   2532 
   2533 RUNTIME_FUNCTION(Runtime_RegExpExecRT) {
   2534   HandleScope scope(isolate);
   2535   DCHECK(args.length() == 4);
   2536   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2537   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   2538   CONVERT_INT32_ARG_CHECKED(index, 2);
   2539   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   2540   // Due to the way the JS calls are constructed this must be less than the
   2541   // length of a string, i.e. it is always a Smi.  We check anyway for security.
   2542   RUNTIME_ASSERT(index >= 0);
   2543   RUNTIME_ASSERT(index <= subject->length());
   2544   isolate->counters()->regexp_entry_runtime()->Increment();
   2545   Handle<Object> result;
   2546   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2547       isolate, result,
   2548       RegExpImpl::Exec(regexp, subject, index, last_match_info));
   2549   return *result;
   2550 }
   2551 
   2552 
   2553 RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
   2554   HandleScope handle_scope(isolate);
   2555   DCHECK(args.length() == 3);
   2556   CONVERT_SMI_ARG_CHECKED(size, 0);
   2557   RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
   2558   CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
   2559   CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
   2560   Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
   2561   Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
   2562   Handle<JSObject> object =
   2563       isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
   2564   Handle<JSArray> array = Handle<JSArray>::cast(object);
   2565   array->set_elements(*elements);
   2566   array->set_length(Smi::FromInt(size));
   2567   // Write in-object properties after the length of the array.
   2568   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
   2569   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
   2570   return *array;
   2571 }
   2572 
   2573 
   2574 RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
   2575   HandleScope scope(isolate);
   2576   DCHECK(args.length() == 6);
   2577   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2578   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   2579   // If source is the empty string we set it to "(?:)" instead as
   2580   // suggested by ECMA-262, 5th, section 15.10.4.1.
   2581   if (source->length() == 0) source = isolate->factory()->query_colon_string();
   2582 
   2583   CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
   2584   if (!global->IsTrue()) global = isolate->factory()->false_value();
   2585 
   2586   CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
   2587   if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
   2588 
   2589   CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
   2590   if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
   2591 
   2592   CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5);
   2593   if (!sticky->IsTrue()) sticky = isolate->factory()->false_value();
   2594 
   2595   Map* map = regexp->map();
   2596   Object* constructor = map->constructor();
   2597   if (!FLAG_harmony_regexps &&
   2598       constructor->IsJSFunction() &&
   2599       JSFunction::cast(constructor)->initial_map() == map) {
   2600     // If we still have the original map, set in-object properties directly.
   2601     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
   2602     // Both true and false are immovable immortal objects so no need for write
   2603     // barrier.
   2604     regexp->InObjectPropertyAtPut(
   2605         JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
   2606     regexp->InObjectPropertyAtPut(
   2607         JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
   2608     regexp->InObjectPropertyAtPut(
   2609         JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
   2610     regexp->InObjectPropertyAtPut(
   2611         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
   2612     return *regexp;
   2613   }
   2614 
   2615   // Map has changed, so use generic, but slower, method.  We also end here if
   2616   // the --harmony-regexp flag is set, because the initial map does not have
   2617   // space for the 'sticky' flag, since it is from the snapshot, but must work
   2618   // both with and without --harmony-regexp.  When sticky comes out from under
   2619   // the flag, we will be able to use the fast initial map.
   2620   PropertyAttributes final =
   2621       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
   2622   PropertyAttributes writable =
   2623       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
   2624   Handle<Object> zero(Smi::FromInt(0), isolate);
   2625   Factory* factory = isolate->factory();
   2626   JSObject::SetOwnPropertyIgnoreAttributes(
   2627       regexp, factory->source_string(), source, final).Check();
   2628   JSObject::SetOwnPropertyIgnoreAttributes(
   2629       regexp, factory->global_string(), global, final).Check();
   2630   JSObject::SetOwnPropertyIgnoreAttributes(
   2631       regexp, factory->ignore_case_string(), ignoreCase, final).Check();
   2632   JSObject::SetOwnPropertyIgnoreAttributes(
   2633       regexp, factory->multiline_string(), multiline, final).Check();
   2634   if (FLAG_harmony_regexps) {
   2635     JSObject::SetOwnPropertyIgnoreAttributes(
   2636         regexp, factory->sticky_string(), sticky, final).Check();
   2637   }
   2638   JSObject::SetOwnPropertyIgnoreAttributes(
   2639       regexp, factory->last_index_string(), zero, writable).Check();
   2640   return *regexp;
   2641 }
   2642 
   2643 
   2644 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
   2645   HandleScope scope(isolate);
   2646   DCHECK(args.length() == 1);
   2647   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
   2648   Object* length = prototype->length();
   2649   RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
   2650   RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
   2651   // This is necessary to enable fast checks for absence of elements
   2652   // on Array.prototype and below.
   2653   prototype->set_elements(isolate->heap()->empty_fixed_array());
   2654   return Smi::FromInt(0);
   2655 }
   2656 
   2657 
   2658 static void InstallBuiltin(Isolate* isolate,
   2659                            Handle<JSObject> holder,
   2660                            const char* name,
   2661                            Builtins::Name builtin_name) {
   2662   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
   2663   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
   2664   Handle<JSFunction> optimized =
   2665       isolate->factory()->NewFunctionWithoutPrototype(key, code);
   2666   optimized->shared()->DontAdaptArguments();
   2667   JSObject::AddProperty(holder, key, optimized, NONE);
   2668 }
   2669 
   2670 
   2671 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
   2672   HandleScope scope(isolate);
   2673   DCHECK(args.length() == 0);
   2674   Handle<JSObject> holder =
   2675       isolate->factory()->NewJSObject(isolate->object_function());
   2676 
   2677   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
   2678   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
   2679   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
   2680   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
   2681   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
   2682   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
   2683   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
   2684 
   2685   return *holder;
   2686 }
   2687 
   2688 
   2689 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
   2690   SealHandleScope shs(isolate);
   2691   DCHECK(args.length() == 1);
   2692   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2693   if (!callable->IsJSFunction()) {
   2694     HandleScope scope(isolate);
   2695     Handle<Object> delegate;
   2696     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2697         isolate, delegate,
   2698         Execution::TryGetFunctionDelegate(
   2699             isolate, Handle<JSReceiver>(callable)));
   2700     callable = JSFunction::cast(*delegate);
   2701   }
   2702   JSFunction* function = JSFunction::cast(callable);
   2703   SharedFunctionInfo* shared = function->shared();
   2704   return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
   2705 }
   2706 
   2707 
   2708 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
   2709   SealHandleScope shs(isolate);
   2710   DCHECK(args.length() == 1);
   2711   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2712 
   2713   if (!callable->IsJSFunction()) {
   2714     HandleScope scope(isolate);
   2715     Handle<Object> delegate;
   2716     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2717         isolate, delegate,
   2718         Execution::TryGetFunctionDelegate(
   2719             isolate, Handle<JSReceiver>(callable)));
   2720     callable = JSFunction::cast(*delegate);
   2721   }
   2722   JSFunction* function = JSFunction::cast(callable);
   2723 
   2724   SharedFunctionInfo* shared = function->shared();
   2725   if (shared->native() || shared->strict_mode() == STRICT) {
   2726     return isolate->heap()->undefined_value();
   2727   }
   2728   // Returns undefined for strict or native functions, or
   2729   // the associated global receiver for "normal" functions.
   2730 
   2731   return function->global_proxy();
   2732 }
   2733 
   2734 
   2735 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
   2736   HandleScope scope(isolate);
   2737   DCHECK(args.length() == 4);
   2738   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
   2739   CONVERT_SMI_ARG_CHECKED(index, 1);
   2740   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
   2741   CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
   2742 
   2743   // Get the RegExp function from the context in the literals array.
   2744   // This is the RegExp function from the context in which the
   2745   // function was created.  We do not use the RegExp function from the
   2746   // current native context because this might be the RegExp function
   2747   // from another context which we should not have access to.
   2748   Handle<JSFunction> constructor =
   2749       Handle<JSFunction>(
   2750           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
   2751   // Compute the regular expression literal.
   2752   Handle<Object> regexp;
   2753   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2754       isolate, regexp,
   2755       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
   2756   literals->set(index, *regexp);
   2757   return *regexp;
   2758 }
   2759 
   2760 
   2761 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
   2762   SealHandleScope shs(isolate);
   2763   DCHECK(args.length() == 1);
   2764 
   2765   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2766   return f->shared()->name();
   2767 }
   2768 
   2769 
   2770 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
   2771   SealHandleScope shs(isolate);
   2772   DCHECK(args.length() == 2);
   2773 
   2774   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2775   CONVERT_ARG_CHECKED(String, name, 1);
   2776   f->shared()->set_name(name);
   2777   return isolate->heap()->undefined_value();
   2778 }
   2779 
   2780 
   2781 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
   2782   SealHandleScope shs(isolate);
   2783   DCHECK(args.length() == 1);
   2784   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2785   return isolate->heap()->ToBoolean(
   2786       f->shared()->name_should_print_as_anonymous());
   2787 }
   2788 
   2789 
   2790 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
   2791   SealHandleScope shs(isolate);
   2792   DCHECK(args.length() == 1);
   2793   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2794   f->shared()->set_name_should_print_as_anonymous(true);
   2795   return isolate->heap()->undefined_value();
   2796 }
   2797 
   2798 
   2799 RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
   2800   SealHandleScope shs(isolate);
   2801   DCHECK(args.length() == 1);
   2802   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2803   return isolate->heap()->ToBoolean(f->shared()->is_generator());
   2804 }
   2805 
   2806 
   2807 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
   2808   SealHandleScope shs(isolate);
   2809   DCHECK(args.length() == 1);
   2810   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2811   return isolate->heap()->ToBoolean(f->shared()->is_arrow());
   2812 }
   2813 
   2814 
   2815 RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
   2816   SealHandleScope shs(isolate);
   2817   DCHECK(args.length() == 1);
   2818   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2819   return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
   2820 }
   2821 
   2822 
   2823 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
   2824   SealHandleScope shs(isolate);
   2825   DCHECK(args.length() == 1);
   2826 
   2827   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2828   RUNTIME_ASSERT(f->RemovePrototype());
   2829 
   2830   return isolate->heap()->undefined_value();
   2831 }
   2832 
   2833 
   2834 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
   2835   HandleScope scope(isolate);
   2836   DCHECK(args.length() == 1);
   2837 
   2838   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2839   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
   2840   if (!script->IsScript()) return isolate->heap()->undefined_value();
   2841 
   2842   return *Script::GetWrapper(Handle<Script>::cast(script));
   2843 }
   2844 
   2845 
   2846 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
   2847   HandleScope scope(isolate);
   2848   DCHECK(args.length() == 1);
   2849 
   2850   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
   2851   Handle<SharedFunctionInfo> shared(f->shared());
   2852   return *shared->GetSourceCode();
   2853 }
   2854 
   2855 
   2856 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
   2857   SealHandleScope shs(isolate);
   2858   DCHECK(args.length() == 1);
   2859 
   2860   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2861   int pos = fun->shared()->start_position();
   2862   return Smi::FromInt(pos);
   2863 }
   2864 
   2865 
   2866 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
   2867   SealHandleScope shs(isolate);
   2868   DCHECK(args.length() == 2);
   2869 
   2870   CONVERT_ARG_CHECKED(Code, code, 0);
   2871   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
   2872 
   2873   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
   2874 
   2875   Address pc = code->address() + offset;
   2876   return Smi::FromInt(code->SourcePosition(pc));
   2877 }
   2878 
   2879 
   2880 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
   2881   SealHandleScope shs(isolate);
   2882   DCHECK(args.length() == 2);
   2883 
   2884   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2885   CONVERT_ARG_CHECKED(String, name, 1);
   2886   fun->SetInstanceClassName(name);
   2887   return isolate->heap()->undefined_value();
   2888 }
   2889 
   2890 
   2891 RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
   2892   SealHandleScope shs(isolate);
   2893   DCHECK(args.length() == 2);
   2894 
   2895   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2896   CONVERT_SMI_ARG_CHECKED(length, 1);
   2897   RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
   2898                  (length & 0xC0000000) == 0x0);
   2899   fun->shared()->set_length(length);
   2900   return isolate->heap()->undefined_value();
   2901 }
   2902 
   2903 
   2904 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
   2905   HandleScope scope(isolate);
   2906   DCHECK(args.length() == 2);
   2907 
   2908   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   2909   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
   2910   RUNTIME_ASSERT(fun->should_have_prototype());
   2911   Accessors::FunctionSetPrototype(fun, value);
   2912   return args[0];  // return TOS
   2913 }
   2914 
   2915 
   2916 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
   2917   SealHandleScope shs(isolate);
   2918   DCHECK(args.length() == 1);
   2919 
   2920   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2921   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
   2922 }
   2923 
   2924 
   2925 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
   2926   SealHandleScope shs(isolate);
   2927   DCHECK(args.length() == 1);
   2928 
   2929   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2930   return isolate->heap()->ToBoolean(f->IsBuiltin());
   2931 }
   2932 
   2933 
   2934 RUNTIME_FUNCTION(Runtime_SetCode) {
   2935   HandleScope scope(isolate);
   2936   DCHECK(args.length() == 2);
   2937 
   2938   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
   2939   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
   2940 
   2941   Handle<SharedFunctionInfo> target_shared(target->shared());
   2942   Handle<SharedFunctionInfo> source_shared(source->shared());
   2943   RUNTIME_ASSERT(!source_shared->bound());
   2944 
   2945   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
   2946     return isolate->heap()->exception();
   2947   }
   2948 
   2949   // Mark both, the source and the target, as un-flushable because the
   2950   // shared unoptimized code makes them impossible to enqueue in a list.
   2951   DCHECK(target_shared->code()->gc_metadata() == NULL);
   2952   DCHECK(source_shared->code()->gc_metadata() == NULL);
   2953   target_shared->set_dont_flush(true);
   2954   source_shared->set_dont_flush(true);
   2955 
   2956   // Set the code, scope info, formal parameter count, and the length
   2957   // of the target shared function info.
   2958   target_shared->ReplaceCode(source_shared->code());
   2959   target_shared->set_scope_info(source_shared->scope_info());
   2960   target_shared->set_length(source_shared->length());
   2961   target_shared->set_feedback_vector(source_shared->feedback_vector());
   2962   target_shared->set_formal_parameter_count(
   2963       source_shared->formal_parameter_count());
   2964   target_shared->set_script(source_shared->script());
   2965   target_shared->set_start_position_and_type(
   2966       source_shared->start_position_and_type());
   2967   target_shared->set_end_position(source_shared->end_position());
   2968   bool was_native = target_shared->native();
   2969   target_shared->set_compiler_hints(source_shared->compiler_hints());
   2970   target_shared->set_native(was_native);
   2971   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
   2972 
   2973   // Set the code of the target function.
   2974   target->ReplaceCode(source_shared->code());
   2975   DCHECK(target->next_function_link()->IsUndefined());
   2976 
   2977   // Make sure we get a fresh copy of the literal vector to avoid cross
   2978   // context contamination.
   2979   Handle<Context> context(source->context());
   2980   int number_of_literals = source->NumberOfLiterals();
   2981   Handle<FixedArray> literals =
   2982       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
   2983   if (number_of_literals > 0) {
   2984     literals->set(JSFunction::kLiteralNativeContextIndex,
   2985                   context->native_context());
   2986   }
   2987   target->set_context(*context);
   2988   target->set_literals(*literals);
   2989 
   2990   if (isolate->logger()->is_logging_code_events() ||
   2991       isolate->cpu_profiler()->is_profiling()) {
   2992     isolate->logger()->LogExistingFunction(
   2993         source_shared, Handle<Code>(source_shared->code()));
   2994   }
   2995 
   2996   return *target;
   2997 }
   2998 
   2999 
   3000 RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
   3001   HandleScope scope(isolate);
   3002   DCHECK(args.length() == 0);
   3003 
   3004   JavaScriptFrameIterator it(isolate);
   3005   JavaScriptFrame* frame = it.frame();
   3006   Handle<JSFunction> function(frame->function());
   3007   RUNTIME_ASSERT(function->shared()->is_generator());
   3008 
   3009   Handle<JSGeneratorObject> generator;
   3010   if (frame->IsConstructor()) {
   3011     generator = handle(JSGeneratorObject::cast(frame->receiver()));
   3012   } else {
   3013     generator = isolate->factory()->NewJSGeneratorObject(function);
   3014   }
   3015   generator->set_function(*function);
   3016   generator->set_context(Context::cast(frame->context()));
   3017   generator->set_receiver(frame->receiver());
   3018   generator->set_continuation(0);
   3019   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
   3020   generator->set_stack_handler_index(-1);
   3021 
   3022   return *generator;
   3023 }
   3024 
   3025 
   3026 RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
   3027   HandleScope handle_scope(isolate);
   3028   DCHECK(args.length() == 1);
   3029   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
   3030 
   3031   JavaScriptFrameIterator stack_iterator(isolate);
   3032   JavaScriptFrame* frame = stack_iterator.frame();
   3033   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
   3034   DCHECK_EQ(frame->function(), generator_object->function());
   3035 
   3036   // The caller should have saved the context and continuation already.
   3037   DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
   3038   DCHECK_LT(0, generator_object->continuation());
   3039 
   3040   // We expect there to be at least two values on the operand stack: the return
   3041   // value of the yield expression, and the argument to this runtime call.
   3042   // Neither of those should be saved.
   3043   int operands_count = frame->ComputeOperandsCount();
   3044   DCHECK_GE(operands_count, 2);
   3045   operands_count -= 2;
   3046 
   3047   if (operands_count == 0) {
   3048     // Although it's semantically harmless to call this function with an
   3049     // operands_count of zero, it is also unnecessary.
   3050     DCHECK_EQ(generator_object->operand_stack(),
   3051               isolate->heap()->empty_fixed_array());
   3052     DCHECK_EQ(generator_object->stack_handler_index(), -1);
   3053     // If there are no operands on the stack, there shouldn't be a handler
   3054     // active either.
   3055     DCHECK(!frame->HasHandler());
   3056   } else {
   3057     int stack_handler_index = -1;
   3058     Handle<FixedArray> operand_stack =
   3059         isolate->factory()->NewFixedArray(operands_count);
   3060     frame->SaveOperandStack(*operand_stack, &stack_handler_index);
   3061     generator_object->set_operand_stack(*operand_stack);
   3062     generator_object->set_stack_handler_index(stack_handler_index);
   3063   }
   3064 
   3065   return isolate->heap()->undefined_value();
   3066 }
   3067 
   3068 
   3069 // Note that this function is the slow path for resuming generators.  It is only
   3070 // called if the suspended activation had operands on the stack, stack handlers
   3071 // needing rewinding, or if the resume should throw an exception.  The fast path
   3072 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
   3073 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
   3074 // called in any case, as it needs to reconstruct the stack frame and make space
   3075 // for arguments and operands.
   3076 RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
   3077   SealHandleScope shs(isolate);
   3078   DCHECK(args.length() == 3);
   3079   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
   3080   CONVERT_ARG_CHECKED(Object, value, 1);
   3081   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
   3082   JavaScriptFrameIterator stack_iterator(isolate);
   3083   JavaScriptFrame* frame = stack_iterator.frame();
   3084 
   3085   DCHECK_EQ(frame->function(), generator_object->function());
   3086   DCHECK(frame->function()->is_compiled());
   3087 
   3088   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
   3089   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
   3090 
   3091   Address pc = generator_object->function()->code()->instruction_start();
   3092   int offset = generator_object->continuation();
   3093   DCHECK(offset > 0);
   3094   frame->set_pc(pc + offset);
   3095   if (FLAG_enable_ool_constant_pool) {
   3096     frame->set_constant_pool(
   3097         generator_object->function()->code()->constant_pool());
   3098   }
   3099   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
   3100 
   3101   FixedArray* operand_stack = generator_object->operand_stack();
   3102   int operands_count = operand_stack->length();
   3103   if (operands_count != 0) {
   3104     frame->RestoreOperandStack(operand_stack,
   3105                                generator_object->stack_handler_index());
   3106     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
   3107     generator_object->set_stack_handler_index(-1);
   3108   }
   3109 
   3110   JSGeneratorObject::ResumeMode resume_mode =
   3111       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
   3112   switch (resume_mode) {
   3113     case JSGeneratorObject::NEXT:
   3114       return value;
   3115     case JSGeneratorObject::THROW:
   3116       return isolate->Throw(value);
   3117   }
   3118 
   3119   UNREACHABLE();
   3120   return isolate->ThrowIllegalOperation();
   3121 }
   3122 
   3123 
   3124 RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
   3125   HandleScope scope(isolate);
   3126   DCHECK(args.length() == 1);
   3127   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   3128   int continuation = generator->continuation();
   3129   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
   3130       "generator_finished" : "generator_running";
   3131   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
   3132   THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
   3133 }
   3134 
   3135 
   3136 RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
   3137   HandleScope scope(isolate);
   3138   DCHECK(args.length() == 1);
   3139   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   3140 
   3141   // %ObjectFreeze is a fast path and these cases are handled elsewhere.
   3142   RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
   3143                  !object->map()->is_observed() &&
   3144                  !object->IsJSProxy());
   3145 
   3146   Handle<Object> result;
   3147   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
   3148   return *result;
   3149 }
   3150 
   3151 
   3152 RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) {
   3153   HandleScope handle_scope(isolate);
   3154   DCHECK(args.length() == 2);
   3155 
   3156   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   3157   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
   3158 
   3159   // Flatten the string.  If someone wants to get a char at an index
   3160   // in a cons string, it is likely that more indices will be
   3161   // accessed.
   3162   subject = String::Flatten(subject);
   3163 
   3164   if (i >= static_cast<uint32_t>(subject->length())) {
   3165     return isolate->heap()->nan_value();
   3166   }
   3167 
   3168   return Smi::FromInt(subject->Get(i));
   3169 }
   3170 
   3171 
   3172 RUNTIME_FUNCTION(Runtime_CharFromCode) {
   3173   HandleScope handlescope(isolate);
   3174   DCHECK(args.length() == 1);
   3175   if (args[0]->IsNumber()) {
   3176     CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
   3177     code &= 0xffff;
   3178     return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
   3179   }
   3180   return isolate->heap()->empty_string();
   3181 }
   3182 
   3183 
   3184 class FixedArrayBuilder {
   3185  public:
   3186   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
   3187       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
   3188         length_(0),
   3189         has_non_smi_elements_(false) {
   3190     // Require a non-zero initial size. Ensures that doubling the size to
   3191     // extend the array will work.
   3192     DCHECK(initial_capacity > 0);
   3193   }
   3194 
   3195   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
   3196       : array_(backing_store),
   3197         length_(0),
   3198         has_non_smi_elements_(false) {
   3199     // Require a non-zero initial size. Ensures that doubling the size to
   3200     // extend the array will work.
   3201     DCHECK(backing_store->length() > 0);
   3202   }
   3203 
   3204   bool HasCapacity(int elements) {
   3205     int length = array_->length();
   3206     int required_length = length_ + elements;
   3207     return (length >= required_length);
   3208   }
   3209 
   3210   void EnsureCapacity(int elements) {
   3211     int length = array_->length();
   3212     int required_length = length_ + elements;
   3213     if (length < required_length) {
   3214       int new_length = length;
   3215       do {
   3216         new_length *= 2;
   3217       } while (new_length < required_length);
   3218       Handle<FixedArray> extended_array =
   3219           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
   3220       array_->CopyTo(0, *extended_array, 0, length_);
   3221       array_ = extended_array;
   3222     }
   3223   }
   3224 
   3225   void Add(Object* value) {
   3226     DCHECK(!value->IsSmi());
   3227     DCHECK(length_ < capacity());
   3228     array_->set(length_, value);
   3229     length_++;
   3230     has_non_smi_elements_ = true;
   3231   }
   3232 
   3233   void Add(Smi* value) {
   3234     DCHECK(value->IsSmi());
   3235     DCHECK(length_ < capacity());
   3236     array_->set(length_, value);
   3237     length_++;
   3238   }
   3239 
   3240   Handle<FixedArray> array() {
   3241     return array_;
   3242   }
   3243 
   3244   int length() {
   3245     return length_;
   3246   }
   3247 
   3248   int capacity() {
   3249     return array_->length();
   3250   }
   3251 
   3252   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
   3253     JSArray::SetContent(target_array, array_);
   3254     target_array->set_length(Smi::FromInt(length_));
   3255     return target_array;
   3256   }
   3257 
   3258 
   3259  private:
   3260   Handle<FixedArray> array_;
   3261   int length_;
   3262   bool has_non_smi_elements_;
   3263 };
   3264 
   3265 
   3266 // Forward declarations.
   3267 const int kStringBuilderConcatHelperLengthBits = 11;
   3268 const int kStringBuilderConcatHelperPositionBits = 19;
   3269 
   3270 template <typename schar>
   3271 static inline void StringBuilderConcatHelper(String*,
   3272                                              schar*,
   3273                                              FixedArray*,
   3274                                              int);
   3275 
   3276 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
   3277     StringBuilderSubstringLength;
   3278 typedef BitField<int,
   3279                  kStringBuilderConcatHelperLengthBits,
   3280                  kStringBuilderConcatHelperPositionBits>
   3281     StringBuilderSubstringPosition;
   3282 
   3283 
   3284 class ReplacementStringBuilder {
   3285  public:
   3286   ReplacementStringBuilder(Heap* heap, Handle<String> subject,
   3287                            int estimated_part_count)
   3288       : heap_(heap),
   3289         array_builder_(heap->isolate(), estimated_part_count),
   3290         subject_(subject),
   3291         character_count_(0),
   3292         is_one_byte_(subject->IsOneByteRepresentation()) {
   3293     // Require a non-zero initial size. Ensures that doubling the size to
   3294     // extend the array will work.
   3295     DCHECK(estimated_part_count > 0);
   3296   }
   3297 
   3298   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
   3299                                      int from,
   3300                                      int to) {
   3301     DCHECK(from >= 0);
   3302     int length = to - from;
   3303     DCHECK(length > 0);
   3304     if (StringBuilderSubstringLength::is_valid(length) &&
   3305         StringBuilderSubstringPosition::is_valid(from)) {
   3306       int encoded_slice = StringBuilderSubstringLength::encode(length) |
   3307           StringBuilderSubstringPosition::encode(from);
   3308       builder->Add(Smi::FromInt(encoded_slice));
   3309     } else {
   3310       // Otherwise encode as two smis.
   3311       builder->Add(Smi::FromInt(-length));
   3312       builder->Add(Smi::FromInt(from));
   3313     }
   3314   }
   3315 
   3316 
   3317   void EnsureCapacity(int elements) {
   3318     array_builder_.EnsureCapacity(elements);
   3319   }
   3320 
   3321 
   3322   void AddSubjectSlice(int from, int to) {
   3323     AddSubjectSlice(&array_builder_, from, to);
   3324     IncrementCharacterCount(to - from);
   3325   }
   3326 
   3327 
   3328   void AddString(Handle<String> string) {
   3329     int length = string->length();
   3330     DCHECK(length > 0);
   3331     AddElement(*string);
   3332     if (!string->IsOneByteRepresentation()) {
   3333       is_one_byte_ = false;
   3334     }
   3335     IncrementCharacterCount(length);
   3336   }
   3337 
   3338 
   3339   MaybeHandle<String> ToString() {
   3340     Isolate* isolate = heap_->isolate();
   3341     if (array_builder_.length() == 0) {
   3342       return isolate->factory()->empty_string();
   3343     }
   3344 
   3345     Handle<String> joined_string;
   3346     if (is_one_byte_) {
   3347       Handle<SeqOneByteString> seq;
   3348       ASSIGN_RETURN_ON_EXCEPTION(
   3349           isolate, seq,
   3350           isolate->factory()->NewRawOneByteString(character_count_),
   3351           String);
   3352 
   3353       DisallowHeapAllocation no_gc;
   3354       uint8_t* char_buffer = seq->GetChars();
   3355       StringBuilderConcatHelper(*subject_,
   3356                                 char_buffer,
   3357                                 *array_builder_.array(),
   3358                                 array_builder_.length());
   3359       joined_string = Handle<String>::cast(seq);
   3360     } else {
   3361       // Two-byte.
   3362       Handle<SeqTwoByteString> seq;
   3363       ASSIGN_RETURN_ON_EXCEPTION(
   3364           isolate, seq,
   3365           isolate->factory()->NewRawTwoByteString(character_count_),
   3366           String);
   3367 
   3368       DisallowHeapAllocation no_gc;
   3369       uc16* char_buffer = seq->GetChars();
   3370       StringBuilderConcatHelper(*subject_,
   3371                                 char_buffer,
   3372                                 *array_builder_.array(),
   3373                                 array_builder_.length());
   3374       joined_string = Handle<String>::cast(seq);
   3375     }
   3376     return joined_string;
   3377   }
   3378 
   3379 
   3380   void IncrementCharacterCount(int by) {
   3381     if (character_count_ > String::kMaxLength - by) {
   3382       STATIC_ASSERT(String::kMaxLength < kMaxInt);
   3383       character_count_ = kMaxInt;
   3384     } else {
   3385       character_count_ += by;
   3386     }
   3387   }
   3388 
   3389  private:
   3390   void AddElement(Object* element) {
   3391     DCHECK(element->IsSmi() || element->IsString());
   3392     DCHECK(array_builder_.capacity() > array_builder_.length());
   3393     array_builder_.Add(element);
   3394   }
   3395 
   3396   Heap* heap_;
   3397   FixedArrayBuilder array_builder_;
   3398   Handle<String> subject_;
   3399   int character_count_;
   3400   bool is_one_byte_;
   3401 };
   3402 
   3403 
   3404 class CompiledReplacement {
   3405  public:
   3406   explicit CompiledReplacement(Zone* zone)
   3407       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
   3408 
   3409   // Return whether the replacement is simple.
   3410   bool Compile(Handle<String> replacement,
   3411                int capture_count,
   3412                int subject_length);
   3413 
   3414   // Use Apply only if Compile returned false.
   3415   void Apply(ReplacementStringBuilder* builder,
   3416              int match_from,
   3417              int match_to,
   3418              int32_t* match);
   3419 
   3420   // Number of distinct parts of the replacement pattern.
   3421   int parts() {
   3422     return parts_.length();
   3423   }
   3424 
   3425   Zone* zone() const { return zone_; }
   3426 
   3427  private:
   3428   enum PartType {
   3429     SUBJECT_PREFIX = 1,
   3430     SUBJECT_SUFFIX,
   3431     SUBJECT_CAPTURE,
   3432     REPLACEMENT_SUBSTRING,
   3433     REPLACEMENT_STRING,
   3434 
   3435     NUMBER_OF_PART_TYPES
   3436   };
   3437 
   3438   struct ReplacementPart {
   3439     static inline ReplacementPart SubjectMatch() {
   3440       return ReplacementPart(SUBJECT_CAPTURE, 0);
   3441     }
   3442     static inline ReplacementPart SubjectCapture(int capture_index) {
   3443       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
   3444     }
   3445     static inline ReplacementPart SubjectPrefix() {
   3446       return ReplacementPart(SUBJECT_PREFIX, 0);
   3447     }
   3448     static inline ReplacementPart SubjectSuffix(int subject_length) {
   3449       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
   3450     }
   3451     static inline ReplacementPart ReplacementString() {
   3452       return ReplacementPart(REPLACEMENT_STRING, 0);
   3453     }
   3454     static inline ReplacementPart ReplacementSubString(int from, int to) {
   3455       DCHECK(from >= 0);
   3456       DCHECK(to > from);
   3457       return ReplacementPart(-from, to);
   3458     }
   3459 
   3460     // If tag <= 0 then it is the negation of a start index of a substring of
   3461     // the replacement pattern, otherwise it's a value from PartType.
   3462     ReplacementPart(int tag, int data)
   3463         : tag(tag), data(data) {
   3464       // Must be non-positive or a PartType value.
   3465       DCHECK(tag < NUMBER_OF_PART_TYPES);
   3466     }
   3467     // Either a value of PartType or a non-positive number that is
   3468     // the negation of an index into the replacement string.
   3469     int tag;
   3470     // The data value's interpretation depends on the value of tag:
   3471     // tag == SUBJECT_PREFIX ||
   3472     // tag == SUBJECT_SUFFIX:  data is unused.
   3473     // tag == SUBJECT_CAPTURE: data is the number of the capture.
   3474     // tag == REPLACEMENT_SUBSTRING ||
   3475     // tag == REPLACEMENT_STRING:    data is index into array of substrings
   3476     //                               of the replacement string.
   3477     // tag <= 0: Temporary representation of the substring of the replacement
   3478     //           string ranging over -tag .. data.
   3479     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
   3480     //           substring objects.
   3481     int data;
   3482   };
   3483 
   3484   template<typename Char>
   3485   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
   3486                                Vector<Char> characters,
   3487                                int capture_count,
   3488                                int subject_length,
   3489                                Zone* zone) {
   3490     int length = characters.length();
   3491     int last = 0;
   3492     for (int i = 0; i < length; i++) {
   3493       Char c = characters[i];
   3494       if (c == '$') {
   3495         int next_index = i + 1;
   3496         if (next_index == length) {  // No next character!
   3497           break;
   3498         }
   3499         Char c2 = characters[next_index];
   3500         switch (c2) {
   3501         case '$':
   3502           if (i > last) {
   3503             // There is a substring before. Include the first "$".
   3504             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
   3505                        zone);
   3506             last = next_index + 1;  // Continue after the second "$".
   3507           } else {
   3508             // Let the next substring start with the second "$".
   3509             last = next_index;
   3510           }
   3511           i = next_index;
   3512           break;
   3513         case '`':
   3514           if (i > last) {
   3515             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3516           }
   3517           parts->Add(ReplacementPart::SubjectPrefix(), zone);
   3518           i = next_index;
   3519           last = i + 1;
   3520           break;
   3521         case '\'':
   3522           if (i > last) {
   3523             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3524           }
   3525           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
   3526           i = next_index;
   3527           last = i + 1;
   3528           break;
   3529         case '&':
   3530           if (i > last) {
   3531             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3532           }
   3533           parts->Add(ReplacementPart::SubjectMatch(), zone);
   3534           i = next_index;
   3535           last = i + 1;
   3536           break;
   3537         case '0':
   3538         case '1':
   3539         case '2':
   3540         case '3':
   3541         case '4':
   3542         case '5':
   3543         case '6':
   3544         case '7':
   3545         case '8':
   3546         case '9': {
   3547           int capture_ref = c2 - '0';
   3548           if (capture_ref > capture_count) {
   3549             i = next_index;
   3550             continue;
   3551           }
   3552           int second_digit_index = next_index + 1;
   3553           if (second_digit_index < length) {
   3554             // Peek ahead to see if we have two digits.
   3555             Char c3 = characters[second_digit_index];
   3556             if ('0' <= c3 && c3 <= '9') {  // Double digits.
   3557               int double_digit_ref = capture_ref * 10 + c3 - '0';
   3558               if (double_digit_ref <= capture_count) {
   3559                 next_index = second_digit_index;
   3560                 capture_ref = double_digit_ref;
   3561               }
   3562             }
   3563           }
   3564           if (capture_ref > 0) {
   3565             if (i > last) {
   3566               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3567             }
   3568             DCHECK(capture_ref <= capture_count);
   3569             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
   3570             last = next_index + 1;
   3571           }
   3572           i = next_index;
   3573           break;
   3574         }
   3575         default:
   3576           i = next_index;
   3577           break;
   3578         }
   3579       }
   3580     }
   3581     if (length > last) {
   3582       if (last == 0) {
   3583         // Replacement is simple.  Do not use Apply to do the replacement.
   3584         return true;
   3585       } else {
   3586         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
   3587       }
   3588     }
   3589     return false;
   3590   }
   3591 
   3592   ZoneList<ReplacementPart> parts_;
   3593   ZoneList<Handle<String> > replacement_substrings_;
   3594   Zone* zone_;
   3595 };
   3596 
   3597 
   3598 bool CompiledReplacement::Compile(Handle<String> replacement,
   3599                                   int capture_count,
   3600                                   int subject_length) {
   3601   {
   3602     DisallowHeapAllocation no_gc;
   3603     String::FlatContent content = replacement->GetFlatContent();
   3604     DCHECK(content.IsFlat());
   3605     bool simple = false;
   3606     if (content.IsOneByte()) {
   3607       simple = ParseReplacementPattern(&parts_,
   3608                                        content.ToOneByteVector(),
   3609                                        capture_count,
   3610                                        subject_length,
   3611                                        zone());
   3612     } else {
   3613       DCHECK(content.IsTwoByte());
   3614       simple = ParseReplacementPattern(&parts_,
   3615                                        content.ToUC16Vector(),
   3616                                        capture_count,
   3617                                        subject_length,
   3618                                        zone());
   3619     }
   3620     if (simple) return true;
   3621   }
   3622 
   3623   Isolate* isolate = replacement->GetIsolate();
   3624   // Find substrings of replacement string and create them as String objects.
   3625   int substring_index = 0;
   3626   for (int i = 0, n = parts_.length(); i < n; i++) {
   3627     int tag = parts_[i].tag;
   3628     if (tag <= 0) {  // A replacement string slice.
   3629       int from = -tag;
   3630       int to = parts_[i].data;
   3631       replacement_substrings_.Add(
   3632           isolate->factory()->NewSubString(replacement, from, to), zone());
   3633       parts_[i].tag = REPLACEMENT_SUBSTRING;
   3634       parts_[i].data = substring_index;
   3635       substring_index++;
   3636     } else if (tag == REPLACEMENT_STRING) {
   3637       replacement_substrings_.Add(replacement, zone());
   3638       parts_[i].data = substring_index;
   3639       substring_index++;
   3640     }
   3641   }
   3642   return false;
   3643 }
   3644 
   3645 
   3646 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
   3647                                 int match_from,
   3648                                 int match_to,
   3649                                 int32_t* match) {
   3650   DCHECK_LT(0, parts_.length());
   3651   for (int i = 0, n = parts_.length(); i < n; i++) {
   3652     ReplacementPart part = parts_[i];
   3653     switch (part.tag) {
   3654       case SUBJECT_PREFIX:
   3655         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
   3656         break;
   3657       case SUBJECT_SUFFIX: {
   3658         int subject_length = part.data;
   3659         if (match_to < subject_length) {
   3660           builder->AddSubjectSlice(match_to, subject_length);
   3661         }
   3662         break;
   3663       }
   3664       case SUBJECT_CAPTURE: {
   3665         int capture = part.data;
   3666         int from = match[capture * 2];
   3667         int to = match[capture * 2 + 1];
   3668         if (from >= 0 && to > from) {
   3669           builder->AddSubjectSlice(from, to);
   3670         }
   3671         break;
   3672       }
   3673       case REPLACEMENT_SUBSTRING:
   3674       case REPLACEMENT_STRING:
   3675         builder->AddString(replacement_substrings_[part.data]);
   3676         break;
   3677       default:
   3678         UNREACHABLE();
   3679     }
   3680   }
   3681 }
   3682 
   3683 
   3684 void FindOneByteStringIndices(Vector<const uint8_t> subject, char pattern,
   3685                               ZoneList<int>* indices, unsigned int limit,
   3686                               Zone* zone) {
   3687   DCHECK(limit > 0);
   3688   // Collect indices of pattern in subject using memchr.
   3689   // Stop after finding at most limit values.
   3690   const uint8_t* subject_start = subject.start();
   3691   const uint8_t* subject_end = subject_start + subject.length();
   3692   const uint8_t* pos = subject_start;
   3693   while (limit > 0) {
   3694     pos = reinterpret_cast<const uint8_t*>(
   3695         memchr(pos, pattern, subject_end - pos));
   3696     if (pos == NULL) return;
   3697     indices->Add(static_cast<int>(pos - subject_start), zone);
   3698     pos++;
   3699     limit--;
   3700   }
   3701 }
   3702 
   3703 
   3704 void FindTwoByteStringIndices(const Vector<const uc16> subject,
   3705                               uc16 pattern,
   3706                               ZoneList<int>* indices,
   3707                               unsigned int limit,
   3708                               Zone* zone) {
   3709   DCHECK(limit > 0);
   3710   const uc16* subject_start = subject.start();
   3711   const uc16* subject_end = subject_start + subject.length();
   3712   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
   3713     if (*pos == pattern) {
   3714       indices->Add(static_cast<int>(pos - subject_start), zone);
   3715       limit--;
   3716     }
   3717   }
   3718 }
   3719 
   3720 
   3721 template <typename SubjectChar, typename PatternChar>
   3722 void FindStringIndices(Isolate* isolate,
   3723                        Vector<const SubjectChar> subject,
   3724                        Vector<const PatternChar> pattern,
   3725                        ZoneList<int>* indices,
   3726                        unsigned int limit,
   3727                        Zone* zone) {
   3728   DCHECK(limit > 0);
   3729   // Collect indices of pattern in subject.
   3730   // Stop after finding at most limit values.
   3731   int pattern_length = pattern.length();
   3732   int index = 0;
   3733   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   3734   while (limit > 0) {
   3735     index = search.Search(subject, index);
   3736     if (index < 0) return;
   3737     indices->Add(index, zone);
   3738     index += pattern_length;
   3739     limit--;
   3740   }
   3741 }
   3742 
   3743 
   3744 void FindStringIndicesDispatch(Isolate* isolate,
   3745                                String* subject,
   3746                                String* pattern,
   3747                                ZoneList<int>* indices,
   3748                                unsigned int limit,
   3749                                Zone* zone) {
   3750   {
   3751     DisallowHeapAllocation no_gc;
   3752     String::FlatContent subject_content = subject->GetFlatContent();
   3753     String::FlatContent pattern_content = pattern->GetFlatContent();
   3754     DCHECK(subject_content.IsFlat());
   3755     DCHECK(pattern_content.IsFlat());
   3756     if (subject_content.IsOneByte()) {
   3757       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
   3758       if (pattern_content.IsOneByte()) {
   3759         Vector<const uint8_t> pattern_vector =
   3760             pattern_content.ToOneByteVector();
   3761         if (pattern_vector.length() == 1) {
   3762           FindOneByteStringIndices(subject_vector, pattern_vector[0], indices,
   3763                                    limit, zone);
   3764         } else {
   3765           FindStringIndices(isolate,
   3766                             subject_vector,
   3767                             pattern_vector,
   3768                             indices,
   3769                             limit,
   3770                             zone);
   3771         }
   3772       } else {
   3773         FindStringIndices(isolate,
   3774                           subject_vector,
   3775                           pattern_content.ToUC16Vector(),
   3776                           indices,
   3777                           limit,
   3778                           zone);
   3779       }
   3780     } else {
   3781       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
   3782       if (pattern_content.IsOneByte()) {
   3783         Vector<const uint8_t> pattern_vector =
   3784             pattern_content.ToOneByteVector();
   3785         if (pattern_vector.length() == 1) {
   3786           FindTwoByteStringIndices(subject_vector,
   3787                                    pattern_vector[0],
   3788                                    indices,
   3789                                    limit,
   3790                                    zone);
   3791         } else {
   3792           FindStringIndices(isolate,
   3793                             subject_vector,
   3794                             pattern_vector,
   3795                             indices,
   3796                             limit,
   3797                             zone);
   3798         }
   3799       } else {
   3800         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
   3801         if (pattern_vector.length() == 1) {
   3802           FindTwoByteStringIndices(subject_vector,
   3803                                    pattern_vector[0],
   3804                                    indices,
   3805                                    limit,
   3806                                    zone);
   3807         } else {
   3808           FindStringIndices(isolate,
   3809                             subject_vector,
   3810                             pattern_vector,
   3811                             indices,
   3812                             limit,
   3813                             zone);
   3814         }
   3815       }
   3816     }
   3817   }
   3818 }
   3819 
   3820 
   3821 template<typename ResultSeqString>
   3822 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
   3823     Isolate* isolate,
   3824     Handle<String> subject,
   3825     Handle<JSRegExp> pattern_regexp,
   3826     Handle<String> replacement,
   3827     Handle<JSArray> last_match_info) {
   3828   DCHECK(subject->IsFlat());
   3829   DCHECK(replacement->IsFlat());
   3830 
   3831   ZoneScope zone_scope(isolate->runtime_zone());
   3832   ZoneList<int> indices(8, zone_scope.zone());
   3833   DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
   3834   String* pattern =
   3835       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
   3836   int subject_len = subject->length();
   3837   int pattern_len = pattern->length();
   3838   int replacement_len = replacement->length();
   3839 
   3840   FindStringIndicesDispatch(
   3841       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
   3842 
   3843   int matches = indices.length();
   3844   if (matches == 0) return *subject;
   3845 
   3846   // Detect integer overflow.
   3847   int64_t result_len_64 =
   3848       (static_cast<int64_t>(replacement_len) -
   3849        static_cast<int64_t>(pattern_len)) *
   3850       static_cast<int64_t>(matches) +
   3851       static_cast<int64_t>(subject_len);
   3852   int result_len;
   3853   if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
   3854     STATIC_ASSERT(String::kMaxLength < kMaxInt);
   3855     result_len = kMaxInt;  // Provoke exception.
   3856   } else {
   3857     result_len = static_cast<int>(result_len_64);
   3858   }
   3859 
   3860   int subject_pos = 0;
   3861   int result_pos = 0;
   3862 
   3863   MaybeHandle<SeqString> maybe_res;
   3864   if (ResultSeqString::kHasOneByteEncoding) {
   3865     maybe_res = isolate->factory()->NewRawOneByteString(result_len);
   3866   } else {
   3867     maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
   3868   }
   3869   Handle<SeqString> untyped_res;
   3870   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
   3871   Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
   3872 
   3873   for (int i = 0; i < matches; i++) {
   3874     // Copy non-matched subject content.
   3875     if (subject_pos < indices.at(i)) {
   3876       String::WriteToFlat(*subject,
   3877                           result->GetChars() + result_pos,
   3878                           subject_pos,
   3879                           indices.at(i));
   3880       result_pos += indices.at(i) - subject_pos;
   3881     }
   3882 
   3883     // Replace match.
   3884     if (replacement_len > 0) {
   3885       String::WriteToFlat(*replacement,
   3886                           result->GetChars() + result_pos,
   3887                           0,
   3888                           replacement_len);
   3889       result_pos += replacement_len;
   3890     }
   3891 
   3892     subject_pos = indices.at(i) + pattern_len;
   3893   }
   3894   // Add remaining subject content at the end.
   3895   if (subject_pos < subject_len) {
   3896     String::WriteToFlat(*subject,
   3897                         result->GetChars() + result_pos,
   3898                         subject_pos,
   3899                         subject_len);
   3900   }
   3901 
   3902   int32_t match_indices[] = { indices.at(matches - 1),
   3903                               indices.at(matches - 1) + pattern_len };
   3904   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
   3905 
   3906   return *result;
   3907 }
   3908 
   3909 
   3910 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
   3911     Isolate* isolate,
   3912     Handle<String> subject,
   3913     Handle<JSRegExp> regexp,
   3914     Handle<String> replacement,
   3915     Handle<JSArray> last_match_info) {
   3916   DCHECK(subject->IsFlat());
   3917   DCHECK(replacement->IsFlat());
   3918 
   3919   int capture_count = regexp->CaptureCount();
   3920   int subject_length = subject->length();
   3921 
   3922   // CompiledReplacement uses zone allocation.
   3923   ZoneScope zone_scope(isolate->runtime_zone());
   3924   CompiledReplacement compiled_replacement(zone_scope.zone());
   3925   bool simple_replace = compiled_replacement.Compile(replacement,
   3926                                                      capture_count,
   3927                                                      subject_length);
   3928 
   3929   // Shortcut for simple non-regexp global replacements
   3930   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
   3931     if (subject->HasOnlyOneByteChars() &&
   3932         replacement->HasOnlyOneByteChars()) {
   3933       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   3934           isolate, subject, regexp, replacement, last_match_info);
   3935     } else {
   3936       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   3937           isolate, subject, regexp, replacement, last_match_info);
   3938     }
   3939   }
   3940 
   3941   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   3942   if (global_cache.HasException()) return isolate->heap()->exception();
   3943 
   3944   int32_t* current_match = global_cache.FetchNext();
   3945   if (current_match == NULL) {
   3946     if (global_cache.HasException()) return isolate->heap()->exception();
   3947     return *subject;
   3948   }
   3949 
   3950   // Guessing the number of parts that the final result string is built
   3951   // from. Global regexps can match any number of times, so we guess
   3952   // conservatively.
   3953   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
   3954   ReplacementStringBuilder builder(isolate->heap(),
   3955                                    subject,
   3956                                    expected_parts);
   3957 
   3958   // Number of parts added by compiled replacement plus preceeding
   3959   // string and possibly suffix after last match.  It is possible for
   3960   // all components to use two elements when encoded as two smis.
   3961   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
   3962 
   3963   int prev = 0;
   3964 
   3965   do {
   3966     builder.EnsureCapacity(parts_added_per_loop);
   3967 
   3968     int start = current_match[0];
   3969     int end = current_match[1];
   3970 
   3971     if (prev < start) {
   3972       builder.AddSubjectSlice(prev, start);
   3973     }
   3974 
   3975     if (simple_replace) {
   3976       builder.AddString(replacement);
   3977     } else {
   3978       compiled_replacement.Apply(&builder,
   3979                                  start,
   3980                                  end,
   3981                                  current_match);
   3982     }
   3983     prev = end;
   3984 
   3985     current_match = global_cache.FetchNext();
   3986   } while (current_match != NULL);
   3987 
   3988   if (global_cache.HasException()) return isolate->heap()->exception();
   3989 
   3990   if (prev < subject_length) {
   3991     builder.EnsureCapacity(2);
   3992     builder.AddSubjectSlice(prev, subject_length);
   3993   }
   3994 
   3995   RegExpImpl::SetLastMatchInfo(last_match_info,
   3996                                subject,
   3997                                capture_count,
   3998                                global_cache.LastSuccessfulMatch());
   3999 
   4000   Handle<String> result;
   4001   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
   4002   return *result;
   4003 }
   4004 
   4005 
   4006 template <typename ResultSeqString>
   4007 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
   4008     Isolate* isolate,
   4009     Handle<String> subject,
   4010     Handle<JSRegExp> regexp,
   4011     Handle<JSArray> last_match_info) {
   4012   DCHECK(subject->IsFlat());
   4013 
   4014   // Shortcut for simple non-regexp global replacements
   4015   if (regexp->TypeTag() == JSRegExp::ATOM) {
   4016     Handle<String> empty_string = isolate->factory()->empty_string();
   4017     if (subject->IsOneByteRepresentation()) {
   4018       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   4019           isolate, subject, regexp, empty_string, last_match_info);
   4020     } else {
   4021       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   4022           isolate, subject, regexp, empty_string, last_match_info);
   4023     }
   4024   }
   4025 
   4026   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4027   if (global_cache.HasException()) return isolate->heap()->exception();
   4028 
   4029   int32_t* current_match = global_cache.FetchNext();
   4030   if (current_match == NULL) {
   4031     if (global_cache.HasException()) return isolate->heap()->exception();
   4032     return *subject;
   4033   }
   4034 
   4035   int start = current_match[0];
   4036   int end = current_match[1];
   4037   int capture_count = regexp->CaptureCount();
   4038   int subject_length = subject->length();
   4039 
   4040   int new_length = subject_length - (end - start);
   4041   if (new_length == 0) return isolate->heap()->empty_string();
   4042 
   4043   Handle<ResultSeqString> answer;
   4044   if (ResultSeqString::kHasOneByteEncoding) {
   4045     answer = Handle<ResultSeqString>::cast(
   4046         isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
   4047   } else {
   4048     answer = Handle<ResultSeqString>::cast(
   4049         isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
   4050   }
   4051 
   4052   int prev = 0;
   4053   int position = 0;
   4054 
   4055   do {
   4056     start = current_match[0];
   4057     end = current_match[1];
   4058     if (prev < start) {
   4059       // Add substring subject[prev;start] to answer string.
   4060       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
   4061       position += start - prev;
   4062     }
   4063     prev = end;
   4064 
   4065     current_match = global_cache.FetchNext();
   4066   } while (current_match != NULL);
   4067 
   4068   if (global_cache.HasException()) return isolate->heap()->exception();
   4069 
   4070   RegExpImpl::SetLastMatchInfo(last_match_info,
   4071                                subject,
   4072                                capture_count,
   4073                                global_cache.LastSuccessfulMatch());
   4074 
   4075   if (prev < subject_length) {
   4076     // Add substring subject[prev;length] to answer string.
   4077     String::WriteToFlat(
   4078         *subject, answer->GetChars() + position, prev, subject_length);
   4079     position += subject_length - prev;
   4080   }
   4081 
   4082   if (position == 0) return isolate->heap()->empty_string();
   4083 
   4084   // Shorten string and fill
   4085   int string_size = ResultSeqString::SizeFor(position);
   4086   int allocated_string_size = ResultSeqString::SizeFor(new_length);
   4087   int delta = allocated_string_size - string_size;
   4088 
   4089   answer->set_length(position);
   4090   if (delta == 0) return *answer;
   4091 
   4092   Address end_of_string = answer->address() + string_size;
   4093   Heap* heap = isolate->heap();
   4094 
   4095   // The trimming is performed on a newly allocated object, which is on a
   4096   // fresly allocated page or on an already swept page. Hence, the sweeper
   4097   // thread can not get confused with the filler creation. No synchronization
   4098   // needed.
   4099   heap->CreateFillerObjectAt(end_of_string, delta);
   4100   heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
   4101   return *answer;
   4102 }
   4103 
   4104 
   4105 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
   4106   HandleScope scope(isolate);
   4107   DCHECK(args.length() == 4);
   4108 
   4109   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4110   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
   4111   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4112   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   4113 
   4114   RUNTIME_ASSERT(regexp->GetFlags().is_global());
   4115   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
   4116 
   4117   subject = String::Flatten(subject);
   4118 
   4119   if (replacement->length() == 0) {
   4120     if (subject->HasOnlyOneByteChars()) {
   4121       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
   4122           isolate, subject, regexp, last_match_info);
   4123     } else {
   4124       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
   4125           isolate, subject, regexp, last_match_info);
   4126     }
   4127   }
   4128 
   4129   replacement = String::Flatten(replacement);
   4130 
   4131   return StringReplaceGlobalRegExpWithString(
   4132       isolate, subject, regexp, replacement, last_match_info);
   4133 }
   4134 
   4135 
   4136 // This may return an empty MaybeHandle if an exception is thrown or
   4137 // we abort due to reaching the recursion limit.
   4138 MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
   4139                                                    Handle<String> subject,
   4140                                                    Handle<String> search,
   4141                                                    Handle<String> replace,
   4142                                                    bool* found,
   4143                                                    int recursion_limit) {
   4144   StackLimitCheck stackLimitCheck(isolate);
   4145   if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
   4146     return MaybeHandle<String>();
   4147   }
   4148   recursion_limit--;
   4149   if (subject->IsConsString()) {
   4150     ConsString* cons = ConsString::cast(*subject);
   4151     Handle<String> first = Handle<String>(cons->first());
   4152     Handle<String> second = Handle<String>(cons->second());
   4153     Handle<String> new_first;
   4154     if (!StringReplaceOneCharWithString(
   4155             isolate, first, search, replace, found, recursion_limit)
   4156             .ToHandle(&new_first)) {
   4157       return MaybeHandle<String>();
   4158     }
   4159     if (*found) return isolate->factory()->NewConsString(new_first, second);
   4160 
   4161     Handle<String> new_second;
   4162     if (!StringReplaceOneCharWithString(
   4163             isolate, second, search, replace, found, recursion_limit)
   4164             .ToHandle(&new_second)) {
   4165       return MaybeHandle<String>();
   4166     }
   4167     if (*found) return isolate->factory()->NewConsString(first, new_second);
   4168 
   4169     return subject;
   4170   } else {
   4171     int index = Runtime::StringMatch(isolate, subject, search, 0);
   4172     if (index == -1) return subject;
   4173     *found = true;
   4174     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
   4175     Handle<String> cons1;
   4176     ASSIGN_RETURN_ON_EXCEPTION(
   4177         isolate, cons1,
   4178         isolate->factory()->NewConsString(first, replace),
   4179         String);
   4180     Handle<String> second =
   4181         isolate->factory()->NewSubString(subject, index + 1, subject->length());
   4182     return isolate->factory()->NewConsString(cons1, second);
   4183   }
   4184 }
   4185 
   4186 
   4187 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
   4188   HandleScope scope(isolate);
   4189   DCHECK(args.length() == 3);
   4190   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4191   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
   4192   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
   4193 
   4194   // If the cons string tree is too deep, we simply abort the recursion and
   4195   // retry with a flattened subject string.
   4196   const int kRecursionLimit = 0x1000;
   4197   bool found = false;
   4198   Handle<String> result;
   4199   if (StringReplaceOneCharWithString(
   4200           isolate, subject, search, replace, &found, kRecursionLimit)
   4201           .ToHandle(&result)) {
   4202     return *result;
   4203   }
   4204   if (isolate->has_pending_exception()) return isolate->heap()->exception();
   4205 
   4206   subject = String::Flatten(subject);
   4207   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4208       isolate, result,
   4209       StringReplaceOneCharWithString(
   4210           isolate, subject, search, replace, &found, kRecursionLimit));
   4211   return *result;
   4212 }
   4213 
   4214 
   4215 // Perform string match of pattern on subject, starting at start index.
   4216 // Caller must ensure that 0 <= start_index <= sub->length(),
   4217 // and should check that pat->length() + start_index <= sub->length().
   4218 int Runtime::StringMatch(Isolate* isolate,
   4219                          Handle<String> sub,
   4220                          Handle<String> pat,
   4221                          int start_index) {
   4222   DCHECK(0 <= start_index);
   4223   DCHECK(start_index <= sub->length());
   4224 
   4225   int pattern_length = pat->length();
   4226   if (pattern_length == 0) return start_index;
   4227 
   4228   int subject_length = sub->length();
   4229   if (start_index + pattern_length > subject_length) return -1;
   4230 
   4231   sub = String::Flatten(sub);
   4232   pat = String::Flatten(pat);
   4233 
   4234   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4235   // Extract flattened substrings of cons strings before getting encoding.
   4236   String::FlatContent seq_sub = sub->GetFlatContent();
   4237   String::FlatContent seq_pat = pat->GetFlatContent();
   4238 
   4239   // dispatch on type of strings
   4240   if (seq_pat.IsOneByte()) {
   4241     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
   4242     if (seq_sub.IsOneByte()) {
   4243       return SearchString(isolate,
   4244                           seq_sub.ToOneByteVector(),
   4245                           pat_vector,
   4246                           start_index);
   4247     }
   4248     return SearchString(isolate,
   4249                         seq_sub.ToUC16Vector(),
   4250                         pat_vector,
   4251                         start_index);
   4252   }
   4253   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
   4254   if (seq_sub.IsOneByte()) {
   4255     return SearchString(isolate,
   4256                         seq_sub.ToOneByteVector(),
   4257                         pat_vector,
   4258                         start_index);
   4259   }
   4260   return SearchString(isolate,
   4261                       seq_sub.ToUC16Vector(),
   4262                       pat_vector,
   4263                       start_index);
   4264 }
   4265 
   4266 
   4267 RUNTIME_FUNCTION(Runtime_StringIndexOf) {
   4268   HandleScope scope(isolate);
   4269   DCHECK(args.length() == 3);
   4270 
   4271   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4272   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4273   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
   4274 
   4275   uint32_t start_index;
   4276   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4277 
   4278   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
   4279   int position = Runtime::StringMatch(isolate, sub, pat, start_index);
   4280   return Smi::FromInt(position);
   4281 }
   4282 
   4283 
   4284 template <typename schar, typename pchar>
   4285 static int StringMatchBackwards(Vector<const schar> subject,
   4286                                 Vector<const pchar> pattern,
   4287                                 int idx) {
   4288   int pattern_length = pattern.length();
   4289   DCHECK(pattern_length >= 1);
   4290   DCHECK(idx + pattern_length <= subject.length());
   4291 
   4292   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   4293     for (int i = 0; i < pattern_length; i++) {
   4294       uc16 c = pattern[i];
   4295       if (c > String::kMaxOneByteCharCode) {
   4296         return -1;
   4297       }
   4298     }
   4299   }
   4300 
   4301   pchar pattern_first_char = pattern[0];
   4302   for (int i = idx; i >= 0; i--) {
   4303     if (subject[i] != pattern_first_char) continue;
   4304     int j = 1;
   4305     while (j < pattern_length) {
   4306       if (pattern[j] != subject[i+j]) {
   4307         break;
   4308       }
   4309       j++;
   4310     }
   4311     if (j == pattern_length) {
   4312       return i;
   4313     }
   4314   }
   4315   return -1;
   4316 }
   4317 
   4318 
   4319 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
   4320   HandleScope scope(isolate);
   4321   DCHECK(args.length() == 3);
   4322 
   4323   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4324   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4325   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
   4326 
   4327   uint32_t start_index;
   4328   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4329 
   4330   uint32_t pat_length = pat->length();
   4331   uint32_t sub_length = sub->length();
   4332 
   4333   if (start_index + pat_length > sub_length) {
   4334     start_index = sub_length - pat_length;
   4335   }
   4336 
   4337   if (pat_length == 0) {
   4338     return Smi::FromInt(start_index);
   4339   }
   4340 
   4341   sub = String::Flatten(sub);
   4342   pat = String::Flatten(pat);
   4343 
   4344   int position = -1;
   4345   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4346 
   4347   String::FlatContent sub_content = sub->GetFlatContent();
   4348   String::FlatContent pat_content = pat->GetFlatContent();
   4349 
   4350   if (pat_content.IsOneByte()) {
   4351     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
   4352     if (sub_content.IsOneByte()) {
   4353       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4354                                       pat_vector,
   4355                                       start_index);
   4356     } else {
   4357       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4358                                       pat_vector,
   4359                                       start_index);
   4360     }
   4361   } else {
   4362     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
   4363     if (sub_content.IsOneByte()) {
   4364       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4365                                       pat_vector,
   4366                                       start_index);
   4367     } else {
   4368       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4369                                       pat_vector,
   4370                                       start_index);
   4371     }
   4372   }
   4373 
   4374   return Smi::FromInt(position);
   4375 }
   4376 
   4377 
   4378 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
   4379   HandleScope handle_scope(isolate);
   4380   DCHECK(args.length() == 2);
   4381 
   4382   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
   4383   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
   4384 
   4385   if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
   4386   int str1_length = str1->length();
   4387   int str2_length = str2->length();
   4388 
   4389   // Decide trivial cases without flattening.
   4390   if (str1_length == 0) {
   4391     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
   4392     return Smi::FromInt(-str2_length);
   4393   } else {
   4394     if (str2_length == 0) return Smi::FromInt(str1_length);
   4395   }
   4396 
   4397   int end = str1_length < str2_length ? str1_length : str2_length;
   4398 
   4399   // No need to flatten if we are going to find the answer on the first
   4400   // character.  At this point we know there is at least one character
   4401   // in each string, due to the trivial case handling above.
   4402   int d = str1->Get(0) - str2->Get(0);
   4403   if (d != 0) return Smi::FromInt(d);
   4404 
   4405   str1 = String::Flatten(str1);
   4406   str2 = String::Flatten(str2);
   4407 
   4408   DisallowHeapAllocation no_gc;
   4409   String::FlatContent flat1 = str1->GetFlatContent();
   4410   String::FlatContent flat2 = str2->GetFlatContent();
   4411 
   4412   for (int i = 0; i < end; i++) {
   4413     if (flat1.Get(i) != flat2.Get(i)) {
   4414       return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
   4415     }
   4416   }
   4417 
   4418   return Smi::FromInt(str1_length - str2_length);
   4419 }
   4420 
   4421 
   4422 RUNTIME_FUNCTION(Runtime_SubString) {
   4423   HandleScope scope(isolate);
   4424   DCHECK(args.length() == 3);
   4425 
   4426   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   4427   int start, end;
   4428   // We have a fast integer-only case here to avoid a conversion to double in
   4429   // the common case where from and to are Smis.
   4430   if (args[1]->IsSmi() && args[2]->IsSmi()) {
   4431     CONVERT_SMI_ARG_CHECKED(from_number, 1);
   4432     CONVERT_SMI_ARG_CHECKED(to_number, 2);
   4433     start = from_number;
   4434     end = to_number;
   4435   } else {
   4436     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
   4437     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
   4438     start = FastD2IChecked(from_number);
   4439     end = FastD2IChecked(to_number);
   4440   }
   4441   RUNTIME_ASSERT(end >= start);
   4442   RUNTIME_ASSERT(start >= 0);
   4443   RUNTIME_ASSERT(end <= string->length());
   4444   isolate->counters()->sub_string_runtime()->Increment();
   4445 
   4446   return *isolate->factory()->NewSubString(string, start, end);
   4447 }
   4448 
   4449 
   4450 RUNTIME_FUNCTION(Runtime_InternalizeString) {
   4451   HandleScope handles(isolate);
   4452   RUNTIME_ASSERT(args.length() == 1);
   4453   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   4454   return *isolate->factory()->InternalizeString(string);
   4455 }
   4456 
   4457 
   4458 RUNTIME_FUNCTION(Runtime_StringMatch) {
   4459   HandleScope handles(isolate);
   4460   DCHECK(args.length() == 3);
   4461 
   4462   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4463   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4464   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
   4465 
   4466   RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
   4467 
   4468   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4469   if (global_cache.HasException()) return isolate->heap()->exception();
   4470 
   4471   int capture_count = regexp->CaptureCount();
   4472 
   4473   ZoneScope zone_scope(isolate->runtime_zone());
   4474   ZoneList<int> offsets(8, zone_scope.zone());
   4475 
   4476   while (true) {
   4477     int32_t* match = global_cache.FetchNext();
   4478     if (match == NULL) break;
   4479     offsets.Add(match[0], zone_scope.zone());  // start
   4480     offsets.Add(match[1], zone_scope.zone());  // end
   4481   }
   4482 
   4483   if (global_cache.HasException()) return isolate->heap()->exception();
   4484 
   4485   if (offsets.length() == 0) {
   4486     // Not a single match.
   4487     return isolate->heap()->null_value();
   4488   }
   4489 
   4490   RegExpImpl::SetLastMatchInfo(regexp_info,
   4491                                subject,
   4492                                capture_count,
   4493                                global_cache.LastSuccessfulMatch());
   4494 
   4495   int matches = offsets.length() / 2;
   4496   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
   4497   Handle<String> substring =
   4498       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
   4499   elements->set(0, *substring);
   4500   for (int i = 1; i < matches; i++) {
   4501     HandleScope temp_scope(isolate);
   4502     int from = offsets.at(i * 2);
   4503     int to = offsets.at(i * 2 + 1);
   4504     Handle<String> substring =
   4505         isolate->factory()->NewProperSubString(subject, from, to);
   4506     elements->set(i, *substring);
   4507   }
   4508   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
   4509   result->set_length(Smi::FromInt(matches));
   4510   return *result;
   4511 }
   4512 
   4513 
   4514 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
   4515 // separate last match info.  See comment on that function.
   4516 template<bool has_capture>
   4517 static Object* SearchRegExpMultiple(
   4518     Isolate* isolate,
   4519     Handle<String> subject,
   4520     Handle<JSRegExp> regexp,
   4521     Handle<JSArray> last_match_array,
   4522     Handle<JSArray> result_array) {
   4523   DCHECK(subject->IsFlat());
   4524   DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
   4525 
   4526   int capture_count = regexp->CaptureCount();
   4527   int subject_length = subject->length();
   4528 
   4529   static const int kMinLengthToCache = 0x1000;
   4530 
   4531   if (subject_length > kMinLengthToCache) {
   4532     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
   4533         isolate->heap(),
   4534         *subject,
   4535         regexp->data(),
   4536         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
   4537     if (*cached_answer != Smi::FromInt(0)) {
   4538       Handle<FixedArray> cached_fixed_array =
   4539           Handle<FixedArray>(FixedArray::cast(*cached_answer));
   4540       // The cache FixedArray is a COW-array and can therefore be reused.
   4541       JSArray::SetContent(result_array, cached_fixed_array);
   4542       // The actual length of the result array is stored in the last element of
   4543       // the backing store (the backing FixedArray may have a larger capacity).
   4544       Object* cached_fixed_array_last_element =
   4545           cached_fixed_array->get(cached_fixed_array->length() - 1);
   4546       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
   4547       result_array->set_length(js_array_length);
   4548       RegExpImpl::SetLastMatchInfo(
   4549           last_match_array, subject, capture_count, NULL);
   4550       return *result_array;
   4551     }
   4552   }
   4553 
   4554   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4555   if (global_cache.HasException()) return isolate->heap()->exception();
   4556 
   4557   // Ensured in Runtime_RegExpExecMultiple.
   4558   DCHECK(result_array->HasFastObjectElements());
   4559   Handle<FixedArray> result_elements(
   4560       FixedArray::cast(result_array->elements()));
   4561   if (result_elements->length() < 16) {
   4562     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   4563   }
   4564 
   4565   FixedArrayBuilder builder(result_elements);
   4566 
   4567   // Position to search from.
   4568   int match_start = -1;
   4569   int match_end = 0;
   4570   bool first = true;
   4571 
   4572   // Two smis before and after the match, for very long strings.
   4573   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
   4574 
   4575   while (true) {
   4576     int32_t* current_match = global_cache.FetchNext();
   4577     if (current_match == NULL) break;
   4578     match_start = current_match[0];
   4579     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   4580     if (match_end < match_start) {
   4581       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4582                                                 match_end,
   4583                                                 match_start);
   4584     }
   4585     match_end = current_match[1];
   4586     {
   4587       // Avoid accumulating new handles inside loop.
   4588       HandleScope temp_scope(isolate);
   4589       Handle<String> match;
   4590       if (!first) {
   4591         match = isolate->factory()->NewProperSubString(subject,
   4592                                                        match_start,
   4593                                                        match_end);
   4594       } else {
   4595         match = isolate->factory()->NewSubString(subject,
   4596                                                  match_start,
   4597                                                  match_end);
   4598         first = false;
   4599       }
   4600 
   4601       if (has_capture) {
   4602         // Arguments array to replace function is match, captures, index and
   4603         // subject, i.e., 3 + capture count in total.
   4604         Handle<FixedArray> elements =
   4605             isolate->factory()->NewFixedArray(3 + capture_count);
   4606 
   4607         elements->set(0, *match);
   4608         for (int i = 1; i <= capture_count; i++) {
   4609           int start = current_match[i * 2];
   4610           if (start >= 0) {
   4611             int end = current_match[i * 2 + 1];
   4612             DCHECK(start <= end);
   4613             Handle<String> substring =
   4614                 isolate->factory()->NewSubString(subject, start, end);
   4615             elements->set(i, *substring);
   4616           } else {
   4617             DCHECK(current_match[i * 2 + 1] < 0);
   4618             elements->set(i, isolate->heap()->undefined_value());
   4619           }
   4620         }
   4621         elements->set(capture_count + 1, Smi::FromInt(match_start));
   4622         elements->set(capture_count + 2, *subject);
   4623         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
   4624       } else {
   4625         builder.Add(*match);
   4626       }
   4627     }
   4628   }
   4629 
   4630   if (global_cache.HasException()) return isolate->heap()->exception();
   4631 
   4632   if (match_start >= 0) {
   4633     // Finished matching, with at least one match.
   4634     if (match_end < subject_length) {
   4635       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4636                                                 match_end,
   4637                                                 subject_length);
   4638     }
   4639 
   4640     RegExpImpl::SetLastMatchInfo(
   4641         last_match_array, subject, capture_count, NULL);
   4642 
   4643     if (subject_length > kMinLengthToCache) {
   4644       // Store the length of the result array into the last element of the
   4645       // backing FixedArray.
   4646       builder.EnsureCapacity(1);
   4647       Handle<FixedArray> fixed_array = builder.array();
   4648       fixed_array->set(fixed_array->length() - 1,
   4649                        Smi::FromInt(builder.length()));
   4650       // Cache the result and turn the FixedArray into a COW array.
   4651       RegExpResultsCache::Enter(isolate,
   4652                                 subject,
   4653                                 handle(regexp->data(), isolate),
   4654                                 fixed_array,
   4655                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
   4656     }
   4657     return *builder.ToJSArray(result_array);
   4658   } else {
   4659     return isolate->heap()->null_value();  // No matches at all.
   4660   }
   4661 }
   4662 
   4663 
   4664 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
   4665 // lastMatchInfoOverride to maintain the last match info, so we don't need to
   4666 // set any other last match array info.
   4667 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
   4668   HandleScope handles(isolate);
   4669   DCHECK(args.length() == 4);
   4670 
   4671   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   4672   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   4673   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
   4674   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
   4675   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
   4676   RUNTIME_ASSERT(result_array->HasFastObjectElements());
   4677 
   4678   subject = String::Flatten(subject);
   4679   RUNTIME_ASSERT(regexp->GetFlags().is_global());
   4680 
   4681   if (regexp->CaptureCount() == 0) {
   4682     return SearchRegExpMultiple<false>(
   4683         isolate, subject, regexp, last_match_info, result_array);
   4684   } else {
   4685     return SearchRegExpMultiple<true>(
   4686         isolate, subject, regexp, last_match_info, result_array);
   4687   }
   4688 }
   4689 
   4690 
   4691 RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
   4692   HandleScope scope(isolate);
   4693   DCHECK(args.length() == 2);
   4694   CONVERT_SMI_ARG_CHECKED(radix, 1);
   4695   RUNTIME_ASSERT(2 <= radix && radix <= 36);
   4696 
   4697   // Fast case where the result is a one character string.
   4698   if (args[0]->IsSmi()) {
   4699     int value = args.smi_at(0);
   4700     if (value >= 0 && value < radix) {
   4701       // Character array used for conversion.
   4702       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   4703       return *isolate->factory()->
   4704           LookupSingleCharacterStringFromCode(kCharTable[value]);
   4705     }
   4706   }
   4707 
   4708   // Slow case.
   4709   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4710   if (std::isnan(value)) {
   4711     return isolate->heap()->nan_string();
   4712   }
   4713   if (std::isinf(value)) {
   4714     if (value < 0) {
   4715       return isolate->heap()->minus_infinity_string();
   4716     }
   4717     return isolate->heap()->infinity_string();
   4718   }
   4719   char* str = DoubleToRadixCString(value, radix);
   4720   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4721   DeleteArray(str);
   4722   return *result;
   4723 }
   4724 
   4725 
   4726 RUNTIME_FUNCTION(Runtime_NumberToFixed) {
   4727   HandleScope scope(isolate);
   4728   DCHECK(args.length() == 2);
   4729 
   4730   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4731   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4732   int f = FastD2IChecked(f_number);
   4733   // See DoubleToFixedCString for these constants:
   4734   RUNTIME_ASSERT(f >= 0 && f <= 20);
   4735   RUNTIME_ASSERT(!Double(value).IsSpecial());
   4736   char* str = DoubleToFixedCString(value, f);
   4737   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4738   DeleteArray(str);
   4739   return *result;
   4740 }
   4741 
   4742 
   4743 RUNTIME_FUNCTION(Runtime_NumberToExponential) {
   4744   HandleScope scope(isolate);
   4745   DCHECK(args.length() == 2);
   4746 
   4747   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4748   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4749   int f = FastD2IChecked(f_number);
   4750   RUNTIME_ASSERT(f >= -1 && f <= 20);
   4751   RUNTIME_ASSERT(!Double(value).IsSpecial());
   4752   char* str = DoubleToExponentialCString(value, f);
   4753   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4754   DeleteArray(str);
   4755   return *result;
   4756 }
   4757 
   4758 
   4759 RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
   4760   HandleScope scope(isolate);
   4761   DCHECK(args.length() == 2);
   4762 
   4763   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4764   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4765   int f = FastD2IChecked(f_number);
   4766   RUNTIME_ASSERT(f >= 1 && f <= 21);
   4767   RUNTIME_ASSERT(!Double(value).IsSpecial());
   4768   char* str = DoubleToPrecisionCString(value, f);
   4769   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4770   DeleteArray(str);
   4771   return *result;
   4772 }
   4773 
   4774 
   4775 RUNTIME_FUNCTION(Runtime_IsValidSmi) {
   4776   SealHandleScope shs(isolate);
   4777   DCHECK(args.length() == 1);
   4778 
   4779   CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
   4780   return isolate->heap()->ToBoolean(Smi::IsValid(number));
   4781 }
   4782 
   4783 
   4784 // Returns a single character string where first character equals
   4785 // string->Get(index).
   4786 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
   4787   if (index < static_cast<uint32_t>(string->length())) {
   4788     Factory* factory = string->GetIsolate()->factory();
   4789     return factory->LookupSingleCharacterStringFromCode(
   4790         String::Flatten(string)->Get(index));
   4791   }
   4792   return Execution::CharAt(string, index);
   4793 }
   4794 
   4795 
   4796 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
   4797                                                 Handle<Object> object,
   4798                                                 uint32_t index) {
   4799   // Handle [] indexing on Strings
   4800   if (object->IsString()) {
   4801     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
   4802     if (!result->IsUndefined()) return result;
   4803   }
   4804 
   4805   // Handle [] indexing on String objects
   4806   if (object->IsStringObjectWithCharacterAt(index)) {
   4807     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
   4808     Handle<Object> result =
   4809         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
   4810     if (!result->IsUndefined()) return result;
   4811   }
   4812 
   4813   Handle<Object> result;
   4814   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
   4815     PrototypeIterator iter(isolate, object);
   4816     return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
   4817                               index);
   4818   } else {
   4819     return Object::GetElement(isolate, object, index);
   4820   }
   4821 }
   4822 
   4823 
   4824 MUST_USE_RESULT
   4825 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
   4826   if (key->IsName()) {
   4827     return Handle<Name>::cast(key);
   4828   } else {
   4829     Handle<Object> converted;
   4830     ASSIGN_RETURN_ON_EXCEPTION(
   4831         isolate, converted, Execution::ToString(isolate, key), Name);
   4832     return Handle<Name>::cast(converted);
   4833   }
   4834 }
   4835 
   4836 
   4837 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
   4838                                                Handle<JSReceiver> object,
   4839                                                Handle<Object> key) {
   4840   Maybe<bool> maybe;
   4841   // Check if the given key is an array index.
   4842   uint32_t index;
   4843   if (key->ToArrayIndex(&index)) {
   4844     maybe = JSReceiver::HasElement(object, index);
   4845   } else {
   4846     // Convert the key to a name - possibly by calling back into JavaScript.
   4847     Handle<Name> name;
   4848     ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
   4849 
   4850     maybe = JSReceiver::HasProperty(object, name);
   4851   }
   4852 
   4853   if (!maybe.has_value) return MaybeHandle<Object>();
   4854   return isolate->factory()->ToBoolean(maybe.value);
   4855 }
   4856 
   4857 
   4858 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
   4859                                                Handle<Object> object,
   4860                                                Handle<Object> key) {
   4861   if (object->IsUndefined() || object->IsNull()) {
   4862     Handle<Object> args[2] = { key, object };
   4863     THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load",
   4864                                           HandleVector(args, 2)),
   4865                     Object);
   4866   }
   4867 
   4868   // Check if the given key is an array index.
   4869   uint32_t index;
   4870   if (key->ToArrayIndex(&index)) {
   4871     return GetElementOrCharAt(isolate, object, index);
   4872   }
   4873 
   4874   // Convert the key to a name - possibly by calling back into JavaScript.
   4875   Handle<Name> name;
   4876   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
   4877 
   4878   // Check if the name is trivially convertible to an index and get
   4879   // the element if so.
   4880   if (name->AsArrayIndex(&index)) {
   4881     return GetElementOrCharAt(isolate, object, index);
   4882   } else {
   4883     return Object::GetProperty(object, name);
   4884   }
   4885 }
   4886 
   4887 
   4888 RUNTIME_FUNCTION(Runtime_GetProperty) {
   4889   HandleScope scope(isolate);
   4890   DCHECK(args.length() == 2);
   4891 
   4892   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   4893   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   4894   Handle<Object> result;
   4895   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4896       isolate, result,
   4897       Runtime::GetObjectProperty(isolate, object, key));
   4898   return *result;
   4899 }
   4900 
   4901 
   4902 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
   4903 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
   4904   HandleScope scope(isolate);
   4905   DCHECK(args.length() == 2);
   4906 
   4907   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
   4908   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
   4909 
   4910   // Fast cases for getting named properties of the receiver JSObject
   4911   // itself.
   4912   //
   4913   // The global proxy objects has to be excluded since LookupOwn on
   4914   // the global proxy object can return a valid result even though the
   4915   // global proxy object never has properties.  This is the case
   4916   // because the global proxy object forwards everything to its hidden
   4917   // prototype including own lookups.
   4918   //
   4919   // Additionally, we need to make sure that we do not cache results
   4920   // for objects that require access checks.
   4921   if (receiver_obj->IsJSObject()) {
   4922     if (!receiver_obj->IsJSGlobalProxy() &&
   4923         !receiver_obj->IsAccessCheckNeeded() &&
   4924         key_obj->IsName()) {
   4925       DisallowHeapAllocation no_allocation;
   4926       Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
   4927       Handle<Name> key = Handle<Name>::cast(key_obj);
   4928       if (receiver->HasFastProperties()) {
   4929         // Attempt to use lookup cache.
   4930         Handle<Map> receiver_map(receiver->map(), isolate);
   4931         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
   4932         int index = keyed_lookup_cache->Lookup(receiver_map, key);
   4933         if (index != -1) {
   4934           // Doubles are not cached, so raw read the value.
   4935           return receiver->RawFastPropertyAt(
   4936               FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
   4937         }
   4938         // Lookup cache miss.  Perform lookup and update the cache if
   4939         // appropriate.
   4940         LookupIterator it(receiver, key, LookupIterator::OWN);
   4941         if (it.state() == LookupIterator::DATA &&
   4942             it.property_details().type() == FIELD) {
   4943           FieldIndex field_index = it.GetFieldIndex();
   4944           // Do not track double fields in the keyed lookup cache. Reading
   4945           // double values requires boxing.
   4946           if (!it.representation().IsDouble()) {
   4947             keyed_lookup_cache->Update(receiver_map, key,
   4948                 field_index.GetKeyedLookupCacheIndex());
   4949           }
   4950           AllowHeapAllocation allow_allocation;
   4951           return *JSObject::FastPropertyAt(receiver, it.representation(),
   4952                                            field_index);
   4953         }
   4954       } else {
   4955         // Attempt dictionary lookup.
   4956         NameDictionary* dictionary = receiver->property_dictionary();
   4957         int entry = dictionary->FindEntry(key);
   4958         if ((entry != NameDictionary::kNotFound) &&
   4959             (dictionary->DetailsAt(entry).type() == NORMAL)) {
   4960           Object* value = dictionary->ValueAt(entry);
   4961           if (!receiver->IsGlobalObject()) return value;
   4962           value = PropertyCell::cast(value)->value();
   4963           if (!value->IsTheHole()) return value;
   4964           // If value is the hole (meaning, absent) do the general lookup.
   4965         }
   4966       }
   4967     } else if (key_obj->IsSmi()) {
   4968       // JSObject without a name key. If the key is a Smi, check for a
   4969       // definite out-of-bounds access to elements, which is a strong indicator
   4970       // that subsequent accesses will also call the runtime. Proactively
   4971       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
   4972       // doubles for those future calls in the case that the elements would
   4973       // become FAST_DOUBLE_ELEMENTS.
   4974       Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
   4975       ElementsKind elements_kind = js_object->GetElementsKind();
   4976       if (IsFastDoubleElementsKind(elements_kind)) {
   4977         Handle<Smi> key = Handle<Smi>::cast(key_obj);
   4978         if (key->value() >= js_object->elements()->length()) {
   4979           if (IsFastHoleyElementsKind(elements_kind)) {
   4980             elements_kind = FAST_HOLEY_ELEMENTS;
   4981           } else {
   4982             elements_kind = FAST_ELEMENTS;
   4983           }
   4984           RETURN_FAILURE_ON_EXCEPTION(
   4985               isolate, TransitionElements(js_object, elements_kind, isolate));
   4986         }
   4987       } else {
   4988         DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
   4989                !IsFastElementsKind(elements_kind));
   4990       }
   4991     }
   4992   } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
   4993     // Fast case for string indexing using [] with a smi index.
   4994     Handle<String> str = Handle<String>::cast(receiver_obj);
   4995     int index = args.smi_at(1);
   4996     if (index >= 0 && index < str->length()) {
   4997       return *GetCharAt(str, index);
   4998     }
   4999   }
   5000 
   5001   // Fall back to GetObjectProperty.
   5002   Handle<Object> result;
   5003   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5004       isolate, result,
   5005       Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
   5006   return *result;
   5007 }
   5008 
   5009 
   5010 static bool IsValidAccessor(Handle<Object> obj) {
   5011   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
   5012 }
   5013 
   5014 
   5015 // Transform getter or setter into something DefineAccessor can handle.
   5016 static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
   5017                                                    Handle<Object> component) {
   5018   if (component->IsUndefined()) return isolate->factory()->undefined_value();
   5019   Handle<FunctionTemplateInfo> info =
   5020       Handle<FunctionTemplateInfo>::cast(component);
   5021   return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
   5022 }
   5023 
   5024 
   5025 RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
   5026   HandleScope scope(isolate);
   5027   DCHECK(args.length() == 5);
   5028   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5029   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5030   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   5031   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   5032   CONVERT_SMI_ARG_CHECKED(attribute, 4);
   5033   RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
   5034   RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
   5035   RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
   5036       static_cast<PropertyAttributes>(attribute)));
   5037   RETURN_FAILURE_ON_EXCEPTION(
   5038       isolate, JSObject::DefineAccessor(
   5039                    object, name, InstantiateAccessorComponent(isolate, getter),
   5040                    InstantiateAccessorComponent(isolate, setter),
   5041                    static_cast<PropertyAttributes>(attribute)));
   5042   return isolate->heap()->undefined_value();
   5043 }
   5044 
   5045 
   5046 // Implements part of 8.12.9 DefineOwnProperty.
   5047 // There are 3 cases that lead here:
   5048 // Step 4b - define a new accessor property.
   5049 // Steps 9c & 12 - replace an existing data property with an accessor property.
   5050 // Step 12 - update an existing accessor property with an accessor or generic
   5051 //           descriptor.
   5052 RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
   5053   HandleScope scope(isolate);
   5054   DCHECK(args.length() == 5);
   5055   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5056   RUNTIME_ASSERT(!obj->IsNull());
   5057   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5058   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   5059   RUNTIME_ASSERT(IsValidAccessor(getter));
   5060   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   5061   RUNTIME_ASSERT(IsValidAccessor(setter));
   5062   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
   5063   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5064   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   5065 
   5066   bool fast = obj->HasFastProperties();
   5067   RETURN_FAILURE_ON_EXCEPTION(
   5068       isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
   5069   if (fast) JSObject::MigrateSlowToFast(obj, 0);
   5070   return isolate->heap()->undefined_value();
   5071 }
   5072 
   5073 
   5074 // Implements part of 8.12.9 DefineOwnProperty.
   5075 // There are 3 cases that lead here:
   5076 // Step 4a - define a new data property.
   5077 // Steps 9b & 12 - replace an existing accessor property with a data property.
   5078 // Step 12 - update an existing data property with a data or generic
   5079 //           descriptor.
   5080 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
   5081   HandleScope scope(isolate);
   5082   DCHECK(args.length() == 4);
   5083   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
   5084   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5085   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
   5086   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
   5087   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5088   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   5089 
   5090   LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   5091   if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
   5092     if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
   5093       return isolate->heap()->undefined_value();
   5094     }
   5095     it.Next();
   5096   }
   5097 
   5098   // Take special care when attributes are different and there is already
   5099   // a property.
   5100   if (it.state() == LookupIterator::ACCESSOR) {
   5101     // Use IgnoreAttributes version since a readonly property may be
   5102     // overridden and SetProperty does not allow this.
   5103     Handle<Object> result;
   5104     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5105         isolate, result,
   5106         JSObject::SetOwnPropertyIgnoreAttributes(
   5107             js_object, name, obj_value, attr,
   5108             JSObject::DONT_FORCE_FIELD));
   5109     return *result;
   5110   }
   5111 
   5112   Handle<Object> result;
   5113   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5114       isolate, result,
   5115       Runtime::DefineObjectProperty(js_object, name, obj_value, attr));
   5116   return *result;
   5117 }
   5118 
   5119 
   5120 // Return property without being observable by accessors or interceptors.
   5121 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
   5122   HandleScope scope(isolate);
   5123   DCHECK(args.length() == 2);
   5124   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5125   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5126   return *JSObject::GetDataProperty(object, key);
   5127 }
   5128 
   5129 
   5130 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
   5131                                                Handle<Object> object,
   5132                                                Handle<Object> key,
   5133                                                Handle<Object> value,
   5134                                                StrictMode strict_mode) {
   5135   if (object->IsUndefined() || object->IsNull()) {
   5136     Handle<Object> args[2] = { key, object };
   5137     THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store",
   5138                                           HandleVector(args, 2)),
   5139                     Object);
   5140   }
   5141 
   5142   if (object->IsJSProxy()) {
   5143     Handle<Object> name_object;
   5144     if (key->IsSymbol()) {
   5145       name_object = key;
   5146     } else {
   5147       ASSIGN_RETURN_ON_EXCEPTION(
   5148           isolate, name_object, Execution::ToString(isolate, key), Object);
   5149     }
   5150     Handle<Name> name = Handle<Name>::cast(name_object);
   5151     return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
   5152                                strict_mode);
   5153   }
   5154 
   5155   // Check if the given key is an array index.
   5156   uint32_t index;
   5157   if (key->ToArrayIndex(&index)) {
   5158     // TODO(verwaest): Support non-JSObject receivers.
   5159     if (!object->IsJSObject()) return value;
   5160     Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   5161 
   5162     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5163     // of a string using [] notation.  We need to support this too in
   5164     // JavaScript.
   5165     // In the case of a String object we just need to redirect the assignment to
   5166     // the underlying string if the index is in range.  Since the underlying
   5167     // string does nothing with the assignment then we can ignore such
   5168     // assignments.
   5169     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5170       return value;
   5171     }
   5172 
   5173     JSObject::ValidateElements(js_object);
   5174     if (js_object->HasExternalArrayElements() ||
   5175         js_object->HasFixedTypedArrayElements()) {
   5176       if (!value->IsNumber() && !value->IsUndefined()) {
   5177         ASSIGN_RETURN_ON_EXCEPTION(
   5178             isolate, value, Execution::ToNumber(isolate, value), Object);
   5179       }
   5180     }
   5181 
   5182     MaybeHandle<Object> result = JSObject::SetElement(
   5183         js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
   5184     JSObject::ValidateElements(js_object);
   5185 
   5186     return result.is_null() ? result : value;
   5187   }
   5188 
   5189   if (key->IsName()) {
   5190     Handle<Name> name = Handle<Name>::cast(key);
   5191     if (name->AsArrayIndex(&index)) {
   5192       // TODO(verwaest): Support non-JSObject receivers.
   5193       if (!object->IsJSObject()) return value;
   5194       Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   5195       if (js_object->HasExternalArrayElements()) {
   5196         if (!value->IsNumber() && !value->IsUndefined()) {
   5197           ASSIGN_RETURN_ON_EXCEPTION(
   5198               isolate, value, Execution::ToNumber(isolate, value), Object);
   5199         }
   5200       }
   5201       return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
   5202                                   true, SET_PROPERTY);
   5203     } else {
   5204       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
   5205       return Object::SetProperty(object, name, value, strict_mode);
   5206     }
   5207   }
   5208 
   5209   // Call-back into JavaScript to convert the key to a string.
   5210   Handle<Object> converted;
   5211   ASSIGN_RETURN_ON_EXCEPTION(
   5212       isolate, converted, Execution::ToString(isolate, key), Object);
   5213   Handle<String> name = Handle<String>::cast(converted);
   5214 
   5215   if (name->AsArrayIndex(&index)) {
   5216     // TODO(verwaest): Support non-JSObject receivers.
   5217     if (!object->IsJSObject()) return value;
   5218     Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   5219     return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
   5220                                 true, SET_PROPERTY);
   5221   }
   5222   return Object::SetProperty(object, name, value, strict_mode);
   5223 }
   5224 
   5225 
   5226 MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
   5227                                                   Handle<Object> key,
   5228                                                   Handle<Object> value,
   5229                                                   PropertyAttributes attr) {
   5230   Isolate* isolate = js_object->GetIsolate();
   5231   // Check if the given key is an array index.
   5232   uint32_t index;
   5233   if (key->ToArrayIndex(&index)) {
   5234     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5235     // of a string using [] notation.  We need to support this too in
   5236     // JavaScript.
   5237     // In the case of a String object we just need to redirect the assignment to
   5238     // the underlying string if the index is in range.  Since the underlying
   5239     // string does nothing with the assignment then we can ignore such
   5240     // assignments.
   5241     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5242       return value;
   5243     }
   5244 
   5245     return JSObject::SetElement(js_object, index, value, attr,
   5246                                 SLOPPY, false, DEFINE_PROPERTY);
   5247   }
   5248 
   5249   if (key->IsName()) {
   5250     Handle<Name> name = Handle<Name>::cast(key);
   5251     if (name->AsArrayIndex(&index)) {
   5252       return JSObject::SetElement(js_object, index, value, attr,
   5253                                   SLOPPY, false, DEFINE_PROPERTY);
   5254     } else {
   5255       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
   5256       return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
   5257                                                       attr);
   5258     }
   5259   }
   5260 
   5261   // Call-back into JavaScript to convert the key to a string.
   5262   Handle<Object> converted;
   5263   ASSIGN_RETURN_ON_EXCEPTION(
   5264       isolate, converted, Execution::ToString(isolate, key), Object);
   5265   Handle<String> name = Handle<String>::cast(converted);
   5266 
   5267   if (name->AsArrayIndex(&index)) {
   5268     return JSObject::SetElement(js_object, index, value, attr,
   5269                                 SLOPPY, false, DEFINE_PROPERTY);
   5270   } else {
   5271     return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
   5272                                                     attr);
   5273   }
   5274 }
   5275 
   5276 
   5277 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
   5278                                                   Handle<JSReceiver> receiver,
   5279                                                   Handle<Object> key,
   5280                                                   JSReceiver::DeleteMode mode) {
   5281   // Check if the given key is an array index.
   5282   uint32_t index;
   5283   if (key->ToArrayIndex(&index)) {
   5284     // In Firefox/SpiderMonkey, Safari and Opera you can access the
   5285     // characters of a string using [] notation.  In the case of a
   5286     // String object we just need to redirect the deletion to the
   5287     // underlying string if the index is in range.  Since the
   5288     // underlying string does nothing with the deletion, we can ignore
   5289     // such deletions.
   5290     if (receiver->IsStringObjectWithCharacterAt(index)) {
   5291       return isolate->factory()->true_value();
   5292     }
   5293 
   5294     return JSReceiver::DeleteElement(receiver, index, mode);
   5295   }
   5296 
   5297   Handle<Name> name;
   5298   if (key->IsName()) {
   5299     name = Handle<Name>::cast(key);
   5300   } else {
   5301     // Call-back into JavaScript to convert the key to a string.
   5302     Handle<Object> converted;
   5303     ASSIGN_RETURN_ON_EXCEPTION(
   5304         isolate, converted, Execution::ToString(isolate, key), Object);
   5305     name = Handle<String>::cast(converted);
   5306   }
   5307 
   5308   if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
   5309   return JSReceiver::DeleteProperty(receiver, name, mode);
   5310 }
   5311 
   5312 
   5313 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
   5314   HandleScope scope(isolate);
   5315   RUNTIME_ASSERT(args.length() == 3);
   5316 
   5317   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5318   CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
   5319   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5320   RUNTIME_ASSERT(key->IsUniqueName());
   5321   return *JSObject::SetHiddenProperty(object, key, value);
   5322 }
   5323 
   5324 
   5325 RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
   5326   HandleScope scope(isolate);
   5327   RUNTIME_ASSERT(args.length() == 4);
   5328 
   5329   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5330   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5331   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5332   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   5333   RUNTIME_ASSERT(
   5334       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5335   // Compute attributes.
   5336   PropertyAttributes attributes =
   5337       static_cast<PropertyAttributes>(unchecked_attributes);
   5338 
   5339 #ifdef DEBUG
   5340   uint32_t index = 0;
   5341   DCHECK(!key->ToArrayIndex(&index));
   5342   LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
   5343   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   5344   if (!maybe.has_value) return isolate->heap()->exception();
   5345   RUNTIME_ASSERT(!it.IsFound());
   5346 #endif
   5347 
   5348   Handle<Object> result;
   5349   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5350       isolate, result,
   5351       JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
   5352   return *result;
   5353 }
   5354 
   5355 
   5356 RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
   5357   HandleScope scope(isolate);
   5358   RUNTIME_ASSERT(args.length() == 4);
   5359 
   5360   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5361   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   5362   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5363   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   5364   RUNTIME_ASSERT(
   5365       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5366   // Compute attributes.
   5367   PropertyAttributes attributes =
   5368       static_cast<PropertyAttributes>(unchecked_attributes);
   5369 
   5370 #ifdef DEBUG
   5371   bool duplicate;
   5372   if (key->IsName()) {
   5373     LookupIterator it(object, Handle<Name>::cast(key),
   5374                       LookupIterator::OWN_SKIP_INTERCEPTOR);
   5375     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   5376     DCHECK(maybe.has_value);
   5377     duplicate = it.IsFound();
   5378   } else {
   5379     uint32_t index = 0;
   5380     RUNTIME_ASSERT(key->ToArrayIndex(&index));
   5381     Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
   5382     if (!maybe.has_value) return isolate->heap()->exception();
   5383     duplicate = maybe.value;
   5384   }
   5385   if (duplicate) {
   5386     Handle<Object> args[1] = { key };
   5387     THROW_NEW_ERROR_RETURN_FAILURE(
   5388         isolate,
   5389         NewTypeError("duplicate_template_property", HandleVector(args, 1)));
   5390   }
   5391 #endif
   5392 
   5393   Handle<Object> result;
   5394   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5395       isolate, result,
   5396       Runtime::DefineObjectProperty(object, key, value, attributes));
   5397   return *result;
   5398 }
   5399 
   5400 
   5401 RUNTIME_FUNCTION(Runtime_SetProperty) {
   5402   HandleScope scope(isolate);
   5403   RUNTIME_ASSERT(args.length() == 4);
   5404 
   5405   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5406   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   5407   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5408   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
   5409   StrictMode strict_mode = strict_mode_arg;
   5410 
   5411   Handle<Object> result;
   5412   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5413       isolate, result,
   5414       Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
   5415   return *result;
   5416 }
   5417 
   5418 
   5419 // Adds an element to an array.
   5420 // This is used to create an indexed data property into an array.
   5421 RUNTIME_FUNCTION(Runtime_AddElement) {
   5422   HandleScope scope(isolate);
   5423   RUNTIME_ASSERT(args.length() == 4);
   5424 
   5425   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5426   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   5427   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5428   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   5429   RUNTIME_ASSERT(
   5430       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5431   // Compute attributes.
   5432   PropertyAttributes attributes =
   5433       static_cast<PropertyAttributes>(unchecked_attributes);
   5434 
   5435   uint32_t index = 0;
   5436   key->ToArrayIndex(&index);
   5437 
   5438   Handle<Object> result;
   5439   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5440       isolate, result, JSObject::SetElement(object, index, value, attributes,
   5441                                             SLOPPY, false, DEFINE_PROPERTY));
   5442   return *result;
   5443 }
   5444 
   5445 
   5446 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
   5447   HandleScope scope(isolate);
   5448   RUNTIME_ASSERT(args.length() == 2);
   5449   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   5450   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
   5451   JSObject::TransitionElementsKind(array, map->elements_kind());
   5452   return *array;
   5453 }
   5454 
   5455 
   5456 // Set the native flag on the function.
   5457 // This is used to decide if we should transform null and undefined
   5458 // into the global object when doing call and apply.
   5459 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
   5460   SealHandleScope shs(isolate);
   5461   RUNTIME_ASSERT(args.length() == 1);
   5462 
   5463   CONVERT_ARG_CHECKED(Object, object, 0);
   5464 
   5465   if (object->IsJSFunction()) {
   5466     JSFunction* func = JSFunction::cast(object);
   5467     func->shared()->set_native(true);
   5468   }
   5469   return isolate->heap()->undefined_value();
   5470 }
   5471 
   5472 
   5473 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
   5474   SealHandleScope shs(isolate);
   5475   RUNTIME_ASSERT(args.length() == 1);
   5476   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5477 
   5478   if (object->IsJSFunction()) {
   5479     JSFunction* func = JSFunction::cast(*object);
   5480     func->shared()->set_inline_builtin(true);
   5481   }
   5482   return isolate->heap()->undefined_value();
   5483 }
   5484 
   5485 
   5486 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
   5487   HandleScope scope(isolate);
   5488   RUNTIME_ASSERT(args.length() == 5);
   5489   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5490   CONVERT_SMI_ARG_CHECKED(store_index, 1);
   5491   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5492   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
   5493   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
   5494 
   5495   Object* raw_literal_cell = literals->get(literal_index);
   5496   JSArray* boilerplate = NULL;
   5497   if (raw_literal_cell->IsAllocationSite()) {
   5498     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
   5499     boilerplate = JSArray::cast(site->transition_info());
   5500   } else {
   5501     boilerplate = JSArray::cast(raw_literal_cell);
   5502   }
   5503   Handle<JSArray> boilerplate_object(boilerplate);
   5504   ElementsKind elements_kind = object->GetElementsKind();
   5505   DCHECK(IsFastElementsKind(elements_kind));
   5506   // Smis should never trigger transitions.
   5507   DCHECK(!value->IsSmi());
   5508 
   5509   if (value->IsNumber()) {
   5510     DCHECK(IsFastSmiElementsKind(elements_kind));
   5511     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5512         ? FAST_HOLEY_DOUBLE_ELEMENTS
   5513         : FAST_DOUBLE_ELEMENTS;
   5514     if (IsMoreGeneralElementsKindTransition(
   5515             boilerplate_object->GetElementsKind(),
   5516             transitioned_kind)) {
   5517       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5518     }
   5519     JSObject::TransitionElementsKind(object, transitioned_kind);
   5520     DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
   5521     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
   5522     HeapNumber* number = HeapNumber::cast(*value);
   5523     double_array->set(store_index, number->Number());
   5524   } else {
   5525     if (!IsFastObjectElementsKind(elements_kind)) {
   5526       ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5527           ? FAST_HOLEY_ELEMENTS
   5528           : FAST_ELEMENTS;
   5529       JSObject::TransitionElementsKind(object, transitioned_kind);
   5530       ElementsKind boilerplate_elements_kind =
   5531           boilerplate_object->GetElementsKind();
   5532       if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
   5533                                               transitioned_kind)) {
   5534         JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5535       }
   5536     }
   5537     FixedArray* object_array = FixedArray::cast(object->elements());
   5538     object_array->set(store_index, *value);
   5539   }
   5540   return *object;
   5541 }
   5542 
   5543 
   5544 // Check whether debugger and is about to step into the callback that is passed
   5545 // to a built-in function such as Array.forEach.
   5546 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
   5547   DCHECK(args.length() == 1);
   5548   if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
   5549     return isolate->heap()->false_value();
   5550   }
   5551   CONVERT_ARG_CHECKED(Object, callback, 0);
   5552   // We do not step into the callback if it's a builtin or not even a function.
   5553   return isolate->heap()->ToBoolean(
   5554       callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
   5555 }
   5556 
   5557 
   5558 // Set one shot breakpoints for the callback function that is passed to a
   5559 // built-in function such as Array.forEach to enable stepping into the callback.
   5560 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
   5561   DCHECK(args.length() == 1);
   5562   Debug* debug = isolate->debug();
   5563   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
   5564 
   5565   HandleScope scope(isolate);
   5566   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5567   RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
   5568   Handle<JSFunction> fun;
   5569   if (object->IsJSFunction()) {
   5570     fun = Handle<JSFunction>::cast(object);
   5571   } else {
   5572     fun = Handle<JSFunction>(
   5573         Handle<JSGeneratorObject>::cast(object)->function(), isolate);
   5574   }
   5575   // When leaving the function, step out has been activated, but not performed
   5576   // if we do not leave the builtin.  To be able to step into the function
   5577   // again, we need to clear the step out at this point.
   5578   debug->ClearStepOut();
   5579   debug->FloodWithOneShot(fun);
   5580   return isolate->heap()->undefined_value();
   5581 }
   5582 
   5583 
   5584 RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
   5585   DCHECK(args.length() == 1);
   5586   HandleScope scope(isolate);
   5587   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
   5588   isolate->PushPromise(promise);
   5589   return isolate->heap()->undefined_value();
   5590 }
   5591 
   5592 
   5593 RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
   5594   DCHECK(args.length() == 0);
   5595   SealHandleScope shs(isolate);
   5596   isolate->PopPromise();
   5597   return isolate->heap()->undefined_value();
   5598 }
   5599 
   5600 
   5601 RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
   5602   DCHECK(args.length() == 1);
   5603   HandleScope scope(isolate);
   5604   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
   5605   isolate->debug()->OnPromiseEvent(data);
   5606   return isolate->heap()->undefined_value();
   5607 }
   5608 
   5609 
   5610 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
   5611   DCHECK(args.length() == 2);
   5612   HandleScope scope(isolate);
   5613   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
   5614   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
   5615   isolate->debug()->OnPromiseReject(promise, value);
   5616   return isolate->heap()->undefined_value();
   5617 }
   5618 
   5619 
   5620 RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
   5621   DCHECK(args.length() == 1);
   5622   HandleScope scope(isolate);
   5623   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
   5624   isolate->debug()->OnAsyncTaskEvent(data);
   5625   return isolate->heap()->undefined_value();
   5626 }
   5627 
   5628 
   5629 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
   5630   HandleScope scope(isolate);
   5631   DCHECK(args.length() == 3);
   5632   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5633   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5634   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
   5635   JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
   5636       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
   5637   Handle<Object> result;
   5638   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5639       isolate, result,
   5640       JSReceiver::DeleteProperty(object, key, delete_mode));
   5641   return *result;
   5642 }
   5643 
   5644 
   5645 static Object* HasOwnPropertyImplementation(Isolate* isolate,
   5646                                             Handle<JSObject> object,
   5647                                             Handle<Name> key) {
   5648   Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
   5649   if (!maybe.has_value) return isolate->heap()->exception();
   5650   if (maybe.value) return isolate->heap()->true_value();
   5651   // Handle hidden prototypes.  If there's a hidden prototype above this thing
   5652   // then we have to check it for properties, because they are supposed to
   5653   // look like they are on this object.
   5654   PrototypeIterator iter(isolate, object);
   5655   if (!iter.IsAtEnd() &&
   5656       Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
   5657           ->map()
   5658           ->is_hidden_prototype()) {
   5659     // TODO(verwaest): The recursion is not necessary for keys that are array
   5660     // indices. Removing this.
   5661     return HasOwnPropertyImplementation(
   5662         isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
   5663         key);
   5664   }
   5665   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5666   return isolate->heap()->false_value();
   5667 }
   5668 
   5669 
   5670 RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
   5671   HandleScope scope(isolate);
   5672   DCHECK(args.length() == 2);
   5673   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
   5674   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5675 
   5676   uint32_t index;
   5677   const bool key_is_array_index = key->AsArrayIndex(&index);
   5678 
   5679   // Only JS objects can have properties.
   5680   if (object->IsJSObject()) {
   5681     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
   5682     // Fast case: either the key is a real named property or it is not
   5683     // an array index and there are no interceptors or hidden
   5684     // prototypes.
   5685     Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
   5686     if (!maybe.has_value) return isolate->heap()->exception();
   5687     DCHECK(!isolate->has_pending_exception());
   5688     if (maybe.value) {
   5689       return isolate->heap()->true_value();
   5690     }
   5691     Map* map = js_obj->map();
   5692     if (!key_is_array_index &&
   5693         !map->has_named_interceptor() &&
   5694         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
   5695       return isolate->heap()->false_value();
   5696     }
   5697     // Slow case.
   5698     return HasOwnPropertyImplementation(isolate,
   5699                                         Handle<JSObject>(js_obj),
   5700                                         Handle<Name>(key));
   5701   } else if (object->IsString() && key_is_array_index) {
   5702     // Well, there is one exception:  Handle [] on strings.
   5703     Handle<String> string = Handle<String>::cast(object);
   5704     if (index < static_cast<uint32_t>(string->length())) {
   5705       return isolate->heap()->true_value();
   5706     }
   5707   }
   5708   return isolate->heap()->false_value();
   5709 }
   5710 
   5711 
   5712 RUNTIME_FUNCTION(Runtime_HasProperty) {
   5713   HandleScope scope(isolate);
   5714   DCHECK(args.length() == 2);
   5715   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   5716   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5717 
   5718   Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
   5719   if (!maybe.has_value) return isolate->heap()->exception();
   5720   return isolate->heap()->ToBoolean(maybe.value);
   5721 }
   5722 
   5723 
   5724 RUNTIME_FUNCTION(Runtime_HasElement) {
   5725   HandleScope scope(isolate);
   5726   DCHECK(args.length() == 2);
   5727   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   5728   CONVERT_SMI_ARG_CHECKED(index, 1);
   5729 
   5730   Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
   5731   if (!maybe.has_value) return isolate->heap()->exception();
   5732   return isolate->heap()->ToBoolean(maybe.value);
   5733 }
   5734 
   5735 
   5736 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
   5737   HandleScope scope(isolate);
   5738   DCHECK(args.length() == 2);
   5739 
   5740   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5741   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5742 
   5743   Maybe<PropertyAttributes> maybe =
   5744       JSReceiver::GetOwnPropertyAttributes(object, key);
   5745   if (!maybe.has_value) return isolate->heap()->exception();
   5746   if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
   5747   return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
   5748 }
   5749 
   5750 
   5751 RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
   5752   HandleScope scope(isolate);
   5753   DCHECK(args.length() == 1);
   5754   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5755   Handle<JSArray> result;
   5756 
   5757   isolate->counters()->for_in()->Increment();
   5758   Handle<FixedArray> elements;
   5759   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5760       isolate, elements,
   5761       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
   5762   return *isolate->factory()->NewJSArrayWithElements(elements);
   5763 }
   5764 
   5765 
   5766 // Returns either a FixedArray as Runtime_GetPropertyNames,
   5767 // or, if the given object has an enum cache that contains
   5768 // all enumerable properties of the object and its prototypes
   5769 // have none, the map of the object. This is used to speed up
   5770 // the check for deletions during a for-in.
   5771 RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
   5772   SealHandleScope shs(isolate);
   5773   DCHECK(args.length() == 1);
   5774 
   5775   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
   5776 
   5777   if (raw_object->IsSimpleEnum()) return raw_object->map();
   5778 
   5779   HandleScope scope(isolate);
   5780   Handle<JSReceiver> object(raw_object);
   5781   Handle<FixedArray> content;
   5782   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5783       isolate, content,
   5784       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
   5785 
   5786   // Test again, since cache may have been built by preceding call.
   5787   if (object->IsSimpleEnum()) return object->map();
   5788 
   5789   return *content;
   5790 }
   5791 
   5792 
   5793 // Find the length of the prototype chain that is to be handled as one. If a
   5794 // prototype object is hidden it is to be viewed as part of the the object it
   5795 // is prototype for.
   5796 static int OwnPrototypeChainLength(JSObject* obj) {
   5797   int count = 1;
   5798   for (PrototypeIterator iter(obj->GetIsolate(), obj);
   5799        !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
   5800     count++;
   5801   }
   5802   return count;
   5803 }
   5804 
   5805 
   5806 // Return the names of the own named properties.
   5807 // args[0]: object
   5808 // args[1]: PropertyAttributes as int
   5809 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
   5810   HandleScope scope(isolate);
   5811   DCHECK(args.length() == 2);
   5812   if (!args[0]->IsJSObject()) {
   5813     return isolate->heap()->undefined_value();
   5814   }
   5815   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5816   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
   5817   PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
   5818 
   5819   // Skip the global proxy as it has no properties and always delegates to the
   5820   // real global object.
   5821   if (obj->IsJSGlobalProxy()) {
   5822     // Only collect names if access is permitted.
   5823     if (obj->IsAccessCheckNeeded() &&
   5824         !isolate->MayNamedAccess(
   5825             obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
   5826       isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
   5827       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5828       return *isolate->factory()->NewJSArray(0);
   5829     }
   5830     PrototypeIterator iter(isolate, obj);
   5831     obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   5832   }
   5833 
   5834   // Find the number of objects making up this.
   5835   int length = OwnPrototypeChainLength(*obj);
   5836 
   5837   // Find the number of own properties for each of the objects.
   5838   ScopedVector<int> own_property_count(length);
   5839   int total_property_count = 0;
   5840   {
   5841     PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
   5842     for (int i = 0; i < length; i++) {
   5843       DCHECK(!iter.IsAtEnd());
   5844       Handle<JSObject> jsproto =
   5845           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   5846       // Only collect names if access is permitted.
   5847       if (jsproto->IsAccessCheckNeeded() &&
   5848           !isolate->MayNamedAccess(jsproto,
   5849                                    isolate->factory()->undefined_value(),
   5850                                    v8::ACCESS_KEYS)) {
   5851         isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
   5852         RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5853         return *isolate->factory()->NewJSArray(0);
   5854       }
   5855       int n;
   5856       n = jsproto->NumberOfOwnProperties(filter);
   5857       own_property_count[i] = n;
   5858       total_property_count += n;
   5859       iter.Advance();
   5860     }
   5861   }
   5862 
   5863   // Allocate an array with storage for all the property names.
   5864   Handle<FixedArray> names =
   5865       isolate->factory()->NewFixedArray(total_property_count);
   5866 
   5867   // Get the property names.
   5868   int next_copy_index = 0;
   5869   int hidden_strings = 0;
   5870   {
   5871     PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
   5872     for (int i = 0; i < length; i++) {
   5873       DCHECK(!iter.IsAtEnd());
   5874       Handle<JSObject> jsproto =
   5875           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   5876       jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
   5877       if (i > 0) {
   5878         // Names from hidden prototypes may already have been added
   5879         // for inherited function template instances. Count the duplicates
   5880         // and stub them out; the final copy pass at the end ignores holes.
   5881         for (int j = next_copy_index;
   5882              j < next_copy_index + own_property_count[i]; j++) {
   5883           Object* name_from_hidden_proto = names->get(j);
   5884           for (int k = 0; k < next_copy_index; k++) {
   5885             if (names->get(k) != isolate->heap()->hidden_string()) {
   5886               Object* name = names->get(k);
   5887               if (name_from_hidden_proto == name) {
   5888                 names->set(j, isolate->heap()->hidden_string());
   5889                 hidden_strings++;
   5890                 break;
   5891               }
   5892             }
   5893           }
   5894         }
   5895       }
   5896       next_copy_index += own_property_count[i];
   5897 
   5898       // Hidden properties only show up if the filter does not skip strings.
   5899       if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
   5900         hidden_strings++;
   5901       }
   5902       iter.Advance();
   5903     }
   5904   }
   5905 
   5906   // Filter out name of hidden properties object and
   5907   // hidden prototype duplicates.
   5908   if (hidden_strings > 0) {
   5909     Handle<FixedArray> old_names = names;
   5910     names = isolate->factory()->NewFixedArray(
   5911         names->length() - hidden_strings);
   5912     int dest_pos = 0;
   5913     for (int i = 0; i < total_property_count; i++) {
   5914       Object* name = old_names->get(i);
   5915       if (name == isolate->heap()->hidden_string()) {
   5916         hidden_strings--;
   5917         continue;
   5918       }
   5919       names->set(dest_pos++, name);
   5920     }
   5921     DCHECK_EQ(0, hidden_strings);
   5922   }
   5923 
   5924   return *isolate->factory()->NewJSArrayWithElements(names);
   5925 }
   5926 
   5927 
   5928 // Return the names of the own indexed properties.
   5929 // args[0]: object
   5930 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
   5931   HandleScope scope(isolate);
   5932   DCHECK(args.length() == 1);
   5933   if (!args[0]->IsJSObject()) {
   5934     return isolate->heap()->undefined_value();
   5935   }
   5936   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5937 
   5938   int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
   5939   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
   5940   obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
   5941   return *isolate->factory()->NewJSArrayWithElements(names);
   5942 }
   5943 
   5944 
   5945 // Return information on whether an object has a named or indexed interceptor.
   5946 // args[0]: object
   5947 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
   5948   HandleScope scope(isolate);
   5949   DCHECK(args.length() == 1);
   5950   if (!args[0]->IsJSObject()) {
   5951     return Smi::FromInt(0);
   5952   }
   5953   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5954 
   5955   int result = 0;
   5956   if (obj->HasNamedInterceptor()) result |= 2;
   5957   if (obj->HasIndexedInterceptor()) result |= 1;
   5958 
   5959   return Smi::FromInt(result);
   5960 }
   5961 
   5962 
   5963 // Return property names from named interceptor.
   5964 // args[0]: object
   5965 RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
   5966   HandleScope scope(isolate);
   5967   DCHECK(args.length() == 1);
   5968   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5969 
   5970   if (obj->HasNamedInterceptor()) {
   5971     Handle<JSObject> result;
   5972     if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
   5973       return *result;
   5974     }
   5975   }
   5976   return isolate->heap()->undefined_value();
   5977 }
   5978 
   5979 
   5980 // Return element names from indexed interceptor.
   5981 // args[0]: object
   5982 RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
   5983   HandleScope scope(isolate);
   5984   DCHECK(args.length() == 1);
   5985   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5986 
   5987   if (obj->HasIndexedInterceptor()) {
   5988     Handle<JSObject> result;
   5989     if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
   5990       return *result;
   5991     }
   5992   }
   5993   return isolate->heap()->undefined_value();
   5994 }
   5995 
   5996 
   5997 RUNTIME_FUNCTION(Runtime_OwnKeys) {
   5998   HandleScope scope(isolate);
   5999   DCHECK(args.length() == 1);
   6000   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
   6001   Handle<JSObject> object(raw_object);
   6002 
   6003   if (object->IsJSGlobalProxy()) {
   6004     // Do access checks before going to the global object.
   6005     if (object->IsAccessCheckNeeded() &&
   6006         !isolate->MayNamedAccess(
   6007             object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
   6008       isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
   6009       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   6010       return *isolate->factory()->NewJSArray(0);
   6011     }
   6012 
   6013     PrototypeIterator iter(isolate, object);
   6014     // If proxy is detached we simply return an empty array.
   6015     if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
   6016     object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   6017   }
   6018 
   6019   Handle<FixedArray> contents;
   6020   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6021       isolate, contents,
   6022       JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
   6023 
   6024   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
   6025   // property array and since the result is mutable we have to create
   6026   // a fresh clone on each invocation.
   6027   int length = contents->length();
   6028   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
   6029   for (int i = 0; i < length; i++) {
   6030     Object* entry = contents->get(i);
   6031     if (entry->IsString()) {
   6032       copy->set(i, entry);
   6033     } else {
   6034       DCHECK(entry->IsNumber());
   6035       HandleScope scope(isolate);
   6036       Handle<Object> entry_handle(entry, isolate);
   6037       Handle<Object> entry_str =
   6038           isolate->factory()->NumberToString(entry_handle);
   6039       copy->set(i, *entry_str);
   6040     }
   6041   }
   6042   return *isolate->factory()->NewJSArrayWithElements(copy);
   6043 }
   6044 
   6045 
   6046 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
   6047   SealHandleScope shs(isolate);
   6048   DCHECK(args.length() == 1);
   6049   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
   6050 
   6051   // Compute the frame holding the arguments.
   6052   JavaScriptFrameIterator it(isolate);
   6053   it.AdvanceToArgumentsFrame();
   6054   JavaScriptFrame* frame = it.frame();
   6055 
   6056   // Get the actual number of provided arguments.
   6057   const uint32_t n = frame->ComputeParametersCount();
   6058 
   6059   // Try to convert the key to an index. If successful and within
   6060   // index return the the argument from the frame.
   6061   uint32_t index;
   6062   if (raw_key->ToArrayIndex(&index) && index < n) {
   6063     return frame->GetParameter(index);
   6064   }
   6065 
   6066   HandleScope scope(isolate);
   6067   if (raw_key->IsSymbol()) {
   6068     Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
   6069     if (symbol->Equals(isolate->native_context()->iterator_symbol())) {
   6070       return isolate->native_context()->array_values_iterator();
   6071     }
   6072     // Lookup in the initial Object.prototype object.
   6073     Handle<Object> result;
   6074     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6075         isolate, result,
   6076         Object::GetProperty(isolate->initial_object_prototype(),
   6077                             Handle<Symbol>::cast(raw_key)));
   6078     return *result;
   6079   }
   6080 
   6081   // Convert the key to a string.
   6082   Handle<Object> converted;
   6083   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6084       isolate, converted, Execution::ToString(isolate, raw_key));
   6085   Handle<String> key = Handle<String>::cast(converted);
   6086 
   6087   // Try to convert the string key into an array index.
   6088   if (key->AsArrayIndex(&index)) {
   6089     if (index < n) {
   6090       return frame->GetParameter(index);
   6091     } else {
   6092       Handle<Object> initial_prototype(isolate->initial_object_prototype());
   6093       Handle<Object> result;
   6094       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6095           isolate, result,
   6096           Object::GetElement(isolate, initial_prototype, index));
   6097       return *result;
   6098     }
   6099   }
   6100 
   6101   // Handle special arguments properties.
   6102   if (String::Equals(isolate->factory()->length_string(), key)) {
   6103     return Smi::FromInt(n);
   6104   }
   6105   if (String::Equals(isolate->factory()->callee_string(), key)) {
   6106     JSFunction* function = frame->function();
   6107     if (function->shared()->strict_mode() == STRICT) {
   6108       THROW_NEW_ERROR_RETURN_FAILURE(
   6109           isolate, NewTypeError("strict_arguments_callee",
   6110                                 HandleVector<Object>(NULL, 0)));
   6111     }
   6112     return function;
   6113   }
   6114 
   6115   // Lookup in the initial Object.prototype object.
   6116   Handle<Object> result;
   6117   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6118       isolate, result,
   6119       Object::GetProperty(isolate->initial_object_prototype(), key));
   6120   return *result;
   6121 }
   6122 
   6123 
   6124 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
   6125   HandleScope scope(isolate);
   6126   DCHECK(args.length() == 1);
   6127   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   6128   if (object->IsJSObject() && !object->IsGlobalObject()) {
   6129     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0);
   6130   }
   6131   return *object;
   6132 }
   6133 
   6134 
   6135 RUNTIME_FUNCTION(Runtime_ToBool) {
   6136   SealHandleScope shs(isolate);
   6137   DCHECK(args.length() == 1);
   6138   CONVERT_ARG_CHECKED(Object, object, 0);
   6139 
   6140   return isolate->heap()->ToBoolean(object->BooleanValue());
   6141 }
   6142 
   6143 
   6144 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
   6145 // Possible optimizations: put the type string into the oddballs.
   6146 RUNTIME_FUNCTION(Runtime_Typeof) {
   6147   SealHandleScope shs(isolate);
   6148   DCHECK(args.length() == 1);
   6149   CONVERT_ARG_CHECKED(Object, obj, 0);
   6150   if (obj->IsNumber()) return isolate->heap()->number_string();
   6151   HeapObject* heap_obj = HeapObject::cast(obj);
   6152 
   6153   // typeof an undetectable object is 'undefined'
   6154   if (heap_obj->map()->is_undetectable()) {
   6155     return isolate->heap()->undefined_string();
   6156   }
   6157 
   6158   InstanceType instance_type = heap_obj->map()->instance_type();
   6159   if (instance_type < FIRST_NONSTRING_TYPE) {
   6160     return isolate->heap()->string_string();
   6161   }
   6162 
   6163   switch (instance_type) {
   6164     case ODDBALL_TYPE:
   6165       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
   6166         return isolate->heap()->boolean_string();
   6167       }
   6168       if (heap_obj->IsNull()) {
   6169         return isolate->heap()->object_string();
   6170       }
   6171       DCHECK(heap_obj->IsUndefined());
   6172       return isolate->heap()->undefined_string();
   6173     case SYMBOL_TYPE:
   6174       return isolate->heap()->symbol_string();
   6175     case JS_FUNCTION_TYPE:
   6176     case JS_FUNCTION_PROXY_TYPE:
   6177       return isolate->heap()->function_string();
   6178     default:
   6179       // For any kind of object not handled above, the spec rule for
   6180       // host objects gives that it is okay to return "object"
   6181       return isolate->heap()->object_string();
   6182   }
   6183 }
   6184 
   6185 
   6186 RUNTIME_FUNCTION(Runtime_Booleanize) {
   6187   SealHandleScope shs(isolate);
   6188   DCHECK(args.length() == 2);
   6189   CONVERT_ARG_CHECKED(Object, value_raw, 0);
   6190   CONVERT_SMI_ARG_CHECKED(token_raw, 1);
   6191   intptr_t value = reinterpret_cast<intptr_t>(value_raw);
   6192   Token::Value token = static_cast<Token::Value>(token_raw);
   6193   switch (token) {
   6194     case Token::EQ:
   6195     case Token::EQ_STRICT:
   6196       return isolate->heap()->ToBoolean(value == 0);
   6197     case Token::NE:
   6198     case Token::NE_STRICT:
   6199       return isolate->heap()->ToBoolean(value != 0);
   6200     case Token::LT:
   6201       return isolate->heap()->ToBoolean(value < 0);
   6202     case Token::GT:
   6203       return isolate->heap()->ToBoolean(value > 0);
   6204     case Token::LTE:
   6205       return isolate->heap()->ToBoolean(value <= 0);
   6206     case Token::GTE:
   6207       return isolate->heap()->ToBoolean(value >= 0);
   6208     default:
   6209       // This should only happen during natives fuzzing.
   6210       return isolate->heap()->undefined_value();
   6211   }
   6212 }
   6213 
   6214 
   6215 static bool AreDigits(const uint8_t*s, int from, int to) {
   6216   for (int i = from; i < to; i++) {
   6217     if (s[i] < '0' || s[i] > '9') return false;
   6218   }
   6219 
   6220   return true;
   6221 }
   6222 
   6223 
   6224 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
   6225   DCHECK(to - from < 10);  // Overflow is not possible.
   6226   DCHECK(from < to);
   6227   int d = s[from] - '0';
   6228 
   6229   for (int i = from + 1; i < to; i++) {
   6230     d = 10 * d + (s[i] - '0');
   6231   }
   6232 
   6233   return d;
   6234 }
   6235 
   6236 
   6237 RUNTIME_FUNCTION(Runtime_StringToNumber) {
   6238   HandleScope handle_scope(isolate);
   6239   DCHECK(args.length() == 1);
   6240   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6241   subject = String::Flatten(subject);
   6242 
   6243   // Fast case: short integer or some sorts of junk values.
   6244   if (subject->IsSeqOneByteString()) {
   6245     int len = subject->length();
   6246     if (len == 0) return Smi::FromInt(0);
   6247 
   6248     DisallowHeapAllocation no_gc;
   6249     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
   6250     bool minus = (data[0] == '-');
   6251     int start_pos = (minus ? 1 : 0);
   6252 
   6253     if (start_pos == len) {
   6254       return isolate->heap()->nan_value();
   6255     } else if (data[start_pos] > '9') {
   6256       // Fast check for a junk value. A valid string may start from a
   6257       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
   6258       // or the 'I' character ('Infinity'). All of that have codes not greater
   6259       // than '9' except 'I' and &nbsp;.
   6260       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   6261         return isolate->heap()->nan_value();
   6262       }
   6263     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   6264       // The maximal/minimal smi has 10 digits. If the string has less digits
   6265       // we know it will fit into the smi-data type.
   6266       int d = ParseDecimalInteger(data, start_pos, len);
   6267       if (minus) {
   6268         if (d == 0) return isolate->heap()->minus_zero_value();
   6269         d = -d;
   6270       } else if (!subject->HasHashCode() &&
   6271                  len <= String::kMaxArrayIndexSize &&
   6272                  (len == 1 || data[0] != '0')) {
   6273         // String hash is not calculated yet but all the data are present.
   6274         // Update the hash field to speed up sequential convertions.
   6275         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   6276 #ifdef DEBUG
   6277         subject->Hash();  // Force hash calculation.
   6278         DCHECK_EQ(static_cast<int>(subject->hash_field()),
   6279                   static_cast<int>(hash));
   6280 #endif
   6281         subject->set_hash_field(hash);
   6282       }
   6283       return Smi::FromInt(d);
   6284     }
   6285   }
   6286 
   6287   // Slower case.
   6288   int flags = ALLOW_HEX;
   6289   if (FLAG_harmony_numeric_literals) {
   6290     // The current spec draft has not updated "ToNumber Applied to the String
   6291     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
   6292     flags |= ALLOW_OCTAL | ALLOW_BINARY;
   6293   }
   6294 
   6295   return *isolate->factory()->NewNumber(StringToDouble(
   6296       isolate->unicode_cache(), *subject, flags));
   6297 }
   6298 
   6299 
   6300 RUNTIME_FUNCTION(Runtime_NewString) {
   6301   HandleScope scope(isolate);
   6302   DCHECK(args.length() == 2);
   6303   CONVERT_INT32_ARG_CHECKED(length, 0);
   6304   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
   6305   if (length == 0) return isolate->heap()->empty_string();
   6306   Handle<String> result;
   6307   if (is_one_byte) {
   6308     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6309         isolate, result, isolate->factory()->NewRawOneByteString(length));
   6310   } else {
   6311     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6312         isolate, result, isolate->factory()->NewRawTwoByteString(length));
   6313   }
   6314   return *result;
   6315 }
   6316 
   6317 
   6318 RUNTIME_FUNCTION(Runtime_TruncateString) {
   6319   HandleScope scope(isolate);
   6320   DCHECK(args.length() == 2);
   6321   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
   6322   CONVERT_INT32_ARG_CHECKED(new_length, 1);
   6323   RUNTIME_ASSERT(new_length >= 0);
   6324   return *SeqString::Truncate(string, new_length);
   6325 }
   6326 
   6327 
   6328 RUNTIME_FUNCTION(Runtime_URIEscape) {
   6329   HandleScope scope(isolate);
   6330   DCHECK(args.length() == 1);
   6331   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6332   Handle<String> string = String::Flatten(source);
   6333   DCHECK(string->IsFlat());
   6334   Handle<String> result;
   6335   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6336       isolate, result,
   6337       string->IsOneByteRepresentationUnderneath()
   6338             ? URIEscape::Escape<uint8_t>(isolate, source)
   6339             : URIEscape::Escape<uc16>(isolate, source));
   6340   return *result;
   6341 }
   6342 
   6343 
   6344 RUNTIME_FUNCTION(Runtime_URIUnescape) {
   6345   HandleScope scope(isolate);
   6346   DCHECK(args.length() == 1);
   6347   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6348   Handle<String> string = String::Flatten(source);
   6349   DCHECK(string->IsFlat());
   6350   Handle<String> result;
   6351   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6352       isolate, result,
   6353       string->IsOneByteRepresentationUnderneath()
   6354             ? URIUnescape::Unescape<uint8_t>(isolate, source)
   6355             : URIUnescape::Unescape<uc16>(isolate, source));
   6356   return *result;
   6357 }
   6358 
   6359 
   6360 RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
   6361   HandleScope scope(isolate);
   6362   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   6363   DCHECK(args.length() == 1);
   6364   Handle<Object> result;
   6365   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6366       isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
   6367   return *result;
   6368 }
   6369 
   6370 
   6371 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
   6372   HandleScope scope(isolate);
   6373   DCHECK(args.length() == 1);
   6374   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   6375   BasicJsonStringifier stringifier(isolate);
   6376   Handle<Object> result;
   6377   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6378       isolate, result, stringifier.Stringify(object));
   6379   return *result;
   6380 }
   6381 
   6382 
   6383 RUNTIME_FUNCTION(Runtime_StringParseInt) {
   6384   HandleScope handle_scope(isolate);
   6385   DCHECK(args.length() == 2);
   6386   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6387   CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
   6388   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
   6389 
   6390   subject = String::Flatten(subject);
   6391   double value;
   6392 
   6393   { DisallowHeapAllocation no_gc;
   6394     String::FlatContent flat = subject->GetFlatContent();
   6395 
   6396     // ECMA-262 section 15.1.2.3, empty string is NaN
   6397     if (flat.IsOneByte()) {
   6398       value = StringToInt(
   6399           isolate->unicode_cache(), flat.ToOneByteVector(), radix);
   6400     } else {
   6401       value = StringToInt(
   6402           isolate->unicode_cache(), flat.ToUC16Vector(), radix);
   6403     }
   6404   }
   6405 
   6406   return *isolate->factory()->NewNumber(value);
   6407 }
   6408 
   6409 
   6410 RUNTIME_FUNCTION(Runtime_StringParseFloat) {
   6411   HandleScope shs(isolate);
   6412   DCHECK(args.length() == 1);
   6413   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6414 
   6415   subject = String::Flatten(subject);
   6416   double value = StringToDouble(isolate->unicode_cache(), *subject,
   6417                                 ALLOW_TRAILING_JUNK, base::OS::nan_value());
   6418 
   6419   return *isolate->factory()->NewNumber(value);
   6420 }
   6421 
   6422 
   6423 static inline bool ToUpperOverflows(uc32 character) {
   6424   // y with umlauts and the micro sign are the only characters that stop
   6425   // fitting into one-byte when converting to uppercase.
   6426   static const uc32 yuml_code = 0xff;
   6427   static const uc32 micro_code = 0xb5;
   6428   return (character == yuml_code || character == micro_code);
   6429 }
   6430 
   6431 
   6432 template <class Converter>
   6433 MUST_USE_RESULT static Object* ConvertCaseHelper(
   6434     Isolate* isolate,
   6435     String* string,
   6436     SeqString* result,
   6437     int result_length,
   6438     unibrow::Mapping<Converter, 128>* mapping) {
   6439   DisallowHeapAllocation no_gc;
   6440   // We try this twice, once with the assumption that the result is no longer
   6441   // than the input and, if that assumption breaks, again with the exact
   6442   // length.  This may not be pretty, but it is nicer than what was here before
   6443   // and I hereby claim my vaffel-is.
   6444   //
   6445   // NOTE: This assumes that the upper/lower case of an ASCII
   6446   // character is also ASCII.  This is currently the case, but it
   6447   // might break in the future if we implement more context and locale
   6448   // dependent upper/lower conversions.
   6449   bool has_changed_character = false;
   6450 
   6451   // Convert all characters to upper case, assuming that they will fit
   6452   // in the buffer
   6453   Access<ConsStringIteratorOp> op(
   6454       isolate->runtime_state()->string_iterator());
   6455   StringCharacterStream stream(string, op.value());
   6456   unibrow::uchar chars[Converter::kMaxWidth];
   6457   // We can assume that the string is not empty
   6458   uc32 current = stream.GetNext();
   6459   bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
   6460   for (int i = 0; i < result_length;) {
   6461     bool has_next = stream.HasMore();
   6462     uc32 next = has_next ? stream.GetNext() : 0;
   6463     int char_length = mapping->get(current, next, chars);
   6464     if (char_length == 0) {
   6465       // The case conversion of this character is the character itself.
   6466       result->Set(i, current);
   6467       i++;
   6468     } else if (char_length == 1 &&
   6469                (ignore_overflow || !ToUpperOverflows(current))) {
   6470       // Common case: converting the letter resulted in one character.
   6471       DCHECK(static_cast<uc32>(chars[0]) != current);
   6472       result->Set(i, chars[0]);
   6473       has_changed_character = true;
   6474       i++;
   6475     } else if (result_length == string->length()) {
   6476       bool overflows = ToUpperOverflows(current);
   6477       // We've assumed that the result would be as long as the
   6478       // input but here is a character that converts to several
   6479       // characters.  No matter, we calculate the exact length
   6480       // of the result and try the whole thing again.
   6481       //
   6482       // Note that this leaves room for optimization.  We could just
   6483       // memcpy what we already have to the result string.  Also,
   6484       // the result string is the last object allocated we could
   6485       // "realloc" it and probably, in the vast majority of cases,
   6486       // extend the existing string to be able to hold the full
   6487       // result.
   6488       int next_length = 0;
   6489       if (has_next) {
   6490         next_length = mapping->get(next, 0, chars);
   6491         if (next_length == 0) next_length = 1;
   6492       }
   6493       int current_length = i + char_length + next_length;
   6494       while (stream.HasMore()) {
   6495         current = stream.GetNext();
   6496         overflows |= ToUpperOverflows(current);
   6497         // NOTE: we use 0 as the next character here because, while
   6498         // the next character may affect what a character converts to,
   6499         // it does not in any case affect the length of what it convert
   6500         // to.
   6501         int char_length = mapping->get(current, 0, chars);
   6502         if (char_length == 0) char_length = 1;
   6503         current_length += char_length;
   6504         if (current_length > String::kMaxLength) {
   6505           AllowHeapAllocation allocate_error_and_return;
   6506           THROW_NEW_ERROR_RETURN_FAILURE(isolate,
   6507                                          NewInvalidStringLengthError());
   6508         }
   6509       }
   6510       // Try again with the real length.  Return signed if we need
   6511       // to allocate a two-byte string for to uppercase.
   6512       return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
   6513                                              : Smi::FromInt(current_length);
   6514     } else {
   6515       for (int j = 0; j < char_length; j++) {
   6516         result->Set(i, chars[j]);
   6517         i++;
   6518       }
   6519       has_changed_character = true;
   6520     }
   6521     current = next;
   6522   }
   6523   if (has_changed_character) {
   6524     return result;
   6525   } else {
   6526     // If we didn't actually change anything in doing the conversion
   6527     // we simple return the result and let the converted string
   6528     // become garbage; there is no reason to keep two identical strings
   6529     // alive.
   6530     return string;
   6531   }
   6532 }
   6533 
   6534 
   6535 namespace {
   6536 
   6537 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
   6538 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
   6539 
   6540 // Given a word and two range boundaries returns a word with high bit
   6541 // set in every byte iff the corresponding input byte was strictly in
   6542 // the range (m, n). All the other bits in the result are cleared.
   6543 // This function is only useful when it can be inlined and the
   6544 // boundaries are statically known.
   6545 // Requires: all bytes in the input word and the boundaries must be
   6546 // ASCII (less than 0x7F).
   6547 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
   6548   // Use strict inequalities since in edge cases the function could be
   6549   // further simplified.
   6550   DCHECK(0 < m && m < n);
   6551   // Has high bit set in every w byte less than n.
   6552   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   6553   // Has high bit set in every w byte greater than m.
   6554   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
   6555   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
   6556 }
   6557 
   6558 
   6559 #ifdef DEBUG
   6560 static bool CheckFastAsciiConvert(char* dst,
   6561                                   const char* src,
   6562                                   int length,
   6563                                   bool changed,
   6564                                   bool is_to_lower) {
   6565   bool expected_changed = false;
   6566   for (int i = 0; i < length; i++) {
   6567     if (dst[i] == src[i]) continue;
   6568     expected_changed = true;
   6569     if (is_to_lower) {
   6570       DCHECK('A' <= src[i] && src[i] <= 'Z');
   6571       DCHECK(dst[i] == src[i] + ('a' - 'A'));
   6572     } else {
   6573       DCHECK('a' <= src[i] && src[i] <= 'z');
   6574       DCHECK(dst[i] == src[i] - ('a' - 'A'));
   6575     }
   6576   }
   6577   return (expected_changed == changed);
   6578 }
   6579 #endif
   6580 
   6581 
   6582 template<class Converter>
   6583 static bool FastAsciiConvert(char* dst,
   6584                              const char* src,
   6585                              int length,
   6586                              bool* changed_out) {
   6587 #ifdef DEBUG
   6588     char* saved_dst = dst;
   6589     const char* saved_src = src;
   6590 #endif
   6591   DisallowHeapAllocation no_gc;
   6592   // We rely on the distance between upper and lower case letters
   6593   // being a known power of 2.
   6594   DCHECK('a' - 'A' == (1 << 5));
   6595   // Boundaries for the range of input characters than require conversion.
   6596   static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
   6597   static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
   6598   bool changed = false;
   6599   uintptr_t or_acc = 0;
   6600   const char* const limit = src + length;
   6601 
   6602   // dst is newly allocated and always aligned.
   6603   DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t)));
   6604   // Only attempt processing one word at a time if src is also aligned.
   6605   if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) {
   6606     // Process the prefix of the input that requires no conversion one aligned
   6607     // (machine) word at a time.
   6608     while (src <= limit - sizeof(uintptr_t)) {
   6609       const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
   6610       or_acc |= w;
   6611       if (AsciiRangeMask(w, lo, hi) != 0) {
   6612         changed = true;
   6613         break;
   6614       }
   6615       *reinterpret_cast<uintptr_t*>(dst) = w;
   6616       src += sizeof(uintptr_t);
   6617       dst += sizeof(uintptr_t);
   6618     }
   6619     // Process the remainder of the input performing conversion when
   6620     // required one word at a time.
   6621     while (src <= limit - sizeof(uintptr_t)) {
   6622       const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
   6623       or_acc |= w;
   6624       uintptr_t m = AsciiRangeMask(w, lo, hi);
   6625       // The mask has high (7th) bit set in every byte that needs
   6626       // conversion and we know that the distance between cases is
   6627       // 1 << 5.
   6628       *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
   6629       src += sizeof(uintptr_t);
   6630       dst += sizeof(uintptr_t);
   6631     }
   6632   }
   6633   // Process the last few bytes of the input (or the whole input if
   6634   // unaligned access is not supported).
   6635   while (src < limit) {
   6636     char c = *src;
   6637     or_acc |= c;
   6638     if (lo < c && c < hi) {
   6639       c ^= (1 << 5);
   6640       changed = true;
   6641     }
   6642     *dst = c;
   6643     ++src;
   6644     ++dst;
   6645   }
   6646 
   6647   if ((or_acc & kAsciiMask) != 0) return false;
   6648 
   6649   DCHECK(CheckFastAsciiConvert(
   6650              saved_dst, saved_src, length, changed, Converter::kIsToLower));
   6651 
   6652   *changed_out = changed;
   6653   return true;
   6654 }
   6655 
   6656 }  // namespace
   6657 
   6658 
   6659 template <class Converter>
   6660 MUST_USE_RESULT static Object* ConvertCase(
   6661     Handle<String> s,
   6662     Isolate* isolate,
   6663     unibrow::Mapping<Converter, 128>* mapping) {
   6664   s = String::Flatten(s);
   6665   int length = s->length();
   6666   // Assume that the string is not empty; we need this assumption later
   6667   if (length == 0) return *s;
   6668 
   6669   // Simpler handling of ASCII strings.
   6670   //
   6671   // NOTE: This assumes that the upper/lower case of an ASCII
   6672   // character is also ASCII.  This is currently the case, but it
   6673   // might break in the future if we implement more context and locale
   6674   // dependent upper/lower conversions.
   6675   if (s->IsOneByteRepresentationUnderneath()) {
   6676     // Same length as input.
   6677     Handle<SeqOneByteString> result =
   6678         isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
   6679     DisallowHeapAllocation no_gc;
   6680     String::FlatContent flat_content = s->GetFlatContent();
   6681     DCHECK(flat_content.IsFlat());
   6682     bool has_changed_character = false;
   6683     bool is_ascii = FastAsciiConvert<Converter>(
   6684         reinterpret_cast<char*>(result->GetChars()),
   6685         reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
   6686         length,
   6687         &has_changed_character);
   6688     // If not ASCII, we discard the result and take the 2 byte path.
   6689     if (is_ascii) return has_changed_character ? *result : *s;
   6690   }
   6691 
   6692   Handle<SeqString> result;  // Same length as input.
   6693   if (s->IsOneByteRepresentation()) {
   6694     result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
   6695   } else {
   6696     result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
   6697   }
   6698 
   6699   Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
   6700   if (answer->IsException() || answer->IsString()) return answer;
   6701 
   6702   DCHECK(answer->IsSmi());
   6703   length = Smi::cast(answer)->value();
   6704   if (s->IsOneByteRepresentation() && length > 0) {
   6705     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6706         isolate, result, isolate->factory()->NewRawOneByteString(length));
   6707   } else {
   6708     if (length < 0) length = -length;
   6709     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6710         isolate, result, isolate->factory()->NewRawTwoByteString(length));
   6711   }
   6712   return ConvertCaseHelper(isolate, *s, *result, length, mapping);
   6713 }
   6714 
   6715 
   6716 RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
   6717   HandleScope scope(isolate);
   6718   DCHECK(args.length() == 1);
   6719   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6720   return ConvertCase(
   6721       s, isolate, isolate->runtime_state()->to_lower_mapping());
   6722 }
   6723 
   6724 
   6725 RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
   6726   HandleScope scope(isolate);
   6727   DCHECK(args.length() == 1);
   6728   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6729   return ConvertCase(
   6730       s, isolate, isolate->runtime_state()->to_upper_mapping());
   6731 }
   6732 
   6733 
   6734 RUNTIME_FUNCTION(Runtime_StringTrim) {
   6735   HandleScope scope(isolate);
   6736   DCHECK(args.length() == 3);
   6737 
   6738   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   6739   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
   6740   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
   6741 
   6742   string = String::Flatten(string);
   6743   int length = string->length();
   6744 
   6745   int left = 0;
   6746   UnicodeCache* unicode_cache = isolate->unicode_cache();
   6747   if (trimLeft) {
   6748     while (left < length &&
   6749            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
   6750       left++;
   6751     }
   6752   }
   6753 
   6754   int right = length;
   6755   if (trimRight) {
   6756     while (right > left &&
   6757            unicode_cache->IsWhiteSpaceOrLineTerminator(
   6758                string->Get(right - 1))) {
   6759       right--;
   6760     }
   6761   }
   6762 
   6763   return *isolate->factory()->NewSubString(string, left, right);
   6764 }
   6765 
   6766 
   6767 RUNTIME_FUNCTION(Runtime_StringSplit) {
   6768   HandleScope handle_scope(isolate);
   6769   DCHECK(args.length() == 3);
   6770   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6771   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   6772   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
   6773   RUNTIME_ASSERT(limit > 0);
   6774 
   6775   int subject_length = subject->length();
   6776   int pattern_length = pattern->length();
   6777   RUNTIME_ASSERT(pattern_length > 0);
   6778 
   6779   if (limit == 0xffffffffu) {
   6780     Handle<Object> cached_answer(
   6781         RegExpResultsCache::Lookup(isolate->heap(),
   6782                                    *subject,
   6783                                    *pattern,
   6784                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
   6785         isolate);
   6786     if (*cached_answer != Smi::FromInt(0)) {
   6787       // The cache FixedArray is a COW-array and can therefore be reused.
   6788       Handle<JSArray> result =
   6789           isolate->factory()->NewJSArrayWithElements(
   6790               Handle<FixedArray>::cast(cached_answer));
   6791       return *result;
   6792     }
   6793   }
   6794 
   6795   // The limit can be very large (0xffffffffu), but since the pattern
   6796   // isn't empty, we can never create more parts than ~half the length
   6797   // of the subject.
   6798 
   6799   subject = String::Flatten(subject);
   6800   pattern = String::Flatten(pattern);
   6801 
   6802   static const int kMaxInitialListCapacity = 16;
   6803 
   6804   ZoneScope zone_scope(isolate->runtime_zone());
   6805 
   6806   // Find (up to limit) indices of separator and end-of-string in subject
   6807   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
   6808   ZoneList<int> indices(initial_capacity, zone_scope.zone());
   6809 
   6810   FindStringIndicesDispatch(isolate, *subject, *pattern,
   6811                             &indices, limit, zone_scope.zone());
   6812 
   6813   if (static_cast<uint32_t>(indices.length()) < limit) {
   6814     indices.Add(subject_length, zone_scope.zone());
   6815   }
   6816 
   6817   // The list indices now contains the end of each part to create.
   6818 
   6819   // Create JSArray of substrings separated by separator.
   6820   int part_count = indices.length();
   6821 
   6822   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
   6823   JSObject::EnsureCanContainHeapObjectElements(result);
   6824   result->set_length(Smi::FromInt(part_count));
   6825 
   6826   DCHECK(result->HasFastObjectElements());
   6827 
   6828   if (part_count == 1 && indices.at(0) == subject_length) {
   6829     FixedArray::cast(result->elements())->set(0, *subject);
   6830     return *result;
   6831   }
   6832 
   6833   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
   6834   int part_start = 0;
   6835   for (int i = 0; i < part_count; i++) {
   6836     HandleScope local_loop_handle(isolate);
   6837     int part_end = indices.at(i);
   6838     Handle<String> substring =
   6839         isolate->factory()->NewProperSubString(subject, part_start, part_end);
   6840     elements->set(i, *substring);
   6841     part_start = part_end + pattern_length;
   6842   }
   6843 
   6844   if (limit == 0xffffffffu) {
   6845     if (result->HasFastObjectElements()) {
   6846       RegExpResultsCache::Enter(isolate,
   6847                                 subject,
   6848                                 pattern,
   6849                                 elements,
   6850                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
   6851     }
   6852   }
   6853 
   6854   return *result;
   6855 }
   6856 
   6857 
   6858 // Copies Latin1 characters to the given fixed array looking up
   6859 // one-char strings in the cache. Gives up on the first char that is
   6860 // not in the cache and fills the remainder with smi zeros. Returns
   6861 // the length of the successfully copied prefix.
   6862 static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars,
   6863                                          FixedArray* elements, int length) {
   6864   DisallowHeapAllocation no_gc;
   6865   FixedArray* one_byte_cache = heap->single_character_string_cache();
   6866   Object* undefined = heap->undefined_value();
   6867   int i;
   6868   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   6869   for (i = 0; i < length; ++i) {
   6870     Object* value = one_byte_cache->get(chars[i]);
   6871     if (value == undefined) break;
   6872     elements->set(i, value, mode);
   6873   }
   6874   if (i < length) {
   6875     DCHECK(Smi::FromInt(0) == 0);
   6876     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
   6877   }
   6878 #ifdef DEBUG
   6879   for (int j = 0; j < length; ++j) {
   6880     Object* element = elements->get(j);
   6881     DCHECK(element == Smi::FromInt(0) ||
   6882            (element->IsString() && String::cast(element)->LooksValid()));
   6883   }
   6884 #endif
   6885   return i;
   6886 }
   6887 
   6888 
   6889 // Converts a String to JSArray.
   6890 // For example, "foo" => ["f", "o", "o"].
   6891 RUNTIME_FUNCTION(Runtime_StringToArray) {
   6892   HandleScope scope(isolate);
   6893   DCHECK(args.length() == 2);
   6894   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6895   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   6896 
   6897   s = String::Flatten(s);
   6898   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
   6899 
   6900   Handle<FixedArray> elements;
   6901   int position = 0;
   6902   if (s->IsFlat() && s->IsOneByteRepresentation()) {
   6903     // Try using cached chars where possible.
   6904     elements = isolate->factory()->NewUninitializedFixedArray(length);
   6905 
   6906     DisallowHeapAllocation no_gc;
   6907     String::FlatContent content = s->GetFlatContent();
   6908     if (content.IsOneByte()) {
   6909       Vector<const uint8_t> chars = content.ToOneByteVector();
   6910       // Note, this will initialize all elements (not only the prefix)
   6911       // to prevent GC from seeing partially initialized array.
   6912       position = CopyCachedOneByteCharsToArray(isolate->heap(), chars.start(),
   6913                                                *elements, length);
   6914     } else {
   6915       MemsetPointer(elements->data_start(),
   6916                     isolate->heap()->undefined_value(),
   6917                     length);
   6918     }
   6919   } else {
   6920     elements = isolate->factory()->NewFixedArray(length);
   6921   }
   6922   for (int i = position; i < length; ++i) {
   6923     Handle<Object> str =
   6924         isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
   6925     elements->set(i, *str);
   6926   }
   6927 
   6928 #ifdef DEBUG
   6929   for (int i = 0; i < length; ++i) {
   6930     DCHECK(String::cast(elements->get(i))->length() == 1);
   6931   }
   6932 #endif
   6933 
   6934   return *isolate->factory()->NewJSArrayWithElements(elements);
   6935 }
   6936 
   6937 
   6938 RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
   6939   HandleScope scope(isolate);
   6940   DCHECK(args.length() == 1);
   6941   CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
   6942   return *Object::ToObject(isolate, value).ToHandleChecked();
   6943 }
   6944 
   6945 
   6946 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
   6947   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
   6948   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
   6949   return char_length == 0;
   6950 }
   6951 
   6952 
   6953 RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
   6954   HandleScope scope(isolate);
   6955   DCHECK(args.length() == 1);
   6956   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
   6957 
   6958   return *isolate->factory()->NumberToString(number);
   6959 }
   6960 
   6961 
   6962 RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
   6963   HandleScope scope(isolate);
   6964   DCHECK(args.length() == 1);
   6965   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
   6966 
   6967   return *isolate->factory()->NumberToString(number, false);
   6968 }
   6969 
   6970 
   6971 RUNTIME_FUNCTION(Runtime_NumberToInteger) {
   6972   HandleScope scope(isolate);
   6973   DCHECK(args.length() == 1);
   6974 
   6975   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6976   return *isolate->factory()->NewNumber(DoubleToInteger(number));
   6977 }
   6978 
   6979 
   6980 RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
   6981   HandleScope scope(isolate);
   6982   DCHECK(args.length() == 1);
   6983 
   6984   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6985   double double_value = DoubleToInteger(number);
   6986   // Map both -0 and +0 to +0.
   6987   if (double_value == 0) double_value = 0;
   6988 
   6989   return *isolate->factory()->NewNumber(double_value);
   6990 }
   6991 
   6992 
   6993 RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
   6994   HandleScope scope(isolate);
   6995   DCHECK(args.length() == 1);
   6996 
   6997   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
   6998   return *isolate->factory()->NewNumberFromUint(number);
   6999 }
   7000 
   7001 
   7002 RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
   7003   HandleScope scope(isolate);
   7004   DCHECK(args.length() == 1);
   7005 
   7006   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   7007   return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
   7008 }
   7009 
   7010 
   7011 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
   7012 // a small integer.
   7013 RUNTIME_FUNCTION(Runtime_NumberToSmi) {
   7014   SealHandleScope shs(isolate);
   7015   DCHECK(args.length() == 1);
   7016   CONVERT_ARG_CHECKED(Object, obj, 0);
   7017   if (obj->IsSmi()) {
   7018     return obj;
   7019   }
   7020   if (obj->IsHeapNumber()) {
   7021     double value = HeapNumber::cast(obj)->value();
   7022     int int_value = FastD2I(value);
   7023     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
   7024       return Smi::FromInt(int_value);
   7025     }
   7026   }
   7027   return isolate->heap()->nan_value();
   7028 }
   7029 
   7030 
   7031 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
   7032   HandleScope scope(isolate);
   7033   DCHECK(args.length() == 0);
   7034   return *isolate->factory()->NewHeapNumber(0);
   7035 }
   7036 
   7037 
   7038 RUNTIME_FUNCTION(Runtime_NumberAdd) {
   7039   HandleScope scope(isolate);
   7040   DCHECK(args.length() == 2);
   7041 
   7042   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7043   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7044   return *isolate->factory()->NewNumber(x + y);
   7045 }
   7046 
   7047 
   7048 RUNTIME_FUNCTION(Runtime_NumberSub) {
   7049   HandleScope scope(isolate);
   7050   DCHECK(args.length() == 2);
   7051 
   7052   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7053   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7054   return *isolate->factory()->NewNumber(x - y);
   7055 }
   7056 
   7057 
   7058 RUNTIME_FUNCTION(Runtime_NumberMul) {
   7059   HandleScope scope(isolate);
   7060   DCHECK(args.length() == 2);
   7061 
   7062   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7063   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7064   return *isolate->factory()->NewNumber(x * y);
   7065 }
   7066 
   7067 
   7068 RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
   7069   HandleScope scope(isolate);
   7070   DCHECK(args.length() == 1);
   7071 
   7072   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7073   return *isolate->factory()->NewNumber(-x);
   7074 }
   7075 
   7076 
   7077 RUNTIME_FUNCTION(Runtime_NumberDiv) {
   7078   HandleScope scope(isolate);
   7079   DCHECK(args.length() == 2);
   7080 
   7081   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7082   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7083   return *isolate->factory()->NewNumber(x / y);
   7084 }
   7085 
   7086 
   7087 RUNTIME_FUNCTION(Runtime_NumberMod) {
   7088   HandleScope scope(isolate);
   7089   DCHECK(args.length() == 2);
   7090 
   7091   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7092   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7093   return *isolate->factory()->NewNumber(modulo(x, y));
   7094 }
   7095 
   7096 
   7097 RUNTIME_FUNCTION(Runtime_NumberImul) {
   7098   HandleScope scope(isolate);
   7099   DCHECK(args.length() == 2);
   7100 
   7101   // We rely on implementation-defined behavior below, but at least not on
   7102   // undefined behavior.
   7103   CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
   7104   CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
   7105   int32_t product = static_cast<int32_t>(x * y);
   7106   return *isolate->factory()->NewNumberFromInt(product);
   7107 }
   7108 
   7109 
   7110 RUNTIME_FUNCTION(Runtime_StringAdd) {
   7111   HandleScope scope(isolate);
   7112   DCHECK(args.length() == 2);
   7113   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
   7114   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
   7115   isolate->counters()->string_add_runtime()->Increment();
   7116   Handle<String> result;
   7117   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7118       isolate, result, isolate->factory()->NewConsString(str1, str2));
   7119   return *result;
   7120 }
   7121 
   7122 
   7123 template <typename sinkchar>
   7124 static inline void StringBuilderConcatHelper(String* special,
   7125                                              sinkchar* sink,
   7126                                              FixedArray* fixed_array,
   7127                                              int array_length) {
   7128   DisallowHeapAllocation no_gc;
   7129   int position = 0;
   7130   for (int i = 0; i < array_length; i++) {
   7131     Object* element = fixed_array->get(i);
   7132     if (element->IsSmi()) {
   7133       // Smi encoding of position and length.
   7134       int encoded_slice = Smi::cast(element)->value();
   7135       int pos;
   7136       int len;
   7137       if (encoded_slice > 0) {
   7138         // Position and length encoded in one smi.
   7139         pos = StringBuilderSubstringPosition::decode(encoded_slice);
   7140         len = StringBuilderSubstringLength::decode(encoded_slice);
   7141       } else {
   7142         // Position and length encoded in two smis.
   7143         Object* obj = fixed_array->get(++i);
   7144         DCHECK(obj->IsSmi());
   7145         pos = Smi::cast(obj)->value();
   7146         len = -encoded_slice;
   7147       }
   7148       String::WriteToFlat(special,
   7149                           sink + position,
   7150                           pos,
   7151                           pos + len);
   7152       position += len;
   7153     } else {
   7154       String* string = String::cast(element);
   7155       int element_length = string->length();
   7156       String::WriteToFlat(string, sink + position, 0, element_length);
   7157       position += element_length;
   7158     }
   7159   }
   7160 }
   7161 
   7162 
   7163 // Returns the result length of the concatenation.
   7164 // On illegal argument, -1 is returned.
   7165 static inline int StringBuilderConcatLength(int special_length,
   7166                                             FixedArray* fixed_array,
   7167                                             int array_length,
   7168                                             bool* one_byte) {
   7169   DisallowHeapAllocation no_gc;
   7170   int position = 0;
   7171   for (int i = 0; i < array_length; i++) {
   7172     int increment = 0;
   7173     Object* elt = fixed_array->get(i);
   7174     if (elt->IsSmi()) {
   7175       // Smi encoding of position and length.
   7176       int smi_value = Smi::cast(elt)->value();
   7177       int pos;
   7178       int len;
   7179       if (smi_value > 0) {
   7180         // Position and length encoded in one smi.
   7181         pos = StringBuilderSubstringPosition::decode(smi_value);
   7182         len = StringBuilderSubstringLength::decode(smi_value);
   7183       } else {
   7184         // Position and length encoded in two smis.
   7185         len = -smi_value;
   7186         // Get the position and check that it is a positive smi.
   7187         i++;
   7188         if (i >= array_length) return -1;
   7189         Object* next_smi = fixed_array->get(i);
   7190         if (!next_smi->IsSmi()) return -1;
   7191         pos = Smi::cast(next_smi)->value();
   7192         if (pos < 0) return -1;
   7193       }
   7194       DCHECK(pos >= 0);
   7195       DCHECK(len >= 0);
   7196       if (pos > special_length || len > special_length - pos) return -1;
   7197       increment = len;
   7198     } else if (elt->IsString()) {
   7199       String* element = String::cast(elt);
   7200       int element_length = element->length();
   7201       increment = element_length;
   7202       if (*one_byte && !element->HasOnlyOneByteChars()) {
   7203         *one_byte = false;
   7204       }
   7205     } else {
   7206       return -1;
   7207     }
   7208     if (increment > String::kMaxLength - position) {
   7209       return kMaxInt;  // Provoke throw on allocation.
   7210     }
   7211     position += increment;
   7212   }
   7213   return position;
   7214 }
   7215 
   7216 
   7217 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
   7218   HandleScope scope(isolate);
   7219   DCHECK(args.length() == 3);
   7220   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   7221   int32_t array_length;
   7222   if (!args[1]->ToInt32(&array_length)) {
   7223     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
   7224   }
   7225   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
   7226 
   7227   size_t actual_array_length = 0;
   7228   RUNTIME_ASSERT(
   7229       TryNumberToSize(isolate, array->length(), &actual_array_length));
   7230   RUNTIME_ASSERT(array_length >= 0);
   7231   RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
   7232 
   7233   // This assumption is used by the slice encoding in one or two smis.
   7234   DCHECK(Smi::kMaxValue >= String::kMaxLength);
   7235 
   7236   RUNTIME_ASSERT(array->HasFastElements());
   7237   JSObject::EnsureCanContainHeapObjectElements(array);
   7238 
   7239   int special_length = special->length();
   7240   if (!array->HasFastObjectElements()) {
   7241     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7242   }
   7243 
   7244   int length;
   7245   bool one_byte = special->HasOnlyOneByteChars();
   7246 
   7247   { DisallowHeapAllocation no_gc;
   7248     FixedArray* fixed_array = FixedArray::cast(array->elements());
   7249     if (fixed_array->length() < array_length) {
   7250       array_length = fixed_array->length();
   7251     }
   7252 
   7253     if (array_length == 0) {
   7254       return isolate->heap()->empty_string();
   7255     } else if (array_length == 1) {
   7256       Object* first = fixed_array->get(0);
   7257       if (first->IsString()) return first;
   7258     }
   7259     length = StringBuilderConcatLength(
   7260         special_length, fixed_array, array_length, &one_byte);
   7261   }
   7262 
   7263   if (length == -1) {
   7264     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7265   }
   7266 
   7267   if (one_byte) {
   7268     Handle<SeqOneByteString> answer;
   7269     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7270         isolate, answer,
   7271         isolate->factory()->NewRawOneByteString(length));
   7272     StringBuilderConcatHelper(*special,
   7273                               answer->GetChars(),
   7274                               FixedArray::cast(array->elements()),
   7275                               array_length);
   7276     return *answer;
   7277   } else {
   7278     Handle<SeqTwoByteString> answer;
   7279     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7280         isolate, answer,
   7281         isolate->factory()->NewRawTwoByteString(length));
   7282     StringBuilderConcatHelper(*special,
   7283                               answer->GetChars(),
   7284                               FixedArray::cast(array->elements()),
   7285                               array_length);
   7286     return *answer;
   7287   }
   7288 }
   7289 
   7290 
   7291 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
   7292   HandleScope scope(isolate);
   7293   DCHECK(args.length() == 3);
   7294   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   7295   int32_t array_length;
   7296   if (!args[1]->ToInt32(&array_length)) {
   7297     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
   7298   }
   7299   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
   7300   RUNTIME_ASSERT(array->HasFastObjectElements());
   7301   RUNTIME_ASSERT(array_length >= 0);
   7302 
   7303   Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
   7304   if (fixed_array->length() < array_length) {
   7305     array_length = fixed_array->length();
   7306   }
   7307 
   7308   if (array_length == 0) {
   7309     return isolate->heap()->empty_string();
   7310   } else if (array_length == 1) {
   7311     Object* first = fixed_array->get(0);
   7312     RUNTIME_ASSERT(first->IsString());
   7313     return first;
   7314   }
   7315 
   7316   int separator_length = separator->length();
   7317   RUNTIME_ASSERT(separator_length > 0);
   7318   int max_nof_separators =
   7319       (String::kMaxLength + separator_length - 1) / separator_length;
   7320   if (max_nof_separators < (array_length - 1)) {
   7321     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
   7322   }
   7323   int length = (array_length - 1) * separator_length;
   7324   for (int i = 0; i < array_length; i++) {
   7325     Object* element_obj = fixed_array->get(i);
   7326     RUNTIME_ASSERT(element_obj->IsString());
   7327     String* element = String::cast(element_obj);
   7328     int increment = element->length();
   7329     if (increment > String::kMaxLength - length) {
   7330       STATIC_ASSERT(String::kMaxLength < kMaxInt);
   7331       length = kMaxInt;  // Provoke exception;
   7332       break;
   7333     }
   7334     length += increment;
   7335   }
   7336 
   7337   Handle<SeqTwoByteString> answer;
   7338   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7339       isolate, answer,
   7340       isolate->factory()->NewRawTwoByteString(length));
   7341 
   7342   DisallowHeapAllocation no_gc;
   7343 
   7344   uc16* sink = answer->GetChars();
   7345 #ifdef DEBUG
   7346   uc16* end = sink + length;
   7347 #endif
   7348 
   7349   RUNTIME_ASSERT(fixed_array->get(0)->IsString());
   7350   String* first = String::cast(fixed_array->get(0));
   7351   String* separator_raw = *separator;
   7352   int first_length = first->length();
   7353   String::WriteToFlat(first, sink, 0, first_length);
   7354   sink += first_length;
   7355 
   7356   for (int i = 1; i < array_length; i++) {
   7357     DCHECK(sink + separator_length <= end);
   7358     String::WriteToFlat(separator_raw, sink, 0, separator_length);
   7359     sink += separator_length;
   7360 
   7361     RUNTIME_ASSERT(fixed_array->get(i)->IsString());
   7362     String* element = String::cast(fixed_array->get(i));
   7363     int element_length = element->length();
   7364     DCHECK(sink + element_length <= end);
   7365     String::WriteToFlat(element, sink, 0, element_length);
   7366     sink += element_length;
   7367   }
   7368   DCHECK(sink == end);
   7369 
   7370   // Use %_FastOneByteArrayJoin instead.
   7371   DCHECK(!answer->IsOneByteRepresentation());
   7372   return *answer;
   7373 }
   7374 
   7375 template <typename Char>
   7376 static void JoinSparseArrayWithSeparator(FixedArray* elements,
   7377                                          int elements_length,
   7378                                          uint32_t array_length,
   7379                                          String* separator,
   7380                                          Vector<Char> buffer) {
   7381   DisallowHeapAllocation no_gc;
   7382   int previous_separator_position = 0;
   7383   int separator_length = separator->length();
   7384   int cursor = 0;
   7385   for (int i = 0; i < elements_length; i += 2) {
   7386     int position = NumberToInt32(elements->get(i));
   7387     String* string = String::cast(elements->get(i + 1));
   7388     int string_length = string->length();
   7389     if (string->length() > 0) {
   7390       while (previous_separator_position < position) {
   7391         String::WriteToFlat<Char>(separator, &buffer[cursor],
   7392                                   0, separator_length);
   7393         cursor += separator_length;
   7394         previous_separator_position++;
   7395       }
   7396       String::WriteToFlat<Char>(string, &buffer[cursor],
   7397                                 0, string_length);
   7398       cursor += string->length();
   7399     }
   7400   }
   7401   if (separator_length > 0) {
   7402     // Array length must be representable as a signed 32-bit number,
   7403     // otherwise the total string length would have been too large.
   7404     DCHECK(array_length <= 0x7fffffff);  // Is int32_t.
   7405     int last_array_index = static_cast<int>(array_length - 1);
   7406     while (previous_separator_position < last_array_index) {
   7407       String::WriteToFlat<Char>(separator, &buffer[cursor],
   7408                                 0, separator_length);
   7409       cursor += separator_length;
   7410       previous_separator_position++;
   7411     }
   7412   }
   7413   DCHECK(cursor <= buffer.length());
   7414 }
   7415 
   7416 
   7417 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
   7418   HandleScope scope(isolate);
   7419   DCHECK(args.length() == 3);
   7420   CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
   7421   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
   7422   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
   7423   // elements_array is fast-mode JSarray of alternating positions
   7424   // (increasing order) and strings.
   7425   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
   7426   // array_length is length of original array (used to add separators);
   7427   // separator is string to put between elements. Assumed to be non-empty.
   7428   RUNTIME_ASSERT(array_length > 0);
   7429 
   7430   // Find total length of join result.
   7431   int string_length = 0;
   7432   bool is_one_byte = separator->IsOneByteRepresentation();
   7433   bool overflow = false;
   7434   CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
   7435   RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
   7436   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
   7437   FixedArray* elements = FixedArray::cast(elements_array->elements());
   7438   for (int i = 0; i < elements_length; i += 2) {
   7439     RUNTIME_ASSERT(elements->get(i)->IsNumber());
   7440     CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
   7441     RUNTIME_ASSERT(position < array_length);
   7442     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
   7443   }
   7444 
   7445   { DisallowHeapAllocation no_gc;
   7446     for (int i = 0; i < elements_length; i += 2) {
   7447       String* string = String::cast(elements->get(i + 1));
   7448       int length = string->length();
   7449       if (is_one_byte && !string->IsOneByteRepresentation()) {
   7450         is_one_byte = false;
   7451       }
   7452       if (length > String::kMaxLength ||
   7453           String::kMaxLength - length < string_length) {
   7454         overflow = true;
   7455         break;
   7456       }
   7457       string_length += length;
   7458     }
   7459   }
   7460 
   7461   int separator_length = separator->length();
   7462   if (!overflow && separator_length > 0) {
   7463     if (array_length <= 0x7fffffffu) {
   7464       int separator_count = static_cast<int>(array_length) - 1;
   7465       int remaining_length = String::kMaxLength - string_length;
   7466       if ((remaining_length / separator_length) >= separator_count) {
   7467         string_length += separator_length * (array_length - 1);
   7468       } else {
   7469         // Not room for the separators within the maximal string length.
   7470         overflow = true;
   7471       }
   7472     } else {
   7473       // Nonempty separator and at least 2^31-1 separators necessary
   7474       // means that the string is too large to create.
   7475       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
   7476       overflow = true;
   7477     }
   7478   }
   7479   if (overflow) {
   7480     // Throw an exception if the resulting string is too large. See
   7481     // https://code.google.com/p/chromium/issues/detail?id=336820
   7482     // for details.
   7483     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
   7484   }
   7485 
   7486   if (is_one_byte) {
   7487     Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
   7488         string_length).ToHandleChecked();
   7489     JoinSparseArrayWithSeparator<uint8_t>(
   7490         FixedArray::cast(elements_array->elements()),
   7491         elements_length,
   7492         array_length,
   7493         *separator,
   7494         Vector<uint8_t>(result->GetChars(), string_length));
   7495     return *result;
   7496   } else {
   7497     Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
   7498         string_length).ToHandleChecked();
   7499     JoinSparseArrayWithSeparator<uc16>(
   7500         FixedArray::cast(elements_array->elements()),
   7501         elements_length,
   7502         array_length,
   7503         *separator,
   7504         Vector<uc16>(result->GetChars(), string_length));
   7505     return *result;
   7506   }
   7507 }
   7508 
   7509 
   7510 RUNTIME_FUNCTION(Runtime_NumberOr) {
   7511   HandleScope scope(isolate);
   7512   DCHECK(args.length() == 2);
   7513 
   7514   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7515   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7516   return *isolate->factory()->NewNumberFromInt(x | y);
   7517 }
   7518 
   7519 
   7520 RUNTIME_FUNCTION(Runtime_NumberAnd) {
   7521   HandleScope scope(isolate);
   7522   DCHECK(args.length() == 2);
   7523 
   7524   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7525   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7526   return *isolate->factory()->NewNumberFromInt(x & y);
   7527 }
   7528 
   7529 
   7530 RUNTIME_FUNCTION(Runtime_NumberXor) {
   7531   HandleScope scope(isolate);
   7532   DCHECK(args.length() == 2);
   7533 
   7534   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7535   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7536   return *isolate->factory()->NewNumberFromInt(x ^ y);
   7537 }
   7538 
   7539 
   7540 RUNTIME_FUNCTION(Runtime_NumberShl) {
   7541   HandleScope scope(isolate);
   7542   DCHECK(args.length() == 2);
   7543 
   7544   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7545   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7546   return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
   7547 }
   7548 
   7549 
   7550 RUNTIME_FUNCTION(Runtime_NumberShr) {
   7551   HandleScope scope(isolate);
   7552   DCHECK(args.length() == 2);
   7553 
   7554   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
   7555   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7556   return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
   7557 }
   7558 
   7559 
   7560 RUNTIME_FUNCTION(Runtime_NumberSar) {
   7561   HandleScope scope(isolate);
   7562   DCHECK(args.length() == 2);
   7563 
   7564   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7565   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7566   return *isolate->factory()->NewNumberFromInt(
   7567       ArithmeticShiftRight(x, y & 0x1f));
   7568 }
   7569 
   7570 
   7571 RUNTIME_FUNCTION(Runtime_NumberEquals) {
   7572   SealHandleScope shs(isolate);
   7573   DCHECK(args.length() == 2);
   7574 
   7575   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7576   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7577   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
   7578   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
   7579   if (x == y) return Smi::FromInt(EQUAL);
   7580   Object* result;
   7581   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
   7582     result = Smi::FromInt(EQUAL);
   7583   } else {
   7584     result = Smi::FromInt(NOT_EQUAL);
   7585   }
   7586   return result;
   7587 }
   7588 
   7589 
   7590 RUNTIME_FUNCTION(Runtime_StringEquals) {
   7591   HandleScope handle_scope(isolate);
   7592   DCHECK(args.length() == 2);
   7593 
   7594   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
   7595   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
   7596 
   7597   bool not_equal = !String::Equals(x, y);
   7598   // This is slightly convoluted because the value that signifies
   7599   // equality is 0 and inequality is 1 so we have to negate the result
   7600   // from String::Equals.
   7601   DCHECK(not_equal == 0 || not_equal == 1);
   7602   STATIC_ASSERT(EQUAL == 0);
   7603   STATIC_ASSERT(NOT_EQUAL == 1);
   7604   return Smi::FromInt(not_equal);
   7605 }
   7606 
   7607 
   7608 RUNTIME_FUNCTION(Runtime_NumberCompare) {
   7609   SealHandleScope shs(isolate);
   7610   DCHECK(args.length() == 3);
   7611 
   7612   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7613   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7614   CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
   7615   if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
   7616   if (x == y) return Smi::FromInt(EQUAL);
   7617   if (isless(x, y)) return Smi::FromInt(LESS);
   7618   return Smi::FromInt(GREATER);
   7619 }
   7620 
   7621 
   7622 // Compare two Smis as if they were converted to strings and then
   7623 // compared lexicographically.
   7624 RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
   7625   SealHandleScope shs(isolate);
   7626   DCHECK(args.length() == 2);
   7627   CONVERT_SMI_ARG_CHECKED(x_value, 0);
   7628   CONVERT_SMI_ARG_CHECKED(y_value, 1);
   7629 
   7630   // If the integers are equal so are the string representations.
   7631   if (x_value == y_value) return Smi::FromInt(EQUAL);
   7632 
   7633   // If one of the integers is zero the normal integer order is the
   7634   // same as the lexicographic order of the string representations.
   7635   if (x_value == 0 || y_value == 0)
   7636     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
   7637 
   7638   // If only one of the integers is negative the negative number is
   7639   // smallest because the char code of '-' is less than the char code
   7640   // of any digit.  Otherwise, we make both values positive.
   7641 
   7642   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
   7643   // architectures using 32-bit Smis.
   7644   uint32_t x_scaled = x_value;
   7645   uint32_t y_scaled = y_value;
   7646   if (x_value < 0 || y_value < 0) {
   7647     if (y_value >= 0) return Smi::FromInt(LESS);
   7648     if (x_value >= 0) return Smi::FromInt(GREATER);
   7649     x_scaled = -x_value;
   7650     y_scaled = -y_value;
   7651   }
   7652 
   7653   static const uint32_t kPowersOf10[] = {
   7654     1, 10, 100, 1000, 10*1000, 100*1000,
   7655     1000*1000, 10*1000*1000, 100*1000*1000,
   7656     1000*1000*1000
   7657   };
   7658 
   7659   // If the integers have the same number of decimal digits they can be
   7660   // compared directly as the numeric order is the same as the
   7661   // lexicographic order.  If one integer has fewer digits, it is scaled
   7662   // by some power of 10 to have the same number of digits as the longer
   7663   // integer.  If the scaled integers are equal it means the shorter
   7664   // integer comes first in the lexicographic order.
   7665 
   7666   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
   7667   int x_log2 = IntegerLog2(x_scaled);
   7668   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
   7669   x_log10 -= x_scaled < kPowersOf10[x_log10];
   7670 
   7671   int y_log2 = IntegerLog2(y_scaled);
   7672   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
   7673   y_log10 -= y_scaled < kPowersOf10[y_log10];
   7674 
   7675   int tie = EQUAL;
   7676 
   7677   if (x_log10 < y_log10) {
   7678     // X has fewer digits.  We would like to simply scale up X but that
   7679     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
   7680     // be scaled up to 9_000_000_000. So we scale up by the next
   7681     // smallest power and scale down Y to drop one digit. It is OK to
   7682     // drop one digit from the longer integer since the final digit is
   7683     // past the length of the shorter integer.
   7684     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
   7685     y_scaled /= 10;
   7686     tie = LESS;
   7687   } else if (y_log10 < x_log10) {
   7688     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
   7689     x_scaled /= 10;
   7690     tie = GREATER;
   7691   }
   7692 
   7693   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
   7694   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
   7695   return Smi::FromInt(tie);
   7696 }
   7697 
   7698 
   7699 RUNTIME_FUNCTION(Runtime_StringCompare) {
   7700   HandleScope handle_scope(isolate);
   7701   DCHECK(args.length() == 2);
   7702 
   7703   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
   7704   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
   7705 
   7706   isolate->counters()->string_compare_runtime()->Increment();
   7707 
   7708   // A few fast case tests before we flatten.
   7709   if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
   7710   if (y->length() == 0) {
   7711     if (x->length() == 0) return Smi::FromInt(EQUAL);
   7712     return Smi::FromInt(GREATER);
   7713   } else if (x->length() == 0) {
   7714     return Smi::FromInt(LESS);
   7715   }
   7716 
   7717   int d = x->Get(0) - y->Get(0);
   7718   if (d < 0) return Smi::FromInt(LESS);
   7719   else if (d > 0) return Smi::FromInt(GREATER);
   7720 
   7721   // Slow case.
   7722   x = String::Flatten(x);
   7723   y = String::Flatten(y);
   7724 
   7725   DisallowHeapAllocation no_gc;
   7726   Object* equal_prefix_result = Smi::FromInt(EQUAL);
   7727   int prefix_length = x->length();
   7728   if (y->length() < prefix_length) {
   7729     prefix_length = y->length();
   7730     equal_prefix_result = Smi::FromInt(GREATER);
   7731   } else if (y->length() > prefix_length) {
   7732     equal_prefix_result = Smi::FromInt(LESS);
   7733   }
   7734   int r;
   7735   String::FlatContent x_content = x->GetFlatContent();
   7736   String::FlatContent y_content = y->GetFlatContent();
   7737   if (x_content.IsOneByte()) {
   7738     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   7739     if (y_content.IsOneByte()) {
   7740       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7741       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7742     } else {
   7743       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7744       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7745     }
   7746   } else {
   7747     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   7748     if (y_content.IsOneByte()) {
   7749       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7750       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7751     } else {
   7752       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7753       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7754     }
   7755   }
   7756   Object* result;
   7757   if (r == 0) {
   7758     result = equal_prefix_result;
   7759   } else {
   7760     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
   7761   }
   7762   return result;
   7763 }
   7764 
   7765 
   7766 #define RUNTIME_UNARY_MATH(Name, name)                                         \
   7767 RUNTIME_FUNCTION(Runtime_Math##Name) {                           \
   7768   HandleScope scope(isolate);                                                  \
   7769   DCHECK(args.length() == 1);                                                  \
   7770   isolate->counters()->math_##name()->Increment();                             \
   7771   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
   7772   return *isolate->factory()->NewHeapNumber(std::name(x));                     \
   7773 }
   7774 
   7775 RUNTIME_UNARY_MATH(Acos, acos)
   7776 RUNTIME_UNARY_MATH(Asin, asin)
   7777 RUNTIME_UNARY_MATH(Atan, atan)
   7778 RUNTIME_UNARY_MATH(LogRT, log)
   7779 #undef RUNTIME_UNARY_MATH
   7780 
   7781 
   7782 RUNTIME_FUNCTION(Runtime_DoubleHi) {
   7783   HandleScope scope(isolate);
   7784   DCHECK(args.length() == 1);
   7785   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7786   uint64_t integer = double_to_uint64(x);
   7787   integer = (integer >> 32) & 0xFFFFFFFFu;
   7788   return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
   7789 }
   7790 
   7791 
   7792 RUNTIME_FUNCTION(Runtime_DoubleLo) {
   7793   HandleScope scope(isolate);
   7794   DCHECK(args.length() == 1);
   7795   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7796   return *isolate->factory()->NewNumber(
   7797       static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
   7798 }
   7799 
   7800 
   7801 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
   7802   HandleScope scope(isolate);
   7803   DCHECK(args.length() == 2);
   7804   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
   7805   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
   7806   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
   7807   return *isolate->factory()->NewNumber(uint64_to_double(result));
   7808 }
   7809 
   7810 
   7811 RUNTIME_FUNCTION(Runtime_RemPiO2) {
   7812   HandleScope handle_scope(isolate);
   7813   DCHECK(args.length() == 1);
   7814   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7815   Factory* factory = isolate->factory();
   7816   double y[2] = {0.0, 0.0};
   7817   int n = fdlibm::rempio2(x, y);
   7818   Handle<FixedArray> array = factory->NewFixedArray(3);
   7819   Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
   7820   Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
   7821   array->set(0, Smi::FromInt(n));
   7822   array->set(1, *y0);
   7823   array->set(2, *y1);
   7824   return *factory->NewJSArrayWithElements(array);
   7825 }
   7826 
   7827 
   7828 static const double kPiDividedBy4 = 0.78539816339744830962;
   7829 
   7830 
   7831 RUNTIME_FUNCTION(Runtime_MathAtan2) {
   7832   HandleScope scope(isolate);
   7833   DCHECK(args.length() == 2);
   7834   isolate->counters()->math_atan2()->Increment();
   7835 
   7836   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7837   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7838   double result;
   7839   if (std::isinf(x) && std::isinf(y)) {
   7840     // Make sure that the result in case of two infinite arguments
   7841     // is a multiple of Pi / 4. The sign of the result is determined
   7842     // by the first argument (x) and the sign of the second argument
   7843     // determines the multiplier: one or three.
   7844     int multiplier = (x < 0) ? -1 : 1;
   7845     if (y < 0) multiplier *= 3;
   7846     result = multiplier * kPiDividedBy4;
   7847   } else {
   7848     result = std::atan2(x, y);
   7849   }
   7850   return *isolate->factory()->NewNumber(result);
   7851 }
   7852 
   7853 
   7854 RUNTIME_FUNCTION(Runtime_MathExpRT) {
   7855   HandleScope scope(isolate);
   7856   DCHECK(args.length() == 1);
   7857   isolate->counters()->math_exp()->Increment();
   7858 
   7859   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7860   lazily_initialize_fast_exp();
   7861   return *isolate->factory()->NewNumber(fast_exp(x));
   7862 }
   7863 
   7864 
   7865 RUNTIME_FUNCTION(Runtime_MathFloorRT) {
   7866   HandleScope scope(isolate);
   7867   DCHECK(args.length() == 1);
   7868   isolate->counters()->math_floor()->Increment();
   7869 
   7870   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7871   return *isolate->factory()->NewNumber(Floor(x));
   7872 }
   7873 
   7874 
   7875 // Slow version of Math.pow.  We check for fast paths for special cases.
   7876 // Used if VFP3 is not available.
   7877 RUNTIME_FUNCTION(Runtime_MathPowSlow) {
   7878   HandleScope scope(isolate);
   7879   DCHECK(args.length() == 2);
   7880   isolate->counters()->math_pow()->Increment();
   7881 
   7882   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7883 
   7884   // If the second argument is a smi, it is much faster to call the
   7885   // custom powi() function than the generic pow().
   7886   if (args[1]->IsSmi()) {
   7887     int y = args.smi_at(1);
   7888     return *isolate->factory()->NewNumber(power_double_int(x, y));
   7889   }
   7890 
   7891   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7892   double result = power_helper(x, y);
   7893   if (std::isnan(result)) return isolate->heap()->nan_value();
   7894   return *isolate->factory()->NewNumber(result);
   7895 }
   7896 
   7897 
   7898 // Fast version of Math.pow if we know that y is not an integer and y is not
   7899 // -0.5 or 0.5.  Used as slow case from full codegen.
   7900 RUNTIME_FUNCTION(Runtime_MathPowRT) {
   7901   HandleScope scope(isolate);
   7902   DCHECK(args.length() == 2);
   7903   isolate->counters()->math_pow()->Increment();
   7904 
   7905   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7906   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7907   if (y == 0) {
   7908     return Smi::FromInt(1);
   7909   } else {
   7910     double result = power_double_double(x, y);
   7911     if (std::isnan(result)) return isolate->heap()->nan_value();
   7912     return *isolate->factory()->NewNumber(result);
   7913   }
   7914 }
   7915 
   7916 
   7917 RUNTIME_FUNCTION(Runtime_RoundNumber) {
   7918   HandleScope scope(isolate);
   7919   DCHECK(args.length() == 1);
   7920   CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
   7921   isolate->counters()->math_round()->Increment();
   7922 
   7923   if (!input->IsHeapNumber()) {
   7924     DCHECK(input->IsSmi());
   7925     return *input;
   7926   }
   7927 
   7928   Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
   7929 
   7930   double value = number->value();
   7931   int exponent = number->get_exponent();
   7932   int sign = number->get_sign();
   7933 
   7934   if (exponent < -1) {
   7935     // Number in range ]-0.5..0.5[. These always round to +/-zero.
   7936     if (sign) return isolate->heap()->minus_zero_value();
   7937     return Smi::FromInt(0);
   7938   }
   7939 
   7940   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
   7941   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
   7942   // argument holds for 32-bit smis).
   7943   if (!sign && exponent < kSmiValueSize - 2) {
   7944     return Smi::FromInt(static_cast<int>(value + 0.5));
   7945   }
   7946 
   7947   // If the magnitude is big enough, there's no place for fraction part. If we
   7948   // try to add 0.5 to this number, 1.0 will be added instead.
   7949   if (exponent >= 52) {
   7950     return *number;
   7951   }
   7952 
   7953   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
   7954 
   7955   // Do not call NumberFromDouble() to avoid extra checks.
   7956   return *isolate->factory()->NewNumber(Floor(value + 0.5));
   7957 }
   7958 
   7959 
   7960 RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
   7961   HandleScope scope(isolate);
   7962   DCHECK(args.length() == 1);
   7963   isolate->counters()->math_sqrt()->Increment();
   7964 
   7965   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7966   return *isolate->factory()->NewNumber(fast_sqrt(x));
   7967 }
   7968 
   7969 
   7970 RUNTIME_FUNCTION(Runtime_MathFround) {
   7971   HandleScope scope(isolate);
   7972   DCHECK(args.length() == 1);
   7973 
   7974   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7975   float xf = DoubleToFloat32(x);
   7976   return *isolate->factory()->NewNumber(xf);
   7977 }
   7978 
   7979 
   7980 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
   7981   SealHandleScope shs(isolate);
   7982   DCHECK(args.length() == 2);
   7983 
   7984   CONVERT_SMI_ARG_CHECKED(year, 0);
   7985   CONVERT_SMI_ARG_CHECKED(month, 1);
   7986 
   7987   int days = isolate->date_cache()->DaysFromYearMonth(year, month);
   7988   RUNTIME_ASSERT(Smi::IsValid(days));
   7989   return Smi::FromInt(days);
   7990 }
   7991 
   7992 
   7993 RUNTIME_FUNCTION(Runtime_DateSetValue) {
   7994   HandleScope scope(isolate);
   7995   DCHECK(args.length() == 3);
   7996 
   7997   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
   7998   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
   7999   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
   8000 
   8001   DateCache* date_cache = isolate->date_cache();
   8002 
   8003   Handle<Object> value;;
   8004   bool is_value_nan = false;
   8005   if (std::isnan(time)) {
   8006     value = isolate->factory()->nan_value();
   8007     is_value_nan = true;
   8008   } else if (!is_utc &&
   8009              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
   8010               time > DateCache::kMaxTimeBeforeUTCInMs)) {
   8011     value = isolate->factory()->nan_value();
   8012     is_value_nan = true;
   8013   } else {
   8014     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
   8015     if (time < -DateCache::kMaxTimeInMs ||
   8016         time > DateCache::kMaxTimeInMs) {
   8017       value = isolate->factory()->nan_value();
   8018       is_value_nan = true;
   8019     } else  {
   8020       value = isolate->factory()->NewNumber(DoubleToInteger(time));
   8021     }
   8022   }
   8023   date->SetValue(*value, is_value_nan);
   8024   return *value;
   8025 }
   8026 
   8027 
   8028 static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
   8029                                            Handle<JSFunction> callee,
   8030                                            Object** parameters,
   8031                                            int argument_count) {
   8032   Handle<JSObject> result =
   8033       isolate->factory()->NewArgumentsObject(callee, argument_count);
   8034 
   8035   // Allocate the elements if needed.
   8036   int parameter_count = callee->shared()->formal_parameter_count();
   8037   if (argument_count > 0) {
   8038     if (parameter_count > 0) {
   8039       int mapped_count = Min(argument_count, parameter_count);
   8040       Handle<FixedArray> parameter_map =
   8041           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
   8042       parameter_map->set_map(
   8043           isolate->heap()->sloppy_arguments_elements_map());
   8044 
   8045       Handle<Map> map = Map::Copy(handle(result->map()));
   8046       map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
   8047 
   8048       result->set_map(*map);
   8049       result->set_elements(*parameter_map);
   8050 
   8051       // Store the context and the arguments array at the beginning of the
   8052       // parameter map.
   8053       Handle<Context> context(isolate->context());
   8054       Handle<FixedArray> arguments =
   8055           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   8056       parameter_map->set(0, *context);
   8057       parameter_map->set(1, *arguments);
   8058 
   8059       // Loop over the actual parameters backwards.
   8060       int index = argument_count - 1;
   8061       while (index >= mapped_count) {
   8062         // These go directly in the arguments array and have no
   8063         // corresponding slot in the parameter map.
   8064         arguments->set(index, *(parameters - index - 1));
   8065         --index;
   8066       }
   8067 
   8068       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
   8069       while (index >= 0) {
   8070         // Detect duplicate names to the right in the parameter list.
   8071         Handle<String> name(scope_info->ParameterName(index));
   8072         int context_local_count = scope_info->ContextLocalCount();
   8073         bool duplicate = false;
   8074         for (int j = index + 1; j < parameter_count; ++j) {
   8075           if (scope_info->ParameterName(j) == *name) {
   8076             duplicate = true;
   8077             break;
   8078           }
   8079         }
   8080 
   8081         if (duplicate) {
   8082           // This goes directly in the arguments array with a hole in the
   8083           // parameter map.
   8084           arguments->set(index, *(parameters - index - 1));
   8085           parameter_map->set_the_hole(index + 2);
   8086         } else {
   8087           // The context index goes in the parameter map with a hole in the
   8088           // arguments array.
   8089           int context_index = -1;
   8090           for (int j = 0; j < context_local_count; ++j) {
   8091             if (scope_info->ContextLocalName(j) == *name) {
   8092               context_index = j;
   8093               break;
   8094             }
   8095           }
   8096           DCHECK(context_index >= 0);
   8097           arguments->set_the_hole(index);
   8098           parameter_map->set(index + 2, Smi::FromInt(
   8099               Context::MIN_CONTEXT_SLOTS + context_index));
   8100         }
   8101 
   8102         --index;
   8103       }
   8104     } else {
   8105       // If there is no aliasing, the arguments object elements are not
   8106       // special in any way.
   8107       Handle<FixedArray> elements =
   8108           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   8109       result->set_elements(*elements);
   8110       for (int i = 0; i < argument_count; ++i) {
   8111         elements->set(i, *(parameters - i - 1));
   8112       }
   8113     }
   8114   }
   8115   return result;
   8116 }
   8117 
   8118 
   8119 static Handle<JSObject> NewStrictArguments(Isolate* isolate,
   8120                                            Handle<JSFunction> callee,
   8121                                            Object** parameters,
   8122                                            int argument_count) {
   8123   Handle<JSObject> result =
   8124       isolate->factory()->NewArgumentsObject(callee, argument_count);
   8125 
   8126   if (argument_count > 0) {
   8127     Handle<FixedArray> array =
   8128         isolate->factory()->NewUninitializedFixedArray(argument_count);
   8129     DisallowHeapAllocation no_gc;
   8130     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   8131     for (int i = 0; i < argument_count; i++) {
   8132       array->set(i, *--parameters, mode);
   8133     }
   8134     result->set_elements(*array);
   8135   }
   8136   return result;
   8137 }
   8138 
   8139 
   8140 RUNTIME_FUNCTION(Runtime_NewArguments) {
   8141   HandleScope scope(isolate);
   8142   DCHECK(args.length() == 1);
   8143   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
   8144   JavaScriptFrameIterator it(isolate);
   8145 
   8146   // Find the frame that holds the actual arguments passed to the function.
   8147   it.AdvanceToArgumentsFrame();
   8148   JavaScriptFrame* frame = it.frame();
   8149 
   8150   // Determine parameter location on the stack and dispatch on language mode.
   8151   int argument_count = frame->GetArgumentsLength();
   8152   Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
   8153   return callee->shared()->strict_mode() == STRICT
   8154              ? *NewStrictArguments(isolate, callee, parameters, argument_count)
   8155              : *NewSloppyArguments(isolate, callee, parameters, argument_count);
   8156 }
   8157 
   8158 
   8159 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
   8160   HandleScope scope(isolate);
   8161   DCHECK(args.length() == 3);
   8162   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
   8163   Object** parameters = reinterpret_cast<Object**>(args[1]);
   8164   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
   8165   return *NewSloppyArguments(isolate, callee, parameters, argument_count);
   8166 }
   8167 
   8168 
   8169 RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
   8170   HandleScope scope(isolate);
   8171   DCHECK(args.length() == 3);
   8172   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
   8173   Object** parameters = reinterpret_cast<Object**>(args[1]);
   8174   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
   8175   return *NewStrictArguments(isolate, callee, parameters, argument_count);
   8176 }
   8177 
   8178 
   8179 RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) {
   8180   HandleScope scope(isolate);
   8181   DCHECK(args.length() == 1);
   8182   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
   8183   Handle<Context> context(isolate->context());
   8184   PretenureFlag pretenure_flag = NOT_TENURED;
   8185   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
   8186                                                                 pretenure_flag);
   8187 }
   8188 
   8189 
   8190 RUNTIME_FUNCTION(Runtime_NewClosure) {
   8191   HandleScope scope(isolate);
   8192   DCHECK(args.length() == 3);
   8193   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   8194   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
   8195   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
   8196 
   8197   // The caller ensures that we pretenure closures that are assigned
   8198   // directly to properties.
   8199   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   8200   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
   8201       shared, context, pretenure_flag);
   8202 }
   8203 
   8204 
   8205 // Find the arguments of the JavaScript function invocation that called
   8206 // into C++ code. Collect these in a newly allocated array of handles (possibly
   8207 // prefixed by a number of empty handles).
   8208 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
   8209     Isolate* isolate,
   8210     int prefix_argc,
   8211     int* total_argc) {
   8212   // Find frame containing arguments passed to the caller.
   8213   JavaScriptFrameIterator it(isolate);
   8214   JavaScriptFrame* frame = it.frame();
   8215   List<JSFunction*> functions(2);
   8216   frame->GetFunctions(&functions);
   8217   if (functions.length() > 1) {
   8218     int inlined_jsframe_index = functions.length() - 1;
   8219     JSFunction* inlined_function = functions[inlined_jsframe_index];
   8220     SlotRefValueBuilder slot_refs(
   8221         frame,
   8222         inlined_jsframe_index,
   8223         inlined_function->shared()->formal_parameter_count());
   8224 
   8225     int args_count = slot_refs.args_length();
   8226 
   8227     *total_argc = prefix_argc + args_count;
   8228     SmartArrayPointer<Handle<Object> > param_data(
   8229         NewArray<Handle<Object> >(*total_argc));
   8230     slot_refs.Prepare(isolate);
   8231     for (int i = 0; i < args_count; i++) {
   8232       Handle<Object> val = slot_refs.GetNext(isolate, 0);
   8233       param_data[prefix_argc + i] = val;
   8234     }
   8235     slot_refs.Finish(isolate);
   8236 
   8237     return param_data;
   8238   } else {
   8239     it.AdvanceToArgumentsFrame();
   8240     frame = it.frame();
   8241     int args_count = frame->ComputeParametersCount();
   8242 
   8243     *total_argc = prefix_argc + args_count;
   8244     SmartArrayPointer<Handle<Object> > param_data(
   8245         NewArray<Handle<Object> >(*total_argc));
   8246     for (int i = 0; i < args_count; i++) {
   8247       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
   8248       param_data[prefix_argc + i] = val;
   8249     }
   8250     return param_data;
   8251   }
   8252 }
   8253 
   8254 
   8255 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
   8256   HandleScope scope(isolate);
   8257   DCHECK(args.length() == 4);
   8258   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
   8259   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
   8260   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
   8261   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
   8262 
   8263   // TODO(lrn): Create bound function in C++ code from premade shared info.
   8264   bound_function->shared()->set_bound(true);
   8265   // Get all arguments of calling function (Function.prototype.bind).
   8266   int argc = 0;
   8267   SmartArrayPointer<Handle<Object> > arguments =
   8268       GetCallerArguments(isolate, 0, &argc);
   8269   // Don't count the this-arg.
   8270   if (argc > 0) {
   8271     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
   8272     argc--;
   8273   } else {
   8274     RUNTIME_ASSERT(this_object->IsUndefined());
   8275   }
   8276   // Initialize array of bindings (function, this, and any existing arguments
   8277   // if the function was already bound).
   8278   Handle<FixedArray> new_bindings;
   8279   int i;
   8280   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
   8281     Handle<FixedArray> old_bindings(
   8282         JSFunction::cast(*bindee)->function_bindings());
   8283     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
   8284     new_bindings =
   8285         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
   8286     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
   8287                             isolate);
   8288     i = 0;
   8289     for (int n = old_bindings->length(); i < n; i++) {
   8290       new_bindings->set(i, old_bindings->get(i));
   8291     }
   8292   } else {
   8293     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
   8294     new_bindings = isolate->factory()->NewFixedArray(array_size);
   8295     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
   8296     new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
   8297     i = 2;
   8298   }
   8299   // Copy arguments, skipping the first which is "this_arg".
   8300   for (int j = 0; j < argc; j++, i++) {
   8301     new_bindings->set(i, *arguments[j + 1]);
   8302   }
   8303   new_bindings->set_map_no_write_barrier(
   8304       isolate->heap()->fixed_cow_array_map());
   8305   bound_function->set_function_bindings(*new_bindings);
   8306 
   8307   // Update length. Have to remove the prototype first so that map migration
   8308   // is happy about the number of fields.
   8309   RUNTIME_ASSERT(bound_function->RemovePrototype());
   8310   Handle<Map> bound_function_map(
   8311       isolate->native_context()->bound_function_map());
   8312   JSObject::MigrateToMap(bound_function, bound_function_map);
   8313   Handle<String> length_string = isolate->factory()->length_string();
   8314   PropertyAttributes attr =
   8315       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
   8316   RETURN_FAILURE_ON_EXCEPTION(
   8317       isolate,
   8318       JSObject::SetOwnPropertyIgnoreAttributes(
   8319           bound_function, length_string, new_length, attr));
   8320   return *bound_function;
   8321 }
   8322 
   8323 
   8324 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
   8325   HandleScope handles(isolate);
   8326   DCHECK(args.length() == 1);
   8327   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
   8328   if (callable->IsJSFunction()) {
   8329     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
   8330     if (function->shared()->bound()) {
   8331       Handle<FixedArray> bindings(function->function_bindings());
   8332       RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
   8333       return *isolate->factory()->NewJSArrayWithElements(bindings);
   8334     }
   8335   }
   8336   return isolate->heap()->undefined_value();
   8337 }
   8338 
   8339 
   8340 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
   8341   HandleScope scope(isolate);
   8342   DCHECK(args.length() == 1);
   8343   // First argument is a function to use as a constructor.
   8344   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8345   RUNTIME_ASSERT(function->shared()->bound());
   8346 
   8347   // The argument is a bound function. Extract its bound arguments
   8348   // and callable.
   8349   Handle<FixedArray> bound_args =
   8350       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
   8351   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
   8352   Handle<Object> bound_function(
   8353       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
   8354       isolate);
   8355   DCHECK(!bound_function->IsJSFunction() ||
   8356          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
   8357 
   8358   int total_argc = 0;
   8359   SmartArrayPointer<Handle<Object> > param_data =
   8360       GetCallerArguments(isolate, bound_argc, &total_argc);
   8361   for (int i = 0; i < bound_argc; i++) {
   8362     param_data[i] = Handle<Object>(bound_args->get(
   8363         JSFunction::kBoundArgumentsStartIndex + i), isolate);
   8364   }
   8365 
   8366   if (!bound_function->IsJSFunction()) {
   8367     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8368         isolate, bound_function,
   8369         Execution::TryGetConstructorDelegate(isolate, bound_function));
   8370   }
   8371   DCHECK(bound_function->IsJSFunction());
   8372 
   8373   Handle<Object> result;
   8374   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8375       isolate, result,
   8376       Execution::New(Handle<JSFunction>::cast(bound_function),
   8377                      total_argc, param_data.get()));
   8378   return *result;
   8379 }
   8380 
   8381 
   8382 static Object* Runtime_NewObjectHelper(Isolate* isolate,
   8383                                             Handle<Object> constructor,
   8384                                             Handle<AllocationSite> site) {
   8385   // If the constructor isn't a proper function we throw a type error.
   8386   if (!constructor->IsJSFunction()) {
   8387     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8388     THROW_NEW_ERROR_RETURN_FAILURE(isolate,
   8389                                    NewTypeError("not_constructor", arguments));
   8390   }
   8391 
   8392   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
   8393 
   8394   // If function should not have prototype, construction is not allowed. In this
   8395   // case generated code bailouts here, since function has no initial_map.
   8396   if (!function->should_have_prototype() && !function->shared()->bound()) {
   8397     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8398     THROW_NEW_ERROR_RETURN_FAILURE(isolate,
   8399                                    NewTypeError("not_constructor", arguments));
   8400   }
   8401 
   8402   Debug* debug = isolate->debug();
   8403   // Handle stepping into constructors if step into is active.
   8404   if (debug->StepInActive()) {
   8405     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
   8406   }
   8407 
   8408   if (function->has_initial_map()) {
   8409     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
   8410       // The 'Function' function ignores the receiver object when
   8411       // called using 'new' and creates a new JSFunction object that
   8412       // is returned.  The receiver object is only used for error
   8413       // reporting if an error occurs when constructing the new
   8414       // JSFunction. Factory::NewJSObject() should not be used to
   8415       // allocate JSFunctions since it does not properly initialize
   8416       // the shared part of the function. Since the receiver is
   8417       // ignored anyway, we use the global object as the receiver
   8418       // instead of a new JSFunction object. This way, errors are
   8419       // reported the same way whether or not 'Function' is called
   8420       // using 'new'.
   8421       return isolate->global_proxy();
   8422     }
   8423   }
   8424 
   8425   // The function should be compiled for the optimization hints to be
   8426   // available.
   8427   Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
   8428 
   8429   Handle<JSObject> result;
   8430   if (site.is_null()) {
   8431     result = isolate->factory()->NewJSObject(function);
   8432   } else {
   8433     result = isolate->factory()->NewJSObjectWithMemento(function, site);
   8434   }
   8435 
   8436   isolate->counters()->constructed_objects()->Increment();
   8437   isolate->counters()->constructed_objects_runtime()->Increment();
   8438 
   8439   return *result;
   8440 }
   8441 
   8442 
   8443 RUNTIME_FUNCTION(Runtime_NewObject) {
   8444   HandleScope scope(isolate);
   8445   DCHECK(args.length() == 1);
   8446   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
   8447   return Runtime_NewObjectHelper(isolate,
   8448                                  constructor,
   8449                                  Handle<AllocationSite>::null());
   8450 }
   8451 
   8452 
   8453 RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
   8454   HandleScope scope(isolate);
   8455   DCHECK(args.length() == 2);
   8456   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
   8457   CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
   8458   Handle<AllocationSite> site;
   8459   if (feedback->IsAllocationSite()) {
   8460     // The feedback can be an AllocationSite or undefined.
   8461     site = Handle<AllocationSite>::cast(feedback);
   8462   }
   8463   return Runtime_NewObjectHelper(isolate, constructor, site);
   8464 }
   8465 
   8466 
   8467 RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
   8468   HandleScope scope(isolate);
   8469   DCHECK(args.length() == 1);
   8470 
   8471   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8472   function->CompleteInobjectSlackTracking();
   8473 
   8474   return isolate->heap()->undefined_value();
   8475 }
   8476 
   8477 
   8478 RUNTIME_FUNCTION(Runtime_CompileLazy) {
   8479   HandleScope scope(isolate);
   8480   DCHECK(args.length() == 1);
   8481   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8482 #ifdef DEBUG
   8483   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
   8484     PrintF("[unoptimized: ");
   8485     function->PrintName();
   8486     PrintF("]\n");
   8487   }
   8488 #endif
   8489 
   8490   // Compile the target function.
   8491   DCHECK(function->shared()->allows_lazy_compilation());
   8492 
   8493   Handle<Code> code;
   8494   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
   8495                                      Compiler::GetLazyCode(function));
   8496   DCHECK(code->kind() == Code::FUNCTION ||
   8497          code->kind() == Code::OPTIMIZED_FUNCTION);
   8498   function->ReplaceCode(*code);
   8499   return *code;
   8500 }
   8501 
   8502 
   8503 RUNTIME_FUNCTION(Runtime_CompileOptimized) {
   8504   HandleScope scope(isolate);
   8505   DCHECK(args.length() == 2);
   8506   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8507   CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
   8508 
   8509   Handle<Code> unoptimized(function->shared()->code());
   8510   if (!isolate->use_crankshaft() ||
   8511       function->shared()->optimization_disabled() ||
   8512       isolate->DebuggerHasBreakPoints()) {
   8513     // If the function is not optimizable or debugger is active continue
   8514     // using the code from the full compiler.
   8515     if (FLAG_trace_opt) {
   8516       PrintF("[failed to optimize ");
   8517       function->PrintName();
   8518       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
   8519           function->shared()->optimization_disabled() ? "F" : "T",
   8520           isolate->DebuggerHasBreakPoints() ? "T" : "F");
   8521     }
   8522     function->ReplaceCode(*unoptimized);
   8523     return function->code();
   8524   }
   8525 
   8526   Compiler::ConcurrencyMode mode =
   8527       concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
   8528   Handle<Code> code;
   8529   if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
   8530     function->ReplaceCode(*code);
   8531   } else {
   8532     function->ReplaceCode(function->shared()->code());
   8533   }
   8534 
   8535   DCHECK(function->code()->kind() == Code::FUNCTION ||
   8536          function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
   8537          function->IsInOptimizationQueue());
   8538   return function->code();
   8539 }
   8540 
   8541 
   8542 class ActivationsFinder : public ThreadVisitor {
   8543  public:
   8544   Code* code_;
   8545   bool has_code_activations_;
   8546 
   8547   explicit ActivationsFinder(Code* code)
   8548     : code_(code),
   8549       has_code_activations_(false) { }
   8550 
   8551   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
   8552     JavaScriptFrameIterator it(isolate, top);
   8553     VisitFrames(&it);
   8554   }
   8555 
   8556   void VisitFrames(JavaScriptFrameIterator* it) {
   8557     for (; !it->done(); it->Advance()) {
   8558       JavaScriptFrame* frame = it->frame();
   8559       if (code_->contains(frame->pc())) has_code_activations_ = true;
   8560     }
   8561   }
   8562 };
   8563 
   8564 
   8565 RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
   8566   HandleScope scope(isolate);
   8567   DCHECK(args.length() == 0);
   8568   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8569   DCHECK(AllowHeapAllocation::IsAllowed());
   8570   delete deoptimizer;
   8571   return isolate->heap()->undefined_value();
   8572 }
   8573 
   8574 
   8575 RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
   8576   HandleScope scope(isolate);
   8577   DCHECK(args.length() == 1);
   8578   CONVERT_SMI_ARG_CHECKED(type_arg, 0);
   8579   Deoptimizer::BailoutType type =
   8580       static_cast<Deoptimizer::BailoutType>(type_arg);
   8581   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8582   DCHECK(AllowHeapAllocation::IsAllowed());
   8583 
   8584   Handle<JSFunction> function = deoptimizer->function();
   8585   Handle<Code> optimized_code = deoptimizer->compiled_code();
   8586 
   8587   DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
   8588   DCHECK(type == deoptimizer->bailout_type());
   8589 
   8590   // Make sure to materialize objects before causing any allocation.
   8591   JavaScriptFrameIterator it(isolate);
   8592   deoptimizer->MaterializeHeapObjects(&it);
   8593   delete deoptimizer;
   8594 
   8595   JavaScriptFrame* frame = it.frame();
   8596   RUNTIME_ASSERT(frame->function()->IsJSFunction());
   8597   DCHECK(frame->function() == *function);
   8598 
   8599   // Avoid doing too much work when running with --always-opt and keep
   8600   // the optimized code around.
   8601   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
   8602     return isolate->heap()->undefined_value();
   8603   }
   8604 
   8605   // Search for other activations of the same function and code.
   8606   ActivationsFinder activations_finder(*optimized_code);
   8607   activations_finder.VisitFrames(&it);
   8608   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
   8609 
   8610   if (!activations_finder.has_code_activations_) {
   8611     if (function->code() == *optimized_code) {
   8612       if (FLAG_trace_deopt) {
   8613         PrintF("[removing optimized code for: ");
   8614         function->PrintName();
   8615         PrintF("]\n");
   8616       }
   8617       function->ReplaceCode(function->shared()->code());
   8618       // Evict optimized code for this function from the cache so that it
   8619       // doesn't get used for new closures.
   8620       function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
   8621                                                     "notify deoptimized");
   8622     }
   8623   } else {
   8624     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
   8625     // unconditionally if the code is not already marked for deoptimization.
   8626     // If there is an index by shared function info, all the better.
   8627     Deoptimizer::DeoptimizeFunction(*function);
   8628   }
   8629 
   8630   return isolate->heap()->undefined_value();
   8631 }
   8632 
   8633 
   8634 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
   8635   HandleScope scope(isolate);
   8636   DCHECK(args.length() == 1);
   8637   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8638   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
   8639 
   8640   // TODO(turbofan): Deoptimization is not supported yet.
   8641   if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
   8642     return isolate->heap()->undefined_value();
   8643   }
   8644 
   8645   Deoptimizer::DeoptimizeFunction(*function);
   8646 
   8647   return isolate->heap()->undefined_value();
   8648 }
   8649 
   8650 
   8651 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
   8652   HandleScope scope(isolate);
   8653   DCHECK(args.length() == 1);
   8654   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8655   function->shared()->ClearTypeFeedbackInfo();
   8656   Code* unoptimized = function->shared()->code();
   8657   if (unoptimized->kind() == Code::FUNCTION) {
   8658     unoptimized->ClearInlineCaches();
   8659   }
   8660   return isolate->heap()->undefined_value();
   8661 }
   8662 
   8663 
   8664 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
   8665   SealHandleScope shs(isolate);
   8666   DCHECK(args.length() == 0);
   8667 #if defined(USE_SIMULATOR)
   8668   return isolate->heap()->true_value();
   8669 #else
   8670   return isolate->heap()->false_value();
   8671 #endif
   8672 }
   8673 
   8674 
   8675 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
   8676   SealHandleScope shs(isolate);
   8677   DCHECK(args.length() == 0);
   8678   return isolate->heap()->ToBoolean(
   8679       isolate->concurrent_recompilation_enabled());
   8680 }
   8681 
   8682 
   8683 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
   8684   HandleScope scope(isolate);
   8685   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8686   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8687   // The following two assertions are lifted from the DCHECKs inside
   8688   // JSFunction::MarkForOptimization().
   8689   RUNTIME_ASSERT(!function->shared()->is_generator());
   8690   RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
   8691                  (function->code()->kind() == Code::FUNCTION &&
   8692                   function->code()->optimizable()));
   8693 
   8694   // If the function is optimized, just return.
   8695   if (function->IsOptimized()) return isolate->heap()->undefined_value();
   8696 
   8697   function->MarkForOptimization();
   8698 
   8699   Code* unoptimized = function->shared()->code();
   8700   if (args.length() == 2 &&
   8701       unoptimized->kind() == Code::FUNCTION) {
   8702     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   8703     if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
   8704       // Start patching from the currently patched loop nesting level.
   8705       DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
   8706       isolate->runtime_profiler()->AttemptOnStackReplacement(
   8707           *function, Code::kMaxLoopNestingMarker);
   8708     } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
   8709                isolate->concurrent_recompilation_enabled()) {
   8710       function->MarkForConcurrentOptimization();
   8711     }
   8712   }
   8713 
   8714   return isolate->heap()->undefined_value();
   8715 }
   8716 
   8717 
   8718 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
   8719   HandleScope scope(isolate);
   8720   DCHECK(args.length() == 1);
   8721   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8722   function->shared()->set_optimization_disabled(true);
   8723   return isolate->heap()->undefined_value();
   8724 }
   8725 
   8726 
   8727 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
   8728   HandleScope scope(isolate);
   8729   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8730   if (!isolate->use_crankshaft()) {
   8731     return Smi::FromInt(4);  // 4 == "never".
   8732   }
   8733   bool sync_with_compiler_thread = true;
   8734   if (args.length() == 2) {
   8735     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
   8736     if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
   8737       sync_with_compiler_thread = false;
   8738     }
   8739   }
   8740   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8741   if (isolate->concurrent_recompilation_enabled() &&
   8742       sync_with_compiler_thread) {
   8743     while (function->IsInOptimizationQueue()) {
   8744       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   8745       base::OS::Sleep(50);
   8746     }
   8747   }
   8748   if (FLAG_always_opt) {
   8749     // We may have always opt, but that is more best-effort than a real
   8750     // promise, so we still say "no" if it is not optimized.
   8751     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
   8752                                    : Smi::FromInt(2);  // 2 == "no".
   8753   }
   8754   if (FLAG_deopt_every_n_times) {
   8755     return Smi::FromInt(6);  // 6 == "maybe deopted".
   8756   }
   8757   if (function->IsOptimized() && function->code()->is_turbofanned()) {
   8758     return Smi::FromInt(7);  // 7 == "TurboFan compiler".
   8759   }
   8760   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
   8761                                  : Smi::FromInt(2);  // 2 == "no".
   8762 }
   8763 
   8764 
   8765 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
   8766   DCHECK(args.length() == 0);
   8767   RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
   8768   RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
   8769   isolate->optimizing_compiler_thread()->Unblock();
   8770   return isolate->heap()->undefined_value();
   8771 }
   8772 
   8773 
   8774 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
   8775   HandleScope scope(isolate);
   8776   DCHECK(args.length() == 1);
   8777   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8778   return Smi::FromInt(function->shared()->opt_count());
   8779 }
   8780 
   8781 
   8782 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
   8783                                             Handle<JSFunction> function,
   8784                                             Handle<Code> current_code) {
   8785   // Keep track of whether we've succeeded in optimizing.
   8786   if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
   8787   // If we are trying to do OSR when there are already optimized
   8788   // activations of the function, it means (a) the function is directly or
   8789   // indirectly recursive and (b) an optimized invocation has been
   8790   // deoptimized so that we are currently in an unoptimized activation.
   8791   // Check for optimized activations of this function.
   8792   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
   8793     JavaScriptFrame* frame = it.frame();
   8794     if (frame->is_optimized() && frame->function() == *function) return false;
   8795   }
   8796 
   8797   return true;
   8798 }
   8799 
   8800 
   8801 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
   8802   HandleScope scope(isolate);
   8803   DCHECK(args.length() == 1);
   8804   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8805   Handle<Code> caller_code(function->shared()->code());
   8806 
   8807   // We're not prepared to handle a function with arguments object.
   8808   DCHECK(!function->shared()->uses_arguments());
   8809 
   8810   RUNTIME_ASSERT(FLAG_use_osr);
   8811 
   8812   // Passing the PC in the javascript frame from the caller directly is
   8813   // not GC safe, so we walk the stack to get it.
   8814   JavaScriptFrameIterator it(isolate);
   8815   JavaScriptFrame* frame = it.frame();
   8816   if (!caller_code->contains(frame->pc())) {
   8817     // Code on the stack may not be the code object referenced by the shared
   8818     // function info.  It may have been replaced to include deoptimization data.
   8819     caller_code = Handle<Code>(frame->LookupCode());
   8820   }
   8821 
   8822   uint32_t pc_offset = static_cast<uint32_t>(
   8823       frame->pc() - caller_code->instruction_start());
   8824 
   8825 #ifdef DEBUG
   8826   DCHECK_EQ(frame->function(), *function);
   8827   DCHECK_EQ(frame->LookupCode(), *caller_code);
   8828   DCHECK(caller_code->contains(frame->pc()));
   8829 #endif  // DEBUG
   8830 
   8831 
   8832   BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
   8833   DCHECK(!ast_id.IsNone());
   8834 
   8835   Compiler::ConcurrencyMode mode =
   8836       isolate->concurrent_osr_enabled() &&
   8837       (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT
   8838                                                    : Compiler::NOT_CONCURRENT;
   8839   Handle<Code> result = Handle<Code>::null();
   8840 
   8841   OptimizedCompileJob* job = NULL;
   8842   if (mode == Compiler::CONCURRENT) {
   8843     // Gate the OSR entry with a stack check.
   8844     BackEdgeTable::AddStackCheck(caller_code, pc_offset);
   8845     // Poll already queued compilation jobs.
   8846     OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
   8847     if (thread->IsQueuedForOSR(function, ast_id)) {
   8848       if (FLAG_trace_osr) {
   8849         PrintF("[OSR - Still waiting for queued: ");
   8850         function->PrintName();
   8851         PrintF(" at AST id %d]\n", ast_id.ToInt());
   8852       }
   8853       return NULL;
   8854     }
   8855 
   8856     job = thread->FindReadyOSRCandidate(function, ast_id);
   8857   }
   8858 
   8859   if (job != NULL) {
   8860     if (FLAG_trace_osr) {
   8861       PrintF("[OSR - Found ready: ");
   8862       function->PrintName();
   8863       PrintF(" at AST id %d]\n", ast_id.ToInt());
   8864     }
   8865     result = Compiler::GetConcurrentlyOptimizedCode(job);
   8866   } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
   8867     if (FLAG_trace_osr) {
   8868       PrintF("[OSR - Compiling: ");
   8869       function->PrintName();
   8870       PrintF(" at AST id %d]\n", ast_id.ToInt());
   8871     }
   8872     MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
   8873         function, caller_code, mode, ast_id);
   8874     if (maybe_result.ToHandle(&result) &&
   8875         result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
   8876       // Optimization is queued.  Return to check later.
   8877       return NULL;
   8878     }
   8879   }
   8880 
   8881   // Revert the patched back edge table, regardless of whether OSR succeeds.
   8882   BackEdgeTable::Revert(isolate, *caller_code);
   8883 
   8884   // Check whether we ended up with usable optimized code.
   8885   if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
   8886     DeoptimizationInputData* data =
   8887         DeoptimizationInputData::cast(result->deoptimization_data());
   8888 
   8889     if (data->OsrPcOffset()->value() >= 0) {
   8890       DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
   8891       if (FLAG_trace_osr) {
   8892         PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
   8893                ast_id.ToInt(), data->OsrPcOffset()->value());
   8894       }
   8895       // TODO(titzer): this is a massive hack to make the deopt counts
   8896       // match. Fix heuristics for reenabling optimizations!
   8897       function->shared()->increment_deopt_count();
   8898 
   8899       // TODO(titzer): Do not install code into the function.
   8900       function->ReplaceCode(*result);
   8901       return *result;
   8902     }
   8903   }
   8904 
   8905   // Failed.
   8906   if (FLAG_trace_osr) {
   8907     PrintF("[OSR - Failed: ");
   8908     function->PrintName();
   8909     PrintF(" at AST id %d]\n", ast_id.ToInt());
   8910   }
   8911 
   8912   if (!function->IsOptimized()) {
   8913     function->ReplaceCode(function->shared()->code());
   8914   }
   8915   return NULL;
   8916 }
   8917 
   8918 
   8919 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
   8920   SealHandleScope shs(isolate);
   8921   DCHECK(args.length() == 2 || args.length() == 3);
   8922 #ifdef DEBUG
   8923   CONVERT_SMI_ARG_CHECKED(interval, 0);
   8924   CONVERT_SMI_ARG_CHECKED(timeout, 1);
   8925   isolate->heap()->set_allocation_timeout(timeout);
   8926   FLAG_gc_interval = interval;
   8927   if (args.length() == 3) {
   8928     // Enable/disable inline allocation if requested.
   8929     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
   8930     if (inline_allocation) {
   8931       isolate->heap()->EnableInlineAllocation();
   8932     } else {
   8933       isolate->heap()->DisableInlineAllocation();
   8934     }
   8935   }
   8936 #endif
   8937   return isolate->heap()->undefined_value();
   8938 }
   8939 
   8940 
   8941 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
   8942   SealHandleScope shs(isolate);
   8943   DCHECK(args.length() == 0);
   8944   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8945   return isolate->heap()->undefined_value();
   8946 }
   8947 
   8948 
   8949 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
   8950   SealHandleScope shs(isolate);
   8951   DCHECK(args.length() == 0);
   8952   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8953   return isolate->heap()->nan_value();
   8954 }
   8955 
   8956 
   8957 RUNTIME_FUNCTION(Runtime_Call) {
   8958   HandleScope scope(isolate);
   8959   DCHECK(args.length() >= 2);
   8960   int argc = args.length() - 2;
   8961   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
   8962   Object* receiver = args[0];
   8963 
   8964   // If there are too many arguments, allocate argv via malloc.
   8965   const int argv_small_size = 10;
   8966   Handle<Object> argv_small_buffer[argv_small_size];
   8967   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8968   Handle<Object>* argv = argv_small_buffer;
   8969   if (argc > argv_small_size) {
   8970     argv = new Handle<Object>[argc];
   8971     if (argv == NULL) return isolate->StackOverflow();
   8972     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8973   }
   8974 
   8975   for (int i = 0; i < argc; ++i) {
   8976      argv[i] = Handle<Object>(args[1 + i], isolate);
   8977   }
   8978 
   8979   Handle<JSReceiver> hfun(fun);
   8980   Handle<Object> hreceiver(receiver, isolate);
   8981   Handle<Object> result;
   8982   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8983       isolate, result,
   8984       Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
   8985   return *result;
   8986 }
   8987 
   8988 
   8989 RUNTIME_FUNCTION(Runtime_Apply) {
   8990   HandleScope scope(isolate);
   8991   DCHECK(args.length() == 5);
   8992   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
   8993   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
   8994   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
   8995   CONVERT_INT32_ARG_CHECKED(offset, 3);
   8996   CONVERT_INT32_ARG_CHECKED(argc, 4);
   8997   RUNTIME_ASSERT(offset >= 0);
   8998   // Loose upper bound to allow fuzzing. We'll most likely run out of
   8999   // stack space before hitting this limit.
   9000   static int kMaxArgc = 1000000;
   9001   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
   9002 
   9003   // If there are too many arguments, allocate argv via malloc.
   9004   const int argv_small_size = 10;
   9005   Handle<Object> argv_small_buffer[argv_small_size];
   9006   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   9007   Handle<Object>* argv = argv_small_buffer;
   9008   if (argc > argv_small_size) {
   9009     argv = new Handle<Object>[argc];
   9010     if (argv == NULL) return isolate->StackOverflow();
   9011     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   9012   }
   9013 
   9014   for (int i = 0; i < argc; ++i) {
   9015     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9016         isolate, argv[i],
   9017         Object::GetElement(isolate, arguments, offset + i));
   9018   }
   9019 
   9020   Handle<Object> result;
   9021   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9022       isolate, result,
   9023       Execution::Call(isolate, fun, receiver, argc, argv, true));
   9024   return *result;
   9025 }
   9026 
   9027 
   9028 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
   9029   HandleScope scope(isolate);
   9030   DCHECK(args.length() == 1);
   9031   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   9032   RUNTIME_ASSERT(!object->IsJSFunction());
   9033   return *Execution::GetFunctionDelegate(isolate, object);
   9034 }
   9035 
   9036 
   9037 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
   9038   HandleScope scope(isolate);
   9039   DCHECK(args.length() == 1);
   9040   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   9041   RUNTIME_ASSERT(!object->IsJSFunction());
   9042   return *Execution::GetConstructorDelegate(isolate, object);
   9043 }
   9044 
   9045 
   9046 RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
   9047   HandleScope scope(isolate);
   9048   DCHECK(args.length() == 2);
   9049 
   9050   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   9051   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
   9052   Handle<Context> result =
   9053       isolate->factory()->NewGlobalContext(function, scope_info);
   9054 
   9055   DCHECK(function->context() == isolate->context());
   9056   DCHECK(function->context()->global_object() == result->global_object());
   9057   result->global_object()->set_global_context(*result);
   9058   return *result;
   9059 }
   9060 
   9061 
   9062 RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
   9063   HandleScope scope(isolate);
   9064   DCHECK(args.length() == 1);
   9065 
   9066   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   9067 
   9068   DCHECK(function->context() == isolate->context());
   9069   int length = function->shared()->scope_info()->ContextLength();
   9070   return *isolate->factory()->NewFunctionContext(length, function);
   9071 }
   9072 
   9073 
   9074 RUNTIME_FUNCTION(Runtime_PushWithContext) {
   9075   HandleScope scope(isolate);
   9076   DCHECK(args.length() == 2);
   9077   Handle<JSReceiver> extension_object;
   9078   if (args[0]->IsJSReceiver()) {
   9079     extension_object = args.at<JSReceiver>(0);
   9080   } else {
   9081     // Try to convert the object to a proper JavaScript object.
   9082     MaybeHandle<JSReceiver> maybe_object =
   9083         Object::ToObject(isolate, args.at<Object>(0));
   9084     if (!maybe_object.ToHandle(&extension_object)) {
   9085       Handle<Object> handle = args.at<Object>(0);
   9086       THROW_NEW_ERROR_RETURN_FAILURE(
   9087           isolate, NewTypeError("with_expression", HandleVector(&handle, 1)));
   9088     }
   9089   }
   9090 
   9091   Handle<JSFunction> function;
   9092   if (args[1]->IsSmi()) {
   9093     // A smi sentinel indicates a context nested inside global code rather
   9094     // than some function.  There is a canonical empty function that can be
   9095     // gotten from the native context.
   9096     function = handle(isolate->native_context()->closure());
   9097   } else {
   9098     function = args.at<JSFunction>(1);
   9099   }
   9100 
   9101   Handle<Context> current(isolate->context());
   9102   Handle<Context> context = isolate->factory()->NewWithContext(
   9103       function, current, extension_object);
   9104   isolate->set_context(*context);
   9105   return *context;
   9106 }
   9107 
   9108 
   9109 RUNTIME_FUNCTION(Runtime_PushCatchContext) {
   9110   HandleScope scope(isolate);
   9111   DCHECK(args.length() == 3);
   9112   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   9113   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
   9114   Handle<JSFunction> function;
   9115   if (args[2]->IsSmi()) {
   9116     // A smi sentinel indicates a context nested inside global code rather
   9117     // than some function.  There is a canonical empty function that can be
   9118     // gotten from the native context.
   9119     function = handle(isolate->native_context()->closure());
   9120   } else {
   9121     function = args.at<JSFunction>(2);
   9122   }
   9123   Handle<Context> current(isolate->context());
   9124   Handle<Context> context = isolate->factory()->NewCatchContext(
   9125       function, current, name, thrown_object);
   9126   isolate->set_context(*context);
   9127   return *context;
   9128 }
   9129 
   9130 
   9131 RUNTIME_FUNCTION(Runtime_PushBlockContext) {
   9132   HandleScope scope(isolate);
   9133   DCHECK(args.length() == 2);
   9134   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
   9135   Handle<JSFunction> function;
   9136   if (args[1]->IsSmi()) {
   9137     // A smi sentinel indicates a context nested inside global code rather
   9138     // than some function.  There is a canonical empty function that can be
   9139     // gotten from the native context.
   9140     function = handle(isolate->native_context()->closure());
   9141   } else {
   9142     function = args.at<JSFunction>(1);
   9143   }
   9144   Handle<Context> current(isolate->context());
   9145   Handle<Context> context = isolate->factory()->NewBlockContext(
   9146       function, current, scope_info);
   9147   isolate->set_context(*context);
   9148   return *context;
   9149 }
   9150 
   9151 
   9152 RUNTIME_FUNCTION(Runtime_IsJSModule) {
   9153   SealHandleScope shs(isolate);
   9154   DCHECK(args.length() == 1);
   9155   CONVERT_ARG_CHECKED(Object, obj, 0);
   9156   return isolate->heap()->ToBoolean(obj->IsJSModule());
   9157 }
   9158 
   9159 
   9160 RUNTIME_FUNCTION(Runtime_PushModuleContext) {
   9161   SealHandleScope shs(isolate);
   9162   DCHECK(args.length() == 2);
   9163   CONVERT_SMI_ARG_CHECKED(index, 0);
   9164 
   9165   if (!args[1]->IsScopeInfo()) {
   9166     // Module already initialized. Find hosting context and retrieve context.
   9167     Context* host = Context::cast(isolate->context())->global_context();
   9168     Context* context = Context::cast(host->get(index));
   9169     DCHECK(context->previous() == isolate->context());
   9170     isolate->set_context(context);
   9171     return context;
   9172   }
   9173 
   9174   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
   9175 
   9176   // Allocate module context.
   9177   HandleScope scope(isolate);
   9178   Factory* factory = isolate->factory();
   9179   Handle<Context> context = factory->NewModuleContext(scope_info);
   9180   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
   9181   context->set_module(*module);
   9182   Context* previous = isolate->context();
   9183   context->set_previous(previous);
   9184   context->set_closure(previous->closure());
   9185   context->set_global_object(previous->global_object());
   9186   isolate->set_context(*context);
   9187 
   9188   // Find hosting scope and initialize internal variable holding module there.
   9189   previous->global_context()->set(index, *context);
   9190 
   9191   return *context;
   9192 }
   9193 
   9194 
   9195 RUNTIME_FUNCTION(Runtime_DeclareModules) {
   9196   HandleScope scope(isolate);
   9197   DCHECK(args.length() == 1);
   9198   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
   9199   Context* host_context = isolate->context();
   9200 
   9201   for (int i = 0; i < descriptions->length(); ++i) {
   9202     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
   9203     int host_index = description->host_index();
   9204     Handle<Context> context(Context::cast(host_context->get(host_index)));
   9205     Handle<JSModule> module(context->module());
   9206 
   9207     for (int j = 0; j < description->length(); ++j) {
   9208       Handle<String> name(description->name(j));
   9209       VariableMode mode = description->mode(j);
   9210       int index = description->index(j);
   9211       switch (mode) {
   9212         case VAR:
   9213         case LET:
   9214         case CONST:
   9215         case CONST_LEGACY: {
   9216           PropertyAttributes attr =
   9217               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
   9218           Handle<AccessorInfo> info =
   9219               Accessors::MakeModuleExport(name, index, attr);
   9220           Handle<Object> result =
   9221               JSObject::SetAccessor(module, info).ToHandleChecked();
   9222           DCHECK(!result->IsUndefined());
   9223           USE(result);
   9224           break;
   9225         }
   9226         case MODULE: {
   9227           Object* referenced_context = Context::cast(host_context)->get(index);
   9228           Handle<JSModule> value(Context::cast(referenced_context)->module());
   9229           JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
   9230               .Assert();
   9231           break;
   9232         }
   9233         case INTERNAL:
   9234         case TEMPORARY:
   9235         case DYNAMIC:
   9236         case DYNAMIC_GLOBAL:
   9237         case DYNAMIC_LOCAL:
   9238           UNREACHABLE();
   9239       }
   9240     }
   9241 
   9242     JSObject::PreventExtensions(module).Assert();
   9243   }
   9244 
   9245   DCHECK(!isolate->has_pending_exception());
   9246   return isolate->heap()->undefined_value();
   9247 }
   9248 
   9249 
   9250 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
   9251   HandleScope scope(isolate);
   9252   DCHECK(args.length() == 2);
   9253 
   9254   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   9255   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   9256 
   9257   int index;
   9258   PropertyAttributes attributes;
   9259   ContextLookupFlags flags = FOLLOW_CHAINS;
   9260   BindingFlags binding_flags;
   9261   Handle<Object> holder = context->Lookup(name,
   9262                                           flags,
   9263                                           &index,
   9264                                           &attributes,
   9265                                           &binding_flags);
   9266 
   9267   // If the slot was not found the result is true.
   9268   if (holder.is_null()) {
   9269     return isolate->heap()->true_value();
   9270   }
   9271 
   9272   // If the slot was found in a context, it should be DONT_DELETE.
   9273   if (holder->IsContext()) {
   9274     return isolate->heap()->false_value();
   9275   }
   9276 
   9277   // The slot was found in a JSObject, either a context extension object,
   9278   // the global object, or the subject of a with.  Try to delete it
   9279   // (respecting DONT_DELETE).
   9280   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   9281   Handle<Object> result;
   9282   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9283       isolate, result,
   9284       JSReceiver::DeleteProperty(object, name));
   9285   return *result;
   9286 }
   9287 
   9288 
   9289 // A mechanism to return a pair of Object pointers in registers (if possible).
   9290 // How this is achieved is calling convention-dependent.
   9291 // All currently supported x86 compiles uses calling conventions that are cdecl
   9292 // variants where a 64-bit value is returned in two 32-bit registers
   9293 // (edx:eax on ia32, r1:r0 on ARM).
   9294 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
   9295 // In Win64 calling convention, a struct of two pointers is returned in memory,
   9296 // allocated by the caller, and passed as a pointer in a hidden first parameter.
   9297 #ifdef V8_HOST_ARCH_64_BIT
   9298 struct ObjectPair {
   9299   Object* x;
   9300   Object* y;
   9301 };
   9302 
   9303 
   9304 static inline ObjectPair MakePair(Object* x, Object* y) {
   9305   ObjectPair result = {x, y};
   9306   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
   9307   // In Win64 they are assigned to a hidden first argument.
   9308   return result;
   9309 }
   9310 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
   9311 // For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
   9312 // are used in the full codegen and Crankshaft compiler. An alternative is
   9313 // using uint64_t and modifying full codegen and Crankshaft compiler.
   9314 struct ObjectPair {
   9315   Object* x;
   9316   uint32_t x_upper;
   9317   Object* y;
   9318   uint32_t y_upper;
   9319 };
   9320 
   9321 
   9322 static inline ObjectPair MakePair(Object* x, Object* y) {
   9323   ObjectPair result = {x, 0, y, 0};
   9324   // Pointers x and y returned in rax and rdx, in x32-abi.
   9325   return result;
   9326 }
   9327 #else
   9328 typedef uint64_t ObjectPair;
   9329 static inline ObjectPair MakePair(Object* x, Object* y) {
   9330 #if defined(V8_TARGET_LITTLE_ENDIAN)
   9331   return reinterpret_cast<uint32_t>(x) |
   9332       (reinterpret_cast<ObjectPair>(y) << 32);
   9333 #elif defined(V8_TARGET_BIG_ENDIAN)
   9334     return reinterpret_cast<uint32_t>(y) |
   9335         (reinterpret_cast<ObjectPair>(x) << 32);
   9336 #else
   9337 #error Unknown endianness
   9338 #endif
   9339 }
   9340 #endif
   9341 
   9342 
   9343 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
   9344                                            JSObject* holder) {
   9345   DCHECK(!holder->IsGlobalObject());
   9346   Context* top = isolate->context();
   9347   // Get the context extension function.
   9348   JSFunction* context_extension_function =
   9349       top->native_context()->context_extension_function();
   9350   // If the holder isn't a context extension object, we just return it
   9351   // as the receiver. This allows arguments objects to be used as
   9352   // receivers, but only if they are put in the context scope chain
   9353   // explicitly via a with-statement.
   9354   Object* constructor = holder->map()->constructor();
   9355   if (constructor != context_extension_function) return holder;
   9356   // Fall back to using the global object as the implicit receiver if
   9357   // the property turns out to be a local variable allocated in a
   9358   // context extension object - introduced via eval.
   9359   return isolate->heap()->undefined_value();
   9360 }
   9361 
   9362 
   9363 static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
   9364                                        bool throw_error) {
   9365   HandleScope scope(isolate);
   9366   DCHECK_EQ(2, args.length());
   9367 
   9368   if (!args[0]->IsContext() || !args[1]->IsString()) {
   9369     return MakePair(isolate->ThrowIllegalOperation(), NULL);
   9370   }
   9371   Handle<Context> context = args.at<Context>(0);
   9372   Handle<String> name = args.at<String>(1);
   9373 
   9374   int index;
   9375   PropertyAttributes attributes;
   9376   ContextLookupFlags flags = FOLLOW_CHAINS;
   9377   BindingFlags binding_flags;
   9378   Handle<Object> holder = context->Lookup(name,
   9379                                           flags,
   9380                                           &index,
   9381                                           &attributes,
   9382                                           &binding_flags);
   9383   if (isolate->has_pending_exception()) {
   9384     return MakePair(isolate->heap()->exception(), NULL);
   9385   }
   9386 
   9387   // If the index is non-negative, the slot has been found in a context.
   9388   if (index >= 0) {
   9389     DCHECK(holder->IsContext());
   9390     // If the "property" we were looking for is a local variable, the
   9391     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
   9392     Handle<Object> receiver = isolate->factory()->undefined_value();
   9393     Object* value = Context::cast(*holder)->get(index);
   9394     // Check for uninitialized bindings.
   9395     switch (binding_flags) {
   9396       case MUTABLE_CHECK_INITIALIZED:
   9397       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
   9398         if (value->IsTheHole()) {
   9399           Handle<Object> error;
   9400           MaybeHandle<Object> maybe_error =
   9401               isolate->factory()->NewReferenceError("not_defined",
   9402                                                     HandleVector(&name, 1));
   9403           if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
   9404           return MakePair(isolate->heap()->exception(), NULL);
   9405         }
   9406         // FALLTHROUGH
   9407       case MUTABLE_IS_INITIALIZED:
   9408       case IMMUTABLE_IS_INITIALIZED:
   9409       case IMMUTABLE_IS_INITIALIZED_HARMONY:
   9410         DCHECK(!value->IsTheHole());
   9411         return MakePair(value, *receiver);
   9412       case IMMUTABLE_CHECK_INITIALIZED:
   9413         if (value->IsTheHole()) {
   9414           DCHECK((attributes & READ_ONLY) != 0);
   9415           value = isolate->heap()->undefined_value();
   9416         }
   9417         return MakePair(value, *receiver);
   9418       case MISSING_BINDING:
   9419         UNREACHABLE();
   9420         return MakePair(NULL, NULL);
   9421     }
   9422   }
   9423 
   9424   // Otherwise, if the slot was found the holder is a context extension
   9425   // object, subject of a with, or a global object.  We read the named
   9426   // property from it.
   9427   if (!holder.is_null()) {
   9428     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
   9429 #ifdef DEBUG
   9430     if (!object->IsJSProxy()) {
   9431       Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
   9432       DCHECK(maybe.has_value);
   9433       DCHECK(maybe.value);
   9434     }
   9435 #endif
   9436     // GetProperty below can cause GC.
   9437     Handle<Object> receiver_handle(
   9438         object->IsGlobalObject()
   9439             ? Object::cast(isolate->heap()->undefined_value())
   9440             : object->IsJSProxy() ? static_cast<Object*>(*object)
   9441                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
   9442         isolate);
   9443 
   9444     // No need to unhole the value here.  This is taken care of by the
   9445     // GetProperty function.
   9446     Handle<Object> value;
   9447     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   9448         isolate, value,
   9449         Object::GetProperty(object, name),
   9450         MakePair(isolate->heap()->exception(), NULL));
   9451     return MakePair(*value, *receiver_handle);
   9452   }
   9453 
   9454   if (throw_error) {
   9455     // The property doesn't exist - throw exception.
   9456     Handle<Object> error;
   9457     MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError(
   9458         "not_defined", HandleVector(&name, 1));
   9459     if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
   9460     return MakePair(isolate->heap()->exception(), NULL);
   9461   } else {
   9462     // The property doesn't exist - return undefined.
   9463     return MakePair(isolate->heap()->undefined_value(),
   9464                     isolate->heap()->undefined_value());
   9465   }
   9466 }
   9467 
   9468 
   9469 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) {
   9470   return LoadLookupSlotHelper(args, isolate, true);
   9471 }
   9472 
   9473 
   9474 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) {
   9475   return LoadLookupSlotHelper(args, isolate, false);
   9476 }
   9477 
   9478 
   9479 RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
   9480   HandleScope scope(isolate);
   9481   DCHECK(args.length() == 4);
   9482 
   9483   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
   9484   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   9485   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   9486   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
   9487 
   9488   int index;
   9489   PropertyAttributes attributes;
   9490   ContextLookupFlags flags = FOLLOW_CHAINS;
   9491   BindingFlags binding_flags;
   9492   Handle<Object> holder = context->Lookup(name,
   9493                                           flags,
   9494                                           &index,
   9495                                           &attributes,
   9496                                           &binding_flags);
   9497   // In case of JSProxy, an exception might have been thrown.
   9498   if (isolate->has_pending_exception()) return isolate->heap()->exception();
   9499 
   9500   // The property was found in a context slot.
   9501   if (index >= 0) {
   9502     if ((attributes & READ_ONLY) == 0) {
   9503       Handle<Context>::cast(holder)->set(index, *value);
   9504     } else if (strict_mode == STRICT) {
   9505       // Setting read only property in strict mode.
   9506       THROW_NEW_ERROR_RETURN_FAILURE(
   9507           isolate,
   9508           NewTypeError("strict_cannot_assign", HandleVector(&name, 1)));
   9509     }
   9510     return *value;
   9511   }
   9512 
   9513   // Slow case: The property is not in a context slot.  It is either in a
   9514   // context extension object, a property of the subject of a with, or a
   9515   // property of the global object.
   9516   Handle<JSReceiver> object;
   9517   if (attributes != ABSENT) {
   9518     // The property exists on the holder.
   9519     object = Handle<JSReceiver>::cast(holder);
   9520   } else if (strict_mode == STRICT) {
   9521     // If absent in strict mode: throw.
   9522     THROW_NEW_ERROR_RETURN_FAILURE(
   9523         isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
   9524   } else {
   9525     // If absent in sloppy mode: add the property to the global object.
   9526     object = Handle<JSReceiver>(context->global_object());
   9527   }
   9528 
   9529   RETURN_FAILURE_ON_EXCEPTION(
   9530       isolate, Object::SetProperty(object, name, value, strict_mode));
   9531 
   9532   return *value;
   9533 }
   9534 
   9535 
   9536 RUNTIME_FUNCTION(Runtime_Throw) {
   9537   HandleScope scope(isolate);
   9538   DCHECK(args.length() == 1);
   9539 
   9540   return isolate->Throw(args[0]);
   9541 }
   9542 
   9543 
   9544 RUNTIME_FUNCTION(Runtime_ReThrow) {
   9545   HandleScope scope(isolate);
   9546   DCHECK(args.length() == 1);
   9547 
   9548   return isolate->ReThrow(args[0]);
   9549 }
   9550 
   9551 
   9552 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
   9553   SealHandleScope shs(isolate);
   9554   DCHECK(args.length() == 0);
   9555   return isolate->PromoteScheduledException();
   9556 }
   9557 
   9558 
   9559 RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
   9560   HandleScope scope(isolate);
   9561   DCHECK(args.length() == 1);
   9562   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
   9563   THROW_NEW_ERROR_RETURN_FAILURE(
   9564       isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
   9565 }
   9566 
   9567 
   9568 RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) {
   9569   HandleScope scope(isolate);
   9570   DCHECK(args.length() == 0);
   9571   THROW_NEW_ERROR_RETURN_FAILURE(
   9572       isolate, NewReferenceError("non_method", HandleVector<Object>(NULL, 0)));
   9573 }
   9574 
   9575 
   9576 RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
   9577   HandleScope scope(isolate);
   9578   DCHECK(args.length() == 0);
   9579   THROW_NEW_ERROR_RETURN_FAILURE(
   9580       isolate,
   9581       NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
   9582 }
   9583 
   9584 
   9585 RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
   9586   HandleScope scope(isolate);
   9587   DCHECK(args.length() == 0);
   9588   THROW_NEW_ERROR_RETURN_FAILURE(
   9589       isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
   9590 }
   9591 
   9592 
   9593 RUNTIME_FUNCTION(Runtime_StackGuard) {
   9594   SealHandleScope shs(isolate);
   9595   DCHECK(args.length() == 0);
   9596 
   9597   // First check if this is a real stack overflow.
   9598   StackLimitCheck check(isolate);
   9599   if (check.JsHasOverflowed()) {
   9600     return isolate->StackOverflow();
   9601   }
   9602 
   9603   return isolate->stack_guard()->HandleInterrupts();
   9604 }
   9605 
   9606 
   9607 RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
   9608   HandleScope scope(isolate);
   9609   DCHECK(args.length() == 1);
   9610   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   9611 
   9612   // First check if this is a real stack overflow.
   9613   StackLimitCheck check(isolate);
   9614   if (check.JsHasOverflowed()) {
   9615     SealHandleScope shs(isolate);
   9616     return isolate->StackOverflow();
   9617   }
   9618 
   9619   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   9620   return (function->IsOptimized()) ? function->code()
   9621                                    : function->shared()->code();
   9622 }
   9623 
   9624 
   9625 RUNTIME_FUNCTION(Runtime_Interrupt) {
   9626   SealHandleScope shs(isolate);
   9627   DCHECK(args.length() == 0);
   9628   return isolate->stack_guard()->HandleInterrupts();
   9629 }
   9630 
   9631 
   9632 static int StackSize(Isolate* isolate) {
   9633   int n = 0;
   9634   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
   9635   return n;
   9636 }
   9637 
   9638 
   9639 static void PrintTransition(Isolate* isolate, Object* result) {
   9640   // indentation
   9641   { const int nmax = 80;
   9642     int n = StackSize(isolate);
   9643     if (n <= nmax)
   9644       PrintF("%4d:%*s", n, n, "");
   9645     else
   9646       PrintF("%4d:%*s", n, nmax, "...");
   9647   }
   9648 
   9649   if (result == NULL) {
   9650     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
   9651     PrintF(" {\n");
   9652   } else {
   9653     // function result
   9654     PrintF("} -> ");
   9655     result->ShortPrint();
   9656     PrintF("\n");
   9657   }
   9658 }
   9659 
   9660 
   9661 RUNTIME_FUNCTION(Runtime_TraceEnter) {
   9662   SealHandleScope shs(isolate);
   9663   DCHECK(args.length() == 0);
   9664   PrintTransition(isolate, NULL);
   9665   return isolate->heap()->undefined_value();
   9666 }
   9667 
   9668 
   9669 RUNTIME_FUNCTION(Runtime_TraceExit) {
   9670   SealHandleScope shs(isolate);
   9671   DCHECK(args.length() == 1);
   9672   CONVERT_ARG_CHECKED(Object, obj, 0);
   9673   PrintTransition(isolate, obj);
   9674   return obj;  // return TOS
   9675 }
   9676 
   9677 
   9678 RUNTIME_FUNCTION(Runtime_DebugPrint) {
   9679   SealHandleScope shs(isolate);
   9680   DCHECK(args.length() == 1);
   9681 
   9682   OFStream os(stdout);
   9683 #ifdef DEBUG
   9684   if (args[0]->IsString()) {
   9685     // If we have a string, assume it's a code "marker"
   9686     // and print some interesting cpu debugging info.
   9687     JavaScriptFrameIterator it(isolate);
   9688     JavaScriptFrame* frame = it.frame();
   9689     os << "fp = " << frame->fp() << ", sp = " << frame->sp()
   9690        << ", caller_sp = " << frame->caller_sp() << ": ";
   9691   } else {
   9692     os << "DebugPrint: ";
   9693   }
   9694   args[0]->Print(os);
   9695   if (args[0]->IsHeapObject()) {
   9696     os << "\n";
   9697     HeapObject::cast(args[0])->map()->Print(os);
   9698   }
   9699 #else
   9700   // ShortPrint is available in release mode. Print is not.
   9701   os << Brief(args[0]);
   9702 #endif
   9703   os << endl;
   9704 
   9705   return args[0];  // return TOS
   9706 }
   9707 
   9708 
   9709 RUNTIME_FUNCTION(Runtime_DebugTrace) {
   9710   SealHandleScope shs(isolate);
   9711   DCHECK(args.length() == 0);
   9712   isolate->PrintStack(stdout);
   9713   return isolate->heap()->undefined_value();
   9714 }
   9715 
   9716 
   9717 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
   9718   HandleScope scope(isolate);
   9719   DCHECK(args.length() == 0);
   9720   if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
   9721 
   9722   // According to ECMA-262, section 15.9.1, page 117, the precision of
   9723   // the number in a Date object representing a particular instant in
   9724   // time is milliseconds. Therefore, we floor the result of getting
   9725   // the OS time.
   9726   double millis;
   9727   if (FLAG_verify_predictable) {
   9728     millis = 1388534400000.0;  // Jan 1 2014 00:00:00 GMT+0000
   9729     millis += Floor(isolate->heap()->synthetic_time());
   9730   } else {
   9731     millis = Floor(base::OS::TimeCurrentMillis());
   9732   }
   9733   return *isolate->factory()->NewNumber(millis);
   9734 }
   9735 
   9736 
   9737 RUNTIME_FUNCTION(Runtime_DateParseString) {
   9738   HandleScope scope(isolate);
   9739   DCHECK(args.length() == 2);
   9740   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   9741   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
   9742 
   9743   RUNTIME_ASSERT(output->HasFastElements());
   9744   JSObject::EnsureCanContainHeapObjectElements(output);
   9745   RUNTIME_ASSERT(output->HasFastObjectElements());
   9746   Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
   9747   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
   9748 
   9749   str = String::Flatten(str);
   9750   DisallowHeapAllocation no_gc;
   9751 
   9752   bool result;
   9753   String::FlatContent str_content = str->GetFlatContent();
   9754   if (str_content.IsOneByte()) {
   9755     result = DateParser::Parse(str_content.ToOneByteVector(),
   9756                                *output_array,
   9757                                isolate->unicode_cache());
   9758   } else {
   9759     DCHECK(str_content.IsTwoByte());
   9760     result = DateParser::Parse(str_content.ToUC16Vector(),
   9761                                *output_array,
   9762                                isolate->unicode_cache());
   9763   }
   9764 
   9765   if (result) {
   9766     return *output;
   9767   } else {
   9768     return isolate->heap()->null_value();
   9769   }
   9770 }
   9771 
   9772 
   9773 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
   9774   HandleScope scope(isolate);
   9775   DCHECK(args.length() == 1);
   9776 
   9777   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9778   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
   9779                  x <= DateCache::kMaxTimeBeforeUTCInMs);
   9780   const char* zone =
   9781       isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
   9782   Handle<String> result = isolate->factory()->NewStringFromUtf8(
   9783       CStrVector(zone)).ToHandleChecked();
   9784   return *result;
   9785 }
   9786 
   9787 
   9788 RUNTIME_FUNCTION(Runtime_DateToUTC) {
   9789   HandleScope scope(isolate);
   9790   DCHECK(args.length() == 1);
   9791 
   9792   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9793   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
   9794                  x <= DateCache::kMaxTimeBeforeUTCInMs);
   9795   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
   9796 
   9797   return *isolate->factory()->NewNumber(static_cast<double>(time));
   9798 }
   9799 
   9800 
   9801 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
   9802   HandleScope hs(isolate);
   9803   DCHECK(args.length() == 0);
   9804   if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
   9805     Handle<FixedArray> date_cache_version =
   9806         isolate->factory()->NewFixedArray(1, TENURED);
   9807     date_cache_version->set(0, Smi::FromInt(0));
   9808     isolate->eternal_handles()->CreateSingleton(
   9809         isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
   9810   }
   9811   Handle<FixedArray> date_cache_version =
   9812       Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
   9813           EternalHandles::DATE_CACHE_VERSION));
   9814   // Return result as a JS array.
   9815   Handle<JSObject> result =
   9816       isolate->factory()->NewJSObject(isolate->array_function());
   9817   JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
   9818   return *result;
   9819 }
   9820 
   9821 
   9822 RUNTIME_FUNCTION(Runtime_GlobalProxy) {
   9823   SealHandleScope shs(isolate);
   9824   DCHECK(args.length() == 1);
   9825   CONVERT_ARG_CHECKED(Object, global, 0);
   9826   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
   9827   return JSGlobalObject::cast(global)->global_proxy();
   9828 }
   9829 
   9830 
   9831 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
   9832   SealHandleScope shs(isolate);
   9833   DCHECK(args.length() == 1);
   9834   CONVERT_ARG_CHECKED(Object, global, 0);
   9835   if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
   9836   return isolate->heap()->ToBoolean(
   9837       !JSGlobalObject::cast(global)->IsDetached());
   9838 }
   9839 
   9840 
   9841 RUNTIME_FUNCTION(Runtime_ParseJson) {
   9842   HandleScope scope(isolate);
   9843   DCHECK(args.length() == 1);
   9844   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9845 
   9846   source = String::Flatten(source);
   9847   // Optimized fast case where we only have Latin1 characters.
   9848   Handle<Object> result;
   9849   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9850       isolate, result,
   9851       source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
   9852                                    : JsonParser<false>::Parse(source));
   9853   return *result;
   9854 }
   9855 
   9856 
   9857 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   9858                                       Handle<Context> context) {
   9859   DCHECK(context->allow_code_gen_from_strings()->IsFalse());
   9860   // Check with callback if set.
   9861   AllowCodeGenerationFromStringsCallback callback =
   9862       isolate->allow_code_gen_callback();
   9863   if (callback == NULL) {
   9864     // No callback set and code generation disallowed.
   9865     return false;
   9866   } else {
   9867     // Callback set. Let it decide if code generation is allowed.
   9868     VMState<EXTERNAL> state(isolate);
   9869     return callback(v8::Utils::ToLocal(context));
   9870   }
   9871 }
   9872 
   9873 
   9874 RUNTIME_FUNCTION(Runtime_CompileString) {
   9875   HandleScope scope(isolate);
   9876   DCHECK(args.length() == 2);
   9877   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9878   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
   9879 
   9880   // Extract native context.
   9881   Handle<Context> context(isolate->native_context());
   9882 
   9883   // Check if native context allows code generation from
   9884   // strings. Throw an exception if it doesn't.
   9885   if (context->allow_code_gen_from_strings()->IsFalse() &&
   9886       !CodeGenerationFromStringsAllowed(isolate, context)) {
   9887     Handle<Object> error_message =
   9888         context->ErrorMessageForCodeGenerationFromStrings();
   9889     THROW_NEW_ERROR_RETURN_FAILURE(
   9890         isolate, NewEvalError("code_gen_from_strings",
   9891                               HandleVector<Object>(&error_message, 1)));
   9892   }
   9893 
   9894   // Compile source string in the native context.
   9895   ParseRestriction restriction = function_literal_only
   9896       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
   9897   Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
   9898   Handle<JSFunction> fun;
   9899   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9900       isolate, fun,
   9901       Compiler::GetFunctionFromEval(
   9902           source, outer_info,
   9903           context, SLOPPY, restriction, RelocInfo::kNoPosition));
   9904   return *fun;
   9905 }
   9906 
   9907 
   9908 static ObjectPair CompileGlobalEval(Isolate* isolate,
   9909                                     Handle<String> source,
   9910                                     Handle<SharedFunctionInfo> outer_info,
   9911                                     Handle<Object> receiver,
   9912                                     StrictMode strict_mode,
   9913                                     int scope_position) {
   9914   Handle<Context> context = Handle<Context>(isolate->context());
   9915   Handle<Context> native_context = Handle<Context>(context->native_context());
   9916 
   9917   // Check if native context allows code generation from
   9918   // strings. Throw an exception if it doesn't.
   9919   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
   9920       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
   9921     Handle<Object> error_message =
   9922         native_context->ErrorMessageForCodeGenerationFromStrings();
   9923     Handle<Object> error;
   9924     MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
   9925         "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
   9926     if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
   9927     return MakePair(isolate->heap()->exception(), NULL);
   9928   }
   9929 
   9930   // Deal with a normal eval call with a string argument. Compile it
   9931   // and return the compiled function bound in the local context.
   9932   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
   9933   Handle<JSFunction> compiled;
   9934   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   9935       isolate, compiled,
   9936       Compiler::GetFunctionFromEval(
   9937           source, outer_info,
   9938           context, strict_mode, restriction, scope_position),
   9939       MakePair(isolate->heap()->exception(), NULL));
   9940   return MakePair(*compiled, *receiver);
   9941 }
   9942 
   9943 
   9944 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
   9945   HandleScope scope(isolate);
   9946   DCHECK(args.length() == 6);
   9947 
   9948   Handle<Object> callee = args.at<Object>(0);
   9949 
   9950   // If "eval" didn't refer to the original GlobalEval, it's not a
   9951   // direct call to eval.
   9952   // (And even if it is, but the first argument isn't a string, just let
   9953   // execution default to an indirect call to eval, which will also return
   9954   // the first argument without doing anything).
   9955   if (*callee != isolate->native_context()->global_eval_fun() ||
   9956       !args[1]->IsString()) {
   9957     return MakePair(*callee, isolate->heap()->undefined_value());
   9958   }
   9959 
   9960   DCHECK(args[4]->IsSmi());
   9961   DCHECK(args.smi_at(4) == SLOPPY || args.smi_at(4) == STRICT);
   9962   StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(4));
   9963   DCHECK(args[5]->IsSmi());
   9964   Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
   9965                                         isolate);
   9966   return CompileGlobalEval(isolate,
   9967                            args.at<String>(1),
   9968                            outer_info,
   9969                            args.at<Object>(3),
   9970                            strict_mode,
   9971                            args.smi_at(5));
   9972 }
   9973 
   9974 
   9975 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
   9976   HandleScope scope(isolate);
   9977   DCHECK(args.length() == 1);
   9978   CONVERT_SMI_ARG_CHECKED(size, 0);
   9979   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9980   RUNTIME_ASSERT(size > 0);
   9981   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
   9982   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
   9983 }
   9984 
   9985 
   9986 RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
   9987   HandleScope scope(isolate);
   9988   DCHECK(args.length() == 2);
   9989   CONVERT_SMI_ARG_CHECKED(size, 0);
   9990   CONVERT_SMI_ARG_CHECKED(flags, 1);
   9991   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9992   RUNTIME_ASSERT(size > 0);
   9993   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
   9994   bool double_align = AllocateDoubleAlignFlag::decode(flags);
   9995   AllocationSpace space = AllocateTargetSpace::decode(flags);
   9996   return *isolate->factory()->NewFillerObject(size, double_align, space);
   9997 }
   9998 
   9999 
   10000 // Push an object unto an array of objects if it is not already in the
   10001 // array.  Returns true if the element was pushed on the stack and
   10002 // false otherwise.
   10003 RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
   10004   HandleScope scope(isolate);
   10005   DCHECK(args.length() == 2);
   10006   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   10007   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
   10008   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
   10009   int length = Smi::cast(array->length())->value();
   10010   FixedArray* elements = FixedArray::cast(array->elements());
   10011   for (int i = 0; i < length; i++) {
   10012     if (elements->get(i) == *element) return isolate->heap()->false_value();
   10013   }
   10014 
   10015   // Strict not needed. Used for cycle detection in Array join implementation.
   10016   RETURN_FAILURE_ON_EXCEPTION(
   10017       isolate,
   10018       JSObject::SetFastElement(array, length, element, SLOPPY, true));
   10019   return isolate->heap()->true_value();
   10020 }
   10021 
   10022 
   10023 /**
   10024  * A simple visitor visits every element of Array's.
   10025  * The backend storage can be a fixed array for fast elements case,
   10026  * or a dictionary for sparse array. Since Dictionary is a subtype
   10027  * of FixedArray, the class can be used by both fast and slow cases.
   10028  * The second parameter of the constructor, fast_elements, specifies
   10029  * whether the storage is a FixedArray or Dictionary.
   10030  *
   10031  * An index limit is used to deal with the situation that a result array
   10032  * length overflows 32-bit non-negative integer.
   10033  */
   10034 class ArrayConcatVisitor {
   10035  public:
   10036   ArrayConcatVisitor(Isolate* isolate,
   10037                      Handle<FixedArray> storage,
   10038                      bool fast_elements) :
   10039       isolate_(isolate),
   10040       storage_(Handle<FixedArray>::cast(
   10041           isolate->global_handles()->Create(*storage))),
   10042       index_offset_(0u),
   10043       fast_elements_(fast_elements),
   10044       exceeds_array_limit_(false) { }
   10045 
   10046   ~ArrayConcatVisitor() {
   10047     clear_storage();
   10048   }
   10049 
   10050   void visit(uint32_t i, Handle<Object> elm) {
   10051     if (i > JSObject::kMaxElementCount - index_offset_) {
   10052       exceeds_array_limit_ = true;
   10053       return;
   10054     }
   10055     uint32_t index = index_offset_ + i;
   10056 
   10057     if (fast_elements_) {
   10058       if (index < static_cast<uint32_t>(storage_->length())) {
   10059         storage_->set(index, *elm);
   10060         return;
   10061       }
   10062       // Our initial estimate of length was foiled, possibly by
   10063       // getters on the arrays increasing the length of later arrays
   10064       // during iteration.
   10065       // This shouldn't happen in anything but pathological cases.
   10066       SetDictionaryMode();
   10067       // Fall-through to dictionary mode.
   10068     }
   10069     DCHECK(!fast_elements_);
   10070     Handle<SeededNumberDictionary> dict(
   10071         SeededNumberDictionary::cast(*storage_));
   10072     Handle<SeededNumberDictionary> result =
   10073         SeededNumberDictionary::AtNumberPut(dict, index, elm);
   10074     if (!result.is_identical_to(dict)) {
   10075       // Dictionary needed to grow.
   10076       clear_storage();
   10077       set_storage(*result);
   10078     }
   10079   }
   10080 
   10081   void increase_index_offset(uint32_t delta) {
   10082     if (JSObject::kMaxElementCount - index_offset_ < delta) {
   10083       index_offset_ = JSObject::kMaxElementCount;
   10084     } else {
   10085       index_offset_ += delta;
   10086     }
   10087     // If the initial length estimate was off (see special case in visit()),
   10088     // but the array blowing the limit didn't contain elements beyond the
   10089     // provided-for index range, go to dictionary mode now.
   10090     if (fast_elements_ &&
   10091         index_offset_ >
   10092             static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
   10093       SetDictionaryMode();
   10094     }
   10095   }
   10096 
   10097   bool exceeds_array_limit() {
   10098     return exceeds_array_limit_;
   10099   }
   10100 
   10101   Handle<JSArray> ToArray() {
   10102     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
   10103     Handle<Object> length =
   10104         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
   10105     Handle<Map> map = JSObject::GetElementsTransitionMap(
   10106         array,
   10107         fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
   10108     array->set_map(*map);
   10109     array->set_length(*length);
   10110     array->set_elements(*storage_);
   10111     return array;
   10112   }
   10113 
   10114  private:
   10115   // Convert storage to dictionary mode.
   10116   void SetDictionaryMode() {
   10117     DCHECK(fast_elements_);
   10118     Handle<FixedArray> current_storage(*storage_);
   10119     Handle<SeededNumberDictionary> slow_storage(
   10120         SeededNumberDictionary::New(isolate_, current_storage->length()));
   10121     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
   10122     for (uint32_t i = 0; i < current_length; i++) {
   10123       HandleScope loop_scope(isolate_);
   10124       Handle<Object> element(current_storage->get(i), isolate_);
   10125       if (!element->IsTheHole()) {
   10126         Handle<SeededNumberDictionary> new_storage =
   10127             SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
   10128         if (!new_storage.is_identical_to(slow_storage)) {
   10129           slow_storage = loop_scope.CloseAndEscape(new_storage);
   10130         }
   10131       }
   10132     }
   10133     clear_storage();
   10134     set_storage(*slow_storage);
   10135     fast_elements_ = false;
   10136   }
   10137 
   10138   inline void clear_storage() {
   10139     GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
   10140   }
   10141 
   10142   inline void set_storage(FixedArray* storage) {
   10143     storage_ = Handle<FixedArray>::cast(
   10144         isolate_->global_handles()->Create(storage));
   10145   }
   10146 
   10147   Isolate* isolate_;
   10148   Handle<FixedArray> storage_;  // Always a global handle.
   10149   // Index after last seen index. Always less than or equal to
   10150   // JSObject::kMaxElementCount.
   10151   uint32_t index_offset_;
   10152   bool fast_elements_ : 1;
   10153   bool exceeds_array_limit_ : 1;
   10154 };
   10155 
   10156 
   10157 static uint32_t EstimateElementCount(Handle<JSArray> array) {
   10158   uint32_t length = static_cast<uint32_t>(array->length()->Number());
   10159   int element_count = 0;
   10160   switch (array->GetElementsKind()) {
   10161     case FAST_SMI_ELEMENTS:
   10162     case FAST_HOLEY_SMI_ELEMENTS:
   10163     case FAST_ELEMENTS:
   10164     case FAST_HOLEY_ELEMENTS: {
   10165       // Fast elements can't have lengths that are not representable by
   10166       // a 32-bit signed integer.
   10167       DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
   10168       int fast_length = static_cast<int>(length);
   10169       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
   10170       for (int i = 0; i < fast_length; i++) {
   10171         if (!elements->get(i)->IsTheHole()) element_count++;
   10172       }
   10173       break;
   10174     }
   10175     case FAST_DOUBLE_ELEMENTS:
   10176     case FAST_HOLEY_DOUBLE_ELEMENTS: {
   10177       // Fast elements can't have lengths that are not representable by
   10178       // a 32-bit signed integer.
   10179       DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
   10180       int fast_length = static_cast<int>(length);
   10181       if (array->elements()->IsFixedArray()) {
   10182         DCHECK(FixedArray::cast(array->elements())->length() == 0);
   10183         break;
   10184       }
   10185       Handle<FixedDoubleArray> elements(
   10186           FixedDoubleArray::cast(array->elements()));
   10187       for (int i = 0; i < fast_length; i++) {
   10188         if (!elements->is_the_hole(i)) element_count++;
   10189       }
   10190       break;
   10191     }
   10192     case DICTIONARY_ELEMENTS: {
   10193       Handle<SeededNumberDictionary> dictionary(
   10194           SeededNumberDictionary::cast(array->elements()));
   10195       int capacity = dictionary->Capacity();
   10196       for (int i = 0; i < capacity; i++) {
   10197         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
   10198         if (dictionary->IsKey(*key)) {
   10199           element_count++;
   10200         }
   10201       }
   10202       break;
   10203     }
   10204     case SLOPPY_ARGUMENTS_ELEMENTS:
   10205 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
   10206     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
   10207     case TYPE##_ELEMENTS:                                                    \
   10208 
   10209     TYPED_ARRAYS(TYPED_ARRAY_CASE)
   10210 #undef TYPED_ARRAY_CASE
   10211       // External arrays are always dense.
   10212       return length;
   10213   }
   10214   // As an estimate, we assume that the prototype doesn't contain any
   10215   // inherited elements.
   10216   return element_count;
   10217 }
   10218 
   10219 
   10220 
   10221 template<class ExternalArrayClass, class ElementType>
   10222 static void IterateExternalArrayElements(Isolate* isolate,
   10223                                          Handle<JSObject> receiver,
   10224                                          bool elements_are_ints,
   10225                                          bool elements_are_guaranteed_smis,
   10226                                          ArrayConcatVisitor* visitor) {
   10227   Handle<ExternalArrayClass> array(
   10228       ExternalArrayClass::cast(receiver->elements()));
   10229   uint32_t len = static_cast<uint32_t>(array->length());
   10230 
   10231   DCHECK(visitor != NULL);
   10232   if (elements_are_ints) {
   10233     if (elements_are_guaranteed_smis) {
   10234       for (uint32_t j = 0; j < len; j++) {
   10235         HandleScope loop_scope(isolate);
   10236         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
   10237                       isolate);
   10238         visitor->visit(j, e);
   10239       }
   10240     } else {
   10241       for (uint32_t j = 0; j < len; j++) {
   10242         HandleScope loop_scope(isolate);
   10243         int64_t val = static_cast<int64_t>(array->get_scalar(j));
   10244         if (Smi::IsValid(static_cast<intptr_t>(val))) {
   10245           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
   10246           visitor->visit(j, e);
   10247         } else {
   10248           Handle<Object> e =
   10249               isolate->factory()->NewNumber(static_cast<ElementType>(val));
   10250           visitor->visit(j, e);
   10251         }
   10252       }
   10253     }
   10254   } else {
   10255     for (uint32_t j = 0; j < len; j++) {
   10256       HandleScope loop_scope(isolate);
   10257       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
   10258       visitor->visit(j, e);
   10259     }
   10260   }
   10261 }
   10262 
   10263 
   10264 // Used for sorting indices in a List<uint32_t>.
   10265 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
   10266   uint32_t a = *ap;
   10267   uint32_t b = *bp;
   10268   return (a == b) ? 0 : (a < b) ? -1 : 1;
   10269 }
   10270 
   10271 
   10272 static void CollectElementIndices(Handle<JSObject> object,
   10273                                   uint32_t range,
   10274                                   List<uint32_t>* indices) {
   10275   Isolate* isolate = object->GetIsolate();
   10276   ElementsKind kind = object->GetElementsKind();
   10277   switch (kind) {
   10278     case FAST_SMI_ELEMENTS:
   10279     case FAST_ELEMENTS:
   10280     case FAST_HOLEY_SMI_ELEMENTS:
   10281     case FAST_HOLEY_ELEMENTS: {
   10282       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
   10283       uint32_t length = static_cast<uint32_t>(elements->length());
   10284       if (range < length) length = range;
   10285       for (uint32_t i = 0; i < length; i++) {
   10286         if (!elements->get(i)->IsTheHole()) {
   10287           indices->Add(i);
   10288         }
   10289       }
   10290       break;
   10291     }
   10292     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10293     case FAST_DOUBLE_ELEMENTS: {
   10294       if (object->elements()->IsFixedArray()) {
   10295         DCHECK(object->elements()->length() == 0);
   10296         break;
   10297       }
   10298       Handle<FixedDoubleArray> elements(
   10299           FixedDoubleArray::cast(object->elements()));
   10300       uint32_t length = static_cast<uint32_t>(elements->length());
   10301       if (range < length) length = range;
   10302       for (uint32_t i = 0; i < length; i++) {
   10303         if (!elements->is_the_hole(i)) {
   10304           indices->Add(i);
   10305         }
   10306       }
   10307       break;
   10308     }
   10309     case DICTIONARY_ELEMENTS: {
   10310       Handle<SeededNumberDictionary> dict(
   10311           SeededNumberDictionary::cast(object->elements()));
   10312       uint32_t capacity = dict->Capacity();
   10313       for (uint32_t j = 0; j < capacity; j++) {
   10314         HandleScope loop_scope(isolate);
   10315         Handle<Object> k(dict->KeyAt(j), isolate);
   10316         if (dict->IsKey(*k)) {
   10317           DCHECK(k->IsNumber());
   10318           uint32_t index = static_cast<uint32_t>(k->Number());
   10319           if (index < range) {
   10320             indices->Add(index);
   10321           }
   10322         }
   10323       }
   10324       break;
   10325     }
   10326 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
   10327     case TYPE##_ELEMENTS:                               \
   10328     case EXTERNAL_##TYPE##_ELEMENTS:
   10329 
   10330       TYPED_ARRAYS(TYPED_ARRAY_CASE)
   10331 #undef TYPED_ARRAY_CASE
   10332     {
   10333       uint32_t length = static_cast<uint32_t>(
   10334           FixedArrayBase::cast(object->elements())->length());
   10335       if (range <= length) {
   10336         length = range;
   10337         // We will add all indices, so we might as well clear it first
   10338         // and avoid duplicates.
   10339         indices->Clear();
   10340       }
   10341       for (uint32_t i = 0; i < length; i++) {
   10342         indices->Add(i);
   10343       }
   10344       if (length == range) return;  // All indices accounted for already.
   10345       break;
   10346     }
   10347     case SLOPPY_ARGUMENTS_ELEMENTS: {
   10348       MaybeHandle<Object> length_obj =
   10349           Object::GetProperty(object, isolate->factory()->length_string());
   10350       double length_num = length_obj.ToHandleChecked()->Number();
   10351       uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num));
   10352       ElementsAccessor* accessor = object->GetElementsAccessor();
   10353       for (uint32_t i = 0; i < length; i++) {
   10354         if (accessor->HasElement(object, object, i)) {
   10355           indices->Add(i);
   10356         }
   10357       }
   10358       break;
   10359     }
   10360   }
   10361 
   10362   PrototypeIterator iter(isolate, object);
   10363   if (!iter.IsAtEnd()) {
   10364     // The prototype will usually have no inherited element indices,
   10365     // but we have to check.
   10366     CollectElementIndices(
   10367         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
   10368         indices);
   10369   }
   10370 }
   10371 
   10372 
   10373 /**
   10374  * A helper function that visits elements of a JSArray in numerical
   10375  * order.
   10376  *
   10377  * The visitor argument called for each existing element in the array
   10378  * with the element index and the element's value.
   10379  * Afterwards it increments the base-index of the visitor by the array
   10380  * length.
   10381  * Returns false if any access threw an exception, otherwise true.
   10382  */
   10383 static bool IterateElements(Isolate* isolate,
   10384                             Handle<JSArray> receiver,
   10385                             ArrayConcatVisitor* visitor) {
   10386   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
   10387   switch (receiver->GetElementsKind()) {
   10388     case FAST_SMI_ELEMENTS:
   10389     case FAST_ELEMENTS:
   10390     case FAST_HOLEY_SMI_ELEMENTS:
   10391     case FAST_HOLEY_ELEMENTS: {
   10392       // Run through the elements FixedArray and use HasElement and GetElement
   10393       // to check the prototype for missing elements.
   10394       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
   10395       int fast_length = static_cast<int>(length);
   10396       DCHECK(fast_length <= elements->length());
   10397       for (int j = 0; j < fast_length; j++) {
   10398         HandleScope loop_scope(isolate);
   10399         Handle<Object> element_value(elements->get(j), isolate);
   10400         if (!element_value->IsTheHole()) {
   10401           visitor->visit(j, element_value);
   10402         } else {
   10403           Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
   10404           if (!maybe.has_value) return false;
   10405           if (maybe.value) {
   10406             // Call GetElement on receiver, not its prototype, or getters won't
   10407             // have the correct receiver.
   10408             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   10409                 isolate, element_value,
   10410                 Object::GetElement(isolate, receiver, j), false);
   10411             visitor->visit(j, element_value);
   10412           }
   10413         }
   10414       }
   10415       break;
   10416     }
   10417     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10418     case FAST_DOUBLE_ELEMENTS: {
   10419       // Empty array is FixedArray but not FixedDoubleArray.
   10420       if (length == 0) break;
   10421       // Run through the elements FixedArray and use HasElement and GetElement
   10422       // to check the prototype for missing elements.
   10423       if (receiver->elements()->IsFixedArray()) {
   10424         DCHECK(receiver->elements()->length() == 0);
   10425         break;
   10426       }
   10427       Handle<FixedDoubleArray> elements(
   10428           FixedDoubleArray::cast(receiver->elements()));
   10429       int fast_length = static_cast<int>(length);
   10430       DCHECK(fast_length <= elements->length());
   10431       for (int j = 0; j < fast_length; j++) {
   10432         HandleScope loop_scope(isolate);
   10433         if (!elements->is_the_hole(j)) {
   10434           double double_value = elements->get_scalar(j);
   10435           Handle<Object> element_value =
   10436               isolate->factory()->NewNumber(double_value);
   10437           visitor->visit(j, element_value);
   10438         } else {
   10439           Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
   10440           if (!maybe.has_value) return false;
   10441           if (maybe.value) {
   10442             // Call GetElement on receiver, not its prototype, or getters won't
   10443             // have the correct receiver.
   10444             Handle<Object> element_value;
   10445             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   10446                 isolate, element_value,
   10447                 Object::GetElement(isolate, receiver, j), false);
   10448             visitor->visit(j, element_value);
   10449           }
   10450         }
   10451       }
   10452       break;
   10453     }
   10454     case DICTIONARY_ELEMENTS: {
   10455       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
   10456       List<uint32_t> indices(dict->Capacity() / 2);
   10457       // Collect all indices in the object and the prototypes less
   10458       // than length. This might introduce duplicates in the indices list.
   10459       CollectElementIndices(receiver, length, &indices);
   10460       indices.Sort(&compareUInt32);
   10461       int j = 0;
   10462       int n = indices.length();
   10463       while (j < n) {
   10464         HandleScope loop_scope(isolate);
   10465         uint32_t index = indices[j];
   10466         Handle<Object> element;
   10467         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   10468             isolate, element,
   10469             Object::GetElement(isolate, receiver, index),
   10470             false);
   10471         visitor->visit(index, element);
   10472         // Skip to next different index (i.e., omit duplicates).
   10473         do {
   10474           j++;
   10475         } while (j < n && indices[j] == index);
   10476       }
   10477       break;
   10478     }
   10479     case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
   10480       Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
   10481           receiver->elements()));
   10482       for (uint32_t j = 0; j < length; j++) {
   10483         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
   10484         visitor->visit(j, e);
   10485       }
   10486       break;
   10487     }
   10488     case EXTERNAL_INT8_ELEMENTS: {
   10489       IterateExternalArrayElements<ExternalInt8Array, int8_t>(
   10490           isolate, receiver, true, true, visitor);
   10491       break;
   10492     }
   10493     case EXTERNAL_UINT8_ELEMENTS: {
   10494       IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
   10495           isolate, receiver, true, true, visitor);
   10496       break;
   10497     }
   10498     case EXTERNAL_INT16_ELEMENTS: {
   10499       IterateExternalArrayElements<ExternalInt16Array, int16_t>(
   10500           isolate, receiver, true, true, visitor);
   10501       break;
   10502     }
   10503     case EXTERNAL_UINT16_ELEMENTS: {
   10504       IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
   10505           isolate, receiver, true, true, visitor);
   10506       break;
   10507     }
   10508     case EXTERNAL_INT32_ELEMENTS: {
   10509       IterateExternalArrayElements<ExternalInt32Array, int32_t>(
   10510           isolate, receiver, true, false, visitor);
   10511       break;
   10512     }
   10513     case EXTERNAL_UINT32_ELEMENTS: {
   10514       IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
   10515           isolate, receiver, true, false, visitor);
   10516       break;
   10517     }
   10518     case EXTERNAL_FLOAT32_ELEMENTS: {
   10519       IterateExternalArrayElements<ExternalFloat32Array, float>(
   10520           isolate, receiver, false, false, visitor);
   10521       break;
   10522     }
   10523     case EXTERNAL_FLOAT64_ELEMENTS: {
   10524       IterateExternalArrayElements<ExternalFloat64Array, double>(
   10525           isolate, receiver, false, false, visitor);
   10526       break;
   10527     }
   10528     default:
   10529       UNREACHABLE();
   10530       break;
   10531   }
   10532   visitor->increase_index_offset(length);
   10533   return true;
   10534 }
   10535 
   10536 
   10537 /**
   10538  * Array::concat implementation.
   10539  * See ECMAScript 262, 15.4.4.4.
   10540  * TODO(581): Fix non-compliance for very large concatenations and update to
   10541  * following the ECMAScript 5 specification.
   10542  */
   10543 RUNTIME_FUNCTION(Runtime_ArrayConcat) {
   10544   HandleScope handle_scope(isolate);
   10545   DCHECK(args.length() == 1);
   10546 
   10547   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
   10548   int argument_count = static_cast<int>(arguments->length()->Number());
   10549   RUNTIME_ASSERT(arguments->HasFastObjectElements());
   10550   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
   10551 
   10552   // Pass 1: estimate the length and number of elements of the result.
   10553   // The actual length can be larger if any of the arguments have getters
   10554   // that mutate other arguments (but will otherwise be precise).
   10555   // The number of elements is precise if there are no inherited elements.
   10556 
   10557   ElementsKind kind = FAST_SMI_ELEMENTS;
   10558 
   10559   uint32_t estimate_result_length = 0;
   10560   uint32_t estimate_nof_elements = 0;
   10561   for (int i = 0; i < argument_count; i++) {
   10562     HandleScope loop_scope(isolate);
   10563     Handle<Object> obj(elements->get(i), isolate);
   10564     uint32_t length_estimate;
   10565     uint32_t element_estimate;
   10566     if (obj->IsJSArray()) {
   10567       Handle<JSArray> array(Handle<JSArray>::cast(obj));
   10568       length_estimate = static_cast<uint32_t>(array->length()->Number());
   10569       if (length_estimate != 0) {
   10570         ElementsKind array_kind =
   10571             GetPackedElementsKind(array->map()->elements_kind());
   10572         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
   10573           kind = array_kind;
   10574         }
   10575       }
   10576       element_estimate = EstimateElementCount(array);
   10577     } else {
   10578       if (obj->IsHeapObject()) {
   10579         if (obj->IsNumber()) {
   10580           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
   10581             kind = FAST_DOUBLE_ELEMENTS;
   10582           }
   10583         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
   10584           kind = FAST_ELEMENTS;
   10585         }
   10586       }
   10587       length_estimate = 1;
   10588       element_estimate = 1;
   10589     }
   10590     // Avoid overflows by capping at kMaxElementCount.
   10591     if (JSObject::kMaxElementCount - estimate_result_length <
   10592         length_estimate) {
   10593       estimate_result_length = JSObject::kMaxElementCount;
   10594     } else {
   10595       estimate_result_length += length_estimate;
   10596     }
   10597     if (JSObject::kMaxElementCount - estimate_nof_elements <
   10598         element_estimate) {
   10599       estimate_nof_elements = JSObject::kMaxElementCount;
   10600     } else {
   10601       estimate_nof_elements += element_estimate;
   10602     }
   10603   }
   10604 
   10605   // If estimated number of elements is more than half of length, a
   10606   // fixed array (fast case) is more time and space-efficient than a
   10607   // dictionary.
   10608   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
   10609 
   10610   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
   10611     Handle<FixedArrayBase> storage =
   10612         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
   10613     int j = 0;
   10614     bool failure = false;
   10615     if (estimate_result_length > 0) {
   10616       Handle<FixedDoubleArray> double_storage =
   10617           Handle<FixedDoubleArray>::cast(storage);
   10618       for (int i = 0; i < argument_count; i++) {
   10619         Handle<Object> obj(elements->get(i), isolate);
   10620         if (obj->IsSmi()) {
   10621           double_storage->set(j, Smi::cast(*obj)->value());
   10622           j++;
   10623         } else if (obj->IsNumber()) {
   10624           double_storage->set(j, obj->Number());
   10625           j++;
   10626         } else {
   10627           JSArray* array = JSArray::cast(*obj);
   10628           uint32_t length = static_cast<uint32_t>(array->length()->Number());
   10629           switch (array->map()->elements_kind()) {
   10630             case FAST_HOLEY_DOUBLE_ELEMENTS:
   10631             case FAST_DOUBLE_ELEMENTS: {
   10632               // Empty array is FixedArray but not FixedDoubleArray.
   10633               if (length == 0) break;
   10634               FixedDoubleArray* elements =
   10635                   FixedDoubleArray::cast(array->elements());
   10636               for (uint32_t i = 0; i < length; i++) {
   10637                 if (elements->is_the_hole(i)) {
   10638                   // TODO(jkummerow/verwaest): We could be a bit more clever
   10639                   // here: Check if there are no elements/getters on the
   10640                   // prototype chain, and if so, allow creation of a holey
   10641                   // result array.
   10642                   // Same thing below (holey smi case).
   10643                   failure = true;
   10644                   break;
   10645                 }
   10646                 double double_value = elements->get_scalar(i);
   10647                 double_storage->set(j, double_value);
   10648                 j++;
   10649               }
   10650               break;
   10651             }
   10652             case FAST_HOLEY_SMI_ELEMENTS:
   10653             case FAST_SMI_ELEMENTS: {
   10654               FixedArray* elements(
   10655                   FixedArray::cast(array->elements()));
   10656               for (uint32_t i = 0; i < length; i++) {
   10657                 Object* element = elements->get(i);
   10658                 if (element->IsTheHole()) {
   10659                   failure = true;
   10660                   break;
   10661                 }
   10662                 int32_t int_value = Smi::cast(element)->value();
   10663                 double_storage->set(j, int_value);
   10664                 j++;
   10665               }
   10666               break;
   10667             }
   10668             case FAST_HOLEY_ELEMENTS:
   10669             case FAST_ELEMENTS:
   10670               DCHECK_EQ(0, length);
   10671               break;
   10672             default:
   10673               UNREACHABLE();
   10674           }
   10675         }
   10676         if (failure) break;
   10677       }
   10678     }
   10679     if (!failure) {
   10680       Handle<JSArray> array = isolate->factory()->NewJSArray(0);
   10681       Smi* length = Smi::FromInt(j);
   10682       Handle<Map> map;
   10683       map = JSObject::GetElementsTransitionMap(array, kind);
   10684       array->set_map(*map);
   10685       array->set_length(length);
   10686       array->set_elements(*storage);
   10687       return *array;
   10688     }
   10689     // In case of failure, fall through.
   10690   }
   10691 
   10692   Handle<FixedArray> storage;
   10693   if (fast_case) {
   10694     // The backing storage array must have non-existing elements to preserve
   10695     // holes across concat operations.
   10696     storage = isolate->factory()->NewFixedArrayWithHoles(
   10697         estimate_result_length);
   10698   } else {
   10699     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
   10700     uint32_t at_least_space_for = estimate_nof_elements +
   10701                                   (estimate_nof_elements >> 2);
   10702     storage = Handle<FixedArray>::cast(
   10703         SeededNumberDictionary::New(isolate, at_least_space_for));
   10704   }
   10705 
   10706   ArrayConcatVisitor visitor(isolate, storage, fast_case);
   10707 
   10708   for (int i = 0; i < argument_count; i++) {
   10709     Handle<Object> obj(elements->get(i), isolate);
   10710     if (obj->IsJSArray()) {
   10711       Handle<JSArray> array = Handle<JSArray>::cast(obj);
   10712       if (!IterateElements(isolate, array, &visitor)) {
   10713         return isolate->heap()->exception();
   10714       }
   10715     } else {
   10716       visitor.visit(0, obj);
   10717       visitor.increase_index_offset(1);
   10718     }
   10719   }
   10720 
   10721   if (visitor.exceeds_array_limit()) {
   10722     THROW_NEW_ERROR_RETURN_FAILURE(
   10723         isolate,
   10724         NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0)));
   10725   }
   10726   return *visitor.ToArray();
   10727 }
   10728 
   10729 
   10730 // This will not allocate (flatten the string), but it may run
   10731 // very slowly for very deeply nested ConsStrings.  For debugging use only.
   10732 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
   10733   SealHandleScope shs(isolate);
   10734   DCHECK(args.length() == 1);
   10735 
   10736   CONVERT_ARG_CHECKED(String, string, 0);
   10737   ConsStringIteratorOp op;
   10738   StringCharacterStream stream(string, &op);
   10739   while (stream.HasMore()) {
   10740     uint16_t character = stream.GetNext();
   10741     PrintF("%c", character);
   10742   }
   10743   return string;
   10744 }
   10745 
   10746 
   10747 // Moves all own elements of an object, that are below a limit, to positions
   10748 // starting at zero. All undefined values are placed after non-undefined values,
   10749 // and are followed by non-existing element. Does not change the length
   10750 // property.
   10751 // Returns the number of non-undefined elements collected.
   10752 // Returns -1 if hole removal is not supported by this method.
   10753 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
   10754   HandleScope scope(isolate);
   10755   DCHECK(args.length() == 2);
   10756   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   10757   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   10758   return *JSObject::PrepareElementsForSort(object, limit);
   10759 }
   10760 
   10761 
   10762 // Move contents of argument 0 (an array) to argument 1 (an array)
   10763 RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
   10764   HandleScope scope(isolate);
   10765   DCHECK(args.length() == 2);
   10766   CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
   10767   CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
   10768   JSObject::ValidateElements(from);
   10769   JSObject::ValidateElements(to);
   10770 
   10771   Handle<FixedArrayBase> new_elements(from->elements());
   10772   ElementsKind from_kind = from->GetElementsKind();
   10773   Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
   10774   JSObject::SetMapAndElements(to, new_map, new_elements);
   10775   to->set_length(from->length());
   10776 
   10777   JSObject::ResetElements(from);
   10778   from->set_length(Smi::FromInt(0));
   10779 
   10780   JSObject::ValidateElements(to);
   10781   return *to;
   10782 }
   10783 
   10784 
   10785 // How many elements does this object/array have?
   10786 RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
   10787   HandleScope scope(isolate);
   10788   DCHECK(args.length() == 1);
   10789   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   10790   Handle<FixedArrayBase> elements(array->elements(), isolate);
   10791   SealHandleScope shs(isolate);
   10792   if (elements->IsDictionary()) {
   10793     int result =
   10794         Handle<SeededNumberDictionary>::cast(elements)->NumberOfElements();
   10795     return Smi::FromInt(result);
   10796   } else {
   10797     DCHECK(array->length()->IsSmi());
   10798     // For packed elements, we know the exact number of elements
   10799     int length = elements->length();
   10800     ElementsKind kind = array->GetElementsKind();
   10801     if (IsFastPackedElementsKind(kind)) {
   10802       return Smi::FromInt(length);
   10803     }
   10804     // For holey elements, take samples from the buffer checking for holes
   10805     // to generate the estimate.
   10806     const int kNumberOfHoleCheckSamples = 97;
   10807     int increment = (length < kNumberOfHoleCheckSamples)
   10808                         ? 1
   10809                         : static_cast<int>(length / kNumberOfHoleCheckSamples);
   10810     ElementsAccessor* accessor = array->GetElementsAccessor();
   10811     int holes = 0;
   10812     for (int i = 0; i < length; i += increment) {
   10813       if (!accessor->HasElement(array, array, i, elements)) {
   10814         ++holes;
   10815       }
   10816     }
   10817     int estimate = static_cast<int>((kNumberOfHoleCheckSamples - holes) /
   10818                                     kNumberOfHoleCheckSamples * length);
   10819     return Smi::FromInt(estimate);
   10820   }
   10821 }
   10822 
   10823 
   10824 // Returns an array that tells you where in the [0, length) interval an array
   10825 // might have elements.  Can either return an array of keys (positive integers
   10826 // or undefined) or a number representing the positive length of an interval
   10827 // starting at index 0.
   10828 // Intervals can span over some keys that are not in the object.
   10829 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
   10830   HandleScope scope(isolate);
   10831   DCHECK(args.length() == 2);
   10832   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   10833   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
   10834   if (array->elements()->IsDictionary()) {
   10835     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
   10836     for (PrototypeIterator iter(isolate, array,
   10837                                 PrototypeIterator::START_AT_RECEIVER);
   10838          !iter.IsAtEnd(); iter.Advance()) {
   10839       if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
   10840           JSObject::cast(*PrototypeIterator::GetCurrent(iter))
   10841               ->HasIndexedInterceptor()) {
   10842         // Bail out if we find a proxy or interceptor, likely not worth
   10843         // collecting keys in that case.
   10844         return *isolate->factory()->NewNumberFromUint(length);
   10845       }
   10846       Handle<JSObject> current =
   10847           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   10848       Handle<FixedArray> current_keys =
   10849           isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
   10850       current->GetOwnElementKeys(*current_keys, NONE);
   10851       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   10852           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
   10853     }
   10854     // Erase any keys >= length.
   10855     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
   10856     // is changed to let this happen on the JS side.
   10857     for (int i = 0; i < keys->length(); i++) {
   10858       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
   10859     }
   10860     return *isolate->factory()->NewJSArrayWithElements(keys);
   10861   } else {
   10862     RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
   10863                    array->HasFastDoubleElements());
   10864     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
   10865     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
   10866   }
   10867 }
   10868 
   10869 
   10870 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
   10871   HandleScope scope(isolate);
   10872   DCHECK(args.length() == 3);
   10873   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   10874   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10875   CONVERT_SMI_ARG_CHECKED(flag, 2);
   10876   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
   10877   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
   10878   Handle<Object> result;
   10879   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   10880       isolate, result,
   10881       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
   10882   return *result;
   10883 }
   10884 
   10885 
   10886 RUNTIME_FUNCTION(Runtime_DebugBreak) {
   10887   SealHandleScope shs(isolate);
   10888   DCHECK(args.length() == 0);
   10889   isolate->debug()->HandleDebugBreak();
   10890   return isolate->heap()->undefined_value();
   10891 }
   10892 
   10893 
   10894 // Helper functions for wrapping and unwrapping stack frame ids.
   10895 static Smi* WrapFrameId(StackFrame::Id id) {
   10896   DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
   10897   return Smi::FromInt(id >> 2);
   10898 }
   10899 
   10900 
   10901 static StackFrame::Id UnwrapFrameId(int wrapped) {
   10902   return static_cast<StackFrame::Id>(wrapped << 2);
   10903 }
   10904 
   10905 
   10906 // Adds a JavaScript function as a debug event listener.
   10907 // args[0]: debug event listener function to set or null or undefined for
   10908 //          clearing the event listener function
   10909 // args[1]: object supplied during callback
   10910 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
   10911   SealHandleScope shs(isolate);
   10912   DCHECK(args.length() == 2);
   10913   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
   10914                  args[0]->IsUndefined() ||
   10915                  args[0]->IsNull());
   10916   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
   10917   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
   10918   isolate->debug()->SetEventListener(callback, data);
   10919 
   10920   return isolate->heap()->undefined_value();
   10921 }
   10922 
   10923 
   10924 RUNTIME_FUNCTION(Runtime_Break) {
   10925   SealHandleScope shs(isolate);
   10926   DCHECK(args.length() == 0);
   10927   isolate->stack_guard()->RequestDebugBreak();
   10928   return isolate->heap()->undefined_value();
   10929 }
   10930 
   10931 
   10932 static Handle<Object> DebugGetProperty(LookupIterator* it,
   10933                                        bool* has_caught = NULL) {
   10934   for (; it->IsFound(); it->Next()) {
   10935     switch (it->state()) {
   10936       case LookupIterator::NOT_FOUND:
   10937       case LookupIterator::TRANSITION:
   10938         UNREACHABLE();
   10939       case LookupIterator::ACCESS_CHECK:
   10940         // Ignore access checks.
   10941         break;
   10942       case LookupIterator::INTERCEPTOR:
   10943       case LookupIterator::JSPROXY:
   10944         return it->isolate()->factory()->undefined_value();
   10945       case LookupIterator::ACCESSOR: {
   10946         Handle<Object> accessors = it->GetAccessors();
   10947         if (!accessors->IsAccessorInfo()) {
   10948           return it->isolate()->factory()->undefined_value();
   10949         }
   10950         MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
   10951             it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
   10952             accessors);
   10953         Handle<Object> result;
   10954         if (!maybe_result.ToHandle(&result)) {
   10955           result = handle(it->isolate()->pending_exception(), it->isolate());
   10956           it->isolate()->clear_pending_exception();
   10957           if (has_caught != NULL) *has_caught = true;
   10958         }
   10959         return result;
   10960       }
   10961 
   10962       case LookupIterator::DATA:
   10963         return it->GetDataValue();
   10964     }
   10965   }
   10966 
   10967   return it->isolate()->factory()->undefined_value();
   10968 }
   10969 
   10970 
   10971 // Get debugger related details for an object property, in the following format:
   10972 // 0: Property value
   10973 // 1: Property details
   10974 // 2: Property value is exception
   10975 // 3: Getter function if defined
   10976 // 4: Setter function if defined
   10977 // Items 2-4 are only filled if the property has either a getter or a setter.
   10978 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
   10979   HandleScope scope(isolate);
   10980 
   10981   DCHECK(args.length() == 2);
   10982 
   10983   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10984   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10985 
   10986   // Make sure to set the current context to the context before the debugger was
   10987   // entered (if the debugger is entered). The reason for switching context here
   10988   // is that for some property lookups (accessors and interceptors) callbacks
   10989   // into the embedding application can occour, and the embedding application
   10990   // could have the assumption that its own native context is the current
   10991   // context and not some internal debugger context.
   10992   SaveContext save(isolate);
   10993   if (isolate->debug()->in_debug_scope()) {
   10994     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
   10995   }
   10996 
   10997   // Check if the name is trivially convertible to an index and get the element
   10998   // if so.
   10999   uint32_t index;
   11000   if (name->AsArrayIndex(&index)) {
   11001     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
   11002     Handle<Object> element_or_char;
   11003     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   11004         isolate, element_or_char,
   11005         Runtime::GetElementOrCharAt(isolate, obj, index));
   11006     details->set(0, *element_or_char);
   11007     details->set(
   11008         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
   11009     return *isolate->factory()->NewJSArrayWithElements(details);
   11010   }
   11011 
   11012   LookupIterator it(obj, name, LookupIterator::HIDDEN);
   11013   bool has_caught = false;
   11014   Handle<Object> value = DebugGetProperty(&it, &has_caught);
   11015   if (!it.IsFound()) return isolate->heap()->undefined_value();
   11016 
   11017   Handle<Object> maybe_pair;
   11018   if (it.state() == LookupIterator::ACCESSOR) {
   11019     maybe_pair = it.GetAccessors();
   11020   }
   11021 
   11022   // If the callback object is a fixed array then it contains JavaScript
   11023   // getter and/or setter.
   11024   bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
   11025   Handle<FixedArray> details =
   11026       isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
   11027   details->set(0, *value);
   11028   // TODO(verwaest): Get rid of this random way of handling interceptors.
   11029   PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
   11030                           ? PropertyDetails(NONE, NORMAL, 0)
   11031                           : it.property_details();
   11032   details->set(1, d.AsSmi());
   11033   details->set(
   11034       2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
   11035   if (has_js_accessors) {
   11036     AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
   11037     details->set(3, isolate->heap()->ToBoolean(has_caught));
   11038     details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
   11039     details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
   11040   }
   11041 
   11042   return *isolate->factory()->NewJSArrayWithElements(details);
   11043 }
   11044 
   11045 
   11046 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
   11047   HandleScope scope(isolate);
   11048 
   11049   DCHECK(args.length() == 2);
   11050 
   11051   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   11052   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   11053 
   11054   LookupIterator it(obj, name);
   11055   return *DebugGetProperty(&it);
   11056 }
   11057 
   11058 
   11059 // Return the property type calculated from the property details.
   11060 // args[0]: smi with property details.
   11061 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
   11062   SealHandleScope shs(isolate);
   11063   DCHECK(args.length() == 1);
   11064   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   11065   return Smi::FromInt(static_cast<int>(details.type()));
   11066 }
   11067 
   11068 
   11069 // Return the property attribute calculated from the property details.
   11070 // args[0]: smi with property details.
   11071 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
   11072   SealHandleScope shs(isolate);
   11073   DCHECK(args.length() == 1);
   11074   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   11075   return Smi::FromInt(static_cast<int>(details.attributes()));
   11076 }
   11077 
   11078 
   11079 // Return the property insertion index calculated from the property details.
   11080 // args[0]: smi with property details.
   11081 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
   11082   SealHandleScope shs(isolate);
   11083   DCHECK(args.length() == 1);
   11084   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   11085   // TODO(verwaest): Depends on the type of details.
   11086   return Smi::FromInt(details.dictionary_index());
   11087 }
   11088 
   11089 
   11090 // Return property value from named interceptor.
   11091 // args[0]: object
   11092 // args[1]: property name
   11093 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
   11094   HandleScope scope(isolate);
   11095   DCHECK(args.length() == 2);
   11096   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   11097   RUNTIME_ASSERT(obj->HasNamedInterceptor());
   11098   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   11099 
   11100   Handle<Object> result;
   11101   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   11102       isolate, result, JSObject::GetProperty(obj, name));
   11103   return *result;
   11104 }
   11105 
   11106 
   11107 // Return element value from indexed interceptor.
   11108 // args[0]: object
   11109 // args[1]: index
   11110 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
   11111   HandleScope scope(isolate);
   11112   DCHECK(args.length() == 2);
   11113   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   11114   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
   11115   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
   11116   Handle<Object> result;
   11117   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   11118       isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
   11119   return *result;
   11120 }
   11121 
   11122 
   11123 static bool CheckExecutionState(Isolate* isolate, int break_id) {
   11124   return !isolate->debug()->debug_context().is_null() &&
   11125          isolate->debug()->break_id() != 0 &&
   11126          isolate->debug()->break_id() == break_id;
   11127 }
   11128 
   11129 
   11130 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
   11131   SealHandleScope shs(isolate);
   11132   DCHECK(args.length() == 1);
   11133   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   11134   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   11135   return isolate->heap()->true_value();
   11136 }
   11137 
   11138 
   11139 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
   11140   HandleScope scope(isolate);
   11141   DCHECK(args.length() == 1);
   11142   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   11143   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   11144 
   11145   // Count all frames which are relevant to debugging stack trace.
   11146   int n = 0;
   11147   StackFrame::Id id = isolate->debug()->break_frame_id();
   11148   if (id == StackFrame::NO_ID) {
   11149     // If there is no JavaScript stack frame count is 0.
   11150     return Smi::FromInt(0);
   11151   }
   11152 
   11153   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
   11154     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
   11155     it.frame()->Summarize(&frames);
   11156     for (int i = frames.length() - 1; i >= 0; i--) {
   11157       // Omit functions from native scripts.
   11158       if (!frames[i].function()->IsFromNativeScript()) n++;
   11159     }
   11160   }
   11161   return Smi::FromInt(n);
   11162 }
   11163 
   11164 
   11165 class FrameInspector {
   11166  public:
   11167   FrameInspector(JavaScriptFrame* frame,
   11168                  int inlined_jsframe_index,
   11169                  Isolate* isolate)
   11170       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
   11171     // Calculate the deoptimized frame.
   11172     if (frame->is_optimized()) {
   11173       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
   11174           frame, inlined_jsframe_index, isolate);
   11175     }
   11176     has_adapted_arguments_ = frame_->has_adapted_arguments();
   11177     is_bottommost_ = inlined_jsframe_index == 0;
   11178     is_optimized_ = frame_->is_optimized();
   11179   }
   11180 
   11181   ~FrameInspector() {
   11182     // Get rid of the calculated deoptimized frame if any.
   11183     if (deoptimized_frame_ != NULL) {
   11184       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
   11185                                                   isolate_);
   11186     }
   11187   }
   11188 
   11189   int GetParametersCount() {
   11190     return is_optimized_
   11191         ? deoptimized_frame_->parameters_count()
   11192         : frame_->ComputeParametersCount();
   11193   }
   11194   int expression_count() { return deoptimized_frame_->expression_count(); }
   11195   Object* GetFunction() {
   11196     return is_optimized_
   11197         ? deoptimized_frame_->GetFunction()
   11198         : frame_->function();
   11199   }
   11200   Object* GetParameter(int index) {
   11201     return is_optimized_
   11202         ? deoptimized_frame_->GetParameter(index)
   11203         : frame_->GetParameter(index);
   11204   }
   11205   Object* GetExpression(int index) {
   11206     return is_optimized_
   11207         ? deoptimized_frame_->GetExpression(index)
   11208         : frame_->GetExpression(index);
   11209   }
   11210   int GetSourcePosition() {
   11211     return is_optimized_
   11212         ? deoptimized_frame_->GetSourcePosition()
   11213         : frame_->LookupCode()->SourcePosition(frame_->pc());
   11214   }
   11215   bool IsConstructor() {
   11216     return is_optimized_ && !is_bottommost_
   11217         ? deoptimized_frame_->HasConstructStub()
   11218         : frame_->IsConstructor();
   11219   }
   11220   Object* GetContext() {
   11221     return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
   11222   }
   11223 
   11224   // To inspect all the provided arguments the frame might need to be
   11225   // replaced with the arguments frame.
   11226   void SetArgumentsFrame(JavaScriptFrame* frame) {
   11227     DCHECK(has_adapted_arguments_);
   11228     frame_ = frame;
   11229     is_optimized_ = frame_->is_optimized();
   11230     DCHECK(!is_optimized_);
   11231   }
   11232 
   11233  private:
   11234   JavaScriptFrame* frame_;
   11235   DeoptimizedFrameInfo* deoptimized_frame_;
   11236   Isolate* isolate_;
   11237   bool is_optimized_;
   11238   bool is_bottommost_;
   11239   bool has_adapted_arguments_;
   11240 
   11241   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
   11242 };
   11243 
   11244 
   11245 static const int kFrameDetailsFrameIdIndex = 0;
   11246 static const int kFrameDetailsReceiverIndex = 1;
   11247 static const int kFrameDetailsFunctionIndex = 2;
   11248 static const int kFrameDetailsArgumentCountIndex = 3;
   11249 static const int kFrameDetailsLocalCountIndex = 4;
   11250 static const int kFrameDetailsSourcePositionIndex = 5;
   11251 static const int kFrameDetailsConstructCallIndex = 6;
   11252 static const int kFrameDetailsAtReturnIndex = 7;
   11253 static const int kFrameDetailsFlagsIndex = 8;
   11254 static const int kFrameDetailsFirstDynamicIndex = 9;
   11255 
   11256 
   11257 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
   11258                                              JavaScriptFrame* frame) {
   11259   SaveContext* save = isolate->save_context();
   11260   while (save != NULL && !save->IsBelowFrame(frame)) {
   11261     save = save->prev();
   11262   }
   11263   DCHECK(save != NULL);
   11264   return save;
   11265 }
   11266 
   11267 
   11268 // Advances the iterator to the frame that matches the index and returns the
   11269 // inlined frame index, or -1 if not found.  Skips native JS functions.
   11270 static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
   11271   int count = -1;
   11272   for (; !it->done(); it->Advance()) {
   11273     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
   11274     it->frame()->Summarize(&frames);
   11275     for (int i = frames.length() - 1; i >= 0; i--) {
   11276       // Omit functions from native scripts.
   11277       if (frames[i].function()->IsFromNativeScript()) continue;
   11278       if (++count == index) return i;
   11279     }
   11280   }
   11281   return -1;
   11282 }
   11283 
   11284 
   11285 // Return an array with frame details
   11286 // args[0]: number: break id
   11287 // args[1]: number: frame index
   11288 //
   11289 // The array returned contains the following information:
   11290 // 0: Frame id
   11291 // 1: Receiver
   11292 // 2: Function
   11293 // 3: Argument count
   11294 // 4: Local count
   11295 // 5: Source position
   11296 // 6: Constructor call
   11297 // 7: Is at return
   11298 // 8: Flags
   11299 // Arguments name, value
   11300 // Locals name, value
   11301 // Return value if any
   11302 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
   11303   HandleScope scope(isolate);
   11304   DCHECK(args.length() == 2);
   11305   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   11306   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   11307 
   11308   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   11309   Heap* heap = isolate->heap();
   11310 
   11311   // Find the relevant frame with the requested index.
   11312   StackFrame::Id id = isolate->debug()->break_frame_id();
   11313   if (id == StackFrame::NO_ID) {
   11314     // If there are no JavaScript stack frames return undefined.
   11315     return heap->undefined_value();
   11316   }
   11317 
   11318   JavaScriptFrameIterator it(isolate, id);
   11319   // Inlined frame index in optimized frame, starting from outer function.
   11320   int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
   11321   if (inlined_jsframe_index == -1) return heap->undefined_value();
   11322 
   11323   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
   11324   bool is_optimized = it.frame()->is_optimized();
   11325 
   11326   // Traverse the saved contexts chain to find the active context for the
   11327   // selected frame.
   11328   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
   11329 
   11330   // Get the frame id.
   11331   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
   11332 
   11333   // Find source position in unoptimized code.
   11334   int position = frame_inspector.GetSourcePosition();
   11335 
   11336   // Check for constructor frame.
   11337   bool constructor = frame_inspector.IsConstructor();
   11338 
   11339   // Get scope info and read from it for local variable information.
   11340   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11341   Handle<SharedFunctionInfo> shared(function->shared());
   11342   Handle<ScopeInfo> scope_info(shared->scope_info());
   11343   DCHECK(*scope_info != ScopeInfo::Empty(isolate));
   11344 
   11345   // Get the locals names and values into a temporary array.
   11346   int local_count = scope_info->LocalCount();
   11347   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
   11348     // Hide compiler-introduced temporary variables, whether on the stack or on
   11349     // the context.
   11350     if (scope_info->LocalIsSynthetic(slot))
   11351       local_count--;
   11352   }
   11353 
   11354   Handle<FixedArray> locals =
   11355       isolate->factory()->NewFixedArray(local_count * 2);
   11356 
   11357   // Fill in the values of the locals.
   11358   int local = 0;
   11359   int i = 0;
   11360   for (; i < scope_info->StackLocalCount(); ++i) {
   11361     // Use the value from the stack.
   11362     if (scope_info->LocalIsSynthetic(i))
   11363       continue;
   11364     locals->set(local * 2, scope_info->LocalName(i));
   11365     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
   11366     local++;
   11367   }
   11368   if (local < local_count) {
   11369     // Get the context containing declarations.
   11370     Handle<Context> context(
   11371         Context::cast(frame_inspector.GetContext())->declaration_context());
   11372     for (; i < scope_info->LocalCount(); ++i) {
   11373       if (scope_info->LocalIsSynthetic(i))
   11374         continue;
   11375       Handle<String> name(scope_info->LocalName(i));
   11376       VariableMode mode;
   11377       InitializationFlag init_flag;
   11378       MaybeAssignedFlag maybe_assigned_flag;
   11379       locals->set(local * 2, *name);
   11380       int context_slot_index = ScopeInfo::ContextSlotIndex(
   11381           scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
   11382       Object* value = context->get(context_slot_index);
   11383       locals->set(local * 2 + 1, value);
   11384       local++;
   11385     }
   11386   }
   11387 
   11388   // Check whether this frame is positioned at return. If not top
   11389   // frame or if the frame is optimized it cannot be at a return.
   11390   bool at_return = false;
   11391   if (!is_optimized && index == 0) {
   11392     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
   11393   }
   11394 
   11395   // If positioned just before return find the value to be returned and add it
   11396   // to the frame information.
   11397   Handle<Object> return_value = isolate->factory()->undefined_value();
   11398   if (at_return) {
   11399     StackFrameIterator it2(isolate);
   11400     Address internal_frame_sp = NULL;
   11401     while (!it2.done()) {
   11402       if (it2.frame()->is_internal()) {
   11403         internal_frame_sp = it2.frame()->sp();
   11404       } else {
   11405         if (it2.frame()->is_java_script()) {
   11406           if (it2.frame()->id() == it.frame()->id()) {
   11407             // The internal frame just before the JavaScript frame contains the
   11408             // value to return on top. A debug break at return will create an
   11409             // internal frame to store the return value (eax/rax/r0) before
   11410             // entering the debug break exit frame.
   11411             if (internal_frame_sp != NULL) {
   11412               return_value =
   11413                   Handle<Object>(Memory::Object_at(internal_frame_sp),
   11414                                  isolate);
   11415               break;
   11416             }
   11417           }
   11418         }
   11419 
   11420         // Indicate that the previous frame was not an internal frame.
   11421         internal_frame_sp = NULL;
   11422       }
   11423       it2.Advance();
   11424     }
   11425   }
   11426 
   11427   // Now advance to the arguments adapter frame (if any). It contains all
   11428   // the provided parameters whereas the function frame always have the number
   11429   // of arguments matching the functions parameters. The rest of the
   11430   // information (except for what is collected above) is the same.
   11431   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
   11432     it.AdvanceToArgumentsFrame();
   11433     frame_inspector.SetArgumentsFrame(it.frame());
   11434   }
   11435 
   11436   // Find the number of arguments to fill. At least fill the number of
   11437   // parameters for the function and fill more if more parameters are provided.
   11438   int argument_count = scope_info->ParameterCount();
   11439   if (argument_count < frame_inspector.GetParametersCount()) {
   11440     argument_count = frame_inspector.GetParametersCount();
   11441   }
   11442 
   11443   // Calculate the size of the result.
   11444   int details_size = kFrameDetailsFirstDynamicIndex +
   11445                      2 * (argument_count + local_count) +
   11446                      (at_return ? 1 : 0);
   11447   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   11448 
   11449   // Add the frame id.
   11450   details->set(kFrameDetailsFrameIdIndex, *frame_id);
   11451 
   11452   // Add the function (same as in function frame).
   11453   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
   11454 
   11455   // Add the arguments count.
   11456   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
   11457 
   11458   // Add the locals count
   11459   details->set(kFrameDetailsLocalCountIndex,
   11460                Smi::FromInt(local_count));
   11461 
   11462   // Add the source position.
   11463   if (position != RelocInfo::kNoPosition) {
   11464     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
   11465   } else {
   11466     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
   11467   }
   11468 
   11469   // Add the constructor information.
   11470   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
   11471 
   11472   // Add the at return information.
   11473   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
   11474 
   11475   // Add flags to indicate information on whether this frame is
   11476   //   bit 0: invoked in the debugger context.
   11477   //   bit 1: optimized frame.
   11478   //   bit 2: inlined in optimized frame
   11479   int flags = 0;
   11480   if (*save->context() == *isolate->debug()->debug_context()) {
   11481     flags |= 1 << 0;
   11482   }
   11483   if (is_optimized) {
   11484     flags |= 1 << 1;
   11485     flags |= inlined_jsframe_index << 2;
   11486   }
   11487   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
   11488 
   11489   // Fill the dynamic part.
   11490   int details_index = kFrameDetailsFirstDynamicIndex;
   11491 
   11492   // Add arguments name and value.
   11493   for (int i = 0; i < argument_count; i++) {
   11494     // Name of the argument.
   11495     if (i < scope_info->ParameterCount()) {
   11496       details->set(details_index++, scope_info->ParameterName(i));
   11497     } else {
   11498       details->set(details_index++, heap->undefined_value());
   11499     }
   11500 
   11501     // Parameter value.
   11502     if (i < frame_inspector.GetParametersCount()) {
   11503       // Get the value from the stack.
   11504       details->set(details_index++, frame_inspector.GetParameter(i));
   11505     } else {
   11506       details->set(details_index++, heap->undefined_value());
   11507     }
   11508   }
   11509 
   11510   // Add locals name and value from the temporary copy from the function frame.
   11511   for (int i = 0; i < local_count * 2; i++) {
   11512     details->set(details_index++, locals->get(i));
   11513   }
   11514 
   11515   // Add the value being returned.
   11516   if (at_return) {
   11517     details->set(details_index++, *return_value);
   11518   }
   11519 
   11520   // Add the receiver (same as in function frame).
   11521   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
   11522   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
   11523   Handle<Object> receiver(it.frame()->receiver(), isolate);
   11524   if (!receiver->IsJSObject() &&
   11525       shared->strict_mode() == SLOPPY &&
   11526       !function->IsBuiltin()) {
   11527     // If the receiver is not a JSObject and the function is not a
   11528     // builtin or strict-mode we have hit an optimization where a
   11529     // value object is not converted into a wrapped JS objects. To
   11530     // hide this optimization from the debugger, we wrap the receiver
   11531     // by creating correct wrapper object based on the calling frame's
   11532     // native context.
   11533     it.Advance();
   11534     if (receiver->IsUndefined()) {
   11535       receiver = handle(function->global_proxy());
   11536     } else {
   11537       Context* context = Context::cast(it.frame()->context());
   11538       Handle<Context> native_context(Context::cast(context->native_context()));
   11539       if (!Object::ToObject(isolate, receiver, native_context)
   11540                .ToHandle(&receiver)) {
   11541         // This only happens if the receiver is forcibly set in %_CallFunction.
   11542         return heap->undefined_value();
   11543       }
   11544     }
   11545   }
   11546   details->set(kFrameDetailsReceiverIndex, *receiver);
   11547 
   11548   DCHECK_EQ(details_size, details_index);
   11549   return *isolate->factory()->NewJSArrayWithElements(details);
   11550 }
   11551 
   11552 
   11553 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
   11554                                               Handle<String> parameter_name) {
   11555   VariableMode mode;
   11556   InitializationFlag init_flag;
   11557   MaybeAssignedFlag maybe_assigned_flag;
   11558   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
   11559                                      &maybe_assigned_flag) != -1;
   11560 }
   11561 
   11562 
   11563 // Create a plain JSObject which materializes the local scope for the specified
   11564 // frame.
   11565 MUST_USE_RESULT
   11566 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
   11567     Isolate* isolate,
   11568     Handle<JSObject> target,
   11569     Handle<JSFunction> function,
   11570     FrameInspector* frame_inspector) {
   11571   Handle<SharedFunctionInfo> shared(function->shared());
   11572   Handle<ScopeInfo> scope_info(shared->scope_info());
   11573 
   11574   // First fill all parameters.
   11575   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11576     // Do not materialize the parameter if it is shadowed by a context local.
   11577     Handle<String> name(scope_info->ParameterName(i));
   11578     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
   11579 
   11580     HandleScope scope(isolate);
   11581     Handle<Object> value(i < frame_inspector->GetParametersCount()
   11582                              ? frame_inspector->GetParameter(i)
   11583                              : isolate->heap()->undefined_value(),
   11584                          isolate);
   11585     DCHECK(!value->IsTheHole());
   11586 
   11587     RETURN_ON_EXCEPTION(
   11588         isolate,
   11589         Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
   11590         JSObject);
   11591   }
   11592 
   11593   // Second fill all stack locals.
   11594   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11595     if (scope_info->LocalIsSynthetic(i)) continue;
   11596     Handle<String> name(scope_info->StackLocalName(i));
   11597     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
   11598     if (value->IsTheHole()) continue;
   11599 
   11600     RETURN_ON_EXCEPTION(
   11601         isolate,
   11602         Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
   11603         JSObject);
   11604   }
   11605 
   11606   return target;
   11607 }
   11608 
   11609 
   11610 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
   11611                                                     Handle<JSObject> target,
   11612                                                     Handle<JSFunction> function,
   11613                                                     JavaScriptFrame* frame,
   11614                                                     int inlined_jsframe_index) {
   11615   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11616     // Optimized frames are not supported.
   11617     // TODO(yangguo): make sure all code deoptimized when debugger is active
   11618     //                and assert that this cannot happen.
   11619     return;
   11620   }
   11621 
   11622   Handle<SharedFunctionInfo> shared(function->shared());
   11623   Handle<ScopeInfo> scope_info(shared->scope_info());
   11624 
   11625   // Parameters.
   11626   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11627     // Shadowed parameters were not materialized.
   11628     Handle<String> name(scope_info->ParameterName(i));
   11629     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
   11630 
   11631     DCHECK(!frame->GetParameter(i)->IsTheHole());
   11632     HandleScope scope(isolate);
   11633     Handle<Object> value =
   11634         Object::GetPropertyOrElement(target, name).ToHandleChecked();
   11635     frame->SetParameterValue(i, *value);
   11636   }
   11637 
   11638   // Stack locals.
   11639   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11640     if (scope_info->LocalIsSynthetic(i)) continue;
   11641     if (frame->GetExpression(i)->IsTheHole()) continue;
   11642     HandleScope scope(isolate);
   11643     Handle<Object> value = Object::GetPropertyOrElement(
   11644         target,
   11645         handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
   11646     frame->SetExpression(i, *value);
   11647   }
   11648 }
   11649 
   11650 
   11651 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
   11652     Isolate* isolate,
   11653     Handle<JSObject> target,
   11654     Handle<JSFunction> function,
   11655     JavaScriptFrame* frame) {
   11656   HandleScope scope(isolate);
   11657   Handle<SharedFunctionInfo> shared(function->shared());
   11658   Handle<ScopeInfo> scope_info(shared->scope_info());
   11659 
   11660   if (!scope_info->HasContext()) return target;
   11661 
   11662   // Third fill all context locals.
   11663   Handle<Context> frame_context(Context::cast(frame->context()));
   11664   Handle<Context> function_context(frame_context->declaration_context());
   11665   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11666           scope_info, function_context, target)) {
   11667     return MaybeHandle<JSObject>();
   11668   }
   11669 
   11670   // Finally copy any properties from the function context extension.
   11671   // These will be variables introduced by eval.
   11672   if (function_context->closure() == *function) {
   11673     if (function_context->has_extension() &&
   11674         !function_context->IsNativeContext()) {
   11675       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11676       Handle<FixedArray> keys;
   11677       ASSIGN_RETURN_ON_EXCEPTION(
   11678           isolate, keys,
   11679           JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
   11680           JSObject);
   11681 
   11682       for (int i = 0; i < keys->length(); i++) {
   11683         // Names of variables introduced by eval are strings.
   11684         DCHECK(keys->get(i)->IsString());
   11685         Handle<String> key(String::cast(keys->get(i)));
   11686         Handle<Object> value;
   11687         ASSIGN_RETURN_ON_EXCEPTION(
   11688             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
   11689         RETURN_ON_EXCEPTION(
   11690             isolate,
   11691             Runtime::SetObjectProperty(isolate, target, key, value, SLOPPY),
   11692             JSObject);
   11693       }
   11694     }
   11695   }
   11696 
   11697   return target;
   11698 }
   11699 
   11700 
   11701 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
   11702     Isolate* isolate,
   11703     JavaScriptFrame* frame,
   11704     int inlined_jsframe_index) {
   11705   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   11706   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11707 
   11708   Handle<JSObject> local_scope =
   11709       isolate->factory()->NewJSObject(isolate->object_function());
   11710   ASSIGN_RETURN_ON_EXCEPTION(
   11711       isolate, local_scope,
   11712       MaterializeStackLocalsWithFrameInspector(
   11713           isolate, local_scope, function, &frame_inspector),
   11714       JSObject);
   11715 
   11716   return MaterializeLocalContext(isolate, local_scope, function, frame);
   11717 }
   11718 
   11719 
   11720 // Set the context local variable value.
   11721 static bool SetContextLocalValue(Isolate* isolate,
   11722                                  Handle<ScopeInfo> scope_info,
   11723                                  Handle<Context> context,
   11724                                  Handle<String> variable_name,
   11725                                  Handle<Object> new_value) {
   11726   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
   11727     Handle<String> next_name(scope_info->ContextLocalName(i));
   11728     if (String::Equals(variable_name, next_name)) {
   11729       VariableMode mode;
   11730       InitializationFlag init_flag;
   11731       MaybeAssignedFlag maybe_assigned_flag;
   11732       int context_index = ScopeInfo::ContextSlotIndex(
   11733           scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
   11734       context->set(context_index, *new_value);
   11735       return true;
   11736     }
   11737   }
   11738 
   11739   return false;
   11740 }
   11741 
   11742 
   11743 static bool SetLocalVariableValue(Isolate* isolate,
   11744                                   JavaScriptFrame* frame,
   11745                                   int inlined_jsframe_index,
   11746                                   Handle<String> variable_name,
   11747                                   Handle<Object> new_value) {
   11748   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11749     // Optimized frames are not supported.
   11750     return false;
   11751   }
   11752 
   11753   Handle<JSFunction> function(frame->function());
   11754   Handle<SharedFunctionInfo> shared(function->shared());
   11755   Handle<ScopeInfo> scope_info(shared->scope_info());
   11756 
   11757   bool default_result = false;
   11758 
   11759   // Parameters.
   11760   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11761     HandleScope scope(isolate);
   11762     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
   11763       frame->SetParameterValue(i, *new_value);
   11764       // Argument might be shadowed in heap context, don't stop here.
   11765       default_result = true;
   11766     }
   11767   }
   11768 
   11769   // Stack locals.
   11770   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11771     HandleScope scope(isolate);
   11772     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
   11773       frame->SetExpression(i, *new_value);
   11774       return true;
   11775     }
   11776   }
   11777 
   11778   if (scope_info->HasContext()) {
   11779     // Context locals.
   11780     Handle<Context> frame_context(Context::cast(frame->context()));
   11781     Handle<Context> function_context(frame_context->declaration_context());
   11782     if (SetContextLocalValue(
   11783         isolate, scope_info, function_context, variable_name, new_value)) {
   11784       return true;
   11785     }
   11786 
   11787     // Function context extension. These are variables introduced by eval.
   11788     if (function_context->closure() == *function) {
   11789       if (function_context->has_extension() &&
   11790           !function_context->IsNativeContext()) {
   11791         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11792 
   11793         Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
   11794         DCHECK(maybe.has_value);
   11795         if (maybe.value) {
   11796           // We don't expect this to do anything except replacing
   11797           // property value.
   11798           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
   11799                                      SLOPPY).Assert();
   11800           return true;
   11801         }
   11802       }
   11803     }
   11804   }
   11805 
   11806   return default_result;
   11807 }
   11808 
   11809 
   11810 // Create a plain JSObject which materializes the closure content for the
   11811 // context.
   11812 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
   11813     Isolate* isolate,
   11814     Handle<Context> context) {
   11815   DCHECK(context->IsFunctionContext());
   11816 
   11817   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11818   Handle<ScopeInfo> scope_info(shared->scope_info());
   11819 
   11820   // Allocate and initialize a JSObject with all the content of this function
   11821   // closure.
   11822   Handle<JSObject> closure_scope =
   11823       isolate->factory()->NewJSObject(isolate->object_function());
   11824 
   11825   // Fill all context locals to the context extension.
   11826   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11827           scope_info, context, closure_scope)) {
   11828     return MaybeHandle<JSObject>();
   11829   }
   11830 
   11831   // Finally copy any properties from the function context extension. This will
   11832   // be variables introduced by eval.
   11833   if (context->has_extension()) {
   11834     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11835     Handle<FixedArray> keys;
   11836     ASSIGN_RETURN_ON_EXCEPTION(
   11837         isolate, keys,
   11838         JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
   11839 
   11840     for (int i = 0; i < keys->length(); i++) {
   11841       HandleScope scope(isolate);
   11842       // Names of variables introduced by eval are strings.
   11843       DCHECK(keys->get(i)->IsString());
   11844       Handle<String> key(String::cast(keys->get(i)));
   11845       Handle<Object> value;
   11846       ASSIGN_RETURN_ON_EXCEPTION(
   11847           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
   11848       RETURN_ON_EXCEPTION(
   11849           isolate,
   11850           Runtime::DefineObjectProperty(closure_scope, key, value, NONE),
   11851           JSObject);
   11852     }
   11853   }
   11854 
   11855   return closure_scope;
   11856 }
   11857 
   11858 
   11859 // This method copies structure of MaterializeClosure method above.
   11860 static bool SetClosureVariableValue(Isolate* isolate,
   11861                                     Handle<Context> context,
   11862                                     Handle<String> variable_name,
   11863                                     Handle<Object> new_value) {
   11864   DCHECK(context->IsFunctionContext());
   11865 
   11866   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11867   Handle<ScopeInfo> scope_info(shared->scope_info());
   11868 
   11869   // Context locals to the context extension.
   11870   if (SetContextLocalValue(
   11871           isolate, scope_info, context, variable_name, new_value)) {
   11872     return true;
   11873   }
   11874 
   11875   // Properties from the function context extension. This will
   11876   // be variables introduced by eval.
   11877   if (context->has_extension()) {
   11878     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11879     Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
   11880     DCHECK(maybe.has_value);
   11881     if (maybe.value) {
   11882       // We don't expect this to do anything except replacing property value.
   11883       Runtime::DefineObjectProperty(
   11884           ext, variable_name, new_value, NONE).Assert();
   11885       return true;
   11886     }
   11887   }
   11888 
   11889   return false;
   11890 }
   11891 
   11892 
   11893 // Create a plain JSObject which materializes the scope for the specified
   11894 // catch context.
   11895 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
   11896     Isolate* isolate,
   11897     Handle<Context> context) {
   11898   DCHECK(context->IsCatchContext());
   11899   Handle<String> name(String::cast(context->extension()));
   11900   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
   11901                                isolate);
   11902   Handle<JSObject> catch_scope =
   11903       isolate->factory()->NewJSObject(isolate->object_function());
   11904   RETURN_ON_EXCEPTION(
   11905       isolate,
   11906       Runtime::DefineObjectProperty(catch_scope, name, thrown_object, NONE),
   11907       JSObject);
   11908   return catch_scope;
   11909 }
   11910 
   11911 
   11912 static bool SetCatchVariableValue(Isolate* isolate,
   11913                                   Handle<Context> context,
   11914                                   Handle<String> variable_name,
   11915                                   Handle<Object> new_value) {
   11916   DCHECK(context->IsCatchContext());
   11917   Handle<String> name(String::cast(context->extension()));
   11918   if (!String::Equals(name, variable_name)) {
   11919     return false;
   11920   }
   11921   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
   11922   return true;
   11923 }
   11924 
   11925 
   11926 // Create a plain JSObject which materializes the block scope for the specified
   11927 // block context.
   11928 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
   11929     Isolate* isolate,
   11930     Handle<Context> context) {
   11931   DCHECK(context->IsBlockContext());
   11932   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11933 
   11934   // Allocate and initialize a JSObject with all the arguments, stack locals
   11935   // heap locals and extension properties of the debugged function.
   11936   Handle<JSObject> block_scope =
   11937       isolate->factory()->NewJSObject(isolate->object_function());
   11938 
   11939   // Fill all context locals.
   11940   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11941           scope_info, context, block_scope)) {
   11942     return MaybeHandle<JSObject>();
   11943   }
   11944 
   11945   return block_scope;
   11946 }
   11947 
   11948 
   11949 // Create a plain JSObject which materializes the module scope for the specified
   11950 // module context.
   11951 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
   11952     Isolate* isolate,
   11953     Handle<Context> context) {
   11954   DCHECK(context->IsModuleContext());
   11955   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11956 
   11957   // Allocate and initialize a JSObject with all the members of the debugged
   11958   // module.
   11959   Handle<JSObject> module_scope =
   11960       isolate->factory()->NewJSObject(isolate->object_function());
   11961 
   11962   // Fill all context locals.
   11963   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11964           scope_info, context, module_scope)) {
   11965     return MaybeHandle<JSObject>();
   11966   }
   11967 
   11968   return module_scope;
   11969 }
   11970 
   11971 
   11972 // Iterate over the actual scopes visible from a stack frame or from a closure.
   11973 // The iteration proceeds from the innermost visible nested scope outwards.
   11974 // All scopes are backed by an actual context except the local scope,
   11975 // which is inserted "artificially" in the context chain.
   11976 class ScopeIterator {
   11977  public:
   11978   enum ScopeType {
   11979     ScopeTypeGlobal = 0,
   11980     ScopeTypeLocal,
   11981     ScopeTypeWith,
   11982     ScopeTypeClosure,
   11983     ScopeTypeCatch,
   11984     ScopeTypeBlock,
   11985     ScopeTypeModule
   11986   };
   11987 
   11988   ScopeIterator(Isolate* isolate,
   11989                 JavaScriptFrame* frame,
   11990                 int inlined_jsframe_index,
   11991                 bool ignore_nested_scopes = false)
   11992     : isolate_(isolate),
   11993       frame_(frame),
   11994       inlined_jsframe_index_(inlined_jsframe_index),
   11995       function_(frame->function()),
   11996       context_(Context::cast(frame->context())),
   11997       nested_scope_chain_(4),
   11998       failed_(false) {
   11999 
   12000     // Catch the case when the debugger stops in an internal function.
   12001     Handle<SharedFunctionInfo> shared_info(function_->shared());
   12002     Handle<ScopeInfo> scope_info(shared_info->scope_info());
   12003     if (shared_info->script() == isolate->heap()->undefined_value()) {
   12004       while (context_->closure() == *function_) {
   12005         context_ = Handle<Context>(context_->previous(), isolate_);
   12006       }
   12007       return;
   12008     }
   12009 
   12010     // Get the debug info (create it if it does not exist).
   12011     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
   12012       // Return if ensuring debug info failed.
   12013       return;
   12014     }
   12015 
   12016     // Currently it takes too much time to find nested scopes due to script
   12017     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
   12018     // (for example, while collecting async call stacks on every
   12019     // addEventListener call), even if we drop some nested scopes.
   12020     // Later we may optimize getting the nested scopes (cache the result?)
   12021     // and include nested scopes into the "fast" iteration case as well.
   12022     if (!ignore_nested_scopes) {
   12023       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
   12024 
   12025       // Find the break point where execution has stopped.
   12026       BreakLocationIterator break_location_iterator(debug_info,
   12027                                                     ALL_BREAK_LOCATIONS);
   12028       // pc points to the instruction after the current one, possibly a break
   12029       // location as well. So the "- 1" to exclude it from the search.
   12030       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   12031 
   12032       // Within the return sequence at the moment it is not possible to
   12033       // get a source position which is consistent with the current scope chain.
   12034       // Thus all nested with, catch and block contexts are skipped and we only
   12035       // provide the function scope.
   12036       ignore_nested_scopes = break_location_iterator.IsExit();
   12037     }
   12038 
   12039     if (ignore_nested_scopes) {
   12040       if (scope_info->HasContext()) {
   12041         context_ = Handle<Context>(context_->declaration_context(), isolate_);
   12042       } else {
   12043         while (context_->closure() == *function_) {
   12044           context_ = Handle<Context>(context_->previous(), isolate_);
   12045         }
   12046       }
   12047       if (scope_info->scope_type() == FUNCTION_SCOPE) {
   12048         nested_scope_chain_.Add(scope_info);
   12049       }
   12050     } else {
   12051       // Reparse the code and analyze the scopes.
   12052       Handle<Script> script(Script::cast(shared_info->script()));
   12053       Scope* scope = NULL;
   12054 
   12055       // Check whether we are in global, eval or function code.
   12056       Handle<ScopeInfo> scope_info(shared_info->scope_info());
   12057       if (scope_info->scope_type() != FUNCTION_SCOPE) {
   12058         // Global or eval code.
   12059         CompilationInfoWithZone info(script);
   12060         if (scope_info->scope_type() == GLOBAL_SCOPE) {
   12061           info.MarkAsGlobal();
   12062         } else {
   12063           DCHECK(scope_info->scope_type() == EVAL_SCOPE);
   12064           info.MarkAsEval();
   12065           info.SetContext(Handle<Context>(function_->context()));
   12066         }
   12067         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   12068           scope = info.function()->scope();
   12069         }
   12070         RetrieveScopeChain(scope, shared_info);
   12071       } else {
   12072         // Function code
   12073         CompilationInfoWithZone info(shared_info);
   12074         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   12075           scope = info.function()->scope();
   12076         }
   12077         RetrieveScopeChain(scope, shared_info);
   12078       }
   12079     }
   12080   }
   12081 
   12082   ScopeIterator(Isolate* isolate,
   12083                 Handle<JSFunction> function)
   12084     : isolate_(isolate),
   12085       frame_(NULL),
   12086       inlined_jsframe_index_(0),
   12087       function_(function),
   12088       context_(function->context()),
   12089       failed_(false) {
   12090     if (function->IsBuiltin()) {
   12091       context_ = Handle<Context>();
   12092     }
   12093   }
   12094 
   12095   // More scopes?
   12096   bool Done() {
   12097     DCHECK(!failed_);
   12098     return context_.is_null();
   12099   }
   12100 
   12101   bool Failed() { return failed_; }
   12102 
   12103   // Move to the next scope.
   12104   void Next() {
   12105     DCHECK(!failed_);
   12106     ScopeType scope_type = Type();
   12107     if (scope_type == ScopeTypeGlobal) {
   12108       // The global scope is always the last in the chain.
   12109       DCHECK(context_->IsNativeContext());
   12110       context_ = Handle<Context>();
   12111       return;
   12112     }
   12113     if (nested_scope_chain_.is_empty()) {
   12114       context_ = Handle<Context>(context_->previous(), isolate_);
   12115     } else {
   12116       if (nested_scope_chain_.last()->HasContext()) {
   12117         DCHECK(context_->previous() != NULL);
   12118         context_ = Handle<Context>(context_->previous(), isolate_);
   12119       }
   12120       nested_scope_chain_.RemoveLast();
   12121     }
   12122   }
   12123 
   12124   // Return the type of the current scope.
   12125   ScopeType Type() {
   12126     DCHECK(!failed_);
   12127     if (!nested_scope_chain_.is_empty()) {
   12128       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
   12129       switch (scope_info->scope_type()) {
   12130         case FUNCTION_SCOPE:
   12131           DCHECK(context_->IsFunctionContext() ||
   12132                  !scope_info->HasContext());
   12133           return ScopeTypeLocal;
   12134         case MODULE_SCOPE:
   12135           DCHECK(context_->IsModuleContext());
   12136           return ScopeTypeModule;
   12137         case GLOBAL_SCOPE:
   12138           DCHECK(context_->IsNativeContext());
   12139           return ScopeTypeGlobal;
   12140         case WITH_SCOPE:
   12141           DCHECK(context_->IsWithContext());
   12142           return ScopeTypeWith;
   12143         case CATCH_SCOPE:
   12144           DCHECK(context_->IsCatchContext());
   12145           return ScopeTypeCatch;
   12146         case BLOCK_SCOPE:
   12147           DCHECK(!scope_info->HasContext() ||
   12148                  context_->IsBlockContext());
   12149           return ScopeTypeBlock;
   12150         case EVAL_SCOPE:
   12151           UNREACHABLE();
   12152       }
   12153     }
   12154     if (context_->IsNativeContext()) {
   12155       DCHECK(context_->global_object()->IsGlobalObject());
   12156       return ScopeTypeGlobal;
   12157     }
   12158     if (context_->IsFunctionContext()) {
   12159       return ScopeTypeClosure;
   12160     }
   12161     if (context_->IsCatchContext()) {
   12162       return ScopeTypeCatch;
   12163     }
   12164     if (context_->IsBlockContext()) {
   12165       return ScopeTypeBlock;
   12166     }
   12167     if (context_->IsModuleContext()) {
   12168       return ScopeTypeModule;
   12169     }
   12170     DCHECK(context_->IsWithContext());
   12171     return ScopeTypeWith;
   12172   }
   12173 
   12174   // Return the JavaScript object with the content of the current scope.
   12175   MaybeHandle<JSObject> ScopeObject() {
   12176     DCHECK(!failed_);
   12177     switch (Type()) {
   12178       case ScopeIterator::ScopeTypeGlobal:
   12179         return Handle<JSObject>(CurrentContext()->global_object());
   12180       case ScopeIterator::ScopeTypeLocal:
   12181         // Materialize the content of the local scope into a JSObject.
   12182         DCHECK(nested_scope_chain_.length() == 1);
   12183         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
   12184       case ScopeIterator::ScopeTypeWith:
   12185         // Return the with object.
   12186         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
   12187       case ScopeIterator::ScopeTypeCatch:
   12188         return MaterializeCatchScope(isolate_, CurrentContext());
   12189       case ScopeIterator::ScopeTypeClosure:
   12190         // Materialize the content of the closure scope into a JSObject.
   12191         return MaterializeClosure(isolate_, CurrentContext());
   12192       case ScopeIterator::ScopeTypeBlock:
   12193         return MaterializeBlockScope(isolate_, CurrentContext());
   12194       case ScopeIterator::ScopeTypeModule:
   12195         return MaterializeModuleScope(isolate_, CurrentContext());
   12196     }
   12197     UNREACHABLE();
   12198     return Handle<JSObject>();
   12199   }
   12200 
   12201   bool SetVariableValue(Handle<String> variable_name,
   12202                         Handle<Object> new_value) {
   12203     DCHECK(!failed_);
   12204     switch (Type()) {
   12205       case ScopeIterator::ScopeTypeGlobal:
   12206         break;
   12207       case ScopeIterator::ScopeTypeLocal:
   12208         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
   12209             variable_name, new_value);
   12210       case ScopeIterator::ScopeTypeWith:
   12211         break;
   12212       case ScopeIterator::ScopeTypeCatch:
   12213         return SetCatchVariableValue(isolate_, CurrentContext(),
   12214             variable_name, new_value);
   12215       case ScopeIterator::ScopeTypeClosure:
   12216         return SetClosureVariableValue(isolate_, CurrentContext(),
   12217             variable_name, new_value);
   12218       case ScopeIterator::ScopeTypeBlock:
   12219         // TODO(2399): should we implement it?
   12220         break;
   12221       case ScopeIterator::ScopeTypeModule:
   12222         // TODO(2399): should we implement it?
   12223         break;
   12224     }
   12225     return false;
   12226   }
   12227 
   12228   Handle<ScopeInfo> CurrentScopeInfo() {
   12229     DCHECK(!failed_);
   12230     if (!nested_scope_chain_.is_empty()) {
   12231       return nested_scope_chain_.last();
   12232     } else if (context_->IsBlockContext()) {
   12233       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
   12234     } else if (context_->IsFunctionContext()) {
   12235       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
   12236     }
   12237     return Handle<ScopeInfo>::null();
   12238   }
   12239 
   12240   // Return the context for this scope. For the local context there might not
   12241   // be an actual context.
   12242   Handle<Context> CurrentContext() {
   12243     DCHECK(!failed_);
   12244     if (Type() == ScopeTypeGlobal ||
   12245         nested_scope_chain_.is_empty()) {
   12246       return context_;
   12247     } else if (nested_scope_chain_.last()->HasContext()) {
   12248       return context_;
   12249     } else {
   12250       return Handle<Context>();
   12251     }
   12252   }
   12253 
   12254 #ifdef DEBUG
   12255   // Debug print of the content of the current scope.
   12256   void DebugPrint() {
   12257     OFStream os(stdout);
   12258     DCHECK(!failed_);
   12259     switch (Type()) {
   12260       case ScopeIterator::ScopeTypeGlobal:
   12261         os << "Global:\n";
   12262         CurrentContext()->Print(os);
   12263         break;
   12264 
   12265       case ScopeIterator::ScopeTypeLocal: {
   12266         os << "Local:\n";
   12267         function_->shared()->scope_info()->Print();
   12268         if (!CurrentContext().is_null()) {
   12269           CurrentContext()->Print(os);
   12270           if (CurrentContext()->has_extension()) {
   12271             Handle<Object> extension(CurrentContext()->extension(), isolate_);
   12272             if (extension->IsJSContextExtensionObject()) {
   12273               extension->Print(os);
   12274             }
   12275           }
   12276         }
   12277         break;
   12278       }
   12279 
   12280       case ScopeIterator::ScopeTypeWith:
   12281         os << "With:\n";
   12282         CurrentContext()->extension()->Print(os);
   12283         break;
   12284 
   12285       case ScopeIterator::ScopeTypeCatch:
   12286         os << "Catch:\n";
   12287         CurrentContext()->extension()->Print(os);
   12288         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
   12289         break;
   12290 
   12291       case ScopeIterator::ScopeTypeClosure:
   12292         os << "Closure:\n";
   12293         CurrentContext()->Print(os);
   12294         if (CurrentContext()->has_extension()) {
   12295           Handle<Object> extension(CurrentContext()->extension(), isolate_);
   12296           if (extension->IsJSContextExtensionObject()) {
   12297             extension->Print(os);
   12298           }
   12299         }
   12300         break;
   12301 
   12302       default:
   12303         UNREACHABLE();
   12304     }
   12305     PrintF("\n");
   12306   }
   12307 #endif
   12308 
   12309  private:
   12310   Isolate* isolate_;
   12311   JavaScriptFrame* frame_;
   12312   int inlined_jsframe_index_;
   12313   Handle<JSFunction> function_;
   12314   Handle<Context> context_;
   12315   List<Handle<ScopeInfo> > nested_scope_chain_;
   12316   bool failed_;
   12317 
   12318   void RetrieveScopeChain(Scope* scope,
   12319                           Handle<SharedFunctionInfo> shared_info) {
   12320     if (scope != NULL) {
   12321       int source_position = shared_info->code()->SourcePosition(frame_->pc());
   12322       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
   12323     } else {
   12324       // A failed reparse indicates that the preparser has diverged from the
   12325       // parser or that the preparse data given to the initial parse has been
   12326       // faulty. We fail in debug mode but in release mode we only provide the
   12327       // information we get from the context chain but nothing about
   12328       // completely stack allocated scopes or stack allocated locals.
   12329       // Or it could be due to stack overflow.
   12330       DCHECK(isolate_->has_pending_exception());
   12331       failed_ = true;
   12332     }
   12333   }
   12334 
   12335   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
   12336 };
   12337 
   12338 
   12339 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
   12340   HandleScope scope(isolate);
   12341   DCHECK(args.length() == 2);
   12342   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12343   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12344 
   12345   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12346 
   12347   // Get the frame where the debugging is performed.
   12348   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12349   JavaScriptFrameIterator it(isolate, id);
   12350   JavaScriptFrame* frame = it.frame();
   12351 
   12352   // Count the visible scopes.
   12353   int n = 0;
   12354   for (ScopeIterator it(isolate, frame, 0);
   12355        !it.Done();
   12356        it.Next()) {
   12357     n++;
   12358   }
   12359 
   12360   return Smi::FromInt(n);
   12361 }
   12362 
   12363 
   12364 // Returns the list of step-in positions (text offset) in a function of the
   12365 // stack frame in a range from the current debug break position to the end
   12366 // of the corresponding statement.
   12367 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
   12368   HandleScope scope(isolate);
   12369   DCHECK(args.length() == 2);
   12370   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12371   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12372 
   12373   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12374 
   12375   // Get the frame where the debugging is performed.
   12376   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12377   JavaScriptFrameIterator frame_it(isolate, id);
   12378   RUNTIME_ASSERT(!frame_it.done());
   12379 
   12380   JavaScriptFrame* frame = frame_it.frame();
   12381 
   12382   Handle<JSFunction> fun =
   12383       Handle<JSFunction>(frame->function());
   12384   Handle<SharedFunctionInfo> shared =
   12385       Handle<SharedFunctionInfo>(fun->shared());
   12386 
   12387   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
   12388     return isolate->heap()->undefined_value();
   12389   }
   12390 
   12391   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
   12392 
   12393   int len = 0;
   12394   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
   12395   // Find the break point where execution has stopped.
   12396   BreakLocationIterator break_location_iterator(debug_info,
   12397                                                 ALL_BREAK_LOCATIONS);
   12398 
   12399   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   12400   int current_statement_pos = break_location_iterator.statement_position();
   12401 
   12402   while (!break_location_iterator.Done()) {
   12403     bool accept;
   12404     if (break_location_iterator.pc() > frame->pc()) {
   12405       accept = true;
   12406     } else {
   12407       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
   12408       // The break point is near our pc. Could be a step-in possibility,
   12409       // that is currently taken by active debugger call.
   12410       if (break_frame_id == StackFrame::NO_ID) {
   12411         // We are not stepping.
   12412         accept = false;
   12413       } else {
   12414         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
   12415         // If our frame is a top frame and we are stepping, we can do step-in
   12416         // at this place.
   12417         accept = additional_frame_it.frame()->id() == id;
   12418       }
   12419     }
   12420     if (accept) {
   12421       if (break_location_iterator.IsStepInLocation(isolate)) {
   12422         Smi* position_value = Smi::FromInt(break_location_iterator.position());
   12423         RETURN_FAILURE_ON_EXCEPTION(
   12424             isolate,
   12425             JSObject::SetElement(array, len,
   12426                                  Handle<Object>(position_value, isolate),
   12427                                  NONE, SLOPPY));
   12428         len++;
   12429       }
   12430     }
   12431     // Advance iterator.
   12432     break_location_iterator.Next();
   12433     if (current_statement_pos !=
   12434         break_location_iterator.statement_position()) {
   12435       break;
   12436     }
   12437   }
   12438   return *array;
   12439 }
   12440 
   12441 
   12442 static const int kScopeDetailsTypeIndex = 0;
   12443 static const int kScopeDetailsObjectIndex = 1;
   12444 static const int kScopeDetailsSize = 2;
   12445 
   12446 
   12447 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
   12448     Isolate* isolate,
   12449     ScopeIterator* it) {
   12450   // Calculate the size of the result.
   12451   int details_size = kScopeDetailsSize;
   12452   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   12453 
   12454   // Fill in scope details.
   12455   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
   12456   Handle<JSObject> scope_object;
   12457   ASSIGN_RETURN_ON_EXCEPTION(
   12458       isolate, scope_object, it->ScopeObject(), JSObject);
   12459   details->set(kScopeDetailsObjectIndex, *scope_object);
   12460 
   12461   return isolate->factory()->NewJSArrayWithElements(details);
   12462 }
   12463 
   12464 
   12465 // Return an array with scope details
   12466 // args[0]: number: break id
   12467 // args[1]: number: frame index
   12468 // args[2]: number: inlined frame index
   12469 // args[3]: number: scope index
   12470 //
   12471 // The array returned contains the following information:
   12472 // 0: Scope type
   12473 // 1: Scope object
   12474 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
   12475   HandleScope scope(isolate);
   12476   DCHECK(args.length() == 4);
   12477   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12478   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12479 
   12480   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12481   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12482   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12483 
   12484   // Get the frame where the debugging is performed.
   12485   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12486   JavaScriptFrameIterator frame_it(isolate, id);
   12487   JavaScriptFrame* frame = frame_it.frame();
   12488 
   12489   // Find the requested scope.
   12490   int n = 0;
   12491   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12492   for (; !it.Done() && n < index; it.Next()) {
   12493     n++;
   12494   }
   12495   if (it.Done()) {
   12496     return isolate->heap()->undefined_value();
   12497   }
   12498   Handle<JSObject> details;
   12499   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12500       isolate, details, MaterializeScopeDetails(isolate, &it));
   12501   return *details;
   12502 }
   12503 
   12504 
   12505 // Return an array of scope details
   12506 // args[0]: number: break id
   12507 // args[1]: number: frame index
   12508 // args[2]: number: inlined frame index
   12509 // args[3]: boolean: ignore nested scopes
   12510 //
   12511 // The array returned contains arrays with the following information:
   12512 // 0: Scope type
   12513 // 1: Scope object
   12514 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
   12515   HandleScope scope(isolate);
   12516   DCHECK(args.length() == 3 || args.length() == 4);
   12517   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12518   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12519 
   12520   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12521   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12522 
   12523   bool ignore_nested_scopes = false;
   12524   if (args.length() == 4) {
   12525     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
   12526     ignore_nested_scopes = flag;
   12527   }
   12528 
   12529   // Get the frame where the debugging is performed.
   12530   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12531   JavaScriptFrameIterator frame_it(isolate, id);
   12532   JavaScriptFrame* frame = frame_it.frame();
   12533 
   12534   List<Handle<JSObject> > result(4);
   12535   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
   12536   for (; !it.Done(); it.Next()) {
   12537     Handle<JSObject> details;
   12538     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12539         isolate, details, MaterializeScopeDetails(isolate, &it));
   12540     result.Add(details);
   12541   }
   12542 
   12543   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
   12544   for (int i = 0; i < result.length(); ++i) {
   12545     array->set(i, *result[i]);
   12546   }
   12547   return *isolate->factory()->NewJSArrayWithElements(array);
   12548 }
   12549 
   12550 
   12551 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
   12552   HandleScope scope(isolate);
   12553   DCHECK(args.length() == 1);
   12554 
   12555   // Check arguments.
   12556   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12557 
   12558   // Count the visible scopes.
   12559   int n = 0;
   12560   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
   12561     n++;
   12562   }
   12563 
   12564   return Smi::FromInt(n);
   12565 }
   12566 
   12567 
   12568 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
   12569   HandleScope scope(isolate);
   12570   DCHECK(args.length() == 2);
   12571 
   12572   // Check arguments.
   12573   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12574   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12575 
   12576   // Find the requested scope.
   12577   int n = 0;
   12578   ScopeIterator it(isolate, fun);
   12579   for (; !it.Done() && n < index; it.Next()) {
   12580     n++;
   12581   }
   12582   if (it.Done()) {
   12583     return isolate->heap()->undefined_value();
   12584   }
   12585 
   12586   Handle<JSObject> details;
   12587   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12588       isolate, details, MaterializeScopeDetails(isolate, &it));
   12589   return *details;
   12590 }
   12591 
   12592 
   12593 static bool SetScopeVariableValue(ScopeIterator* it, int index,
   12594                                   Handle<String> variable_name,
   12595                                   Handle<Object> new_value) {
   12596   for (int n = 0; !it->Done() && n < index; it->Next()) {
   12597     n++;
   12598   }
   12599   if (it->Done()) {
   12600     return false;
   12601   }
   12602   return it->SetVariableValue(variable_name, new_value);
   12603 }
   12604 
   12605 
   12606 // Change variable value in closure or local scope
   12607 // args[0]: number or JsFunction: break id or function
   12608 // args[1]: number: frame index (when arg[0] is break id)
   12609 // args[2]: number: inlined frame index (when arg[0] is break id)
   12610 // args[3]: number: scope index
   12611 // args[4]: string: variable name
   12612 // args[5]: object: new value
   12613 //
   12614 // Return true if success and false otherwise
   12615 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
   12616   HandleScope scope(isolate);
   12617   DCHECK(args.length() == 6);
   12618 
   12619   // Check arguments.
   12620   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12621   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
   12622   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
   12623 
   12624   bool res;
   12625   if (args[0]->IsNumber()) {
   12626     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12627     RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12628 
   12629     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12630     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12631 
   12632     // Get the frame where the debugging is performed.
   12633     StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12634     JavaScriptFrameIterator frame_it(isolate, id);
   12635     JavaScriptFrame* frame = frame_it.frame();
   12636 
   12637     ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12638     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12639   } else {
   12640     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12641     ScopeIterator it(isolate, fun);
   12642     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12643   }
   12644 
   12645   return isolate->heap()->ToBoolean(res);
   12646 }
   12647 
   12648 
   12649 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
   12650   HandleScope scope(isolate);
   12651   DCHECK(args.length() == 0);
   12652 
   12653 #ifdef DEBUG
   12654   // Print the scopes for the top frame.
   12655   StackFrameLocator locator(isolate);
   12656   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
   12657   for (ScopeIterator it(isolate, frame, 0);
   12658        !it.Done();
   12659        it.Next()) {
   12660     it.DebugPrint();
   12661   }
   12662 #endif
   12663   return isolate->heap()->undefined_value();
   12664 }
   12665 
   12666 
   12667 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
   12668   HandleScope scope(isolate);
   12669   DCHECK(args.length() == 1);
   12670   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12671   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12672 
   12673   // Count all archived V8 threads.
   12674   int n = 0;
   12675   for (ThreadState* thread =
   12676           isolate->thread_manager()->FirstThreadStateInUse();
   12677        thread != NULL;
   12678        thread = thread->Next()) {
   12679     n++;
   12680   }
   12681 
   12682   // Total number of threads is current thread and archived threads.
   12683   return Smi::FromInt(n + 1);
   12684 }
   12685 
   12686 
   12687 static const int kThreadDetailsCurrentThreadIndex = 0;
   12688 static const int kThreadDetailsThreadIdIndex = 1;
   12689 static const int kThreadDetailsSize = 2;
   12690 
   12691 // Return an array with thread details
   12692 // args[0]: number: break id
   12693 // args[1]: number: thread index
   12694 //
   12695 // The array returned contains the following information:
   12696 // 0: Is current thread?
   12697 // 1: Thread id
   12698 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
   12699   HandleScope scope(isolate);
   12700   DCHECK(args.length() == 2);
   12701   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12702   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12703 
   12704   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12705 
   12706   // Allocate array for result.
   12707   Handle<FixedArray> details =
   12708       isolate->factory()->NewFixedArray(kThreadDetailsSize);
   12709 
   12710   // Thread index 0 is current thread.
   12711   if (index == 0) {
   12712     // Fill the details.
   12713     details->set(kThreadDetailsCurrentThreadIndex,
   12714                  isolate->heap()->true_value());
   12715     details->set(kThreadDetailsThreadIdIndex,
   12716                  Smi::FromInt(ThreadId::Current().ToInteger()));
   12717   } else {
   12718     // Find the thread with the requested index.
   12719     int n = 1;
   12720     ThreadState* thread =
   12721         isolate->thread_manager()->FirstThreadStateInUse();
   12722     while (index != n && thread != NULL) {
   12723       thread = thread->Next();
   12724       n++;
   12725     }
   12726     if (thread == NULL) {
   12727       return isolate->heap()->undefined_value();
   12728     }
   12729 
   12730     // Fill the details.
   12731     details->set(kThreadDetailsCurrentThreadIndex,
   12732                  isolate->heap()->false_value());
   12733     details->set(kThreadDetailsThreadIdIndex,
   12734                  Smi::FromInt(thread->id().ToInteger()));
   12735   }
   12736 
   12737   // Convert to JS array and return.
   12738   return *isolate->factory()->NewJSArrayWithElements(details);
   12739 }
   12740 
   12741 
   12742 // Sets the disable break state
   12743 // args[0]: disable break state
   12744 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
   12745   HandleScope scope(isolate);
   12746   DCHECK(args.length() == 1);
   12747   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
   12748   isolate->debug()->set_disable_break(disable_break);
   12749   return  isolate->heap()->undefined_value();
   12750 }
   12751 
   12752 
   12753 static bool IsPositionAlignmentCodeCorrect(int alignment) {
   12754   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
   12755 }
   12756 
   12757 
   12758 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
   12759   HandleScope scope(isolate);
   12760   DCHECK(args.length() == 2);
   12761 
   12762   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12763   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
   12764 
   12765   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12766     return isolate->ThrowIllegalOperation();
   12767   }
   12768   BreakPositionAlignment alignment =
   12769       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12770 
   12771   Handle<SharedFunctionInfo> shared(fun->shared());
   12772   // Find the number of break points
   12773   Handle<Object> break_locations =
   12774       Debug::GetSourceBreakLocations(shared, alignment);
   12775   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   12776   // Return array as JS array
   12777   return *isolate->factory()->NewJSArrayWithElements(
   12778       Handle<FixedArray>::cast(break_locations));
   12779 }
   12780 
   12781 
   12782 // Set a break point in a function.
   12783 // args[0]: function
   12784 // args[1]: number: break source position (within the function source)
   12785 // args[2]: number: break point object
   12786 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
   12787   HandleScope scope(isolate);
   12788   DCHECK(args.length() == 3);
   12789   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   12790   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12791   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
   12792                  source_position <= function->shared()->end_position());
   12793   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
   12794 
   12795   // Set break point.
   12796   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
   12797       function, break_point_object_arg, &source_position));
   12798 
   12799   return Smi::FromInt(source_position);
   12800 }
   12801 
   12802 
   12803 // Changes the state of a break point in a script and returns source position
   12804 // where break point was set. NOTE: Regarding performance see the NOTE for
   12805 // GetScriptFromScriptData.
   12806 // args[0]: script to set break point in
   12807 // args[1]: number: break source position (within the script source)
   12808 // args[2]: number, breakpoint position alignment
   12809 // args[3]: number: break point object
   12810 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
   12811   HandleScope scope(isolate);
   12812   DCHECK(args.length() == 4);
   12813   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   12814   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12815   RUNTIME_ASSERT(source_position >= 0);
   12816   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
   12817   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
   12818 
   12819   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12820     return isolate->ThrowIllegalOperation();
   12821   }
   12822   BreakPositionAlignment alignment =
   12823       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12824 
   12825   // Get the script from the script wrapper.
   12826   RUNTIME_ASSERT(wrapper->value()->IsScript());
   12827   Handle<Script> script(Script::cast(wrapper->value()));
   12828 
   12829   // Set break point.
   12830   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
   12831                                                 &source_position,
   12832                                                 alignment)) {
   12833     return isolate->heap()->undefined_value();
   12834   }
   12835 
   12836   return Smi::FromInt(source_position);
   12837 }
   12838 
   12839 
   12840 // Clear a break point
   12841 // args[0]: number: break point object
   12842 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
   12843   HandleScope scope(isolate);
   12844   DCHECK(args.length() == 1);
   12845   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
   12846 
   12847   // Clear break point.
   12848   isolate->debug()->ClearBreakPoint(break_point_object_arg);
   12849 
   12850   return isolate->heap()->undefined_value();
   12851 }
   12852 
   12853 
   12854 // Change the state of break on exceptions.
   12855 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
   12856 // args[1]: Boolean indicating on/off.
   12857 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
   12858   HandleScope scope(isolate);
   12859   DCHECK(args.length() == 2);
   12860   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
   12861   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
   12862 
   12863   // If the number doesn't match an enum value, the ChangeBreakOnException
   12864   // function will default to affecting caught exceptions.
   12865   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
   12866   // Update break point state.
   12867   isolate->debug()->ChangeBreakOnException(type, enable);
   12868   return isolate->heap()->undefined_value();
   12869 }
   12870 
   12871 
   12872 // Returns the state of break on exceptions
   12873 // args[0]: boolean indicating uncaught exceptions
   12874 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
   12875   HandleScope scope(isolate);
   12876   DCHECK(args.length() == 1);
   12877   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
   12878 
   12879   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
   12880   bool result = isolate->debug()->IsBreakOnException(type);
   12881   return Smi::FromInt(result);
   12882 }
   12883 
   12884 
   12885 // Prepare for stepping
   12886 // args[0]: break id for checking execution state
   12887 // args[1]: step action from the enumeration StepAction
   12888 // args[2]: number of times to perform the step, for step out it is the number
   12889 //          of frames to step down.
   12890 RUNTIME_FUNCTION(Runtime_PrepareStep) {
   12891   HandleScope scope(isolate);
   12892   DCHECK(args.length() == 4);
   12893   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12894   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12895 
   12896   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
   12897     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12898   }
   12899 
   12900   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
   12901 
   12902   StackFrame::Id frame_id;
   12903   if (wrapped_frame_id == 0) {
   12904     frame_id = StackFrame::NO_ID;
   12905   } else {
   12906     frame_id = UnwrapFrameId(wrapped_frame_id);
   12907   }
   12908 
   12909   // Get the step action and check validity.
   12910   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   12911   if (step_action != StepIn &&
   12912       step_action != StepNext &&
   12913       step_action != StepOut &&
   12914       step_action != StepInMin &&
   12915       step_action != StepMin) {
   12916     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12917   }
   12918 
   12919   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
   12920       step_action != StepMin && step_action != StepOut) {
   12921     return isolate->ThrowIllegalOperation();
   12922   }
   12923 
   12924   // Get the number of steps.
   12925   int step_count = NumberToInt32(args[2]);
   12926   if (step_count < 1) {
   12927     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12928   }
   12929 
   12930   // Clear all current stepping setup.
   12931   isolate->debug()->ClearStepping();
   12932 
   12933   // Prepare step.
   12934   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
   12935                                 step_count,
   12936                                 frame_id);
   12937   return isolate->heap()->undefined_value();
   12938 }
   12939 
   12940 
   12941 // Clear all stepping set by PrepareStep.
   12942 RUNTIME_FUNCTION(Runtime_ClearStepping) {
   12943   HandleScope scope(isolate);
   12944   DCHECK(args.length() == 0);
   12945   isolate->debug()->ClearStepping();
   12946   return isolate->heap()->undefined_value();
   12947 }
   12948 
   12949 
   12950 // Helper function to find or create the arguments object for
   12951 // Runtime_DebugEvaluate.
   12952 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
   12953     Isolate* isolate,
   12954     Handle<JSObject> target,
   12955     Handle<JSFunction> function) {
   12956   // Do not materialize the arguments object for eval or top-level code.
   12957   // Skip if "arguments" is already taken.
   12958   if (!function->shared()->is_function()) return target;
   12959   Maybe<bool> maybe = JSReceiver::HasOwnProperty(
   12960       target, isolate->factory()->arguments_string());
   12961   if (!maybe.has_value) return MaybeHandle<JSObject>();
   12962   if (maybe.value) return target;
   12963 
   12964   // FunctionGetArguments can't throw an exception.
   12965   Handle<JSObject> arguments = Handle<JSObject>::cast(
   12966       Accessors::FunctionGetArguments(function));
   12967   Handle<String> arguments_str = isolate->factory()->arguments_string();
   12968   RETURN_ON_EXCEPTION(
   12969       isolate,
   12970       Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE),
   12971       JSObject);
   12972   return target;
   12973 }
   12974 
   12975 
   12976 // Compile and evaluate source for the given context.
   12977 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
   12978                                          Handle<SharedFunctionInfo> outer_info,
   12979                                          Handle<Context> context,
   12980                                          Handle<Object> context_extension,
   12981                                          Handle<Object> receiver,
   12982                                          Handle<String> source) {
   12983   if (context_extension->IsJSObject()) {
   12984     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
   12985     Handle<JSFunction> closure(context->closure(), isolate);
   12986     context = isolate->factory()->NewWithContext(closure, context, extension);
   12987   }
   12988 
   12989   Handle<JSFunction> eval_fun;
   12990   ASSIGN_RETURN_ON_EXCEPTION(
   12991       isolate, eval_fun,
   12992       Compiler::GetFunctionFromEval(source,
   12993                                     outer_info,
   12994                                     context,
   12995                                     SLOPPY,
   12996                                     NO_PARSE_RESTRICTION,
   12997                                     RelocInfo::kNoPosition),
   12998       Object);
   12999 
   13000   Handle<Object> result;
   13001   ASSIGN_RETURN_ON_EXCEPTION(
   13002       isolate, result,
   13003       Execution::Call(isolate, eval_fun, receiver, 0, NULL),
   13004       Object);
   13005 
   13006   // Skip the global proxy as it has no properties and always delegates to the
   13007   // real global object.
   13008   if (result->IsJSGlobalProxy()) {
   13009     PrototypeIterator iter(isolate, result);
   13010     // TODO(verwaest): This will crash when the global proxy is detached.
   13011     result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   13012   }
   13013 
   13014   // Clear the oneshot breakpoints so that the debugger does not step further.
   13015   isolate->debug()->ClearStepping();
   13016   return result;
   13017 }
   13018 
   13019 
   13020 static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
   13021   Handle<JSObject> result =
   13022       isolate->factory()->NewJSObject(isolate->object_function());
   13023   Handle<Map> new_map = Map::Copy(Handle<Map>(result->map()));
   13024   new_map->set_prototype(*isolate->factory()->null_value());
   13025   JSObject::MigrateToMap(result, new_map);
   13026   return result;
   13027 }
   13028 
   13029 
   13030 // Evaluate a piece of JavaScript in the context of a stack frame for
   13031 // debugging.  Things that need special attention are:
   13032 // - Parameters and stack-allocated locals need to be materialized.  Altered
   13033 //   values need to be written back to the stack afterwards.
   13034 // - The arguments object needs to materialized.
   13035 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
   13036   HandleScope scope(isolate);
   13037 
   13038   // Check the execution state and decode arguments frame and source to be
   13039   // evaluated.
   13040   DCHECK(args.length() == 6);
   13041   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   13042   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   13043 
   13044   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   13045   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   13046   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
   13047   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
   13048   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
   13049 
   13050   // Handle the processing of break.
   13051   DisableBreak disable_break_scope(isolate->debug(), disable_break);
   13052 
   13053   // Get the frame where the debugging is performed.
   13054   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   13055   JavaScriptFrameIterator it(isolate, id);
   13056   JavaScriptFrame* frame = it.frame();
   13057   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   13058   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   13059   Handle<SharedFunctionInfo> outer_info(function->shared());
   13060 
   13061   // Traverse the saved contexts chain to find the active context for the
   13062   // selected frame.
   13063   SaveContext* save = FindSavedContextForFrame(isolate, frame);
   13064 
   13065   SaveContext savex(isolate);
   13066   isolate->set_context(*(save->context()));
   13067 
   13068   // Evaluate on the context of the frame.
   13069   Handle<Context> context(Context::cast(frame_inspector.GetContext()));
   13070   DCHECK(!context.is_null());
   13071 
   13072   // Materialize stack locals and the arguments object.
   13073   Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
   13074 
   13075   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13076       isolate, materialized,
   13077       MaterializeStackLocalsWithFrameInspector(
   13078           isolate, materialized, function, &frame_inspector));
   13079 
   13080   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13081       isolate, materialized,
   13082       MaterializeArgumentsObject(isolate, materialized, function));
   13083 
   13084   // Add the materialized object in a with-scope to shadow the stack locals.
   13085   context = isolate->factory()->NewWithContext(function, context, materialized);
   13086 
   13087   Handle<Object> receiver(frame->receiver(), isolate);
   13088   Handle<Object> result;
   13089   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13090       isolate, result,
   13091       DebugEvaluate(isolate, outer_info,
   13092                     context, context_extension, receiver, source));
   13093 
   13094   // Write back potential changes to materialized stack locals to the stack.
   13095   UpdateStackLocalsFromMaterializedObject(
   13096       isolate, materialized, function, frame, inlined_jsframe_index);
   13097 
   13098   return *result;
   13099 }
   13100 
   13101 
   13102 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
   13103   HandleScope scope(isolate);
   13104 
   13105   // Check the execution state and decode arguments frame and source to be
   13106   // evaluated.
   13107   DCHECK(args.length() == 4);
   13108   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   13109   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   13110 
   13111   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13112   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
   13113   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
   13114 
   13115   // Handle the processing of break.
   13116   DisableBreak disable_break_scope(isolate->debug(), disable_break);
   13117 
   13118   // Enter the top context from before the debugger was invoked.
   13119   SaveContext save(isolate);
   13120   SaveContext* top = &save;
   13121   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
   13122     top = top->prev();
   13123   }
   13124   if (top != NULL) {
   13125     isolate->set_context(*top->context());
   13126   }
   13127 
   13128   // Get the native context now set to the top context from before the
   13129   // debugger was invoked.
   13130   Handle<Context> context = isolate->native_context();
   13131   Handle<JSObject> receiver(context->global_proxy());
   13132   Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
   13133   Handle<Object> result;
   13134   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13135       isolate, result,
   13136       DebugEvaluate(isolate, outer_info,
   13137                     context, context_extension, receiver, source));
   13138   return *result;
   13139 }
   13140 
   13141 
   13142 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
   13143   HandleScope scope(isolate);
   13144   DCHECK(args.length() == 0);
   13145 
   13146   // Fill the script objects.
   13147   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
   13148 
   13149   // Convert the script objects to proper JS objects.
   13150   for (int i = 0; i < instances->length(); i++) {
   13151     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
   13152     // Get the script wrapper in a local handle before calling GetScriptWrapper,
   13153     // because using
   13154     //   instances->set(i, *GetScriptWrapper(script))
   13155     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
   13156     // already have dereferenced the instances handle.
   13157     Handle<JSObject> wrapper = Script::GetWrapper(script);
   13158     instances->set(i, *wrapper);
   13159   }
   13160 
   13161   // Return result as a JS array.
   13162   Handle<JSObject> result =
   13163       isolate->factory()->NewJSObject(isolate->array_function());
   13164   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   13165   return *result;
   13166 }
   13167 
   13168 
   13169 // Helper function used by Runtime_DebugReferencedBy below.
   13170 static int DebugReferencedBy(HeapIterator* iterator,
   13171                              JSObject* target,
   13172                              Object* instance_filter, int max_references,
   13173                              FixedArray* instances, int instances_size,
   13174                              JSFunction* arguments_function) {
   13175   Isolate* isolate = target->GetIsolate();
   13176   SealHandleScope shs(isolate);
   13177   DisallowHeapAllocation no_allocation;
   13178 
   13179   // Iterate the heap.
   13180   int count = 0;
   13181   JSObject* last = NULL;
   13182   HeapObject* heap_obj = NULL;
   13183   while (((heap_obj = iterator->next()) != NULL) &&
   13184          (max_references == 0 || count < max_references)) {
   13185     // Only look at all JSObjects.
   13186     if (heap_obj->IsJSObject()) {
   13187       // Skip context extension objects and argument arrays as these are
   13188       // checked in the context of functions using them.
   13189       JSObject* obj = JSObject::cast(heap_obj);
   13190       if (obj->IsJSContextExtensionObject() ||
   13191           obj->map()->constructor() == arguments_function) {
   13192         continue;
   13193       }
   13194 
   13195       // Check if the JS object has a reference to the object looked for.
   13196       if (obj->ReferencesObject(target)) {
   13197         // Check instance filter if supplied. This is normally used to avoid
   13198         // references from mirror objects (see Runtime_IsInPrototypeChain).
   13199         if (!instance_filter->IsUndefined()) {
   13200           for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
   13201                iter.Advance()) {
   13202             if (iter.GetCurrent() == instance_filter) {
   13203               obj = NULL;  // Don't add this object.
   13204               break;
   13205             }
   13206           }
   13207         }
   13208 
   13209         if (obj != NULL) {
   13210           // Valid reference found add to instance array if supplied an update
   13211           // count.
   13212           if (instances != NULL && count < instances_size) {
   13213             instances->set(count, obj);
   13214           }
   13215           last = obj;
   13216           count++;
   13217         }
   13218       }
   13219     }
   13220   }
   13221 
   13222   // Check for circular reference only. This can happen when the object is only
   13223   // referenced from mirrors and has a circular reference in which case the
   13224   // object is not really alive and would have been garbage collected if not
   13225   // referenced from the mirror.
   13226   if (count == 1 && last == target) {
   13227     count = 0;
   13228   }
   13229 
   13230   // Return the number of referencing objects found.
   13231   return count;
   13232 }
   13233 
   13234 
   13235 // Scan the heap for objects with direct references to an object
   13236 // args[0]: the object to find references to
   13237 // args[1]: constructor function for instances to exclude (Mirror)
   13238 // args[2]: the the maximum number of objects to return
   13239 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
   13240   HandleScope scope(isolate);
   13241   DCHECK(args.length() == 3);
   13242 
   13243   // Check parameters.
   13244   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
   13245   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
   13246   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
   13247                  instance_filter->IsJSObject());
   13248   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
   13249   RUNTIME_ASSERT(max_references >= 0);
   13250 
   13251 
   13252   // Get the constructor function for context extension and arguments array.
   13253   Handle<JSFunction> arguments_function(
   13254       JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
   13255 
   13256   // Get the number of referencing objects.
   13257   int count;
   13258   // First perform a full GC in order to avoid dead objects and to make the heap
   13259   // iterable.
   13260   Heap* heap = isolate->heap();
   13261   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
   13262   {
   13263     HeapIterator heap_iterator(heap);
   13264     count = DebugReferencedBy(&heap_iterator,
   13265                               *target, *instance_filter, max_references,
   13266                               NULL, 0, *arguments_function);
   13267   }
   13268 
   13269   // Allocate an array to hold the result.
   13270   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
   13271 
   13272   // Fill the referencing objects.
   13273   {
   13274     HeapIterator heap_iterator(heap);
   13275     count = DebugReferencedBy(&heap_iterator,
   13276                               *target, *instance_filter, max_references,
   13277                               *instances, count, *arguments_function);
   13278   }
   13279 
   13280   // Return result as JS array.
   13281   Handle<JSFunction> constructor = isolate->array_function();
   13282 
   13283   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
   13284   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   13285   return *result;
   13286 }
   13287 
   13288 
   13289 // Helper function used by Runtime_DebugConstructedBy below.
   13290 static int DebugConstructedBy(HeapIterator* iterator,
   13291                               JSFunction* constructor,
   13292                               int max_references,
   13293                               FixedArray* instances,
   13294                               int instances_size) {
   13295   DisallowHeapAllocation no_allocation;
   13296 
   13297   // Iterate the heap.
   13298   int count = 0;
   13299   HeapObject* heap_obj = NULL;
   13300   while (((heap_obj = iterator->next()) != NULL) &&
   13301          (max_references == 0 || count < max_references)) {
   13302     // Only look at all JSObjects.
   13303     if (heap_obj->IsJSObject()) {
   13304       JSObject* obj = JSObject::cast(heap_obj);
   13305       if (obj->map()->constructor() == constructor) {
   13306         // Valid reference found add to instance array if supplied an update
   13307         // count.
   13308         if (instances != NULL && count < instances_size) {
   13309           instances->set(count, obj);
   13310         }
   13311         count++;
   13312       }
   13313     }
   13314   }
   13315 
   13316   // Return the number of referencing objects found.
   13317   return count;
   13318 }
   13319 
   13320 
   13321 // Scan the heap for objects constructed by a specific function.
   13322 // args[0]: the constructor to find instances of
   13323 // args[1]: the the maximum number of objects to return
   13324 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
   13325   HandleScope scope(isolate);
   13326   DCHECK(args.length() == 2);
   13327 
   13328 
   13329   // Check parameters.
   13330   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
   13331   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   13332   RUNTIME_ASSERT(max_references >= 0);
   13333 
   13334   // Get the number of referencing objects.
   13335   int count;
   13336   // First perform a full GC in order to avoid dead objects and to make the heap
   13337   // iterable.
   13338   Heap* heap = isolate->heap();
   13339   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
   13340   {
   13341     HeapIterator heap_iterator(heap);
   13342     count = DebugConstructedBy(&heap_iterator,
   13343                                *constructor,
   13344                                max_references,
   13345                                NULL,
   13346                                0);
   13347   }
   13348 
   13349   // Allocate an array to hold the result.
   13350   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
   13351 
   13352   // Fill the referencing objects.
   13353   {
   13354     HeapIterator heap_iterator2(heap);
   13355     count = DebugConstructedBy(&heap_iterator2,
   13356                                *constructor,
   13357                                max_references,
   13358                                *instances,
   13359                                count);
   13360   }
   13361 
   13362   // Return result as JS array.
   13363   Handle<JSFunction> array_function = isolate->array_function();
   13364   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
   13365   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   13366   return *result;
   13367 }
   13368 
   13369 
   13370 // Find the effective prototype object as returned by __proto__.
   13371 // args[0]: the object to find the prototype for.
   13372 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
   13373   HandleScope shs(isolate);
   13374   DCHECK(args.length() == 1);
   13375   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   13376   return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
   13377 }
   13378 
   13379 
   13380 // Patches script source (should be called upon BeforeCompile event).
   13381 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
   13382   HandleScope scope(isolate);
   13383   DCHECK(args.length() == 2);
   13384 
   13385   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
   13386   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13387 
   13388   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
   13389   Handle<Script> script(Script::cast(script_wrapper->value()));
   13390 
   13391   int compilation_state = script->compilation_state();
   13392   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
   13393   script->set_source(*source);
   13394 
   13395   return isolate->heap()->undefined_value();
   13396 }
   13397 
   13398 
   13399 RUNTIME_FUNCTION(Runtime_SystemBreak) {
   13400   SealHandleScope shs(isolate);
   13401   DCHECK(args.length() == 0);
   13402   base::OS::DebugBreak();
   13403   return isolate->heap()->undefined_value();
   13404 }
   13405 
   13406 
   13407 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
   13408   HandleScope scope(isolate);
   13409 #ifdef DEBUG
   13410   DCHECK(args.length() == 1);
   13411   // Get the function and make sure it is compiled.
   13412   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13413   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13414     return isolate->heap()->exception();
   13415   }
   13416   OFStream os(stdout);
   13417   func->code()->Print(os);
   13418   os << endl;
   13419 #endif  // DEBUG
   13420   return isolate->heap()->undefined_value();
   13421 }
   13422 
   13423 
   13424 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
   13425   HandleScope scope(isolate);
   13426 #ifdef DEBUG
   13427   DCHECK(args.length() == 1);
   13428   // Get the function and make sure it is compiled.
   13429   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13430   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13431     return isolate->heap()->exception();
   13432   }
   13433   OFStream os(stdout);
   13434   func->shared()->construct_stub()->Print(os);
   13435   os << endl;
   13436 #endif  // DEBUG
   13437   return isolate->heap()->undefined_value();
   13438 }
   13439 
   13440 
   13441 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
   13442   SealHandleScope shs(isolate);
   13443   DCHECK(args.length() == 1);
   13444 
   13445   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   13446   return f->shared()->inferred_name();
   13447 }
   13448 
   13449 
   13450 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
   13451                                             Script* script,
   13452                                             FixedArray* buffer) {
   13453   DisallowHeapAllocation no_allocation;
   13454   int counter = 0;
   13455   int buffer_size = buffer->length();
   13456   for (HeapObject* obj = iterator->next();
   13457        obj != NULL;
   13458        obj = iterator->next()) {
   13459     DCHECK(obj != NULL);
   13460     if (!obj->IsSharedFunctionInfo()) {
   13461       continue;
   13462     }
   13463     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
   13464     if (shared->script() != script) {
   13465       continue;
   13466     }
   13467     if (counter < buffer_size) {
   13468       buffer->set(counter, shared);
   13469     }
   13470     counter++;
   13471   }
   13472   return counter;
   13473 }
   13474 
   13475 
   13476 // For a script finds all SharedFunctionInfo's in the heap that points
   13477 // to this script. Returns JSArray of SharedFunctionInfo wrapped
   13478 // in OpaqueReferences.
   13479 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
   13480   HandleScope scope(isolate);
   13481   CHECK(isolate->debug()->live_edit_enabled());
   13482   DCHECK(args.length() == 1);
   13483   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
   13484 
   13485   RUNTIME_ASSERT(script_value->value()->IsScript());
   13486   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
   13487 
   13488   const int kBufferSize = 32;
   13489 
   13490   Handle<FixedArray> array;
   13491   array = isolate->factory()->NewFixedArray(kBufferSize);
   13492   int number;
   13493   Heap* heap = isolate->heap();
   13494   {
   13495     HeapIterator heap_iterator(heap);
   13496     Script* scr = *script;
   13497     FixedArray* arr = *array;
   13498     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13499   }
   13500   if (number > kBufferSize) {
   13501     array = isolate->factory()->NewFixedArray(number);
   13502     HeapIterator heap_iterator(heap);
   13503     Script* scr = *script;
   13504     FixedArray* arr = *array;
   13505     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13506   }
   13507 
   13508   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
   13509   result->set_length(Smi::FromInt(number));
   13510 
   13511   LiveEdit::WrapSharedFunctionInfos(result);
   13512 
   13513   return *result;
   13514 }
   13515 
   13516 
   13517 // For a script calculates compilation information about all its functions.
   13518 // The script source is explicitly specified by the second argument.
   13519 // The source of the actual script is not used, however it is important that
   13520 // all generated code keeps references to this particular instance of script.
   13521 // Returns a JSArray of compilation infos. The array is ordered so that
   13522 // each function with all its descendant is always stored in a continues range
   13523 // with the function itself going first. The root function is a script function.
   13524 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
   13525   HandleScope scope(isolate);
   13526   CHECK(isolate->debug()->live_edit_enabled());
   13527   DCHECK(args.length() == 2);
   13528   CONVERT_ARG_CHECKED(JSValue, script, 0);
   13529   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13530 
   13531   RUNTIME_ASSERT(script->value()->IsScript());
   13532   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
   13533 
   13534   Handle<JSArray> result;
   13535   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13536       isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
   13537   return *result;
   13538 }
   13539 
   13540 
   13541 // Changes the source of the script to a new_source.
   13542 // If old_script_name is provided (i.e. is a String), also creates a copy of
   13543 // the script with its original source and sends notification to debugger.
   13544 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
   13545   HandleScope scope(isolate);
   13546   CHECK(isolate->debug()->live_edit_enabled());
   13547   DCHECK(args.length() == 3);
   13548   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
   13549   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
   13550   CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
   13551 
   13552   RUNTIME_ASSERT(original_script_value->value()->IsScript());
   13553   Handle<Script> original_script(Script::cast(original_script_value->value()));
   13554 
   13555   Handle<Object> old_script = LiveEdit::ChangeScriptSource(
   13556       original_script,  new_source,  old_script_name);
   13557 
   13558   if (old_script->IsScript()) {
   13559     Handle<Script> script_handle = Handle<Script>::cast(old_script);
   13560     return *Script::GetWrapper(script_handle);
   13561   } else {
   13562     return isolate->heap()->null_value();
   13563   }
   13564 }
   13565 
   13566 
   13567 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
   13568   HandleScope scope(isolate);
   13569   CHECK(isolate->debug()->live_edit_enabled());
   13570   DCHECK(args.length() == 1);
   13571   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
   13572   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
   13573 
   13574   LiveEdit::FunctionSourceUpdated(shared_info);
   13575   return isolate->heap()->undefined_value();
   13576 }
   13577 
   13578 
   13579 // Replaces code of SharedFunctionInfo with a new one.
   13580 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
   13581   HandleScope scope(isolate);
   13582   CHECK(isolate->debug()->live_edit_enabled());
   13583   DCHECK(args.length() == 2);
   13584   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
   13585   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
   13586   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
   13587 
   13588   LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
   13589   return isolate->heap()->undefined_value();
   13590 }
   13591 
   13592 
   13593 // Connects SharedFunctionInfo to another script.
   13594 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
   13595   HandleScope scope(isolate);
   13596   CHECK(isolate->debug()->live_edit_enabled());
   13597   DCHECK(args.length() == 2);
   13598   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
   13599   CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
   13600 
   13601   if (function_object->IsJSValue()) {
   13602     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
   13603     if (script_object->IsJSValue()) {
   13604       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
   13605       Script* script = Script::cast(JSValue::cast(*script_object)->value());
   13606       script_object = Handle<Object>(script, isolate);
   13607     }
   13608     RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
   13609     LiveEdit::SetFunctionScript(function_wrapper, script_object);
   13610   } else {
   13611     // Just ignore this. We may not have a SharedFunctionInfo for some functions
   13612     // and we check it in this function.
   13613   }
   13614 
   13615   return isolate->heap()->undefined_value();
   13616 }
   13617 
   13618 
   13619 // In a code of a parent function replaces original function as embedded object
   13620 // with a substitution one.
   13621 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
   13622   HandleScope scope(isolate);
   13623   CHECK(isolate->debug()->live_edit_enabled());
   13624   DCHECK(args.length() == 3);
   13625 
   13626   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
   13627   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
   13628   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
   13629   RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
   13630   RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
   13631   RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
   13632 
   13633   LiveEdit::ReplaceRefToNestedFunction(
   13634       parent_wrapper, orig_wrapper, subst_wrapper);
   13635   return isolate->heap()->undefined_value();
   13636 }
   13637 
   13638 
   13639 // Updates positions of a shared function info (first parameter) according
   13640 // to script source change. Text change is described in second parameter as
   13641 // array of groups of 3 numbers:
   13642 // (change_begin, change_end, change_end_new_position).
   13643 // Each group describes a change in text; groups are sorted by change_begin.
   13644 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
   13645   HandleScope scope(isolate);
   13646   CHECK(isolate->debug()->live_edit_enabled());
   13647   DCHECK(args.length() == 2);
   13648   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13649   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
   13650   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
   13651 
   13652   LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
   13653   return isolate->heap()->undefined_value();
   13654 }
   13655 
   13656 
   13657 // For array of SharedFunctionInfo's (each wrapped in JSValue)
   13658 // checks that none of them have activations on stacks (of any thread).
   13659 // Returns array of the same length with corresponding results of
   13660 // LiveEdit::FunctionPatchabilityStatus type.
   13661 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
   13662   HandleScope scope(isolate);
   13663   CHECK(isolate->debug()->live_edit_enabled());
   13664   DCHECK(args.length() == 2);
   13665   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13666   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
   13667   RUNTIME_ASSERT(shared_array->length()->IsSmi());
   13668   RUNTIME_ASSERT(shared_array->HasFastElements())
   13669   int array_length = Smi::cast(shared_array->length())->value();
   13670   for (int i = 0; i < array_length; i++) {
   13671     Handle<Object> element =
   13672         Object::GetElement(isolate, shared_array, i).ToHandleChecked();
   13673     RUNTIME_ASSERT(
   13674         element->IsJSValue() &&
   13675         Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
   13676   }
   13677 
   13678   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
   13679 }
   13680 
   13681 
   13682 // Compares 2 strings line-by-line, then token-wise and returns diff in form
   13683 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
   13684 // of diff chunks.
   13685 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
   13686   HandleScope scope(isolate);
   13687   CHECK(isolate->debug()->live_edit_enabled());
   13688   DCHECK(args.length() == 2);
   13689   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
   13690   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
   13691 
   13692   return *LiveEdit::CompareStrings(s1, s2);
   13693 }
   13694 
   13695 
   13696 // Restarts a call frame and completely drops all frames above.
   13697 // Returns true if successful. Otherwise returns undefined or an error message.
   13698 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
   13699   HandleScope scope(isolate);
   13700   CHECK(isolate->debug()->live_edit_enabled());
   13701   DCHECK(args.length() == 2);
   13702   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   13703   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   13704 
   13705   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   13706   Heap* heap = isolate->heap();
   13707 
   13708   // Find the relevant frame with the requested index.
   13709   StackFrame::Id id = isolate->debug()->break_frame_id();
   13710   if (id == StackFrame::NO_ID) {
   13711     // If there are no JavaScript stack frames return undefined.
   13712     return heap->undefined_value();
   13713   }
   13714 
   13715   JavaScriptFrameIterator it(isolate, id);
   13716   int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
   13717   if (inlined_jsframe_index == -1) return heap->undefined_value();
   13718   // We don't really care what the inlined frame index is, since we are
   13719   // throwing away the entire frame anyways.
   13720   const char* error_message = LiveEdit::RestartFrame(it.frame());
   13721   if (error_message) {
   13722     return *(isolate->factory()->InternalizeUtf8String(error_message));
   13723   }
   13724   return heap->true_value();
   13725 }
   13726 
   13727 
   13728 // A testing entry. Returns statement position which is the closest to
   13729 // source_position.
   13730 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
   13731   HandleScope scope(isolate);
   13732   CHECK(isolate->debug()->live_edit_enabled());
   13733   DCHECK(args.length() == 2);
   13734   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13735   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   13736 
   13737   Handle<Code> code(function->code(), isolate);
   13738 
   13739   if (code->kind() != Code::FUNCTION &&
   13740       code->kind() != Code::OPTIMIZED_FUNCTION) {
   13741     return isolate->heap()->undefined_value();
   13742   }
   13743 
   13744   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
   13745   int closest_pc = 0;
   13746   int distance = kMaxInt;
   13747   while (!it.done()) {
   13748     int statement_position = static_cast<int>(it.rinfo()->data());
   13749     // Check if this break point is closer that what was previously found.
   13750     if (source_position <= statement_position &&
   13751         statement_position - source_position < distance) {
   13752       closest_pc =
   13753           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
   13754       distance = statement_position - source_position;
   13755       // Check whether we can't get any closer.
   13756       if (distance == 0) break;
   13757     }
   13758     it.next();
   13759   }
   13760 
   13761   return Smi::FromInt(closest_pc);
   13762 }
   13763 
   13764 
   13765 // Calls specified function with or without entering the debugger.
   13766 // This is used in unit tests to run code as if debugger is entered or simply
   13767 // to have a stack with C++ frame in the middle.
   13768 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
   13769   HandleScope scope(isolate);
   13770   DCHECK(args.length() == 2);
   13771   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13772   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
   13773 
   13774   MaybeHandle<Object> maybe_result;
   13775   if (without_debugger) {
   13776     maybe_result = Execution::Call(isolate,
   13777                                    function,
   13778                                    handle(function->global_proxy()),
   13779                                    0,
   13780                                    NULL);
   13781   } else {
   13782     DebugScope debug_scope(isolate->debug());
   13783     maybe_result = Execution::Call(isolate,
   13784                                    function,
   13785                                    handle(function->global_proxy()),
   13786                                    0,
   13787                                    NULL);
   13788   }
   13789   Handle<Object> result;
   13790   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
   13791   return *result;
   13792 }
   13793 
   13794 
   13795 // Sets a v8 flag.
   13796 RUNTIME_FUNCTION(Runtime_SetFlags) {
   13797   SealHandleScope shs(isolate);
   13798   DCHECK(args.length() == 1);
   13799   CONVERT_ARG_CHECKED(String, arg, 0);
   13800   SmartArrayPointer<char> flags =
   13801       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   13802   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
   13803   return isolate->heap()->undefined_value();
   13804 }
   13805 
   13806 
   13807 // Performs a GC.
   13808 // Presently, it only does a full GC.
   13809 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
   13810   SealHandleScope shs(isolate);
   13811   DCHECK(args.length() == 1);
   13812   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
   13813   return isolate->heap()->undefined_value();
   13814 }
   13815 
   13816 
   13817 // Gets the current heap usage.
   13818 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
   13819   SealHandleScope shs(isolate);
   13820   DCHECK(args.length() == 0);
   13821   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
   13822   if (!Smi::IsValid(usage)) {
   13823     return *isolate->factory()->NewNumberFromInt(usage);
   13824   }
   13825   return Smi::FromInt(usage);
   13826 }
   13827 
   13828 
   13829 #ifdef V8_I18N_SUPPORT
   13830 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
   13831   HandleScope scope(isolate);
   13832   Factory* factory = isolate->factory();
   13833 
   13834   DCHECK(args.length() == 1);
   13835   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
   13836 
   13837   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
   13838 
   13839   // Return value which denotes invalid language tag.
   13840   const char* const kInvalidTag = "invalid-tag";
   13841 
   13842   UErrorCode error = U_ZERO_ERROR;
   13843   char icu_result[ULOC_FULLNAME_CAPACITY];
   13844   int icu_length = 0;
   13845 
   13846   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
   13847                       &icu_length, &error);
   13848   if (U_FAILURE(error) || icu_length == 0) {
   13849     return *factory->NewStringFromAsciiChecked(kInvalidTag);
   13850   }
   13851 
   13852   char result[ULOC_FULLNAME_CAPACITY];
   13853 
   13854   // Force strict BCP47 rules.
   13855   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
   13856 
   13857   if (U_FAILURE(error)) {
   13858     return *factory->NewStringFromAsciiChecked(kInvalidTag);
   13859   }
   13860 
   13861   return *factory->NewStringFromAsciiChecked(result);
   13862 }
   13863 
   13864 
   13865 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
   13866   HandleScope scope(isolate);
   13867   Factory* factory = isolate->factory();
   13868 
   13869   DCHECK(args.length() == 1);
   13870   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
   13871 
   13872   const icu::Locale* available_locales = NULL;
   13873   int32_t count = 0;
   13874 
   13875   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
   13876     available_locales = icu::Collator::getAvailableLocales(count);
   13877   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
   13878     available_locales = icu::NumberFormat::getAvailableLocales(count);
   13879   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
   13880     available_locales = icu::DateFormat::getAvailableLocales(count);
   13881   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
   13882     available_locales = icu::BreakIterator::getAvailableLocales(count);
   13883   }
   13884 
   13885   UErrorCode error = U_ZERO_ERROR;
   13886   char result[ULOC_FULLNAME_CAPACITY];
   13887   Handle<JSObject> locales =
   13888       factory->NewJSObject(isolate->object_function());
   13889 
   13890   for (int32_t i = 0; i < count; ++i) {
   13891     const char* icu_name = available_locales[i].getName();
   13892 
   13893     error = U_ZERO_ERROR;
   13894     // No need to force strict BCP47 rules.
   13895     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13896     if (U_FAILURE(error)) {
   13897       // This shouldn't happen, but lets not break the user.
   13898       continue;
   13899     }
   13900 
   13901     RETURN_FAILURE_ON_EXCEPTION(isolate,
   13902         JSObject::SetOwnPropertyIgnoreAttributes(
   13903             locales,
   13904             factory->NewStringFromAsciiChecked(result),
   13905             factory->NewNumber(i),
   13906             NONE));
   13907   }
   13908 
   13909   return *locales;
   13910 }
   13911 
   13912 
   13913 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
   13914   HandleScope scope(isolate);
   13915   Factory* factory = isolate->factory();
   13916 
   13917   DCHECK(args.length() == 0);
   13918 
   13919   icu::Locale default_locale;
   13920 
   13921   // Set the locale
   13922   char result[ULOC_FULLNAME_CAPACITY];
   13923   UErrorCode status = U_ZERO_ERROR;
   13924   uloc_toLanguageTag(
   13925       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
   13926   if (U_SUCCESS(status)) {
   13927     return *factory->NewStringFromAsciiChecked(result);
   13928   }
   13929 
   13930   return *factory->NewStringFromStaticChars("und");
   13931 }
   13932 
   13933 
   13934 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
   13935   HandleScope scope(isolate);
   13936   Factory* factory = isolate->factory();
   13937 
   13938   DCHECK(args.length() == 1);
   13939 
   13940   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
   13941 
   13942   uint32_t length = static_cast<uint32_t>(input->length()->Number());
   13943   // Set some limit to prevent fuzz tests from going OOM.
   13944   // Can be bumped when callers' requirements change.
   13945   RUNTIME_ASSERT(length < 100);
   13946   Handle<FixedArray> output = factory->NewFixedArray(length);
   13947   Handle<Name> maximized = factory->NewStringFromStaticChars("maximized");
   13948   Handle<Name> base = factory->NewStringFromStaticChars("base");
   13949   for (unsigned int i = 0; i < length; ++i) {
   13950     Handle<Object> locale_id;
   13951     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13952         isolate, locale_id, Object::GetElement(isolate, input, i));
   13953     if (!locale_id->IsString()) {
   13954       return isolate->Throw(*factory->illegal_argument_string());
   13955     }
   13956 
   13957     v8::String::Utf8Value utf8_locale_id(
   13958         v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
   13959 
   13960     UErrorCode error = U_ZERO_ERROR;
   13961 
   13962     // Convert from BCP47 to ICU format.
   13963     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
   13964     char icu_locale[ULOC_FULLNAME_CAPACITY];
   13965     int icu_locale_length = 0;
   13966     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
   13967                         &icu_locale_length, &error);
   13968     if (U_FAILURE(error) || icu_locale_length == 0) {
   13969       return isolate->Throw(*factory->illegal_argument_string());
   13970     }
   13971 
   13972     // Maximize the locale.
   13973     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
   13974     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
   13975     uloc_addLikelySubtags(
   13976         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13977 
   13978     // Remove extensions from maximized locale.
   13979     // de_Latn_DE@collation=phonebook -> de_Latn_DE
   13980     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
   13981     uloc_getBaseName(
   13982         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13983 
   13984     // Get original name without extensions.
   13985     // de_DE@collation=phonebook -> de_DE
   13986     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
   13987     uloc_getBaseName(
   13988         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
   13989 
   13990     // Convert from ICU locale format to BCP47 format.
   13991     // de_Latn_DE -> de-Latn-DE
   13992     char base_max_locale[ULOC_FULLNAME_CAPACITY];
   13993     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
   13994                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13995 
   13996     // de_DE -> de-DE
   13997     char base_locale[ULOC_FULLNAME_CAPACITY];
   13998     uloc_toLanguageTag(
   13999         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   14000 
   14001     if (U_FAILURE(error)) {
   14002       return isolate->Throw(*factory->illegal_argument_string());
   14003     }
   14004 
   14005     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
   14006     Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale);
   14007     JSObject::AddProperty(result, maximized, value, NONE);
   14008     value = factory->NewStringFromAsciiChecked(base_locale);
   14009     JSObject::AddProperty(result, base, value, NONE);
   14010     output->set(i, *result);
   14011   }
   14012 
   14013   Handle<JSArray> result = factory->NewJSArrayWithElements(output);
   14014   result->set_length(Smi::FromInt(length));
   14015   return *result;
   14016 }
   14017 
   14018 
   14019 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
   14020   HandleScope scope(isolate);
   14021 
   14022   DCHECK(args.length() == 1);
   14023 
   14024   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   14025 
   14026   if (!input->IsJSObject()) return isolate->heap()->false_value();
   14027   Handle<JSObject> obj = Handle<JSObject>::cast(input);
   14028 
   14029   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
   14030   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
   14031   return isolate->heap()->ToBoolean(!tag->IsTheHole());
   14032 }
   14033 
   14034 
   14035 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
   14036   HandleScope scope(isolate);
   14037 
   14038   DCHECK(args.length() == 2);
   14039 
   14040   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   14041   CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
   14042 
   14043   if (!input->IsJSObject()) return isolate->heap()->false_value();
   14044   Handle<JSObject> obj = Handle<JSObject>::cast(input);
   14045 
   14046   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
   14047   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
   14048   return isolate->heap()->ToBoolean(
   14049       tag->IsString() && String::cast(*tag)->Equals(*expected_type));
   14050 }
   14051 
   14052 
   14053 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
   14054   HandleScope scope(isolate);
   14055 
   14056   DCHECK(args.length() == 3);
   14057 
   14058   CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
   14059   CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   14060   CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
   14061 
   14062   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
   14063   JSObject::SetHiddenProperty(input, marker, type);
   14064 
   14065   marker = isolate->factory()->intl_impl_object_string();
   14066   JSObject::SetHiddenProperty(input, marker, impl);
   14067 
   14068   return isolate->heap()->undefined_value();
   14069 }
   14070 
   14071 
   14072 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
   14073   HandleScope scope(isolate);
   14074 
   14075   DCHECK(args.length() == 1);
   14076 
   14077   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   14078 
   14079   if (!input->IsJSObject()) {
   14080     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
   14081     THROW_NEW_ERROR_RETURN_FAILURE(isolate,
   14082                                    NewTypeError("not_intl_object", arguments));
   14083   }
   14084 
   14085   Handle<JSObject> obj = Handle<JSObject>::cast(input);
   14086 
   14087   Handle<String> marker = isolate->factory()->intl_impl_object_string();
   14088   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
   14089   if (impl->IsTheHole()) {
   14090     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
   14091     THROW_NEW_ERROR_RETURN_FAILURE(isolate,
   14092                                    NewTypeError("not_intl_object", arguments));
   14093   }
   14094   return *impl;
   14095 }
   14096 
   14097 
   14098 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
   14099   HandleScope scope(isolate);
   14100 
   14101   DCHECK(args.length() == 3);
   14102 
   14103   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14104   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14105   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14106 
   14107   Handle<ObjectTemplateInfo> date_format_template =
   14108       I18N::GetTemplate(isolate);
   14109 
   14110   // Create an empty object wrapper.
   14111   Handle<JSObject> local_object;
   14112   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14113       isolate, local_object,
   14114       Execution::InstantiateObject(date_format_template));
   14115 
   14116   // Set date time formatter as internal field of the resulting JS object.
   14117   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
   14118       isolate, locale, options, resolved);
   14119 
   14120   if (!date_format) return isolate->ThrowIllegalOperation();
   14121 
   14122   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
   14123 
   14124   Factory* factory = isolate->factory();
   14125   Handle<String> key = factory->NewStringFromStaticChars("dateFormat");
   14126   Handle<String> value = factory->NewStringFromStaticChars("valid");
   14127   JSObject::AddProperty(local_object, key, value, NONE);
   14128 
   14129   // Make object handle weak so we can delete the data format once GC kicks in.
   14130   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14131   GlobalHandles::MakeWeak(wrapper.location(),
   14132                           reinterpret_cast<void*>(wrapper.location()),
   14133                           DateFormat::DeleteDateFormat);
   14134   return *local_object;
   14135 }
   14136 
   14137 
   14138 RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
   14139   HandleScope scope(isolate);
   14140 
   14141   DCHECK(args.length() == 2);
   14142 
   14143   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   14144   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
   14145 
   14146   Handle<Object> value;
   14147   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14148       isolate, value, Execution::ToNumber(isolate, date));
   14149 
   14150   icu::SimpleDateFormat* date_format =
   14151       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   14152   if (!date_format) return isolate->ThrowIllegalOperation();
   14153 
   14154   icu::UnicodeString result;
   14155   date_format->format(value->Number(), result);
   14156 
   14157   Handle<String> result_str;
   14158   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14159       isolate, result_str,
   14160       isolate->factory()->NewStringFromTwoByte(
   14161           Vector<const uint16_t>(
   14162               reinterpret_cast<const uint16_t*>(result.getBuffer()),
   14163               result.length())));
   14164   return *result_str;
   14165 }
   14166 
   14167 
   14168 RUNTIME_FUNCTION(Runtime_InternalDateParse) {
   14169   HandleScope scope(isolate);
   14170 
   14171   DCHECK(args.length() == 2);
   14172 
   14173   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   14174   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
   14175 
   14176   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
   14177   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
   14178   icu::SimpleDateFormat* date_format =
   14179       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   14180   if (!date_format) return isolate->ThrowIllegalOperation();
   14181 
   14182   UErrorCode status = U_ZERO_ERROR;
   14183   UDate date = date_format->parse(u_date, status);
   14184   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   14185 
   14186   Handle<Object> result;
   14187   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14188       isolate, result,
   14189       Execution::NewDate(isolate, static_cast<double>(date)));
   14190   DCHECK(result->IsJSDate());
   14191   return *result;
   14192 }
   14193 
   14194 
   14195 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
   14196   HandleScope scope(isolate);
   14197 
   14198   DCHECK(args.length() == 3);
   14199 
   14200   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14201   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14202   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14203 
   14204   Handle<ObjectTemplateInfo> number_format_template =
   14205       I18N::GetTemplate(isolate);
   14206 
   14207   // Create an empty object wrapper.
   14208   Handle<JSObject> local_object;
   14209   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14210       isolate, local_object,
   14211       Execution::InstantiateObject(number_format_template));
   14212 
   14213   // Set number formatter as internal field of the resulting JS object.
   14214   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
   14215       isolate, locale, options, resolved);
   14216 
   14217   if (!number_format) return isolate->ThrowIllegalOperation();
   14218 
   14219   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
   14220 
   14221   Factory* factory = isolate->factory();
   14222   Handle<String> key = factory->NewStringFromStaticChars("numberFormat");
   14223   Handle<String> value = factory->NewStringFromStaticChars("valid");
   14224   JSObject::AddProperty(local_object, key, value, NONE);
   14225 
   14226   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14227   GlobalHandles::MakeWeak(wrapper.location(),
   14228                           reinterpret_cast<void*>(wrapper.location()),
   14229                           NumberFormat::DeleteNumberFormat);
   14230   return *local_object;
   14231 }
   14232 
   14233 
   14234 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
   14235   HandleScope scope(isolate);
   14236 
   14237   DCHECK(args.length() == 2);
   14238 
   14239   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   14240   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
   14241 
   14242   Handle<Object> value;
   14243   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14244       isolate, value, Execution::ToNumber(isolate, number));
   14245 
   14246   icu::DecimalFormat* number_format =
   14247       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   14248   if (!number_format) return isolate->ThrowIllegalOperation();
   14249 
   14250   icu::UnicodeString result;
   14251   number_format->format(value->Number(), result);
   14252 
   14253   Handle<String> result_str;
   14254   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14255       isolate, result_str,
   14256       isolate->factory()->NewStringFromTwoByte(
   14257           Vector<const uint16_t>(
   14258               reinterpret_cast<const uint16_t*>(result.getBuffer()),
   14259               result.length())));
   14260   return *result_str;
   14261 }
   14262 
   14263 
   14264 RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
   14265   HandleScope scope(isolate);
   14266 
   14267   DCHECK(args.length() == 2);
   14268 
   14269   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   14270   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
   14271 
   14272   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
   14273   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
   14274   icu::DecimalFormat* number_format =
   14275       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   14276   if (!number_format) return isolate->ThrowIllegalOperation();
   14277 
   14278   UErrorCode status = U_ZERO_ERROR;
   14279   icu::Formattable result;
   14280   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
   14281   // to be part of Chrome.
   14282   // TODO(cira): Include currency parsing code using parseCurrency call.
   14283   // We need to check if the formatter parses all currencies or only the
   14284   // one it was constructed with (it will impact the API - how to return ISO
   14285   // code and the value).
   14286   number_format->parse(u_number, result, status);
   14287   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   14288 
   14289   switch (result.getType()) {
   14290   case icu::Formattable::kDouble:
   14291     return *isolate->factory()->NewNumber(result.getDouble());
   14292   case icu::Formattable::kLong:
   14293     return *isolate->factory()->NewNumberFromInt(result.getLong());
   14294   case icu::Formattable::kInt64:
   14295     return *isolate->factory()->NewNumber(
   14296         static_cast<double>(result.getInt64()));
   14297   default:
   14298     return isolate->heap()->undefined_value();
   14299   }
   14300 }
   14301 
   14302 
   14303 RUNTIME_FUNCTION(Runtime_CreateCollator) {
   14304   HandleScope scope(isolate);
   14305 
   14306   DCHECK(args.length() == 3);
   14307 
   14308   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14309   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14310   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14311 
   14312   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
   14313 
   14314   // Create an empty object wrapper.
   14315   Handle<JSObject> local_object;
   14316   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14317       isolate, local_object, Execution::InstantiateObject(collator_template));
   14318 
   14319   // Set collator as internal field of the resulting JS object.
   14320   icu::Collator* collator = Collator::InitializeCollator(
   14321       isolate, locale, options, resolved);
   14322 
   14323   if (!collator) return isolate->ThrowIllegalOperation();
   14324 
   14325   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
   14326 
   14327   Factory* factory = isolate->factory();
   14328   Handle<String> key = factory->NewStringFromStaticChars("collator");
   14329   Handle<String> value = factory->NewStringFromStaticChars("valid");
   14330   JSObject::AddProperty(local_object, key, value, NONE);
   14331 
   14332   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14333   GlobalHandles::MakeWeak(wrapper.location(),
   14334                           reinterpret_cast<void*>(wrapper.location()),
   14335                           Collator::DeleteCollator);
   14336   return *local_object;
   14337 }
   14338 
   14339 
   14340 RUNTIME_FUNCTION(Runtime_InternalCompare) {
   14341   HandleScope scope(isolate);
   14342 
   14343   DCHECK(args.length() == 3);
   14344 
   14345   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
   14346   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
   14347   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
   14348 
   14349   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
   14350   if (!collator) return isolate->ThrowIllegalOperation();
   14351 
   14352   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
   14353   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
   14354   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
   14355   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
   14356   UErrorCode status = U_ZERO_ERROR;
   14357   UCollationResult result = collator->compare(u_string1,
   14358                                               string_value1.length(),
   14359                                               u_string2,
   14360                                               string_value2.length(),
   14361                                               status);
   14362   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
   14363 
   14364   return *isolate->factory()->NewNumberFromInt(result);
   14365 }
   14366 
   14367 
   14368 RUNTIME_FUNCTION(Runtime_StringNormalize) {
   14369   HandleScope scope(isolate);
   14370   static const UNormalizationMode normalizationForms[] =
   14371       { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
   14372 
   14373   DCHECK(args.length() == 2);
   14374 
   14375   CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
   14376   CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
   14377   RUNTIME_ASSERT(form_id >= 0 &&
   14378                  static_cast<size_t>(form_id) < arraysize(normalizationForms));
   14379 
   14380   v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
   14381   const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
   14382 
   14383   // TODO(mnita): check Normalizer2 (not available in ICU 46)
   14384   UErrorCode status = U_ZERO_ERROR;
   14385   icu::UnicodeString result;
   14386   icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
   14387       result, status);
   14388   if (U_FAILURE(status)) {
   14389     return isolate->heap()->undefined_value();
   14390   }
   14391 
   14392   Handle<String> result_str;
   14393   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14394       isolate, result_str,
   14395       isolate->factory()->NewStringFromTwoByte(
   14396           Vector<const uint16_t>(
   14397               reinterpret_cast<const uint16_t*>(result.getBuffer()),
   14398               result.length())));
   14399   return *result_str;
   14400 }
   14401 
   14402 
   14403 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
   14404   HandleScope scope(isolate);
   14405 
   14406   DCHECK(args.length() == 3);
   14407 
   14408   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14409   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14410   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14411 
   14412   Handle<ObjectTemplateInfo> break_iterator_template =
   14413       I18N::GetTemplate2(isolate);
   14414 
   14415   // Create an empty object wrapper.
   14416   Handle<JSObject> local_object;
   14417   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14418       isolate, local_object,
   14419       Execution::InstantiateObject(break_iterator_template));
   14420 
   14421   // Set break iterator as internal field of the resulting JS object.
   14422   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
   14423       isolate, locale, options, resolved);
   14424 
   14425   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14426 
   14427   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
   14428   // Make sure that the pointer to adopted text is NULL.
   14429   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
   14430 
   14431   Factory* factory = isolate->factory();
   14432   Handle<String> key = factory->NewStringFromStaticChars("breakIterator");
   14433   Handle<String> value = factory->NewStringFromStaticChars("valid");
   14434   JSObject::AddProperty(local_object, key, value, NONE);
   14435 
   14436   // Make object handle weak so we can delete the break iterator once GC kicks
   14437   // in.
   14438   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14439   GlobalHandles::MakeWeak(wrapper.location(),
   14440                           reinterpret_cast<void*>(wrapper.location()),
   14441                           BreakIterator::DeleteBreakIterator);
   14442   return *local_object;
   14443 }
   14444 
   14445 
   14446 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
   14447   HandleScope scope(isolate);
   14448 
   14449   DCHECK(args.length() == 2);
   14450 
   14451   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14452   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
   14453 
   14454   icu::BreakIterator* break_iterator =
   14455       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14456   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14457 
   14458   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
   14459       break_iterator_holder->GetInternalField(1));
   14460   delete u_text;
   14461 
   14462   v8::String::Value text_value(v8::Utils::ToLocal(text));
   14463   u_text = new icu::UnicodeString(
   14464       reinterpret_cast<const UChar*>(*text_value), text_value.length());
   14465   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
   14466 
   14467   break_iterator->setText(*u_text);
   14468 
   14469   return isolate->heap()->undefined_value();
   14470 }
   14471 
   14472 
   14473 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
   14474   HandleScope scope(isolate);
   14475 
   14476   DCHECK(args.length() == 1);
   14477 
   14478   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14479 
   14480   icu::BreakIterator* break_iterator =
   14481       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14482   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14483 
   14484   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
   14485 }
   14486 
   14487 
   14488 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
   14489   HandleScope scope(isolate);
   14490 
   14491   DCHECK(args.length() == 1);
   14492 
   14493   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14494 
   14495   icu::BreakIterator* break_iterator =
   14496       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14497   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14498 
   14499   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
   14500 }
   14501 
   14502 
   14503 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
   14504   HandleScope scope(isolate);
   14505 
   14506   DCHECK(args.length() == 1);
   14507 
   14508   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14509 
   14510   icu::BreakIterator* break_iterator =
   14511       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14512   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14513 
   14514   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
   14515 }
   14516 
   14517 
   14518 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
   14519   HandleScope scope(isolate);
   14520 
   14521   DCHECK(args.length() == 1);
   14522 
   14523   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14524 
   14525   icu::BreakIterator* break_iterator =
   14526       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14527   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14528 
   14529   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
   14530   icu::RuleBasedBreakIterator* rule_based_iterator =
   14531       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
   14532   int32_t status = rule_based_iterator->getRuleStatus();
   14533   // Keep return values in sync with JavaScript BreakType enum.
   14534   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
   14535     return *isolate->factory()->NewStringFromStaticChars("none");
   14536   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
   14537     return *isolate->factory()->number_string();
   14538   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
   14539     return *isolate->factory()->NewStringFromStaticChars("letter");
   14540   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
   14541     return *isolate->factory()->NewStringFromStaticChars("kana");
   14542   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
   14543     return *isolate->factory()->NewStringFromStaticChars("ideo");
   14544   } else {
   14545     return *isolate->factory()->NewStringFromStaticChars("unknown");
   14546   }
   14547 }
   14548 #endif  // V8_I18N_SUPPORT
   14549 
   14550 
   14551 // Finds the script object from the script data. NOTE: This operation uses
   14552 // heap traversal to find the function generated for the source position
   14553 // for the requested break point. For lazily compiled functions several heap
   14554 // traversals might be required rendering this operation as a rather slow
   14555 // operation. However for setting break points which is normally done through
   14556 // some kind of user interaction the performance is not crucial.
   14557 static Handle<Object> Runtime_GetScriptFromScriptName(
   14558     Handle<String> script_name) {
   14559   // Scan the heap for Script objects to find the script with the requested
   14560   // script data.
   14561   Handle<Script> script;
   14562   Factory* factory = script_name->GetIsolate()->factory();
   14563   Heap* heap = script_name->GetHeap();
   14564   HeapIterator iterator(heap);
   14565   HeapObject* obj = NULL;
   14566   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
   14567     // If a script is found check if it has the script data requested.
   14568     if (obj->IsScript()) {
   14569       if (Script::cast(obj)->name()->IsString()) {
   14570         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
   14571           script = Handle<Script>(Script::cast(obj));
   14572         }
   14573       }
   14574     }
   14575   }
   14576 
   14577   // If no script with the requested script data is found return undefined.
   14578   if (script.is_null()) return factory->undefined_value();
   14579 
   14580   // Return the script found.
   14581   return Script::GetWrapper(script);
   14582 }
   14583 
   14584 
   14585 // Get the script object from script data. NOTE: Regarding performance
   14586 // see the NOTE for GetScriptFromScriptData.
   14587 // args[0]: script data for the script to find the source for
   14588 RUNTIME_FUNCTION(Runtime_GetScript) {
   14589   HandleScope scope(isolate);
   14590 
   14591   DCHECK(args.length() == 1);
   14592 
   14593   CONVERT_ARG_CHECKED(String, script_name, 0);
   14594 
   14595   // Find the requested script.
   14596   Handle<Object> result =
   14597       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
   14598   return *result;
   14599 }
   14600 
   14601 
   14602 // Collect the raw data for a stack trace.  Returns an array of 4
   14603 // element segments each containing a receiver, function, code and
   14604 // native code offset.
   14605 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
   14606   HandleScope scope(isolate);
   14607   DCHECK(args.length() == 2);
   14608   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   14609   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
   14610 
   14611   if (!isolate->bootstrapper()->IsActive()) {
   14612     // Optionally capture a more detailed stack trace for the message.
   14613     isolate->CaptureAndSetDetailedStackTrace(error_object);
   14614     // Capture a simple stack trace for the stack property.
   14615     isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
   14616   }
   14617   return isolate->heap()->undefined_value();
   14618 }
   14619 
   14620 
   14621 // Returns V8 version as a string.
   14622 RUNTIME_FUNCTION(Runtime_GetV8Version) {
   14623   HandleScope scope(isolate);
   14624   DCHECK(args.length() == 0);
   14625 
   14626   const char* version_string = v8::V8::GetVersion();
   14627 
   14628   return *isolate->factory()->NewStringFromAsciiChecked(version_string);
   14629 }
   14630 
   14631 
   14632 // Returns function of generator activation.
   14633 RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
   14634   HandleScope scope(isolate);
   14635   DCHECK(args.length() == 1);
   14636   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   14637 
   14638   return generator->function();
   14639 }
   14640 
   14641 
   14642 // Returns context of generator activation.
   14643 RUNTIME_FUNCTION(Runtime_GeneratorGetContext) {
   14644   HandleScope scope(isolate);
   14645   DCHECK(args.length() == 1);
   14646   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   14647 
   14648   return generator->context();
   14649 }
   14650 
   14651 
   14652 // Returns receiver of generator activation.
   14653 RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
   14654   HandleScope scope(isolate);
   14655   DCHECK(args.length() == 1);
   14656   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   14657 
   14658   return generator->receiver();
   14659 }
   14660 
   14661 
   14662 // Returns generator continuation as a PC offset, or the magic -1 or 0 values.
   14663 RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
   14664   HandleScope scope(isolate);
   14665   DCHECK(args.length() == 1);
   14666   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   14667 
   14668   return Smi::FromInt(generator->continuation());
   14669 }
   14670 
   14671 
   14672 RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
   14673   HandleScope scope(isolate);
   14674   DCHECK(args.length() == 1);
   14675   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   14676 
   14677   if (generator->is_suspended()) {
   14678     Handle<Code> code(generator->function()->code(), isolate);
   14679     int offset = generator->continuation();
   14680 
   14681     RUNTIME_ASSERT(0 <= offset && offset < code->Size());
   14682     Address pc = code->address() + offset;
   14683 
   14684     return Smi::FromInt(code->SourcePosition(pc));
   14685   }
   14686 
   14687   return isolate->heap()->undefined_value();
   14688 }
   14689 
   14690 
   14691 RUNTIME_FUNCTION(Runtime_Abort) {
   14692   SealHandleScope shs(isolate);
   14693   DCHECK(args.length() == 1);
   14694   CONVERT_SMI_ARG_CHECKED(message_id, 0);
   14695   const char* message = GetBailoutReason(
   14696       static_cast<BailoutReason>(message_id));
   14697   base::OS::PrintError("abort: %s\n", message);
   14698   isolate->PrintStack(stderr);
   14699   base::OS::Abort();
   14700   UNREACHABLE();
   14701   return NULL;
   14702 }
   14703 
   14704 
   14705 RUNTIME_FUNCTION(Runtime_AbortJS) {
   14706   HandleScope scope(isolate);
   14707   DCHECK(args.length() == 1);
   14708   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
   14709   base::OS::PrintError("abort: %s\n", message->ToCString().get());
   14710   isolate->PrintStack(stderr);
   14711   base::OS::Abort();
   14712   UNREACHABLE();
   14713   return NULL;
   14714 }
   14715 
   14716 
   14717 RUNTIME_FUNCTION(Runtime_FlattenString) {
   14718   HandleScope scope(isolate);
   14719   DCHECK(args.length() == 1);
   14720   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   14721   return *String::Flatten(str);
   14722 }
   14723 
   14724 
   14725 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
   14726   HandleScope scope(isolate);
   14727   DCHECK(args.length() == 0);
   14728   isolate->heap()->NotifyContextDisposed();
   14729   return isolate->heap()->undefined_value();
   14730 }
   14731 
   14732 
   14733 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
   14734   HandleScope scope(isolate);
   14735   DCHECK(args.length() == 2);
   14736   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   14737   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
   14738   RUNTIME_ASSERT((index->value() & 1) == 1);
   14739   FieldIndex field_index =
   14740       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
   14741   if (field_index.is_inobject()) {
   14742     RUNTIME_ASSERT(field_index.property_index() <
   14743                    object->map()->inobject_properties());
   14744   } else {
   14745     RUNTIME_ASSERT(field_index.outobject_array_index() <
   14746                    object->properties()->length());
   14747   }
   14748   Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
   14749   RUNTIME_ASSERT(raw_value->IsMutableHeapNumber());
   14750   return *Object::WrapForRead(isolate, raw_value, Representation::Double());
   14751 }
   14752 
   14753 
   14754 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
   14755   HandleScope scope(isolate);
   14756   DCHECK(args.length() == 1);
   14757   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   14758   if (!object->IsJSObject()) return Smi::FromInt(0);
   14759   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   14760   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
   14761   // This call must not cause lazy deopts, because it's called from deferred
   14762   // code where we can't handle lazy deopts for lack of a suitable bailout
   14763   // ID. So we just try migration and signal failure if necessary,
   14764   // which will also trigger a deopt.
   14765   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
   14766   return *object;
   14767 }
   14768 
   14769 
   14770 RUNTIME_FUNCTION(Runtime_GetFromCache) {
   14771   SealHandleScope shs(isolate);
   14772   // This is only called from codegen, so checks might be more lax.
   14773   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
   14774   CONVERT_ARG_CHECKED(Object, key, 1);
   14775 
   14776   {
   14777     DisallowHeapAllocation no_alloc;
   14778 
   14779     int finger_index = cache->finger_index();
   14780     Object* o = cache->get(finger_index);
   14781     if (o == key) {
   14782       // The fastest case: hit the same place again.
   14783       return cache->get(finger_index + 1);
   14784     }
   14785 
   14786     for (int i = finger_index - 2;
   14787          i >= JSFunctionResultCache::kEntriesIndex;
   14788          i -= 2) {
   14789       o = cache->get(i);
   14790       if (o == key) {
   14791         cache->set_finger_index(i);
   14792         return cache->get(i + 1);
   14793       }
   14794     }
   14795 
   14796     int size = cache->size();
   14797     DCHECK(size <= cache->length());
   14798 
   14799     for (int i = size - 2; i > finger_index; i -= 2) {
   14800       o = cache->get(i);
   14801       if (o == key) {
   14802         cache->set_finger_index(i);
   14803         return cache->get(i + 1);
   14804       }
   14805     }
   14806   }
   14807 
   14808   // There is no value in the cache.  Invoke the function and cache result.
   14809   HandleScope scope(isolate);
   14810 
   14811   Handle<JSFunctionResultCache> cache_handle(cache);
   14812   Handle<Object> key_handle(key, isolate);
   14813   Handle<Object> value;
   14814   {
   14815     Handle<JSFunction> factory(JSFunction::cast(
   14816           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
   14817     // TODO(antonm): consider passing a receiver when constructing a cache.
   14818     Handle<JSObject> receiver(isolate->global_proxy());
   14819     // This handle is nor shared, nor used later, so it's safe.
   14820     Handle<Object> argv[] = { key_handle };
   14821     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14822         isolate, value,
   14823         Execution::Call(isolate, factory, receiver, arraysize(argv), argv));
   14824   }
   14825 
   14826 #ifdef VERIFY_HEAP
   14827   if (FLAG_verify_heap) {
   14828     cache_handle->JSFunctionResultCacheVerify();
   14829   }
   14830 #endif
   14831 
   14832   // Function invocation may have cleared the cache.  Reread all the data.
   14833   int finger_index = cache_handle->finger_index();
   14834   int size = cache_handle->size();
   14835 
   14836   // If we have spare room, put new data into it, otherwise evict post finger
   14837   // entry which is likely to be the least recently used.
   14838   int index = -1;
   14839   if (size < cache_handle->length()) {
   14840     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
   14841     index = size;
   14842   } else {
   14843     index = finger_index + JSFunctionResultCache::kEntrySize;
   14844     if (index == cache_handle->length()) {
   14845       index = JSFunctionResultCache::kEntriesIndex;
   14846     }
   14847   }
   14848 
   14849   DCHECK(index % 2 == 0);
   14850   DCHECK(index >= JSFunctionResultCache::kEntriesIndex);
   14851   DCHECK(index < cache_handle->length());
   14852 
   14853   cache_handle->set(index, *key_handle);
   14854   cache_handle->set(index + 1, *value);
   14855   cache_handle->set_finger_index(index);
   14856 
   14857 #ifdef VERIFY_HEAP
   14858   if (FLAG_verify_heap) {
   14859     cache_handle->JSFunctionResultCacheVerify();
   14860   }
   14861 #endif
   14862 
   14863   return *value;
   14864 }
   14865 
   14866 
   14867 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
   14868   SealHandleScope shs(isolate);
   14869   DCHECK(args.length() == 1);
   14870   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14871   return Smi::FromInt(message->start_position());
   14872 }
   14873 
   14874 
   14875 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
   14876   SealHandleScope shs(isolate);
   14877   DCHECK(args.length() == 1);
   14878   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14879   return message->script();
   14880 }
   14881 
   14882 
   14883 #ifdef DEBUG
   14884 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
   14885 // Exclude the code in release mode.
   14886 RUNTIME_FUNCTION(Runtime_ListNatives) {
   14887   HandleScope scope(isolate);
   14888   DCHECK(args.length() == 0);
   14889 #define COUNT_ENTRY(Name, argc, ressize) + 1
   14890   int entry_count = 0
   14891       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
   14892       INLINE_FUNCTION_LIST(COUNT_ENTRY)
   14893       INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
   14894 #undef COUNT_ENTRY
   14895   Factory* factory = isolate->factory();
   14896   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
   14897   int index = 0;
   14898   bool inline_runtime_functions = false;
   14899 #define ADD_ENTRY(Name, argc, ressize)                                      \
   14900   {                                                                         \
   14901     HandleScope inner(isolate);                                             \
   14902     Handle<String> name;                                                    \
   14903     /* Inline runtime functions have an underscore in front of the name. */ \
   14904     if (inline_runtime_functions) {                                         \
   14905       name = factory->NewStringFromStaticChars("_" #Name);                  \
   14906     } else {                                                                \
   14907       name = factory->NewStringFromStaticChars(#Name);                      \
   14908     }                                                                       \
   14909     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);           \
   14910     pair_elements->set(0, *name);                                           \
   14911     pair_elements->set(1, Smi::FromInt(argc));                              \
   14912     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);  \
   14913     elements->set(index++, *pair);                                          \
   14914   }
   14915   inline_runtime_functions = false;
   14916   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   14917   INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
   14918   inline_runtime_functions = true;
   14919   INLINE_FUNCTION_LIST(ADD_ENTRY)
   14920 #undef ADD_ENTRY
   14921   DCHECK_EQ(index, entry_count);
   14922   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
   14923   return *result;
   14924 }
   14925 #endif
   14926 
   14927 
   14928 RUNTIME_FUNCTION(Runtime_IS_VAR) {
   14929   UNREACHABLE();  // implemented as macro in the parser
   14930   return NULL;
   14931 }
   14932 
   14933 
   14934 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
   14935   RUNTIME_FUNCTION(Runtime_Has##Name) {          \
   14936     CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
   14937     return isolate->heap()->ToBoolean(obj->Has##Name());  \
   14938   }
   14939 
   14940 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
   14941 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
   14942 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
   14943 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
   14944 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
   14945 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
   14946 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
   14947 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
   14948 // Properties test sitting with elements tests - not fooling anyone.
   14949 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
   14950 
   14951 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
   14952 
   14953 
   14954 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
   14955   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
   14956     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
   14957     return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
   14958   }
   14959 
   14960 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
   14961 
   14962 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
   14963 
   14964 
   14965 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
   14966   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
   14967     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
   14968     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
   14969   }
   14970 
   14971 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
   14972 
   14973 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
   14974 
   14975 
   14976 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
   14977   SealHandleScope shs(isolate);
   14978   DCHECK(args.length() == 2);
   14979   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
   14980   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
   14981   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
   14982 }
   14983 
   14984 
   14985 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
   14986   SealHandleScope shs(isolate);
   14987   DCHECK(args.length() == 1);
   14988   CONVERT_ARG_CHECKED(Object, obj, 0);
   14989   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
   14990 }
   14991 
   14992 
   14993 RUNTIME_FUNCTION(Runtime_IsObserved) {
   14994   SealHandleScope shs(isolate);
   14995   DCHECK(args.length() == 1);
   14996 
   14997   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
   14998   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
   14999   DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
   15000   return isolate->heap()->ToBoolean(obj->map()->is_observed());
   15001 }
   15002 
   15003 
   15004 RUNTIME_FUNCTION(Runtime_SetIsObserved) {
   15005   HandleScope scope(isolate);
   15006   DCHECK(args.length() == 1);
   15007   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
   15008   RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
   15009   if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
   15010   RUNTIME_ASSERT(!obj->map()->is_observed());
   15011 
   15012   DCHECK(obj->IsJSObject());
   15013   JSObject::SetObserved(Handle<JSObject>::cast(obj));
   15014   return isolate->heap()->undefined_value();
   15015 }
   15016 
   15017 
   15018 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
   15019   HandleScope scope(isolate);
   15020   DCHECK(args.length() == 1);
   15021   CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
   15022   isolate->EnqueueMicrotask(microtask);
   15023   return isolate->heap()->undefined_value();
   15024 }
   15025 
   15026 
   15027 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
   15028   HandleScope scope(isolate);
   15029   DCHECK(args.length() == 0);
   15030   isolate->RunMicrotasks();
   15031   return isolate->heap()->undefined_value();
   15032 }
   15033 
   15034 
   15035 RUNTIME_FUNCTION(Runtime_GetObservationState) {
   15036   SealHandleScope shs(isolate);
   15037   DCHECK(args.length() == 0);
   15038   return isolate->heap()->observation_state();
   15039 }
   15040 
   15041 
   15042 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
   15043   HandleScope scope(isolate);
   15044   DCHECK(args.length() == 0);
   15045   // TODO(adamk): Currently this runtime function is only called three times per
   15046   // isolate. If it's called more often, the map should be moved into the
   15047   // strong root list.
   15048   Handle<Map> map =
   15049       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
   15050   Handle<JSWeakMap> weakmap =
   15051       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
   15052   return *WeakCollectionInitialize(isolate, weakmap);
   15053 }
   15054 
   15055 
   15056 static bool ContextsHaveSameOrigin(Handle<Context> context1,
   15057                                    Handle<Context> context2) {
   15058   return context1->security_token() == context2->security_token();
   15059 }
   15060 
   15061 
   15062 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
   15063   HandleScope scope(isolate);
   15064   DCHECK(args.length() == 3);
   15065   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
   15066   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
   15067   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
   15068 
   15069   Handle<Context> observer_context(observer->context()->native_context());
   15070   Handle<Context> object_context(object->GetCreationContext());
   15071   Handle<Context> record_context(record->GetCreationContext());
   15072 
   15073   return isolate->heap()->ToBoolean(
   15074       ContextsHaveSameOrigin(object_context, observer_context) &&
   15075       ContextsHaveSameOrigin(object_context, record_context));
   15076 }
   15077 
   15078 
   15079 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
   15080   HandleScope scope(isolate);
   15081   DCHECK(args.length() == 1);
   15082   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   15083 
   15084   Handle<Context> creation_context(object->GetCreationContext(), isolate);
   15085   return isolate->heap()->ToBoolean(
   15086       ContextsHaveSameOrigin(creation_context, isolate->native_context()));
   15087 }
   15088 
   15089 
   15090 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
   15091   HandleScope scope(isolate);
   15092   DCHECK(args.length() == 1);
   15093   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   15094 
   15095   Handle<Context> context(object->GetCreationContext(), isolate);
   15096   return context->native_object_observe();
   15097 }
   15098 
   15099 
   15100 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
   15101   HandleScope scope(isolate);
   15102   DCHECK(args.length() == 1);
   15103   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   15104 
   15105   Handle<Context> context(object->GetCreationContext(), isolate);
   15106   return context->native_object_get_notifier();
   15107 }
   15108 
   15109 
   15110 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
   15111   HandleScope scope(isolate);
   15112   DCHECK(args.length() == 1);
   15113   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
   15114 
   15115   Handle<Context> context(object_info->GetCreationContext(), isolate);
   15116   return context->native_object_notifier_perform_change();
   15117 }
   15118 
   15119 
   15120 static Object* ArrayConstructorCommon(Isolate* isolate,
   15121                                            Handle<JSFunction> constructor,
   15122                                            Handle<AllocationSite> site,
   15123                                            Arguments* caller_args) {
   15124   Factory* factory = isolate->factory();
   15125 
   15126   bool holey = false;
   15127   bool can_use_type_feedback = true;
   15128   if (caller_args->length() == 1) {
   15129     Handle<Object> argument_one = caller_args->at<Object>(0);
   15130     if (argument_one->IsSmi()) {
   15131       int value = Handle<Smi>::cast(argument_one)->value();
   15132       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
   15133         // the array is a dictionary in this case.
   15134         can_use_type_feedback = false;
   15135       } else if (value != 0) {
   15136         holey = true;
   15137       }
   15138     } else {
   15139       // Non-smi length argument produces a dictionary
   15140       can_use_type_feedback = false;
   15141     }
   15142   }
   15143 
   15144   Handle<JSArray> array;
   15145   if (!site.is_null() && can_use_type_feedback) {
   15146     ElementsKind to_kind = site->GetElementsKind();
   15147     if (holey && !IsFastHoleyElementsKind(to_kind)) {
   15148       to_kind = GetHoleyElementsKind(to_kind);
   15149       // Update the allocation site info to reflect the advice alteration.
   15150       site->SetElementsKind(to_kind);
   15151     }
   15152 
   15153     // We should allocate with an initial map that reflects the allocation site
   15154     // advice. Therefore we use AllocateJSObjectFromMap instead of passing
   15155     // the constructor.
   15156     Handle<Map> initial_map(constructor->initial_map(), isolate);
   15157     if (to_kind != initial_map->elements_kind()) {
   15158       initial_map = Map::AsElementsKind(initial_map, to_kind);
   15159     }
   15160 
   15161     // If we don't care to track arrays of to_kind ElementsKind, then
   15162     // don't emit a memento for them.
   15163     Handle<AllocationSite> allocation_site;
   15164     if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
   15165       allocation_site = site;
   15166     }
   15167 
   15168     array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
   15169         initial_map, NOT_TENURED, true, allocation_site));
   15170   } else {
   15171     array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
   15172 
   15173     // We might need to transition to holey
   15174     ElementsKind kind = constructor->initial_map()->elements_kind();
   15175     if (holey && !IsFastHoleyElementsKind(kind)) {
   15176       kind = GetHoleyElementsKind(kind);
   15177       JSObject::TransitionElementsKind(array, kind);
   15178     }
   15179   }
   15180 
   15181   factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
   15182 
   15183   ElementsKind old_kind = array->GetElementsKind();
   15184   RETURN_FAILURE_ON_EXCEPTION(
   15185       isolate, ArrayConstructInitializeElements(array, caller_args));
   15186   if (!site.is_null() &&
   15187       (old_kind != array->GetElementsKind() ||
   15188        !can_use_type_feedback)) {
   15189     // The arguments passed in caused a transition. This kind of complexity
   15190     // can't be dealt with in the inlined hydrogen array constructor case.
   15191     // We must mark the allocationsite as un-inlinable.
   15192     site->SetDoNotInlineCall();
   15193   }
   15194   return *array;
   15195 }
   15196 
   15197 
   15198 RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
   15199   HandleScope scope(isolate);
   15200   // If we get 2 arguments then they are the stub parameters (constructor, type
   15201   // info).  If we get 4, then the first one is a pointer to the arguments
   15202   // passed by the caller, and the last one is the length of the arguments
   15203   // passed to the caller (redundant, but useful to check on the deoptimizer
   15204   // with an assert).
   15205   Arguments empty_args(0, NULL);
   15206   bool no_caller_args = args.length() == 2;
   15207   DCHECK(no_caller_args || args.length() == 4);
   15208   int parameters_start = no_caller_args ? 0 : 1;
   15209   Arguments* caller_args = no_caller_args
   15210       ? &empty_args
   15211       : reinterpret_cast<Arguments*>(args[0]);
   15212   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   15213   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
   15214 #ifdef DEBUG
   15215   if (!no_caller_args) {
   15216     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
   15217     DCHECK(arg_count == caller_args->length());
   15218   }
   15219 #endif
   15220 
   15221   Handle<AllocationSite> site;
   15222   if (!type_info.is_null() &&
   15223       *type_info != isolate->heap()->undefined_value()) {
   15224     site = Handle<AllocationSite>::cast(type_info);
   15225     DCHECK(!site->SitePointsToLiteral());
   15226   }
   15227 
   15228   return ArrayConstructorCommon(isolate,
   15229                                 constructor,
   15230                                 site,
   15231                                 caller_args);
   15232 }
   15233 
   15234 
   15235 RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
   15236   HandleScope scope(isolate);
   15237   Arguments empty_args(0, NULL);
   15238   bool no_caller_args = args.length() == 1;
   15239   DCHECK(no_caller_args || args.length() == 3);
   15240   int parameters_start = no_caller_args ? 0 : 1;
   15241   Arguments* caller_args = no_caller_args
   15242       ? &empty_args
   15243       : reinterpret_cast<Arguments*>(args[0]);
   15244   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   15245 #ifdef DEBUG
   15246   if (!no_caller_args) {
   15247     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
   15248     DCHECK(arg_count == caller_args->length());
   15249   }
   15250 #endif
   15251   return ArrayConstructorCommon(isolate,
   15252                                 constructor,
   15253                                 Handle<AllocationSite>::null(),
   15254                                 caller_args);
   15255 }
   15256 
   15257 
   15258 RUNTIME_FUNCTION(Runtime_NormalizeElements) {
   15259   HandleScope scope(isolate);
   15260   DCHECK(args.length() == 1);
   15261   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   15262   RUNTIME_ASSERT(!array->HasExternalArrayElements() &&
   15263                  !array->HasFixedTypedArrayElements());
   15264   JSObject::NormalizeElements(array);
   15265   return *array;
   15266 }
   15267 
   15268 
   15269 RUNTIME_FUNCTION(Runtime_MaxSmi) {
   15270   SealHandleScope shs(isolate);
   15271   DCHECK(args.length() == 0);
   15272   return Smi::FromInt(Smi::kMaxValue);
   15273 }
   15274 
   15275 
   15276 // TODO(dcarney): remove this function when TurboFan supports it.
   15277 // Takes the object to be iterated over and the result of GetPropertyNamesFast
   15278 // Returns pair (cache_array, cache_type).
   15279 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInInit) {
   15280   SealHandleScope scope(isolate);
   15281   DCHECK(args.length() == 2);
   15282   // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
   15283   // Not worth creating a macro atm as this function should be removed.
   15284   if (!args[0]->IsJSReceiver() || !args[1]->IsObject()) {
   15285     Object* error = isolate->ThrowIllegalOperation();
   15286     return MakePair(error, isolate->heap()->undefined_value());
   15287   }
   15288   Handle<JSReceiver> object = args.at<JSReceiver>(0);
   15289   Handle<Object> cache_type = args.at<Object>(1);
   15290   if (cache_type->IsMap()) {
   15291     // Enum cache case.
   15292     if (Map::EnumLengthBits::decode(Map::cast(*cache_type)->bit_field3()) ==
   15293         0) {
   15294       // 0 length enum.
   15295       // Can't handle this case in the graph builder,
   15296       // so transform it into the empty fixed array case.
   15297       return MakePair(isolate->heap()->empty_fixed_array(), Smi::FromInt(1));
   15298     }
   15299     return MakePair(object->map()->instance_descriptors()->GetEnumCache(),
   15300                     *cache_type);
   15301   } else {
   15302     // FixedArray case.
   15303     Smi* new_cache_type = Smi::FromInt(object->IsJSProxy() ? 0 : 1);
   15304     return MakePair(*Handle<FixedArray>::cast(cache_type), new_cache_type);
   15305   }
   15306 }
   15307 
   15308 
   15309 // TODO(dcarney): remove this function when TurboFan supports it.
   15310 RUNTIME_FUNCTION(Runtime_ForInCacheArrayLength) {
   15311   SealHandleScope shs(isolate);
   15312   DCHECK(args.length() == 2);
   15313   CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 0);
   15314   CONVERT_ARG_HANDLE_CHECKED(FixedArray, array, 1);
   15315   int length = 0;
   15316   if (cache_type->IsMap()) {
   15317     length = Map::cast(*cache_type)->EnumLength();
   15318   } else {
   15319     DCHECK(cache_type->IsSmi());
   15320     length = array->length();
   15321   }
   15322   return Smi::FromInt(length);
   15323 }
   15324 
   15325 
   15326 // TODO(dcarney): remove this function when TurboFan supports it.
   15327 // Takes (the object to be iterated over,
   15328 //        cache_array from ForInInit,
   15329 //        cache_type from ForInInit,
   15330 //        the current index)
   15331 // Returns pair (array[index], needs_filtering).
   15332 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
   15333   SealHandleScope scope(isolate);
   15334   DCHECK(args.length() == 4);
   15335   int32_t index;
   15336   // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
   15337   // Not worth creating a macro atm as this function should be removed.
   15338   if (!args[0]->IsJSReceiver() || !args[1]->IsFixedArray() ||
   15339       !args[2]->IsObject() || !args[3]->ToInt32(&index)) {
   15340     Object* error = isolate->ThrowIllegalOperation();
   15341     return MakePair(error, isolate->heap()->undefined_value());
   15342   }
   15343   Handle<JSReceiver> object = args.at<JSReceiver>(0);
   15344   Handle<FixedArray> array = args.at<FixedArray>(1);
   15345   Handle<Object> cache_type = args.at<Object>(2);
   15346   // Figure out first if a slow check is needed for this object.
   15347   bool slow_check_needed = false;
   15348   if (cache_type->IsMap()) {
   15349     if (object->map() != Map::cast(*cache_type)) {
   15350       // Object transitioned.  Need slow check.
   15351       slow_check_needed = true;
   15352     }
   15353   } else {
   15354     // No slow check needed for proxies.
   15355     slow_check_needed = Smi::cast(*cache_type)->value() == 1;
   15356   }
   15357   return MakePair(array->get(index),
   15358                   isolate->heap()->ToBoolean(slow_check_needed));
   15359 }
   15360 
   15361 
   15362 // ----------------------------------------------------------------------------
   15363 // Reference implementation for inlined runtime functions.  Only used when the
   15364 // compiler does not support a certain intrinsic.  Don't optimize these, but
   15365 // implement the intrinsic in the respective compiler instead.
   15366 
   15367 // TODO(mstarzinger): These are place-holder stubs for TurboFan and will
   15368 // eventually all have a C++ implementation and this macro will be gone.
   15369 #define U(name)                               \
   15370   RUNTIME_FUNCTION(RuntimeReference_##name) { \
   15371     UNIMPLEMENTED();                          \
   15372     return NULL;                              \
   15373   }
   15374 
   15375 U(IsStringWrapperSafeForDefaultValueOf)
   15376 U(DebugBreakInOptimizedCode)
   15377 
   15378 #undef U
   15379 
   15380 
   15381 RUNTIME_FUNCTION(RuntimeReference_IsSmi) {
   15382   SealHandleScope shs(isolate);
   15383   DCHECK(args.length() == 1);
   15384   CONVERT_ARG_CHECKED(Object, obj, 0);
   15385   return isolate->heap()->ToBoolean(obj->IsSmi());
   15386 }
   15387 
   15388 
   15389 RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) {
   15390   SealHandleScope shs(isolate);
   15391   DCHECK(args.length() == 1);
   15392   CONVERT_ARG_CHECKED(Object, obj, 0);
   15393   return isolate->heap()->ToBoolean(obj->IsSmi() &&
   15394                                     Smi::cast(obj)->value() >= 0);
   15395 }
   15396 
   15397 
   15398 RUNTIME_FUNCTION(RuntimeReference_IsArray) {
   15399   SealHandleScope shs(isolate);
   15400   DCHECK(args.length() == 1);
   15401   CONVERT_ARG_CHECKED(Object, obj, 0);
   15402   return isolate->heap()->ToBoolean(obj->IsJSArray());
   15403 }
   15404 
   15405 
   15406 RUNTIME_FUNCTION(RuntimeReference_IsRegExp) {
   15407   SealHandleScope shs(isolate);
   15408   DCHECK(args.length() == 1);
   15409   CONVERT_ARG_CHECKED(Object, obj, 0);
   15410   return isolate->heap()->ToBoolean(obj->IsJSRegExp());
   15411 }
   15412 
   15413 
   15414 RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) {
   15415   SealHandleScope shs(isolate);
   15416   DCHECK(args.length() == 0);
   15417   JavaScriptFrameIterator it(isolate);
   15418   JavaScriptFrame* frame = it.frame();
   15419   return isolate->heap()->ToBoolean(frame->IsConstructor());
   15420 }
   15421 
   15422 
   15423 RUNTIME_FUNCTION(RuntimeReference_CallFunction) {
   15424   SealHandleScope shs(isolate);
   15425   return __RT_impl_Runtime_Call(args, isolate);
   15426 }
   15427 
   15428 
   15429 RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) {
   15430   SealHandleScope shs(isolate);
   15431   DCHECK(args.length() == 0);
   15432   JavaScriptFrameIterator it(isolate);
   15433   JavaScriptFrame* frame = it.frame();
   15434   return Smi::FromInt(frame->GetArgumentsLength());
   15435 }
   15436 
   15437 
   15438 RUNTIME_FUNCTION(RuntimeReference_Arguments) {
   15439   SealHandleScope shs(isolate);
   15440   return __RT_impl_Runtime_GetArgumentsProperty(args, isolate);
   15441 }
   15442 
   15443 
   15444 RUNTIME_FUNCTION(RuntimeReference_ValueOf) {
   15445   SealHandleScope shs(isolate);
   15446   DCHECK(args.length() == 1);
   15447   CONVERT_ARG_CHECKED(Object, obj, 0);
   15448   if (!obj->IsJSValue()) return obj;
   15449   return JSValue::cast(obj)->value();
   15450 }
   15451 
   15452 
   15453 RUNTIME_FUNCTION(RuntimeReference_SetValueOf) {
   15454   SealHandleScope shs(isolate);
   15455   DCHECK(args.length() == 2);
   15456   CONVERT_ARG_CHECKED(Object, obj, 0);
   15457   CONVERT_ARG_CHECKED(Object, value, 1);
   15458   if (!obj->IsJSValue()) return value;
   15459   JSValue::cast(obj)->set_value(value);
   15460   return value;
   15461 }
   15462 
   15463 
   15464 RUNTIME_FUNCTION(RuntimeReference_DateField) {
   15465   SealHandleScope shs(isolate);
   15466   DCHECK(args.length() == 2);
   15467   CONVERT_ARG_CHECKED(Object, obj, 0);
   15468   CONVERT_SMI_ARG_CHECKED(index, 1);
   15469   if (!obj->IsJSDate()) {
   15470     HandleScope scope(isolate);
   15471     THROW_NEW_ERROR_RETURN_FAILURE(
   15472         isolate,
   15473         NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
   15474   }
   15475   JSDate* date = JSDate::cast(obj);
   15476   if (index == 0) return date->value();
   15477   return JSDate::GetField(date, Smi::FromInt(index));
   15478 }
   15479 
   15480 
   15481 RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
   15482   SealHandleScope shs(isolate);
   15483   return __RT_impl_Runtime_CharFromCode(args, isolate);
   15484 }
   15485 
   15486 
   15487 RUNTIME_FUNCTION(RuntimeReference_StringCharAt) {
   15488   SealHandleScope shs(isolate);
   15489   DCHECK(args.length() == 2);
   15490   if (!args[0]->IsString()) return Smi::FromInt(0);
   15491   if (!args[1]->IsNumber()) return Smi::FromInt(0);
   15492   if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string();
   15493   Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
   15494   if (code->IsNaN()) return isolate->heap()->empty_string();
   15495   return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate);
   15496 }
   15497 
   15498 
   15499 RUNTIME_FUNCTION(RuntimeReference_OneByteSeqStringSetChar) {
   15500   SealHandleScope shs(isolate);
   15501   DCHECK(args.length() == 3);
   15502   CONVERT_INT32_ARG_CHECKED(index, 0);
   15503   CONVERT_INT32_ARG_CHECKED(value, 1);
   15504   CONVERT_ARG_CHECKED(SeqOneByteString, string, 2);
   15505   string->SeqOneByteStringSet(index, value);
   15506   return string;
   15507 }
   15508 
   15509 
   15510 RUNTIME_FUNCTION(RuntimeReference_TwoByteSeqStringSetChar) {
   15511   SealHandleScope shs(isolate);
   15512   DCHECK(args.length() == 3);
   15513   CONVERT_INT32_ARG_CHECKED(index, 0);
   15514   CONVERT_INT32_ARG_CHECKED(value, 1);
   15515   CONVERT_ARG_CHECKED(SeqTwoByteString, string, 2);
   15516   string->SeqTwoByteStringSet(index, value);
   15517   return string;
   15518 }
   15519 
   15520 
   15521 RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
   15522   SealHandleScope shs(isolate);
   15523   DCHECK(args.length() == 2);
   15524   CONVERT_ARG_CHECKED(Object, obj1, 0);
   15525   CONVERT_ARG_CHECKED(Object, obj2, 1);
   15526   return isolate->heap()->ToBoolean(obj1 == obj2);
   15527 }
   15528 
   15529 
   15530 RUNTIME_FUNCTION(RuntimeReference_IsObject) {
   15531   SealHandleScope shs(isolate);
   15532   DCHECK(args.length() == 1);
   15533   CONVERT_ARG_CHECKED(Object, obj, 0);
   15534   if (!obj->IsHeapObject()) return isolate->heap()->false_value();
   15535   if (obj->IsNull()) return isolate->heap()->true_value();
   15536   if (obj->IsUndetectableObject()) return isolate->heap()->false_value();
   15537   Map* map = HeapObject::cast(obj)->map();
   15538   bool is_non_callable_spec_object =
   15539       map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
   15540       map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE;
   15541   return isolate->heap()->ToBoolean(is_non_callable_spec_object);
   15542 }
   15543 
   15544 
   15545 RUNTIME_FUNCTION(RuntimeReference_IsFunction) {
   15546   SealHandleScope shs(isolate);
   15547   DCHECK(args.length() == 1);
   15548   CONVERT_ARG_CHECKED(Object, obj, 0);
   15549   return isolate->heap()->ToBoolean(obj->IsJSFunction());
   15550 }
   15551 
   15552 
   15553 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) {
   15554   SealHandleScope shs(isolate);
   15555   DCHECK(args.length() == 1);
   15556   CONVERT_ARG_CHECKED(Object, obj, 0);
   15557   return isolate->heap()->ToBoolean(obj->IsUndetectableObject());
   15558 }
   15559 
   15560 
   15561 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
   15562   SealHandleScope shs(isolate);
   15563   DCHECK(args.length() == 1);
   15564   CONVERT_ARG_CHECKED(Object, obj, 0);
   15565   return isolate->heap()->ToBoolean(obj->IsSpecObject());
   15566 }
   15567 
   15568 
   15569 RUNTIME_FUNCTION(RuntimeReference_MathPow) {
   15570   SealHandleScope shs(isolate);
   15571   return __RT_impl_Runtime_MathPowSlow(args, isolate);
   15572 }
   15573 
   15574 
   15575 RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
   15576   SealHandleScope shs(isolate);
   15577   DCHECK(args.length() == 1);
   15578   CONVERT_ARG_CHECKED(Object, obj, 0);
   15579   if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
   15580   HeapNumber* number = HeapNumber::cast(obj);
   15581   return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
   15582 }
   15583 
   15584 
   15585 RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
   15586   SealHandleScope shs(isolate);
   15587   DCHECK(args.length() == 1);
   15588   return isolate->heap()->false_value();
   15589 }
   15590 
   15591 
   15592 RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
   15593   SealHandleScope shs(isolate);
   15594   DCHECK(args.length() == 1);
   15595   return isolate->heap()->undefined_value();
   15596 }
   15597 
   15598 
   15599 RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) {
   15600   SealHandleScope shs(isolate);
   15601   DCHECK(args.length() == 2);
   15602   return isolate->heap()->undefined_value();
   15603 }
   15604 
   15605 
   15606 RUNTIME_FUNCTION(RuntimeReference_GeneratorNext) {
   15607   UNREACHABLE();  // Optimization disabled in SetUpGenerators().
   15608   return NULL;
   15609 }
   15610 
   15611 
   15612 RUNTIME_FUNCTION(RuntimeReference_GeneratorThrow) {
   15613   UNREACHABLE();  // Optimization disabled in SetUpGenerators().
   15614   return NULL;
   15615 }
   15616 
   15617 
   15618 RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
   15619   SealHandleScope shs(isolate);
   15620   DCHECK(args.length() == 1);
   15621   CONVERT_ARG_CHECKED(Object, obj, 0);
   15622   if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
   15623   return JSReceiver::cast(obj)->class_name();
   15624 }
   15625 
   15626 
   15627 RUNTIME_FUNCTION(RuntimeReference_StringCharCodeAt) {
   15628   SealHandleScope shs(isolate);
   15629   DCHECK(args.length() == 2);
   15630   if (!args[0]->IsString()) return isolate->heap()->undefined_value();
   15631   if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
   15632   if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
   15633   return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
   15634 }
   15635 
   15636 
   15637 RUNTIME_FUNCTION(RuntimeReference_StringAdd) {
   15638   SealHandleScope shs(isolate);
   15639   return __RT_impl_Runtime_StringAdd(args, isolate);
   15640 }
   15641 
   15642 
   15643 RUNTIME_FUNCTION(RuntimeReference_SubString) {
   15644   SealHandleScope shs(isolate);
   15645   return __RT_impl_Runtime_SubString(args, isolate);
   15646 }
   15647 
   15648 
   15649 RUNTIME_FUNCTION(RuntimeReference_StringCompare) {
   15650   SealHandleScope shs(isolate);
   15651   return __RT_impl_Runtime_StringCompare(args, isolate);
   15652 }
   15653 
   15654 
   15655 RUNTIME_FUNCTION(RuntimeReference_RegExpExec) {
   15656   SealHandleScope shs(isolate);
   15657   return __RT_impl_Runtime_RegExpExecRT(args, isolate);
   15658 }
   15659 
   15660 
   15661 RUNTIME_FUNCTION(RuntimeReference_RegExpConstructResult) {
   15662   SealHandleScope shs(isolate);
   15663   return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
   15664 }
   15665 
   15666 
   15667 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
   15668   HandleScope scope(isolate);
   15669   DCHECK(args.length() == 2);
   15670   CONVERT_SMI_ARG_CHECKED(id, 0);
   15671   args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
   15672   return __RT_impl_Runtime_GetFromCache(args, isolate);
   15673 }
   15674 
   15675 
   15676 RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
   15677   SealHandleScope shs(isolate);
   15678   return __RT_impl_Runtime_NumberToStringRT(args, isolate);
   15679 }
   15680 
   15681 
   15682 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
   15683   SealHandleScope shs(isolate);
   15684   return Smi::FromInt(isolate->debug()->is_active());
   15685 }
   15686 
   15687 
   15688 // ----------------------------------------------------------------------------
   15689 // Implementation of Runtime
   15690 
   15691 #define F(name, number_of_args, result_size)                                  \
   15692   {                                                                           \
   15693     Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
   15694         number_of_args, result_size                                           \
   15695   }                                                                           \
   15696   ,
   15697 
   15698 
   15699 #define I(name, number_of_args, result_size)                                \
   15700   {                                                                         \
   15701     Runtime::kInline##name, Runtime::INLINE, "_" #name,                     \
   15702         FUNCTION_ADDR(RuntimeReference_##name), number_of_args, result_size \
   15703   }                                                                         \
   15704   ,
   15705 
   15706 
   15707 #define IO(name, number_of_args, result_size)                              \
   15708   {                                                                        \
   15709     Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \
   15710         FUNCTION_ADDR(Runtime_##name), number_of_args, result_size         \
   15711   }                                                                        \
   15712   ,
   15713 
   15714 
   15715 static const Runtime::Function kIntrinsicFunctions[] = {
   15716   RUNTIME_FUNCTION_LIST(F)
   15717   INLINE_OPTIMIZED_FUNCTION_LIST(F)
   15718   INLINE_FUNCTION_LIST(I)
   15719   INLINE_OPTIMIZED_FUNCTION_LIST(IO)
   15720 };
   15721 
   15722 #undef IO
   15723 #undef I
   15724 #undef F
   15725 
   15726 
   15727 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
   15728                                                Handle<NameDictionary> dict) {
   15729   DCHECK(dict->NumberOfElements() == 0);
   15730   HandleScope scope(isolate);
   15731   for (int i = 0; i < kNumFunctions; ++i) {
   15732     const char* name = kIntrinsicFunctions[i].name;
   15733     if (name == NULL) continue;
   15734     Handle<NameDictionary> new_dict = NameDictionary::Add(
   15735         dict,
   15736         isolate->factory()->InternalizeUtf8String(name),
   15737         Handle<Smi>(Smi::FromInt(i), isolate),
   15738         PropertyDetails(NONE, NORMAL, Representation::None()));
   15739     // The dictionary does not need to grow.
   15740     CHECK(new_dict.is_identical_to(dict));
   15741   }
   15742 }
   15743 
   15744 
   15745 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
   15746   Heap* heap = name->GetHeap();
   15747   int entry = heap->intrinsic_function_names()->FindEntry(name);
   15748   if (entry != kNotFound) {
   15749     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
   15750     int function_index = Smi::cast(smi_index)->value();
   15751     return &(kIntrinsicFunctions[function_index]);
   15752   }
   15753   return NULL;
   15754 }
   15755 
   15756 
   15757 const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
   15758   for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
   15759     if (entry == kIntrinsicFunctions[i].entry) {
   15760       return &(kIntrinsicFunctions[i]);
   15761     }
   15762   }
   15763   return NULL;
   15764 }
   15765 
   15766 
   15767 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
   15768   return &(kIntrinsicFunctions[static_cast<int>(id)]);
   15769 }
   15770 
   15771 } }  // namespace v8::internal
   15772