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/bootstrapper.h"
     15 #include "src/codegen.h"
     16 #include "src/compilation-cache.h"
     17 #include "src/compiler.h"
     18 #include "src/conversions.h"
     19 #include "src/cpu.h"
     20 #include "src/cpu-profiler.h"
     21 #include "src/dateparser-inl.h"
     22 #include "src/debug.h"
     23 #include "src/deoptimizer.h"
     24 #include "src/date.h"
     25 #include "src/execution.h"
     26 #include "src/full-codegen.h"
     27 #include "src/global-handles.h"
     28 #include "src/isolate-inl.h"
     29 #include "src/jsregexp.h"
     30 #include "src/jsregexp-inl.h"
     31 #include "src/json-parser.h"
     32 #include "src/json-stringifier.h"
     33 #include "src/liveedit.h"
     34 #include "src/misc-intrinsics.h"
     35 #include "src/parser.h"
     36 #include "src/platform.h"
     37 #include "src/runtime-profiler.h"
     38 #include "src/runtime.h"
     39 #include "src/scopeinfo.h"
     40 #include "src/smart-pointers.h"
     41 #include "src/string-search.h"
     42 #include "src/stub-cache.h"
     43 #include "src/uri.h"
     44 #include "src/v8threads.h"
     45 #include "src/vm-state-inl.h"
     46 
     47 #ifdef V8_I18N_SUPPORT
     48 #include "src/i18n.h"
     49 #include "unicode/brkiter.h"
     50 #include "unicode/calendar.h"
     51 #include "unicode/coll.h"
     52 #include "unicode/curramt.h"
     53 #include "unicode/datefmt.h"
     54 #include "unicode/dcfmtsym.h"
     55 #include "unicode/decimfmt.h"
     56 #include "unicode/dtfmtsym.h"
     57 #include "unicode/dtptngen.h"
     58 #include "unicode/locid.h"
     59 #include "unicode/numfmt.h"
     60 #include "unicode/numsys.h"
     61 #include "unicode/rbbi.h"
     62 #include "unicode/smpdtfmt.h"
     63 #include "unicode/timezone.h"
     64 #include "unicode/uchar.h"
     65 #include "unicode/ucol.h"
     66 #include "unicode/ucurr.h"
     67 #include "unicode/uloc.h"
     68 #include "unicode/unum.h"
     69 #include "unicode/uversion.h"
     70 #endif
     71 
     72 #ifndef _STLP_VENDOR_CSTD
     73 // STLPort doesn't import fpclassify and isless into the std namespace.
     74 using std::fpclassify;
     75 using std::isless;
     76 #endif
     77 
     78 namespace v8 {
     79 namespace internal {
     80 
     81 
     82 #define RUNTIME_ASSERT(value) \
     83   if (!(value)) return isolate->ThrowIllegalOperation();
     84 
     85 #define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
     86   if (!(value)) {                                                    \
     87     isolate->ThrowIllegalOperation();                                \
     88     return MaybeHandle<T>();                                         \
     89   }
     90 
     91 // Cast the given object to a value of the specified type and store
     92 // it in a variable with the given name.  If the object is not of the
     93 // expected type call IllegalOperation and return.
     94 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
     95   RUNTIME_ASSERT(args[index]->Is##Type());                           \
     96   Type* name = Type::cast(args[index]);
     97 
     98 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
     99   RUNTIME_ASSERT(args[index]->Is##Type());                           \
    100   Handle<Type> name = args.at<Type>(index);
    101 
    102 #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
    103   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    104   Handle<Object> name = args.at<Object>(index);
    105 
    106 // Cast the given object to a boolean and store it in a variable with
    107 // the given name.  If the object is not a boolean call IllegalOperation
    108 // and return.
    109 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
    110   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
    111   bool name = args[index]->IsTrue();
    112 
    113 // Cast the given argument to a Smi and store its value in an int variable
    114 // with the given name.  If the argument is not a Smi call IllegalOperation
    115 // and return.
    116 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
    117   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    118   int name = args.smi_at(index);
    119 
    120 // Cast the given argument to a double and store it in a variable with
    121 // the given name.  If the argument is not a number (as opposed to
    122 // the number not-a-number) call IllegalOperation and return.
    123 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
    124   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    125   double name = args.number_at(index);
    126 
    127 // Call the specified converter on the object *comand store the result in
    128 // a variable of the specified type with the given name.  If the
    129 // object is not a Number call IllegalOperation and return.
    130 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
    131   RUNTIME_ASSERT(obj->IsNumber());                                   \
    132   type name = NumberTo##Type(obj);
    133 
    134 
    135 // Cast the given argument to PropertyDetails and store its value in a
    136 // variable with the given name.  If the argument is not a Smi call
    137 // IllegalOperation and return.
    138 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
    139   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    140   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
    141 
    142 
    143 // Assert that the given argument has a valid value for a StrictMode
    144 // and store it in a StrictMode variable with the given name.
    145 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
    146   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    147   RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
    148                  args.smi_at(index) == SLOPPY);                      \
    149   StrictMode name = static_cast<StrictMode>(args.smi_at(index));
    150 
    151 
    152 static Handle<Map> ComputeObjectLiteralMap(
    153     Handle<Context> context,
    154     Handle<FixedArray> constant_properties,
    155     bool* is_result_from_cache) {
    156   Isolate* isolate = context->GetIsolate();
    157   int properties_length = constant_properties->length();
    158   int number_of_properties = properties_length / 2;
    159   // Check that there are only internal strings and array indices among keys.
    160   int number_of_string_keys = 0;
    161   for (int p = 0; p != properties_length; p += 2) {
    162     Object* key = constant_properties->get(p);
    163     uint32_t element_index = 0;
    164     if (key->IsInternalizedString()) {
    165       number_of_string_keys++;
    166     } else if (key->ToArrayIndex(&element_index)) {
    167       // An index key does not require space in the property backing store.
    168       number_of_properties--;
    169     } else {
    170       // Bail out as a non-internalized-string non-index key makes caching
    171       // impossible.
    172       // ASSERT to make sure that the if condition after the loop is false.
    173       ASSERT(number_of_string_keys != number_of_properties);
    174       break;
    175     }
    176   }
    177   // If we only have internalized strings and array indices among keys then we
    178   // can use the map cache in the native context.
    179   const int kMaxKeys = 10;
    180   if ((number_of_string_keys == number_of_properties) &&
    181       (number_of_string_keys < kMaxKeys)) {
    182     // Create the fixed array with the key.
    183     Handle<FixedArray> keys =
    184         isolate->factory()->NewFixedArray(number_of_string_keys);
    185     if (number_of_string_keys > 0) {
    186       int index = 0;
    187       for (int p = 0; p < properties_length; p += 2) {
    188         Object* key = constant_properties->get(p);
    189         if (key->IsInternalizedString()) {
    190           keys->set(index++, key);
    191         }
    192       }
    193       ASSERT(index == number_of_string_keys);
    194     }
    195     *is_result_from_cache = true;
    196     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
    197   }
    198   *is_result_from_cache = false;
    199   return Map::Create(handle(context->object_function()), number_of_properties);
    200 }
    201 
    202 
    203 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
    204     Isolate* isolate,
    205     Handle<FixedArray> literals,
    206     Handle<FixedArray> constant_properties);
    207 
    208 
    209 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
    210     Isolate* isolate,
    211     Handle<FixedArray> literals,
    212     Handle<FixedArray> constant_properties,
    213     bool should_have_fast_elements,
    214     bool has_function_literal) {
    215   // Get the native context from the literals array.  This is the
    216   // context in which the function was created and we use the object
    217   // function from this context to create the object literal.  We do
    218   // not use the object function from the current native context
    219   // because this might be the object function from another context
    220   // which we should not have access to.
    221   Handle<Context> context =
    222       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
    223 
    224   // In case we have function literals, we want the object to be in
    225   // slow properties mode for now. We don't go in the map cache because
    226   // maps with constant functions can't be shared if the functions are
    227   // not the same (which is the common case).
    228   bool is_result_from_cache = false;
    229   Handle<Map> map = has_function_literal
    230       ? Handle<Map>(context->object_function()->initial_map())
    231       : ComputeObjectLiteralMap(context,
    232                                 constant_properties,
    233                                 &is_result_from_cache);
    234 
    235   PretenureFlag pretenure_flag =
    236       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
    237 
    238   Handle<JSObject> boilerplate =
    239       isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
    240 
    241   // Normalize the elements of the boilerplate to save space if needed.
    242   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
    243 
    244   // Add the constant properties to the boilerplate.
    245   int length = constant_properties->length();
    246   bool should_transform =
    247       !is_result_from_cache && boilerplate->HasFastProperties();
    248   bool should_normalize = should_transform || has_function_literal;
    249   if (should_normalize) {
    250     // TODO(verwaest): We might not want to ever normalize here.
    251     JSObject::NormalizeProperties(
    252         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
    253   }
    254   Object::ValueType value_type = should_normalize
    255       ? Object::FORCE_TAGGED : Object::OPTIMAL_REPRESENTATION;
    256 
    257   // TODO(verwaest): Support tracking representations in the boilerplate.
    258   for (int index = 0; index < length; index +=2) {
    259     Handle<Object> key(constant_properties->get(index+0), isolate);
    260     Handle<Object> value(constant_properties->get(index+1), isolate);
    261     if (value->IsFixedArray()) {
    262       // The value contains the constant_properties of a
    263       // simple object or array literal.
    264       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
    265       ASSIGN_RETURN_ON_EXCEPTION(
    266           isolate, value,
    267           CreateLiteralBoilerplate(isolate, literals, array),
    268           Object);
    269     }
    270     MaybeHandle<Object> maybe_result;
    271     uint32_t element_index = 0;
    272     StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
    273     if (key->IsInternalizedString()) {
    274       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
    275         // Array index as string (uint32).
    276         maybe_result = JSObject::SetOwnElement(
    277             boilerplate, element_index, value, SLOPPY);
    278       } else {
    279         Handle<String> name(String::cast(*key));
    280         ASSERT(!name->AsArrayIndex(&element_index));
    281         maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
    282             boilerplate, name, value, NONE,
    283             value_type, mode);
    284       }
    285     } else if (key->ToArrayIndex(&element_index)) {
    286       // Array index (uint32).
    287       maybe_result = JSObject::SetOwnElement(
    288           boilerplate, element_index, value, SLOPPY);
    289     } else {
    290       // Non-uint32 number.
    291       ASSERT(key->IsNumber());
    292       double num = key->Number();
    293       char arr[100];
    294       Vector<char> buffer(arr, ARRAY_SIZE(arr));
    295       const char* str = DoubleToCString(num, buffer);
    296       Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
    297       maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
    298           boilerplate, name, value, NONE,
    299           value_type, mode);
    300     }
    301     // If setting the property on the boilerplate throws an
    302     // exception, the exception is converted to an empty handle in
    303     // the handle based operations.  In that case, we need to
    304     // convert back to an exception.
    305     RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
    306   }
    307 
    308   // Transform to fast properties if necessary. For object literals with
    309   // containing function literals we defer this operation until after all
    310   // computed properties have been assigned so that we can generate
    311   // constant function properties.
    312   if (should_transform && !has_function_literal) {
    313     JSObject::TransformToFastProperties(
    314         boilerplate, boilerplate->map()->unused_property_fields());
    315   }
    316 
    317   return boilerplate;
    318 }
    319 
    320 
    321 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
    322     Handle<Object> object,
    323     ElementsKind to_kind,
    324     Isolate* isolate) {
    325   HandleScope scope(isolate);
    326   if (!object->IsJSObject()) {
    327     isolate->ThrowIllegalOperation();
    328     return MaybeHandle<Object>();
    329   }
    330   ElementsKind from_kind =
    331       Handle<JSObject>::cast(object)->map()->elements_kind();
    332   if (Map::IsValidElementsTransition(from_kind, to_kind)) {
    333     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
    334     return object;
    335   }
    336   isolate->ThrowIllegalOperation();
    337   return MaybeHandle<Object>();
    338 }
    339 
    340 
    341 static const int kSmiLiteralMinimumLength = 1024;
    342 
    343 
    344 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
    345     Isolate* isolate,
    346     Handle<FixedArray> literals,
    347     Handle<FixedArray> elements) {
    348   // Create the JSArray.
    349   Handle<JSFunction> constructor(
    350       JSFunction::NativeContextFromLiterals(*literals)->array_function());
    351 
    352   PretenureFlag pretenure_flag =
    353       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
    354 
    355   Handle<JSArray> object = Handle<JSArray>::cast(
    356       isolate->factory()->NewJSObject(constructor, pretenure_flag));
    357 
    358   ElementsKind constant_elements_kind =
    359       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
    360   Handle<FixedArrayBase> constant_elements_values(
    361       FixedArrayBase::cast(elements->get(1)));
    362 
    363   { DisallowHeapAllocation no_gc;
    364     ASSERT(IsFastElementsKind(constant_elements_kind));
    365     Context* native_context = isolate->context()->native_context();
    366     Object* maps_array = native_context->js_array_maps();
    367     ASSERT(!maps_array->IsUndefined());
    368     Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
    369     object->set_map(Map::cast(map));
    370   }
    371 
    372   Handle<FixedArrayBase> copied_elements_values;
    373   if (IsFastDoubleElementsKind(constant_elements_kind)) {
    374     ASSERT(FLAG_smi_only_arrays);
    375     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
    376         Handle<FixedDoubleArray>::cast(constant_elements_values));
    377   } else {
    378     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
    379     const bool is_cow =
    380         (constant_elements_values->map() ==
    381          isolate->heap()->fixed_cow_array_map());
    382     if (is_cow) {
    383       copied_elements_values = constant_elements_values;
    384 #if DEBUG
    385       Handle<FixedArray> fixed_array_values =
    386           Handle<FixedArray>::cast(copied_elements_values);
    387       for (int i = 0; i < fixed_array_values->length(); i++) {
    388         ASSERT(!fixed_array_values->get(i)->IsFixedArray());
    389       }
    390 #endif
    391     } else {
    392       Handle<FixedArray> fixed_array_values =
    393           Handle<FixedArray>::cast(constant_elements_values);
    394       Handle<FixedArray> fixed_array_values_copy =
    395           isolate->factory()->CopyFixedArray(fixed_array_values);
    396       copied_elements_values = fixed_array_values_copy;
    397       for (int i = 0; i < fixed_array_values->length(); i++) {
    398         if (fixed_array_values->get(i)->IsFixedArray()) {
    399           // The value contains the constant_properties of a
    400           // simple object or array literal.
    401           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
    402           Handle<Object> result;
    403           ASSIGN_RETURN_ON_EXCEPTION(
    404               isolate, result,
    405               CreateLiteralBoilerplate(isolate, literals, fa),
    406               Object);
    407           fixed_array_values_copy->set(i, *result);
    408         }
    409       }
    410     }
    411   }
    412   object->set_elements(*copied_elements_values);
    413   object->set_length(Smi::FromInt(copied_elements_values->length()));
    414 
    415   //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
    416   //  on or the object is larger than the threshold.
    417   if (!FLAG_smi_only_arrays &&
    418       constant_elements_values->length() < kSmiLiteralMinimumLength) {
    419     ElementsKind elements_kind = object->GetElementsKind();
    420     if (!IsFastObjectElementsKind(elements_kind)) {
    421       if (IsFastHoleyElementsKind(elements_kind)) {
    422         TransitionElements(object, FAST_HOLEY_ELEMENTS, isolate).Check();
    423       } else {
    424         TransitionElements(object, FAST_ELEMENTS, isolate).Check();
    425       }
    426     }
    427   }
    428 
    429   JSObject::ValidateElements(object);
    430   return object;
    431 }
    432 
    433 
    434 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
    435     Isolate* isolate,
    436     Handle<FixedArray> literals,
    437     Handle<FixedArray> array) {
    438   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
    439   const bool kHasNoFunctionLiteral = false;
    440   switch (CompileTimeValue::GetLiteralType(array)) {
    441     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
    442       return CreateObjectLiteralBoilerplate(isolate,
    443                                             literals,
    444                                             elements,
    445                                             true,
    446                                             kHasNoFunctionLiteral);
    447     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
    448       return CreateObjectLiteralBoilerplate(isolate,
    449                                             literals,
    450                                             elements,
    451                                             false,
    452                                             kHasNoFunctionLiteral);
    453     case CompileTimeValue::ARRAY_LITERAL:
    454       return Runtime::CreateArrayLiteralBoilerplate(
    455           isolate, literals, elements);
    456     default:
    457       UNREACHABLE();
    458       return MaybeHandle<Object>();
    459   }
    460 }
    461 
    462 
    463 RUNTIME_FUNCTION(RuntimeHidden_CreateObjectLiteral) {
    464   HandleScope scope(isolate);
    465   ASSERT(args.length() == 4);
    466   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    467   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    468   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    469   CONVERT_SMI_ARG_CHECKED(flags, 3);
    470   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    471   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    472 
    473   RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
    474 
    475   // Check if boilerplate exists. If not, create it first.
    476   Handle<Object> literal_site(literals->get(literals_index), isolate);
    477   Handle<AllocationSite> site;
    478   Handle<JSObject> boilerplate;
    479   if (*literal_site == isolate->heap()->undefined_value()) {
    480     Handle<Object> raw_boilerplate;
    481     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    482         isolate, raw_boilerplate,
    483         CreateObjectLiteralBoilerplate(
    484             isolate,
    485             literals,
    486             constant_properties,
    487             should_have_fast_elements,
    488             has_function_literal));
    489     boilerplate = Handle<JSObject>::cast(raw_boilerplate);
    490 
    491     AllocationSiteCreationContext creation_context(isolate);
    492     site = creation_context.EnterNewScope();
    493     RETURN_FAILURE_ON_EXCEPTION(
    494         isolate,
    495         JSObject::DeepWalk(boilerplate, &creation_context));
    496     creation_context.ExitScope(site, boilerplate);
    497 
    498     // Update the functions literal and return the boilerplate.
    499     literals->set(literals_index, *site);
    500   } else {
    501     site = Handle<AllocationSite>::cast(literal_site);
    502     boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
    503                                    isolate);
    504   }
    505 
    506   AllocationSiteUsageContext usage_context(isolate, site, true);
    507   usage_context.EnterNewScope();
    508   MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
    509       boilerplate, &usage_context);
    510   usage_context.ExitScope(site, boilerplate);
    511   Handle<Object> copy;
    512   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
    513   return *copy;
    514 }
    515 
    516 
    517 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
    518     Isolate* isolate,
    519     Handle<FixedArray> literals,
    520     int literals_index,
    521     Handle<FixedArray> elements) {
    522   // Check if boilerplate exists. If not, create it first.
    523   Handle<Object> literal_site(literals->get(literals_index), isolate);
    524   Handle<AllocationSite> site;
    525   if (*literal_site == isolate->heap()->undefined_value()) {
    526     ASSERT(*elements != isolate->heap()->empty_fixed_array());
    527     Handle<Object> boilerplate;
    528     ASSIGN_RETURN_ON_EXCEPTION(
    529         isolate, boilerplate,
    530         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
    531         AllocationSite);
    532 
    533     AllocationSiteCreationContext creation_context(isolate);
    534     site = creation_context.EnterNewScope();
    535     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
    536                            &creation_context).is_null()) {
    537       return Handle<AllocationSite>::null();
    538     }
    539     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
    540 
    541     literals->set(literals_index, *site);
    542   } else {
    543     site = Handle<AllocationSite>::cast(literal_site);
    544   }
    545 
    546   return site;
    547 }
    548 
    549 
    550 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
    551                                            Handle<FixedArray> literals,
    552                                            int literals_index,
    553                                            Handle<FixedArray> elements,
    554                                            int flags) {
    555   RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
    556                             literals_index < literals->length(), JSObject);
    557   Handle<AllocationSite> site;
    558   ASSIGN_RETURN_ON_EXCEPTION(
    559       isolate, site,
    560       GetLiteralAllocationSite(isolate, literals, literals_index, elements),
    561       JSObject);
    562 
    563   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
    564   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
    565   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
    566   usage_context.EnterNewScope();
    567   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
    568       ? JSObject::kNoHints
    569       : JSObject::kObjectIsShallowArray;
    570   MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
    571                                                   hints);
    572   usage_context.ExitScope(site, boilerplate);
    573   return copy;
    574 }
    575 
    576 
    577 RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteral) {
    578   HandleScope scope(isolate);
    579   ASSERT(args.length() == 4);
    580   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    581   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    582   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    583   CONVERT_SMI_ARG_CHECKED(flags, 3);
    584 
    585   Handle<JSObject> result;
    586   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    587       CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
    588                              flags));
    589   return *result;
    590 }
    591 
    592 
    593 RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteralStubBailout) {
    594   HandleScope scope(isolate);
    595   ASSERT(args.length() == 3);
    596   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    597   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    598   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    599 
    600   Handle<JSObject> result;
    601   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    602      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
    603                             ArrayLiteral::kShallowElements));
    604   return *result;
    605 }
    606 
    607 
    608 RUNTIME_FUNCTION(Runtime_CreateSymbol) {
    609   HandleScope scope(isolate);
    610   ASSERT(args.length() == 1);
    611   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
    612   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    613   Handle<Symbol> symbol = isolate->factory()->NewSymbol();
    614   if (name->IsString()) symbol->set_name(*name);
    615   return *symbol;
    616 }
    617 
    618 
    619 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
    620   HandleScope scope(isolate);
    621   ASSERT(args.length() == 1);
    622   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
    623   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    624   Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
    625   if (name->IsString()) symbol->set_name(*name);
    626   return *symbol;
    627 }
    628 
    629 
    630 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
    631   HandleScope scope(isolate);
    632   ASSERT(args.length() == 1);
    633   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    634   Handle<JSObject> registry = isolate->GetSymbolRegistry();
    635   Handle<String> part = isolate->factory()->private_intern_string();
    636   Handle<Object> privates;
    637   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    638       isolate, privates, Object::GetPropertyOrElement(registry, part));
    639   Handle<Object> symbol;
    640   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    641       isolate, symbol, Object::GetPropertyOrElement(privates, name));
    642   if (!symbol->IsSymbol()) {
    643     ASSERT(symbol->IsUndefined());
    644     symbol = isolate->factory()->NewPrivateSymbol();
    645     Handle<Symbol>::cast(symbol)->set_name(*name);
    646     JSObject::SetProperty(Handle<JSObject>::cast(privates),
    647                           name, symbol, NONE, STRICT).Assert();
    648   }
    649   return *symbol;
    650 }
    651 
    652 
    653 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
    654   HandleScope scope(isolate);
    655   ASSERT(args.length() == 1);
    656   CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
    657   return *Object::ToObject(isolate, symbol).ToHandleChecked();
    658 }
    659 
    660 
    661 RUNTIME_FUNCTION(Runtime_SymbolDescription) {
    662   SealHandleScope shs(isolate);
    663   ASSERT(args.length() == 1);
    664   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    665   return symbol->name();
    666 }
    667 
    668 
    669 RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
    670   HandleScope scope(isolate);
    671   ASSERT(args.length() == 0);
    672   return *isolate->GetSymbolRegistry();
    673 }
    674 
    675 
    676 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
    677   SealHandleScope shs(isolate);
    678   ASSERT(args.length() == 1);
    679   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    680   return isolate->heap()->ToBoolean(symbol->is_private());
    681 }
    682 
    683 
    684 RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
    685   HandleScope scope(isolate);
    686   ASSERT(args.length() == 2);
    687   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
    688   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
    689   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
    690   return *isolate->factory()->NewJSProxy(handler, prototype);
    691 }
    692 
    693 
    694 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
    695   HandleScope scope(isolate);
    696   ASSERT(args.length() == 4);
    697   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
    698   CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
    699   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
    700   CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
    701   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
    702   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
    703   return *isolate->factory()->NewJSFunctionProxy(
    704       handler, call_trap, construct_trap, prototype);
    705 }
    706 
    707 
    708 RUNTIME_FUNCTION(Runtime_IsJSProxy) {
    709   SealHandleScope shs(isolate);
    710   ASSERT(args.length() == 1);
    711   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
    712   return isolate->heap()->ToBoolean(obj->IsJSProxy());
    713 }
    714 
    715 
    716 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
    717   SealHandleScope shs(isolate);
    718   ASSERT(args.length() == 1);
    719   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
    720   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
    721 }
    722 
    723 
    724 RUNTIME_FUNCTION(Runtime_GetHandler) {
    725   SealHandleScope shs(isolate);
    726   ASSERT(args.length() == 1);
    727   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    728   return proxy->handler();
    729 }
    730 
    731 
    732 RUNTIME_FUNCTION(Runtime_GetCallTrap) {
    733   SealHandleScope shs(isolate);
    734   ASSERT(args.length() == 1);
    735   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    736   return proxy->call_trap();
    737 }
    738 
    739 
    740 RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
    741   SealHandleScope shs(isolate);
    742   ASSERT(args.length() == 1);
    743   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    744   return proxy->construct_trap();
    745 }
    746 
    747 
    748 RUNTIME_FUNCTION(Runtime_Fix) {
    749   HandleScope scope(isolate);
    750   ASSERT(args.length() == 1);
    751   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
    752   JSProxy::Fix(proxy);
    753   return isolate->heap()->undefined_value();
    754 }
    755 
    756 
    757 void Runtime::FreeArrayBuffer(Isolate* isolate,
    758                               JSArrayBuffer* phantom_array_buffer) {
    759   if (phantom_array_buffer->should_be_freed()) {
    760     ASSERT(phantom_array_buffer->is_external());
    761     free(phantom_array_buffer->backing_store());
    762   }
    763   if (phantom_array_buffer->is_external()) return;
    764 
    765   size_t allocated_length = NumberToSize(
    766       isolate, phantom_array_buffer->byte_length());
    767 
    768   reinterpret_cast<v8::Isolate*>(isolate)
    769       ->AdjustAmountOfExternalAllocatedMemory(
    770           -static_cast<int64_t>(allocated_length));
    771   CHECK(V8::ArrayBufferAllocator() != NULL);
    772   V8::ArrayBufferAllocator()->Free(
    773       phantom_array_buffer->backing_store(),
    774       allocated_length);
    775 }
    776 
    777 
    778 void Runtime::SetupArrayBuffer(Isolate* isolate,
    779                                Handle<JSArrayBuffer> array_buffer,
    780                                bool is_external,
    781                                void* data,
    782                                size_t allocated_length) {
    783   ASSERT(array_buffer->GetInternalFieldCount() ==
    784       v8::ArrayBuffer::kInternalFieldCount);
    785   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
    786     array_buffer->SetInternalField(i, Smi::FromInt(0));
    787   }
    788   array_buffer->set_backing_store(data);
    789   array_buffer->set_flag(Smi::FromInt(0));
    790   array_buffer->set_is_external(is_external);
    791 
    792   Handle<Object> byte_length =
    793       isolate->factory()->NewNumberFromSize(allocated_length);
    794   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
    795   array_buffer->set_byte_length(*byte_length);
    796 
    797   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
    798   isolate->heap()->set_array_buffers_list(*array_buffer);
    799   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
    800 }
    801 
    802 
    803 bool Runtime::SetupArrayBufferAllocatingData(
    804     Isolate* isolate,
    805     Handle<JSArrayBuffer> array_buffer,
    806     size_t allocated_length,
    807     bool initialize) {
    808   void* data;
    809   CHECK(V8::ArrayBufferAllocator() != NULL);
    810   if (allocated_length != 0) {
    811     if (initialize) {
    812       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
    813     } else {
    814       data =
    815           V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
    816     }
    817     if (data == NULL) return false;
    818   } else {
    819     data = NULL;
    820   }
    821 
    822   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
    823 
    824   reinterpret_cast<v8::Isolate*>(isolate)
    825       ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
    826 
    827   return true;
    828 }
    829 
    830 
    831 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
    832   Isolate* isolate = array_buffer->GetIsolate();
    833   for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
    834        !view_obj->IsUndefined();) {
    835     Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
    836     if (view->IsJSTypedArray()) {
    837       JSTypedArray::cast(*view)->Neuter();
    838     } else if (view->IsJSDataView()) {
    839       JSDataView::cast(*view)->Neuter();
    840     } else {
    841       UNREACHABLE();
    842     }
    843     view_obj = handle(view->weak_next(), isolate);
    844   }
    845   array_buffer->Neuter();
    846 }
    847 
    848 
    849 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
    850   HandleScope scope(isolate);
    851   ASSERT(args.length() == 2);
    852   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
    853   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
    854   if (!holder->byte_length()->IsUndefined()) {
    855     // ArrayBuffer is already initialized; probably a fuzz test.
    856     return *holder;
    857   }
    858   size_t allocated_length = 0;
    859   if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
    860     return isolate->Throw(
    861         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
    862                                            HandleVector<Object>(NULL, 0)));
    863   }
    864   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
    865                                                holder, allocated_length)) {
    866     return isolate->Throw(
    867         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
    868                                            HandleVector<Object>(NULL, 0)));
    869   }
    870   return *holder;
    871 }
    872 
    873 
    874 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
    875   SealHandleScope shs(isolate);
    876   ASSERT(args.length() == 1);
    877   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
    878   return holder->byte_length();
    879 }
    880 
    881 
    882 RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
    883   HandleScope scope(isolate);
    884   ASSERT(args.length() == 3);
    885   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
    886   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
    887   CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
    888   RUNTIME_ASSERT(!source.is_identical_to(target));
    889   size_t start = 0;
    890   RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
    891   size_t target_length = NumberToSize(isolate, target->byte_length());
    892 
    893   if (target_length == 0) return isolate->heap()->undefined_value();
    894 
    895   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
    896   RUNTIME_ASSERT(start <= source_byte_length);
    897   RUNTIME_ASSERT(source_byte_length - start >= target_length);
    898   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
    899   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
    900   CopyBytes(target_data, source_data + start, target_length);
    901   return isolate->heap()->undefined_value();
    902 }
    903 
    904 
    905 RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
    906   HandleScope scope(isolate);
    907   ASSERT(args.length() == 1);
    908   CONVERT_ARG_CHECKED(Object, object, 0);
    909   return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
    910 }
    911 
    912 
    913 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
    914   HandleScope scope(isolate);
    915   ASSERT(args.length() == 1);
    916   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
    917   if (array_buffer->backing_store() == NULL) {
    918     CHECK(Smi::FromInt(0) == array_buffer->byte_length());
    919     return isolate->heap()->undefined_value();
    920   }
    921   ASSERT(!array_buffer->is_external());
    922   void* backing_store = array_buffer->backing_store();
    923   size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
    924   array_buffer->set_is_external(true);
    925   Runtime::NeuterArrayBuffer(array_buffer);
    926   V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
    927   return isolate->heap()->undefined_value();
    928 }
    929 
    930 
    931 void Runtime::ArrayIdToTypeAndSize(
    932     int arrayId,
    933     ExternalArrayType* array_type,
    934     ElementsKind* external_elements_kind,
    935     ElementsKind* fixed_elements_kind,
    936     size_t* element_size) {
    937   switch (arrayId) {
    938 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
    939     case ARRAY_ID_##TYPE:                                                      \
    940       *array_type = kExternal##Type##Array;                                    \
    941       *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
    942       *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
    943       *element_size = size;                                                    \
    944       break;
    945 
    946     TYPED_ARRAYS(ARRAY_ID_CASE)
    947 #undef ARRAY_ID_CASE
    948 
    949     default:
    950       UNREACHABLE();
    951   }
    952 }
    953 
    954 
    955 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
    956   HandleScope scope(isolate);
    957   ASSERT(args.length() == 5);
    958   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
    959   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
    960   CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
    961   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
    962   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
    963 
    964   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
    965                  arrayId <= Runtime::ARRAY_ID_LAST);
    966 
    967   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
    968   size_t element_size = 1;  // Bogus initialization.
    969   ElementsKind external_elements_kind =
    970       EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
    971   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
    972   Runtime::ArrayIdToTypeAndSize(arrayId,
    973       &array_type,
    974       &external_elements_kind,
    975       &fixed_elements_kind,
    976       &element_size);
    977   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
    978 
    979   size_t byte_offset = 0;
    980   size_t byte_length = 0;
    981   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
    982   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
    983 
    984   if (maybe_buffer->IsJSArrayBuffer()) {
    985     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
    986     size_t array_buffer_byte_length =
    987         NumberToSize(isolate, buffer->byte_length());
    988     RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
    989     RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
    990   } else {
    991     RUNTIME_ASSERT(maybe_buffer->IsNull());
    992   }
    993 
    994   RUNTIME_ASSERT(byte_length % element_size == 0);
    995   size_t length = byte_length / element_size;
    996 
    997   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
    998     return isolate->Throw(
    999         *isolate->factory()->NewRangeError("invalid_typed_array_length",
   1000                                            HandleVector<Object>(NULL, 0)));
   1001   }
   1002 
   1003   // All checks are done, now we can modify objects.
   1004 
   1005   ASSERT(holder->GetInternalFieldCount() ==
   1006       v8::ArrayBufferView::kInternalFieldCount);
   1007   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1008     holder->SetInternalField(i, Smi::FromInt(0));
   1009   }
   1010   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
   1011   holder->set_length(*length_obj);
   1012   holder->set_byte_offset(*byte_offset_object);
   1013   holder->set_byte_length(*byte_length_object);
   1014 
   1015   if (!maybe_buffer->IsNull()) {
   1016     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
   1017     holder->set_buffer(*buffer);
   1018     holder->set_weak_next(buffer->weak_first_view());
   1019     buffer->set_weak_first_view(*holder);
   1020 
   1021     Handle<ExternalArray> elements =
   1022         isolate->factory()->NewExternalArray(
   1023             static_cast<int>(length), array_type,
   1024             static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
   1025     Handle<Map> map =
   1026         JSObject::GetElementsTransitionMap(holder, external_elements_kind);
   1027     JSObject::SetMapAndElements(holder, map, elements);
   1028     ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
   1029   } else {
   1030     holder->set_buffer(Smi::FromInt(0));
   1031     holder->set_weak_next(isolate->heap()->undefined_value());
   1032     Handle<FixedTypedArrayBase> elements =
   1033         isolate->factory()->NewFixedTypedArray(
   1034             static_cast<int>(length), array_type);
   1035     holder->set_elements(*elements);
   1036   }
   1037   return isolate->heap()->undefined_value();
   1038 }
   1039 
   1040 
   1041 // Initializes a typed array from an array-like object.
   1042 // If an array-like object happens to be a typed array of the same type,
   1043 // initializes backing store using memove.
   1044 //
   1045 // Returns true if backing store was initialized or false otherwise.
   1046 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
   1047   HandleScope scope(isolate);
   1048   ASSERT(args.length() == 4);
   1049   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
   1050   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
   1051   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
   1052   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
   1053 
   1054   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
   1055                  arrayId <= Runtime::ARRAY_ID_LAST);
   1056 
   1057   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
   1058   size_t element_size = 1;  // Bogus initialization.
   1059   ElementsKind external_elements_kind =
   1060       EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
   1061   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
   1062   Runtime::ArrayIdToTypeAndSize(arrayId,
   1063       &array_type,
   1064       &external_elements_kind,
   1065       &fixed_elements_kind,
   1066       &element_size);
   1067 
   1068   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
   1069 
   1070   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
   1071   if (source->IsJSTypedArray() &&
   1072       JSTypedArray::cast(*source)->type() == array_type) {
   1073     length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
   1074   }
   1075   size_t length = 0;
   1076   RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
   1077 
   1078   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
   1079       (length > (kMaxInt / element_size))) {
   1080     return isolate->Throw(*isolate->factory()->
   1081           NewRangeError("invalid_typed_array_length",
   1082             HandleVector<Object>(NULL, 0)));
   1083   }
   1084   size_t byte_length = length * element_size;
   1085 
   1086   ASSERT(holder->GetInternalFieldCount() ==
   1087       v8::ArrayBufferView::kInternalFieldCount);
   1088   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1089     holder->SetInternalField(i, Smi::FromInt(0));
   1090   }
   1091 
   1092   // NOTE: not initializing backing store.
   1093   // We assume that the caller of this function will initialize holder
   1094   // with the loop
   1095   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
   1096   // We assume that the caller of this function is always a typed array
   1097   // constructor.
   1098   // If source is a typed array, this loop will always run to completion,
   1099   // so we are sure that the backing store will be initialized.
   1100   // Otherwise, the indexing operation might throw, so the loop will not
   1101   // run to completion and the typed array might remain partly initialized.
   1102   // However we further assume that the caller of this function is a typed array
   1103   // constructor, and the exception will propagate out of the constructor,
   1104   // therefore uninitialized memory will not be accessible by a user program.
   1105   //
   1106   // TODO(dslomov): revise this once we support subclassing.
   1107 
   1108   if (!Runtime::SetupArrayBufferAllocatingData(
   1109         isolate, buffer, byte_length, false)) {
   1110     return isolate->Throw(*isolate->factory()->
   1111           NewRangeError("invalid_array_buffer_length",
   1112             HandleVector<Object>(NULL, 0)));
   1113   }
   1114 
   1115   holder->set_buffer(*buffer);
   1116   holder->set_byte_offset(Smi::FromInt(0));
   1117   Handle<Object> byte_length_obj(
   1118       isolate->factory()->NewNumberFromSize(byte_length));
   1119   holder->set_byte_length(*byte_length_obj);
   1120   holder->set_length(*length_obj);
   1121   holder->set_weak_next(buffer->weak_first_view());
   1122   buffer->set_weak_first_view(*holder);
   1123 
   1124   Handle<ExternalArray> elements =
   1125       isolate->factory()->NewExternalArray(
   1126           static_cast<int>(length), array_type,
   1127           static_cast<uint8_t*>(buffer->backing_store()));
   1128   Handle<Map> map = JSObject::GetElementsTransitionMap(
   1129       holder, external_elements_kind);
   1130   JSObject::SetMapAndElements(holder, map, elements);
   1131 
   1132   if (source->IsJSTypedArray()) {
   1133     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
   1134 
   1135     if (typed_array->type() == holder->type()) {
   1136       uint8_t* backing_store =
   1137         static_cast<uint8_t*>(
   1138           typed_array->GetBuffer()->backing_store());
   1139       size_t source_byte_offset =
   1140           NumberToSize(isolate, typed_array->byte_offset());
   1141       memcpy(
   1142           buffer->backing_store(),
   1143           backing_store + source_byte_offset,
   1144           byte_length);
   1145       return isolate->heap()->true_value();
   1146     }
   1147   }
   1148 
   1149   return isolate->heap()->false_value();
   1150 }
   1151 
   1152 
   1153 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
   1154   RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
   1155     HandleScope scope(isolate);                                               \
   1156     ASSERT(args.length() == 1);                                               \
   1157     CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
   1158     return holder->accessor();                                                \
   1159   }
   1160 
   1161 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
   1162 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
   1163 BUFFER_VIEW_GETTER(TypedArray, Length, length)
   1164 BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
   1165 
   1166 #undef BUFFER_VIEW_GETTER
   1167 
   1168 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
   1169   HandleScope scope(isolate);
   1170   ASSERT(args.length() == 1);
   1171   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
   1172   return *holder->GetBuffer();
   1173 }
   1174 
   1175 
   1176 // Return codes for Runtime_TypedArraySetFastCases.
   1177 // Should be synchronized with typedarray.js natives.
   1178 enum TypedArraySetResultCodes {
   1179   // Set from typed array of the same type.
   1180   // This is processed by TypedArraySetFastCases
   1181   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
   1182   // Set from typed array of the different type, overlapping in memory.
   1183   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
   1184   // Set from typed array of the different type, non-overlapping.
   1185   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
   1186   // Set from non-typed array.
   1187   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
   1188 };
   1189 
   1190 
   1191 RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
   1192   HandleScope scope(isolate);
   1193   ASSERT(args.length() == 3);
   1194   if (!args[0]->IsJSTypedArray())
   1195     return isolate->Throw(*isolate->factory()->NewTypeError(
   1196         "not_typed_array", HandleVector<Object>(NULL, 0)));
   1197 
   1198   if (!args[1]->IsJSTypedArray())
   1199     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
   1200 
   1201   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
   1202   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
   1203   CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
   1204 
   1205   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
   1206   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
   1207   size_t offset = 0;
   1208   RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
   1209   size_t target_length = NumberToSize(isolate, target->length());
   1210   size_t source_length = NumberToSize(isolate, source->length());
   1211   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
   1212   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
   1213   if (offset > target_length ||
   1214       offset + source_length > target_length ||
   1215       offset + source_length < offset)  // overflow
   1216     return isolate->Throw(*isolate->factory()->NewRangeError(
   1217           "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
   1218 
   1219   size_t target_offset = NumberToSize(isolate, target->byte_offset());
   1220   size_t source_offset = NumberToSize(isolate, source->byte_offset());
   1221   uint8_t* target_base =
   1222       static_cast<uint8_t*>(
   1223         target->GetBuffer()->backing_store()) + target_offset;
   1224   uint8_t* source_base =
   1225       static_cast<uint8_t*>(
   1226         source->GetBuffer()->backing_store()) + source_offset;
   1227 
   1228   // Typed arrays of the same type: use memmove.
   1229   if (target->type() == source->type()) {
   1230     memmove(target_base + offset * target->element_size(),
   1231         source_base, source_byte_length);
   1232     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
   1233   }
   1234 
   1235   // Typed arrays of different types over the same backing store
   1236   if ((source_base <= target_base &&
   1237         source_base + source_byte_length > target_base) ||
   1238       (target_base <= source_base &&
   1239         target_base + target_byte_length > source_base)) {
   1240     // We do not support overlapping ArrayBuffers
   1241     ASSERT(
   1242       target->GetBuffer()->backing_store() ==
   1243       source->GetBuffer()->backing_store());
   1244     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
   1245   } else {  // Non-overlapping typed arrays
   1246     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
   1247   }
   1248 }
   1249 
   1250 
   1251 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
   1252   ASSERT(args.length() == 0);
   1253   ASSERT_OBJECT_SIZE(
   1254       FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
   1255   return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
   1256 }
   1257 
   1258 
   1259 RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
   1260   HandleScope scope(isolate);
   1261   ASSERT(args.length() == 4);
   1262   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
   1263   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
   1264   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
   1265   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
   1266 
   1267   ASSERT(holder->GetInternalFieldCount() ==
   1268       v8::ArrayBufferView::kInternalFieldCount);
   1269   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1270     holder->SetInternalField(i, Smi::FromInt(0));
   1271   }
   1272   size_t buffer_length = 0;
   1273   size_t offset = 0;
   1274   size_t length = 0;
   1275   RUNTIME_ASSERT(
   1276       TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
   1277   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
   1278   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
   1279 
   1280   // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
   1281   // Entire range [offset, offset + length] must be in bounds.
   1282   RUNTIME_ASSERT(offset <= buffer_length);
   1283   RUNTIME_ASSERT(offset + length <= buffer_length);
   1284   // No overflow.
   1285   RUNTIME_ASSERT(offset + length >= offset);
   1286 
   1287   holder->set_buffer(*buffer);
   1288   holder->set_byte_offset(*byte_offset);
   1289   holder->set_byte_length(*byte_length);
   1290 
   1291   holder->set_weak_next(buffer->weak_first_view());
   1292   buffer->set_weak_first_view(*holder);
   1293 
   1294   return isolate->heap()->undefined_value();
   1295 }
   1296 
   1297 
   1298 inline static bool NeedToFlipBytes(bool is_little_endian) {
   1299 #ifdef V8_TARGET_LITTLE_ENDIAN
   1300   return !is_little_endian;
   1301 #else
   1302   return is_little_endian;
   1303 #endif
   1304 }
   1305 
   1306 
   1307 template<int n>
   1308 inline void CopyBytes(uint8_t* target, uint8_t* source) {
   1309   for (int i = 0; i < n; i++) {
   1310     *(target++) = *(source++);
   1311   }
   1312 }
   1313 
   1314 
   1315 template<int n>
   1316 inline void FlipBytes(uint8_t* target, uint8_t* source) {
   1317   source = source + (n-1);
   1318   for (int i = 0; i < n; i++) {
   1319     *(target++) = *(source--);
   1320   }
   1321 }
   1322 
   1323 
   1324 template<typename T>
   1325 inline static bool DataViewGetValue(
   1326     Isolate* isolate,
   1327     Handle<JSDataView> data_view,
   1328     Handle<Object> byte_offset_obj,
   1329     bool is_little_endian,
   1330     T* result) {
   1331   size_t byte_offset = 0;
   1332   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
   1333     return false;
   1334   }
   1335   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1336 
   1337   size_t data_view_byte_offset =
   1338       NumberToSize(isolate, data_view->byte_offset());
   1339   size_t data_view_byte_length =
   1340       NumberToSize(isolate, data_view->byte_length());
   1341   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1342       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1343     return false;
   1344   }
   1345 
   1346   union Value {
   1347     T data;
   1348     uint8_t bytes[sizeof(T)];
   1349   };
   1350 
   1351   Value value;
   1352   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1353   ASSERT(
   1354       NumberToSize(isolate, buffer->byte_length())
   1355       >= buffer_offset + sizeof(T));
   1356   uint8_t* source =
   1357         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1358   if (NeedToFlipBytes(is_little_endian)) {
   1359     FlipBytes<sizeof(T)>(value.bytes, source);
   1360   } else {
   1361     CopyBytes<sizeof(T)>(value.bytes, source);
   1362   }
   1363   *result = value.data;
   1364   return true;
   1365 }
   1366 
   1367 
   1368 template<typename T>
   1369 static bool DataViewSetValue(
   1370     Isolate* isolate,
   1371     Handle<JSDataView> data_view,
   1372     Handle<Object> byte_offset_obj,
   1373     bool is_little_endian,
   1374     T data) {
   1375   size_t byte_offset = 0;
   1376   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
   1377     return false;
   1378   }
   1379   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1380 
   1381   size_t data_view_byte_offset =
   1382       NumberToSize(isolate, data_view->byte_offset());
   1383   size_t data_view_byte_length =
   1384       NumberToSize(isolate, data_view->byte_length());
   1385   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1386       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1387     return false;
   1388   }
   1389 
   1390   union Value {
   1391     T data;
   1392     uint8_t bytes[sizeof(T)];
   1393   };
   1394 
   1395   Value value;
   1396   value.data = data;
   1397   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1398   ASSERT(
   1399       NumberToSize(isolate, buffer->byte_length())
   1400       >= buffer_offset + sizeof(T));
   1401   uint8_t* target =
   1402         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1403   if (NeedToFlipBytes(is_little_endian)) {
   1404     FlipBytes<sizeof(T)>(target, value.bytes);
   1405   } else {
   1406     CopyBytes<sizeof(T)>(target, value.bytes);
   1407   }
   1408   return true;
   1409 }
   1410 
   1411 
   1412 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
   1413   RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                           \
   1414     HandleScope scope(isolate);                                               \
   1415     ASSERT(args.length() == 3);                                               \
   1416     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
   1417     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
   1418     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
   1419     Type result;                                                              \
   1420     if (DataViewGetValue(                                                     \
   1421           isolate, holder, offset, is_little_endian, &result)) {              \
   1422       return *isolate->factory()->Converter(result);                          \
   1423     } else {                                                                  \
   1424       return isolate->Throw(*isolate->factory()->NewRangeError(               \
   1425           "invalid_data_view_accessor_offset",                                \
   1426           HandleVector<Object>(NULL, 0)));                                    \
   1427     }                                                                         \
   1428   }
   1429 
   1430 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
   1431 DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
   1432 DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
   1433 DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
   1434 DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
   1435 DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
   1436 DATA_VIEW_GETTER(Float32, float, NewNumber)
   1437 DATA_VIEW_GETTER(Float64, double, NewNumber)
   1438 
   1439 #undef DATA_VIEW_GETTER
   1440 
   1441 
   1442 template <typename T>
   1443 static T DataViewConvertValue(double value);
   1444 
   1445 
   1446 template <>
   1447 int8_t DataViewConvertValue<int8_t>(double value) {
   1448   return static_cast<int8_t>(DoubleToInt32(value));
   1449 }
   1450 
   1451 
   1452 template <>
   1453 int16_t DataViewConvertValue<int16_t>(double value) {
   1454   return static_cast<int16_t>(DoubleToInt32(value));
   1455 }
   1456 
   1457 
   1458 template <>
   1459 int32_t DataViewConvertValue<int32_t>(double value) {
   1460   return DoubleToInt32(value);
   1461 }
   1462 
   1463 
   1464 template <>
   1465 uint8_t DataViewConvertValue<uint8_t>(double value) {
   1466   return static_cast<uint8_t>(DoubleToUint32(value));
   1467 }
   1468 
   1469 
   1470 template <>
   1471 uint16_t DataViewConvertValue<uint16_t>(double value) {
   1472   return static_cast<uint16_t>(DoubleToUint32(value));
   1473 }
   1474 
   1475 
   1476 template <>
   1477 uint32_t DataViewConvertValue<uint32_t>(double value) {
   1478   return DoubleToUint32(value);
   1479 }
   1480 
   1481 
   1482 template <>
   1483 float DataViewConvertValue<float>(double value) {
   1484   return static_cast<float>(value);
   1485 }
   1486 
   1487 
   1488 template <>
   1489 double DataViewConvertValue<double>(double value) {
   1490   return value;
   1491 }
   1492 
   1493 
   1494 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
   1495   RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                           \
   1496     HandleScope scope(isolate);                                               \
   1497     ASSERT(args.length() == 4);                                               \
   1498     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
   1499     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
   1500     CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                              \
   1501     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
   1502     Type v = DataViewConvertValue<Type>(value->Number());                     \
   1503     if (DataViewSetValue(                                                     \
   1504           isolate, holder, offset, is_little_endian, v)) {                    \
   1505       return isolate->heap()->undefined_value();                              \
   1506     } else {                                                                  \
   1507       return isolate->Throw(*isolate->factory()->NewRangeError(               \
   1508           "invalid_data_view_accessor_offset",                                \
   1509           HandleVector<Object>(NULL, 0)));                                    \
   1510     }                                                                         \
   1511   }
   1512 
   1513 DATA_VIEW_SETTER(Uint8, uint8_t)
   1514 DATA_VIEW_SETTER(Int8, int8_t)
   1515 DATA_VIEW_SETTER(Uint16, uint16_t)
   1516 DATA_VIEW_SETTER(Int16, int16_t)
   1517 DATA_VIEW_SETTER(Uint32, uint32_t)
   1518 DATA_VIEW_SETTER(Int32, int32_t)
   1519 DATA_VIEW_SETTER(Float32, float)
   1520 DATA_VIEW_SETTER(Float64, double)
   1521 
   1522 #undef DATA_VIEW_SETTER
   1523 
   1524 
   1525 RUNTIME_FUNCTION(Runtime_SetInitialize) {
   1526   HandleScope scope(isolate);
   1527   ASSERT(args.length() == 1);
   1528   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1529   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
   1530   holder->set_table(*table);
   1531   return *holder;
   1532 }
   1533 
   1534 
   1535 RUNTIME_FUNCTION(Runtime_SetAdd) {
   1536   HandleScope scope(isolate);
   1537   ASSERT(args.length() == 2);
   1538   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1539   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1540   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1541   table = OrderedHashSet::Add(table, key);
   1542   holder->set_table(*table);
   1543   return isolate->heap()->undefined_value();
   1544 }
   1545 
   1546 
   1547 RUNTIME_FUNCTION(Runtime_SetHas) {
   1548   HandleScope scope(isolate);
   1549   ASSERT(args.length() == 2);
   1550   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1551   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1552   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1553   return isolate->heap()->ToBoolean(table->Contains(key));
   1554 }
   1555 
   1556 
   1557 RUNTIME_FUNCTION(Runtime_SetDelete) {
   1558   HandleScope scope(isolate);
   1559   ASSERT(args.length() == 2);
   1560   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1561   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1562   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1563   bool was_present = false;
   1564   table = OrderedHashSet::Remove(table, key, &was_present);
   1565   holder->set_table(*table);
   1566   return isolate->heap()->ToBoolean(was_present);
   1567 }
   1568 
   1569 
   1570 RUNTIME_FUNCTION(Runtime_SetClear) {
   1571   HandleScope scope(isolate);
   1572   ASSERT(args.length() == 1);
   1573   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1574   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1575   table = OrderedHashSet::Clear(table);
   1576   holder->set_table(*table);
   1577   return isolate->heap()->undefined_value();
   1578 }
   1579 
   1580 
   1581 RUNTIME_FUNCTION(Runtime_SetGetSize) {
   1582   HandleScope scope(isolate);
   1583   ASSERT(args.length() == 1);
   1584   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1585   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
   1586   return Smi::FromInt(table->NumberOfElements());
   1587 }
   1588 
   1589 
   1590 RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
   1591   HandleScope scope(isolate);
   1592   ASSERT(args.length() == 3);
   1593   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
   1594   CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
   1595   CONVERT_SMI_ARG_CHECKED(kind, 2)
   1596   RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
   1597                  kind == JSSetIterator::kKindEntries);
   1598   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
   1599   holder->set_table(*table);
   1600   holder->set_index(Smi::FromInt(0));
   1601   holder->set_kind(Smi::FromInt(kind));
   1602   return isolate->heap()->undefined_value();
   1603 }
   1604 
   1605 
   1606 RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
   1607   HandleScope scope(isolate);
   1608   ASSERT(args.length() == 1);
   1609   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
   1610   return *JSSetIterator::Next(holder);
   1611 }
   1612 
   1613 
   1614 RUNTIME_FUNCTION(Runtime_MapInitialize) {
   1615   HandleScope scope(isolate);
   1616   ASSERT(args.length() == 1);
   1617   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1618   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
   1619   holder->set_table(*table);
   1620   return *holder;
   1621 }
   1622 
   1623 
   1624 RUNTIME_FUNCTION(Runtime_MapGet) {
   1625   HandleScope scope(isolate);
   1626   ASSERT(args.length() == 2);
   1627   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1628   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1629   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1630   Handle<Object> lookup(table->Lookup(key), isolate);
   1631   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1632 }
   1633 
   1634 
   1635 RUNTIME_FUNCTION(Runtime_MapHas) {
   1636   HandleScope scope(isolate);
   1637   ASSERT(args.length() == 2);
   1638   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1639   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1640   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1641   Handle<Object> lookup(table->Lookup(key), isolate);
   1642   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1643 }
   1644 
   1645 
   1646 RUNTIME_FUNCTION(Runtime_MapDelete) {
   1647   HandleScope scope(isolate);
   1648   ASSERT(args.length() == 2);
   1649   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1650   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1651   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1652   bool was_present = false;
   1653   Handle<OrderedHashMap> new_table =
   1654       OrderedHashMap::Remove(table, key, &was_present);
   1655   holder->set_table(*new_table);
   1656   return isolate->heap()->ToBoolean(was_present);
   1657 }
   1658 
   1659 
   1660 RUNTIME_FUNCTION(Runtime_MapClear) {
   1661   HandleScope scope(isolate);
   1662   ASSERT(args.length() == 1);
   1663   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1664   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1665   table = OrderedHashMap::Clear(table);
   1666   holder->set_table(*table);
   1667   return isolate->heap()->undefined_value();
   1668 }
   1669 
   1670 
   1671 RUNTIME_FUNCTION(Runtime_MapSet) {
   1672   HandleScope scope(isolate);
   1673   ASSERT(args.length() == 3);
   1674   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1675   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1676   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   1677   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1678   Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
   1679   holder->set_table(*new_table);
   1680   return isolate->heap()->undefined_value();
   1681 }
   1682 
   1683 
   1684 RUNTIME_FUNCTION(Runtime_MapGetSize) {
   1685   HandleScope scope(isolate);
   1686   ASSERT(args.length() == 1);
   1687   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1688   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
   1689   return Smi::FromInt(table->NumberOfElements());
   1690 }
   1691 
   1692 
   1693 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
   1694   HandleScope scope(isolate);
   1695   ASSERT(args.length() == 3);
   1696   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
   1697   CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
   1698   CONVERT_SMI_ARG_CHECKED(kind, 2)
   1699   RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
   1700       || kind == JSMapIterator::kKindValues
   1701       || kind == JSMapIterator::kKindEntries);
   1702   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
   1703   holder->set_table(*table);
   1704   holder->set_index(Smi::FromInt(0));
   1705   holder->set_kind(Smi::FromInt(kind));
   1706   return isolate->heap()->undefined_value();
   1707 }
   1708 
   1709 
   1710 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
   1711   HandleScope scope(isolate);
   1712   ASSERT(args.length() == 1);
   1713   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
   1714   return *JSMapIterator::Next(holder);
   1715 }
   1716 
   1717 
   1718 static Handle<JSWeakCollection> WeakCollectionInitialize(
   1719     Isolate* isolate,
   1720     Handle<JSWeakCollection> weak_collection) {
   1721   ASSERT(weak_collection->map()->inobject_properties() == 0);
   1722   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   1723   weak_collection->set_table(*table);
   1724   return weak_collection;
   1725 }
   1726 
   1727 
   1728 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
   1729   HandleScope scope(isolate);
   1730   ASSERT(args.length() == 1);
   1731   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1732   return *WeakCollectionInitialize(isolate, weak_collection);
   1733 }
   1734 
   1735 
   1736 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
   1737   HandleScope scope(isolate);
   1738   ASSERT(args.length() == 2);
   1739   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1740   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1741   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1742   Handle<ObjectHashTable> table(
   1743       ObjectHashTable::cast(weak_collection->table()));
   1744   RUNTIME_ASSERT(table->IsKey(*key));
   1745   Handle<Object> lookup(table->Lookup(key), isolate);
   1746   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1747 }
   1748 
   1749 
   1750 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
   1751   HandleScope scope(isolate);
   1752   ASSERT(args.length() == 2);
   1753   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1754   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1755   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1756   Handle<ObjectHashTable> table(
   1757       ObjectHashTable::cast(weak_collection->table()));
   1758   RUNTIME_ASSERT(table->IsKey(*key));
   1759   Handle<Object> lookup(table->Lookup(key), isolate);
   1760   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1761 }
   1762 
   1763 
   1764 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
   1765   HandleScope scope(isolate);
   1766   ASSERT(args.length() == 2);
   1767   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1768   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1769   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1770   Handle<ObjectHashTable> table(ObjectHashTable::cast(
   1771       weak_collection->table()));
   1772   RUNTIME_ASSERT(table->IsKey(*key));
   1773   bool was_present = false;
   1774   Handle<ObjectHashTable> new_table =
   1775       ObjectHashTable::Remove(table, key, &was_present);
   1776   weak_collection->set_table(*new_table);
   1777   return isolate->heap()->ToBoolean(was_present);
   1778 }
   1779 
   1780 
   1781 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
   1782   HandleScope scope(isolate);
   1783   ASSERT(args.length() == 3);
   1784   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1785   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1786   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
   1787   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   1788   Handle<ObjectHashTable> table(
   1789       ObjectHashTable::cast(weak_collection->table()));
   1790   RUNTIME_ASSERT(table->IsKey(*key));
   1791   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
   1792   weak_collection->set_table(*new_table);
   1793   return isolate->heap()->undefined_value();
   1794 }
   1795 
   1796 
   1797 RUNTIME_FUNCTION(Runtime_ClassOf) {
   1798   SealHandleScope shs(isolate);
   1799   ASSERT(args.length() == 1);
   1800   CONVERT_ARG_CHECKED(Object, obj, 0);
   1801   if (!obj->IsJSObject()) return isolate->heap()->null_value();
   1802   return JSObject::cast(obj)->class_name();
   1803 }
   1804 
   1805 
   1806 RUNTIME_FUNCTION(Runtime_GetPrototype) {
   1807   HandleScope scope(isolate);
   1808   ASSERT(args.length() == 1);
   1809   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
   1810   // We don't expect access checks to be needed on JSProxy objects.
   1811   ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
   1812   do {
   1813     if (obj->IsAccessCheckNeeded() &&
   1814         !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
   1815                                  isolate->factory()->proto_string(),
   1816                                  v8::ACCESS_GET)) {
   1817       isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
   1818                                        v8::ACCESS_GET);
   1819       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   1820       return isolate->heap()->undefined_value();
   1821     }
   1822     obj = Object::GetPrototype(isolate, obj);
   1823   } while (obj->IsJSObject() &&
   1824            JSObject::cast(*obj)->map()->is_hidden_prototype());
   1825   return *obj;
   1826 }
   1827 
   1828 
   1829 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
   1830     Isolate* isolate, Handle<Object> receiver) {
   1831   Handle<Object> current = Object::GetPrototype(isolate, receiver);
   1832   while (current->IsJSObject() &&
   1833          JSObject::cast(*current)->map()->is_hidden_prototype()) {
   1834     current = Object::GetPrototype(isolate, current);
   1835   }
   1836   return current;
   1837 }
   1838 
   1839 
   1840 RUNTIME_FUNCTION(Runtime_SetPrototype) {
   1841   HandleScope scope(isolate);
   1842   ASSERT(args.length() == 2);
   1843   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1844   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   1845   if (obj->IsAccessCheckNeeded() &&
   1846       !isolate->MayNamedAccess(
   1847           obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
   1848     isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
   1849     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   1850     return isolate->heap()->undefined_value();
   1851   }
   1852   if (obj->map()->is_observed()) {
   1853     Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
   1854     Handle<Object> result;
   1855     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1856         isolate, result,
   1857         JSObject::SetPrototype(obj, prototype, true));
   1858 
   1859     Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
   1860     if (!new_value->SameValue(*old_value)) {
   1861       JSObject::EnqueueChangeRecord(obj, "setPrototype",
   1862                                     isolate->factory()->proto_string(),
   1863                                     old_value);
   1864     }
   1865     return *result;
   1866   }
   1867   Handle<Object> result;
   1868   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1869       isolate, result,
   1870       JSObject::SetPrototype(obj, prototype, true));
   1871   return *result;
   1872 }
   1873 
   1874 
   1875 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
   1876   HandleScope shs(isolate);
   1877   ASSERT(args.length() == 2);
   1878   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
   1879   CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
   1880   CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
   1881   while (true) {
   1882     Handle<Object> prototype = Object::GetPrototype(isolate, V);
   1883     if (prototype->IsNull()) return isolate->heap()->false_value();
   1884     if (*O == *prototype) return isolate->heap()->true_value();
   1885     V = prototype;
   1886   }
   1887 }
   1888 
   1889 
   1890 static bool CheckAccessException(Object* callback,
   1891                                  v8::AccessType access_type) {
   1892   DisallowHeapAllocation no_gc;
   1893   ASSERT(!callback->IsForeign());
   1894   if (callback->IsAccessorInfo()) {
   1895     AccessorInfo* info = AccessorInfo::cast(callback);
   1896     return
   1897         (access_type == v8::ACCESS_HAS &&
   1898            (info->all_can_read() || info->all_can_write())) ||
   1899         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
   1900         (access_type == v8::ACCESS_SET && info->all_can_write());
   1901   }
   1902   if (callback->IsAccessorPair()) {
   1903     AccessorPair* info = AccessorPair::cast(callback);
   1904     return
   1905         (access_type == v8::ACCESS_HAS &&
   1906            (info->all_can_read() || info->all_can_write())) ||
   1907         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
   1908         (access_type == v8::ACCESS_SET && info->all_can_write());
   1909   }
   1910   return false;
   1911 }
   1912 
   1913 
   1914 template<class Key>
   1915 static bool CheckGenericAccess(
   1916     Handle<JSObject> receiver,
   1917     Handle<JSObject> holder,
   1918     Key key,
   1919     v8::AccessType access_type,
   1920     bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
   1921   Isolate* isolate = receiver->GetIsolate();
   1922   for (Handle<JSObject> current = receiver;
   1923        true;
   1924        current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
   1925     if (current->IsAccessCheckNeeded() &&
   1926         !(isolate->*mayAccess)(current, key, access_type)) {
   1927       return false;
   1928     }
   1929     if (current.is_identical_to(holder)) break;
   1930   }
   1931   return true;
   1932 }
   1933 
   1934 
   1935 enum AccessCheckResult {
   1936   ACCESS_FORBIDDEN,
   1937   ACCESS_ALLOWED,
   1938   ACCESS_ABSENT
   1939 };
   1940 
   1941 
   1942 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
   1943                                              Handle<Name> name,
   1944                                              v8::AccessType access_type) {
   1945   uint32_t index;
   1946   if (name->AsArrayIndex(&index)) {
   1947     // TODO(1095): we should traverse hidden prototype hierachy as well.
   1948     if (CheckGenericAccess(
   1949             obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
   1950       return ACCESS_ALLOWED;
   1951     }
   1952 
   1953     obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
   1954     return ACCESS_FORBIDDEN;
   1955   }
   1956 
   1957   Isolate* isolate = obj->GetIsolate();
   1958   LookupResult lookup(isolate);
   1959   obj->LookupOwn(name, &lookup, true);
   1960 
   1961   if (!lookup.IsProperty()) return ACCESS_ABSENT;
   1962   Handle<JSObject> holder(lookup.holder(), isolate);
   1963   if (CheckGenericAccess<Handle<Object> >(
   1964           obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
   1965     return ACCESS_ALLOWED;
   1966   }
   1967 
   1968   // Access check callback denied the access, but some properties
   1969   // can have a special permissions which override callbacks descision
   1970   // (currently see v8::AccessControl).
   1971   // API callbacks can have per callback access exceptions.
   1972   switch (lookup.type()) {
   1973     case CALLBACKS:
   1974       if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
   1975         return ACCESS_ALLOWED;
   1976       }
   1977       break;
   1978     case INTERCEPTOR:
   1979       // If the object has an interceptor, try real named properties.
   1980       // Overwrite the result to fetch the correct property later.
   1981       holder->LookupRealNamedProperty(name, &lookup);
   1982       if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
   1983         if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
   1984           return ACCESS_ALLOWED;
   1985         }
   1986       }
   1987       break;
   1988     default:
   1989       break;
   1990   }
   1991 
   1992   isolate->ReportFailedAccessCheck(obj, access_type);
   1993   return ACCESS_FORBIDDEN;
   1994 }
   1995 
   1996 
   1997 // Enumerator used as indices into the array returned from GetOwnProperty
   1998 enum PropertyDescriptorIndices {
   1999   IS_ACCESSOR_INDEX,
   2000   VALUE_INDEX,
   2001   GETTER_INDEX,
   2002   SETTER_INDEX,
   2003   WRITABLE_INDEX,
   2004   ENUMERABLE_INDEX,
   2005   CONFIGURABLE_INDEX,
   2006   DESCRIPTOR_SIZE
   2007 };
   2008 
   2009 
   2010 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
   2011                                                           Handle<JSObject> obj,
   2012                                                           Handle<Name> name) {
   2013   Heap* heap = isolate->heap();
   2014   Factory* factory = isolate->factory();
   2015   // Due to some WebKit tests, we want to make sure that we do not log
   2016   // more than one access failure here.
   2017   AccessCheckResult access_check_result =
   2018       CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
   2019   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   2020   switch (access_check_result) {
   2021     case ACCESS_FORBIDDEN: return factory->false_value();
   2022     case ACCESS_ALLOWED: break;
   2023     case ACCESS_ABSENT: return factory->undefined_value();
   2024   }
   2025 
   2026   PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name);
   2027   if (attrs == ABSENT) {
   2028     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   2029     return factory->undefined_value();
   2030   }
   2031   ASSERT(!isolate->has_scheduled_exception());
   2032   Handle<AccessorPair> accessors;
   2033   bool has_accessors =
   2034       JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors);
   2035   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   2036   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
   2037   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
   2038   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
   2039 
   2040   if (!has_accessors) {
   2041     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
   2042     // Runtime::GetObjectProperty does access check.
   2043     Handle<Object> value;
   2044     ASSIGN_RETURN_ON_EXCEPTION(
   2045         isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
   2046         Object);
   2047     elms->set(VALUE_INDEX, *value);
   2048   } else {
   2049     // Access checks are performed for both accessors separately.
   2050     // When they fail, the respective field is not set in the descriptor.
   2051     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
   2052     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
   2053 
   2054     if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) {
   2055       ASSERT(!isolate->has_scheduled_exception());
   2056       elms->set(GETTER_INDEX, *getter);
   2057     } else {
   2058       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   2059     }
   2060 
   2061     if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
   2062       ASSERT(!isolate->has_scheduled_exception());
   2063       elms->set(SETTER_INDEX, *setter);
   2064     } else {
   2065       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   2066     }
   2067   }
   2068 
   2069   return isolate->factory()->NewJSArrayWithElements(elms);
   2070 }
   2071 
   2072 
   2073 // Returns an array with the property description:
   2074 //  if args[1] is not a property on args[0]
   2075 //          returns undefined
   2076 //  if args[1] is a data property on args[0]
   2077 //         [false, value, Writeable, Enumerable, Configurable]
   2078 //  if args[1] is an accessor on args[0]
   2079 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
   2080 RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
   2081   HandleScope scope(isolate);
   2082   ASSERT(args.length() == 2);
   2083   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   2084   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   2085   Handle<Object> result;
   2086   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2087       isolate, result, GetOwnProperty(isolate, obj, name));
   2088   return *result;
   2089 }
   2090 
   2091 
   2092 RUNTIME_FUNCTION(Runtime_PreventExtensions) {
   2093   HandleScope scope(isolate);
   2094   ASSERT(args.length() == 1);
   2095   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   2096   Handle<Object> result;
   2097   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2098       isolate, result, JSObject::PreventExtensions(obj));
   2099   return *result;
   2100 }
   2101 
   2102 
   2103 RUNTIME_FUNCTION(Runtime_IsExtensible) {
   2104   SealHandleScope shs(isolate);
   2105   ASSERT(args.length() == 1);
   2106   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   2107   if (obj->IsJSGlobalProxy()) {
   2108     Object* proto = obj->GetPrototype();
   2109     if (proto->IsNull()) return isolate->heap()->false_value();
   2110     ASSERT(proto->IsJSGlobalObject());
   2111     obj = JSObject::cast(proto);
   2112   }
   2113   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
   2114 }
   2115 
   2116 
   2117 RUNTIME_FUNCTION(Runtime_RegExpCompile) {
   2118   HandleScope scope(isolate);
   2119   ASSERT(args.length() == 3);
   2120   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
   2121   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   2122   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
   2123   Handle<Object> result;
   2124   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2125       isolate, result, RegExpImpl::Compile(re, pattern, flags));
   2126   return *result;
   2127 }
   2128 
   2129 
   2130 RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
   2131   HandleScope scope(isolate);
   2132   ASSERT(args.length() == 2);
   2133   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
   2134   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   2135   return *isolate->factory()->CreateApiFunction(data, prototype);
   2136 }
   2137 
   2138 
   2139 RUNTIME_FUNCTION(Runtime_IsTemplate) {
   2140   SealHandleScope shs(isolate);
   2141   ASSERT(args.length() == 1);
   2142   CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
   2143   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
   2144   return isolate->heap()->ToBoolean(result);
   2145 }
   2146 
   2147 
   2148 RUNTIME_FUNCTION(Runtime_GetTemplateField) {
   2149   SealHandleScope shs(isolate);
   2150   ASSERT(args.length() == 2);
   2151   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
   2152   CONVERT_SMI_ARG_CHECKED(index, 1);
   2153   int offset = index * kPointerSize + HeapObject::kHeaderSize;
   2154   InstanceType type = templ->map()->instance_type();
   2155   RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
   2156                  type == OBJECT_TEMPLATE_INFO_TYPE);
   2157   RUNTIME_ASSERT(offset > 0);
   2158   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
   2159     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
   2160   } else {
   2161     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
   2162   }
   2163   return *HeapObject::RawField(templ, offset);
   2164 }
   2165 
   2166 
   2167 RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
   2168   HandleScope scope(isolate);
   2169   ASSERT(args.length() == 1);
   2170   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
   2171   Handle<Map> old_map(object->map());
   2172   bool needs_access_checks = old_map->is_access_check_needed();
   2173   if (needs_access_checks) {
   2174     // Copy map so it won't interfere constructor's initial map.
   2175     Handle<Map> new_map = Map::Copy(old_map);
   2176     new_map->set_is_access_check_needed(false);
   2177     if (object->IsJSObject()) {
   2178       JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
   2179     } else {
   2180       object->set_map(*new_map);
   2181     }
   2182   }
   2183   return isolate->heap()->ToBoolean(needs_access_checks);
   2184 }
   2185 
   2186 
   2187 RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
   2188   HandleScope scope(isolate);
   2189   ASSERT(args.length() == 1);
   2190   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
   2191   Handle<Map> old_map(object->map());
   2192   if (!old_map->is_access_check_needed()) {
   2193     // Copy map so it won't interfere constructor's initial map.
   2194     Handle<Map> new_map = Map::Copy(old_map);
   2195     new_map->set_is_access_check_needed(true);
   2196     if (object->IsJSObject()) {
   2197       JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
   2198     } else {
   2199       object->set_map(*new_map);
   2200     }
   2201   }
   2202   return isolate->heap()->undefined_value();
   2203 }
   2204 
   2205 
   2206 // Transform getter or setter into something DefineAccessor can handle.
   2207 static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
   2208                                                    Handle<Object> component) {
   2209   if (component->IsUndefined()) return isolate->factory()->null_value();
   2210   Handle<FunctionTemplateInfo> info =
   2211       Handle<FunctionTemplateInfo>::cast(component);
   2212   return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
   2213 }
   2214 
   2215 
   2216 RUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
   2217   HandleScope scope(isolate);
   2218   ASSERT(args.length() == 6);
   2219   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2220   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   2221   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   2222   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   2223   CONVERT_SMI_ARG_CHECKED(attribute, 4);
   2224   CONVERT_SMI_ARG_CHECKED(access_control, 5);
   2225   RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
   2226   RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
   2227   RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
   2228       static_cast<PropertyAttributes>(attribute)));
   2229   JSObject::DefineAccessor(object,
   2230                            name,
   2231                            InstantiateAccessorComponent(isolate, getter),
   2232                            InstantiateAccessorComponent(isolate, setter),
   2233                            static_cast<PropertyAttributes>(attribute),
   2234                            static_cast<v8::AccessControl>(access_control));
   2235   return isolate->heap()->undefined_value();
   2236 }
   2237 
   2238 
   2239 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
   2240   HandleScope scope(isolate);
   2241   Handle<Object> args[1] = { name };
   2242   Handle<Object> error = isolate->factory()->NewTypeError(
   2243       "var_redeclaration", HandleVector(args, 1));
   2244   return isolate->Throw(*error);
   2245 }
   2246 
   2247 
   2248 RUNTIME_FUNCTION(RuntimeHidden_DeclareGlobals) {
   2249   HandleScope scope(isolate);
   2250   ASSERT(args.length() == 3);
   2251   Handle<GlobalObject> global = Handle<GlobalObject>(
   2252       isolate->context()->global_object());
   2253 
   2254   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   2255   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
   2256   CONVERT_SMI_ARG_CHECKED(flags, 2);
   2257 
   2258   // Traverse the name/value pairs and set the properties.
   2259   int length = pairs->length();
   2260   for (int i = 0; i < length; i += 2) {
   2261     HandleScope scope(isolate);
   2262     Handle<String> name(String::cast(pairs->get(i)));
   2263     Handle<Object> value(pairs->get(i + 1), isolate);
   2264 
   2265     // We have to declare a global const property. To capture we only
   2266     // assign to it when evaluating the assignment for "const x =
   2267     // <expr>" the initial value is the hole.
   2268     bool is_var = value->IsUndefined();
   2269     bool is_const = value->IsTheHole();
   2270     bool is_function = value->IsSharedFunctionInfo();
   2271     ASSERT(is_var + is_const + is_function == 1);
   2272 
   2273     if (is_var || is_const) {
   2274       // Lookup the property in the global object, and don't set the
   2275       // value of the variable if the property is already there.
   2276       // Do the lookup own properties only, see ES5 erratum.
   2277       LookupResult lookup(isolate);
   2278       global->LookupOwn(name, &lookup, true);
   2279       if (lookup.IsFound()) {
   2280         // We found an existing property. Unless it was an interceptor
   2281         // that claims the property is absent, skip this declaration.
   2282         if (!lookup.IsInterceptor()) continue;
   2283         if (JSReceiver::GetPropertyAttributes(global, name) != ABSENT) continue;
   2284         // Fall-through and introduce the absent property by using
   2285         // SetProperty.
   2286       }
   2287     } else if (is_function) {
   2288       // Copy the function and update its context. Use it as value.
   2289       Handle<SharedFunctionInfo> shared =
   2290           Handle<SharedFunctionInfo>::cast(value);
   2291       Handle<JSFunction> function =
   2292           isolate->factory()->NewFunctionFromSharedFunctionInfo(
   2293               shared, context, TENURED);
   2294       value = function;
   2295     }
   2296 
   2297     LookupResult lookup(isolate);
   2298     global->LookupOwn(name, &lookup, true);
   2299 
   2300     // Compute the property attributes. According to ECMA-262,
   2301     // the property must be non-configurable except in eval.
   2302     int attr = NONE;
   2303     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
   2304     if (!is_eval) {
   2305       attr |= DONT_DELETE;
   2306     }
   2307     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
   2308     if (is_const || (is_native && is_function)) {
   2309       attr |= READ_ONLY;
   2310     }
   2311 
   2312     StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
   2313 
   2314     if (!lookup.IsFound() || is_function) {
   2315       // If the own property exists, check that we can reconfigure it
   2316       // as required for function declarations.
   2317       if (lookup.IsFound() && lookup.IsDontDelete()) {
   2318         if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
   2319             lookup.IsPropertyCallbacks()) {
   2320           return ThrowRedeclarationError(isolate, name);
   2321         }
   2322         // If the existing property is not configurable, keep its attributes.
   2323         attr = lookup.GetAttributes();
   2324       }
   2325       // Define or redefine own property.
   2326       RETURN_FAILURE_ON_EXCEPTION(isolate,
   2327           JSObject::SetOwnPropertyIgnoreAttributes(
   2328               global, name, value, static_cast<PropertyAttributes>(attr)));
   2329     } else {
   2330       // Do a [[Put]] on the existing (own) property.
   2331       RETURN_FAILURE_ON_EXCEPTION(
   2332           isolate,
   2333           JSObject::SetProperty(
   2334               global, name, value, static_cast<PropertyAttributes>(attr),
   2335               strict_mode));
   2336     }
   2337   }
   2338 
   2339   ASSERT(!isolate->has_pending_exception());
   2340   return isolate->heap()->undefined_value();
   2341 }
   2342 
   2343 
   2344 RUNTIME_FUNCTION(RuntimeHidden_DeclareContextSlot) {
   2345   HandleScope scope(isolate);
   2346   ASSERT(args.length() == 4);
   2347 
   2348   // Declarations are always made in a function or native context.  In the
   2349   // case of eval code, the context passed is the context of the caller,
   2350   // which may be some nested context and not the declaration context.
   2351   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
   2352   Handle<Context> context(context_arg->declaration_context());
   2353   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   2354   CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
   2355   PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
   2356   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
   2357   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
   2358 
   2359   int index;
   2360   PropertyAttributes attributes;
   2361   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   2362   BindingFlags binding_flags;
   2363   Handle<Object> holder =
   2364       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2365 
   2366   if (attributes != ABSENT) {
   2367     // The name was declared before; check for conflicting re-declarations.
   2368     // Note: this is actually inconsistent with what happens for globals (where
   2369     // we silently ignore such declarations).
   2370     if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
   2371       // Functions are not read-only.
   2372       ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
   2373       return ThrowRedeclarationError(isolate, name);
   2374     }
   2375 
   2376     // Initialize it if necessary.
   2377     if (*initial_value != NULL) {
   2378       if (index >= 0) {
   2379         ASSERT(holder.is_identical_to(context));
   2380         if (((attributes & READ_ONLY) == 0) ||
   2381             context->get(index)->IsTheHole()) {
   2382           context->set(index, *initial_value);
   2383         }
   2384       } else {
   2385         // Slow case: The property is in the context extension object of a
   2386         // function context or the global object of a native context.
   2387         Handle<JSObject> object = Handle<JSObject>::cast(holder);
   2388         RETURN_FAILURE_ON_EXCEPTION(
   2389             isolate,
   2390             JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
   2391       }
   2392     }
   2393 
   2394   } else {
   2395     // The property is not in the function context. It needs to be
   2396     // "declared" in the function context's extension context or as a
   2397     // property of the the global object.
   2398     Handle<JSObject> object;
   2399     if (context->has_extension()) {
   2400       object = Handle<JSObject>(JSObject::cast(context->extension()));
   2401     } else {
   2402       // Context extension objects are allocated lazily.
   2403       ASSERT(context->IsFunctionContext());
   2404       object = isolate->factory()->NewJSObject(
   2405           isolate->context_extension_function());
   2406       context->set_extension(*object);
   2407     }
   2408     ASSERT(*object != NULL);
   2409 
   2410     // Declare the property by setting it to the initial value if provided,
   2411     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
   2412     // constant declarations).
   2413     ASSERT(!JSReceiver::HasOwnProperty(object, name));
   2414     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
   2415     if (*initial_value != NULL) value = initial_value;
   2416     // Declaring a const context slot is a conflicting declaration if
   2417     // there is a callback with that name in a prototype. It is
   2418     // allowed to introduce const variables in
   2419     // JSContextExtensionObjects. They are treated specially in
   2420     // SetProperty and no setters are invoked for those since they are
   2421     // not real JSObjects.
   2422     if (initial_value->IsTheHole() &&
   2423         !object->IsJSContextExtensionObject()) {
   2424       LookupResult lookup(isolate);
   2425       object->Lookup(name, &lookup);
   2426       if (lookup.IsPropertyCallbacks()) {
   2427         return ThrowRedeclarationError(isolate, name);
   2428       }
   2429     }
   2430     if (object->IsJSGlobalObject()) {
   2431       // Define own property on the global object.
   2432       RETURN_FAILURE_ON_EXCEPTION(isolate,
   2433          JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, mode));
   2434     } else {
   2435       RETURN_FAILURE_ON_EXCEPTION(isolate,
   2436          JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
   2437     }
   2438   }
   2439 
   2440   return isolate->heap()->undefined_value();
   2441 }
   2442 
   2443 
   2444 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
   2445   HandleScope scope(isolate);
   2446   // args[0] == name
   2447   // args[1] == language_mode
   2448   // args[2] == value (optional)
   2449 
   2450   // Determine if we need to assign to the variable if it already
   2451   // exists (based on the number of arguments).
   2452   RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
   2453   bool assign = args.length() == 3;
   2454 
   2455   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2456   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
   2457 
   2458   // According to ECMA-262, section 12.2, page 62, the property must
   2459   // not be deletable.
   2460   PropertyAttributes attributes = DONT_DELETE;
   2461 
   2462   // Lookup the property as own on the global object. If it isn't
   2463   // there, there is a property with this name in the prototype chain.
   2464   // We follow Safari and Firefox behavior and only set the property
   2465   // if there is an explicit initialization value that we have
   2466   // to assign to the property.
   2467   // Note that objects can have hidden prototypes, so we need to traverse
   2468   // the whole chain of hidden prototypes to do an 'own' lookup.
   2469   LookupResult lookup(isolate);
   2470   isolate->context()->global_object()->LookupOwn(name, &lookup, true);
   2471   if (lookup.IsInterceptor()) {
   2472     Handle<JSObject> holder(lookup.holder());
   2473     PropertyAttributes intercepted =
   2474         JSReceiver::GetPropertyAttributes(holder, name);
   2475     if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
   2476       // Found an interceptor that's not read only.
   2477       if (assign) {
   2478         CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   2479         Handle<Object> result;
   2480         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2481             isolate, result,
   2482             JSObject::SetPropertyForResult(
   2483                 holder, &lookup, name, value, attributes, strict_mode));
   2484         return *result;
   2485       } else {
   2486         return isolate->heap()->undefined_value();
   2487       }
   2488     }
   2489   }
   2490 
   2491   if (assign) {
   2492     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   2493     Handle<GlobalObject> global(isolate->context()->global_object());
   2494     Handle<Object> result;
   2495     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2496         isolate, result,
   2497         JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
   2498     return *result;
   2499   }
   2500   return isolate->heap()->undefined_value();
   2501 }
   2502 
   2503 
   2504 RUNTIME_FUNCTION(RuntimeHidden_InitializeConstGlobal) {
   2505   SealHandleScope shs(isolate);
   2506   // All constants are declared with an initial value. The name
   2507   // of the constant is the first argument and the initial value
   2508   // is the second.
   2509   RUNTIME_ASSERT(args.length() == 2);
   2510   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2511   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
   2512 
   2513   // Get the current global object from top.
   2514   GlobalObject* global = isolate->context()->global_object();
   2515 
   2516   // According to ECMA-262, section 12.2, page 62, the property must
   2517   // not be deletable. Since it's a const, it must be READ_ONLY too.
   2518   PropertyAttributes attributes =
   2519       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
   2520 
   2521   // Lookup the property as own on the global object. If it isn't
   2522   // there, we add the property and take special precautions to always
   2523   // add it even in case of callbacks in the prototype chain (this rules
   2524   // out using SetProperty). We use SetOwnPropertyIgnoreAttributes instead
   2525   LookupResult lookup(isolate);
   2526   global->LookupOwn(name, &lookup);
   2527   if (!lookup.IsFound()) {
   2528     HandleScope handle_scope(isolate);
   2529     Handle<GlobalObject> global(isolate->context()->global_object());
   2530     RETURN_FAILURE_ON_EXCEPTION(
   2531         isolate,
   2532         JSObject::SetOwnPropertyIgnoreAttributes(global, name, value,
   2533                                                  attributes));
   2534     return *value;
   2535   }
   2536 
   2537   if (!lookup.IsReadOnly()) {
   2538     // Restore global object from context (in case of GC) and continue
   2539     // with setting the value.
   2540     HandleScope handle_scope(isolate);
   2541     Handle<GlobalObject> global(isolate->context()->global_object());
   2542 
   2543     // BUG 1213575: Handle the case where we have to set a read-only
   2544     // property through an interceptor and only do it if it's
   2545     // uninitialized, e.g. the hole. Nirk...
   2546     // Passing sloppy mode because the property is writable.
   2547     RETURN_FAILURE_ON_EXCEPTION(
   2548         isolate,
   2549         JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
   2550     return *value;
   2551   }
   2552 
   2553   // Set the value, but only if we're assigning the initial value to a
   2554   // constant. For now, we determine this by checking if the
   2555   // current value is the hole.
   2556   // Strict mode handling not needed (const is disallowed in strict mode).
   2557   if (lookup.IsField()) {
   2558     FixedArray* properties = global->properties();
   2559     int index = lookup.GetFieldIndex().outobject_array_index();
   2560     if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
   2561       properties->set(index, *value);
   2562     }
   2563   } else if (lookup.IsNormal()) {
   2564     if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
   2565         !lookup.IsReadOnly()) {
   2566       HandleScope scope(isolate);
   2567       JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
   2568     }
   2569   } else {
   2570     // Ignore re-initialization of constants that have already been
   2571     // assigned a constant value.
   2572     ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
   2573   }
   2574 
   2575   // Use the set value as the result of the operation.
   2576   return *value;
   2577 }
   2578 
   2579 
   2580 RUNTIME_FUNCTION(RuntimeHidden_InitializeConstContextSlot) {
   2581   HandleScope scope(isolate);
   2582   ASSERT(args.length() == 3);
   2583 
   2584   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
   2585   ASSERT(!value->IsTheHole());
   2586   // Initializations are always done in a function or native context.
   2587   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
   2588   Handle<Context> context(context_arg->declaration_context());
   2589   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   2590 
   2591   int index;
   2592   PropertyAttributes attributes;
   2593   ContextLookupFlags flags = FOLLOW_CHAINS;
   2594   BindingFlags binding_flags;
   2595   Handle<Object> holder =
   2596       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2597 
   2598   if (index >= 0) {
   2599     ASSERT(holder->IsContext());
   2600     // Property was found in a context.  Perform the assignment if we
   2601     // found some non-constant or an uninitialized constant.
   2602     Handle<Context> context = Handle<Context>::cast(holder);
   2603     if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
   2604       context->set(index, *value);
   2605     }
   2606     return *value;
   2607   }
   2608 
   2609   // The property could not be found, we introduce it as a property of the
   2610   // global object.
   2611   if (attributes == ABSENT) {
   2612     Handle<JSObject> global = Handle<JSObject>(
   2613         isolate->context()->global_object());
   2614     // Strict mode not needed (const disallowed in strict mode).
   2615     RETURN_FAILURE_ON_EXCEPTION(
   2616         isolate,
   2617         JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
   2618     return *value;
   2619   }
   2620 
   2621   // The property was present in some function's context extension object,
   2622   // as a property on the subject of a with, or as a property of the global
   2623   // object.
   2624   //
   2625   // In most situations, eval-introduced consts should still be present in
   2626   // the context extension object.  However, because declaration and
   2627   // initialization are separate, the property might have been deleted
   2628   // before we reach the initialization point.
   2629   //
   2630   // Example:
   2631   //
   2632   //    function f() { eval("delete x; const x;"); }
   2633   //
   2634   // In that case, the initialization behaves like a normal assignment.
   2635   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   2636 
   2637   if (*object == context->extension()) {
   2638     // This is the property that was introduced by the const declaration.
   2639     // Set it if it hasn't been set before.  NOTE: We cannot use
   2640     // GetProperty() to get the current value as it 'unholes' the value.
   2641     LookupResult lookup(isolate);
   2642     object->LookupOwnRealNamedProperty(name, &lookup);
   2643     ASSERT(lookup.IsFound());  // the property was declared
   2644     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
   2645 
   2646     if (lookup.IsField()) {
   2647       FixedArray* properties = object->properties();
   2648       FieldIndex index = lookup.GetFieldIndex();
   2649       ASSERT(!index.is_inobject());
   2650       if (properties->get(index.outobject_array_index())->IsTheHole()) {
   2651         properties->set(index.outobject_array_index(), *value);
   2652       }
   2653     } else if (lookup.IsNormal()) {
   2654       if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
   2655         JSObject::SetNormalizedProperty(object, &lookup, value);
   2656       }
   2657     } else {
   2658       // We should not reach here. Any real, named property should be
   2659       // either a field or a dictionary slot.
   2660       UNREACHABLE();
   2661     }
   2662   } else {
   2663     // The property was found on some other object.  Set it if it is not a
   2664     // read-only property.
   2665     if ((attributes & READ_ONLY) == 0) {
   2666       // Strict mode not needed (const disallowed in strict mode).
   2667       RETURN_FAILURE_ON_EXCEPTION(
   2668           isolate,
   2669           JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
   2670     }
   2671   }
   2672 
   2673   return *value;
   2674 }
   2675 
   2676 
   2677 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
   2678   HandleScope scope(isolate);
   2679   ASSERT(args.length() == 2);
   2680   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2681   CONVERT_SMI_ARG_CHECKED(properties, 1);
   2682   // Conservative upper limit to prevent fuzz tests from going OOM.
   2683   RUNTIME_ASSERT(properties <= 100000);
   2684   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
   2685     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
   2686   }
   2687   return *object;
   2688 }
   2689 
   2690 
   2691 RUNTIME_FUNCTION(RuntimeHidden_RegExpExec) {
   2692   HandleScope scope(isolate);
   2693   ASSERT(args.length() == 4);
   2694   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2695   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   2696   // Due to the way the JS calls are constructed this must be less than the
   2697   // length of a string, i.e. it is always a Smi.  We check anyway for security.
   2698   CONVERT_SMI_ARG_CHECKED(index, 2);
   2699   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   2700   RUNTIME_ASSERT(index >= 0);
   2701   RUNTIME_ASSERT(index <= subject->length());
   2702   isolate->counters()->regexp_entry_runtime()->Increment();
   2703   Handle<Object> result;
   2704   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2705       isolate, result,
   2706       RegExpImpl::Exec(regexp, subject, index, last_match_info));
   2707   return *result;
   2708 }
   2709 
   2710 
   2711 RUNTIME_FUNCTION(RuntimeHidden_RegExpConstructResult) {
   2712   HandleScope handle_scope(isolate);
   2713   ASSERT(args.length() == 3);
   2714   CONVERT_SMI_ARG_CHECKED(size, 0);
   2715   RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
   2716   CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
   2717   CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
   2718   Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
   2719   Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
   2720   Handle<JSObject> object =
   2721       isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
   2722   Handle<JSArray> array = Handle<JSArray>::cast(object);
   2723   array->set_elements(*elements);
   2724   array->set_length(Smi::FromInt(size));
   2725   // Write in-object properties after the length of the array.
   2726   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
   2727   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
   2728   return *array;
   2729 }
   2730 
   2731 
   2732 RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
   2733   HandleScope scope(isolate);
   2734   ASSERT(args.length() == 5);
   2735   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2736   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   2737   // If source is the empty string we set it to "(?:)" instead as
   2738   // suggested by ECMA-262, 5th, section 15.10.4.1.
   2739   if (source->length() == 0) source = isolate->factory()->query_colon_string();
   2740 
   2741   CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
   2742   if (!global->IsTrue()) global = isolate->factory()->false_value();
   2743 
   2744   CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
   2745   if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
   2746 
   2747   CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
   2748   if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
   2749 
   2750   Map* map = regexp->map();
   2751   Object* constructor = map->constructor();
   2752   if (constructor->IsJSFunction() &&
   2753       JSFunction::cast(constructor)->initial_map() == map) {
   2754     // If we still have the original map, set in-object properties directly.
   2755     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
   2756     // Both true and false are immovable immortal objects so no need for write
   2757     // barrier.
   2758     regexp->InObjectPropertyAtPut(
   2759         JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
   2760     regexp->InObjectPropertyAtPut(
   2761         JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
   2762     regexp->InObjectPropertyAtPut(
   2763         JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
   2764     regexp->InObjectPropertyAtPut(
   2765         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
   2766     return *regexp;
   2767   }
   2768 
   2769   // Map has changed, so use generic, but slower, method.
   2770   PropertyAttributes final =
   2771       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
   2772   PropertyAttributes writable =
   2773       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
   2774   Handle<Object> zero(Smi::FromInt(0), isolate);
   2775   Factory* factory = isolate->factory();
   2776   JSObject::SetOwnPropertyIgnoreAttributes(
   2777       regexp, factory->source_string(), source, final).Check();
   2778   JSObject::SetOwnPropertyIgnoreAttributes(
   2779       regexp, factory->global_string(), global, final).Check();
   2780   JSObject::SetOwnPropertyIgnoreAttributes(
   2781       regexp, factory->ignore_case_string(), ignoreCase, final).Check();
   2782   JSObject::SetOwnPropertyIgnoreAttributes(
   2783       regexp, factory->multiline_string(), multiline, final).Check();
   2784   JSObject::SetOwnPropertyIgnoreAttributes(
   2785       regexp, factory->last_index_string(), zero, writable).Check();
   2786   return *regexp;
   2787 }
   2788 
   2789 
   2790 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
   2791   HandleScope scope(isolate);
   2792   ASSERT(args.length() == 1);
   2793   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
   2794   Object* length = prototype->length();
   2795   RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
   2796   RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
   2797   // This is necessary to enable fast checks for absence of elements
   2798   // on Array.prototype and below.
   2799   prototype->set_elements(isolate->heap()->empty_fixed_array());
   2800   return Smi::FromInt(0);
   2801 }
   2802 
   2803 
   2804 static void InstallBuiltin(Isolate* isolate,
   2805                            Handle<JSObject> holder,
   2806                            const char* name,
   2807                            Builtins::Name builtin_name) {
   2808   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
   2809   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
   2810   Handle<JSFunction> optimized =
   2811       isolate->factory()->NewFunctionWithoutPrototype(key, code);
   2812   optimized->shared()->DontAdaptArguments();
   2813   JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT).Assert();
   2814 }
   2815 
   2816 
   2817 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
   2818   HandleScope scope(isolate);
   2819   ASSERT(args.length() == 0);
   2820   Handle<JSObject> holder =
   2821       isolate->factory()->NewJSObject(isolate->object_function());
   2822 
   2823   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
   2824   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
   2825   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
   2826   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
   2827   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
   2828   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
   2829   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
   2830 
   2831   return *holder;
   2832 }
   2833 
   2834 
   2835 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
   2836   SealHandleScope shs(isolate);
   2837   ASSERT(args.length() == 1);
   2838   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2839   if (!callable->IsJSFunction()) {
   2840     HandleScope scope(isolate);
   2841     Handle<Object> delegate;
   2842     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2843         isolate, delegate,
   2844         Execution::TryGetFunctionDelegate(
   2845             isolate, Handle<JSReceiver>(callable)));
   2846     callable = JSFunction::cast(*delegate);
   2847   }
   2848   JSFunction* function = JSFunction::cast(callable);
   2849   SharedFunctionInfo* shared = function->shared();
   2850   return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
   2851 }
   2852 
   2853 
   2854 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
   2855   SealHandleScope shs(isolate);
   2856   ASSERT(args.length() == 1);
   2857   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2858 
   2859   if (!callable->IsJSFunction()) {
   2860     HandleScope scope(isolate);
   2861     Handle<Object> delegate;
   2862     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2863         isolate, delegate,
   2864         Execution::TryGetFunctionDelegate(
   2865             isolate, Handle<JSReceiver>(callable)));
   2866     callable = JSFunction::cast(*delegate);
   2867   }
   2868   JSFunction* function = JSFunction::cast(callable);
   2869 
   2870   SharedFunctionInfo* shared = function->shared();
   2871   if (shared->native() || shared->strict_mode() == STRICT) {
   2872     return isolate->heap()->undefined_value();
   2873   }
   2874   // Returns undefined for strict or native functions, or
   2875   // the associated global receiver for "normal" functions.
   2876 
   2877   Context* native_context =
   2878       function->context()->global_object()->native_context();
   2879   return native_context->global_object()->global_receiver();
   2880 }
   2881 
   2882 
   2883 RUNTIME_FUNCTION(RuntimeHidden_MaterializeRegExpLiteral) {
   2884   HandleScope scope(isolate);
   2885   ASSERT(args.length() == 4);
   2886   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
   2887   CONVERT_SMI_ARG_CHECKED(index, 1);
   2888   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
   2889   CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
   2890 
   2891   // Get the RegExp function from the context in the literals array.
   2892   // This is the RegExp function from the context in which the
   2893   // function was created.  We do not use the RegExp function from the
   2894   // current native context because this might be the RegExp function
   2895   // from another context which we should not have access to.
   2896   Handle<JSFunction> constructor =
   2897       Handle<JSFunction>(
   2898           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
   2899   // Compute the regular expression literal.
   2900   Handle<Object> regexp;
   2901   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2902       isolate, regexp,
   2903       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
   2904   literals->set(index, *regexp);
   2905   return *regexp;
   2906 }
   2907 
   2908 
   2909 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
   2910   SealHandleScope shs(isolate);
   2911   ASSERT(args.length() == 1);
   2912 
   2913   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2914   return f->shared()->name();
   2915 }
   2916 
   2917 
   2918 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
   2919   SealHandleScope shs(isolate);
   2920   ASSERT(args.length() == 2);
   2921 
   2922   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2923   CONVERT_ARG_CHECKED(String, name, 1);
   2924   f->shared()->set_name(name);
   2925   return isolate->heap()->undefined_value();
   2926 }
   2927 
   2928 
   2929 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
   2930   SealHandleScope shs(isolate);
   2931   ASSERT(args.length() == 1);
   2932   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2933   return isolate->heap()->ToBoolean(
   2934       f->shared()->name_should_print_as_anonymous());
   2935 }
   2936 
   2937 
   2938 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
   2939   SealHandleScope shs(isolate);
   2940   ASSERT(args.length() == 1);
   2941   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2942   f->shared()->set_name_should_print_as_anonymous(true);
   2943   return isolate->heap()->undefined_value();
   2944 }
   2945 
   2946 
   2947 RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
   2948   SealHandleScope shs(isolate);
   2949   ASSERT(args.length() == 1);
   2950   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2951   return isolate->heap()->ToBoolean(f->shared()->is_generator());
   2952 }
   2953 
   2954 
   2955 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
   2956   SealHandleScope shs(isolate);
   2957   ASSERT(args.length() == 1);
   2958 
   2959   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2960   RUNTIME_ASSERT(f->RemovePrototype());
   2961 
   2962   return isolate->heap()->undefined_value();
   2963 }
   2964 
   2965 
   2966 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
   2967   HandleScope scope(isolate);
   2968   ASSERT(args.length() == 1);
   2969 
   2970   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2971   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
   2972   if (!script->IsScript()) return isolate->heap()->undefined_value();
   2973 
   2974   return *Script::GetWrapper(Handle<Script>::cast(script));
   2975 }
   2976 
   2977 
   2978 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
   2979   HandleScope scope(isolate);
   2980   ASSERT(args.length() == 1);
   2981 
   2982   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
   2983   Handle<SharedFunctionInfo> shared(f->shared());
   2984   return *shared->GetSourceCode();
   2985 }
   2986 
   2987 
   2988 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
   2989   SealHandleScope shs(isolate);
   2990   ASSERT(args.length() == 1);
   2991 
   2992   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2993   int pos = fun->shared()->start_position();
   2994   return Smi::FromInt(pos);
   2995 }
   2996 
   2997 
   2998 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
   2999   SealHandleScope shs(isolate);
   3000   ASSERT(args.length() == 2);
   3001 
   3002   CONVERT_ARG_CHECKED(Code, code, 0);
   3003   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
   3004 
   3005   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
   3006 
   3007   Address pc = code->address() + offset;
   3008   return Smi::FromInt(code->SourcePosition(pc));
   3009 }
   3010 
   3011 
   3012 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
   3013   SealHandleScope shs(isolate);
   3014   ASSERT(args.length() == 2);
   3015 
   3016   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   3017   CONVERT_ARG_CHECKED(String, name, 1);
   3018   fun->SetInstanceClassName(name);
   3019   return isolate->heap()->undefined_value();
   3020 }
   3021 
   3022 
   3023 RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
   3024   SealHandleScope shs(isolate);
   3025   ASSERT(args.length() == 2);
   3026 
   3027   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   3028   CONVERT_SMI_ARG_CHECKED(length, 1);
   3029   RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
   3030                  (length & 0xC0000000) == 0x0);
   3031   fun->shared()->set_length(length);
   3032   return isolate->heap()->undefined_value();
   3033 }
   3034 
   3035 
   3036 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
   3037   HandleScope scope(isolate);
   3038   ASSERT(args.length() == 2);
   3039 
   3040   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   3041   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
   3042   RUNTIME_ASSERT(fun->should_have_prototype());
   3043   Accessors::FunctionSetPrototype(fun, value);
   3044   return args[0];  // return TOS
   3045 }
   3046 
   3047 
   3048 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
   3049   SealHandleScope shs(isolate);
   3050   ASSERT(args.length() == 1);
   3051 
   3052   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   3053   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
   3054 }
   3055 
   3056 
   3057 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
   3058   SealHandleScope shs(isolate);
   3059   ASSERT(args.length() == 1);
   3060 
   3061   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   3062   return isolate->heap()->ToBoolean(f->IsBuiltin());
   3063 }
   3064 
   3065 
   3066 RUNTIME_FUNCTION(Runtime_SetCode) {
   3067   HandleScope scope(isolate);
   3068   ASSERT(args.length() == 2);
   3069 
   3070   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
   3071   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
   3072 
   3073   Handle<SharedFunctionInfo> target_shared(target->shared());
   3074   Handle<SharedFunctionInfo> source_shared(source->shared());
   3075   RUNTIME_ASSERT(!source_shared->bound());
   3076 
   3077   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
   3078     return isolate->heap()->exception();
   3079   }
   3080 
   3081   // Mark both, the source and the target, as un-flushable because the
   3082   // shared unoptimized code makes them impossible to enqueue in a list.
   3083   ASSERT(target_shared->code()->gc_metadata() == NULL);
   3084   ASSERT(source_shared->code()->gc_metadata() == NULL);
   3085   target_shared->set_dont_flush(true);
   3086   source_shared->set_dont_flush(true);
   3087 
   3088   // Set the code, scope info, formal parameter count, and the length
   3089   // of the target shared function info.
   3090   target_shared->ReplaceCode(source_shared->code());
   3091   target_shared->set_scope_info(source_shared->scope_info());
   3092   target_shared->set_length(source_shared->length());
   3093   target_shared->set_feedback_vector(source_shared->feedback_vector());
   3094   target_shared->set_formal_parameter_count(
   3095       source_shared->formal_parameter_count());
   3096   target_shared->set_script(source_shared->script());
   3097   target_shared->set_start_position_and_type(
   3098       source_shared->start_position_and_type());
   3099   target_shared->set_end_position(source_shared->end_position());
   3100   bool was_native = target_shared->native();
   3101   target_shared->set_compiler_hints(source_shared->compiler_hints());
   3102   target_shared->set_native(was_native);
   3103   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
   3104 
   3105   // Set the code of the target function.
   3106   target->ReplaceCode(source_shared->code());
   3107   ASSERT(target->next_function_link()->IsUndefined());
   3108 
   3109   // Make sure we get a fresh copy of the literal vector to avoid cross
   3110   // context contamination.
   3111   Handle<Context> context(source->context());
   3112   int number_of_literals = source->NumberOfLiterals();
   3113   Handle<FixedArray> literals =
   3114       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
   3115   if (number_of_literals > 0) {
   3116     literals->set(JSFunction::kLiteralNativeContextIndex,
   3117                   context->native_context());
   3118   }
   3119   target->set_context(*context);
   3120   target->set_literals(*literals);
   3121 
   3122   if (isolate->logger()->is_logging_code_events() ||
   3123       isolate->cpu_profiler()->is_profiling()) {
   3124     isolate->logger()->LogExistingFunction(
   3125         source_shared, Handle<Code>(source_shared->code()));
   3126   }
   3127 
   3128   return *target;
   3129 }
   3130 
   3131 
   3132 RUNTIME_FUNCTION(RuntimeHidden_CreateJSGeneratorObject) {
   3133   HandleScope scope(isolate);
   3134   ASSERT(args.length() == 0);
   3135 
   3136   JavaScriptFrameIterator it(isolate);
   3137   JavaScriptFrame* frame = it.frame();
   3138   Handle<JSFunction> function(frame->function());
   3139   RUNTIME_ASSERT(function->shared()->is_generator());
   3140 
   3141   Handle<JSGeneratorObject> generator;
   3142   if (frame->IsConstructor()) {
   3143     generator = handle(JSGeneratorObject::cast(frame->receiver()));
   3144   } else {
   3145     generator = isolate->factory()->NewJSGeneratorObject(function);
   3146   }
   3147   generator->set_function(*function);
   3148   generator->set_context(Context::cast(frame->context()));
   3149   generator->set_receiver(frame->receiver());
   3150   generator->set_continuation(0);
   3151   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
   3152   generator->set_stack_handler_index(-1);
   3153 
   3154   return *generator;
   3155 }
   3156 
   3157 
   3158 RUNTIME_FUNCTION(RuntimeHidden_SuspendJSGeneratorObject) {
   3159   HandleScope handle_scope(isolate);
   3160   ASSERT(args.length() == 1);
   3161   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
   3162 
   3163   JavaScriptFrameIterator stack_iterator(isolate);
   3164   JavaScriptFrame* frame = stack_iterator.frame();
   3165   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
   3166   ASSERT_EQ(frame->function(), generator_object->function());
   3167 
   3168   // The caller should have saved the context and continuation already.
   3169   ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
   3170   ASSERT_LT(0, generator_object->continuation());
   3171 
   3172   // We expect there to be at least two values on the operand stack: the return
   3173   // value of the yield expression, and the argument to this runtime call.
   3174   // Neither of those should be saved.
   3175   int operands_count = frame->ComputeOperandsCount();
   3176   ASSERT_GE(operands_count, 2);
   3177   operands_count -= 2;
   3178 
   3179   if (operands_count == 0) {
   3180     // Although it's semantically harmless to call this function with an
   3181     // operands_count of zero, it is also unnecessary.
   3182     ASSERT_EQ(generator_object->operand_stack(),
   3183               isolate->heap()->empty_fixed_array());
   3184     ASSERT_EQ(generator_object->stack_handler_index(), -1);
   3185     // If there are no operands on the stack, there shouldn't be a handler
   3186     // active either.
   3187     ASSERT(!frame->HasHandler());
   3188   } else {
   3189     int stack_handler_index = -1;
   3190     Handle<FixedArray> operand_stack =
   3191         isolate->factory()->NewFixedArray(operands_count);
   3192     frame->SaveOperandStack(*operand_stack, &stack_handler_index);
   3193     generator_object->set_operand_stack(*operand_stack);
   3194     generator_object->set_stack_handler_index(stack_handler_index);
   3195   }
   3196 
   3197   return isolate->heap()->undefined_value();
   3198 }
   3199 
   3200 
   3201 // Note that this function is the slow path for resuming generators.  It is only
   3202 // called if the suspended activation had operands on the stack, stack handlers
   3203 // needing rewinding, or if the resume should throw an exception.  The fast path
   3204 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
   3205 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
   3206 // called in any case, as it needs to reconstruct the stack frame and make space
   3207 // for arguments and operands.
   3208 RUNTIME_FUNCTION(RuntimeHidden_ResumeJSGeneratorObject) {
   3209   SealHandleScope shs(isolate);
   3210   ASSERT(args.length() == 3);
   3211   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
   3212   CONVERT_ARG_CHECKED(Object, value, 1);
   3213   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
   3214   JavaScriptFrameIterator stack_iterator(isolate);
   3215   JavaScriptFrame* frame = stack_iterator.frame();
   3216 
   3217   ASSERT_EQ(frame->function(), generator_object->function());
   3218   ASSERT(frame->function()->is_compiled());
   3219 
   3220   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
   3221   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
   3222 
   3223   Address pc = generator_object->function()->code()->instruction_start();
   3224   int offset = generator_object->continuation();
   3225   ASSERT(offset > 0);
   3226   frame->set_pc(pc + offset);
   3227   if (FLAG_enable_ool_constant_pool) {
   3228     frame->set_constant_pool(
   3229         generator_object->function()->code()->constant_pool());
   3230   }
   3231   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
   3232 
   3233   FixedArray* operand_stack = generator_object->operand_stack();
   3234   int operands_count = operand_stack->length();
   3235   if (operands_count != 0) {
   3236     frame->RestoreOperandStack(operand_stack,
   3237                                generator_object->stack_handler_index());
   3238     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
   3239     generator_object->set_stack_handler_index(-1);
   3240   }
   3241 
   3242   JSGeneratorObject::ResumeMode resume_mode =
   3243       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
   3244   switch (resume_mode) {
   3245     case JSGeneratorObject::NEXT:
   3246       return value;
   3247     case JSGeneratorObject::THROW:
   3248       return isolate->Throw(value);
   3249   }
   3250 
   3251   UNREACHABLE();
   3252   return isolate->ThrowIllegalOperation();
   3253 }
   3254 
   3255 
   3256 RUNTIME_FUNCTION(RuntimeHidden_ThrowGeneratorStateError) {
   3257   HandleScope scope(isolate);
   3258   ASSERT(args.length() == 1);
   3259   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   3260   int continuation = generator->continuation();
   3261   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
   3262       "generator_finished" : "generator_running";
   3263   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
   3264   Handle<Object> error = isolate->factory()->NewError(message, argv);
   3265   return isolate->Throw(*error);
   3266 }
   3267 
   3268 
   3269 RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
   3270   HandleScope scope(isolate);
   3271   ASSERT(args.length() == 1);
   3272   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   3273 
   3274   // %ObjectFreeze is a fast path and these cases are handled elsewhere.
   3275   RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
   3276                  !object->map()->is_observed() &&
   3277                  !object->IsJSProxy());
   3278 
   3279   Handle<Object> result;
   3280   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
   3281   return *result;
   3282 }
   3283 
   3284 
   3285 RUNTIME_FUNCTION(RuntimeHidden_StringCharCodeAt) {
   3286   HandleScope handle_scope(isolate);
   3287   ASSERT(args.length() == 2);
   3288 
   3289   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   3290   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
   3291 
   3292   // Flatten the string.  If someone wants to get a char at an index
   3293   // in a cons string, it is likely that more indices will be
   3294   // accessed.
   3295   subject = String::Flatten(subject);
   3296 
   3297   if (i >= static_cast<uint32_t>(subject->length())) {
   3298     return isolate->heap()->nan_value();
   3299   }
   3300 
   3301   return Smi::FromInt(subject->Get(i));
   3302 }
   3303 
   3304 
   3305 RUNTIME_FUNCTION(Runtime_CharFromCode) {
   3306   HandleScope handlescope(isolate);
   3307   ASSERT(args.length() == 1);
   3308   if (args[0]->IsNumber()) {
   3309     CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
   3310     code &= 0xffff;
   3311     return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
   3312   }
   3313   return isolate->heap()->empty_string();
   3314 }
   3315 
   3316 
   3317 class FixedArrayBuilder {
   3318  public:
   3319   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
   3320       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
   3321         length_(0),
   3322         has_non_smi_elements_(false) {
   3323     // Require a non-zero initial size. Ensures that doubling the size to
   3324     // extend the array will work.
   3325     ASSERT(initial_capacity > 0);
   3326   }
   3327 
   3328   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
   3329       : array_(backing_store),
   3330         length_(0),
   3331         has_non_smi_elements_(false) {
   3332     // Require a non-zero initial size. Ensures that doubling the size to
   3333     // extend the array will work.
   3334     ASSERT(backing_store->length() > 0);
   3335   }
   3336 
   3337   bool HasCapacity(int elements) {
   3338     int length = array_->length();
   3339     int required_length = length_ + elements;
   3340     return (length >= required_length);
   3341   }
   3342 
   3343   void EnsureCapacity(int elements) {
   3344     int length = array_->length();
   3345     int required_length = length_ + elements;
   3346     if (length < required_length) {
   3347       int new_length = length;
   3348       do {
   3349         new_length *= 2;
   3350       } while (new_length < required_length);
   3351       Handle<FixedArray> extended_array =
   3352           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
   3353       array_->CopyTo(0, *extended_array, 0, length_);
   3354       array_ = extended_array;
   3355     }
   3356   }
   3357 
   3358   void Add(Object* value) {
   3359     ASSERT(!value->IsSmi());
   3360     ASSERT(length_ < capacity());
   3361     array_->set(length_, value);
   3362     length_++;
   3363     has_non_smi_elements_ = true;
   3364   }
   3365 
   3366   void Add(Smi* value) {
   3367     ASSERT(value->IsSmi());
   3368     ASSERT(length_ < capacity());
   3369     array_->set(length_, value);
   3370     length_++;
   3371   }
   3372 
   3373   Handle<FixedArray> array() {
   3374     return array_;
   3375   }
   3376 
   3377   int length() {
   3378     return length_;
   3379   }
   3380 
   3381   int capacity() {
   3382     return array_->length();
   3383   }
   3384 
   3385   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
   3386     JSArray::SetContent(target_array, array_);
   3387     target_array->set_length(Smi::FromInt(length_));
   3388     return target_array;
   3389   }
   3390 
   3391 
   3392  private:
   3393   Handle<FixedArray> array_;
   3394   int length_;
   3395   bool has_non_smi_elements_;
   3396 };
   3397 
   3398 
   3399 // Forward declarations.
   3400 const int kStringBuilderConcatHelperLengthBits = 11;
   3401 const int kStringBuilderConcatHelperPositionBits = 19;
   3402 
   3403 template <typename schar>
   3404 static inline void StringBuilderConcatHelper(String*,
   3405                                              schar*,
   3406                                              FixedArray*,
   3407                                              int);
   3408 
   3409 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
   3410     StringBuilderSubstringLength;
   3411 typedef BitField<int,
   3412                  kStringBuilderConcatHelperLengthBits,
   3413                  kStringBuilderConcatHelperPositionBits>
   3414     StringBuilderSubstringPosition;
   3415 
   3416 
   3417 class ReplacementStringBuilder {
   3418  public:
   3419   ReplacementStringBuilder(Heap* heap,
   3420                            Handle<String> subject,
   3421                            int estimated_part_count)
   3422       : heap_(heap),
   3423         array_builder_(heap->isolate(), estimated_part_count),
   3424         subject_(subject),
   3425         character_count_(0),
   3426         is_ascii_(subject->IsOneByteRepresentation()) {
   3427     // Require a non-zero initial size. Ensures that doubling the size to
   3428     // extend the array will work.
   3429     ASSERT(estimated_part_count > 0);
   3430   }
   3431 
   3432   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
   3433                                      int from,
   3434                                      int to) {
   3435     ASSERT(from >= 0);
   3436     int length = to - from;
   3437     ASSERT(length > 0);
   3438     if (StringBuilderSubstringLength::is_valid(length) &&
   3439         StringBuilderSubstringPosition::is_valid(from)) {
   3440       int encoded_slice = StringBuilderSubstringLength::encode(length) |
   3441           StringBuilderSubstringPosition::encode(from);
   3442       builder->Add(Smi::FromInt(encoded_slice));
   3443     } else {
   3444       // Otherwise encode as two smis.
   3445       builder->Add(Smi::FromInt(-length));
   3446       builder->Add(Smi::FromInt(from));
   3447     }
   3448   }
   3449 
   3450 
   3451   void EnsureCapacity(int elements) {
   3452     array_builder_.EnsureCapacity(elements);
   3453   }
   3454 
   3455 
   3456   void AddSubjectSlice(int from, int to) {
   3457     AddSubjectSlice(&array_builder_, from, to);
   3458     IncrementCharacterCount(to - from);
   3459   }
   3460 
   3461 
   3462   void AddString(Handle<String> string) {
   3463     int length = string->length();
   3464     ASSERT(length > 0);
   3465     AddElement(*string);
   3466     if (!string->IsOneByteRepresentation()) {
   3467       is_ascii_ = false;
   3468     }
   3469     IncrementCharacterCount(length);
   3470   }
   3471 
   3472 
   3473   MaybeHandle<String> ToString() {
   3474     Isolate* isolate = heap_->isolate();
   3475     if (array_builder_.length() == 0) {
   3476       return isolate->factory()->empty_string();
   3477     }
   3478 
   3479     Handle<String> joined_string;
   3480     if (is_ascii_) {
   3481       Handle<SeqOneByteString> seq;
   3482       ASSIGN_RETURN_ON_EXCEPTION(
   3483           isolate, seq,
   3484           isolate->factory()->NewRawOneByteString(character_count_),
   3485           String);
   3486 
   3487       DisallowHeapAllocation no_gc;
   3488       uint8_t* char_buffer = seq->GetChars();
   3489       StringBuilderConcatHelper(*subject_,
   3490                                 char_buffer,
   3491                                 *array_builder_.array(),
   3492                                 array_builder_.length());
   3493       joined_string = Handle<String>::cast(seq);
   3494     } else {
   3495       // Non-ASCII.
   3496       Handle<SeqTwoByteString> seq;
   3497       ASSIGN_RETURN_ON_EXCEPTION(
   3498           isolate, seq,
   3499           isolate->factory()->NewRawTwoByteString(character_count_),
   3500           String);
   3501 
   3502       DisallowHeapAllocation no_gc;
   3503       uc16* char_buffer = seq->GetChars();
   3504       StringBuilderConcatHelper(*subject_,
   3505                                 char_buffer,
   3506                                 *array_builder_.array(),
   3507                                 array_builder_.length());
   3508       joined_string = Handle<String>::cast(seq);
   3509     }
   3510     return joined_string;
   3511   }
   3512 
   3513 
   3514   void IncrementCharacterCount(int by) {
   3515     if (character_count_ > String::kMaxLength - by) {
   3516       STATIC_ASSERT(String::kMaxLength < kMaxInt);
   3517       character_count_ = kMaxInt;
   3518     } else {
   3519       character_count_ += by;
   3520     }
   3521   }
   3522 
   3523  private:
   3524   void AddElement(Object* element) {
   3525     ASSERT(element->IsSmi() || element->IsString());
   3526     ASSERT(array_builder_.capacity() > array_builder_.length());
   3527     array_builder_.Add(element);
   3528   }
   3529 
   3530   Heap* heap_;
   3531   FixedArrayBuilder array_builder_;
   3532   Handle<String> subject_;
   3533   int character_count_;
   3534   bool is_ascii_;
   3535 };
   3536 
   3537 
   3538 class CompiledReplacement {
   3539  public:
   3540   explicit CompiledReplacement(Zone* zone)
   3541       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
   3542 
   3543   // Return whether the replacement is simple.
   3544   bool Compile(Handle<String> replacement,
   3545                int capture_count,
   3546                int subject_length);
   3547 
   3548   // Use Apply only if Compile returned false.
   3549   void Apply(ReplacementStringBuilder* builder,
   3550              int match_from,
   3551              int match_to,
   3552              int32_t* match);
   3553 
   3554   // Number of distinct parts of the replacement pattern.
   3555   int parts() {
   3556     return parts_.length();
   3557   }
   3558 
   3559   Zone* zone() const { return zone_; }
   3560 
   3561  private:
   3562   enum PartType {
   3563     SUBJECT_PREFIX = 1,
   3564     SUBJECT_SUFFIX,
   3565     SUBJECT_CAPTURE,
   3566     REPLACEMENT_SUBSTRING,
   3567     REPLACEMENT_STRING,
   3568 
   3569     NUMBER_OF_PART_TYPES
   3570   };
   3571 
   3572   struct ReplacementPart {
   3573     static inline ReplacementPart SubjectMatch() {
   3574       return ReplacementPart(SUBJECT_CAPTURE, 0);
   3575     }
   3576     static inline ReplacementPart SubjectCapture(int capture_index) {
   3577       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
   3578     }
   3579     static inline ReplacementPart SubjectPrefix() {
   3580       return ReplacementPart(SUBJECT_PREFIX, 0);
   3581     }
   3582     static inline ReplacementPart SubjectSuffix(int subject_length) {
   3583       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
   3584     }
   3585     static inline ReplacementPart ReplacementString() {
   3586       return ReplacementPart(REPLACEMENT_STRING, 0);
   3587     }
   3588     static inline ReplacementPart ReplacementSubString(int from, int to) {
   3589       ASSERT(from >= 0);
   3590       ASSERT(to > from);
   3591       return ReplacementPart(-from, to);
   3592     }
   3593 
   3594     // If tag <= 0 then it is the negation of a start index of a substring of
   3595     // the replacement pattern, otherwise it's a value from PartType.
   3596     ReplacementPart(int tag, int data)
   3597         : tag(tag), data(data) {
   3598       // Must be non-positive or a PartType value.
   3599       ASSERT(tag < NUMBER_OF_PART_TYPES);
   3600     }
   3601     // Either a value of PartType or a non-positive number that is
   3602     // the negation of an index into the replacement string.
   3603     int tag;
   3604     // The data value's interpretation depends on the value of tag:
   3605     // tag == SUBJECT_PREFIX ||
   3606     // tag == SUBJECT_SUFFIX:  data is unused.
   3607     // tag == SUBJECT_CAPTURE: data is the number of the capture.
   3608     // tag == REPLACEMENT_SUBSTRING ||
   3609     // tag == REPLACEMENT_STRING:    data is index into array of substrings
   3610     //                               of the replacement string.
   3611     // tag <= 0: Temporary representation of the substring of the replacement
   3612     //           string ranging over -tag .. data.
   3613     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
   3614     //           substring objects.
   3615     int data;
   3616   };
   3617 
   3618   template<typename Char>
   3619   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
   3620                                Vector<Char> characters,
   3621                                int capture_count,
   3622                                int subject_length,
   3623                                Zone* zone) {
   3624     int length = characters.length();
   3625     int last = 0;
   3626     for (int i = 0; i < length; i++) {
   3627       Char c = characters[i];
   3628       if (c == '$') {
   3629         int next_index = i + 1;
   3630         if (next_index == length) {  // No next character!
   3631           break;
   3632         }
   3633         Char c2 = characters[next_index];
   3634         switch (c2) {
   3635         case '$':
   3636           if (i > last) {
   3637             // There is a substring before. Include the first "$".
   3638             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
   3639                        zone);
   3640             last = next_index + 1;  // Continue after the second "$".
   3641           } else {
   3642             // Let the next substring start with the second "$".
   3643             last = next_index;
   3644           }
   3645           i = next_index;
   3646           break;
   3647         case '`':
   3648           if (i > last) {
   3649             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3650           }
   3651           parts->Add(ReplacementPart::SubjectPrefix(), zone);
   3652           i = next_index;
   3653           last = i + 1;
   3654           break;
   3655         case '\'':
   3656           if (i > last) {
   3657             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3658           }
   3659           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
   3660           i = next_index;
   3661           last = i + 1;
   3662           break;
   3663         case '&':
   3664           if (i > last) {
   3665             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3666           }
   3667           parts->Add(ReplacementPart::SubjectMatch(), zone);
   3668           i = next_index;
   3669           last = i + 1;
   3670           break;
   3671         case '0':
   3672         case '1':
   3673         case '2':
   3674         case '3':
   3675         case '4':
   3676         case '5':
   3677         case '6':
   3678         case '7':
   3679         case '8':
   3680         case '9': {
   3681           int capture_ref = c2 - '0';
   3682           if (capture_ref > capture_count) {
   3683             i = next_index;
   3684             continue;
   3685           }
   3686           int second_digit_index = next_index + 1;
   3687           if (second_digit_index < length) {
   3688             // Peek ahead to see if we have two digits.
   3689             Char c3 = characters[second_digit_index];
   3690             if ('0' <= c3 && c3 <= '9') {  // Double digits.
   3691               int double_digit_ref = capture_ref * 10 + c3 - '0';
   3692               if (double_digit_ref <= capture_count) {
   3693                 next_index = second_digit_index;
   3694                 capture_ref = double_digit_ref;
   3695               }
   3696             }
   3697           }
   3698           if (capture_ref > 0) {
   3699             if (i > last) {
   3700               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3701             }
   3702             ASSERT(capture_ref <= capture_count);
   3703             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
   3704             last = next_index + 1;
   3705           }
   3706           i = next_index;
   3707           break;
   3708         }
   3709         default:
   3710           i = next_index;
   3711           break;
   3712         }
   3713       }
   3714     }
   3715     if (length > last) {
   3716       if (last == 0) {
   3717         // Replacement is simple.  Do not use Apply to do the replacement.
   3718         return true;
   3719       } else {
   3720         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
   3721       }
   3722     }
   3723     return false;
   3724   }
   3725 
   3726   ZoneList<ReplacementPart> parts_;
   3727   ZoneList<Handle<String> > replacement_substrings_;
   3728   Zone* zone_;
   3729 };
   3730 
   3731 
   3732 bool CompiledReplacement::Compile(Handle<String> replacement,
   3733                                   int capture_count,
   3734                                   int subject_length) {
   3735   {
   3736     DisallowHeapAllocation no_gc;
   3737     String::FlatContent content = replacement->GetFlatContent();
   3738     ASSERT(content.IsFlat());
   3739     bool simple = false;
   3740     if (content.IsAscii()) {
   3741       simple = ParseReplacementPattern(&parts_,
   3742                                        content.ToOneByteVector(),
   3743                                        capture_count,
   3744                                        subject_length,
   3745                                        zone());
   3746     } else {
   3747       ASSERT(content.IsTwoByte());
   3748       simple = ParseReplacementPattern(&parts_,
   3749                                        content.ToUC16Vector(),
   3750                                        capture_count,
   3751                                        subject_length,
   3752                                        zone());
   3753     }
   3754     if (simple) return true;
   3755   }
   3756 
   3757   Isolate* isolate = replacement->GetIsolate();
   3758   // Find substrings of replacement string and create them as String objects.
   3759   int substring_index = 0;
   3760   for (int i = 0, n = parts_.length(); i < n; i++) {
   3761     int tag = parts_[i].tag;
   3762     if (tag <= 0) {  // A replacement string slice.
   3763       int from = -tag;
   3764       int to = parts_[i].data;
   3765       replacement_substrings_.Add(
   3766           isolate->factory()->NewSubString(replacement, from, to), zone());
   3767       parts_[i].tag = REPLACEMENT_SUBSTRING;
   3768       parts_[i].data = substring_index;
   3769       substring_index++;
   3770     } else if (tag == REPLACEMENT_STRING) {
   3771       replacement_substrings_.Add(replacement, zone());
   3772       parts_[i].data = substring_index;
   3773       substring_index++;
   3774     }
   3775   }
   3776   return false;
   3777 }
   3778 
   3779 
   3780 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
   3781                                 int match_from,
   3782                                 int match_to,
   3783                                 int32_t* match) {
   3784   ASSERT_LT(0, parts_.length());
   3785   for (int i = 0, n = parts_.length(); i < n; i++) {
   3786     ReplacementPart part = parts_[i];
   3787     switch (part.tag) {
   3788       case SUBJECT_PREFIX:
   3789         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
   3790         break;
   3791       case SUBJECT_SUFFIX: {
   3792         int subject_length = part.data;
   3793         if (match_to < subject_length) {
   3794           builder->AddSubjectSlice(match_to, subject_length);
   3795         }
   3796         break;
   3797       }
   3798       case SUBJECT_CAPTURE: {
   3799         int capture = part.data;
   3800         int from = match[capture * 2];
   3801         int to = match[capture * 2 + 1];
   3802         if (from >= 0 && to > from) {
   3803           builder->AddSubjectSlice(from, to);
   3804         }
   3805         break;
   3806       }
   3807       case REPLACEMENT_SUBSTRING:
   3808       case REPLACEMENT_STRING:
   3809         builder->AddString(replacement_substrings_[part.data]);
   3810         break;
   3811       default:
   3812         UNREACHABLE();
   3813     }
   3814   }
   3815 }
   3816 
   3817 
   3818 void FindAsciiStringIndices(Vector<const uint8_t> subject,
   3819                             char pattern,
   3820                             ZoneList<int>* indices,
   3821                             unsigned int limit,
   3822                             Zone* zone) {
   3823   ASSERT(limit > 0);
   3824   // Collect indices of pattern in subject using memchr.
   3825   // Stop after finding at most limit values.
   3826   const uint8_t* subject_start = subject.start();
   3827   const uint8_t* subject_end = subject_start + subject.length();
   3828   const uint8_t* pos = subject_start;
   3829   while (limit > 0) {
   3830     pos = reinterpret_cast<const uint8_t*>(
   3831         memchr(pos, pattern, subject_end - pos));
   3832     if (pos == NULL) return;
   3833     indices->Add(static_cast<int>(pos - subject_start), zone);
   3834     pos++;
   3835     limit--;
   3836   }
   3837 }
   3838 
   3839 
   3840 void FindTwoByteStringIndices(const Vector<const uc16> subject,
   3841                               uc16 pattern,
   3842                               ZoneList<int>* indices,
   3843                               unsigned int limit,
   3844                               Zone* zone) {
   3845   ASSERT(limit > 0);
   3846   const uc16* subject_start = subject.start();
   3847   const uc16* subject_end = subject_start + subject.length();
   3848   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
   3849     if (*pos == pattern) {
   3850       indices->Add(static_cast<int>(pos - subject_start), zone);
   3851       limit--;
   3852     }
   3853   }
   3854 }
   3855 
   3856 
   3857 template <typename SubjectChar, typename PatternChar>
   3858 void FindStringIndices(Isolate* isolate,
   3859                        Vector<const SubjectChar> subject,
   3860                        Vector<const PatternChar> pattern,
   3861                        ZoneList<int>* indices,
   3862                        unsigned int limit,
   3863                        Zone* zone) {
   3864   ASSERT(limit > 0);
   3865   // Collect indices of pattern in subject.
   3866   // Stop after finding at most limit values.
   3867   int pattern_length = pattern.length();
   3868   int index = 0;
   3869   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   3870   while (limit > 0) {
   3871     index = search.Search(subject, index);
   3872     if (index < 0) return;
   3873     indices->Add(index, zone);
   3874     index += pattern_length;
   3875     limit--;
   3876   }
   3877 }
   3878 
   3879 
   3880 void FindStringIndicesDispatch(Isolate* isolate,
   3881                                String* subject,
   3882                                String* pattern,
   3883                                ZoneList<int>* indices,
   3884                                unsigned int limit,
   3885                                Zone* zone) {
   3886   {
   3887     DisallowHeapAllocation no_gc;
   3888     String::FlatContent subject_content = subject->GetFlatContent();
   3889     String::FlatContent pattern_content = pattern->GetFlatContent();
   3890     ASSERT(subject_content.IsFlat());
   3891     ASSERT(pattern_content.IsFlat());
   3892     if (subject_content.IsAscii()) {
   3893       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
   3894       if (pattern_content.IsAscii()) {
   3895         Vector<const uint8_t> pattern_vector =
   3896             pattern_content.ToOneByteVector();
   3897         if (pattern_vector.length() == 1) {
   3898           FindAsciiStringIndices(subject_vector,
   3899                                  pattern_vector[0],
   3900                                  indices,
   3901                                  limit,
   3902                                  zone);
   3903         } else {
   3904           FindStringIndices(isolate,
   3905                             subject_vector,
   3906                             pattern_vector,
   3907                             indices,
   3908                             limit,
   3909                             zone);
   3910         }
   3911       } else {
   3912         FindStringIndices(isolate,
   3913                           subject_vector,
   3914                           pattern_content.ToUC16Vector(),
   3915                           indices,
   3916                           limit,
   3917                           zone);
   3918       }
   3919     } else {
   3920       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
   3921       if (pattern_content.IsAscii()) {
   3922         Vector<const uint8_t> pattern_vector =
   3923             pattern_content.ToOneByteVector();
   3924         if (pattern_vector.length() == 1) {
   3925           FindTwoByteStringIndices(subject_vector,
   3926                                    pattern_vector[0],
   3927                                    indices,
   3928                                    limit,
   3929                                    zone);
   3930         } else {
   3931           FindStringIndices(isolate,
   3932                             subject_vector,
   3933                             pattern_vector,
   3934                             indices,
   3935                             limit,
   3936                             zone);
   3937         }
   3938       } else {
   3939         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
   3940         if (pattern_vector.length() == 1) {
   3941           FindTwoByteStringIndices(subject_vector,
   3942                                    pattern_vector[0],
   3943                                    indices,
   3944                                    limit,
   3945                                    zone);
   3946         } else {
   3947           FindStringIndices(isolate,
   3948                             subject_vector,
   3949                             pattern_vector,
   3950                             indices,
   3951                             limit,
   3952                             zone);
   3953         }
   3954       }
   3955     }
   3956   }
   3957 }
   3958 
   3959 
   3960 template<typename ResultSeqString>
   3961 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
   3962     Isolate* isolate,
   3963     Handle<String> subject,
   3964     Handle<JSRegExp> pattern_regexp,
   3965     Handle<String> replacement,
   3966     Handle<JSArray> last_match_info) {
   3967   ASSERT(subject->IsFlat());
   3968   ASSERT(replacement->IsFlat());
   3969 
   3970   ZoneScope zone_scope(isolate->runtime_zone());
   3971   ZoneList<int> indices(8, zone_scope.zone());
   3972   ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
   3973   String* pattern =
   3974       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
   3975   int subject_len = subject->length();
   3976   int pattern_len = pattern->length();
   3977   int replacement_len = replacement->length();
   3978 
   3979   FindStringIndicesDispatch(
   3980       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
   3981 
   3982   int matches = indices.length();
   3983   if (matches == 0) return *subject;
   3984 
   3985   // Detect integer overflow.
   3986   int64_t result_len_64 =
   3987       (static_cast<int64_t>(replacement_len) -
   3988        static_cast<int64_t>(pattern_len)) *
   3989       static_cast<int64_t>(matches) +
   3990       static_cast<int64_t>(subject_len);
   3991   int result_len;
   3992   if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
   3993     STATIC_ASSERT(String::kMaxLength < kMaxInt);
   3994     result_len = kMaxInt;  // Provoke exception.
   3995   } else {
   3996     result_len = static_cast<int>(result_len_64);
   3997   }
   3998 
   3999   int subject_pos = 0;
   4000   int result_pos = 0;
   4001 
   4002   MaybeHandle<SeqString> maybe_res;
   4003   if (ResultSeqString::kHasAsciiEncoding) {
   4004     maybe_res = isolate->factory()->NewRawOneByteString(result_len);
   4005   } else {
   4006     maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
   4007   }
   4008   Handle<SeqString> untyped_res;
   4009   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
   4010   Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
   4011 
   4012   for (int i = 0; i < matches; i++) {
   4013     // Copy non-matched subject content.
   4014     if (subject_pos < indices.at(i)) {
   4015       String::WriteToFlat(*subject,
   4016                           result->GetChars() + result_pos,
   4017                           subject_pos,
   4018                           indices.at(i));
   4019       result_pos += indices.at(i) - subject_pos;
   4020     }
   4021 
   4022     // Replace match.
   4023     if (replacement_len > 0) {
   4024       String::WriteToFlat(*replacement,
   4025                           result->GetChars() + result_pos,
   4026                           0,
   4027                           replacement_len);
   4028       result_pos += replacement_len;
   4029     }
   4030 
   4031     subject_pos = indices.at(i) + pattern_len;
   4032   }
   4033   // Add remaining subject content at the end.
   4034   if (subject_pos < subject_len) {
   4035     String::WriteToFlat(*subject,
   4036                         result->GetChars() + result_pos,
   4037                         subject_pos,
   4038                         subject_len);
   4039   }
   4040 
   4041   int32_t match_indices[] = { indices.at(matches - 1),
   4042                               indices.at(matches - 1) + pattern_len };
   4043   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
   4044 
   4045   return *result;
   4046 }
   4047 
   4048 
   4049 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
   4050     Isolate* isolate,
   4051     Handle<String> subject,
   4052     Handle<JSRegExp> regexp,
   4053     Handle<String> replacement,
   4054     Handle<JSArray> last_match_info) {
   4055   ASSERT(subject->IsFlat());
   4056   ASSERT(replacement->IsFlat());
   4057 
   4058   int capture_count = regexp->CaptureCount();
   4059   int subject_length = subject->length();
   4060 
   4061   // CompiledReplacement uses zone allocation.
   4062   ZoneScope zone_scope(isolate->runtime_zone());
   4063   CompiledReplacement compiled_replacement(zone_scope.zone());
   4064   bool simple_replace = compiled_replacement.Compile(replacement,
   4065                                                      capture_count,
   4066                                                      subject_length);
   4067 
   4068   // Shortcut for simple non-regexp global replacements
   4069   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
   4070     if (subject->HasOnlyOneByteChars() &&
   4071         replacement->HasOnlyOneByteChars()) {
   4072       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   4073           isolate, subject, regexp, replacement, last_match_info);
   4074     } else {
   4075       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   4076           isolate, subject, regexp, replacement, last_match_info);
   4077     }
   4078   }
   4079 
   4080   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4081   if (global_cache.HasException()) return isolate->heap()->exception();
   4082 
   4083   int32_t* current_match = global_cache.FetchNext();
   4084   if (current_match == NULL) {
   4085     if (global_cache.HasException()) return isolate->heap()->exception();
   4086     return *subject;
   4087   }
   4088 
   4089   // Guessing the number of parts that the final result string is built
   4090   // from. Global regexps can match any number of times, so we guess
   4091   // conservatively.
   4092   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
   4093   ReplacementStringBuilder builder(isolate->heap(),
   4094                                    subject,
   4095                                    expected_parts);
   4096 
   4097   // Number of parts added by compiled replacement plus preceeding
   4098   // string and possibly suffix after last match.  It is possible for
   4099   // all components to use two elements when encoded as two smis.
   4100   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
   4101 
   4102   int prev = 0;
   4103 
   4104   do {
   4105     builder.EnsureCapacity(parts_added_per_loop);
   4106 
   4107     int start = current_match[0];
   4108     int end = current_match[1];
   4109 
   4110     if (prev < start) {
   4111       builder.AddSubjectSlice(prev, start);
   4112     }
   4113 
   4114     if (simple_replace) {
   4115       builder.AddString(replacement);
   4116     } else {
   4117       compiled_replacement.Apply(&builder,
   4118                                  start,
   4119                                  end,
   4120                                  current_match);
   4121     }
   4122     prev = end;
   4123 
   4124     current_match = global_cache.FetchNext();
   4125   } while (current_match != NULL);
   4126 
   4127   if (global_cache.HasException()) return isolate->heap()->exception();
   4128 
   4129   if (prev < subject_length) {
   4130     builder.EnsureCapacity(2);
   4131     builder.AddSubjectSlice(prev, subject_length);
   4132   }
   4133 
   4134   RegExpImpl::SetLastMatchInfo(last_match_info,
   4135                                subject,
   4136                                capture_count,
   4137                                global_cache.LastSuccessfulMatch());
   4138 
   4139   Handle<String> result;
   4140   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
   4141   return *result;
   4142 }
   4143 
   4144 
   4145 template <typename ResultSeqString>
   4146 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
   4147     Isolate* isolate,
   4148     Handle<String> subject,
   4149     Handle<JSRegExp> regexp,
   4150     Handle<JSArray> last_match_info) {
   4151   ASSERT(subject->IsFlat());
   4152 
   4153   // Shortcut for simple non-regexp global replacements
   4154   if (regexp->TypeTag() == JSRegExp::ATOM) {
   4155     Handle<String> empty_string = isolate->factory()->empty_string();
   4156     if (subject->IsOneByteRepresentation()) {
   4157       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   4158           isolate, subject, regexp, empty_string, last_match_info);
   4159     } else {
   4160       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   4161           isolate, subject, regexp, empty_string, last_match_info);
   4162     }
   4163   }
   4164 
   4165   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4166   if (global_cache.HasException()) return isolate->heap()->exception();
   4167 
   4168   int32_t* current_match = global_cache.FetchNext();
   4169   if (current_match == NULL) {
   4170     if (global_cache.HasException()) return isolate->heap()->exception();
   4171     return *subject;
   4172   }
   4173 
   4174   int start = current_match[0];
   4175   int end = current_match[1];
   4176   int capture_count = regexp->CaptureCount();
   4177   int subject_length = subject->length();
   4178 
   4179   int new_length = subject_length - (end - start);
   4180   if (new_length == 0) return isolate->heap()->empty_string();
   4181 
   4182   Handle<ResultSeqString> answer;
   4183   if (ResultSeqString::kHasAsciiEncoding) {
   4184     answer = Handle<ResultSeqString>::cast(
   4185         isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
   4186   } else {
   4187     answer = Handle<ResultSeqString>::cast(
   4188         isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
   4189   }
   4190 
   4191   int prev = 0;
   4192   int position = 0;
   4193 
   4194   do {
   4195     start = current_match[0];
   4196     end = current_match[1];
   4197     if (prev < start) {
   4198       // Add substring subject[prev;start] to answer string.
   4199       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
   4200       position += start - prev;
   4201     }
   4202     prev = end;
   4203 
   4204     current_match = global_cache.FetchNext();
   4205   } while (current_match != NULL);
   4206 
   4207   if (global_cache.HasException()) return isolate->heap()->exception();
   4208 
   4209   RegExpImpl::SetLastMatchInfo(last_match_info,
   4210                                subject,
   4211                                capture_count,
   4212                                global_cache.LastSuccessfulMatch());
   4213 
   4214   if (prev < subject_length) {
   4215     // Add substring subject[prev;length] to answer string.
   4216     String::WriteToFlat(
   4217         *subject, answer->GetChars() + position, prev, subject_length);
   4218     position += subject_length - prev;
   4219   }
   4220 
   4221   if (position == 0) return isolate->heap()->empty_string();
   4222 
   4223   // Shorten string and fill
   4224   int string_size = ResultSeqString::SizeFor(position);
   4225   int allocated_string_size = ResultSeqString::SizeFor(new_length);
   4226   int delta = allocated_string_size - string_size;
   4227 
   4228   answer->set_length(position);
   4229   if (delta == 0) return *answer;
   4230 
   4231   Address end_of_string = answer->address() + string_size;
   4232   Heap* heap = isolate->heap();
   4233 
   4234   // The trimming is performed on a newly allocated object, which is on a
   4235   // fresly allocated page or on an already swept page. Hence, the sweeper
   4236   // thread can not get confused with the filler creation. No synchronization
   4237   // needed.
   4238   heap->CreateFillerObjectAt(end_of_string, delta);
   4239   heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
   4240   return *answer;
   4241 }
   4242 
   4243 
   4244 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
   4245   HandleScope scope(isolate);
   4246   ASSERT(args.length() == 4);
   4247 
   4248   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4249   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
   4250   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4251   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   4252 
   4253   RUNTIME_ASSERT(regexp->GetFlags().is_global());
   4254   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
   4255 
   4256   subject = String::Flatten(subject);
   4257 
   4258   if (replacement->length() == 0) {
   4259     if (subject->HasOnlyOneByteChars()) {
   4260       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
   4261           isolate, subject, regexp, last_match_info);
   4262     } else {
   4263       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
   4264           isolate, subject, regexp, last_match_info);
   4265     }
   4266   }
   4267 
   4268   replacement = String::Flatten(replacement);
   4269 
   4270   return StringReplaceGlobalRegExpWithString(
   4271       isolate, subject, regexp, replacement, last_match_info);
   4272 }
   4273 
   4274 
   4275 // This may return an empty MaybeHandle if an exception is thrown or
   4276 // we abort due to reaching the recursion limit.
   4277 MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
   4278                                                    Handle<String> subject,
   4279                                                    Handle<String> search,
   4280                                                    Handle<String> replace,
   4281                                                    bool* found,
   4282                                                    int recursion_limit) {
   4283   StackLimitCheck stackLimitCheck(isolate);
   4284   if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
   4285     return MaybeHandle<String>();
   4286   }
   4287   recursion_limit--;
   4288   if (subject->IsConsString()) {
   4289     ConsString* cons = ConsString::cast(*subject);
   4290     Handle<String> first = Handle<String>(cons->first());
   4291     Handle<String> second = Handle<String>(cons->second());
   4292     Handle<String> new_first;
   4293     if (!StringReplaceOneCharWithString(
   4294             isolate, first, search, replace, found, recursion_limit)
   4295             .ToHandle(&new_first)) {
   4296       return MaybeHandle<String>();
   4297     }
   4298     if (*found) return isolate->factory()->NewConsString(new_first, second);
   4299 
   4300     Handle<String> new_second;
   4301     if (!StringReplaceOneCharWithString(
   4302             isolate, second, search, replace, found, recursion_limit)
   4303             .ToHandle(&new_second)) {
   4304       return MaybeHandle<String>();
   4305     }
   4306     if (*found) return isolate->factory()->NewConsString(first, new_second);
   4307 
   4308     return subject;
   4309   } else {
   4310     int index = Runtime::StringMatch(isolate, subject, search, 0);
   4311     if (index == -1) return subject;
   4312     *found = true;
   4313     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
   4314     Handle<String> cons1;
   4315     ASSIGN_RETURN_ON_EXCEPTION(
   4316         isolate, cons1,
   4317         isolate->factory()->NewConsString(first, replace),
   4318         String);
   4319     Handle<String> second =
   4320         isolate->factory()->NewSubString(subject, index + 1, subject->length());
   4321     return isolate->factory()->NewConsString(cons1, second);
   4322   }
   4323 }
   4324 
   4325 
   4326 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
   4327   HandleScope scope(isolate);
   4328   ASSERT(args.length() == 3);
   4329   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4330   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
   4331   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
   4332 
   4333   // If the cons string tree is too deep, we simply abort the recursion and
   4334   // retry with a flattened subject string.
   4335   const int kRecursionLimit = 0x1000;
   4336   bool found = false;
   4337   Handle<String> result;
   4338   if (StringReplaceOneCharWithString(
   4339           isolate, subject, search, replace, &found, kRecursionLimit)
   4340           .ToHandle(&result)) {
   4341     return *result;
   4342   }
   4343   if (isolate->has_pending_exception()) return isolate->heap()->exception();
   4344 
   4345   subject = String::Flatten(subject);
   4346   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   4347       isolate, result,
   4348       StringReplaceOneCharWithString(
   4349           isolate, subject, search, replace, &found, kRecursionLimit));
   4350   return *result;
   4351 }
   4352 
   4353 
   4354 // Perform string match of pattern on subject, starting at start index.
   4355 // Caller must ensure that 0 <= start_index <= sub->length(),
   4356 // and should check that pat->length() + start_index <= sub->length().
   4357 int Runtime::StringMatch(Isolate* isolate,
   4358                          Handle<String> sub,
   4359                          Handle<String> pat,
   4360                          int start_index) {
   4361   ASSERT(0 <= start_index);
   4362   ASSERT(start_index <= sub->length());
   4363 
   4364   int pattern_length = pat->length();
   4365   if (pattern_length == 0) return start_index;
   4366 
   4367   int subject_length = sub->length();
   4368   if (start_index + pattern_length > subject_length) return -1;
   4369 
   4370   sub = String::Flatten(sub);
   4371   pat = String::Flatten(pat);
   4372 
   4373   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4374   // Extract flattened substrings of cons strings before determining asciiness.
   4375   String::FlatContent seq_sub = sub->GetFlatContent();
   4376   String::FlatContent seq_pat = pat->GetFlatContent();
   4377 
   4378   // dispatch on type of strings
   4379   if (seq_pat.IsAscii()) {
   4380     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
   4381     if (seq_sub.IsAscii()) {
   4382       return SearchString(isolate,
   4383                           seq_sub.ToOneByteVector(),
   4384                           pat_vector,
   4385                           start_index);
   4386     }
   4387     return SearchString(isolate,
   4388                         seq_sub.ToUC16Vector(),
   4389                         pat_vector,
   4390                         start_index);
   4391   }
   4392   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
   4393   if (seq_sub.IsAscii()) {
   4394     return SearchString(isolate,
   4395                         seq_sub.ToOneByteVector(),
   4396                         pat_vector,
   4397                         start_index);
   4398   }
   4399   return SearchString(isolate,
   4400                       seq_sub.ToUC16Vector(),
   4401                       pat_vector,
   4402                       start_index);
   4403 }
   4404 
   4405 
   4406 RUNTIME_FUNCTION(Runtime_StringIndexOf) {
   4407   HandleScope scope(isolate);
   4408   ASSERT(args.length() == 3);
   4409 
   4410   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4411   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4412   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
   4413 
   4414   uint32_t start_index;
   4415   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4416 
   4417   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
   4418   int position = Runtime::StringMatch(isolate, sub, pat, start_index);
   4419   return Smi::FromInt(position);
   4420 }
   4421 
   4422 
   4423 template <typename schar, typename pchar>
   4424 static int StringMatchBackwards(Vector<const schar> subject,
   4425                                 Vector<const pchar> pattern,
   4426                                 int idx) {
   4427   int pattern_length = pattern.length();
   4428   ASSERT(pattern_length >= 1);
   4429   ASSERT(idx + pattern_length <= subject.length());
   4430 
   4431   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   4432     for (int i = 0; i < pattern_length; i++) {
   4433       uc16 c = pattern[i];
   4434       if (c > String::kMaxOneByteCharCode) {
   4435         return -1;
   4436       }
   4437     }
   4438   }
   4439 
   4440   pchar pattern_first_char = pattern[0];
   4441   for (int i = idx; i >= 0; i--) {
   4442     if (subject[i] != pattern_first_char) continue;
   4443     int j = 1;
   4444     while (j < pattern_length) {
   4445       if (pattern[j] != subject[i+j]) {
   4446         break;
   4447       }
   4448       j++;
   4449     }
   4450     if (j == pattern_length) {
   4451       return i;
   4452     }
   4453   }
   4454   return -1;
   4455 }
   4456 
   4457 
   4458 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
   4459   HandleScope scope(isolate);
   4460   ASSERT(args.length() == 3);
   4461 
   4462   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4463   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4464   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
   4465 
   4466   uint32_t start_index;
   4467   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4468 
   4469   uint32_t pat_length = pat->length();
   4470   uint32_t sub_length = sub->length();
   4471 
   4472   if (start_index + pat_length > sub_length) {
   4473     start_index = sub_length - pat_length;
   4474   }
   4475 
   4476   if (pat_length == 0) {
   4477     return Smi::FromInt(start_index);
   4478   }
   4479 
   4480   sub = String::Flatten(sub);
   4481   pat = String::Flatten(pat);
   4482 
   4483   int position = -1;
   4484   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4485 
   4486   String::FlatContent sub_content = sub->GetFlatContent();
   4487   String::FlatContent pat_content = pat->GetFlatContent();
   4488 
   4489   if (pat_content.IsAscii()) {
   4490     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
   4491     if (sub_content.IsAscii()) {
   4492       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4493                                       pat_vector,
   4494                                       start_index);
   4495     } else {
   4496       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4497                                       pat_vector,
   4498                                       start_index);
   4499     }
   4500   } else {
   4501     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
   4502     if (sub_content.IsAscii()) {
   4503       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4504                                       pat_vector,
   4505                                       start_index);
   4506     } else {
   4507       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4508                                       pat_vector,
   4509                                       start_index);
   4510     }
   4511   }
   4512 
   4513   return Smi::FromInt(position);
   4514 }
   4515 
   4516 
   4517 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
   4518   HandleScope handle_scope(isolate);
   4519   ASSERT(args.length() == 2);
   4520 
   4521   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
   4522   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
   4523 
   4524   if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
   4525   int str1_length = str1->length();
   4526   int str2_length = str2->length();
   4527 
   4528   // Decide trivial cases without flattening.
   4529   if (str1_length == 0) {
   4530     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
   4531     return Smi::FromInt(-str2_length);
   4532   } else {
   4533     if (str2_length == 0) return Smi::FromInt(str1_length);
   4534   }
   4535 
   4536   int end = str1_length < str2_length ? str1_length : str2_length;
   4537 
   4538   // No need to flatten if we are going to find the answer on the first
   4539   // character.  At this point we know there is at least one character
   4540   // in each string, due to the trivial case handling above.
   4541   int d = str1->Get(0) - str2->Get(0);
   4542   if (d != 0) return Smi::FromInt(d);
   4543 
   4544   str1 = String::Flatten(str1);
   4545   str2 = String::Flatten(str2);
   4546 
   4547   DisallowHeapAllocation no_gc;
   4548   String::FlatContent flat1 = str1->GetFlatContent();
   4549   String::FlatContent flat2 = str2->GetFlatContent();
   4550 
   4551   for (int i = 0; i < end; i++) {
   4552     if (flat1.Get(i) != flat2.Get(i)) {
   4553       return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
   4554     }
   4555   }
   4556 
   4557   return Smi::FromInt(str1_length - str2_length);
   4558 }
   4559 
   4560 
   4561 RUNTIME_FUNCTION(RuntimeHidden_SubString) {
   4562   HandleScope scope(isolate);
   4563   ASSERT(args.length() == 3);
   4564 
   4565   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   4566   int start, end;
   4567   // We have a fast integer-only case here to avoid a conversion to double in
   4568   // the common case where from and to are Smis.
   4569   if (args[1]->IsSmi() && args[2]->IsSmi()) {
   4570     CONVERT_SMI_ARG_CHECKED(from_number, 1);
   4571     CONVERT_SMI_ARG_CHECKED(to_number, 2);
   4572     start = from_number;
   4573     end = to_number;
   4574   } else {
   4575     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
   4576     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
   4577     start = FastD2IChecked(from_number);
   4578     end = FastD2IChecked(to_number);
   4579   }
   4580   RUNTIME_ASSERT(end >= start);
   4581   RUNTIME_ASSERT(start >= 0);
   4582   RUNTIME_ASSERT(end <= string->length());
   4583   isolate->counters()->sub_string_runtime()->Increment();
   4584 
   4585   return *isolate->factory()->NewSubString(string, start, end);
   4586 }
   4587 
   4588 
   4589 RUNTIME_FUNCTION(Runtime_StringMatch) {
   4590   HandleScope handles(isolate);
   4591   ASSERT(args.length() == 3);
   4592 
   4593   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4594   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4595   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
   4596 
   4597   RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
   4598 
   4599   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4600   if (global_cache.HasException()) return isolate->heap()->exception();
   4601 
   4602   int capture_count = regexp->CaptureCount();
   4603 
   4604   ZoneScope zone_scope(isolate->runtime_zone());
   4605   ZoneList<int> offsets(8, zone_scope.zone());
   4606 
   4607   while (true) {
   4608     int32_t* match = global_cache.FetchNext();
   4609     if (match == NULL) break;
   4610     offsets.Add(match[0], zone_scope.zone());  // start
   4611     offsets.Add(match[1], zone_scope.zone());  // end
   4612   }
   4613 
   4614   if (global_cache.HasException()) return isolate->heap()->exception();
   4615 
   4616   if (offsets.length() == 0) {
   4617     // Not a single match.
   4618     return isolate->heap()->null_value();
   4619   }
   4620 
   4621   RegExpImpl::SetLastMatchInfo(regexp_info,
   4622                                subject,
   4623                                capture_count,
   4624                                global_cache.LastSuccessfulMatch());
   4625 
   4626   int matches = offsets.length() / 2;
   4627   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
   4628   Handle<String> substring =
   4629       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
   4630   elements->set(0, *substring);
   4631   for (int i = 1; i < matches; i++) {
   4632     HandleScope temp_scope(isolate);
   4633     int from = offsets.at(i * 2);
   4634     int to = offsets.at(i * 2 + 1);
   4635     Handle<String> substring =
   4636         isolate->factory()->NewProperSubString(subject, from, to);
   4637     elements->set(i, *substring);
   4638   }
   4639   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
   4640   result->set_length(Smi::FromInt(matches));
   4641   return *result;
   4642 }
   4643 
   4644 
   4645 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
   4646 // separate last match info.  See comment on that function.
   4647 template<bool has_capture>
   4648 static Object* SearchRegExpMultiple(
   4649     Isolate* isolate,
   4650     Handle<String> subject,
   4651     Handle<JSRegExp> regexp,
   4652     Handle<JSArray> last_match_array,
   4653     Handle<JSArray> result_array) {
   4654   ASSERT(subject->IsFlat());
   4655   ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
   4656 
   4657   int capture_count = regexp->CaptureCount();
   4658   int subject_length = subject->length();
   4659 
   4660   static const int kMinLengthToCache = 0x1000;
   4661 
   4662   if (subject_length > kMinLengthToCache) {
   4663     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
   4664         isolate->heap(),
   4665         *subject,
   4666         regexp->data(),
   4667         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
   4668     if (*cached_answer != Smi::FromInt(0)) {
   4669       Handle<FixedArray> cached_fixed_array =
   4670           Handle<FixedArray>(FixedArray::cast(*cached_answer));
   4671       // The cache FixedArray is a COW-array and can therefore be reused.
   4672       JSArray::SetContent(result_array, cached_fixed_array);
   4673       // The actual length of the result array is stored in the last element of
   4674       // the backing store (the backing FixedArray may have a larger capacity).
   4675       Object* cached_fixed_array_last_element =
   4676           cached_fixed_array->get(cached_fixed_array->length() - 1);
   4677       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
   4678       result_array->set_length(js_array_length);
   4679       RegExpImpl::SetLastMatchInfo(
   4680           last_match_array, subject, capture_count, NULL);
   4681       return *result_array;
   4682     }
   4683   }
   4684 
   4685   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4686   if (global_cache.HasException()) return isolate->heap()->exception();
   4687 
   4688   // Ensured in Runtime_RegExpExecMultiple.
   4689   ASSERT(result_array->HasFastObjectElements());
   4690   Handle<FixedArray> result_elements(
   4691       FixedArray::cast(result_array->elements()));
   4692   if (result_elements->length() < 16) {
   4693     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   4694   }
   4695 
   4696   FixedArrayBuilder builder(result_elements);
   4697 
   4698   // Position to search from.
   4699   int match_start = -1;
   4700   int match_end = 0;
   4701   bool first = true;
   4702 
   4703   // Two smis before and after the match, for very long strings.
   4704   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
   4705 
   4706   while (true) {
   4707     int32_t* current_match = global_cache.FetchNext();
   4708     if (current_match == NULL) break;
   4709     match_start = current_match[0];
   4710     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   4711     if (match_end < match_start) {
   4712       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4713                                                 match_end,
   4714                                                 match_start);
   4715     }
   4716     match_end = current_match[1];
   4717     {
   4718       // Avoid accumulating new handles inside loop.
   4719       HandleScope temp_scope(isolate);
   4720       Handle<String> match;
   4721       if (!first) {
   4722         match = isolate->factory()->NewProperSubString(subject,
   4723                                                        match_start,
   4724                                                        match_end);
   4725       } else {
   4726         match = isolate->factory()->NewSubString(subject,
   4727                                                  match_start,
   4728                                                  match_end);
   4729         first = false;
   4730       }
   4731 
   4732       if (has_capture) {
   4733         // Arguments array to replace function is match, captures, index and
   4734         // subject, i.e., 3 + capture count in total.
   4735         Handle<FixedArray> elements =
   4736             isolate->factory()->NewFixedArray(3 + capture_count);
   4737 
   4738         elements->set(0, *match);
   4739         for (int i = 1; i <= capture_count; i++) {
   4740           int start = current_match[i * 2];
   4741           if (start >= 0) {
   4742             int end = current_match[i * 2 + 1];
   4743             ASSERT(start <= end);
   4744             Handle<String> substring =
   4745                 isolate->factory()->NewSubString(subject, start, end);
   4746             elements->set(i, *substring);
   4747           } else {
   4748             ASSERT(current_match[i * 2 + 1] < 0);
   4749             elements->set(i, isolate->heap()->undefined_value());
   4750           }
   4751         }
   4752         elements->set(capture_count + 1, Smi::FromInt(match_start));
   4753         elements->set(capture_count + 2, *subject);
   4754         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
   4755       } else {
   4756         builder.Add(*match);
   4757       }
   4758     }
   4759   }
   4760 
   4761   if (global_cache.HasException()) return isolate->heap()->exception();
   4762 
   4763   if (match_start >= 0) {
   4764     // Finished matching, with at least one match.
   4765     if (match_end < subject_length) {
   4766       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4767                                                 match_end,
   4768                                                 subject_length);
   4769     }
   4770 
   4771     RegExpImpl::SetLastMatchInfo(
   4772         last_match_array, subject, capture_count, NULL);
   4773 
   4774     if (subject_length > kMinLengthToCache) {
   4775       // Store the length of the result array into the last element of the
   4776       // backing FixedArray.
   4777       builder.EnsureCapacity(1);
   4778       Handle<FixedArray> fixed_array = builder.array();
   4779       fixed_array->set(fixed_array->length() - 1,
   4780                        Smi::FromInt(builder.length()));
   4781       // Cache the result and turn the FixedArray into a COW array.
   4782       RegExpResultsCache::Enter(isolate,
   4783                                 subject,
   4784                                 handle(regexp->data(), isolate),
   4785                                 fixed_array,
   4786                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
   4787     }
   4788     return *builder.ToJSArray(result_array);
   4789   } else {
   4790     return isolate->heap()->null_value();  // No matches at all.
   4791   }
   4792 }
   4793 
   4794 
   4795 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
   4796 // lastMatchInfoOverride to maintain the last match info, so we don't need to
   4797 // set any other last match array info.
   4798 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
   4799   HandleScope handles(isolate);
   4800   ASSERT(args.length() == 4);
   4801 
   4802   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   4803   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   4804   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
   4805   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
   4806   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
   4807   RUNTIME_ASSERT(result_array->HasFastObjectElements());
   4808 
   4809   subject = String::Flatten(subject);
   4810   RUNTIME_ASSERT(regexp->GetFlags().is_global());
   4811 
   4812   if (regexp->CaptureCount() == 0) {
   4813     return SearchRegExpMultiple<false>(
   4814         isolate, subject, regexp, last_match_info, result_array);
   4815   } else {
   4816     return SearchRegExpMultiple<true>(
   4817         isolate, subject, regexp, last_match_info, result_array);
   4818   }
   4819 }
   4820 
   4821 
   4822 RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
   4823   HandleScope scope(isolate);
   4824   ASSERT(args.length() == 2);
   4825   CONVERT_SMI_ARG_CHECKED(radix, 1);
   4826   RUNTIME_ASSERT(2 <= radix && radix <= 36);
   4827 
   4828   // Fast case where the result is a one character string.
   4829   if (args[0]->IsSmi()) {
   4830     int value = args.smi_at(0);
   4831     if (value >= 0 && value < radix) {
   4832       // Character array used for conversion.
   4833       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   4834       return *isolate->factory()->
   4835           LookupSingleCharacterStringFromCode(kCharTable[value]);
   4836     }
   4837   }
   4838 
   4839   // Slow case.
   4840   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4841   if (std::isnan(value)) {
   4842     return isolate->heap()->nan_string();
   4843   }
   4844   if (std::isinf(value)) {
   4845     if (value < 0) {
   4846       return isolate->heap()->minus_infinity_string();
   4847     }
   4848     return isolate->heap()->infinity_string();
   4849   }
   4850   char* str = DoubleToRadixCString(value, radix);
   4851   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4852   DeleteArray(str);
   4853   return *result;
   4854 }
   4855 
   4856 
   4857 RUNTIME_FUNCTION(Runtime_NumberToFixed) {
   4858   HandleScope scope(isolate);
   4859   ASSERT(args.length() == 2);
   4860 
   4861   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4862   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4863   int f = FastD2IChecked(f_number);
   4864   // See DoubleToFixedCString for these constants:
   4865   RUNTIME_ASSERT(f >= 0 && f <= 20);
   4866   RUNTIME_ASSERT(!Double(value).IsSpecial());
   4867   char* str = DoubleToFixedCString(value, f);
   4868   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4869   DeleteArray(str);
   4870   return *result;
   4871 }
   4872 
   4873 
   4874 RUNTIME_FUNCTION(Runtime_NumberToExponential) {
   4875   HandleScope scope(isolate);
   4876   ASSERT(args.length() == 2);
   4877 
   4878   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4879   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4880   int f = FastD2IChecked(f_number);
   4881   RUNTIME_ASSERT(f >= -1 && f <= 20);
   4882   RUNTIME_ASSERT(!Double(value).IsSpecial());
   4883   char* str = DoubleToExponentialCString(value, f);
   4884   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4885   DeleteArray(str);
   4886   return *result;
   4887 }
   4888 
   4889 
   4890 RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
   4891   HandleScope scope(isolate);
   4892   ASSERT(args.length() == 2);
   4893 
   4894   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4895   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4896   int f = FastD2IChecked(f_number);
   4897   RUNTIME_ASSERT(f >= 1 && f <= 21);
   4898   RUNTIME_ASSERT(!Double(value).IsSpecial());
   4899   char* str = DoubleToPrecisionCString(value, f);
   4900   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
   4901   DeleteArray(str);
   4902   return *result;
   4903 }
   4904 
   4905 
   4906 RUNTIME_FUNCTION(Runtime_IsValidSmi) {
   4907   SealHandleScope shs(isolate);
   4908   ASSERT(args.length() == 1);
   4909 
   4910   CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
   4911   return isolate->heap()->ToBoolean(Smi::IsValid(number));
   4912 }
   4913 
   4914 
   4915 // Returns a single character string where first character equals
   4916 // string->Get(index).
   4917 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
   4918   if (index < static_cast<uint32_t>(string->length())) {
   4919     Factory* factory = string->GetIsolate()->factory();
   4920     return factory->LookupSingleCharacterStringFromCode(
   4921         String::Flatten(string)->Get(index));
   4922   }
   4923   return Execution::CharAt(string, index);
   4924 }
   4925 
   4926 
   4927 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
   4928                                                 Handle<Object> object,
   4929                                                 uint32_t index) {
   4930   // Handle [] indexing on Strings
   4931   if (object->IsString()) {
   4932     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
   4933     if (!result->IsUndefined()) return result;
   4934   }
   4935 
   4936   // Handle [] indexing on String objects
   4937   if (object->IsStringObjectWithCharacterAt(index)) {
   4938     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
   4939     Handle<Object> result =
   4940         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
   4941     if (!result->IsUndefined()) return result;
   4942   }
   4943 
   4944   Handle<Object> result;
   4945   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
   4946     Handle<Object> proto(object->GetPrototype(isolate), isolate);
   4947     return Object::GetElement(isolate, proto, index);
   4948   } else {
   4949     return Object::GetElement(isolate, object, index);
   4950   }
   4951 }
   4952 
   4953 
   4954 MUST_USE_RESULT
   4955 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
   4956   if (key->IsName()) {
   4957     return Handle<Name>::cast(key);
   4958   } else {
   4959     Handle<Object> converted;
   4960     ASSIGN_RETURN_ON_EXCEPTION(
   4961         isolate, converted, Execution::ToString(isolate, key), Name);
   4962     return Handle<Name>::cast(converted);
   4963   }
   4964 }
   4965 
   4966 
   4967 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
   4968                                                Handle<JSReceiver> object,
   4969                                                Handle<Object> key) {
   4970   // Check if the given key is an array index.
   4971   uint32_t index;
   4972   if (key->ToArrayIndex(&index)) {
   4973     return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
   4974   }
   4975 
   4976   // Convert the key to a name - possibly by calling back into JavaScript.
   4977   Handle<Name> name;
   4978   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
   4979 
   4980   return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
   4981 }
   4982 
   4983 
   4984 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
   4985                                                Handle<Object> object,
   4986                                                Handle<Object> key) {
   4987   if (object->IsUndefined() || object->IsNull()) {
   4988     Handle<Object> args[2] = { key, object };
   4989     return isolate->Throw<Object>(
   4990         isolate->factory()->NewTypeError("non_object_property_load",
   4991                                          HandleVector(args, 2)));
   4992   }
   4993 
   4994   // Check if the given key is an array index.
   4995   uint32_t index;
   4996   if (key->ToArrayIndex(&index)) {
   4997     return GetElementOrCharAt(isolate, object, index);
   4998   }
   4999 
   5000   // Convert the key to a name - possibly by calling back into JavaScript.
   5001   Handle<Name> name;
   5002   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
   5003 
   5004   // Check if the name is trivially convertible to an index and get
   5005   // the element if so.
   5006   if (name->AsArrayIndex(&index)) {
   5007     return GetElementOrCharAt(isolate, object, index);
   5008   } else {
   5009     return Object::GetProperty(object, name);
   5010   }
   5011 }
   5012 
   5013 
   5014 RUNTIME_FUNCTION(Runtime_GetProperty) {
   5015   HandleScope scope(isolate);
   5016   ASSERT(args.length() == 2);
   5017 
   5018   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5019   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   5020   Handle<Object> result;
   5021   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5022       isolate, result,
   5023       Runtime::GetObjectProperty(isolate, object, key));
   5024   return *result;
   5025 }
   5026 
   5027 
   5028 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
   5029 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
   5030   HandleScope scope(isolate);
   5031   ASSERT(args.length() == 2);
   5032 
   5033   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
   5034   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
   5035 
   5036   // Fast cases for getting named properties of the receiver JSObject
   5037   // itself.
   5038   //
   5039   // The global proxy objects has to be excluded since LookupOwn on
   5040   // the global proxy object can return a valid result even though the
   5041   // global proxy object never has properties.  This is the case
   5042   // because the global proxy object forwards everything to its hidden
   5043   // prototype including own lookups.
   5044   //
   5045   // Additionally, we need to make sure that we do not cache results
   5046   // for objects that require access checks.
   5047   if (receiver_obj->IsJSObject()) {
   5048     if (!receiver_obj->IsJSGlobalProxy() &&
   5049         !receiver_obj->IsAccessCheckNeeded() &&
   5050         key_obj->IsName()) {
   5051       DisallowHeapAllocation no_allocation;
   5052       Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
   5053       Handle<Name> key = Handle<Name>::cast(key_obj);
   5054       if (receiver->HasFastProperties()) {
   5055         // Attempt to use lookup cache.
   5056         Handle<Map> receiver_map(receiver->map(), isolate);
   5057         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
   5058         int index = keyed_lookup_cache->Lookup(receiver_map, key);
   5059         if (index != -1) {
   5060           // Doubles are not cached, so raw read the value.
   5061           Object* value = receiver->RawFastPropertyAt(
   5062               FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
   5063           return value->IsTheHole()
   5064               ? isolate->heap()->undefined_value()
   5065               : value;
   5066         }
   5067         // Lookup cache miss.  Perform lookup and update the cache if
   5068         // appropriate.
   5069         LookupResult result(isolate);
   5070         receiver->LookupOwn(key, &result);
   5071         if (result.IsField()) {
   5072           FieldIndex field_index = result.GetFieldIndex();
   5073           // Do not track double fields in the keyed lookup cache. Reading
   5074           // double values requires boxing.
   5075           if (!result.representation().IsDouble()) {
   5076             keyed_lookup_cache->Update(receiver_map, key,
   5077                 field_index.GetKeyedLookupCacheIndex());
   5078           }
   5079           AllowHeapAllocation allow_allocation;
   5080           return *JSObject::FastPropertyAt(receiver, result.representation(),
   5081                                            field_index);
   5082         }
   5083       } else {
   5084         // Attempt dictionary lookup.
   5085         NameDictionary* dictionary = receiver->property_dictionary();
   5086         int entry = dictionary->FindEntry(key);
   5087         if ((entry != NameDictionary::kNotFound) &&
   5088             (dictionary->DetailsAt(entry).type() == NORMAL)) {
   5089           Object* value = dictionary->ValueAt(entry);
   5090           if (!receiver->IsGlobalObject()) return value;
   5091           value = PropertyCell::cast(value)->value();
   5092           if (!value->IsTheHole()) return value;
   5093           // If value is the hole do the general lookup.
   5094         }
   5095       }
   5096     } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) {
   5097       // JSObject without a name key. If the key is a Smi, check for a
   5098       // definite out-of-bounds access to elements, which is a strong indicator
   5099       // that subsequent accesses will also call the runtime. Proactively
   5100       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
   5101       // doubles for those future calls in the case that the elements would
   5102       // become FAST_DOUBLE_ELEMENTS.
   5103       Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
   5104       ElementsKind elements_kind = js_object->GetElementsKind();
   5105       if (IsFastDoubleElementsKind(elements_kind)) {
   5106         Handle<Smi> key = Handle<Smi>::cast(key_obj);
   5107         if (key->value() >= js_object->elements()->length()) {
   5108           if (IsFastHoleyElementsKind(elements_kind)) {
   5109             elements_kind = FAST_HOLEY_ELEMENTS;
   5110           } else {
   5111             elements_kind = FAST_ELEMENTS;
   5112           }
   5113           RETURN_FAILURE_ON_EXCEPTION(
   5114               isolate, TransitionElements(js_object, elements_kind, isolate));
   5115         }
   5116       } else {
   5117         ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
   5118                !IsFastElementsKind(elements_kind));
   5119       }
   5120     }
   5121   } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
   5122     // Fast case for string indexing using [] with a smi index.
   5123     Handle<String> str = Handle<String>::cast(receiver_obj);
   5124     int index = args.smi_at(1);
   5125     if (index >= 0 && index < str->length()) {
   5126       return *GetCharAt(str, index);
   5127     }
   5128   }
   5129 
   5130   // Fall back to GetObjectProperty.
   5131   Handle<Object> result;
   5132   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5133       isolate, result,
   5134       Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
   5135   return *result;
   5136 }
   5137 
   5138 
   5139 static bool IsValidAccessor(Handle<Object> obj) {
   5140   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
   5141 }
   5142 
   5143 
   5144 // Implements part of 8.12.9 DefineOwnProperty.
   5145 // There are 3 cases that lead here:
   5146 // Step 4b - define a new accessor property.
   5147 // Steps 9c & 12 - replace an existing data property with an accessor property.
   5148 // Step 12 - update an existing accessor property with an accessor or generic
   5149 //           descriptor.
   5150 RUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) {
   5151   HandleScope scope(isolate);
   5152   ASSERT(args.length() == 5);
   5153   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5154   RUNTIME_ASSERT(!obj->IsNull());
   5155   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5156   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   5157   RUNTIME_ASSERT(IsValidAccessor(getter));
   5158   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   5159   RUNTIME_ASSERT(IsValidAccessor(setter));
   5160   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
   5161   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5162   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   5163 
   5164   bool fast = obj->HasFastProperties();
   5165   // DefineAccessor checks access rights.
   5166   JSObject::DefineAccessor(obj, name, getter, setter, attr);
   5167   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5168   if (fast) JSObject::TransformToFastProperties(obj, 0);
   5169   return isolate->heap()->undefined_value();
   5170 }
   5171 
   5172 
   5173 // Implements part of 8.12.9 DefineOwnProperty.
   5174 // There are 3 cases that lead here:
   5175 // Step 4a - define a new data property.
   5176 // Steps 9b & 12 - replace an existing accessor property with a data property.
   5177 // Step 12 - update an existing data property with a data or generic
   5178 //           descriptor.
   5179 RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
   5180   HandleScope scope(isolate);
   5181   ASSERT(args.length() == 4);
   5182   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
   5183   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5184   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
   5185   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
   5186   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5187   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   5188 
   5189   // Check access rights if needed.
   5190   if (js_object->IsAccessCheckNeeded() &&
   5191       !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
   5192     return isolate->heap()->undefined_value();
   5193   }
   5194 
   5195   LookupResult lookup(isolate);
   5196   js_object->LookupOwnRealNamedProperty(name, &lookup);
   5197 
   5198   // Take special care when attributes are different and there is already
   5199   // a property. For simplicity we normalize the property which enables us
   5200   // to not worry about changing the instance_descriptor and creating a new
   5201   // map. The current version of SetObjectProperty does not handle attributes
   5202   // correctly in the case where a property is a field and is reset with
   5203   // new attributes.
   5204   if (lookup.IsFound() &&
   5205       (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
   5206     // New attributes - normalize to avoid writing to instance descriptor
   5207     if (js_object->IsJSGlobalProxy()) {
   5208       // Since the result is a property, the prototype will exist so
   5209       // we don't have to check for null.
   5210       js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
   5211     }
   5212 
   5213     if (attr != lookup.GetAttributes() ||
   5214         (lookup.IsPropertyCallbacks() &&
   5215          !lookup.GetCallbackObject()->IsAccessorInfo())) {
   5216       JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
   5217     }
   5218 
   5219     // Use IgnoreAttributes version since a readonly property may be
   5220     // overridden and SetProperty does not allow this.
   5221     Handle<Object> result;
   5222     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5223         isolate, result,
   5224         JSObject::SetOwnPropertyIgnoreAttributes(
   5225             js_object, name, obj_value, attr,
   5226             Object::OPTIMAL_REPRESENTATION,
   5227             ALLOW_AS_CONSTANT,
   5228             JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
   5229             JSReceiver::MAY_BE_STORE_FROM_KEYED,
   5230             JSObject::DONT_FORCE_FIELD));
   5231     return *result;
   5232   }
   5233 
   5234   Handle<Object> result;
   5235   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5236       isolate, result,
   5237       Runtime::ForceSetObjectProperty(
   5238           js_object, name, obj_value, attr,
   5239           JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
   5240   return *result;
   5241 }
   5242 
   5243 
   5244 // Return property without being observable by accessors or interceptors.
   5245 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
   5246   HandleScope scope(isolate);
   5247   ASSERT(args.length() == 2);
   5248   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5249   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5250   return *JSObject::GetDataProperty(object, key);
   5251 }
   5252 
   5253 
   5254 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
   5255                                                Handle<Object> object,
   5256                                                Handle<Object> key,
   5257                                                Handle<Object> value,
   5258                                                PropertyAttributes attr,
   5259                                                StrictMode strict_mode) {
   5260   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
   5261 
   5262   if (object->IsUndefined() || object->IsNull()) {
   5263     Handle<Object> args[2] = { key, object };
   5264     Handle<Object> error =
   5265         isolate->factory()->NewTypeError("non_object_property_store",
   5266                                          HandleVector(args, 2));
   5267     return isolate->Throw<Object>(error);
   5268   }
   5269 
   5270   if (object->IsJSProxy()) {
   5271     Handle<Object> name_object;
   5272     if (key->IsSymbol()) {
   5273       name_object = key;
   5274     } else {
   5275       ASSIGN_RETURN_ON_EXCEPTION(
   5276           isolate, name_object, Execution::ToString(isolate, key), Object);
   5277     }
   5278     Handle<Name> name = Handle<Name>::cast(name_object);
   5279     return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
   5280                                    attr,
   5281                                    strict_mode);
   5282   }
   5283 
   5284   // If the object isn't a JavaScript object, we ignore the store.
   5285   if (!object->IsJSObject()) return value;
   5286 
   5287   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   5288 
   5289   // Check if the given key is an array index.
   5290   uint32_t index;
   5291   if (key->ToArrayIndex(&index)) {
   5292     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5293     // of a string using [] notation.  We need to support this too in
   5294     // JavaScript.
   5295     // In the case of a String object we just need to redirect the assignment to
   5296     // the underlying string if the index is in range.  Since the underlying
   5297     // string does nothing with the assignment then we can ignore such
   5298     // assignments.
   5299     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5300       return value;
   5301     }
   5302 
   5303     JSObject::ValidateElements(js_object);
   5304     if (js_object->HasExternalArrayElements() ||
   5305         js_object->HasFixedTypedArrayElements()) {
   5306       if (!value->IsNumber() && !value->IsUndefined()) {
   5307         ASSIGN_RETURN_ON_EXCEPTION(
   5308             isolate, value, Execution::ToNumber(isolate, value), Object);
   5309       }
   5310     }
   5311 
   5312     MaybeHandle<Object> result = JSObject::SetElement(
   5313         js_object, index, value, attr, strict_mode, true, set_mode);
   5314     JSObject::ValidateElements(js_object);
   5315 
   5316     return result.is_null() ? result : value;
   5317   }
   5318 
   5319   if (key->IsName()) {
   5320     Handle<Name> name = Handle<Name>::cast(key);
   5321     if (name->AsArrayIndex(&index)) {
   5322       if (js_object->HasExternalArrayElements()) {
   5323         if (!value->IsNumber() && !value->IsUndefined()) {
   5324           ASSIGN_RETURN_ON_EXCEPTION(
   5325               isolate, value, Execution::ToNumber(isolate, value), Object);
   5326         }
   5327       }
   5328       return JSObject::SetElement(js_object, index, value, attr,
   5329                                   strict_mode, true, set_mode);
   5330     } else {
   5331       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
   5332       return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
   5333     }
   5334   }
   5335 
   5336   // Call-back into JavaScript to convert the key to a string.
   5337   Handle<Object> converted;
   5338   ASSIGN_RETURN_ON_EXCEPTION(
   5339       isolate, converted, Execution::ToString(isolate, key), Object);
   5340   Handle<String> name = Handle<String>::cast(converted);
   5341 
   5342   if (name->AsArrayIndex(&index)) {
   5343     return JSObject::SetElement(js_object, index, value, attr,
   5344                                 strict_mode, true, set_mode);
   5345   } else {
   5346     return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
   5347   }
   5348 }
   5349 
   5350 
   5351 MaybeHandle<Object> Runtime::ForceSetObjectProperty(
   5352     Handle<JSObject> js_object,
   5353     Handle<Object> key,
   5354     Handle<Object> value,
   5355     PropertyAttributes attr,
   5356     JSReceiver::StoreFromKeyed store_from_keyed) {
   5357   Isolate* isolate = js_object->GetIsolate();
   5358   // Check if the given key is an array index.
   5359   uint32_t index;
   5360   if (key->ToArrayIndex(&index)) {
   5361     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5362     // of a string using [] notation.  We need to support this too in
   5363     // JavaScript.
   5364     // In the case of a String object we just need to redirect the assignment to
   5365     // the underlying string if the index is in range.  Since the underlying
   5366     // string does nothing with the assignment then we can ignore such
   5367     // assignments.
   5368     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5369       return value;
   5370     }
   5371 
   5372     return JSObject::SetElement(js_object, index, value, attr,
   5373                                 SLOPPY, false, DEFINE_PROPERTY);
   5374   }
   5375 
   5376   if (key->IsName()) {
   5377     Handle<Name> name = Handle<Name>::cast(key);
   5378     if (name->AsArrayIndex(&index)) {
   5379       return JSObject::SetElement(js_object, index, value, attr,
   5380                                   SLOPPY, false, DEFINE_PROPERTY);
   5381     } else {
   5382       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
   5383       return JSObject::SetOwnPropertyIgnoreAttributes(
   5384           js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
   5385           ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
   5386           store_from_keyed);
   5387     }
   5388   }
   5389 
   5390   // Call-back into JavaScript to convert the key to a string.
   5391   Handle<Object> converted;
   5392   ASSIGN_RETURN_ON_EXCEPTION(
   5393       isolate, converted, Execution::ToString(isolate, key), Object);
   5394   Handle<String> name = Handle<String>::cast(converted);
   5395 
   5396   if (name->AsArrayIndex(&index)) {
   5397     return JSObject::SetElement(js_object, index, value, attr,
   5398                                 SLOPPY, false, DEFINE_PROPERTY);
   5399   } else {
   5400     return JSObject::SetOwnPropertyIgnoreAttributes(
   5401         js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
   5402         ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
   5403         store_from_keyed);
   5404   }
   5405 }
   5406 
   5407 
   5408 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
   5409                                                   Handle<JSReceiver> receiver,
   5410                                                   Handle<Object> key,
   5411                                                   JSReceiver::DeleteMode mode) {
   5412   // Check if the given key is an array index.
   5413   uint32_t index;
   5414   if (key->ToArrayIndex(&index)) {
   5415     // In Firefox/SpiderMonkey, Safari and Opera you can access the
   5416     // characters of a string using [] notation.  In the case of a
   5417     // String object we just need to redirect the deletion to the
   5418     // underlying string if the index is in range.  Since the
   5419     // underlying string does nothing with the deletion, we can ignore
   5420     // such deletions.
   5421     if (receiver->IsStringObjectWithCharacterAt(index)) {
   5422       return isolate->factory()->true_value();
   5423     }
   5424 
   5425     return JSReceiver::DeleteElement(receiver, index, mode);
   5426   }
   5427 
   5428   Handle<Name> name;
   5429   if (key->IsName()) {
   5430     name = Handle<Name>::cast(key);
   5431   } else {
   5432     // Call-back into JavaScript to convert the key to a string.
   5433     Handle<Object> converted;
   5434     ASSIGN_RETURN_ON_EXCEPTION(
   5435         isolate, converted, Execution::ToString(isolate, key), Object);
   5436     name = Handle<String>::cast(converted);
   5437   }
   5438 
   5439   if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
   5440   return JSReceiver::DeleteProperty(receiver, name, mode);
   5441 }
   5442 
   5443 
   5444 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
   5445   HandleScope scope(isolate);
   5446   RUNTIME_ASSERT(args.length() == 3);
   5447 
   5448   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5449   CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
   5450   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5451   RUNTIME_ASSERT(key->IsUniqueName());
   5452   return *JSObject::SetHiddenProperty(object, key, value);
   5453 }
   5454 
   5455 
   5456 RUNTIME_FUNCTION(Runtime_SetProperty) {
   5457   HandleScope scope(isolate);
   5458   RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
   5459 
   5460   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5461   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   5462   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5463   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   5464   RUNTIME_ASSERT(
   5465       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5466   // Compute attributes.
   5467   PropertyAttributes attributes =
   5468       static_cast<PropertyAttributes>(unchecked_attributes);
   5469 
   5470   StrictMode strict_mode = SLOPPY;
   5471   if (args.length() == 5) {
   5472     CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 4);
   5473     strict_mode = strict_mode_arg;
   5474   }
   5475 
   5476   Handle<Object> result;
   5477   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5478       isolate, result,
   5479       Runtime::SetObjectProperty(
   5480           isolate, object, key, value, attributes, strict_mode));
   5481   return *result;
   5482 }
   5483 
   5484 
   5485 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
   5486   HandleScope scope(isolate);
   5487   RUNTIME_ASSERT(args.length() == 2);
   5488   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   5489   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
   5490   JSObject::TransitionElementsKind(array, map->elements_kind());
   5491   return *array;
   5492 }
   5493 
   5494 
   5495 // Set the native flag on the function.
   5496 // This is used to decide if we should transform null and undefined
   5497 // into the global object when doing call and apply.
   5498 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
   5499   SealHandleScope shs(isolate);
   5500   RUNTIME_ASSERT(args.length() == 1);
   5501 
   5502   CONVERT_ARG_CHECKED(Object, object, 0);
   5503 
   5504   if (object->IsJSFunction()) {
   5505     JSFunction* func = JSFunction::cast(object);
   5506     func->shared()->set_native(true);
   5507   }
   5508   return isolate->heap()->undefined_value();
   5509 }
   5510 
   5511 
   5512 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
   5513   SealHandleScope shs(isolate);
   5514   RUNTIME_ASSERT(args.length() == 1);
   5515   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5516 
   5517   if (object->IsJSFunction()) {
   5518     JSFunction* func = JSFunction::cast(*object);
   5519     func->shared()->set_inline_builtin(true);
   5520   }
   5521   return isolate->heap()->undefined_value();
   5522 }
   5523 
   5524 
   5525 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
   5526   HandleScope scope(isolate);
   5527   RUNTIME_ASSERT(args.length() == 5);
   5528   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5529   CONVERT_SMI_ARG_CHECKED(store_index, 1);
   5530   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5531   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
   5532   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
   5533 
   5534   Object* raw_literal_cell = literals->get(literal_index);
   5535   JSArray* boilerplate = NULL;
   5536   if (raw_literal_cell->IsAllocationSite()) {
   5537     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
   5538     boilerplate = JSArray::cast(site->transition_info());
   5539   } else {
   5540     boilerplate = JSArray::cast(raw_literal_cell);
   5541   }
   5542   Handle<JSArray> boilerplate_object(boilerplate);
   5543   ElementsKind elements_kind = object->GetElementsKind();
   5544   ASSERT(IsFastElementsKind(elements_kind));
   5545   // Smis should never trigger transitions.
   5546   ASSERT(!value->IsSmi());
   5547 
   5548   if (value->IsNumber()) {
   5549     ASSERT(IsFastSmiElementsKind(elements_kind));
   5550     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5551         ? FAST_HOLEY_DOUBLE_ELEMENTS
   5552         : FAST_DOUBLE_ELEMENTS;
   5553     if (IsMoreGeneralElementsKindTransition(
   5554             boilerplate_object->GetElementsKind(),
   5555             transitioned_kind)) {
   5556       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5557     }
   5558     JSObject::TransitionElementsKind(object, transitioned_kind);
   5559     ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
   5560     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
   5561     HeapNumber* number = HeapNumber::cast(*value);
   5562     double_array->set(store_index, number->Number());
   5563   } else {
   5564     if (!IsFastObjectElementsKind(elements_kind)) {
   5565       ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5566           ? FAST_HOLEY_ELEMENTS
   5567           : FAST_ELEMENTS;
   5568       JSObject::TransitionElementsKind(object, transitioned_kind);
   5569       ElementsKind boilerplate_elements_kind =
   5570           boilerplate_object->GetElementsKind();
   5571       if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
   5572                                               transitioned_kind)) {
   5573         JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5574       }
   5575     }
   5576     FixedArray* object_array = FixedArray::cast(object->elements());
   5577     object_array->set(store_index, *value);
   5578   }
   5579   return *object;
   5580 }
   5581 
   5582 
   5583 // Check whether debugger and is about to step into the callback that is passed
   5584 // to a built-in function such as Array.forEach.
   5585 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
   5586   ASSERT(args.length() == 1);
   5587   if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
   5588     return isolate->heap()->false_value();
   5589   }
   5590   CONVERT_ARG_CHECKED(Object, callback, 0);
   5591   // We do not step into the callback if it's a builtin or not even a function.
   5592   return isolate->heap()->ToBoolean(
   5593       callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
   5594 }
   5595 
   5596 
   5597 // Set one shot breakpoints for the callback function that is passed to a
   5598 // built-in function such as Array.forEach to enable stepping into the callback.
   5599 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
   5600   ASSERT(args.length() == 1);
   5601   Debug* debug = isolate->debug();
   5602   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
   5603   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
   5604   HandleScope scope(isolate);
   5605   // When leaving the callback, step out has been activated, but not performed
   5606   // if we do not leave the builtin.  To be able to step into the callback
   5607   // again, we need to clear the step out at this point.
   5608   debug->ClearStepOut();
   5609   debug->FloodWithOneShot(callback);
   5610   return isolate->heap()->undefined_value();
   5611 }
   5612 
   5613 
   5614 // The argument is a closure that is kept until the epilogue is called.
   5615 // On exception, the closure is called, which returns the promise if the
   5616 // exception is considered uncaught, or undefined otherwise.
   5617 RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
   5618   ASSERT(args.length() == 1);
   5619   HandleScope scope(isolate);
   5620   CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
   5621   isolate->debug()->PromiseHandlePrologue(promise_getter);
   5622   return isolate->heap()->undefined_value();
   5623 }
   5624 
   5625 
   5626 RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
   5627   ASSERT(args.length() == 0);
   5628   SealHandleScope shs(isolate);
   5629   isolate->debug()->PromiseHandleEpilogue();
   5630   return isolate->heap()->undefined_value();
   5631 }
   5632 
   5633 
   5634 // Set an own property, even if it is READ_ONLY.  If the property does not
   5635 // exist, it will be added with attributes NONE.
   5636 RUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
   5637   HandleScope scope(isolate);
   5638   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
   5639   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5640   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5641   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5642   // Compute attributes.
   5643   PropertyAttributes attributes = NONE;
   5644   if (args.length() == 4) {
   5645     CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
   5646     // Only attribute bits should be set.
   5647     RUNTIME_ASSERT(
   5648         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5649     attributes = static_cast<PropertyAttributes>(unchecked_value);
   5650   }
   5651   Handle<Object> result;
   5652   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5653       isolate, result,
   5654       JSObject::SetOwnPropertyIgnoreAttributes(
   5655           object, name, value, attributes));
   5656   return *result;
   5657 }
   5658 
   5659 
   5660 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
   5661   HandleScope scope(isolate);
   5662   ASSERT(args.length() == 3);
   5663   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5664   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5665   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
   5666   JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
   5667       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
   5668   Handle<Object> result;
   5669   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5670       isolate, result,
   5671       JSReceiver::DeleteProperty(object, key, delete_mode));
   5672   return *result;
   5673 }
   5674 
   5675 
   5676 static Object* HasOwnPropertyImplementation(Isolate* isolate,
   5677                                             Handle<JSObject> object,
   5678                                             Handle<Name> key) {
   5679   if (JSReceiver::HasOwnProperty(object, key)) {
   5680     return isolate->heap()->true_value();
   5681   }
   5682   // Handle hidden prototypes.  If there's a hidden prototype above this thing
   5683   // then we have to check it for properties, because they are supposed to
   5684   // look like they are on this object.
   5685   Handle<Object> proto(object->GetPrototype(), isolate);
   5686   if (proto->IsJSObject() &&
   5687       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
   5688     return HasOwnPropertyImplementation(isolate,
   5689                                         Handle<JSObject>::cast(proto),
   5690                                         key);
   5691   }
   5692   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5693   return isolate->heap()->false_value();
   5694 }
   5695 
   5696 
   5697 RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
   5698   HandleScope scope(isolate);
   5699   ASSERT(args.length() == 2);
   5700   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
   5701   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5702 
   5703   uint32_t index;
   5704   const bool key_is_array_index = key->AsArrayIndex(&index);
   5705 
   5706   // Only JS objects can have properties.
   5707   if (object->IsJSObject()) {
   5708     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
   5709     // Fast case: either the key is a real named property or it is not
   5710     // an array index and there are no interceptors or hidden
   5711     // prototypes.
   5712     if (JSObject::HasRealNamedProperty(js_obj, key)) {
   5713       ASSERT(!isolate->has_scheduled_exception());
   5714       return isolate->heap()->true_value();
   5715     } else {
   5716       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5717     }
   5718     Map* map = js_obj->map();
   5719     if (!key_is_array_index &&
   5720         !map->has_named_interceptor() &&
   5721         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
   5722       return isolate->heap()->false_value();
   5723     }
   5724     // Slow case.
   5725     return HasOwnPropertyImplementation(isolate,
   5726                                         Handle<JSObject>(js_obj),
   5727                                         Handle<Name>(key));
   5728   } else if (object->IsString() && key_is_array_index) {
   5729     // Well, there is one exception:  Handle [] on strings.
   5730     Handle<String> string = Handle<String>::cast(object);
   5731     if (index < static_cast<uint32_t>(string->length())) {
   5732       return isolate->heap()->true_value();
   5733     }
   5734   }
   5735   return isolate->heap()->false_value();
   5736 }
   5737 
   5738 
   5739 RUNTIME_FUNCTION(Runtime_HasProperty) {
   5740   HandleScope scope(isolate);
   5741   ASSERT(args.length() == 2);
   5742   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   5743   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5744 
   5745   bool result = JSReceiver::HasProperty(receiver, key);
   5746   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5747   if (isolate->has_pending_exception()) return isolate->heap()->exception();
   5748   return isolate->heap()->ToBoolean(result);
   5749 }
   5750 
   5751 
   5752 RUNTIME_FUNCTION(Runtime_HasElement) {
   5753   HandleScope scope(isolate);
   5754   ASSERT(args.length() == 2);
   5755   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   5756   CONVERT_SMI_ARG_CHECKED(index, 1);
   5757 
   5758   bool result = JSReceiver::HasElement(receiver, index);
   5759   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5760   return isolate->heap()->ToBoolean(result);
   5761 }
   5762 
   5763 
   5764 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
   5765   HandleScope scope(isolate);
   5766   ASSERT(args.length() == 2);
   5767 
   5768   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5769   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5770 
   5771   PropertyAttributes att = JSReceiver::GetOwnPropertyAttributes(object, key);
   5772   if (att == ABSENT || (att & DONT_ENUM) != 0) {
   5773     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5774     return isolate->heap()->false_value();
   5775   }
   5776   ASSERT(!isolate->has_scheduled_exception());
   5777   return isolate->heap()->true_value();
   5778 }
   5779 
   5780 
   5781 RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
   5782   HandleScope scope(isolate);
   5783   ASSERT(args.length() == 1);
   5784   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5785   Handle<JSArray> result;
   5786 
   5787   isolate->counters()->for_in()->Increment();
   5788   Handle<FixedArray> elements;
   5789   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5790       isolate, elements,
   5791       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
   5792   return *isolate->factory()->NewJSArrayWithElements(elements);
   5793 }
   5794 
   5795 
   5796 // Returns either a FixedArray as Runtime_GetPropertyNames,
   5797 // or, if the given object has an enum cache that contains
   5798 // all enumerable properties of the object and its prototypes
   5799 // have none, the map of the object. This is used to speed up
   5800 // the check for deletions during a for-in.
   5801 RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
   5802   SealHandleScope shs(isolate);
   5803   ASSERT(args.length() == 1);
   5804 
   5805   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
   5806 
   5807   if (raw_object->IsSimpleEnum()) return raw_object->map();
   5808 
   5809   HandleScope scope(isolate);
   5810   Handle<JSReceiver> object(raw_object);
   5811   Handle<FixedArray> content;
   5812   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   5813       isolate, content,
   5814       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
   5815 
   5816   // Test again, since cache may have been built by preceding call.
   5817   if (object->IsSimpleEnum()) return object->map();
   5818 
   5819   return *content;
   5820 }
   5821 
   5822 
   5823 // Find the length of the prototype chain that is to be handled as one. If a
   5824 // prototype object is hidden it is to be viewed as part of the the object it
   5825 // is prototype for.
   5826 static int OwnPrototypeChainLength(JSObject* obj) {
   5827   int count = 1;
   5828   Object* proto = obj->GetPrototype();
   5829   while (proto->IsJSObject() &&
   5830          JSObject::cast(proto)->map()->is_hidden_prototype()) {
   5831     count++;
   5832     proto = JSObject::cast(proto)->GetPrototype();
   5833   }
   5834   return count;
   5835 }
   5836 
   5837 
   5838 // Return the names of the own named properties.
   5839 // args[0]: object
   5840 // args[1]: PropertyAttributes as int
   5841 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
   5842   HandleScope scope(isolate);
   5843   ASSERT(args.length() == 2);
   5844   if (!args[0]->IsJSObject()) {
   5845     return isolate->heap()->undefined_value();
   5846   }
   5847   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5848   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
   5849   PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
   5850 
   5851   // Skip the global proxy as it has no properties and always delegates to the
   5852   // real global object.
   5853   if (obj->IsJSGlobalProxy()) {
   5854     // Only collect names if access is permitted.
   5855     if (obj->IsAccessCheckNeeded() &&
   5856         !isolate->MayNamedAccess(
   5857             obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
   5858       isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
   5859       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5860       return *isolate->factory()->NewJSArray(0);
   5861     }
   5862     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   5863   }
   5864 
   5865   // Find the number of objects making up this.
   5866   int length = OwnPrototypeChainLength(*obj);
   5867 
   5868   // Find the number of own properties for each of the objects.
   5869   ScopedVector<int> own_property_count(length);
   5870   int total_property_count = 0;
   5871   Handle<JSObject> jsproto = obj;
   5872   for (int i = 0; i < length; i++) {
   5873     // Only collect names if access is permitted.
   5874     if (jsproto->IsAccessCheckNeeded() &&
   5875         !isolate->MayNamedAccess(
   5876             jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
   5877       isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
   5878       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   5879       return *isolate->factory()->NewJSArray(0);
   5880     }
   5881     int n;
   5882     n = jsproto->NumberOfOwnProperties(filter);
   5883     own_property_count[i] = n;
   5884     total_property_count += n;
   5885     if (i < length - 1) {
   5886       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   5887     }
   5888   }
   5889 
   5890   // Allocate an array with storage for all the property names.
   5891   Handle<FixedArray> names =
   5892       isolate->factory()->NewFixedArray(total_property_count);
   5893 
   5894   // Get the property names.
   5895   jsproto = obj;
   5896   int next_copy_index = 0;
   5897   int hidden_strings = 0;
   5898   for (int i = 0; i < length; i++) {
   5899     jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
   5900     if (i > 0) {
   5901       // Names from hidden prototypes may already have been added
   5902       // for inherited function template instances. Count the duplicates
   5903       // and stub them out; the final copy pass at the end ignores holes.
   5904       for (int j = next_copy_index;
   5905            j < next_copy_index + own_property_count[i];
   5906            j++) {
   5907         Object* name_from_hidden_proto = names->get(j);
   5908         for (int k = 0; k < next_copy_index; k++) {
   5909           if (names->get(k) != isolate->heap()->hidden_string()) {
   5910             Object* name = names->get(k);
   5911             if (name_from_hidden_proto == name) {
   5912               names->set(j, isolate->heap()->hidden_string());
   5913               hidden_strings++;
   5914               break;
   5915             }
   5916           }
   5917         }
   5918       }
   5919     }
   5920     next_copy_index += own_property_count[i];
   5921 
   5922     // Hidden properties only show up if the filter does not skip strings.
   5923     if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
   5924       hidden_strings++;
   5925     }
   5926     if (i < length - 1) {
   5927       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   5928     }
   5929   }
   5930 
   5931   // Filter out name of hidden properties object and
   5932   // hidden prototype duplicates.
   5933   if (hidden_strings > 0) {
   5934     Handle<FixedArray> old_names = names;
   5935     names = isolate->factory()->NewFixedArray(
   5936         names->length() - hidden_strings);
   5937     int dest_pos = 0;
   5938     for (int i = 0; i < total_property_count; i++) {
   5939       Object* name = old_names->get(i);
   5940       if (name == isolate->heap()->hidden_string()) {
   5941         hidden_strings--;
   5942         continue;
   5943       }
   5944       names->set(dest_pos++, name);
   5945     }
   5946     ASSERT_EQ(0, hidden_strings);
   5947   }
   5948 
   5949   return *isolate->factory()->NewJSArrayWithElements(names);
   5950 }
   5951 
   5952 
   5953 // Return the names of the own indexed properties.
   5954 // args[0]: object
   5955 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
   5956   HandleScope scope(isolate);
   5957   ASSERT(args.length() == 1);
   5958   if (!args[0]->IsJSObject()) {
   5959     return isolate->heap()->undefined_value();
   5960   }
   5961   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5962 
   5963   int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
   5964   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
   5965   obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
   5966   return *isolate->factory()->NewJSArrayWithElements(names);
   5967 }
   5968 
   5969 
   5970 // Return information on whether an object has a named or indexed interceptor.
   5971 // args[0]: object
   5972 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
   5973   HandleScope scope(isolate);
   5974   ASSERT(args.length() == 1);
   5975   if (!args[0]->IsJSObject()) {
   5976     return Smi::FromInt(0);
   5977   }
   5978   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5979 
   5980   int result = 0;
   5981   if (obj->HasNamedInterceptor()) result |= 2;
   5982   if (obj->HasIndexedInterceptor()) result |= 1;
   5983 
   5984   return Smi::FromInt(result);
   5985 }
   5986 
   5987 
   5988 // Return property names from named interceptor.
   5989 // args[0]: object
   5990 RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
   5991   HandleScope scope(isolate);
   5992   ASSERT(args.length() == 1);
   5993   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5994 
   5995   if (obj->HasNamedInterceptor()) {
   5996     Handle<JSObject> result;
   5997     if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
   5998       return *result;
   5999     }
   6000   }
   6001   return isolate->heap()->undefined_value();
   6002 }
   6003 
   6004 
   6005 // Return element names from indexed interceptor.
   6006 // args[0]: object
   6007 RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
   6008   HandleScope scope(isolate);
   6009   ASSERT(args.length() == 1);
   6010   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   6011 
   6012   if (obj->HasIndexedInterceptor()) {
   6013     Handle<JSObject> result;
   6014     if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
   6015       return *result;
   6016     }
   6017   }
   6018   return isolate->heap()->undefined_value();
   6019 }
   6020 
   6021 
   6022 RUNTIME_FUNCTION(Runtime_OwnKeys) {
   6023   HandleScope scope(isolate);
   6024   ASSERT(args.length() == 1);
   6025   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
   6026   Handle<JSObject> object(raw_object);
   6027 
   6028   if (object->IsJSGlobalProxy()) {
   6029     // Do access checks before going to the global object.
   6030     if (object->IsAccessCheckNeeded() &&
   6031         !isolate->MayNamedAccess(
   6032             object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
   6033       isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
   6034       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   6035       return *isolate->factory()->NewJSArray(0);
   6036     }
   6037 
   6038     Handle<Object> proto(object->GetPrototype(), isolate);
   6039     // If proxy is detached we simply return an empty array.
   6040     if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
   6041     object = Handle<JSObject>::cast(proto);
   6042   }
   6043 
   6044   Handle<FixedArray> contents;
   6045   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6046       isolate, contents,
   6047       JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
   6048 
   6049   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
   6050   // property array and since the result is mutable we have to create
   6051   // a fresh clone on each invocation.
   6052   int length = contents->length();
   6053   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
   6054   for (int i = 0; i < length; i++) {
   6055     Object* entry = contents->get(i);
   6056     if (entry->IsString()) {
   6057       copy->set(i, entry);
   6058     } else {
   6059       ASSERT(entry->IsNumber());
   6060       HandleScope scope(isolate);
   6061       Handle<Object> entry_handle(entry, isolate);
   6062       Handle<Object> entry_str =
   6063           isolate->factory()->NumberToString(entry_handle);
   6064       copy->set(i, *entry_str);
   6065     }
   6066   }
   6067   return *isolate->factory()->NewJSArrayWithElements(copy);
   6068 }
   6069 
   6070 
   6071 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
   6072   SealHandleScope shs(isolate);
   6073   ASSERT(args.length() == 1);
   6074   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
   6075 
   6076   // Compute the frame holding the arguments.
   6077   JavaScriptFrameIterator it(isolate);
   6078   it.AdvanceToArgumentsFrame();
   6079   JavaScriptFrame* frame = it.frame();
   6080 
   6081   // Get the actual number of provided arguments.
   6082   const uint32_t n = frame->ComputeParametersCount();
   6083 
   6084   // Try to convert the key to an index. If successful and within
   6085   // index return the the argument from the frame.
   6086   uint32_t index;
   6087   if (raw_key->ToArrayIndex(&index) && index < n) {
   6088     return frame->GetParameter(index);
   6089   }
   6090 
   6091   HandleScope scope(isolate);
   6092   if (raw_key->IsSymbol()) {
   6093     // Lookup in the initial Object.prototype object.
   6094     Handle<Object> result;
   6095     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6096         isolate, result,
   6097         Object::GetProperty(isolate->initial_object_prototype(),
   6098                             Handle<Symbol>::cast(raw_key)));
   6099     return *result;
   6100   }
   6101 
   6102   // Convert the key to a string.
   6103   Handle<Object> converted;
   6104   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6105       isolate, converted, Execution::ToString(isolate, raw_key));
   6106   Handle<String> key = Handle<String>::cast(converted);
   6107 
   6108   // Try to convert the string key into an array index.
   6109   if (key->AsArrayIndex(&index)) {
   6110     if (index < n) {
   6111       return frame->GetParameter(index);
   6112     } else {
   6113       Handle<Object> initial_prototype(isolate->initial_object_prototype());
   6114       Handle<Object> result;
   6115       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6116           isolate, result,
   6117           Object::GetElement(isolate, initial_prototype, index));
   6118       return *result;
   6119     }
   6120   }
   6121 
   6122   // Handle special arguments properties.
   6123   if (String::Equals(isolate->factory()->length_string(), key)) {
   6124     return Smi::FromInt(n);
   6125   }
   6126   if (String::Equals(isolate->factory()->callee_string(), key)) {
   6127     JSFunction* function = frame->function();
   6128     if (function->shared()->strict_mode() == STRICT) {
   6129       return isolate->Throw(*isolate->factory()->NewTypeError(
   6130           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
   6131     }
   6132     return function;
   6133   }
   6134 
   6135   // Lookup in the initial Object.prototype object.
   6136   Handle<Object> result;
   6137   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6138       isolate, result,
   6139       Object::GetProperty(isolate->initial_object_prototype(), key));
   6140   return *result;
   6141 }
   6142 
   6143 
   6144 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
   6145   HandleScope scope(isolate);
   6146   ASSERT(args.length() == 1);
   6147   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   6148   if (object->IsJSObject() && !object->IsGlobalObject()) {
   6149     JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0);
   6150   }
   6151   return *object;
   6152 }
   6153 
   6154 
   6155 RUNTIME_FUNCTION(Runtime_ToBool) {
   6156   SealHandleScope shs(isolate);
   6157   ASSERT(args.length() == 1);
   6158   CONVERT_ARG_CHECKED(Object, object, 0);
   6159 
   6160   return isolate->heap()->ToBoolean(object->BooleanValue());
   6161 }
   6162 
   6163 
   6164 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
   6165 // Possible optimizations: put the type string into the oddballs.
   6166 RUNTIME_FUNCTION(Runtime_Typeof) {
   6167   SealHandleScope shs(isolate);
   6168   ASSERT(args.length() == 1);
   6169   CONVERT_ARG_CHECKED(Object, obj, 0);
   6170   if (obj->IsNumber()) return isolate->heap()->number_string();
   6171   HeapObject* heap_obj = HeapObject::cast(obj);
   6172 
   6173   // typeof an undetectable object is 'undefined'
   6174   if (heap_obj->map()->is_undetectable()) {
   6175     return isolate->heap()->undefined_string();
   6176   }
   6177 
   6178   InstanceType instance_type = heap_obj->map()->instance_type();
   6179   if (instance_type < FIRST_NONSTRING_TYPE) {
   6180     return isolate->heap()->string_string();
   6181   }
   6182 
   6183   switch (instance_type) {
   6184     case ODDBALL_TYPE:
   6185       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
   6186         return isolate->heap()->boolean_string();
   6187       }
   6188       if (heap_obj->IsNull()) {
   6189         return FLAG_harmony_typeof
   6190             ? isolate->heap()->null_string()
   6191             : isolate->heap()->object_string();
   6192       }
   6193       ASSERT(heap_obj->IsUndefined());
   6194       return isolate->heap()->undefined_string();
   6195     case SYMBOL_TYPE:
   6196       return isolate->heap()->symbol_string();
   6197     case JS_FUNCTION_TYPE:
   6198     case JS_FUNCTION_PROXY_TYPE:
   6199       return isolate->heap()->function_string();
   6200     default:
   6201       // For any kind of object not handled above, the spec rule for
   6202       // host objects gives that it is okay to return "object"
   6203       return isolate->heap()->object_string();
   6204   }
   6205 }
   6206 
   6207 
   6208 static bool AreDigits(const uint8_t*s, int from, int to) {
   6209   for (int i = from; i < to; i++) {
   6210     if (s[i] < '0' || s[i] > '9') return false;
   6211   }
   6212 
   6213   return true;
   6214 }
   6215 
   6216 
   6217 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
   6218   ASSERT(to - from < 10);  // Overflow is not possible.
   6219   ASSERT(from < to);
   6220   int d = s[from] - '0';
   6221 
   6222   for (int i = from + 1; i < to; i++) {
   6223     d = 10 * d + (s[i] - '0');
   6224   }
   6225 
   6226   return d;
   6227 }
   6228 
   6229 
   6230 RUNTIME_FUNCTION(Runtime_StringToNumber) {
   6231   HandleScope handle_scope(isolate);
   6232   ASSERT(args.length() == 1);
   6233   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6234   subject = String::Flatten(subject);
   6235 
   6236   // Fast case: short integer or some sorts of junk values.
   6237   if (subject->IsSeqOneByteString()) {
   6238     int len = subject->length();
   6239     if (len == 0) return Smi::FromInt(0);
   6240 
   6241     DisallowHeapAllocation no_gc;
   6242     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
   6243     bool minus = (data[0] == '-');
   6244     int start_pos = (minus ? 1 : 0);
   6245 
   6246     if (start_pos == len) {
   6247       return isolate->heap()->nan_value();
   6248     } else if (data[start_pos] > '9') {
   6249       // Fast check for a junk value. A valid string may start from a
   6250       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
   6251       // or the 'I' character ('Infinity'). All of that have codes not greater
   6252       // than '9' except 'I' and &nbsp;.
   6253       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   6254         return isolate->heap()->nan_value();
   6255       }
   6256     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   6257       // The maximal/minimal smi has 10 digits. If the string has less digits
   6258       // we know it will fit into the smi-data type.
   6259       int d = ParseDecimalInteger(data, start_pos, len);
   6260       if (minus) {
   6261         if (d == 0) return isolate->heap()->minus_zero_value();
   6262         d = -d;
   6263       } else if (!subject->HasHashCode() &&
   6264                  len <= String::kMaxArrayIndexSize &&
   6265                  (len == 1 || data[0] != '0')) {
   6266         // String hash is not calculated yet but all the data are present.
   6267         // Update the hash field to speed up sequential convertions.
   6268         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   6269 #ifdef DEBUG
   6270         subject->Hash();  // Force hash calculation.
   6271         ASSERT_EQ(static_cast<int>(subject->hash_field()),
   6272                   static_cast<int>(hash));
   6273 #endif
   6274         subject->set_hash_field(hash);
   6275       }
   6276       return Smi::FromInt(d);
   6277     }
   6278   }
   6279 
   6280   // Slower case.
   6281   int flags = ALLOW_HEX;
   6282   if (FLAG_harmony_numeric_literals) {
   6283     // The current spec draft has not updated "ToNumber Applied to the String
   6284     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
   6285     flags |= ALLOW_OCTAL | ALLOW_BINARY;
   6286   }
   6287 
   6288   return *isolate->factory()->NewNumber(StringToDouble(
   6289       isolate->unicode_cache(), *subject, flags));
   6290 }
   6291 
   6292 
   6293 RUNTIME_FUNCTION(Runtime_NewString) {
   6294   HandleScope scope(isolate);
   6295   ASSERT(args.length() == 2);
   6296   CONVERT_SMI_ARG_CHECKED(length, 0);
   6297   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
   6298   if (length == 0) return isolate->heap()->empty_string();
   6299   Handle<String> result;
   6300   if (is_one_byte) {
   6301     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6302         isolate, result, isolate->factory()->NewRawOneByteString(length));
   6303   } else {
   6304     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6305         isolate, result, isolate->factory()->NewRawTwoByteString(length));
   6306   }
   6307   return *result;
   6308 }
   6309 
   6310 
   6311 RUNTIME_FUNCTION(Runtime_TruncateString) {
   6312   HandleScope scope(isolate);
   6313   ASSERT(args.length() == 2);
   6314   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
   6315   CONVERT_SMI_ARG_CHECKED(new_length, 1);
   6316   RUNTIME_ASSERT(new_length >= 0);
   6317   return *SeqString::Truncate(string, new_length);
   6318 }
   6319 
   6320 
   6321 RUNTIME_FUNCTION(Runtime_URIEscape) {
   6322   HandleScope scope(isolate);
   6323   ASSERT(args.length() == 1);
   6324   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6325   Handle<String> string = String::Flatten(source);
   6326   ASSERT(string->IsFlat());
   6327   Handle<String> result;
   6328   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6329       isolate, result,
   6330       string->IsOneByteRepresentationUnderneath()
   6331             ? URIEscape::Escape<uint8_t>(isolate, source)
   6332             : URIEscape::Escape<uc16>(isolate, source));
   6333   return *result;
   6334 }
   6335 
   6336 
   6337 RUNTIME_FUNCTION(Runtime_URIUnescape) {
   6338   HandleScope scope(isolate);
   6339   ASSERT(args.length() == 1);
   6340   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6341   Handle<String> string = String::Flatten(source);
   6342   ASSERT(string->IsFlat());
   6343   Handle<String> result;
   6344   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6345       isolate, result,
   6346       string->IsOneByteRepresentationUnderneath()
   6347             ? URIUnescape::Unescape<uint8_t>(isolate, source)
   6348             : URIUnescape::Unescape<uc16>(isolate, source));
   6349   return *result;
   6350 }
   6351 
   6352 
   6353 RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
   6354   HandleScope scope(isolate);
   6355   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   6356   ASSERT(args.length() == 1);
   6357   Handle<Object> result;
   6358   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6359       isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
   6360   return *result;
   6361 }
   6362 
   6363 
   6364 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
   6365   HandleScope scope(isolate);
   6366   ASSERT(args.length() == 1);
   6367   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   6368   BasicJsonStringifier stringifier(isolate);
   6369   Handle<Object> result;
   6370   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6371       isolate, result, stringifier.Stringify(object));
   6372   return *result;
   6373 }
   6374 
   6375 
   6376 RUNTIME_FUNCTION(Runtime_StringParseInt) {
   6377   HandleScope handle_scope(isolate);
   6378   ASSERT(args.length() == 2);
   6379   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6380   CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
   6381   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
   6382 
   6383   subject = String::Flatten(subject);
   6384   double value;
   6385 
   6386   { DisallowHeapAllocation no_gc;
   6387     String::FlatContent flat = subject->GetFlatContent();
   6388 
   6389     // ECMA-262 section 15.1.2.3, empty string is NaN
   6390     if (flat.IsAscii()) {
   6391       value = StringToInt(
   6392           isolate->unicode_cache(), flat.ToOneByteVector(), radix);
   6393     } else {
   6394       value = StringToInt(
   6395           isolate->unicode_cache(), flat.ToUC16Vector(), radix);
   6396     }
   6397   }
   6398 
   6399   return *isolate->factory()->NewNumber(value);
   6400 }
   6401 
   6402 
   6403 RUNTIME_FUNCTION(Runtime_StringParseFloat) {
   6404   HandleScope shs(isolate);
   6405   ASSERT(args.length() == 1);
   6406   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6407 
   6408   subject = String::Flatten(subject);
   6409   double value = StringToDouble(
   6410       isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
   6411 
   6412   return *isolate->factory()->NewNumber(value);
   6413 }
   6414 
   6415 
   6416 static inline bool ToUpperOverflows(uc32 character) {
   6417   // y with umlauts and the micro sign are the only characters that stop
   6418   // fitting into one-byte when converting to uppercase.
   6419   static const uc32 yuml_code = 0xff;
   6420   static const uc32 micro_code = 0xb5;
   6421   return (character == yuml_code || character == micro_code);
   6422 }
   6423 
   6424 
   6425 template <class Converter>
   6426 MUST_USE_RESULT static Object* ConvertCaseHelper(
   6427     Isolate* isolate,
   6428     String* string,
   6429     SeqString* result,
   6430     int result_length,
   6431     unibrow::Mapping<Converter, 128>* mapping) {
   6432   DisallowHeapAllocation no_gc;
   6433   // We try this twice, once with the assumption that the result is no longer
   6434   // than the input and, if that assumption breaks, again with the exact
   6435   // length.  This may not be pretty, but it is nicer than what was here before
   6436   // and I hereby claim my vaffel-is.
   6437   //
   6438   // NOTE: This assumes that the upper/lower case of an ASCII
   6439   // character is also ASCII.  This is currently the case, but it
   6440   // might break in the future if we implement more context and locale
   6441   // dependent upper/lower conversions.
   6442   bool has_changed_character = false;
   6443 
   6444   // Convert all characters to upper case, assuming that they will fit
   6445   // in the buffer
   6446   Access<ConsStringIteratorOp> op(
   6447       isolate->runtime_state()->string_iterator());
   6448   StringCharacterStream stream(string, op.value());
   6449   unibrow::uchar chars[Converter::kMaxWidth];
   6450   // We can assume that the string is not empty
   6451   uc32 current = stream.GetNext();
   6452   bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
   6453   for (int i = 0; i < result_length;) {
   6454     bool has_next = stream.HasMore();
   6455     uc32 next = has_next ? stream.GetNext() : 0;
   6456     int char_length = mapping->get(current, next, chars);
   6457     if (char_length == 0) {
   6458       // The case conversion of this character is the character itself.
   6459       result->Set(i, current);
   6460       i++;
   6461     } else if (char_length == 1 &&
   6462                (ignore_overflow || !ToUpperOverflows(current))) {
   6463       // Common case: converting the letter resulted in one character.
   6464       ASSERT(static_cast<uc32>(chars[0]) != current);
   6465       result->Set(i, chars[0]);
   6466       has_changed_character = true;
   6467       i++;
   6468     } else if (result_length == string->length()) {
   6469       bool overflows = ToUpperOverflows(current);
   6470       // We've assumed that the result would be as long as the
   6471       // input but here is a character that converts to several
   6472       // characters.  No matter, we calculate the exact length
   6473       // of the result and try the whole thing again.
   6474       //
   6475       // Note that this leaves room for optimization.  We could just
   6476       // memcpy what we already have to the result string.  Also,
   6477       // the result string is the last object allocated we could
   6478       // "realloc" it and probably, in the vast majority of cases,
   6479       // extend the existing string to be able to hold the full
   6480       // result.
   6481       int next_length = 0;
   6482       if (has_next) {
   6483         next_length = mapping->get(next, 0, chars);
   6484         if (next_length == 0) next_length = 1;
   6485       }
   6486       int current_length = i + char_length + next_length;
   6487       while (stream.HasMore()) {
   6488         current = stream.GetNext();
   6489         overflows |= ToUpperOverflows(current);
   6490         // NOTE: we use 0 as the next character here because, while
   6491         // the next character may affect what a character converts to,
   6492         // it does not in any case affect the length of what it convert
   6493         // to.
   6494         int char_length = mapping->get(current, 0, chars);
   6495         if (char_length == 0) char_length = 1;
   6496         current_length += char_length;
   6497         if (current_length > String::kMaxLength) {
   6498           AllowHeapAllocation allocate_error_and_return;
   6499           return isolate->ThrowInvalidStringLength();
   6500         }
   6501       }
   6502       // Try again with the real length.  Return signed if we need
   6503       // to allocate a two-byte string for to uppercase.
   6504       return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
   6505                                              : Smi::FromInt(current_length);
   6506     } else {
   6507       for (int j = 0; j < char_length; j++) {
   6508         result->Set(i, chars[j]);
   6509         i++;
   6510       }
   6511       has_changed_character = true;
   6512     }
   6513     current = next;
   6514   }
   6515   if (has_changed_character) {
   6516     return result;
   6517   } else {
   6518     // If we didn't actually change anything in doing the conversion
   6519     // we simple return the result and let the converted string
   6520     // become garbage; there is no reason to keep two identical strings
   6521     // alive.
   6522     return string;
   6523   }
   6524 }
   6525 
   6526 
   6527 namespace {
   6528 
   6529 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
   6530 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
   6531 
   6532 // Given a word and two range boundaries returns a word with high bit
   6533 // set in every byte iff the corresponding input byte was strictly in
   6534 // the range (m, n). All the other bits in the result are cleared.
   6535 // This function is only useful when it can be inlined and the
   6536 // boundaries are statically known.
   6537 // Requires: all bytes in the input word and the boundaries must be
   6538 // ASCII (less than 0x7F).
   6539 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
   6540   // Use strict inequalities since in edge cases the function could be
   6541   // further simplified.
   6542   ASSERT(0 < m && m < n);
   6543   // Has high bit set in every w byte less than n.
   6544   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   6545   // Has high bit set in every w byte greater than m.
   6546   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
   6547   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
   6548 }
   6549 
   6550 
   6551 #ifdef DEBUG
   6552 static bool CheckFastAsciiConvert(char* dst,
   6553                                   const char* src,
   6554                                   int length,
   6555                                   bool changed,
   6556                                   bool is_to_lower) {
   6557   bool expected_changed = false;
   6558   for (int i = 0; i < length; i++) {
   6559     if (dst[i] == src[i]) continue;
   6560     expected_changed = true;
   6561     if (is_to_lower) {
   6562       ASSERT('A' <= src[i] && src[i] <= 'Z');
   6563       ASSERT(dst[i] == src[i] + ('a' - 'A'));
   6564     } else {
   6565       ASSERT('a' <= src[i] && src[i] <= 'z');
   6566       ASSERT(dst[i] == src[i] - ('a' - 'A'));
   6567     }
   6568   }
   6569   return (expected_changed == changed);
   6570 }
   6571 #endif
   6572 
   6573 
   6574 template<class Converter>
   6575 static bool FastAsciiConvert(char* dst,
   6576                              const char* src,
   6577                              int length,
   6578                              bool* changed_out) {
   6579 #ifdef DEBUG
   6580     char* saved_dst = dst;
   6581     const char* saved_src = src;
   6582 #endif
   6583   DisallowHeapAllocation no_gc;
   6584   // We rely on the distance between upper and lower case letters
   6585   // being a known power of 2.
   6586   ASSERT('a' - 'A' == (1 << 5));
   6587   // Boundaries for the range of input characters than require conversion.
   6588   static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
   6589   static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
   6590   bool changed = false;
   6591   uintptr_t or_acc = 0;
   6592   const char* const limit = src + length;
   6593 #ifdef V8_HOST_CAN_READ_UNALIGNED
   6594   // Process the prefix of the input that requires no conversion one
   6595   // (machine) word at a time.
   6596   while (src <= limit - sizeof(uintptr_t)) {
   6597     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
   6598     or_acc |= w;
   6599     if (AsciiRangeMask(w, lo, hi) != 0) {
   6600       changed = true;
   6601       break;
   6602     }
   6603     *reinterpret_cast<uintptr_t*>(dst) = w;
   6604     src += sizeof(uintptr_t);
   6605     dst += sizeof(uintptr_t);
   6606   }
   6607   // Process the remainder of the input performing conversion when
   6608   // required one word at a time.
   6609   while (src <= limit - sizeof(uintptr_t)) {
   6610     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
   6611     or_acc |= w;
   6612     uintptr_t m = AsciiRangeMask(w, lo, hi);
   6613     // The mask has high (7th) bit set in every byte that needs
   6614     // conversion and we know that the distance between cases is
   6615     // 1 << 5.
   6616     *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
   6617     src += sizeof(uintptr_t);
   6618     dst += sizeof(uintptr_t);
   6619   }
   6620 #endif
   6621   // Process the last few bytes of the input (or the whole input if
   6622   // unaligned access is not supported).
   6623   while (src < limit) {
   6624     char c = *src;
   6625     or_acc |= c;
   6626     if (lo < c && c < hi) {
   6627       c ^= (1 << 5);
   6628       changed = true;
   6629     }
   6630     *dst = c;
   6631     ++src;
   6632     ++dst;
   6633   }
   6634   if ((or_acc & kAsciiMask) != 0) {
   6635     return false;
   6636   }
   6637 
   6638   ASSERT(CheckFastAsciiConvert(
   6639              saved_dst, saved_src, length, changed, Converter::kIsToLower));
   6640 
   6641   *changed_out = changed;
   6642   return true;
   6643 }
   6644 
   6645 }  // namespace
   6646 
   6647 
   6648 template <class Converter>
   6649 MUST_USE_RESULT static Object* ConvertCase(
   6650     Handle<String> s,
   6651     Isolate* isolate,
   6652     unibrow::Mapping<Converter, 128>* mapping) {
   6653   s = String::Flatten(s);
   6654   int length = s->length();
   6655   // Assume that the string is not empty; we need this assumption later
   6656   if (length == 0) return *s;
   6657 
   6658   // Simpler handling of ASCII strings.
   6659   //
   6660   // NOTE: This assumes that the upper/lower case of an ASCII
   6661   // character is also ASCII.  This is currently the case, but it
   6662   // might break in the future if we implement more context and locale
   6663   // dependent upper/lower conversions.
   6664   if (s->IsOneByteRepresentationUnderneath()) {
   6665     // Same length as input.
   6666     Handle<SeqOneByteString> result =
   6667         isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
   6668     DisallowHeapAllocation no_gc;
   6669     String::FlatContent flat_content = s->GetFlatContent();
   6670     ASSERT(flat_content.IsFlat());
   6671     bool has_changed_character = false;
   6672     bool is_ascii = FastAsciiConvert<Converter>(
   6673         reinterpret_cast<char*>(result->GetChars()),
   6674         reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
   6675         length,
   6676         &has_changed_character);
   6677     // If not ASCII, we discard the result and take the 2 byte path.
   6678     if (is_ascii) return has_changed_character ? *result : *s;
   6679   }
   6680 
   6681   Handle<SeqString> result;  // Same length as input.
   6682   if (s->IsOneByteRepresentation()) {
   6683     result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
   6684   } else {
   6685     result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
   6686   }
   6687 
   6688   Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
   6689   if (answer->IsException() || answer->IsString()) return answer;
   6690 
   6691   ASSERT(answer->IsSmi());
   6692   length = Smi::cast(answer)->value();
   6693   if (s->IsOneByteRepresentation() && length > 0) {
   6694     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6695         isolate, result, isolate->factory()->NewRawOneByteString(length));
   6696   } else {
   6697     if (length < 0) length = -length;
   6698     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   6699         isolate, result, isolate->factory()->NewRawTwoByteString(length));
   6700   }
   6701   return ConvertCaseHelper(isolate, *s, *result, length, mapping);
   6702 }
   6703 
   6704 
   6705 RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
   6706   HandleScope scope(isolate);
   6707   ASSERT(args.length() == 1);
   6708   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6709   return ConvertCase(
   6710       s, isolate, isolate->runtime_state()->to_lower_mapping());
   6711 }
   6712 
   6713 
   6714 RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
   6715   HandleScope scope(isolate);
   6716   ASSERT(args.length() == 1);
   6717   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6718   return ConvertCase(
   6719       s, isolate, isolate->runtime_state()->to_upper_mapping());
   6720 }
   6721 
   6722 
   6723 RUNTIME_FUNCTION(Runtime_StringTrim) {
   6724   HandleScope scope(isolate);
   6725   ASSERT(args.length() == 3);
   6726 
   6727   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   6728   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
   6729   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
   6730 
   6731   string = String::Flatten(string);
   6732   int length = string->length();
   6733 
   6734   int left = 0;
   6735   UnicodeCache* unicode_cache = isolate->unicode_cache();
   6736   if (trimLeft) {
   6737     while (left < length &&
   6738            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
   6739       left++;
   6740     }
   6741   }
   6742 
   6743   int right = length;
   6744   if (trimRight) {
   6745     while (right > left &&
   6746            unicode_cache->IsWhiteSpaceOrLineTerminator(
   6747                string->Get(right - 1))) {
   6748       right--;
   6749     }
   6750   }
   6751 
   6752   return *isolate->factory()->NewSubString(string, left, right);
   6753 }
   6754 
   6755 
   6756 RUNTIME_FUNCTION(Runtime_StringSplit) {
   6757   HandleScope handle_scope(isolate);
   6758   ASSERT(args.length() == 3);
   6759   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6760   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   6761   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
   6762   RUNTIME_ASSERT(limit > 0);
   6763 
   6764   int subject_length = subject->length();
   6765   int pattern_length = pattern->length();
   6766   RUNTIME_ASSERT(pattern_length > 0);
   6767 
   6768   if (limit == 0xffffffffu) {
   6769     Handle<Object> cached_answer(
   6770         RegExpResultsCache::Lookup(isolate->heap(),
   6771                                    *subject,
   6772                                    *pattern,
   6773                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
   6774         isolate);
   6775     if (*cached_answer != Smi::FromInt(0)) {
   6776       // The cache FixedArray is a COW-array and can therefore be reused.
   6777       Handle<JSArray> result =
   6778           isolate->factory()->NewJSArrayWithElements(
   6779               Handle<FixedArray>::cast(cached_answer));
   6780       return *result;
   6781     }
   6782   }
   6783 
   6784   // The limit can be very large (0xffffffffu), but since the pattern
   6785   // isn't empty, we can never create more parts than ~half the length
   6786   // of the subject.
   6787 
   6788   subject = String::Flatten(subject);
   6789   pattern = String::Flatten(pattern);
   6790 
   6791   static const int kMaxInitialListCapacity = 16;
   6792 
   6793   ZoneScope zone_scope(isolate->runtime_zone());
   6794 
   6795   // Find (up to limit) indices of separator and end-of-string in subject
   6796   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
   6797   ZoneList<int> indices(initial_capacity, zone_scope.zone());
   6798 
   6799   FindStringIndicesDispatch(isolate, *subject, *pattern,
   6800                             &indices, limit, zone_scope.zone());
   6801 
   6802   if (static_cast<uint32_t>(indices.length()) < limit) {
   6803     indices.Add(subject_length, zone_scope.zone());
   6804   }
   6805 
   6806   // The list indices now contains the end of each part to create.
   6807 
   6808   // Create JSArray of substrings separated by separator.
   6809   int part_count = indices.length();
   6810 
   6811   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
   6812   JSObject::EnsureCanContainHeapObjectElements(result);
   6813   result->set_length(Smi::FromInt(part_count));
   6814 
   6815   ASSERT(result->HasFastObjectElements());
   6816 
   6817   if (part_count == 1 && indices.at(0) == subject_length) {
   6818     FixedArray::cast(result->elements())->set(0, *subject);
   6819     return *result;
   6820   }
   6821 
   6822   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
   6823   int part_start = 0;
   6824   for (int i = 0; i < part_count; i++) {
   6825     HandleScope local_loop_handle(isolate);
   6826     int part_end = indices.at(i);
   6827     Handle<String> substring =
   6828         isolate->factory()->NewProperSubString(subject, part_start, part_end);
   6829     elements->set(i, *substring);
   6830     part_start = part_end + pattern_length;
   6831   }
   6832 
   6833   if (limit == 0xffffffffu) {
   6834     if (result->HasFastObjectElements()) {
   6835       RegExpResultsCache::Enter(isolate,
   6836                                 subject,
   6837                                 pattern,
   6838                                 elements,
   6839                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
   6840     }
   6841   }
   6842 
   6843   return *result;
   6844 }
   6845 
   6846 
   6847 // Copies ASCII characters to the given fixed array looking up
   6848 // one-char strings in the cache. Gives up on the first char that is
   6849 // not in the cache and fills the remainder with smi zeros. Returns
   6850 // the length of the successfully copied prefix.
   6851 static int CopyCachedAsciiCharsToArray(Heap* heap,
   6852                                        const uint8_t* chars,
   6853                                        FixedArray* elements,
   6854                                        int length) {
   6855   DisallowHeapAllocation no_gc;
   6856   FixedArray* ascii_cache = heap->single_character_string_cache();
   6857   Object* undefined = heap->undefined_value();
   6858   int i;
   6859   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   6860   for (i = 0; i < length; ++i) {
   6861     Object* value = ascii_cache->get(chars[i]);
   6862     if (value == undefined) break;
   6863     elements->set(i, value, mode);
   6864   }
   6865   if (i < length) {
   6866     ASSERT(Smi::FromInt(0) == 0);
   6867     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
   6868   }
   6869 #ifdef DEBUG
   6870   for (int j = 0; j < length; ++j) {
   6871     Object* element = elements->get(j);
   6872     ASSERT(element == Smi::FromInt(0) ||
   6873            (element->IsString() && String::cast(element)->LooksValid()));
   6874   }
   6875 #endif
   6876   return i;
   6877 }
   6878 
   6879 
   6880 // Converts a String to JSArray.
   6881 // For example, "foo" => ["f", "o", "o"].
   6882 RUNTIME_FUNCTION(Runtime_StringToArray) {
   6883   HandleScope scope(isolate);
   6884   ASSERT(args.length() == 2);
   6885   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6886   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   6887 
   6888   s = String::Flatten(s);
   6889   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
   6890 
   6891   Handle<FixedArray> elements;
   6892   int position = 0;
   6893   if (s->IsFlat() && s->IsOneByteRepresentation()) {
   6894     // Try using cached chars where possible.
   6895     elements = isolate->factory()->NewUninitializedFixedArray(length);
   6896 
   6897     DisallowHeapAllocation no_gc;
   6898     String::FlatContent content = s->GetFlatContent();
   6899     if (content.IsAscii()) {
   6900       Vector<const uint8_t> chars = content.ToOneByteVector();
   6901       // Note, this will initialize all elements (not only the prefix)
   6902       // to prevent GC from seeing partially initialized array.
   6903       position = CopyCachedAsciiCharsToArray(isolate->heap(),
   6904                                              chars.start(),
   6905                                              *elements,
   6906                                              length);
   6907     } else {
   6908       MemsetPointer(elements->data_start(),
   6909                     isolate->heap()->undefined_value(),
   6910                     length);
   6911     }
   6912   } else {
   6913     elements = isolate->factory()->NewFixedArray(length);
   6914   }
   6915   for (int i = position; i < length; ++i) {
   6916     Handle<Object> str =
   6917         isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
   6918     elements->set(i, *str);
   6919   }
   6920 
   6921 #ifdef DEBUG
   6922   for (int i = 0; i < length; ++i) {
   6923     ASSERT(String::cast(elements->get(i))->length() == 1);
   6924   }
   6925 #endif
   6926 
   6927   return *isolate->factory()->NewJSArrayWithElements(elements);
   6928 }
   6929 
   6930 
   6931 RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
   6932   HandleScope scope(isolate);
   6933   ASSERT(args.length() == 1);
   6934   CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
   6935   return *Object::ToObject(isolate, value).ToHandleChecked();
   6936 }
   6937 
   6938 
   6939 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
   6940   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
   6941   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
   6942   return char_length == 0;
   6943 }
   6944 
   6945 
   6946 RUNTIME_FUNCTION(RuntimeHidden_NumberToString) {
   6947   HandleScope scope(isolate);
   6948   ASSERT(args.length() == 1);
   6949   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
   6950 
   6951   return *isolate->factory()->NumberToString(number);
   6952 }
   6953 
   6954 
   6955 RUNTIME_FUNCTION(RuntimeHidden_NumberToStringSkipCache) {
   6956   HandleScope scope(isolate);
   6957   ASSERT(args.length() == 1);
   6958   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
   6959 
   6960   return *isolate->factory()->NumberToString(number, false);
   6961 }
   6962 
   6963 
   6964 RUNTIME_FUNCTION(Runtime_NumberToInteger) {
   6965   HandleScope scope(isolate);
   6966   ASSERT(args.length() == 1);
   6967 
   6968   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6969   return *isolate->factory()->NewNumber(DoubleToInteger(number));
   6970 }
   6971 
   6972 
   6973 RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
   6974   HandleScope scope(isolate);
   6975   ASSERT(args.length() == 1);
   6976 
   6977   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6978   double double_value = DoubleToInteger(number);
   6979   // Map both -0 and +0 to +0.
   6980   if (double_value == 0) double_value = 0;
   6981 
   6982   return *isolate->factory()->NewNumber(double_value);
   6983 }
   6984 
   6985 
   6986 RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
   6987   HandleScope scope(isolate);
   6988   ASSERT(args.length() == 1);
   6989 
   6990   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
   6991   return *isolate->factory()->NewNumberFromUint(number);
   6992 }
   6993 
   6994 
   6995 RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
   6996   HandleScope scope(isolate);
   6997   ASSERT(args.length() == 1);
   6998 
   6999   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   7000   return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
   7001 }
   7002 
   7003 
   7004 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
   7005 // a small integer.
   7006 RUNTIME_FUNCTION(RuntimeHidden_NumberToSmi) {
   7007   SealHandleScope shs(isolate);
   7008   ASSERT(args.length() == 1);
   7009   CONVERT_ARG_CHECKED(Object, obj, 0);
   7010   if (obj->IsSmi()) {
   7011     return obj;
   7012   }
   7013   if (obj->IsHeapNumber()) {
   7014     double value = HeapNumber::cast(obj)->value();
   7015     int int_value = FastD2I(value);
   7016     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
   7017       return Smi::FromInt(int_value);
   7018     }
   7019   }
   7020   return isolate->heap()->nan_value();
   7021 }
   7022 
   7023 
   7024 RUNTIME_FUNCTION(RuntimeHidden_AllocateHeapNumber) {
   7025   HandleScope scope(isolate);
   7026   ASSERT(args.length() == 0);
   7027   return *isolate->factory()->NewHeapNumber(0);
   7028 }
   7029 
   7030 
   7031 RUNTIME_FUNCTION(Runtime_NumberAdd) {
   7032   HandleScope scope(isolate);
   7033   ASSERT(args.length() == 2);
   7034 
   7035   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7036   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7037   return *isolate->factory()->NewNumber(x + y);
   7038 }
   7039 
   7040 
   7041 RUNTIME_FUNCTION(Runtime_NumberSub) {
   7042   HandleScope scope(isolate);
   7043   ASSERT(args.length() == 2);
   7044 
   7045   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7046   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7047   return *isolate->factory()->NewNumber(x - y);
   7048 }
   7049 
   7050 
   7051 RUNTIME_FUNCTION(Runtime_NumberMul) {
   7052   HandleScope scope(isolate);
   7053   ASSERT(args.length() == 2);
   7054 
   7055   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7056   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7057   return *isolate->factory()->NewNumber(x * y);
   7058 }
   7059 
   7060 
   7061 RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
   7062   HandleScope scope(isolate);
   7063   ASSERT(args.length() == 1);
   7064 
   7065   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7066   return *isolate->factory()->NewNumber(-x);
   7067 }
   7068 
   7069 
   7070 RUNTIME_FUNCTION(Runtime_NumberDiv) {
   7071   HandleScope scope(isolate);
   7072   ASSERT(args.length() == 2);
   7073 
   7074   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7075   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7076   return *isolate->factory()->NewNumber(x / y);
   7077 }
   7078 
   7079 
   7080 RUNTIME_FUNCTION(Runtime_NumberMod) {
   7081   HandleScope scope(isolate);
   7082   ASSERT(args.length() == 2);
   7083 
   7084   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7085   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7086   return *isolate->factory()->NewNumber(modulo(x, y));
   7087 }
   7088 
   7089 
   7090 RUNTIME_FUNCTION(Runtime_NumberImul) {
   7091   HandleScope scope(isolate);
   7092   ASSERT(args.length() == 2);
   7093 
   7094   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7095   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7096   return *isolate->factory()->NewNumberFromInt(x * y);
   7097 }
   7098 
   7099 
   7100 RUNTIME_FUNCTION(RuntimeHidden_StringAdd) {
   7101   HandleScope scope(isolate);
   7102   ASSERT(args.length() == 2);
   7103   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
   7104   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
   7105   isolate->counters()->string_add_runtime()->Increment();
   7106   Handle<String> result;
   7107   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7108       isolate, result, isolate->factory()->NewConsString(str1, str2));
   7109   return *result;
   7110 }
   7111 
   7112 
   7113 template <typename sinkchar>
   7114 static inline void StringBuilderConcatHelper(String* special,
   7115                                              sinkchar* sink,
   7116                                              FixedArray* fixed_array,
   7117                                              int array_length) {
   7118   DisallowHeapAllocation no_gc;
   7119   int position = 0;
   7120   for (int i = 0; i < array_length; i++) {
   7121     Object* element = fixed_array->get(i);
   7122     if (element->IsSmi()) {
   7123       // Smi encoding of position and length.
   7124       int encoded_slice = Smi::cast(element)->value();
   7125       int pos;
   7126       int len;
   7127       if (encoded_slice > 0) {
   7128         // Position and length encoded in one smi.
   7129         pos = StringBuilderSubstringPosition::decode(encoded_slice);
   7130         len = StringBuilderSubstringLength::decode(encoded_slice);
   7131       } else {
   7132         // Position and length encoded in two smis.
   7133         Object* obj = fixed_array->get(++i);
   7134         ASSERT(obj->IsSmi());
   7135         pos = Smi::cast(obj)->value();
   7136         len = -encoded_slice;
   7137       }
   7138       String::WriteToFlat(special,
   7139                           sink + position,
   7140                           pos,
   7141                           pos + len);
   7142       position += len;
   7143     } else {
   7144       String* string = String::cast(element);
   7145       int element_length = string->length();
   7146       String::WriteToFlat(string, sink + position, 0, element_length);
   7147       position += element_length;
   7148     }
   7149   }
   7150 }
   7151 
   7152 
   7153 // Returns the result length of the concatenation.
   7154 // On illegal argument, -1 is returned.
   7155 static inline int StringBuilderConcatLength(int special_length,
   7156                                             FixedArray* fixed_array,
   7157                                             int array_length,
   7158                                             bool* one_byte) {
   7159   DisallowHeapAllocation no_gc;
   7160   int position = 0;
   7161   for (int i = 0; i < array_length; i++) {
   7162     int increment = 0;
   7163     Object* elt = fixed_array->get(i);
   7164     if (elt->IsSmi()) {
   7165       // Smi encoding of position and length.
   7166       int smi_value = Smi::cast(elt)->value();
   7167       int pos;
   7168       int len;
   7169       if (smi_value > 0) {
   7170         // Position and length encoded in one smi.
   7171         pos = StringBuilderSubstringPosition::decode(smi_value);
   7172         len = StringBuilderSubstringLength::decode(smi_value);
   7173       } else {
   7174         // Position and length encoded in two smis.
   7175         len = -smi_value;
   7176         // Get the position and check that it is a positive smi.
   7177         i++;
   7178         if (i >= array_length) return -1;
   7179         Object* next_smi = fixed_array->get(i);
   7180         if (!next_smi->IsSmi()) return -1;
   7181         pos = Smi::cast(next_smi)->value();
   7182         if (pos < 0) return -1;
   7183       }
   7184       ASSERT(pos >= 0);
   7185       ASSERT(len >= 0);
   7186       if (pos > special_length || len > special_length - pos) return -1;
   7187       increment = len;
   7188     } else if (elt->IsString()) {
   7189       String* element = String::cast(elt);
   7190       int element_length = element->length();
   7191       increment = element_length;
   7192       if (*one_byte && !element->HasOnlyOneByteChars()) {
   7193         *one_byte = false;
   7194       }
   7195     } else {
   7196       return -1;
   7197     }
   7198     if (increment > String::kMaxLength - position) {
   7199       return kMaxInt;  // Provoke throw on allocation.
   7200     }
   7201     position += increment;
   7202   }
   7203   return position;
   7204 }
   7205 
   7206 
   7207 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
   7208   HandleScope scope(isolate);
   7209   ASSERT(args.length() == 3);
   7210   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   7211   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
   7212   CONVERT_SMI_ARG_CHECKED(array_length, 1);
   7213   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
   7214 
   7215   size_t actual_array_length = 0;
   7216   RUNTIME_ASSERT(
   7217       TryNumberToSize(isolate, array->length(), &actual_array_length));
   7218   RUNTIME_ASSERT(array_length >= 0);
   7219   RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
   7220 
   7221   // This assumption is used by the slice encoding in one or two smis.
   7222   ASSERT(Smi::kMaxValue >= String::kMaxLength);
   7223 
   7224   RUNTIME_ASSERT(array->HasFastElements());
   7225   JSObject::EnsureCanContainHeapObjectElements(array);
   7226 
   7227   int special_length = special->length();
   7228   if (!array->HasFastObjectElements()) {
   7229     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7230   }
   7231 
   7232   int length;
   7233   bool one_byte = special->HasOnlyOneByteChars();
   7234 
   7235   { DisallowHeapAllocation no_gc;
   7236     FixedArray* fixed_array = FixedArray::cast(array->elements());
   7237     if (fixed_array->length() < array_length) {
   7238       array_length = fixed_array->length();
   7239     }
   7240 
   7241     if (array_length == 0) {
   7242       return isolate->heap()->empty_string();
   7243     } else if (array_length == 1) {
   7244       Object* first = fixed_array->get(0);
   7245       if (first->IsString()) return first;
   7246     }
   7247     length = StringBuilderConcatLength(
   7248         special_length, fixed_array, array_length, &one_byte);
   7249   }
   7250 
   7251   if (length == -1) {
   7252     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7253   }
   7254 
   7255   if (one_byte) {
   7256     Handle<SeqOneByteString> answer;
   7257     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7258         isolate, answer,
   7259         isolate->factory()->NewRawOneByteString(length));
   7260     StringBuilderConcatHelper(*special,
   7261                               answer->GetChars(),
   7262                               FixedArray::cast(array->elements()),
   7263                               array_length);
   7264     return *answer;
   7265   } else {
   7266     Handle<SeqTwoByteString> answer;
   7267     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7268         isolate, answer,
   7269         isolate->factory()->NewRawTwoByteString(length));
   7270     StringBuilderConcatHelper(*special,
   7271                               answer->GetChars(),
   7272                               FixedArray::cast(array->elements()),
   7273                               array_length);
   7274     return *answer;
   7275   }
   7276 }
   7277 
   7278 
   7279 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
   7280   HandleScope scope(isolate);
   7281   ASSERT(args.length() == 3);
   7282   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   7283   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
   7284   CONVERT_SMI_ARG_CHECKED(array_length, 1);
   7285   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
   7286   RUNTIME_ASSERT(array->HasFastObjectElements());
   7287   RUNTIME_ASSERT(array_length >= 0);
   7288 
   7289   Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
   7290   if (fixed_array->length() < array_length) {
   7291     array_length = fixed_array->length();
   7292   }
   7293 
   7294   if (array_length == 0) {
   7295     return isolate->heap()->empty_string();
   7296   } else if (array_length == 1) {
   7297     Object* first = fixed_array->get(0);
   7298     RUNTIME_ASSERT(first->IsString());
   7299     return first;
   7300   }
   7301 
   7302   int separator_length = separator->length();
   7303   RUNTIME_ASSERT(separator_length > 0);
   7304   int max_nof_separators =
   7305       (String::kMaxLength + separator_length - 1) / separator_length;
   7306   if (max_nof_separators < (array_length - 1)) {
   7307     return isolate->ThrowInvalidStringLength();
   7308   }
   7309   int length = (array_length - 1) * separator_length;
   7310   for (int i = 0; i < array_length; i++) {
   7311     Object* element_obj = fixed_array->get(i);
   7312     RUNTIME_ASSERT(element_obj->IsString());
   7313     String* element = String::cast(element_obj);
   7314     int increment = element->length();
   7315     if (increment > String::kMaxLength - length) {
   7316       STATIC_ASSERT(String::kMaxLength < kMaxInt);
   7317       length = kMaxInt;  // Provoke exception;
   7318       break;
   7319     }
   7320     length += increment;
   7321   }
   7322 
   7323   Handle<SeqTwoByteString> answer;
   7324   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   7325       isolate, answer,
   7326       isolate->factory()->NewRawTwoByteString(length));
   7327 
   7328   DisallowHeapAllocation no_gc;
   7329 
   7330   uc16* sink = answer->GetChars();
   7331 #ifdef DEBUG
   7332   uc16* end = sink + length;
   7333 #endif
   7334 
   7335   RUNTIME_ASSERT(fixed_array->get(0)->IsString());
   7336   String* first = String::cast(fixed_array->get(0));
   7337   String* separator_raw = *separator;
   7338   int first_length = first->length();
   7339   String::WriteToFlat(first, sink, 0, first_length);
   7340   sink += first_length;
   7341 
   7342   for (int i = 1; i < array_length; i++) {
   7343     ASSERT(sink + separator_length <= end);
   7344     String::WriteToFlat(separator_raw, sink, 0, separator_length);
   7345     sink += separator_length;
   7346 
   7347     RUNTIME_ASSERT(fixed_array->get(i)->IsString());
   7348     String* element = String::cast(fixed_array->get(i));
   7349     int element_length = element->length();
   7350     ASSERT(sink + element_length <= end);
   7351     String::WriteToFlat(element, sink, 0, element_length);
   7352     sink += element_length;
   7353   }
   7354   ASSERT(sink == end);
   7355 
   7356   // Use %_FastAsciiArrayJoin instead.
   7357   ASSERT(!answer->IsOneByteRepresentation());
   7358   return *answer;
   7359 }
   7360 
   7361 template <typename Char>
   7362 static void JoinSparseArrayWithSeparator(FixedArray* elements,
   7363                                          int elements_length,
   7364                                          uint32_t array_length,
   7365                                          String* separator,
   7366                                          Vector<Char> buffer) {
   7367   DisallowHeapAllocation no_gc;
   7368   int previous_separator_position = 0;
   7369   int separator_length = separator->length();
   7370   int cursor = 0;
   7371   for (int i = 0; i < elements_length; i += 2) {
   7372     int position = NumberToInt32(elements->get(i));
   7373     String* string = String::cast(elements->get(i + 1));
   7374     int string_length = string->length();
   7375     if (string->length() > 0) {
   7376       while (previous_separator_position < position) {
   7377         String::WriteToFlat<Char>(separator, &buffer[cursor],
   7378                                   0, separator_length);
   7379         cursor += separator_length;
   7380         previous_separator_position++;
   7381       }
   7382       String::WriteToFlat<Char>(string, &buffer[cursor],
   7383                                 0, string_length);
   7384       cursor += string->length();
   7385     }
   7386   }
   7387   if (separator_length > 0) {
   7388     // Array length must be representable as a signed 32-bit number,
   7389     // otherwise the total string length would have been too large.
   7390     ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
   7391     int last_array_index = static_cast<int>(array_length - 1);
   7392     while (previous_separator_position < last_array_index) {
   7393       String::WriteToFlat<Char>(separator, &buffer[cursor],
   7394                                 0, separator_length);
   7395       cursor += separator_length;
   7396       previous_separator_position++;
   7397     }
   7398   }
   7399   ASSERT(cursor <= buffer.length());
   7400 }
   7401 
   7402 
   7403 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
   7404   HandleScope scope(isolate);
   7405   ASSERT(args.length() == 3);
   7406   CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
   7407   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
   7408   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
   7409   // elements_array is fast-mode JSarray of alternating positions
   7410   // (increasing order) and strings.
   7411   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
   7412   // array_length is length of original array (used to add separators);
   7413   // separator is string to put between elements. Assumed to be non-empty.
   7414   RUNTIME_ASSERT(array_length > 0);
   7415 
   7416   // Find total length of join result.
   7417   int string_length = 0;
   7418   bool is_ascii = separator->IsOneByteRepresentation();
   7419   bool overflow = false;
   7420   CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
   7421   RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
   7422   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
   7423   FixedArray* elements = FixedArray::cast(elements_array->elements());
   7424   for (int i = 0; i < elements_length; i += 2) {
   7425     RUNTIME_ASSERT(elements->get(i)->IsNumber());
   7426     CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
   7427     RUNTIME_ASSERT(position < array_length);
   7428     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
   7429   }
   7430 
   7431   { DisallowHeapAllocation no_gc;
   7432     for (int i = 0; i < elements_length; i += 2) {
   7433       String* string = String::cast(elements->get(i + 1));
   7434       int length = string->length();
   7435       if (is_ascii && !string->IsOneByteRepresentation()) {
   7436         is_ascii = false;
   7437       }
   7438       if (length > String::kMaxLength ||
   7439           String::kMaxLength - length < string_length) {
   7440         overflow = true;
   7441         break;
   7442       }
   7443       string_length += length;
   7444     }
   7445   }
   7446 
   7447   int separator_length = separator->length();
   7448   if (!overflow && separator_length > 0) {
   7449     if (array_length <= 0x7fffffffu) {
   7450       int separator_count = static_cast<int>(array_length) - 1;
   7451       int remaining_length = String::kMaxLength - string_length;
   7452       if ((remaining_length / separator_length) >= separator_count) {
   7453         string_length += separator_length * (array_length - 1);
   7454       } else {
   7455         // Not room for the separators within the maximal string length.
   7456         overflow = true;
   7457       }
   7458     } else {
   7459       // Nonempty separator and at least 2^31-1 separators necessary
   7460       // means that the string is too large to create.
   7461       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
   7462       overflow = true;
   7463     }
   7464   }
   7465   if (overflow) {
   7466     // Throw an exception if the resulting string is too large. See
   7467     // https://code.google.com/p/chromium/issues/detail?id=336820
   7468     // for details.
   7469     return isolate->ThrowInvalidStringLength();
   7470   }
   7471 
   7472   if (is_ascii) {
   7473     Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
   7474         string_length).ToHandleChecked();
   7475     JoinSparseArrayWithSeparator<uint8_t>(
   7476         FixedArray::cast(elements_array->elements()),
   7477         elements_length,
   7478         array_length,
   7479         *separator,
   7480         Vector<uint8_t>(result->GetChars(), string_length));
   7481     return *result;
   7482   } else {
   7483     Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
   7484         string_length).ToHandleChecked();
   7485     JoinSparseArrayWithSeparator<uc16>(
   7486         FixedArray::cast(elements_array->elements()),
   7487         elements_length,
   7488         array_length,
   7489         *separator,
   7490         Vector<uc16>(result->GetChars(), string_length));
   7491     return *result;
   7492   }
   7493 }
   7494 
   7495 
   7496 RUNTIME_FUNCTION(Runtime_NumberOr) {
   7497   HandleScope scope(isolate);
   7498   ASSERT(args.length() == 2);
   7499 
   7500   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7501   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7502   return *isolate->factory()->NewNumberFromInt(x | y);
   7503 }
   7504 
   7505 
   7506 RUNTIME_FUNCTION(Runtime_NumberAnd) {
   7507   HandleScope scope(isolate);
   7508   ASSERT(args.length() == 2);
   7509 
   7510   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7511   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7512   return *isolate->factory()->NewNumberFromInt(x & y);
   7513 }
   7514 
   7515 
   7516 RUNTIME_FUNCTION(Runtime_NumberXor) {
   7517   HandleScope scope(isolate);
   7518   ASSERT(args.length() == 2);
   7519 
   7520   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7521   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7522   return *isolate->factory()->NewNumberFromInt(x ^ y);
   7523 }
   7524 
   7525 
   7526 RUNTIME_FUNCTION(Runtime_NumberShl) {
   7527   HandleScope scope(isolate);
   7528   ASSERT(args.length() == 2);
   7529 
   7530   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7531   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7532   return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
   7533 }
   7534 
   7535 
   7536 RUNTIME_FUNCTION(Runtime_NumberShr) {
   7537   HandleScope scope(isolate);
   7538   ASSERT(args.length() == 2);
   7539 
   7540   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
   7541   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7542   return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
   7543 }
   7544 
   7545 
   7546 RUNTIME_FUNCTION(Runtime_NumberSar) {
   7547   HandleScope scope(isolate);
   7548   ASSERT(args.length() == 2);
   7549 
   7550   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7551   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7552   return *isolate->factory()->NewNumberFromInt(
   7553       ArithmeticShiftRight(x, y & 0x1f));
   7554 }
   7555 
   7556 
   7557 RUNTIME_FUNCTION(Runtime_NumberEquals) {
   7558   SealHandleScope shs(isolate);
   7559   ASSERT(args.length() == 2);
   7560 
   7561   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7562   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7563   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
   7564   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
   7565   if (x == y) return Smi::FromInt(EQUAL);
   7566   Object* result;
   7567   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
   7568     result = Smi::FromInt(EQUAL);
   7569   } else {
   7570     result = Smi::FromInt(NOT_EQUAL);
   7571   }
   7572   return result;
   7573 }
   7574 
   7575 
   7576 RUNTIME_FUNCTION(Runtime_StringEquals) {
   7577   HandleScope handle_scope(isolate);
   7578   ASSERT(args.length() == 2);
   7579 
   7580   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
   7581   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
   7582 
   7583   bool not_equal = !String::Equals(x, y);
   7584   // This is slightly convoluted because the value that signifies
   7585   // equality is 0 and inequality is 1 so we have to negate the result
   7586   // from String::Equals.
   7587   ASSERT(not_equal == 0 || not_equal == 1);
   7588   STATIC_ASSERT(EQUAL == 0);
   7589   STATIC_ASSERT(NOT_EQUAL == 1);
   7590   return Smi::FromInt(not_equal);
   7591 }
   7592 
   7593 
   7594 RUNTIME_FUNCTION(Runtime_NumberCompare) {
   7595   SealHandleScope shs(isolate);
   7596   ASSERT(args.length() == 3);
   7597 
   7598   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7599   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7600   CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
   7601   if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
   7602   if (x == y) return Smi::FromInt(EQUAL);
   7603   if (isless(x, y)) return Smi::FromInt(LESS);
   7604   return Smi::FromInt(GREATER);
   7605 }
   7606 
   7607 
   7608 // Compare two Smis as if they were converted to strings and then
   7609 // compared lexicographically.
   7610 RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
   7611   SealHandleScope shs(isolate);
   7612   ASSERT(args.length() == 2);
   7613   CONVERT_SMI_ARG_CHECKED(x_value, 0);
   7614   CONVERT_SMI_ARG_CHECKED(y_value, 1);
   7615 
   7616   // If the integers are equal so are the string representations.
   7617   if (x_value == y_value) return Smi::FromInt(EQUAL);
   7618 
   7619   // If one of the integers is zero the normal integer order is the
   7620   // same as the lexicographic order of the string representations.
   7621   if (x_value == 0 || y_value == 0)
   7622     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
   7623 
   7624   // If only one of the integers is negative the negative number is
   7625   // smallest because the char code of '-' is less than the char code
   7626   // of any digit.  Otherwise, we make both values positive.
   7627 
   7628   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
   7629   // architectures using 32-bit Smis.
   7630   uint32_t x_scaled = x_value;
   7631   uint32_t y_scaled = y_value;
   7632   if (x_value < 0 || y_value < 0) {
   7633     if (y_value >= 0) return Smi::FromInt(LESS);
   7634     if (x_value >= 0) return Smi::FromInt(GREATER);
   7635     x_scaled = -x_value;
   7636     y_scaled = -y_value;
   7637   }
   7638 
   7639   static const uint32_t kPowersOf10[] = {
   7640     1, 10, 100, 1000, 10*1000, 100*1000,
   7641     1000*1000, 10*1000*1000, 100*1000*1000,
   7642     1000*1000*1000
   7643   };
   7644 
   7645   // If the integers have the same number of decimal digits they can be
   7646   // compared directly as the numeric order is the same as the
   7647   // lexicographic order.  If one integer has fewer digits, it is scaled
   7648   // by some power of 10 to have the same number of digits as the longer
   7649   // integer.  If the scaled integers are equal it means the shorter
   7650   // integer comes first in the lexicographic order.
   7651 
   7652   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
   7653   int x_log2 = IntegerLog2(x_scaled);
   7654   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
   7655   x_log10 -= x_scaled < kPowersOf10[x_log10];
   7656 
   7657   int y_log2 = IntegerLog2(y_scaled);
   7658   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
   7659   y_log10 -= y_scaled < kPowersOf10[y_log10];
   7660 
   7661   int tie = EQUAL;
   7662 
   7663   if (x_log10 < y_log10) {
   7664     // X has fewer digits.  We would like to simply scale up X but that
   7665     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
   7666     // be scaled up to 9_000_000_000. So we scale up by the next
   7667     // smallest power and scale down Y to drop one digit. It is OK to
   7668     // drop one digit from the longer integer since the final digit is
   7669     // past the length of the shorter integer.
   7670     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
   7671     y_scaled /= 10;
   7672     tie = LESS;
   7673   } else if (y_log10 < x_log10) {
   7674     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
   7675     x_scaled /= 10;
   7676     tie = GREATER;
   7677   }
   7678 
   7679   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
   7680   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
   7681   return Smi::FromInt(tie);
   7682 }
   7683 
   7684 
   7685 RUNTIME_FUNCTION(RuntimeHidden_StringCompare) {
   7686   HandleScope handle_scope(isolate);
   7687   ASSERT(args.length() == 2);
   7688 
   7689   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
   7690   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
   7691 
   7692   isolate->counters()->string_compare_runtime()->Increment();
   7693 
   7694   // A few fast case tests before we flatten.
   7695   if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
   7696   if (y->length() == 0) {
   7697     if (x->length() == 0) return Smi::FromInt(EQUAL);
   7698     return Smi::FromInt(GREATER);
   7699   } else if (x->length() == 0) {
   7700     return Smi::FromInt(LESS);
   7701   }
   7702 
   7703   int d = x->Get(0) - y->Get(0);
   7704   if (d < 0) return Smi::FromInt(LESS);
   7705   else if (d > 0) return Smi::FromInt(GREATER);
   7706 
   7707   // Slow case.
   7708   x = String::Flatten(x);
   7709   y = String::Flatten(y);
   7710 
   7711   DisallowHeapAllocation no_gc;
   7712   Object* equal_prefix_result = Smi::FromInt(EQUAL);
   7713   int prefix_length = x->length();
   7714   if (y->length() < prefix_length) {
   7715     prefix_length = y->length();
   7716     equal_prefix_result = Smi::FromInt(GREATER);
   7717   } else if (y->length() > prefix_length) {
   7718     equal_prefix_result = Smi::FromInt(LESS);
   7719   }
   7720   int r;
   7721   String::FlatContent x_content = x->GetFlatContent();
   7722   String::FlatContent y_content = y->GetFlatContent();
   7723   if (x_content.IsAscii()) {
   7724     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   7725     if (y_content.IsAscii()) {
   7726       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7727       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7728     } else {
   7729       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7730       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7731     }
   7732   } else {
   7733     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   7734     if (y_content.IsAscii()) {
   7735       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7736       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7737     } else {
   7738       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7739       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7740     }
   7741   }
   7742   Object* result;
   7743   if (r == 0) {
   7744     result = equal_prefix_result;
   7745   } else {
   7746     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
   7747   }
   7748   return result;
   7749 }
   7750 
   7751 
   7752 #define RUNTIME_UNARY_MATH(Name, name)                                         \
   7753 RUNTIME_FUNCTION(Runtime_Math##Name) {                           \
   7754   HandleScope scope(isolate);                                                  \
   7755   ASSERT(args.length() == 1);                                                  \
   7756   isolate->counters()->math_##name()->Increment();                             \
   7757   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
   7758   return *isolate->factory()->NewHeapNumber(std::name(x));                     \
   7759 }
   7760 
   7761 RUNTIME_UNARY_MATH(Acos, acos)
   7762 RUNTIME_UNARY_MATH(Asin, asin)
   7763 RUNTIME_UNARY_MATH(Atan, atan)
   7764 RUNTIME_UNARY_MATH(LogRT, log)
   7765 #undef RUNTIME_UNARY_MATH
   7766 
   7767 
   7768 RUNTIME_FUNCTION(Runtime_DoubleHi) {
   7769   HandleScope scope(isolate);
   7770   ASSERT(args.length() == 1);
   7771   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7772   uint64_t integer = double_to_uint64(x);
   7773   integer = (integer >> 32) & 0xFFFFFFFFu;
   7774   return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
   7775 }
   7776 
   7777 
   7778 RUNTIME_FUNCTION(Runtime_DoubleLo) {
   7779   HandleScope scope(isolate);
   7780   ASSERT(args.length() == 1);
   7781   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7782   return *isolate->factory()->NewNumber(
   7783       static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
   7784 }
   7785 
   7786 
   7787 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
   7788   HandleScope scope(isolate);
   7789   ASSERT(args.length() == 2);
   7790   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
   7791   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
   7792   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
   7793   return *isolate->factory()->NewNumber(uint64_to_double(result));
   7794 }
   7795 
   7796 
   7797 static const double kPiDividedBy4 = 0.78539816339744830962;
   7798 
   7799 
   7800 RUNTIME_FUNCTION(Runtime_MathAtan2) {
   7801   HandleScope scope(isolate);
   7802   ASSERT(args.length() == 2);
   7803   isolate->counters()->math_atan2()->Increment();
   7804 
   7805   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7806   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7807   double result;
   7808   if (std::isinf(x) && std::isinf(y)) {
   7809     // Make sure that the result in case of two infinite arguments
   7810     // is a multiple of Pi / 4. The sign of the result is determined
   7811     // by the first argument (x) and the sign of the second argument
   7812     // determines the multiplier: one or three.
   7813     int multiplier = (x < 0) ? -1 : 1;
   7814     if (y < 0) multiplier *= 3;
   7815     result = multiplier * kPiDividedBy4;
   7816   } else {
   7817     result = std::atan2(x, y);
   7818   }
   7819   return *isolate->factory()->NewNumber(result);
   7820 }
   7821 
   7822 
   7823 RUNTIME_FUNCTION(Runtime_MathExpRT) {
   7824   HandleScope scope(isolate);
   7825   ASSERT(args.length() == 1);
   7826   isolate->counters()->math_exp()->Increment();
   7827 
   7828   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7829   lazily_initialize_fast_exp();
   7830   return *isolate->factory()->NewNumber(fast_exp(x));
   7831 }
   7832 
   7833 
   7834 RUNTIME_FUNCTION(Runtime_MathFloorRT) {
   7835   HandleScope scope(isolate);
   7836   ASSERT(args.length() == 1);
   7837   isolate->counters()->math_floor()->Increment();
   7838 
   7839   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7840   return *isolate->factory()->NewNumber(std::floor(x));
   7841 }
   7842 
   7843 
   7844 // Slow version of Math.pow.  We check for fast paths for special cases.
   7845 // Used if VFP3 is not available.
   7846 RUNTIME_FUNCTION(RuntimeHidden_MathPowSlow) {
   7847   HandleScope scope(isolate);
   7848   ASSERT(args.length() == 2);
   7849   isolate->counters()->math_pow()->Increment();
   7850 
   7851   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7852 
   7853   // If the second argument is a smi, it is much faster to call the
   7854   // custom powi() function than the generic pow().
   7855   if (args[1]->IsSmi()) {
   7856     int y = args.smi_at(1);
   7857     return *isolate->factory()->NewNumber(power_double_int(x, y));
   7858   }
   7859 
   7860   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7861   double result = power_helper(x, y);
   7862   if (std::isnan(result)) return isolate->heap()->nan_value();
   7863   return *isolate->factory()->NewNumber(result);
   7864 }
   7865 
   7866 
   7867 // Fast version of Math.pow if we know that y is not an integer and y is not
   7868 // -0.5 or 0.5.  Used as slow case from full codegen.
   7869 RUNTIME_FUNCTION(RuntimeHidden_MathPow) {
   7870   HandleScope scope(isolate);
   7871   ASSERT(args.length() == 2);
   7872   isolate->counters()->math_pow()->Increment();
   7873 
   7874   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7875   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7876   if (y == 0) {
   7877     return Smi::FromInt(1);
   7878   } else {
   7879     double result = power_double_double(x, y);
   7880     if (std::isnan(result)) return isolate->heap()->nan_value();
   7881     return *isolate->factory()->NewNumber(result);
   7882   }
   7883 }
   7884 
   7885 
   7886 RUNTIME_FUNCTION(Runtime_RoundNumber) {
   7887   HandleScope scope(isolate);
   7888   ASSERT(args.length() == 1);
   7889   CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
   7890   isolate->counters()->math_round()->Increment();
   7891 
   7892   if (!input->IsHeapNumber()) {
   7893     ASSERT(input->IsSmi());
   7894     return *input;
   7895   }
   7896 
   7897   Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
   7898 
   7899   double value = number->value();
   7900   int exponent = number->get_exponent();
   7901   int sign = number->get_sign();
   7902 
   7903   if (exponent < -1) {
   7904     // Number in range ]-0.5..0.5[. These always round to +/-zero.
   7905     if (sign) return isolate->heap()->minus_zero_value();
   7906     return Smi::FromInt(0);
   7907   }
   7908 
   7909   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
   7910   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
   7911   // argument holds for 32-bit smis).
   7912   if (!sign && exponent < kSmiValueSize - 2) {
   7913     return Smi::FromInt(static_cast<int>(value + 0.5));
   7914   }
   7915 
   7916   // If the magnitude is big enough, there's no place for fraction part. If we
   7917   // try to add 0.5 to this number, 1.0 will be added instead.
   7918   if (exponent >= 52) {
   7919     return *number;
   7920   }
   7921 
   7922   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
   7923 
   7924   // Do not call NumberFromDouble() to avoid extra checks.
   7925   return *isolate->factory()->NewNumber(std::floor(value + 0.5));
   7926 }
   7927 
   7928 
   7929 RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
   7930   HandleScope scope(isolate);
   7931   ASSERT(args.length() == 1);
   7932   isolate->counters()->math_sqrt()->Increment();
   7933 
   7934   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7935   return *isolate->factory()->NewNumber(fast_sqrt(x));
   7936 }
   7937 
   7938 
   7939 RUNTIME_FUNCTION(Runtime_MathFround) {
   7940   HandleScope scope(isolate);
   7941   ASSERT(args.length() == 1);
   7942 
   7943   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7944   float xf = static_cast<float>(x);
   7945   return *isolate->factory()->NewNumber(xf);
   7946 }
   7947 
   7948 
   7949 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
   7950   SealHandleScope shs(isolate);
   7951   ASSERT(args.length() == 2);
   7952 
   7953   CONVERT_SMI_ARG_CHECKED(year, 0);
   7954   CONVERT_SMI_ARG_CHECKED(month, 1);
   7955 
   7956   int days = isolate->date_cache()->DaysFromYearMonth(year, month);
   7957   RUNTIME_ASSERT(Smi::IsValid(days));
   7958   return Smi::FromInt(days);
   7959 }
   7960 
   7961 
   7962 RUNTIME_FUNCTION(Runtime_DateSetValue) {
   7963   HandleScope scope(isolate);
   7964   ASSERT(args.length() == 3);
   7965 
   7966   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
   7967   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
   7968   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
   7969 
   7970   DateCache* date_cache = isolate->date_cache();
   7971 
   7972   Handle<Object> value;;
   7973   bool is_value_nan = false;
   7974   if (std::isnan(time)) {
   7975     value = isolate->factory()->nan_value();
   7976     is_value_nan = true;
   7977   } else if (!is_utc &&
   7978              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
   7979               time > DateCache::kMaxTimeBeforeUTCInMs)) {
   7980     value = isolate->factory()->nan_value();
   7981     is_value_nan = true;
   7982   } else {
   7983     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
   7984     if (time < -DateCache::kMaxTimeInMs ||
   7985         time > DateCache::kMaxTimeInMs) {
   7986       value = isolate->factory()->nan_value();
   7987       is_value_nan = true;
   7988     } else  {
   7989       value = isolate->factory()->NewNumber(DoubleToInteger(time));
   7990     }
   7991   }
   7992   date->SetValue(*value, is_value_nan);
   7993   return *value;
   7994 }
   7995 
   7996 
   7997 RUNTIME_FUNCTION(RuntimeHidden_NewSloppyArguments) {
   7998   HandleScope scope(isolate);
   7999   ASSERT(args.length() == 3);
   8000 
   8001   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
   8002   Object** parameters = reinterpret_cast<Object**>(args[1]);
   8003   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
   8004 
   8005   Handle<JSObject> result =
   8006       isolate->factory()->NewArgumentsObject(callee, argument_count);
   8007   // Allocate the elements if needed.
   8008   int parameter_count = callee->shared()->formal_parameter_count();
   8009   if (argument_count > 0) {
   8010     if (parameter_count > 0) {
   8011       int mapped_count = Min(argument_count, parameter_count);
   8012       Handle<FixedArray> parameter_map =
   8013           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
   8014       parameter_map->set_map(
   8015           isolate->heap()->sloppy_arguments_elements_map());
   8016 
   8017       Handle<Map> map = Map::Copy(handle(result->map()));
   8018       map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
   8019 
   8020       result->set_map(*map);
   8021       result->set_elements(*parameter_map);
   8022 
   8023       // Store the context and the arguments array at the beginning of the
   8024       // parameter map.
   8025       Handle<Context> context(isolate->context());
   8026       Handle<FixedArray> arguments =
   8027           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   8028       parameter_map->set(0, *context);
   8029       parameter_map->set(1, *arguments);
   8030 
   8031       // Loop over the actual parameters backwards.
   8032       int index = argument_count - 1;
   8033       while (index >= mapped_count) {
   8034         // These go directly in the arguments array and have no
   8035         // corresponding slot in the parameter map.
   8036         arguments->set(index, *(parameters - index - 1));
   8037         --index;
   8038       }
   8039 
   8040       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
   8041       while (index >= 0) {
   8042         // Detect duplicate names to the right in the parameter list.
   8043         Handle<String> name(scope_info->ParameterName(index));
   8044         int context_local_count = scope_info->ContextLocalCount();
   8045         bool duplicate = false;
   8046         for (int j = index + 1; j < parameter_count; ++j) {
   8047           if (scope_info->ParameterName(j) == *name) {
   8048             duplicate = true;
   8049             break;
   8050           }
   8051         }
   8052 
   8053         if (duplicate) {
   8054           // This goes directly in the arguments array with a hole in the
   8055           // parameter map.
   8056           arguments->set(index, *(parameters - index - 1));
   8057           parameter_map->set_the_hole(index + 2);
   8058         } else {
   8059           // The context index goes in the parameter map with a hole in the
   8060           // arguments array.
   8061           int context_index = -1;
   8062           for (int j = 0; j < context_local_count; ++j) {
   8063             if (scope_info->ContextLocalName(j) == *name) {
   8064               context_index = j;
   8065               break;
   8066             }
   8067           }
   8068           ASSERT(context_index >= 0);
   8069           arguments->set_the_hole(index);
   8070           parameter_map->set(index + 2, Smi::FromInt(
   8071               Context::MIN_CONTEXT_SLOTS + context_index));
   8072         }
   8073 
   8074         --index;
   8075       }
   8076     } else {
   8077       // If there is no aliasing, the arguments object elements are not
   8078       // special in any way.
   8079       Handle<FixedArray> elements =
   8080           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   8081       result->set_elements(*elements);
   8082       for (int i = 0; i < argument_count; ++i) {
   8083         elements->set(i, *(parameters - i - 1));
   8084       }
   8085     }
   8086   }
   8087   return *result;
   8088 }
   8089 
   8090 
   8091 RUNTIME_FUNCTION(RuntimeHidden_NewStrictArguments) {
   8092   HandleScope scope(isolate);
   8093   ASSERT(args.length() == 3);
   8094   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
   8095   Object** parameters = reinterpret_cast<Object**>(args[1]);
   8096   CONVERT_SMI_ARG_CHECKED(length, 2);
   8097 
   8098   Handle<JSObject> result =
   8099         isolate->factory()->NewArgumentsObject(callee, length);
   8100 
   8101   if (length > 0) {
   8102     Handle<FixedArray> array =
   8103         isolate->factory()->NewUninitializedFixedArray(length);
   8104     DisallowHeapAllocation no_gc;
   8105     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   8106     for (int i = 0; i < length; i++) {
   8107       array->set(i, *--parameters, mode);
   8108     }
   8109     result->set_elements(*array);
   8110   }
   8111   return *result;
   8112 }
   8113 
   8114 
   8115 RUNTIME_FUNCTION(RuntimeHidden_NewClosureFromStubFailure) {
   8116   HandleScope scope(isolate);
   8117   ASSERT(args.length() == 1);
   8118   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
   8119   Handle<Context> context(isolate->context());
   8120   PretenureFlag pretenure_flag = NOT_TENURED;
   8121   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
   8122       shared,  context, pretenure_flag);
   8123 }
   8124 
   8125 
   8126 RUNTIME_FUNCTION(RuntimeHidden_NewClosure) {
   8127   HandleScope scope(isolate);
   8128   ASSERT(args.length() == 3);
   8129   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   8130   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
   8131   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
   8132 
   8133   // The caller ensures that we pretenure closures that are assigned
   8134   // directly to properties.
   8135   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   8136   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
   8137       shared, context, pretenure_flag);
   8138 }
   8139 
   8140 
   8141 // Find the arguments of the JavaScript function invocation that called
   8142 // into C++ code. Collect these in a newly allocated array of handles (possibly
   8143 // prefixed by a number of empty handles).
   8144 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
   8145     Isolate* isolate,
   8146     int prefix_argc,
   8147     int* total_argc) {
   8148   // Find frame containing arguments passed to the caller.
   8149   JavaScriptFrameIterator it(isolate);
   8150   JavaScriptFrame* frame = it.frame();
   8151   List<JSFunction*> functions(2);
   8152   frame->GetFunctions(&functions);
   8153   if (functions.length() > 1) {
   8154     int inlined_jsframe_index = functions.length() - 1;
   8155     JSFunction* inlined_function = functions[inlined_jsframe_index];
   8156     SlotRefValueBuilder slot_refs(
   8157         frame,
   8158         inlined_jsframe_index,
   8159         inlined_function->shared()->formal_parameter_count());
   8160 
   8161     int args_count = slot_refs.args_length();
   8162 
   8163     *total_argc = prefix_argc + args_count;
   8164     SmartArrayPointer<Handle<Object> > param_data(
   8165         NewArray<Handle<Object> >(*total_argc));
   8166     slot_refs.Prepare(isolate);
   8167     for (int i = 0; i < args_count; i++) {
   8168       Handle<Object> val = slot_refs.GetNext(isolate, 0);
   8169       param_data[prefix_argc + i] = val;
   8170     }
   8171     slot_refs.Finish(isolate);
   8172 
   8173     return param_data;
   8174   } else {
   8175     it.AdvanceToArgumentsFrame();
   8176     frame = it.frame();
   8177     int args_count = frame->ComputeParametersCount();
   8178 
   8179     *total_argc = prefix_argc + args_count;
   8180     SmartArrayPointer<Handle<Object> > param_data(
   8181         NewArray<Handle<Object> >(*total_argc));
   8182     for (int i = 0; i < args_count; i++) {
   8183       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
   8184       param_data[prefix_argc + i] = val;
   8185     }
   8186     return param_data;
   8187   }
   8188 }
   8189 
   8190 
   8191 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
   8192   HandleScope scope(isolate);
   8193   ASSERT(args.length() == 4);
   8194   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
   8195   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
   8196   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
   8197   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
   8198 
   8199   // TODO(lrn): Create bound function in C++ code from premade shared info.
   8200   bound_function->shared()->set_bound(true);
   8201   // Get all arguments of calling function (Function.prototype.bind).
   8202   int argc = 0;
   8203   SmartArrayPointer<Handle<Object> > arguments =
   8204       GetCallerArguments(isolate, 0, &argc);
   8205   // Don't count the this-arg.
   8206   if (argc > 0) {
   8207     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
   8208     argc--;
   8209   } else {
   8210     RUNTIME_ASSERT(this_object->IsUndefined());
   8211   }
   8212   // Initialize array of bindings (function, this, and any existing arguments
   8213   // if the function was already bound).
   8214   Handle<FixedArray> new_bindings;
   8215   int i;
   8216   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
   8217     Handle<FixedArray> old_bindings(
   8218         JSFunction::cast(*bindee)->function_bindings());
   8219     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
   8220     new_bindings =
   8221         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
   8222     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
   8223                             isolate);
   8224     i = 0;
   8225     for (int n = old_bindings->length(); i < n; i++) {
   8226       new_bindings->set(i, old_bindings->get(i));
   8227     }
   8228   } else {
   8229     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
   8230     new_bindings = isolate->factory()->NewFixedArray(array_size);
   8231     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
   8232     new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
   8233     i = 2;
   8234   }
   8235   // Copy arguments, skipping the first which is "this_arg".
   8236   for (int j = 0; j < argc; j++, i++) {
   8237     new_bindings->set(i, *arguments[j + 1]);
   8238   }
   8239   new_bindings->set_map_no_write_barrier(
   8240       isolate->heap()->fixed_cow_array_map());
   8241   bound_function->set_function_bindings(*new_bindings);
   8242 
   8243   // Update length. Have to remove the prototype first so that map migration
   8244   // is happy about the number of fields.
   8245   RUNTIME_ASSERT(bound_function->RemovePrototype());
   8246   Handle<Map> bound_function_map(
   8247       isolate->native_context()->bound_function_map());
   8248   JSObject::MigrateToMap(bound_function, bound_function_map);
   8249   Handle<String> length_string = isolate->factory()->length_string();
   8250   PropertyAttributes attr =
   8251       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
   8252   RETURN_FAILURE_ON_EXCEPTION(
   8253       isolate,
   8254       JSObject::SetOwnPropertyIgnoreAttributes(bound_function, length_string,
   8255                                                new_length, attr));
   8256   return *bound_function;
   8257 }
   8258 
   8259 
   8260 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
   8261   HandleScope handles(isolate);
   8262   ASSERT(args.length() == 1);
   8263   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
   8264   if (callable->IsJSFunction()) {
   8265     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
   8266     if (function->shared()->bound()) {
   8267       Handle<FixedArray> bindings(function->function_bindings());
   8268       RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
   8269       return *isolate->factory()->NewJSArrayWithElements(bindings);
   8270     }
   8271   }
   8272   return isolate->heap()->undefined_value();
   8273 }
   8274 
   8275 
   8276 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
   8277   HandleScope scope(isolate);
   8278   ASSERT(args.length() == 1);
   8279   // First argument is a function to use as a constructor.
   8280   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8281   RUNTIME_ASSERT(function->shared()->bound());
   8282 
   8283   // The argument is a bound function. Extract its bound arguments
   8284   // and callable.
   8285   Handle<FixedArray> bound_args =
   8286       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
   8287   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
   8288   Handle<Object> bound_function(
   8289       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
   8290       isolate);
   8291   ASSERT(!bound_function->IsJSFunction() ||
   8292          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
   8293 
   8294   int total_argc = 0;
   8295   SmartArrayPointer<Handle<Object> > param_data =
   8296       GetCallerArguments(isolate, bound_argc, &total_argc);
   8297   for (int i = 0; i < bound_argc; i++) {
   8298     param_data[i] = Handle<Object>(bound_args->get(
   8299         JSFunction::kBoundArgumentsStartIndex + i), isolate);
   8300   }
   8301 
   8302   if (!bound_function->IsJSFunction()) {
   8303     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8304         isolate, bound_function,
   8305         Execution::TryGetConstructorDelegate(isolate, bound_function));
   8306   }
   8307   ASSERT(bound_function->IsJSFunction());
   8308 
   8309   Handle<Object> result;
   8310   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8311       isolate, result,
   8312       Execution::New(Handle<JSFunction>::cast(bound_function),
   8313                      total_argc, param_data.get()));
   8314   return *result;
   8315 }
   8316 
   8317 
   8318 static Object* Runtime_NewObjectHelper(Isolate* isolate,
   8319                                             Handle<Object> constructor,
   8320                                             Handle<AllocationSite> site) {
   8321   // If the constructor isn't a proper function we throw a type error.
   8322   if (!constructor->IsJSFunction()) {
   8323     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8324     Handle<Object> type_error =
   8325         isolate->factory()->NewTypeError("not_constructor", arguments);
   8326     return isolate->Throw(*type_error);
   8327   }
   8328 
   8329   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
   8330 
   8331   // If function should not have prototype, construction is not allowed. In this
   8332   // case generated code bailouts here, since function has no initial_map.
   8333   if (!function->should_have_prototype() && !function->shared()->bound()) {
   8334     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8335     Handle<Object> type_error =
   8336         isolate->factory()->NewTypeError("not_constructor", arguments);
   8337     return isolate->Throw(*type_error);
   8338   }
   8339 
   8340   Debug* debug = isolate->debug();
   8341   // Handle stepping into constructors if step into is active.
   8342   if (debug->StepInActive()) {
   8343     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
   8344   }
   8345 
   8346   if (function->has_initial_map()) {
   8347     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
   8348       // The 'Function' function ignores the receiver object when
   8349       // called using 'new' and creates a new JSFunction object that
   8350       // is returned.  The receiver object is only used for error
   8351       // reporting if an error occurs when constructing the new
   8352       // JSFunction. Factory::NewJSObject() should not be used to
   8353       // allocate JSFunctions since it does not properly initialize
   8354       // the shared part of the function. Since the receiver is
   8355       // ignored anyway, we use the global object as the receiver
   8356       // instead of a new JSFunction object. This way, errors are
   8357       // reported the same way whether or not 'Function' is called
   8358       // using 'new'.
   8359       return isolate->context()->global_object();
   8360     }
   8361   }
   8362 
   8363   // The function should be compiled for the optimization hints to be
   8364   // available.
   8365   Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
   8366 
   8367   Handle<JSObject> result;
   8368   if (site.is_null()) {
   8369     result = isolate->factory()->NewJSObject(function);
   8370   } else {
   8371     result = isolate->factory()->NewJSObjectWithMemento(function, site);
   8372   }
   8373 
   8374   isolate->counters()->constructed_objects()->Increment();
   8375   isolate->counters()->constructed_objects_runtime()->Increment();
   8376 
   8377   return *result;
   8378 }
   8379 
   8380 
   8381 RUNTIME_FUNCTION(RuntimeHidden_NewObject) {
   8382   HandleScope scope(isolate);
   8383   ASSERT(args.length() == 1);
   8384   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
   8385   return Runtime_NewObjectHelper(isolate,
   8386                                  constructor,
   8387                                  Handle<AllocationSite>::null());
   8388 }
   8389 
   8390 
   8391 RUNTIME_FUNCTION(RuntimeHidden_NewObjectWithAllocationSite) {
   8392   HandleScope scope(isolate);
   8393   ASSERT(args.length() == 2);
   8394   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
   8395   CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
   8396   Handle<AllocationSite> site;
   8397   if (feedback->IsAllocationSite()) {
   8398     // The feedback can be an AllocationSite or undefined.
   8399     site = Handle<AllocationSite>::cast(feedback);
   8400   }
   8401   return Runtime_NewObjectHelper(isolate, constructor, site);
   8402 }
   8403 
   8404 
   8405 RUNTIME_FUNCTION(RuntimeHidden_FinalizeInstanceSize) {
   8406   HandleScope scope(isolate);
   8407   ASSERT(args.length() == 1);
   8408 
   8409   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8410   function->CompleteInobjectSlackTracking();
   8411 
   8412   return isolate->heap()->undefined_value();
   8413 }
   8414 
   8415 
   8416 RUNTIME_FUNCTION(RuntimeHidden_CompileUnoptimized) {
   8417   HandleScope scope(isolate);
   8418   ASSERT(args.length() == 1);
   8419   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8420 #ifdef DEBUG
   8421   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
   8422     PrintF("[unoptimized: ");
   8423     function->PrintName();
   8424     PrintF("]\n");
   8425   }
   8426 #endif
   8427 
   8428   // Compile the target function.
   8429   ASSERT(function->shared()->allows_lazy_compilation());
   8430 
   8431   Handle<Code> code;
   8432   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
   8433                                      Compiler::GetUnoptimizedCode(function));
   8434   function->ReplaceCode(*code);
   8435 
   8436   // All done. Return the compiled code.
   8437   ASSERT(function->is_compiled());
   8438   ASSERT(function->code()->kind() == Code::FUNCTION ||
   8439          (FLAG_always_opt &&
   8440           function->code()->kind() == Code::OPTIMIZED_FUNCTION));
   8441   return *code;
   8442 }
   8443 
   8444 
   8445 RUNTIME_FUNCTION(RuntimeHidden_CompileOptimized) {
   8446   HandleScope scope(isolate);
   8447   ASSERT(args.length() == 2);
   8448   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8449   CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
   8450 
   8451   Handle<Code> unoptimized(function->shared()->code());
   8452   if (!function->shared()->is_compiled()) {
   8453     // If the function is not compiled, do not optimize.
   8454     // This can happen if the debugger is activated and
   8455     // the function is returned to the not compiled state.
   8456     // TODO(yangguo): reconsider this.
   8457     function->ReplaceCode(function->shared()->code());
   8458   } else if (!isolate->use_crankshaft() ||
   8459              function->shared()->optimization_disabled() ||
   8460              isolate->DebuggerHasBreakPoints()) {
   8461     // If the function is not optimizable or debugger is active continue
   8462     // using the code from the full compiler.
   8463     if (FLAG_trace_opt) {
   8464       PrintF("[failed to optimize ");
   8465       function->PrintName();
   8466       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
   8467           function->shared()->optimization_disabled() ? "F" : "T",
   8468           isolate->DebuggerHasBreakPoints() ? "T" : "F");
   8469     }
   8470     function->ReplaceCode(*unoptimized);
   8471   } else {
   8472     Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
   8473                                                 : Compiler::NOT_CONCURRENT;
   8474     Handle<Code> code;
   8475     if (Compiler::GetOptimizedCode(
   8476             function, unoptimized, mode).ToHandle(&code)) {
   8477       function->ReplaceCode(*code);
   8478     } else {
   8479       function->ReplaceCode(*unoptimized);
   8480     }
   8481   }
   8482 
   8483   ASSERT(function->code()->kind() == Code::FUNCTION ||
   8484          function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
   8485          function->IsInOptimizationQueue());
   8486   return function->code();
   8487 }
   8488 
   8489 
   8490 class ActivationsFinder : public ThreadVisitor {
   8491  public:
   8492   Code* code_;
   8493   bool has_code_activations_;
   8494 
   8495   explicit ActivationsFinder(Code* code)
   8496     : code_(code),
   8497       has_code_activations_(false) { }
   8498 
   8499   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
   8500     JavaScriptFrameIterator it(isolate, top);
   8501     VisitFrames(&it);
   8502   }
   8503 
   8504   void VisitFrames(JavaScriptFrameIterator* it) {
   8505     for (; !it->done(); it->Advance()) {
   8506       JavaScriptFrame* frame = it->frame();
   8507       if (code_->contains(frame->pc())) has_code_activations_ = true;
   8508     }
   8509   }
   8510 };
   8511 
   8512 
   8513 RUNTIME_FUNCTION(RuntimeHidden_NotifyStubFailure) {
   8514   HandleScope scope(isolate);
   8515   ASSERT(args.length() == 0);
   8516   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8517   ASSERT(AllowHeapAllocation::IsAllowed());
   8518   delete deoptimizer;
   8519   return isolate->heap()->undefined_value();
   8520 }
   8521 
   8522 
   8523 RUNTIME_FUNCTION(RuntimeHidden_NotifyDeoptimized) {
   8524   HandleScope scope(isolate);
   8525   ASSERT(args.length() == 1);
   8526   CONVERT_SMI_ARG_CHECKED(type_arg, 0);
   8527   Deoptimizer::BailoutType type =
   8528       static_cast<Deoptimizer::BailoutType>(type_arg);
   8529   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8530   ASSERT(AllowHeapAllocation::IsAllowed());
   8531 
   8532   Handle<JSFunction> function = deoptimizer->function();
   8533   Handle<Code> optimized_code = deoptimizer->compiled_code();
   8534 
   8535   ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
   8536   ASSERT(type == deoptimizer->bailout_type());
   8537 
   8538   // Make sure to materialize objects before causing any allocation.
   8539   JavaScriptFrameIterator it(isolate);
   8540   deoptimizer->MaterializeHeapObjects(&it);
   8541   delete deoptimizer;
   8542 
   8543   JavaScriptFrame* frame = it.frame();
   8544   RUNTIME_ASSERT(frame->function()->IsJSFunction());
   8545   ASSERT(frame->function() == *function);
   8546 
   8547   // Avoid doing too much work when running with --always-opt and keep
   8548   // the optimized code around.
   8549   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
   8550     return isolate->heap()->undefined_value();
   8551   }
   8552 
   8553   // Search for other activations of the same function and code.
   8554   ActivationsFinder activations_finder(*optimized_code);
   8555   activations_finder.VisitFrames(&it);
   8556   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
   8557 
   8558   if (!activations_finder.has_code_activations_) {
   8559     if (function->code() == *optimized_code) {
   8560       if (FLAG_trace_deopt) {
   8561         PrintF("[removing optimized code for: ");
   8562         function->PrintName();
   8563         PrintF("]\n");
   8564       }
   8565       function->ReplaceCode(function->shared()->code());
   8566       // Evict optimized code for this function from the cache so that it
   8567       // doesn't get used for new closures.
   8568       function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
   8569                                                     "notify deoptimized");
   8570     }
   8571   } else {
   8572     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
   8573     // unconditionally if the code is not already marked for deoptimization.
   8574     // If there is an index by shared function info, all the better.
   8575     Deoptimizer::DeoptimizeFunction(*function);
   8576   }
   8577 
   8578   return isolate->heap()->undefined_value();
   8579 }
   8580 
   8581 
   8582 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
   8583   HandleScope scope(isolate);
   8584   ASSERT(args.length() == 1);
   8585   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8586   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
   8587 
   8588   Deoptimizer::DeoptimizeFunction(*function);
   8589 
   8590   return isolate->heap()->undefined_value();
   8591 }
   8592 
   8593 
   8594 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
   8595   HandleScope scope(isolate);
   8596   ASSERT(args.length() == 1);
   8597   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8598   function->shared()->ClearTypeFeedbackInfo();
   8599   Code* unoptimized = function->shared()->code();
   8600   if (unoptimized->kind() == Code::FUNCTION) {
   8601     unoptimized->ClearInlineCaches();
   8602   }
   8603   return isolate->heap()->undefined_value();
   8604 }
   8605 
   8606 
   8607 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
   8608   SealHandleScope shs(isolate);
   8609   ASSERT(args.length() == 0);
   8610 #if defined(USE_SIMULATOR)
   8611   return isolate->heap()->true_value();
   8612 #else
   8613   return isolate->heap()->false_value();
   8614 #endif
   8615 }
   8616 
   8617 
   8618 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
   8619   SealHandleScope shs(isolate);
   8620   ASSERT(args.length() == 0);
   8621   return isolate->heap()->ToBoolean(
   8622       isolate->concurrent_recompilation_enabled());
   8623 }
   8624 
   8625 
   8626 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
   8627   HandleScope scope(isolate);
   8628   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8629   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8630 
   8631   if (!function->IsOptimizable() &&
   8632       !function->IsMarkedForConcurrentOptimization() &&
   8633       !function->IsInOptimizationQueue()) {
   8634     return isolate->heap()->undefined_value();
   8635   }
   8636 
   8637   function->MarkForOptimization();
   8638 
   8639   Code* unoptimized = function->shared()->code();
   8640   if (args.length() == 2 &&
   8641       unoptimized->kind() == Code::FUNCTION) {
   8642     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   8643     if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
   8644       // Start patching from the currently patched loop nesting level.
   8645       int current_level = unoptimized->allow_osr_at_loop_nesting_level();
   8646       ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
   8647       if (FLAG_use_osr) {
   8648         for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
   8649           unoptimized->set_allow_osr_at_loop_nesting_level(i);
   8650           isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
   8651         }
   8652       }
   8653     } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent")) &&
   8654                isolate->concurrent_recompilation_enabled()) {
   8655       function->MarkForConcurrentOptimization();
   8656     }
   8657   }
   8658 
   8659   return isolate->heap()->undefined_value();
   8660 }
   8661 
   8662 
   8663 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
   8664   HandleScope scope(isolate);
   8665   ASSERT(args.length() == 1);
   8666   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8667   function->shared()->set_optimization_disabled(true);
   8668   return isolate->heap()->undefined_value();
   8669 }
   8670 
   8671 
   8672 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
   8673   HandleScope scope(isolate);
   8674   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8675   if (!isolate->use_crankshaft()) {
   8676     return Smi::FromInt(4);  // 4 == "never".
   8677   }
   8678   bool sync_with_compiler_thread = true;
   8679   if (args.length() == 2) {
   8680     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
   8681     if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
   8682       sync_with_compiler_thread = false;
   8683     }
   8684   }
   8685   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8686   if (isolate->concurrent_recompilation_enabled() &&
   8687       sync_with_compiler_thread) {
   8688     while (function->IsInOptimizationQueue()) {
   8689       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   8690       OS::Sleep(50);
   8691     }
   8692   }
   8693   if (FLAG_always_opt) {
   8694     // We may have always opt, but that is more best-effort than a real
   8695     // promise, so we still say "no" if it is not optimized.
   8696     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
   8697                                    : Smi::FromInt(2);  // 2 == "no".
   8698   }
   8699   if (FLAG_deopt_every_n_times) {
   8700     return Smi::FromInt(6);  // 6 == "maybe deopted".
   8701   }
   8702   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
   8703                                  : Smi::FromInt(2);  // 2 == "no".
   8704 }
   8705 
   8706 
   8707 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
   8708   ASSERT(args.length() == 0);
   8709   RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
   8710   RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
   8711   isolate->optimizing_compiler_thread()->Unblock();
   8712   return isolate->heap()->undefined_value();
   8713 }
   8714 
   8715 
   8716 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
   8717   HandleScope scope(isolate);
   8718   ASSERT(args.length() == 1);
   8719   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8720   return Smi::FromInt(function->shared()->opt_count());
   8721 }
   8722 
   8723 
   8724 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
   8725                                             Handle<JSFunction> function,
   8726                                             Handle<Code> current_code) {
   8727   // Keep track of whether we've succeeded in optimizing.
   8728   if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
   8729   // If we are trying to do OSR when there are already optimized
   8730   // activations of the function, it means (a) the function is directly or
   8731   // indirectly recursive and (b) an optimized invocation has been
   8732   // deoptimized so that we are currently in an unoptimized activation.
   8733   // Check for optimized activations of this function.
   8734   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
   8735     JavaScriptFrame* frame = it.frame();
   8736     if (frame->is_optimized() && frame->function() == *function) return false;
   8737   }
   8738 
   8739   return true;
   8740 }
   8741 
   8742 
   8743 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
   8744   HandleScope scope(isolate);
   8745   ASSERT(args.length() == 1);
   8746   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8747   Handle<Code> caller_code(function->shared()->code());
   8748 
   8749   // We're not prepared to handle a function with arguments object.
   8750   ASSERT(!function->shared()->uses_arguments());
   8751 
   8752   RUNTIME_ASSERT(FLAG_use_osr);
   8753 
   8754   // Passing the PC in the javascript frame from the caller directly is
   8755   // not GC safe, so we walk the stack to get it.
   8756   JavaScriptFrameIterator it(isolate);
   8757   JavaScriptFrame* frame = it.frame();
   8758   if (!caller_code->contains(frame->pc())) {
   8759     // Code on the stack may not be the code object referenced by the shared
   8760     // function info.  It may have been replaced to include deoptimization data.
   8761     caller_code = Handle<Code>(frame->LookupCode());
   8762   }
   8763 
   8764   uint32_t pc_offset = static_cast<uint32_t>(
   8765       frame->pc() - caller_code->instruction_start());
   8766 
   8767 #ifdef DEBUG
   8768   ASSERT_EQ(frame->function(), *function);
   8769   ASSERT_EQ(frame->LookupCode(), *caller_code);
   8770   ASSERT(caller_code->contains(frame->pc()));
   8771 #endif  // DEBUG
   8772 
   8773 
   8774   BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
   8775   ASSERT(!ast_id.IsNone());
   8776 
   8777   Compiler::ConcurrencyMode mode =
   8778       isolate->concurrent_osr_enabled() &&
   8779       (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT
   8780                                                    : Compiler::NOT_CONCURRENT;
   8781   Handle<Code> result = Handle<Code>::null();
   8782 
   8783   OptimizedCompileJob* job = NULL;
   8784   if (mode == Compiler::CONCURRENT) {
   8785     // Gate the OSR entry with a stack check.
   8786     BackEdgeTable::AddStackCheck(caller_code, pc_offset);
   8787     // Poll already queued compilation jobs.
   8788     OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
   8789     if (thread->IsQueuedForOSR(function, ast_id)) {
   8790       if (FLAG_trace_osr) {
   8791         PrintF("[OSR - Still waiting for queued: ");
   8792         function->PrintName();
   8793         PrintF(" at AST id %d]\n", ast_id.ToInt());
   8794       }
   8795       return NULL;
   8796     }
   8797 
   8798     job = thread->FindReadyOSRCandidate(function, ast_id);
   8799   }
   8800 
   8801   if (job != NULL) {
   8802     if (FLAG_trace_osr) {
   8803       PrintF("[OSR - Found ready: ");
   8804       function->PrintName();
   8805       PrintF(" at AST id %d]\n", ast_id.ToInt());
   8806     }
   8807     result = Compiler::GetConcurrentlyOptimizedCode(job);
   8808   } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
   8809     if (FLAG_trace_osr) {
   8810       PrintF("[OSR - Compiling: ");
   8811       function->PrintName();
   8812       PrintF(" at AST id %d]\n", ast_id.ToInt());
   8813     }
   8814     MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
   8815         function, caller_code, mode, ast_id);
   8816     if (maybe_result.ToHandle(&result) &&
   8817         result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
   8818       // Optimization is queued.  Return to check later.
   8819       return NULL;
   8820     }
   8821   }
   8822 
   8823   // Revert the patched back edge table, regardless of whether OSR succeeds.
   8824   BackEdgeTable::Revert(isolate, *caller_code);
   8825 
   8826   // Check whether we ended up with usable optimized code.
   8827   if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
   8828     DeoptimizationInputData* data =
   8829         DeoptimizationInputData::cast(result->deoptimization_data());
   8830 
   8831     if (data->OsrPcOffset()->value() >= 0) {
   8832       ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
   8833       if (FLAG_trace_osr) {
   8834         PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
   8835                ast_id.ToInt(), data->OsrPcOffset()->value());
   8836       }
   8837       // TODO(titzer): this is a massive hack to make the deopt counts
   8838       // match. Fix heuristics for reenabling optimizations!
   8839       function->shared()->increment_deopt_count();
   8840 
   8841       // TODO(titzer): Do not install code into the function.
   8842       function->ReplaceCode(*result);
   8843       return *result;
   8844     }
   8845   }
   8846 
   8847   // Failed.
   8848   if (FLAG_trace_osr) {
   8849     PrintF("[OSR - Failed: ");
   8850     function->PrintName();
   8851     PrintF(" at AST id %d]\n", ast_id.ToInt());
   8852   }
   8853 
   8854   if (!function->IsOptimized()) {
   8855     function->ReplaceCode(function->shared()->code());
   8856   }
   8857   return NULL;
   8858 }
   8859 
   8860 
   8861 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
   8862   SealHandleScope shs(isolate);
   8863   ASSERT(args.length() == 2 || args.length() == 3);
   8864 #ifdef DEBUG
   8865   CONVERT_SMI_ARG_CHECKED(interval, 0);
   8866   CONVERT_SMI_ARG_CHECKED(timeout, 1);
   8867   isolate->heap()->set_allocation_timeout(timeout);
   8868   FLAG_gc_interval = interval;
   8869   if (args.length() == 3) {
   8870     // Enable/disable inline allocation if requested.
   8871     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
   8872     if (inline_allocation) {
   8873       isolate->heap()->EnableInlineAllocation();
   8874     } else {
   8875       isolate->heap()->DisableInlineAllocation();
   8876     }
   8877   }
   8878 #endif
   8879   return isolate->heap()->undefined_value();
   8880 }
   8881 
   8882 
   8883 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
   8884   SealHandleScope shs(isolate);
   8885   ASSERT(args.length() == 0);
   8886   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8887   return isolate->heap()->undefined_value();
   8888 }
   8889 
   8890 
   8891 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
   8892   SealHandleScope shs(isolate);
   8893   ASSERT(args.length() == 0);
   8894   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8895   return isolate->heap()->nan_value();
   8896 }
   8897 
   8898 
   8899 RUNTIME_FUNCTION(Runtime_Call) {
   8900   HandleScope scope(isolate);
   8901   ASSERT(args.length() >= 2);
   8902   int argc = args.length() - 2;
   8903   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
   8904   Object* receiver = args[0];
   8905 
   8906   // If there are too many arguments, allocate argv via malloc.
   8907   const int argv_small_size = 10;
   8908   Handle<Object> argv_small_buffer[argv_small_size];
   8909   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8910   Handle<Object>* argv = argv_small_buffer;
   8911   if (argc > argv_small_size) {
   8912     argv = new Handle<Object>[argc];
   8913     if (argv == NULL) return isolate->StackOverflow();
   8914     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8915   }
   8916 
   8917   for (int i = 0; i < argc; ++i) {
   8918      argv[i] = Handle<Object>(args[1 + i], isolate);
   8919   }
   8920 
   8921   Handle<JSReceiver> hfun(fun);
   8922   Handle<Object> hreceiver(receiver, isolate);
   8923   Handle<Object> result;
   8924   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8925       isolate, result,
   8926       Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
   8927   return *result;
   8928 }
   8929 
   8930 
   8931 RUNTIME_FUNCTION(Runtime_Apply) {
   8932   HandleScope scope(isolate);
   8933   ASSERT(args.length() == 5);
   8934   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
   8935   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
   8936   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
   8937   CONVERT_SMI_ARG_CHECKED(offset, 3);
   8938   CONVERT_SMI_ARG_CHECKED(argc, 4);
   8939   RUNTIME_ASSERT(offset >= 0);
   8940   // Loose upper bound to allow fuzzing. We'll most likely run out of
   8941   // stack space before hitting this limit.
   8942   static int kMaxArgc = 1000000;
   8943   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
   8944 
   8945   // If there are too many arguments, allocate argv via malloc.
   8946   const int argv_small_size = 10;
   8947   Handle<Object> argv_small_buffer[argv_small_size];
   8948   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8949   Handle<Object>* argv = argv_small_buffer;
   8950   if (argc > argv_small_size) {
   8951     argv = new Handle<Object>[argc];
   8952     if (argv == NULL) return isolate->StackOverflow();
   8953     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8954   }
   8955 
   8956   for (int i = 0; i < argc; ++i) {
   8957     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8958         isolate, argv[i],
   8959         Object::GetElement(isolate, arguments, offset + i));
   8960   }
   8961 
   8962   Handle<Object> result;
   8963   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   8964       isolate, result,
   8965       Execution::Call(isolate, fun, receiver, argc, argv, true));
   8966   return *result;
   8967 }
   8968 
   8969 
   8970 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
   8971   HandleScope scope(isolate);
   8972   ASSERT(args.length() == 1);
   8973   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   8974   RUNTIME_ASSERT(!object->IsJSFunction());
   8975   return *Execution::GetFunctionDelegate(isolate, object);
   8976 }
   8977 
   8978 
   8979 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
   8980   HandleScope scope(isolate);
   8981   ASSERT(args.length() == 1);
   8982   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   8983   RUNTIME_ASSERT(!object->IsJSFunction());
   8984   return *Execution::GetConstructorDelegate(isolate, object);
   8985 }
   8986 
   8987 
   8988 RUNTIME_FUNCTION(RuntimeHidden_NewGlobalContext) {
   8989   HandleScope scope(isolate);
   8990   ASSERT(args.length() == 2);
   8991 
   8992   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8993   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
   8994   Handle<Context> result =
   8995       isolate->factory()->NewGlobalContext(function, scope_info);
   8996 
   8997   ASSERT(function->context() == isolate->context());
   8998   ASSERT(function->context()->global_object() == result->global_object());
   8999   result->global_object()->set_global_context(*result);
   9000   return *result;
   9001 }
   9002 
   9003 
   9004 RUNTIME_FUNCTION(RuntimeHidden_NewFunctionContext) {
   9005   HandleScope scope(isolate);
   9006   ASSERT(args.length() == 1);
   9007 
   9008   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   9009   int length = function->shared()->scope_info()->ContextLength();
   9010   return *isolate->factory()->NewFunctionContext(length, function);
   9011 }
   9012 
   9013 
   9014 RUNTIME_FUNCTION(RuntimeHidden_PushWithContext) {
   9015   HandleScope scope(isolate);
   9016   ASSERT(args.length() == 2);
   9017   Handle<JSReceiver> extension_object;
   9018   if (args[0]->IsJSReceiver()) {
   9019     extension_object = args.at<JSReceiver>(0);
   9020   } else {
   9021     // Try to convert the object to a proper JavaScript object.
   9022     MaybeHandle<JSReceiver> maybe_object =
   9023         Object::ToObject(isolate, args.at<Object>(0));
   9024     if (!maybe_object.ToHandle(&extension_object)) {
   9025       Handle<Object> handle = args.at<Object>(0);
   9026       Handle<Object> result =
   9027           isolate->factory()->NewTypeError("with_expression",
   9028                                            HandleVector(&handle, 1));
   9029       return isolate->Throw(*result);
   9030     }
   9031   }
   9032 
   9033   Handle<JSFunction> function;
   9034   if (args[1]->IsSmi()) {
   9035     // A smi sentinel indicates a context nested inside global code rather
   9036     // than some function.  There is a canonical empty function that can be
   9037     // gotten from the native context.
   9038     function = handle(isolate->context()->native_context()->closure());
   9039   } else {
   9040     function = args.at<JSFunction>(1);
   9041   }
   9042 
   9043   Handle<Context> current(isolate->context());
   9044   Handle<Context> context = isolate->factory()->NewWithContext(
   9045       function, current, extension_object);
   9046   isolate->set_context(*context);
   9047   return *context;
   9048 }
   9049 
   9050 
   9051 RUNTIME_FUNCTION(RuntimeHidden_PushCatchContext) {
   9052   HandleScope scope(isolate);
   9053   ASSERT(args.length() == 3);
   9054   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   9055   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
   9056   Handle<JSFunction> function;
   9057   if (args[2]->IsSmi()) {
   9058     // A smi sentinel indicates a context nested inside global code rather
   9059     // than some function.  There is a canonical empty function that can be
   9060     // gotten from the native context.
   9061     function = handle(isolate->context()->native_context()->closure());
   9062   } else {
   9063     function = args.at<JSFunction>(2);
   9064   }
   9065   Handle<Context> current(isolate->context());
   9066   Handle<Context> context = isolate->factory()->NewCatchContext(
   9067       function, current, name, thrown_object);
   9068   isolate->set_context(*context);
   9069   return *context;
   9070 }
   9071 
   9072 
   9073 RUNTIME_FUNCTION(RuntimeHidden_PushBlockContext) {
   9074   HandleScope scope(isolate);
   9075   ASSERT(args.length() == 2);
   9076   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
   9077   Handle<JSFunction> function;
   9078   if (args[1]->IsSmi()) {
   9079     // A smi sentinel indicates a context nested inside global code rather
   9080     // than some function.  There is a canonical empty function that can be
   9081     // gotten from the native context.
   9082     function = handle(isolate->context()->native_context()->closure());
   9083   } else {
   9084     function = args.at<JSFunction>(1);
   9085   }
   9086   Handle<Context> current(isolate->context());
   9087   Handle<Context> context = isolate->factory()->NewBlockContext(
   9088       function, current, scope_info);
   9089   isolate->set_context(*context);
   9090   return *context;
   9091 }
   9092 
   9093 
   9094 RUNTIME_FUNCTION(Runtime_IsJSModule) {
   9095   SealHandleScope shs(isolate);
   9096   ASSERT(args.length() == 1);
   9097   CONVERT_ARG_CHECKED(Object, obj, 0);
   9098   return isolate->heap()->ToBoolean(obj->IsJSModule());
   9099 }
   9100 
   9101 
   9102 RUNTIME_FUNCTION(RuntimeHidden_PushModuleContext) {
   9103   SealHandleScope shs(isolate);
   9104   ASSERT(args.length() == 2);
   9105   CONVERT_SMI_ARG_CHECKED(index, 0);
   9106 
   9107   if (!args[1]->IsScopeInfo()) {
   9108     // Module already initialized. Find hosting context and retrieve context.
   9109     Context* host = Context::cast(isolate->context())->global_context();
   9110     Context* context = Context::cast(host->get(index));
   9111     ASSERT(context->previous() == isolate->context());
   9112     isolate->set_context(context);
   9113     return context;
   9114   }
   9115 
   9116   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
   9117 
   9118   // Allocate module context.
   9119   HandleScope scope(isolate);
   9120   Factory* factory = isolate->factory();
   9121   Handle<Context> context = factory->NewModuleContext(scope_info);
   9122   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
   9123   context->set_module(*module);
   9124   Context* previous = isolate->context();
   9125   context->set_previous(previous);
   9126   context->set_closure(previous->closure());
   9127   context->set_global_object(previous->global_object());
   9128   isolate->set_context(*context);
   9129 
   9130   // Find hosting scope and initialize internal variable holding module there.
   9131   previous->global_context()->set(index, *context);
   9132 
   9133   return *context;
   9134 }
   9135 
   9136 
   9137 RUNTIME_FUNCTION(RuntimeHidden_DeclareModules) {
   9138   HandleScope scope(isolate);
   9139   ASSERT(args.length() == 1);
   9140   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
   9141   Context* host_context = isolate->context();
   9142 
   9143   for (int i = 0; i < descriptions->length(); ++i) {
   9144     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
   9145     int host_index = description->host_index();
   9146     Handle<Context> context(Context::cast(host_context->get(host_index)));
   9147     Handle<JSModule> module(context->module());
   9148 
   9149     for (int j = 0; j < description->length(); ++j) {
   9150       Handle<String> name(description->name(j));
   9151       VariableMode mode = description->mode(j);
   9152       int index = description->index(j);
   9153       switch (mode) {
   9154         case VAR:
   9155         case LET:
   9156         case CONST:
   9157         case CONST_LEGACY: {
   9158           PropertyAttributes attr =
   9159               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
   9160           Handle<AccessorInfo> info =
   9161               Accessors::MakeModuleExport(name, index, attr);
   9162           Handle<Object> result =
   9163               JSObject::SetAccessor(module, info).ToHandleChecked();
   9164           ASSERT(!result->IsUndefined());
   9165           USE(result);
   9166           break;
   9167         }
   9168         case MODULE: {
   9169           Object* referenced_context = Context::cast(host_context)->get(index);
   9170           Handle<JSModule> value(Context::cast(referenced_context)->module());
   9171           JSReceiver::SetProperty(module, name, value, FROZEN, STRICT).Assert();
   9172           break;
   9173         }
   9174         case INTERNAL:
   9175         case TEMPORARY:
   9176         case DYNAMIC:
   9177         case DYNAMIC_GLOBAL:
   9178         case DYNAMIC_LOCAL:
   9179           UNREACHABLE();
   9180       }
   9181     }
   9182 
   9183     JSObject::PreventExtensions(module).Assert();
   9184   }
   9185 
   9186   ASSERT(!isolate->has_pending_exception());
   9187   return isolate->heap()->undefined_value();
   9188 }
   9189 
   9190 
   9191 RUNTIME_FUNCTION(RuntimeHidden_DeleteContextSlot) {
   9192   HandleScope scope(isolate);
   9193   ASSERT(args.length() == 2);
   9194 
   9195   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   9196   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   9197 
   9198   int index;
   9199   PropertyAttributes attributes;
   9200   ContextLookupFlags flags = FOLLOW_CHAINS;
   9201   BindingFlags binding_flags;
   9202   Handle<Object> holder = context->Lookup(name,
   9203                                           flags,
   9204                                           &index,
   9205                                           &attributes,
   9206                                           &binding_flags);
   9207 
   9208   // If the slot was not found the result is true.
   9209   if (holder.is_null()) {
   9210     return isolate->heap()->true_value();
   9211   }
   9212 
   9213   // If the slot was found in a context, it should be DONT_DELETE.
   9214   if (holder->IsContext()) {
   9215     return isolate->heap()->false_value();
   9216   }
   9217 
   9218   // The slot was found in a JSObject, either a context extension object,
   9219   // the global object, or the subject of a with.  Try to delete it
   9220   // (respecting DONT_DELETE).
   9221   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   9222   Handle<Object> result;
   9223   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9224       isolate, result,
   9225       JSReceiver::DeleteProperty(object, name));
   9226   return *result;
   9227 }
   9228 
   9229 
   9230 // A mechanism to return a pair of Object pointers in registers (if possible).
   9231 // How this is achieved is calling convention-dependent.
   9232 // All currently supported x86 compiles uses calling conventions that are cdecl
   9233 // variants where a 64-bit value is returned in two 32-bit registers
   9234 // (edx:eax on ia32, r1:r0 on ARM).
   9235 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
   9236 // In Win64 calling convention, a struct of two pointers is returned in memory,
   9237 // allocated by the caller, and passed as a pointer in a hidden first parameter.
   9238 #ifdef V8_HOST_ARCH_64_BIT
   9239 struct ObjectPair {
   9240   Object* x;
   9241   Object* y;
   9242 };
   9243 
   9244 
   9245 static inline ObjectPair MakePair(Object* x, Object* y) {
   9246   ObjectPair result = {x, y};
   9247   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
   9248   // In Win64 they are assigned to a hidden first argument.
   9249   return result;
   9250 }
   9251 #else
   9252 typedef uint64_t ObjectPair;
   9253 static inline ObjectPair MakePair(Object* x, Object* y) {
   9254 #if defined(V8_TARGET_LITTLE_ENDIAN)
   9255   return reinterpret_cast<uint32_t>(x) |
   9256       (reinterpret_cast<ObjectPair>(y) << 32);
   9257 #elif defined(V8_TARGET_BIG_ENDIAN)
   9258     return reinterpret_cast<uint32_t>(y) |
   9259         (reinterpret_cast<ObjectPair>(x) << 32);
   9260 #else
   9261 #error Unknown endianness
   9262 #endif
   9263 }
   9264 #endif
   9265 
   9266 
   9267 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
   9268                                            JSObject* holder) {
   9269   ASSERT(!holder->IsGlobalObject());
   9270   Context* top = isolate->context();
   9271   // Get the context extension function.
   9272   JSFunction* context_extension_function =
   9273       top->native_context()->context_extension_function();
   9274   // If the holder isn't a context extension object, we just return it
   9275   // as the receiver. This allows arguments objects to be used as
   9276   // receivers, but only if they are put in the context scope chain
   9277   // explicitly via a with-statement.
   9278   Object* constructor = holder->map()->constructor();
   9279   if (constructor != context_extension_function) return holder;
   9280   // Fall back to using the global object as the implicit receiver if
   9281   // the property turns out to be a local variable allocated in a
   9282   // context extension object - introduced via eval.
   9283   return isolate->heap()->undefined_value();
   9284 }
   9285 
   9286 
   9287 static ObjectPair LoadContextSlotHelper(Arguments args,
   9288                                         Isolate* isolate,
   9289                                         bool throw_error) {
   9290   HandleScope scope(isolate);
   9291   ASSERT_EQ(2, args.length());
   9292 
   9293   if (!args[0]->IsContext() || !args[1]->IsString()) {
   9294     return MakePair(isolate->ThrowIllegalOperation(), NULL);
   9295   }
   9296   Handle<Context> context = args.at<Context>(0);
   9297   Handle<String> name = args.at<String>(1);
   9298 
   9299   int index;
   9300   PropertyAttributes attributes;
   9301   ContextLookupFlags flags = FOLLOW_CHAINS;
   9302   BindingFlags binding_flags;
   9303   Handle<Object> holder = context->Lookup(name,
   9304                                           flags,
   9305                                           &index,
   9306                                           &attributes,
   9307                                           &binding_flags);
   9308   if (isolate->has_pending_exception()) {
   9309     return MakePair(isolate->heap()->exception(), NULL);
   9310   }
   9311 
   9312   // If the index is non-negative, the slot has been found in a context.
   9313   if (index >= 0) {
   9314     ASSERT(holder->IsContext());
   9315     // If the "property" we were looking for is a local variable, the
   9316     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
   9317     Handle<Object> receiver = isolate->factory()->undefined_value();
   9318     Object* value = Context::cast(*holder)->get(index);
   9319     // Check for uninitialized bindings.
   9320     switch (binding_flags) {
   9321       case MUTABLE_CHECK_INITIALIZED:
   9322       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
   9323         if (value->IsTheHole()) {
   9324           Handle<Object> reference_error =
   9325               isolate->factory()->NewReferenceError("not_defined",
   9326                                                     HandleVector(&name, 1));
   9327           return MakePair(isolate->Throw(*reference_error), NULL);
   9328         }
   9329         // FALLTHROUGH
   9330       case MUTABLE_IS_INITIALIZED:
   9331       case IMMUTABLE_IS_INITIALIZED:
   9332       case IMMUTABLE_IS_INITIALIZED_HARMONY:
   9333         ASSERT(!value->IsTheHole());
   9334         return MakePair(value, *receiver);
   9335       case IMMUTABLE_CHECK_INITIALIZED:
   9336         if (value->IsTheHole()) {
   9337           ASSERT((attributes & READ_ONLY) != 0);
   9338           value = isolate->heap()->undefined_value();
   9339         }
   9340         return MakePair(value, *receiver);
   9341       case MISSING_BINDING:
   9342         UNREACHABLE();
   9343         return MakePair(NULL, NULL);
   9344     }
   9345   }
   9346 
   9347   // Otherwise, if the slot was found the holder is a context extension
   9348   // object, subject of a with, or a global object.  We read the named
   9349   // property from it.
   9350   if (!holder.is_null()) {
   9351     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
   9352     ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
   9353     // GetProperty below can cause GC.
   9354     Handle<Object> receiver_handle(
   9355         object->IsGlobalObject()
   9356             ? Object::cast(isolate->heap()->undefined_value())
   9357             : object->IsJSProxy() ? static_cast<Object*>(*object)
   9358                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
   9359         isolate);
   9360 
   9361     // No need to unhole the value here.  This is taken care of by the
   9362     // GetProperty function.
   9363     Handle<Object> value;
   9364     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   9365         isolate, value,
   9366         Object::GetProperty(object, name),
   9367         MakePair(isolate->heap()->exception(), NULL));
   9368     return MakePair(*value, *receiver_handle);
   9369   }
   9370 
   9371   if (throw_error) {
   9372     // The property doesn't exist - throw exception.
   9373     Handle<Object> reference_error =
   9374         isolate->factory()->NewReferenceError("not_defined",
   9375                                               HandleVector(&name, 1));
   9376     return MakePair(isolate->Throw(*reference_error), NULL);
   9377   } else {
   9378     // The property doesn't exist - return undefined.
   9379     return MakePair(isolate->heap()->undefined_value(),
   9380                     isolate->heap()->undefined_value());
   9381   }
   9382 }
   9383 
   9384 
   9385 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlot) {
   9386   return LoadContextSlotHelper(args, isolate, true);
   9387 }
   9388 
   9389 
   9390 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlotNoReferenceError) {
   9391   return LoadContextSlotHelper(args, isolate, false);
   9392 }
   9393 
   9394 
   9395 RUNTIME_FUNCTION(RuntimeHidden_StoreContextSlot) {
   9396   HandleScope scope(isolate);
   9397   ASSERT(args.length() == 4);
   9398 
   9399   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
   9400   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   9401   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   9402   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
   9403 
   9404   int index;
   9405   PropertyAttributes attributes;
   9406   ContextLookupFlags flags = FOLLOW_CHAINS;
   9407   BindingFlags binding_flags;
   9408   Handle<Object> holder = context->Lookup(name,
   9409                                           flags,
   9410                                           &index,
   9411                                           &attributes,
   9412                                           &binding_flags);
   9413   if (isolate->has_pending_exception()) return isolate->heap()->exception();
   9414 
   9415   if (index >= 0) {
   9416     // The property was found in a context slot.
   9417     Handle<Context> context = Handle<Context>::cast(holder);
   9418     if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
   9419         context->get(index)->IsTheHole()) {
   9420       Handle<Object> error =
   9421           isolate->factory()->NewReferenceError("not_defined",
   9422                                                 HandleVector(&name, 1));
   9423       return isolate->Throw(*error);
   9424     }
   9425     // Ignore if read_only variable.
   9426     if ((attributes & READ_ONLY) == 0) {
   9427       // Context is a fixed array and set cannot fail.
   9428       context->set(index, *value);
   9429     } else if (strict_mode == STRICT) {
   9430       // Setting read only property in strict mode.
   9431       Handle<Object> error =
   9432           isolate->factory()->NewTypeError("strict_cannot_assign",
   9433                                            HandleVector(&name, 1));
   9434       return isolate->Throw(*error);
   9435     }
   9436     return *value;
   9437   }
   9438 
   9439   // Slow case: The property is not in a context slot.  It is either in a
   9440   // context extension object, a property of the subject of a with, or a
   9441   // property of the global object.
   9442   Handle<JSReceiver> object;
   9443 
   9444   if (!holder.is_null()) {
   9445     // The property exists on the holder.
   9446     object = Handle<JSReceiver>::cast(holder);
   9447   } else {
   9448     // The property was not found.
   9449     ASSERT(attributes == ABSENT);
   9450 
   9451     if (strict_mode == STRICT) {
   9452       // Throw in strict mode (assignment to undefined variable).
   9453       Handle<Object> error =
   9454           isolate->factory()->NewReferenceError(
   9455               "not_defined", HandleVector(&name, 1));
   9456       return isolate->Throw(*error);
   9457     }
   9458     // In sloppy mode, the property is added to the global object.
   9459     attributes = NONE;
   9460     object = Handle<JSReceiver>(isolate->context()->global_object());
   9461   }
   9462 
   9463   // Set the property if it's not read only or doesn't yet exist.
   9464   if ((attributes & READ_ONLY) == 0 ||
   9465       (JSReceiver::GetOwnPropertyAttributes(object, name) == ABSENT)) {
   9466     RETURN_FAILURE_ON_EXCEPTION(
   9467         isolate,
   9468         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
   9469   } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
   9470     // Setting read only property in strict mode.
   9471     Handle<Object> error =
   9472       isolate->factory()->NewTypeError(
   9473           "strict_cannot_assign", HandleVector(&name, 1));
   9474     return isolate->Throw(*error);
   9475   }
   9476   return *value;
   9477 }
   9478 
   9479 
   9480 RUNTIME_FUNCTION(RuntimeHidden_Throw) {
   9481   HandleScope scope(isolate);
   9482   ASSERT(args.length() == 1);
   9483 
   9484   return isolate->Throw(args[0]);
   9485 }
   9486 
   9487 
   9488 RUNTIME_FUNCTION(RuntimeHidden_ReThrow) {
   9489   HandleScope scope(isolate);
   9490   ASSERT(args.length() == 1);
   9491 
   9492   return isolate->ReThrow(args[0]);
   9493 }
   9494 
   9495 
   9496 RUNTIME_FUNCTION(RuntimeHidden_PromoteScheduledException) {
   9497   SealHandleScope shs(isolate);
   9498   ASSERT(args.length() == 0);
   9499   return isolate->PromoteScheduledException();
   9500 }
   9501 
   9502 
   9503 RUNTIME_FUNCTION(RuntimeHidden_ThrowReferenceError) {
   9504   HandleScope scope(isolate);
   9505   ASSERT(args.length() == 1);
   9506   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
   9507   Handle<Object> reference_error =
   9508     isolate->factory()->NewReferenceError("not_defined",
   9509                                           HandleVector(&name, 1));
   9510   return isolate->Throw(*reference_error);
   9511 }
   9512 
   9513 
   9514 RUNTIME_FUNCTION(RuntimeHidden_ThrowNotDateError) {
   9515   HandleScope scope(isolate);
   9516   ASSERT(args.length() == 0);
   9517   return isolate->Throw(*isolate->factory()->NewTypeError(
   9518       "not_date_object", HandleVector<Object>(NULL, 0)));
   9519 }
   9520 
   9521 
   9522 RUNTIME_FUNCTION(RuntimeHidden_StackGuard) {
   9523   SealHandleScope shs(isolate);
   9524   ASSERT(args.length() == 0);
   9525 
   9526   // First check if this is a real stack overflow.
   9527   StackLimitCheck check(isolate);
   9528   if (check.JsHasOverflowed()) {
   9529     return isolate->StackOverflow();
   9530   }
   9531 
   9532   return isolate->stack_guard()->HandleInterrupts();
   9533 }
   9534 
   9535 
   9536 RUNTIME_FUNCTION(RuntimeHidden_TryInstallOptimizedCode) {
   9537   HandleScope scope(isolate);
   9538   ASSERT(args.length() == 1);
   9539   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   9540 
   9541   // First check if this is a real stack overflow.
   9542   StackLimitCheck check(isolate);
   9543   if (check.JsHasOverflowed()) {
   9544     SealHandleScope shs(isolate);
   9545     return isolate->StackOverflow();
   9546   }
   9547 
   9548   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   9549   return (function->IsOptimized()) ? function->code()
   9550                                    : function->shared()->code();
   9551 }
   9552 
   9553 
   9554 RUNTIME_FUNCTION(RuntimeHidden_Interrupt) {
   9555   SealHandleScope shs(isolate);
   9556   ASSERT(args.length() == 0);
   9557   return isolate->stack_guard()->HandleInterrupts();
   9558 }
   9559 
   9560 
   9561 static int StackSize(Isolate* isolate) {
   9562   int n = 0;
   9563   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
   9564   return n;
   9565 }
   9566 
   9567 
   9568 static void PrintTransition(Isolate* isolate, Object* result) {
   9569   // indentation
   9570   { const int nmax = 80;
   9571     int n = StackSize(isolate);
   9572     if (n <= nmax)
   9573       PrintF("%4d:%*s", n, n, "");
   9574     else
   9575       PrintF("%4d:%*s", n, nmax, "...");
   9576   }
   9577 
   9578   if (result == NULL) {
   9579     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
   9580     PrintF(" {\n");
   9581   } else {
   9582     // function result
   9583     PrintF("} -> ");
   9584     result->ShortPrint();
   9585     PrintF("\n");
   9586   }
   9587 }
   9588 
   9589 
   9590 RUNTIME_FUNCTION(Runtime_TraceEnter) {
   9591   SealHandleScope shs(isolate);
   9592   ASSERT(args.length() == 0);
   9593   PrintTransition(isolate, NULL);
   9594   return isolate->heap()->undefined_value();
   9595 }
   9596 
   9597 
   9598 RUNTIME_FUNCTION(Runtime_TraceExit) {
   9599   SealHandleScope shs(isolate);
   9600   ASSERT(args.length() == 1);
   9601   CONVERT_ARG_CHECKED(Object, obj, 0);
   9602   PrintTransition(isolate, obj);
   9603   return obj;  // return TOS
   9604 }
   9605 
   9606 
   9607 RUNTIME_FUNCTION(Runtime_DebugPrint) {
   9608   SealHandleScope shs(isolate);
   9609   ASSERT(args.length() == 1);
   9610 
   9611 #ifdef DEBUG
   9612   if (args[0]->IsString()) {
   9613     // If we have a string, assume it's a code "marker"
   9614     // and print some interesting cpu debugging info.
   9615     JavaScriptFrameIterator it(isolate);
   9616     JavaScriptFrame* frame = it.frame();
   9617     PrintF("fp = %p, sp = %p, caller_sp = %p: ",
   9618            frame->fp(), frame->sp(), frame->caller_sp());
   9619   } else {
   9620     PrintF("DebugPrint: ");
   9621   }
   9622   args[0]->Print();
   9623   if (args[0]->IsHeapObject()) {
   9624     PrintF("\n");
   9625     HeapObject::cast(args[0])->map()->Print();
   9626   }
   9627 #else
   9628   // ShortPrint is available in release mode. Print is not.
   9629   args[0]->ShortPrint();
   9630 #endif
   9631   PrintF("\n");
   9632   Flush();
   9633 
   9634   return args[0];  // return TOS
   9635 }
   9636 
   9637 
   9638 RUNTIME_FUNCTION(Runtime_DebugTrace) {
   9639   SealHandleScope shs(isolate);
   9640   ASSERT(args.length() == 0);
   9641   isolate->PrintStack(stdout);
   9642   return isolate->heap()->undefined_value();
   9643 }
   9644 
   9645 
   9646 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
   9647   HandleScope scope(isolate);
   9648   ASSERT(args.length() == 0);
   9649   if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
   9650 
   9651   // According to ECMA-262, section 15.9.1, page 117, the precision of
   9652   // the number in a Date object representing a particular instant in
   9653   // time is milliseconds. Therefore, we floor the result of getting
   9654   // the OS time.
   9655   double millis = std::floor(OS::TimeCurrentMillis());
   9656   return *isolate->factory()->NewNumber(millis);
   9657 }
   9658 
   9659 
   9660 RUNTIME_FUNCTION(Runtime_DateParseString) {
   9661   HandleScope scope(isolate);
   9662   ASSERT(args.length() == 2);
   9663   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   9664   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
   9665 
   9666   RUNTIME_ASSERT(output->HasFastElements());
   9667   JSObject::EnsureCanContainHeapObjectElements(output);
   9668   RUNTIME_ASSERT(output->HasFastObjectElements());
   9669   Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
   9670   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
   9671 
   9672   str = String::Flatten(str);
   9673   DisallowHeapAllocation no_gc;
   9674 
   9675   bool result;
   9676   String::FlatContent str_content = str->GetFlatContent();
   9677   if (str_content.IsAscii()) {
   9678     result = DateParser::Parse(str_content.ToOneByteVector(),
   9679                                *output_array,
   9680                                isolate->unicode_cache());
   9681   } else {
   9682     ASSERT(str_content.IsTwoByte());
   9683     result = DateParser::Parse(str_content.ToUC16Vector(),
   9684                                *output_array,
   9685                                isolate->unicode_cache());
   9686   }
   9687 
   9688   if (result) {
   9689     return *output;
   9690   } else {
   9691     return isolate->heap()->null_value();
   9692   }
   9693 }
   9694 
   9695 
   9696 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
   9697   HandleScope scope(isolate);
   9698   ASSERT(args.length() == 1);
   9699 
   9700   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9701   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
   9702                  x <= DateCache::kMaxTimeBeforeUTCInMs);
   9703   const char* zone =
   9704       isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
   9705   Handle<String> result = isolate->factory()->NewStringFromUtf8(
   9706       CStrVector(zone)).ToHandleChecked();
   9707   return *result;
   9708 }
   9709 
   9710 
   9711 RUNTIME_FUNCTION(Runtime_DateToUTC) {
   9712   HandleScope scope(isolate);
   9713   ASSERT(args.length() == 1);
   9714 
   9715   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9716   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
   9717                  x <= DateCache::kMaxTimeBeforeUTCInMs);
   9718   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
   9719 
   9720   return *isolate->factory()->NewNumber(static_cast<double>(time));
   9721 }
   9722 
   9723 
   9724 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
   9725   HandleScope hs(isolate);
   9726   ASSERT(args.length() == 0);
   9727   if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
   9728     Handle<FixedArray> date_cache_version =
   9729         isolate->factory()->NewFixedArray(1, TENURED);
   9730     date_cache_version->set(0, Smi::FromInt(0));
   9731     isolate->eternal_handles()->CreateSingleton(
   9732         isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
   9733   }
   9734   Handle<FixedArray> date_cache_version =
   9735       Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
   9736           EternalHandles::DATE_CACHE_VERSION));
   9737   // Return result as a JS array.
   9738   Handle<JSObject> result =
   9739       isolate->factory()->NewJSObject(isolate->array_function());
   9740   JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
   9741   return *result;
   9742 }
   9743 
   9744 
   9745 RUNTIME_FUNCTION(Runtime_GlobalReceiver) {
   9746   SealHandleScope shs(isolate);
   9747   ASSERT(args.length() == 1);
   9748   CONVERT_ARG_CHECKED(Object, global, 0);
   9749   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
   9750   return JSGlobalObject::cast(global)->global_receiver();
   9751 }
   9752 
   9753 
   9754 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
   9755   SealHandleScope shs(isolate);
   9756   ASSERT(args.length() == 1);
   9757   CONVERT_ARG_CHECKED(Object, global, 0);
   9758   if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
   9759   return isolate->heap()->ToBoolean(
   9760       !JSGlobalObject::cast(global)->IsDetached());
   9761 }
   9762 
   9763 
   9764 RUNTIME_FUNCTION(Runtime_ParseJson) {
   9765   HandleScope scope(isolate);
   9766   ASSERT(args.length() == 1);
   9767   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9768 
   9769   source = String::Flatten(source);
   9770   // Optimized fast case where we only have ASCII characters.
   9771   Handle<Object> result;
   9772   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9773       isolate, result,
   9774       source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
   9775                                    : JsonParser<false>::Parse(source));
   9776   return *result;
   9777 }
   9778 
   9779 
   9780 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   9781                                       Handle<Context> context) {
   9782   ASSERT(context->allow_code_gen_from_strings()->IsFalse());
   9783   // Check with callback if set.
   9784   AllowCodeGenerationFromStringsCallback callback =
   9785       isolate->allow_code_gen_callback();
   9786   if (callback == NULL) {
   9787     // No callback set and code generation disallowed.
   9788     return false;
   9789   } else {
   9790     // Callback set. Let it decide if code generation is allowed.
   9791     VMState<EXTERNAL> state(isolate);
   9792     return callback(v8::Utils::ToLocal(context));
   9793   }
   9794 }
   9795 
   9796 
   9797 // Walk up the stack expecting:
   9798 //  - Runtime_CompileString
   9799 //  - JSFunction callee (eval, Function constructor, etc)
   9800 //  - call() (maybe)
   9801 //  - apply() (maybe)
   9802 //  - bind() (maybe)
   9803 // - JSFunction caller (maybe)
   9804 //
   9805 // return true if the caller has the same security token as the callee
   9806 // or if an exit frame was hit, in which case allow it through, as it could
   9807 // have come through the api.
   9808 static bool TokensMatchForCompileString(Isolate* isolate) {
   9809   MaybeHandle<JSFunction> callee;
   9810   bool exit_handled = true;
   9811   bool tokens_match = true;
   9812   bool done = false;
   9813   for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
   9814     StackFrame* raw_frame = it.frame();
   9815     if (!raw_frame->is_java_script()) {
   9816       if (raw_frame->is_exit()) exit_handled = false;
   9817       continue;
   9818     }
   9819     JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
   9820     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
   9821     outer_frame->Summarize(&frames);
   9822     for (int i = frames.length() - 1; i >= 0 && !done; --i) {
   9823       FrameSummary& frame = frames[i];
   9824       Handle<JSFunction> fun = frame.function();
   9825       // Capture the callee function.
   9826       if (callee.is_null()) {
   9827         callee = fun;
   9828         exit_handled = true;
   9829         continue;
   9830       }
   9831       // Exit condition.
   9832       Handle<Context> context(callee.ToHandleChecked()->context());
   9833       if (!fun->context()->HasSameSecurityTokenAs(*context)) {
   9834         tokens_match = false;
   9835         done = true;
   9836         continue;
   9837       }
   9838       // Skip bound functions in correct origin.
   9839       if (fun->shared()->bound()) {
   9840         exit_handled = true;
   9841         continue;
   9842       }
   9843       done = true;
   9844     }
   9845   }
   9846   return !exit_handled || tokens_match;
   9847 }
   9848 
   9849 
   9850 RUNTIME_FUNCTION(Runtime_CompileString) {
   9851   HandleScope scope(isolate);
   9852   ASSERT(args.length() == 2);
   9853   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9854   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
   9855 
   9856   // Extract native context.
   9857   Handle<Context> context(isolate->context()->native_context());
   9858 
   9859   // Filter cross security context calls.
   9860   if (!TokensMatchForCompileString(isolate)) {
   9861     return isolate->heap()->undefined_value();
   9862   }
   9863 
   9864   // Check if native context allows code generation from
   9865   // strings. Throw an exception if it doesn't.
   9866   if (context->allow_code_gen_from_strings()->IsFalse() &&
   9867       !CodeGenerationFromStringsAllowed(isolate, context)) {
   9868     Handle<Object> error_message =
   9869         context->ErrorMessageForCodeGenerationFromStrings();
   9870     return isolate->Throw(*isolate->factory()->NewEvalError(
   9871         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
   9872   }
   9873 
   9874   // Compile source string in the native context.
   9875   ParseRestriction restriction = function_literal_only
   9876       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
   9877   Handle<JSFunction> fun;
   9878   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   9879       isolate, fun,
   9880       Compiler::GetFunctionFromEval(
   9881           source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
   9882   return *fun;
   9883 }
   9884 
   9885 
   9886 static ObjectPair CompileGlobalEval(Isolate* isolate,
   9887                                     Handle<String> source,
   9888                                     Handle<Object> receiver,
   9889                                     StrictMode strict_mode,
   9890                                     int scope_position) {
   9891   Handle<Context> context = Handle<Context>(isolate->context());
   9892   Handle<Context> native_context = Handle<Context>(context->native_context());
   9893 
   9894   // Check if native context allows code generation from
   9895   // strings. Throw an exception if it doesn't.
   9896   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
   9897       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
   9898     Handle<Object> error_message =
   9899         native_context->ErrorMessageForCodeGenerationFromStrings();
   9900     isolate->Throw(*isolate->factory()->NewEvalError(
   9901         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
   9902     return MakePair(isolate->heap()->exception(), NULL);
   9903   }
   9904 
   9905   // Deal with a normal eval call with a string argument. Compile it
   9906   // and return the compiled function bound in the local context.
   9907   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
   9908   Handle<JSFunction> compiled;
   9909   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   9910       isolate, compiled,
   9911       Compiler::GetFunctionFromEval(
   9912           source, context, strict_mode, restriction, scope_position),
   9913       MakePair(isolate->heap()->exception(), NULL));
   9914   return MakePair(*compiled, *receiver);
   9915 }
   9916 
   9917 
   9918 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_ResolvePossiblyDirectEval) {
   9919   HandleScope scope(isolate);
   9920   ASSERT(args.length() == 5);
   9921 
   9922   Handle<Object> callee = args.at<Object>(0);
   9923 
   9924   // If "eval" didn't refer to the original GlobalEval, it's not a
   9925   // direct call to eval.
   9926   // (And even if it is, but the first argument isn't a string, just let
   9927   // execution default to an indirect call to eval, which will also return
   9928   // the first argument without doing anything).
   9929   if (*callee != isolate->native_context()->global_eval_fun() ||
   9930       !args[1]->IsString()) {
   9931     return MakePair(*callee, isolate->heap()->undefined_value());
   9932   }
   9933 
   9934   ASSERT(args[3]->IsSmi());
   9935   ASSERT(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
   9936   StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
   9937   ASSERT(args[4]->IsSmi());
   9938   return CompileGlobalEval(isolate,
   9939                            args.at<String>(1),
   9940                            args.at<Object>(2),
   9941                            strict_mode,
   9942                            args.smi_at(4));
   9943 }
   9944 
   9945 
   9946 RUNTIME_FUNCTION(RuntimeHidden_AllocateInNewSpace) {
   9947   HandleScope scope(isolate);
   9948   ASSERT(args.length() == 1);
   9949   CONVERT_SMI_ARG_CHECKED(size, 0);
   9950   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9951   RUNTIME_ASSERT(size > 0);
   9952   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
   9953   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
   9954 }
   9955 
   9956 
   9957 RUNTIME_FUNCTION(RuntimeHidden_AllocateInTargetSpace) {
   9958   HandleScope scope(isolate);
   9959   ASSERT(args.length() == 2);
   9960   CONVERT_SMI_ARG_CHECKED(size, 0);
   9961   CONVERT_SMI_ARG_CHECKED(flags, 1);
   9962   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9963   RUNTIME_ASSERT(size > 0);
   9964   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
   9965   bool double_align = AllocateDoubleAlignFlag::decode(flags);
   9966   AllocationSpace space = AllocateTargetSpace::decode(flags);
   9967   return *isolate->factory()->NewFillerObject(size, double_align, space);
   9968 }
   9969 
   9970 
   9971 // Push an object unto an array of objects if it is not already in the
   9972 // array.  Returns true if the element was pushed on the stack and
   9973 // false otherwise.
   9974 RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
   9975   HandleScope scope(isolate);
   9976   ASSERT(args.length() == 2);
   9977   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   9978   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
   9979   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
   9980   int length = Smi::cast(array->length())->value();
   9981   FixedArray* elements = FixedArray::cast(array->elements());
   9982   for (int i = 0; i < length; i++) {
   9983     if (elements->get(i) == *element) return isolate->heap()->false_value();
   9984   }
   9985 
   9986   // Strict not needed. Used for cycle detection in Array join implementation.
   9987   RETURN_FAILURE_ON_EXCEPTION(
   9988       isolate,
   9989       JSObject::SetFastElement(array, length, element, SLOPPY, true));
   9990   return isolate->heap()->true_value();
   9991 }
   9992 
   9993 
   9994 /**
   9995  * A simple visitor visits every element of Array's.
   9996  * The backend storage can be a fixed array for fast elements case,
   9997  * or a dictionary for sparse array. Since Dictionary is a subtype
   9998  * of FixedArray, the class can be used by both fast and slow cases.
   9999  * The second parameter of the constructor, fast_elements, specifies
   10000  * whether the storage is a FixedArray or Dictionary.
   10001  *
   10002  * An index limit is used to deal with the situation that a result array
   10003  * length overflows 32-bit non-negative integer.
   10004  */
   10005 class ArrayConcatVisitor {
   10006  public:
   10007   ArrayConcatVisitor(Isolate* isolate,
   10008                      Handle<FixedArray> storage,
   10009                      bool fast_elements) :
   10010       isolate_(isolate),
   10011       storage_(Handle<FixedArray>::cast(
   10012           isolate->global_handles()->Create(*storage))),
   10013       index_offset_(0u),
   10014       fast_elements_(fast_elements),
   10015       exceeds_array_limit_(false) { }
   10016 
   10017   ~ArrayConcatVisitor() {
   10018     clear_storage();
   10019   }
   10020 
   10021   void visit(uint32_t i, Handle<Object> elm) {
   10022     if (i > JSObject::kMaxElementCount - index_offset_) {
   10023       exceeds_array_limit_ = true;
   10024       return;
   10025     }
   10026     uint32_t index = index_offset_ + i;
   10027 
   10028     if (fast_elements_) {
   10029       if (index < static_cast<uint32_t>(storage_->length())) {
   10030         storage_->set(index, *elm);
   10031         return;
   10032       }
   10033       // Our initial estimate of length was foiled, possibly by
   10034       // getters on the arrays increasing the length of later arrays
   10035       // during iteration.
   10036       // This shouldn't happen in anything but pathological cases.
   10037       SetDictionaryMode();
   10038       // Fall-through to dictionary mode.
   10039     }
   10040     ASSERT(!fast_elements_);
   10041     Handle<SeededNumberDictionary> dict(
   10042         SeededNumberDictionary::cast(*storage_));
   10043     Handle<SeededNumberDictionary> result =
   10044         SeededNumberDictionary::AtNumberPut(dict, index, elm);
   10045     if (!result.is_identical_to(dict)) {
   10046       // Dictionary needed to grow.
   10047       clear_storage();
   10048       set_storage(*result);
   10049     }
   10050   }
   10051 
   10052   void increase_index_offset(uint32_t delta) {
   10053     if (JSObject::kMaxElementCount - index_offset_ < delta) {
   10054       index_offset_ = JSObject::kMaxElementCount;
   10055     } else {
   10056       index_offset_ += delta;
   10057     }
   10058     // If the initial length estimate was off (see special case in visit()),
   10059     // but the array blowing the limit didn't contain elements beyond the
   10060     // provided-for index range, go to dictionary mode now.
   10061     if (fast_elements_ &&
   10062         index_offset_ >
   10063             static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
   10064       SetDictionaryMode();
   10065     }
   10066   }
   10067 
   10068   bool exceeds_array_limit() {
   10069     return exceeds_array_limit_;
   10070   }
   10071 
   10072   Handle<JSArray> ToArray() {
   10073     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
   10074     Handle<Object> length =
   10075         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
   10076     Handle<Map> map = JSObject::GetElementsTransitionMap(
   10077         array,
   10078         fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
   10079     array->set_map(*map);
   10080     array->set_length(*length);
   10081     array->set_elements(*storage_);
   10082     return array;
   10083   }
   10084 
   10085  private:
   10086   // Convert storage to dictionary mode.
   10087   void SetDictionaryMode() {
   10088     ASSERT(fast_elements_);
   10089     Handle<FixedArray> current_storage(*storage_);
   10090     Handle<SeededNumberDictionary> slow_storage(
   10091         SeededNumberDictionary::New(isolate_, current_storage->length()));
   10092     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
   10093     for (uint32_t i = 0; i < current_length; i++) {
   10094       HandleScope loop_scope(isolate_);
   10095       Handle<Object> element(current_storage->get(i), isolate_);
   10096       if (!element->IsTheHole()) {
   10097         Handle<SeededNumberDictionary> new_storage =
   10098             SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
   10099         if (!new_storage.is_identical_to(slow_storage)) {
   10100           slow_storage = loop_scope.CloseAndEscape(new_storage);
   10101         }
   10102       }
   10103     }
   10104     clear_storage();
   10105     set_storage(*slow_storage);
   10106     fast_elements_ = false;
   10107   }
   10108 
   10109   inline void clear_storage() {
   10110     GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
   10111   }
   10112 
   10113   inline void set_storage(FixedArray* storage) {
   10114     storage_ = Handle<FixedArray>::cast(
   10115         isolate_->global_handles()->Create(storage));
   10116   }
   10117 
   10118   Isolate* isolate_;
   10119   Handle<FixedArray> storage_;  // Always a global handle.
   10120   // Index after last seen index. Always less than or equal to
   10121   // JSObject::kMaxElementCount.
   10122   uint32_t index_offset_;
   10123   bool fast_elements_ : 1;
   10124   bool exceeds_array_limit_ : 1;
   10125 };
   10126 
   10127 
   10128 static uint32_t EstimateElementCount(Handle<JSArray> array) {
   10129   uint32_t length = static_cast<uint32_t>(array->length()->Number());
   10130   int element_count = 0;
   10131   switch (array->GetElementsKind()) {
   10132     case FAST_SMI_ELEMENTS:
   10133     case FAST_HOLEY_SMI_ELEMENTS:
   10134     case FAST_ELEMENTS:
   10135     case FAST_HOLEY_ELEMENTS: {
   10136       // Fast elements can't have lengths that are not representable by
   10137       // a 32-bit signed integer.
   10138       ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
   10139       int fast_length = static_cast<int>(length);
   10140       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
   10141       for (int i = 0; i < fast_length; i++) {
   10142         if (!elements->get(i)->IsTheHole()) element_count++;
   10143       }
   10144       break;
   10145     }
   10146     case FAST_DOUBLE_ELEMENTS:
   10147     case FAST_HOLEY_DOUBLE_ELEMENTS: {
   10148       // Fast elements can't have lengths that are not representable by
   10149       // a 32-bit signed integer.
   10150       ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
   10151       int fast_length = static_cast<int>(length);
   10152       if (array->elements()->IsFixedArray()) {
   10153         ASSERT(FixedArray::cast(array->elements())->length() == 0);
   10154         break;
   10155       }
   10156       Handle<FixedDoubleArray> elements(
   10157           FixedDoubleArray::cast(array->elements()));
   10158       for (int i = 0; i < fast_length; i++) {
   10159         if (!elements->is_the_hole(i)) element_count++;
   10160       }
   10161       break;
   10162     }
   10163     case DICTIONARY_ELEMENTS: {
   10164       Handle<SeededNumberDictionary> dictionary(
   10165           SeededNumberDictionary::cast(array->elements()));
   10166       int capacity = dictionary->Capacity();
   10167       for (int i = 0; i < capacity; i++) {
   10168         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
   10169         if (dictionary->IsKey(*key)) {
   10170           element_count++;
   10171         }
   10172       }
   10173       break;
   10174     }
   10175     case SLOPPY_ARGUMENTS_ELEMENTS:
   10176 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
   10177     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
   10178     case TYPE##_ELEMENTS:                                                    \
   10179 
   10180     TYPED_ARRAYS(TYPED_ARRAY_CASE)
   10181 #undef TYPED_ARRAY_CASE
   10182       // External arrays are always dense.
   10183       return length;
   10184   }
   10185   // As an estimate, we assume that the prototype doesn't contain any
   10186   // inherited elements.
   10187   return element_count;
   10188 }
   10189 
   10190 
   10191 
   10192 template<class ExternalArrayClass, class ElementType>
   10193 static void IterateExternalArrayElements(Isolate* isolate,
   10194                                          Handle<JSObject> receiver,
   10195                                          bool elements_are_ints,
   10196                                          bool elements_are_guaranteed_smis,
   10197                                          ArrayConcatVisitor* visitor) {
   10198   Handle<ExternalArrayClass> array(
   10199       ExternalArrayClass::cast(receiver->elements()));
   10200   uint32_t len = static_cast<uint32_t>(array->length());
   10201 
   10202   ASSERT(visitor != NULL);
   10203   if (elements_are_ints) {
   10204     if (elements_are_guaranteed_smis) {
   10205       for (uint32_t j = 0; j < len; j++) {
   10206         HandleScope loop_scope(isolate);
   10207         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
   10208                       isolate);
   10209         visitor->visit(j, e);
   10210       }
   10211     } else {
   10212       for (uint32_t j = 0; j < len; j++) {
   10213         HandleScope loop_scope(isolate);
   10214         int64_t val = static_cast<int64_t>(array->get_scalar(j));
   10215         if (Smi::IsValid(static_cast<intptr_t>(val))) {
   10216           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
   10217           visitor->visit(j, e);
   10218         } else {
   10219           Handle<Object> e =
   10220               isolate->factory()->NewNumber(static_cast<ElementType>(val));
   10221           visitor->visit(j, e);
   10222         }
   10223       }
   10224     }
   10225   } else {
   10226     for (uint32_t j = 0; j < len; j++) {
   10227       HandleScope loop_scope(isolate);
   10228       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
   10229       visitor->visit(j, e);
   10230     }
   10231   }
   10232 }
   10233 
   10234 
   10235 // Used for sorting indices in a List<uint32_t>.
   10236 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
   10237   uint32_t a = *ap;
   10238   uint32_t b = *bp;
   10239   return (a == b) ? 0 : (a < b) ? -1 : 1;
   10240 }
   10241 
   10242 
   10243 static void CollectElementIndices(Handle<JSObject> object,
   10244                                   uint32_t range,
   10245                                   List<uint32_t>* indices) {
   10246   Isolate* isolate = object->GetIsolate();
   10247   ElementsKind kind = object->GetElementsKind();
   10248   switch (kind) {
   10249     case FAST_SMI_ELEMENTS:
   10250     case FAST_ELEMENTS:
   10251     case FAST_HOLEY_SMI_ELEMENTS:
   10252     case FAST_HOLEY_ELEMENTS: {
   10253       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
   10254       uint32_t length = static_cast<uint32_t>(elements->length());
   10255       if (range < length) length = range;
   10256       for (uint32_t i = 0; i < length; i++) {
   10257         if (!elements->get(i)->IsTheHole()) {
   10258           indices->Add(i);
   10259         }
   10260       }
   10261       break;
   10262     }
   10263     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10264     case FAST_DOUBLE_ELEMENTS: {
   10265       // TODO(1810): Decide if it's worthwhile to implement this.
   10266       UNREACHABLE();
   10267       break;
   10268     }
   10269     case DICTIONARY_ELEMENTS: {
   10270       Handle<SeededNumberDictionary> dict(
   10271           SeededNumberDictionary::cast(object->elements()));
   10272       uint32_t capacity = dict->Capacity();
   10273       for (uint32_t j = 0; j < capacity; j++) {
   10274         HandleScope loop_scope(isolate);
   10275         Handle<Object> k(dict->KeyAt(j), isolate);
   10276         if (dict->IsKey(*k)) {
   10277           ASSERT(k->IsNumber());
   10278           uint32_t index = static_cast<uint32_t>(k->Number());
   10279           if (index < range) {
   10280             indices->Add(index);
   10281           }
   10282         }
   10283       }
   10284       break;
   10285     }
   10286     default: {
   10287       int dense_elements_length;
   10288       switch (kind) {
   10289 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
   10290         case EXTERNAL_##TYPE##_ELEMENTS: {                                     \
   10291           dense_elements_length =                                              \
   10292               External##Type##Array::cast(object->elements())->length();       \
   10293           break;                                                               \
   10294         }
   10295 
   10296         TYPED_ARRAYS(TYPED_ARRAY_CASE)
   10297 #undef TYPED_ARRAY_CASE
   10298 
   10299         default:
   10300           UNREACHABLE();
   10301           dense_elements_length = 0;
   10302           break;
   10303       }
   10304       uint32_t length = static_cast<uint32_t>(dense_elements_length);
   10305       if (range <= length) {
   10306         length = range;
   10307         // We will add all indices, so we might as well clear it first
   10308         // and avoid duplicates.
   10309         indices->Clear();
   10310       }
   10311       for (uint32_t i = 0; i < length; i++) {
   10312         indices->Add(i);
   10313       }
   10314       if (length == range) return;  // All indices accounted for already.
   10315       break;
   10316     }
   10317   }
   10318 
   10319   Handle<Object> prototype(object->GetPrototype(), isolate);
   10320   if (prototype->IsJSObject()) {
   10321     // The prototype will usually have no inherited element indices,
   10322     // but we have to check.
   10323     CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
   10324   }
   10325 }
   10326 
   10327 
   10328 /**
   10329  * A helper function that visits elements of a JSArray in numerical
   10330  * order.
   10331  *
   10332  * The visitor argument called for each existing element in the array
   10333  * with the element index and the element's value.
   10334  * Afterwards it increments the base-index of the visitor by the array
   10335  * length.
   10336  * Returns false if any access threw an exception, otherwise true.
   10337  */
   10338 static bool IterateElements(Isolate* isolate,
   10339                             Handle<JSArray> receiver,
   10340                             ArrayConcatVisitor* visitor) {
   10341   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
   10342   switch (receiver->GetElementsKind()) {
   10343     case FAST_SMI_ELEMENTS:
   10344     case FAST_ELEMENTS:
   10345     case FAST_HOLEY_SMI_ELEMENTS:
   10346     case FAST_HOLEY_ELEMENTS: {
   10347       // Run through the elements FixedArray and use HasElement and GetElement
   10348       // to check the prototype for missing elements.
   10349       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
   10350       int fast_length = static_cast<int>(length);
   10351       ASSERT(fast_length <= elements->length());
   10352       for (int j = 0; j < fast_length; j++) {
   10353         HandleScope loop_scope(isolate);
   10354         Handle<Object> element_value(elements->get(j), isolate);
   10355         if (!element_value->IsTheHole()) {
   10356           visitor->visit(j, element_value);
   10357         } else if (JSReceiver::HasElement(receiver, j)) {
   10358           // Call GetElement on receiver, not its prototype, or getters won't
   10359           // have the correct receiver.
   10360           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   10361               isolate, element_value,
   10362               Object::GetElement(isolate, receiver, j),
   10363               false);
   10364           visitor->visit(j, element_value);
   10365         }
   10366       }
   10367       break;
   10368     }
   10369     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10370     case FAST_DOUBLE_ELEMENTS: {
   10371       // Empty array is FixedArray but not FixedDoubleArray.
   10372       if (length == 0) break;
   10373       // Run through the elements FixedArray and use HasElement and GetElement
   10374       // to check the prototype for missing elements.
   10375       if (receiver->elements()->IsFixedArray()) {
   10376         ASSERT(receiver->elements()->length() == 0);
   10377         break;
   10378       }
   10379       Handle<FixedDoubleArray> elements(
   10380           FixedDoubleArray::cast(receiver->elements()));
   10381       int fast_length = static_cast<int>(length);
   10382       ASSERT(fast_length <= elements->length());
   10383       for (int j = 0; j < fast_length; j++) {
   10384         HandleScope loop_scope(isolate);
   10385         if (!elements->is_the_hole(j)) {
   10386           double double_value = elements->get_scalar(j);
   10387           Handle<Object> element_value =
   10388               isolate->factory()->NewNumber(double_value);
   10389           visitor->visit(j, element_value);
   10390         } else if (JSReceiver::HasElement(receiver, j)) {
   10391           // Call GetElement on receiver, not its prototype, or getters won't
   10392           // have the correct receiver.
   10393           Handle<Object> element_value;
   10394           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   10395               isolate, element_value,
   10396               Object::GetElement(isolate, receiver, j),
   10397               false);
   10398           visitor->visit(j, element_value);
   10399         }
   10400       }
   10401       break;
   10402     }
   10403     case DICTIONARY_ELEMENTS: {
   10404       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
   10405       List<uint32_t> indices(dict->Capacity() / 2);
   10406       // Collect all indices in the object and the prototypes less
   10407       // than length. This might introduce duplicates in the indices list.
   10408       CollectElementIndices(receiver, length, &indices);
   10409       indices.Sort(&compareUInt32);
   10410       int j = 0;
   10411       int n = indices.length();
   10412       while (j < n) {
   10413         HandleScope loop_scope(isolate);
   10414         uint32_t index = indices[j];
   10415         Handle<Object> element;
   10416         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   10417             isolate, element,
   10418             Object::GetElement(isolate, receiver, index),
   10419             false);
   10420         visitor->visit(index, element);
   10421         // Skip to next different index (i.e., omit duplicates).
   10422         do {
   10423           j++;
   10424         } while (j < n && indices[j] == index);
   10425       }
   10426       break;
   10427     }
   10428     case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
   10429       Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
   10430           receiver->elements()));
   10431       for (uint32_t j = 0; j < length; j++) {
   10432         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
   10433         visitor->visit(j, e);
   10434       }
   10435       break;
   10436     }
   10437     case EXTERNAL_INT8_ELEMENTS: {
   10438       IterateExternalArrayElements<ExternalInt8Array, int8_t>(
   10439           isolate, receiver, true, true, visitor);
   10440       break;
   10441     }
   10442     case EXTERNAL_UINT8_ELEMENTS: {
   10443       IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
   10444           isolate, receiver, true, true, visitor);
   10445       break;
   10446     }
   10447     case EXTERNAL_INT16_ELEMENTS: {
   10448       IterateExternalArrayElements<ExternalInt16Array, int16_t>(
   10449           isolate, receiver, true, true, visitor);
   10450       break;
   10451     }
   10452     case EXTERNAL_UINT16_ELEMENTS: {
   10453       IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
   10454           isolate, receiver, true, true, visitor);
   10455       break;
   10456     }
   10457     case EXTERNAL_INT32_ELEMENTS: {
   10458       IterateExternalArrayElements<ExternalInt32Array, int32_t>(
   10459           isolate, receiver, true, false, visitor);
   10460       break;
   10461     }
   10462     case EXTERNAL_UINT32_ELEMENTS: {
   10463       IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
   10464           isolate, receiver, true, false, visitor);
   10465       break;
   10466     }
   10467     case EXTERNAL_FLOAT32_ELEMENTS: {
   10468       IterateExternalArrayElements<ExternalFloat32Array, float>(
   10469           isolate, receiver, false, false, visitor);
   10470       break;
   10471     }
   10472     case EXTERNAL_FLOAT64_ELEMENTS: {
   10473       IterateExternalArrayElements<ExternalFloat64Array, double>(
   10474           isolate, receiver, false, false, visitor);
   10475       break;
   10476     }
   10477     default:
   10478       UNREACHABLE();
   10479       break;
   10480   }
   10481   visitor->increase_index_offset(length);
   10482   return true;
   10483 }
   10484 
   10485 
   10486 /**
   10487  * Array::concat implementation.
   10488  * See ECMAScript 262, 15.4.4.4.
   10489  * TODO(581): Fix non-compliance for very large concatenations and update to
   10490  * following the ECMAScript 5 specification.
   10491  */
   10492 RUNTIME_FUNCTION(Runtime_ArrayConcat) {
   10493   HandleScope handle_scope(isolate);
   10494   ASSERT(args.length() == 1);
   10495 
   10496   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
   10497   int argument_count = static_cast<int>(arguments->length()->Number());
   10498   RUNTIME_ASSERT(arguments->HasFastObjectElements());
   10499   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
   10500 
   10501   // Pass 1: estimate the length and number of elements of the result.
   10502   // The actual length can be larger if any of the arguments have getters
   10503   // that mutate other arguments (but will otherwise be precise).
   10504   // The number of elements is precise if there are no inherited elements.
   10505 
   10506   ElementsKind kind = FAST_SMI_ELEMENTS;
   10507 
   10508   uint32_t estimate_result_length = 0;
   10509   uint32_t estimate_nof_elements = 0;
   10510   for (int i = 0; i < argument_count; i++) {
   10511     HandleScope loop_scope(isolate);
   10512     Handle<Object> obj(elements->get(i), isolate);
   10513     uint32_t length_estimate;
   10514     uint32_t element_estimate;
   10515     if (obj->IsJSArray()) {
   10516       Handle<JSArray> array(Handle<JSArray>::cast(obj));
   10517       length_estimate = static_cast<uint32_t>(array->length()->Number());
   10518       if (length_estimate != 0) {
   10519         ElementsKind array_kind =
   10520             GetPackedElementsKind(array->map()->elements_kind());
   10521         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
   10522           kind = array_kind;
   10523         }
   10524       }
   10525       element_estimate = EstimateElementCount(array);
   10526     } else {
   10527       if (obj->IsHeapObject()) {
   10528         if (obj->IsNumber()) {
   10529           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
   10530             kind = FAST_DOUBLE_ELEMENTS;
   10531           }
   10532         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
   10533           kind = FAST_ELEMENTS;
   10534         }
   10535       }
   10536       length_estimate = 1;
   10537       element_estimate = 1;
   10538     }
   10539     // Avoid overflows by capping at kMaxElementCount.
   10540     if (JSObject::kMaxElementCount - estimate_result_length <
   10541         length_estimate) {
   10542       estimate_result_length = JSObject::kMaxElementCount;
   10543     } else {
   10544       estimate_result_length += length_estimate;
   10545     }
   10546     if (JSObject::kMaxElementCount - estimate_nof_elements <
   10547         element_estimate) {
   10548       estimate_nof_elements = JSObject::kMaxElementCount;
   10549     } else {
   10550       estimate_nof_elements += element_estimate;
   10551     }
   10552   }
   10553 
   10554   // If estimated number of elements is more than half of length, a
   10555   // fixed array (fast case) is more time and space-efficient than a
   10556   // dictionary.
   10557   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
   10558 
   10559   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
   10560     Handle<FixedArrayBase> storage =
   10561         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
   10562     int j = 0;
   10563     if (estimate_result_length > 0) {
   10564       Handle<FixedDoubleArray> double_storage =
   10565           Handle<FixedDoubleArray>::cast(storage);
   10566       bool failure = false;
   10567       for (int i = 0; i < argument_count; i++) {
   10568         Handle<Object> obj(elements->get(i), isolate);
   10569         if (obj->IsSmi()) {
   10570           double_storage->set(j, Smi::cast(*obj)->value());
   10571           j++;
   10572         } else if (obj->IsNumber()) {
   10573           double_storage->set(j, obj->Number());
   10574           j++;
   10575         } else {
   10576           JSArray* array = JSArray::cast(*obj);
   10577           uint32_t length = static_cast<uint32_t>(array->length()->Number());
   10578           switch (array->map()->elements_kind()) {
   10579             case FAST_HOLEY_DOUBLE_ELEMENTS:
   10580             case FAST_DOUBLE_ELEMENTS: {
   10581               // Empty array is FixedArray but not FixedDoubleArray.
   10582               if (length == 0) break;
   10583               FixedDoubleArray* elements =
   10584                   FixedDoubleArray::cast(array->elements());
   10585               for (uint32_t i = 0; i < length; i++) {
   10586                 if (elements->is_the_hole(i)) {
   10587                   failure = true;
   10588                   break;
   10589                 }
   10590                 double double_value = elements->get_scalar(i);
   10591                 double_storage->set(j, double_value);
   10592                 j++;
   10593               }
   10594               break;
   10595             }
   10596             case FAST_HOLEY_SMI_ELEMENTS:
   10597             case FAST_SMI_ELEMENTS: {
   10598               FixedArray* elements(
   10599                   FixedArray::cast(array->elements()));
   10600               for (uint32_t i = 0; i < length; i++) {
   10601                 Object* element = elements->get(i);
   10602                 if (element->IsTheHole()) {
   10603                   failure = true;
   10604                   break;
   10605                 }
   10606                 int32_t int_value = Smi::cast(element)->value();
   10607                 double_storage->set(j, int_value);
   10608                 j++;
   10609               }
   10610               break;
   10611             }
   10612             case FAST_HOLEY_ELEMENTS:
   10613               ASSERT_EQ(0, length);
   10614               break;
   10615             default:
   10616               UNREACHABLE();
   10617           }
   10618         }
   10619         if (failure) break;
   10620       }
   10621     }
   10622     Handle<JSArray> array = isolate->factory()->NewJSArray(0);
   10623     Smi* length = Smi::FromInt(j);
   10624     Handle<Map> map;
   10625     map = JSObject::GetElementsTransitionMap(array, kind);
   10626     array->set_map(*map);
   10627     array->set_length(length);
   10628     array->set_elements(*storage);
   10629     return *array;
   10630   }
   10631 
   10632   Handle<FixedArray> storage;
   10633   if (fast_case) {
   10634     // The backing storage array must have non-existing elements to preserve
   10635     // holes across concat operations.
   10636     storage = isolate->factory()->NewFixedArrayWithHoles(
   10637         estimate_result_length);
   10638   } else {
   10639     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
   10640     uint32_t at_least_space_for = estimate_nof_elements +
   10641                                   (estimate_nof_elements >> 2);
   10642     storage = Handle<FixedArray>::cast(
   10643         SeededNumberDictionary::New(isolate, at_least_space_for));
   10644   }
   10645 
   10646   ArrayConcatVisitor visitor(isolate, storage, fast_case);
   10647 
   10648   for (int i = 0; i < argument_count; i++) {
   10649     Handle<Object> obj(elements->get(i), isolate);
   10650     if (obj->IsJSArray()) {
   10651       Handle<JSArray> array = Handle<JSArray>::cast(obj);
   10652       if (!IterateElements(isolate, array, &visitor)) {
   10653         return isolate->heap()->exception();
   10654       }
   10655     } else {
   10656       visitor.visit(0, obj);
   10657       visitor.increase_index_offset(1);
   10658     }
   10659   }
   10660 
   10661   if (visitor.exceeds_array_limit()) {
   10662     return isolate->Throw(
   10663         *isolate->factory()->NewRangeError("invalid_array_length",
   10664                                            HandleVector<Object>(NULL, 0)));
   10665   }
   10666   return *visitor.ToArray();
   10667 }
   10668 
   10669 
   10670 // This will not allocate (flatten the string), but it may run
   10671 // very slowly for very deeply nested ConsStrings.  For debugging use only.
   10672 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
   10673   SealHandleScope shs(isolate);
   10674   ASSERT(args.length() == 1);
   10675 
   10676   CONVERT_ARG_CHECKED(String, string, 0);
   10677   ConsStringIteratorOp op;
   10678   StringCharacterStream stream(string, &op);
   10679   while (stream.HasMore()) {
   10680     uint16_t character = stream.GetNext();
   10681     PrintF("%c", character);
   10682   }
   10683   return string;
   10684 }
   10685 
   10686 
   10687 // Moves all own elements of an object, that are below a limit, to positions
   10688 // starting at zero. All undefined values are placed after non-undefined values,
   10689 // and are followed by non-existing element. Does not change the length
   10690 // property.
   10691 // Returns the number of non-undefined elements collected.
   10692 // Returns -1 if hole removal is not supported by this method.
   10693 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
   10694   HandleScope scope(isolate);
   10695   ASSERT(args.length() == 2);
   10696   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   10697   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   10698   return *JSObject::PrepareElementsForSort(object, limit);
   10699 }
   10700 
   10701 
   10702 // Move contents of argument 0 (an array) to argument 1 (an array)
   10703 RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
   10704   HandleScope scope(isolate);
   10705   ASSERT(args.length() == 2);
   10706   CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
   10707   CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
   10708   JSObject::ValidateElements(from);
   10709   JSObject::ValidateElements(to);
   10710 
   10711   Handle<FixedArrayBase> new_elements(from->elements());
   10712   ElementsKind from_kind = from->GetElementsKind();
   10713   Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
   10714   JSObject::SetMapAndElements(to, new_map, new_elements);
   10715   to->set_length(from->length());
   10716 
   10717   JSObject::ResetElements(from);
   10718   from->set_length(Smi::FromInt(0));
   10719 
   10720   JSObject::ValidateElements(to);
   10721   return *to;
   10722 }
   10723 
   10724 
   10725 // How many elements does this object/array have?
   10726 RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
   10727   SealHandleScope shs(isolate);
   10728   ASSERT(args.length() == 1);
   10729   CONVERT_ARG_CHECKED(JSArray, object, 0);
   10730   HeapObject* elements = object->elements();
   10731   if (elements->IsDictionary()) {
   10732     int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
   10733     return Smi::FromInt(result);
   10734   } else {
   10735     return object->length();
   10736   }
   10737 }
   10738 
   10739 
   10740 // Returns an array that tells you where in the [0, length) interval an array
   10741 // might have elements.  Can either return an array of keys (positive integers
   10742 // or undefined) or a number representing the positive length of an interval
   10743 // starting at index 0.
   10744 // Intervals can span over some keys that are not in the object.
   10745 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
   10746   HandleScope scope(isolate);
   10747   ASSERT(args.length() == 2);
   10748   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   10749   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
   10750   if (array->elements()->IsDictionary()) {
   10751     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
   10752     for (Handle<Object> p = array;
   10753          !p->IsNull();
   10754          p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
   10755       if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
   10756         // Bail out if we find a proxy or interceptor, likely not worth
   10757         // collecting keys in that case.
   10758         return *isolate->factory()->NewNumberFromUint(length);
   10759       }
   10760       Handle<JSObject> current = Handle<JSObject>::cast(p);
   10761       Handle<FixedArray> current_keys =
   10762           isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
   10763       current->GetOwnElementKeys(*current_keys, NONE);
   10764       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   10765           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
   10766     }
   10767     // Erase any keys >= length.
   10768     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
   10769     // is changed to let this happen on the JS side.
   10770     for (int i = 0; i < keys->length(); i++) {
   10771       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
   10772     }
   10773     return *isolate->factory()->NewJSArrayWithElements(keys);
   10774   } else {
   10775     RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
   10776                    array->HasFastDoubleElements());
   10777     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
   10778     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
   10779   }
   10780 }
   10781 
   10782 
   10783 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
   10784   HandleScope scope(isolate);
   10785   ASSERT(args.length() == 3);
   10786   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   10787   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10788   CONVERT_SMI_ARG_CHECKED(flag, 2);
   10789   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
   10790   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
   10791   Handle<Object> result;
   10792   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   10793       isolate, result,
   10794       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
   10795   return *result;
   10796 }
   10797 
   10798 
   10799 RUNTIME_FUNCTION(Runtime_DebugBreak) {
   10800   SealHandleScope shs(isolate);
   10801   ASSERT(args.length() == 0);
   10802   isolate->debug()->HandleDebugBreak();
   10803   return isolate->heap()->undefined_value();
   10804 }
   10805 
   10806 
   10807 // Helper functions for wrapping and unwrapping stack frame ids.
   10808 static Smi* WrapFrameId(StackFrame::Id id) {
   10809   ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
   10810   return Smi::FromInt(id >> 2);
   10811 }
   10812 
   10813 
   10814 static StackFrame::Id UnwrapFrameId(int wrapped) {
   10815   return static_cast<StackFrame::Id>(wrapped << 2);
   10816 }
   10817 
   10818 
   10819 // Adds a JavaScript function as a debug event listener.
   10820 // args[0]: debug event listener function to set or null or undefined for
   10821 //          clearing the event listener function
   10822 // args[1]: object supplied during callback
   10823 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
   10824   SealHandleScope shs(isolate);
   10825   ASSERT(args.length() == 2);
   10826   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
   10827                  args[0]->IsUndefined() ||
   10828                  args[0]->IsNull());
   10829   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
   10830   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
   10831   isolate->debug()->SetEventListener(callback, data);
   10832 
   10833   return isolate->heap()->undefined_value();
   10834 }
   10835 
   10836 
   10837 RUNTIME_FUNCTION(Runtime_Break) {
   10838   SealHandleScope shs(isolate);
   10839   ASSERT(args.length() == 0);
   10840   isolate->stack_guard()->RequestDebugBreak();
   10841   return isolate->heap()->undefined_value();
   10842 }
   10843 
   10844 
   10845 static Handle<Object> DebugLookupResultValue(Isolate* isolate,
   10846                                              Handle<Object> receiver,
   10847                                              Handle<Name> name,
   10848                                              LookupResult* result,
   10849                                              bool* has_caught = NULL) {
   10850   Handle<Object> value = isolate->factory()->undefined_value();
   10851   if  (!result->IsFound()) return value;
   10852   switch (result->type()) {
   10853     case NORMAL:
   10854       value = JSObject::GetNormalizedProperty(
   10855           handle(result->holder(), isolate), result);
   10856       break;
   10857     case FIELD:
   10858       value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
   10859                                        result->representation(),
   10860                                        result->GetFieldIndex());
   10861       break;
   10862     case CONSTANT:
   10863       return handle(result->GetConstant(), isolate);
   10864     case CALLBACKS: {
   10865       Handle<Object> structure(result->GetCallbackObject(), isolate);
   10866       ASSERT(!structure->IsForeign());
   10867       if (structure->IsAccessorInfo()) {
   10868         MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor(
   10869             receiver, name, handle(result->holder(), isolate), structure);
   10870         if (!obj.ToHandle(&value)) {
   10871           value = handle(isolate->pending_exception(), isolate);
   10872           isolate->clear_pending_exception();
   10873           if (has_caught != NULL) *has_caught = true;
   10874           return value;
   10875         }
   10876       }
   10877       break;
   10878     }
   10879     case INTERCEPTOR:
   10880     case HANDLER:
   10881       break;
   10882     case NONEXISTENT:
   10883       UNREACHABLE();
   10884       break;
   10885   }
   10886   ASSERT(!value->IsTheHole() || result->IsReadOnly());
   10887   return value->IsTheHole()
   10888       ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value;
   10889 }
   10890 
   10891 
   10892 // Get debugger related details for an object property.
   10893 // args[0]: object holding property
   10894 // args[1]: name of the property
   10895 //
   10896 // The array returned contains the following information:
   10897 // 0: Property value
   10898 // 1: Property details
   10899 // 2: Property value is exception
   10900 // 3: Getter function if defined
   10901 // 4: Setter function if defined
   10902 // Items 2-4 are only filled if the property has either a getter or a setter
   10903 // defined through __defineGetter__ and/or __defineSetter__.
   10904 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
   10905   HandleScope scope(isolate);
   10906 
   10907   ASSERT(args.length() == 2);
   10908 
   10909   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10910   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10911 
   10912   // Make sure to set the current context to the context before the debugger was
   10913   // entered (if the debugger is entered). The reason for switching context here
   10914   // is that for some property lookups (accessors and interceptors) callbacks
   10915   // into the embedding application can occour, and the embedding application
   10916   // could have the assumption that its own native context is the current
   10917   // context and not some internal debugger context.
   10918   SaveContext save(isolate);
   10919   if (isolate->debug()->in_debug_scope()) {
   10920     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
   10921   }
   10922 
   10923   // Skip the global proxy as it has no properties and always delegates to the
   10924   // real global object.
   10925   if (obj->IsJSGlobalProxy()) {
   10926     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   10927   }
   10928 
   10929 
   10930   // Check if the name is trivially convertible to an index and get the element
   10931   // if so.
   10932   uint32_t index;
   10933   if (name->AsArrayIndex(&index)) {
   10934     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
   10935     Handle<Object> element_or_char;
   10936     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   10937         isolate, element_or_char,
   10938         Runtime::GetElementOrCharAt(isolate, obj, index));
   10939     details->set(0, *element_or_char);
   10940     details->set(
   10941         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
   10942     return *isolate->factory()->NewJSArrayWithElements(details);
   10943   }
   10944 
   10945   // Find the number of objects making up this.
   10946   int length = OwnPrototypeChainLength(*obj);
   10947 
   10948   // Try own lookup on each of the objects.
   10949   Handle<JSObject> jsproto = obj;
   10950   for (int i = 0; i < length; i++) {
   10951     LookupResult result(isolate);
   10952     jsproto->LookupOwn(name, &result);
   10953     if (result.IsFound()) {
   10954       // LookupResult is not GC safe as it holds raw object pointers.
   10955       // GC can happen later in this code so put the required fields into
   10956       // local variables using handles when required for later use.
   10957       Handle<Object> result_callback_obj;
   10958       if (result.IsPropertyCallbacks()) {
   10959         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
   10960                                              isolate);
   10961       }
   10962 
   10963 
   10964       bool has_caught = false;
   10965       Handle<Object> value = DebugLookupResultValue(
   10966           isolate, obj, name, &result, &has_caught);
   10967 
   10968       // If the callback object is a fixed array then it contains JavaScript
   10969       // getter and/or setter.
   10970       bool has_js_accessors = result.IsPropertyCallbacks() &&
   10971                               result_callback_obj->IsAccessorPair();
   10972       Handle<FixedArray> details =
   10973           isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
   10974       details->set(0, *value);
   10975       details->set(1, result.GetPropertyDetails().AsSmi());
   10976       if (has_js_accessors) {
   10977         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
   10978         details->set(2, isolate->heap()->ToBoolean(has_caught));
   10979         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
   10980         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
   10981       }
   10982 
   10983       return *isolate->factory()->NewJSArrayWithElements(details);
   10984     }
   10985     if (i < length - 1) {
   10986       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   10987     }
   10988   }
   10989 
   10990   return isolate->heap()->undefined_value();
   10991 }
   10992 
   10993 
   10994 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
   10995   HandleScope scope(isolate);
   10996 
   10997   ASSERT(args.length() == 2);
   10998 
   10999   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   11000   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   11001 
   11002   LookupResult result(isolate);
   11003   obj->Lookup(name, &result);
   11004   return *DebugLookupResultValue(isolate, obj, name, &result);
   11005 }
   11006 
   11007 
   11008 // Return the property type calculated from the property details.
   11009 // args[0]: smi with property details.
   11010 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
   11011   SealHandleScope shs(isolate);
   11012   ASSERT(args.length() == 1);
   11013   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   11014   return Smi::FromInt(static_cast<int>(details.type()));
   11015 }
   11016 
   11017 
   11018 // Return the property attribute calculated from the property details.
   11019 // args[0]: smi with property details.
   11020 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
   11021   SealHandleScope shs(isolate);
   11022   ASSERT(args.length() == 1);
   11023   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   11024   return Smi::FromInt(static_cast<int>(details.attributes()));
   11025 }
   11026 
   11027 
   11028 // Return the property insertion index calculated from the property details.
   11029 // args[0]: smi with property details.
   11030 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
   11031   SealHandleScope shs(isolate);
   11032   ASSERT(args.length() == 1);
   11033   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   11034   // TODO(verwaest): Depends on the type of details.
   11035   return Smi::FromInt(details.dictionary_index());
   11036 }
   11037 
   11038 
   11039 // Return property value from named interceptor.
   11040 // args[0]: object
   11041 // args[1]: property name
   11042 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
   11043   HandleScope scope(isolate);
   11044   ASSERT(args.length() == 2);
   11045   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   11046   RUNTIME_ASSERT(obj->HasNamedInterceptor());
   11047   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   11048 
   11049   Handle<Object> result;
   11050   LookupIterator it(obj, name, obj);
   11051   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   11052       isolate, result, JSObject::GetProperty(&it));
   11053   return *result;
   11054 }
   11055 
   11056 
   11057 // Return element value from indexed interceptor.
   11058 // args[0]: object
   11059 // args[1]: index
   11060 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
   11061   HandleScope scope(isolate);
   11062   ASSERT(args.length() == 2);
   11063   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   11064   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
   11065   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
   11066   Handle<Object> result;
   11067   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   11068       isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
   11069   return *result;
   11070 }
   11071 
   11072 
   11073 static bool CheckExecutionState(Isolate* isolate, int break_id) {
   11074   return !isolate->debug()->debug_context().is_null() &&
   11075          isolate->debug()->break_id() != 0 &&
   11076          isolate->debug()->break_id() == break_id;
   11077 }
   11078 
   11079 
   11080 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
   11081   SealHandleScope shs(isolate);
   11082   ASSERT(args.length() == 1);
   11083   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   11084   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   11085   return isolate->heap()->true_value();
   11086 }
   11087 
   11088 
   11089 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
   11090   HandleScope scope(isolate);
   11091   ASSERT(args.length() == 1);
   11092   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   11093   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   11094 
   11095   // Count all frames which are relevant to debugging stack trace.
   11096   int n = 0;
   11097   StackFrame::Id id = isolate->debug()->break_frame_id();
   11098   if (id == StackFrame::NO_ID) {
   11099     // If there is no JavaScript stack frame count is 0.
   11100     return Smi::FromInt(0);
   11101   }
   11102 
   11103   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
   11104     n += it.frame()->GetInlineCount();
   11105   }
   11106   return Smi::FromInt(n);
   11107 }
   11108 
   11109 
   11110 class FrameInspector {
   11111  public:
   11112   FrameInspector(JavaScriptFrame* frame,
   11113                  int inlined_jsframe_index,
   11114                  Isolate* isolate)
   11115       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
   11116     // Calculate the deoptimized frame.
   11117     if (frame->is_optimized()) {
   11118       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
   11119           frame, inlined_jsframe_index, isolate);
   11120     }
   11121     has_adapted_arguments_ = frame_->has_adapted_arguments();
   11122     is_bottommost_ = inlined_jsframe_index == 0;
   11123     is_optimized_ = frame_->is_optimized();
   11124   }
   11125 
   11126   ~FrameInspector() {
   11127     // Get rid of the calculated deoptimized frame if any.
   11128     if (deoptimized_frame_ != NULL) {
   11129       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
   11130                                                   isolate_);
   11131     }
   11132   }
   11133 
   11134   int GetParametersCount() {
   11135     return is_optimized_
   11136         ? deoptimized_frame_->parameters_count()
   11137         : frame_->ComputeParametersCount();
   11138   }
   11139   int expression_count() { return deoptimized_frame_->expression_count(); }
   11140   Object* GetFunction() {
   11141     return is_optimized_
   11142         ? deoptimized_frame_->GetFunction()
   11143         : frame_->function();
   11144   }
   11145   Object* GetParameter(int index) {
   11146     return is_optimized_
   11147         ? deoptimized_frame_->GetParameter(index)
   11148         : frame_->GetParameter(index);
   11149   }
   11150   Object* GetExpression(int index) {
   11151     return is_optimized_
   11152         ? deoptimized_frame_->GetExpression(index)
   11153         : frame_->GetExpression(index);
   11154   }
   11155   int GetSourcePosition() {
   11156     return is_optimized_
   11157         ? deoptimized_frame_->GetSourcePosition()
   11158         : frame_->LookupCode()->SourcePosition(frame_->pc());
   11159   }
   11160   bool IsConstructor() {
   11161     return is_optimized_ && !is_bottommost_
   11162         ? deoptimized_frame_->HasConstructStub()
   11163         : frame_->IsConstructor();
   11164   }
   11165 
   11166   // To inspect all the provided arguments the frame might need to be
   11167   // replaced with the arguments frame.
   11168   void SetArgumentsFrame(JavaScriptFrame* frame) {
   11169     ASSERT(has_adapted_arguments_);
   11170     frame_ = frame;
   11171     is_optimized_ = frame_->is_optimized();
   11172     ASSERT(!is_optimized_);
   11173   }
   11174 
   11175  private:
   11176   JavaScriptFrame* frame_;
   11177   DeoptimizedFrameInfo* deoptimized_frame_;
   11178   Isolate* isolate_;
   11179   bool is_optimized_;
   11180   bool is_bottommost_;
   11181   bool has_adapted_arguments_;
   11182 
   11183   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
   11184 };
   11185 
   11186 
   11187 static const int kFrameDetailsFrameIdIndex = 0;
   11188 static const int kFrameDetailsReceiverIndex = 1;
   11189 static const int kFrameDetailsFunctionIndex = 2;
   11190 static const int kFrameDetailsArgumentCountIndex = 3;
   11191 static const int kFrameDetailsLocalCountIndex = 4;
   11192 static const int kFrameDetailsSourcePositionIndex = 5;
   11193 static const int kFrameDetailsConstructCallIndex = 6;
   11194 static const int kFrameDetailsAtReturnIndex = 7;
   11195 static const int kFrameDetailsFlagsIndex = 8;
   11196 static const int kFrameDetailsFirstDynamicIndex = 9;
   11197 
   11198 
   11199 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
   11200                                              JavaScriptFrame* frame) {
   11201   SaveContext* save = isolate->save_context();
   11202   while (save != NULL && !save->IsBelowFrame(frame)) {
   11203     save = save->prev();
   11204   }
   11205   ASSERT(save != NULL);
   11206   return save;
   11207 }
   11208 
   11209 
   11210 // Return an array with frame details
   11211 // args[0]: number: break id
   11212 // args[1]: number: frame index
   11213 //
   11214 // The array returned contains the following information:
   11215 // 0: Frame id
   11216 // 1: Receiver
   11217 // 2: Function
   11218 // 3: Argument count
   11219 // 4: Local count
   11220 // 5: Source position
   11221 // 6: Constructor call
   11222 // 7: Is at return
   11223 // 8: Flags
   11224 // Arguments name, value
   11225 // Locals name, value
   11226 // Return value if any
   11227 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
   11228   HandleScope scope(isolate);
   11229   ASSERT(args.length() == 2);
   11230   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   11231   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   11232 
   11233   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   11234   Heap* heap = isolate->heap();
   11235 
   11236   // Find the relevant frame with the requested index.
   11237   StackFrame::Id id = isolate->debug()->break_frame_id();
   11238   if (id == StackFrame::NO_ID) {
   11239     // If there are no JavaScript stack frames return undefined.
   11240     return heap->undefined_value();
   11241   }
   11242 
   11243   int count = 0;
   11244   JavaScriptFrameIterator it(isolate, id);
   11245   for (; !it.done(); it.Advance()) {
   11246     if (index < count + it.frame()->GetInlineCount()) break;
   11247     count += it.frame()->GetInlineCount();
   11248   }
   11249   if (it.done()) return heap->undefined_value();
   11250 
   11251   bool is_optimized = it.frame()->is_optimized();
   11252 
   11253   int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
   11254   if (is_optimized) {
   11255     inlined_jsframe_index =
   11256         it.frame()->GetInlineCount() - (index - count) - 1;
   11257   }
   11258   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
   11259 
   11260   // Traverse the saved contexts chain to find the active context for the
   11261   // selected frame.
   11262   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
   11263 
   11264   // Get the frame id.
   11265   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
   11266 
   11267   // Find source position in unoptimized code.
   11268   int position = frame_inspector.GetSourcePosition();
   11269 
   11270   // Check for constructor frame.
   11271   bool constructor = frame_inspector.IsConstructor();
   11272 
   11273   // Get scope info and read from it for local variable information.
   11274   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11275   Handle<SharedFunctionInfo> shared(function->shared());
   11276   Handle<ScopeInfo> scope_info(shared->scope_info());
   11277   ASSERT(*scope_info != ScopeInfo::Empty(isolate));
   11278 
   11279   // Get the locals names and values into a temporary array.
   11280   int local_count = scope_info->LocalCount();
   11281   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
   11282     // Hide compiler-introduced temporary variables, whether on the stack or on
   11283     // the context.
   11284     if (scope_info->LocalIsSynthetic(slot))
   11285       local_count--;
   11286   }
   11287 
   11288   Handle<FixedArray> locals =
   11289       isolate->factory()->NewFixedArray(local_count * 2);
   11290 
   11291   // Fill in the values of the locals.
   11292   int local = 0;
   11293   int i = 0;
   11294   for (; i < scope_info->StackLocalCount(); ++i) {
   11295     // Use the value from the stack.
   11296     if (scope_info->LocalIsSynthetic(i))
   11297       continue;
   11298     locals->set(local * 2, scope_info->LocalName(i));
   11299     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
   11300     local++;
   11301   }
   11302   if (local < local_count) {
   11303     // Get the context containing declarations.
   11304     Handle<Context> context(
   11305         Context::cast(it.frame()->context())->declaration_context());
   11306     for (; i < scope_info->LocalCount(); ++i) {
   11307       if (scope_info->LocalIsSynthetic(i))
   11308         continue;
   11309       Handle<String> name(scope_info->LocalName(i));
   11310       VariableMode mode;
   11311       InitializationFlag init_flag;
   11312       locals->set(local * 2, *name);
   11313       int context_slot_index =
   11314           ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
   11315       Object* value = context->get(context_slot_index);
   11316       locals->set(local * 2 + 1, value);
   11317       local++;
   11318     }
   11319   }
   11320 
   11321   // Check whether this frame is positioned at return. If not top
   11322   // frame or if the frame is optimized it cannot be at a return.
   11323   bool at_return = false;
   11324   if (!is_optimized && index == 0) {
   11325     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
   11326   }
   11327 
   11328   // If positioned just before return find the value to be returned and add it
   11329   // to the frame information.
   11330   Handle<Object> return_value = isolate->factory()->undefined_value();
   11331   if (at_return) {
   11332     StackFrameIterator it2(isolate);
   11333     Address internal_frame_sp = NULL;
   11334     while (!it2.done()) {
   11335       if (it2.frame()->is_internal()) {
   11336         internal_frame_sp = it2.frame()->sp();
   11337       } else {
   11338         if (it2.frame()->is_java_script()) {
   11339           if (it2.frame()->id() == it.frame()->id()) {
   11340             // The internal frame just before the JavaScript frame contains the
   11341             // value to return on top. A debug break at return will create an
   11342             // internal frame to store the return value (eax/rax/r0) before
   11343             // entering the debug break exit frame.
   11344             if (internal_frame_sp != NULL) {
   11345               return_value =
   11346                   Handle<Object>(Memory::Object_at(internal_frame_sp),
   11347                                  isolate);
   11348               break;
   11349             }
   11350           }
   11351         }
   11352 
   11353         // Indicate that the previous frame was not an internal frame.
   11354         internal_frame_sp = NULL;
   11355       }
   11356       it2.Advance();
   11357     }
   11358   }
   11359 
   11360   // Now advance to the arguments adapter frame (if any). It contains all
   11361   // the provided parameters whereas the function frame always have the number
   11362   // of arguments matching the functions parameters. The rest of the
   11363   // information (except for what is collected above) is the same.
   11364   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
   11365     it.AdvanceToArgumentsFrame();
   11366     frame_inspector.SetArgumentsFrame(it.frame());
   11367   }
   11368 
   11369   // Find the number of arguments to fill. At least fill the number of
   11370   // parameters for the function and fill more if more parameters are provided.
   11371   int argument_count = scope_info->ParameterCount();
   11372   if (argument_count < frame_inspector.GetParametersCount()) {
   11373     argument_count = frame_inspector.GetParametersCount();
   11374   }
   11375 
   11376   // Calculate the size of the result.
   11377   int details_size = kFrameDetailsFirstDynamicIndex +
   11378                      2 * (argument_count + local_count) +
   11379                      (at_return ? 1 : 0);
   11380   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   11381 
   11382   // Add the frame id.
   11383   details->set(kFrameDetailsFrameIdIndex, *frame_id);
   11384 
   11385   // Add the function (same as in function frame).
   11386   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
   11387 
   11388   // Add the arguments count.
   11389   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
   11390 
   11391   // Add the locals count
   11392   details->set(kFrameDetailsLocalCountIndex,
   11393                Smi::FromInt(local_count));
   11394 
   11395   // Add the source position.
   11396   if (position != RelocInfo::kNoPosition) {
   11397     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
   11398   } else {
   11399     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
   11400   }
   11401 
   11402   // Add the constructor information.
   11403   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
   11404 
   11405   // Add the at return information.
   11406   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
   11407 
   11408   // Add flags to indicate information on whether this frame is
   11409   //   bit 0: invoked in the debugger context.
   11410   //   bit 1: optimized frame.
   11411   //   bit 2: inlined in optimized frame
   11412   int flags = 0;
   11413   if (*save->context() == *isolate->debug()->debug_context()) {
   11414     flags |= 1 << 0;
   11415   }
   11416   if (is_optimized) {
   11417     flags |= 1 << 1;
   11418     flags |= inlined_jsframe_index << 2;
   11419   }
   11420   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
   11421 
   11422   // Fill the dynamic part.
   11423   int details_index = kFrameDetailsFirstDynamicIndex;
   11424 
   11425   // Add arguments name and value.
   11426   for (int i = 0; i < argument_count; i++) {
   11427     // Name of the argument.
   11428     if (i < scope_info->ParameterCount()) {
   11429       details->set(details_index++, scope_info->ParameterName(i));
   11430     } else {
   11431       details->set(details_index++, heap->undefined_value());
   11432     }
   11433 
   11434     // Parameter value.
   11435     if (i < frame_inspector.GetParametersCount()) {
   11436       // Get the value from the stack.
   11437       details->set(details_index++, frame_inspector.GetParameter(i));
   11438     } else {
   11439       details->set(details_index++, heap->undefined_value());
   11440     }
   11441   }
   11442 
   11443   // Add locals name and value from the temporary copy from the function frame.
   11444   for (int i = 0; i < local_count * 2; i++) {
   11445     details->set(details_index++, locals->get(i));
   11446   }
   11447 
   11448   // Add the value being returned.
   11449   if (at_return) {
   11450     details->set(details_index++, *return_value);
   11451   }
   11452 
   11453   // Add the receiver (same as in function frame).
   11454   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
   11455   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
   11456   Handle<Object> receiver(it.frame()->receiver(), isolate);
   11457   if (!receiver->IsJSObject() &&
   11458       shared->strict_mode() == SLOPPY &&
   11459       !function->IsBuiltin()) {
   11460     // If the receiver is not a JSObject and the function is not a
   11461     // builtin or strict-mode we have hit an optimization where a
   11462     // value object is not converted into a wrapped JS objects. To
   11463     // hide this optimization from the debugger, we wrap the receiver
   11464     // by creating correct wrapper object based on the calling frame's
   11465     // native context.
   11466     it.Advance();
   11467     if (receiver->IsUndefined()) {
   11468       Context* context = function->context();
   11469       receiver = handle(context->global_object()->global_receiver());
   11470     } else {
   11471       ASSERT(!receiver->IsNull());
   11472       Context* context = Context::cast(it.frame()->context());
   11473       Handle<Context> native_context(Context::cast(context->native_context()));
   11474       receiver = Object::ToObject(
   11475           isolate, receiver, native_context).ToHandleChecked();
   11476     }
   11477   }
   11478   details->set(kFrameDetailsReceiverIndex, *receiver);
   11479 
   11480   ASSERT_EQ(details_size, details_index);
   11481   return *isolate->factory()->NewJSArrayWithElements(details);
   11482 }
   11483 
   11484 
   11485 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
   11486                                               Handle<String> parameter_name) {
   11487   VariableMode mode;
   11488   InitializationFlag flag;
   11489   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &flag) != -1;
   11490 }
   11491 
   11492 
   11493 // Create a plain JSObject which materializes the local scope for the specified
   11494 // frame.
   11495 MUST_USE_RESULT
   11496 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
   11497     Isolate* isolate,
   11498     Handle<JSObject> target,
   11499     Handle<JSFunction> function,
   11500     FrameInspector* frame_inspector) {
   11501   Handle<SharedFunctionInfo> shared(function->shared());
   11502   Handle<ScopeInfo> scope_info(shared->scope_info());
   11503 
   11504   // First fill all parameters.
   11505   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11506     // Do not materialize the parameter if it is shadowed by a context local.
   11507     Handle<String> name(scope_info->ParameterName(i));
   11508     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
   11509 
   11510     HandleScope scope(isolate);
   11511     Handle<Object> value(i < frame_inspector->GetParametersCount()
   11512                              ? frame_inspector->GetParameter(i)
   11513                              : isolate->heap()->undefined_value(),
   11514                          isolate);
   11515     ASSERT(!value->IsTheHole());
   11516 
   11517     RETURN_ON_EXCEPTION(
   11518         isolate,
   11519         Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
   11520         JSObject);
   11521   }
   11522 
   11523   // Second fill all stack locals.
   11524   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11525     if (scope_info->LocalIsSynthetic(i)) continue;
   11526     Handle<String> name(scope_info->StackLocalName(i));
   11527     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
   11528     if (value->IsTheHole()) continue;
   11529 
   11530     RETURN_ON_EXCEPTION(
   11531         isolate,
   11532         Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
   11533         JSObject);
   11534   }
   11535 
   11536   return target;
   11537 }
   11538 
   11539 
   11540 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
   11541                                                     Handle<JSObject> target,
   11542                                                     Handle<JSFunction> function,
   11543                                                     JavaScriptFrame* frame,
   11544                                                     int inlined_jsframe_index) {
   11545   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11546     // Optimized frames are not supported.
   11547     // TODO(yangguo): make sure all code deoptimized when debugger is active
   11548     //                and assert that this cannot happen.
   11549     return;
   11550   }
   11551 
   11552   Handle<SharedFunctionInfo> shared(function->shared());
   11553   Handle<ScopeInfo> scope_info(shared->scope_info());
   11554 
   11555   // Parameters.
   11556   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11557     // Shadowed parameters were not materialized.
   11558     Handle<String> name(scope_info->ParameterName(i));
   11559     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
   11560 
   11561     ASSERT(!frame->GetParameter(i)->IsTheHole());
   11562     HandleScope scope(isolate);
   11563     Handle<Object> value =
   11564         Object::GetPropertyOrElement(target, name).ToHandleChecked();
   11565     frame->SetParameterValue(i, *value);
   11566   }
   11567 
   11568   // Stack locals.
   11569   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11570     if (scope_info->LocalIsSynthetic(i)) continue;
   11571     if (frame->GetExpression(i)->IsTheHole()) continue;
   11572     HandleScope scope(isolate);
   11573     Handle<Object> value = Object::GetPropertyOrElement(
   11574         target,
   11575         handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
   11576     frame->SetExpression(i, *value);
   11577   }
   11578 }
   11579 
   11580 
   11581 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
   11582     Isolate* isolate,
   11583     Handle<JSObject> target,
   11584     Handle<JSFunction> function,
   11585     JavaScriptFrame* frame) {
   11586   HandleScope scope(isolate);
   11587   Handle<SharedFunctionInfo> shared(function->shared());
   11588   Handle<ScopeInfo> scope_info(shared->scope_info());
   11589 
   11590   if (!scope_info->HasContext()) return target;
   11591 
   11592   // Third fill all context locals.
   11593   Handle<Context> frame_context(Context::cast(frame->context()));
   11594   Handle<Context> function_context(frame_context->declaration_context());
   11595   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11596           scope_info, function_context, target)) {
   11597     return MaybeHandle<JSObject>();
   11598   }
   11599 
   11600   // Finally copy any properties from the function context extension.
   11601   // These will be variables introduced by eval.
   11602   if (function_context->closure() == *function) {
   11603     if (function_context->has_extension() &&
   11604         !function_context->IsNativeContext()) {
   11605       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11606       Handle<FixedArray> keys;
   11607       ASSIGN_RETURN_ON_EXCEPTION(
   11608           isolate, keys,
   11609           JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
   11610           JSObject);
   11611 
   11612       for (int i = 0; i < keys->length(); i++) {
   11613         // Names of variables introduced by eval are strings.
   11614         ASSERT(keys->get(i)->IsString());
   11615         Handle<String> key(String::cast(keys->get(i)));
   11616         Handle<Object> value;
   11617         ASSIGN_RETURN_ON_EXCEPTION(
   11618             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
   11619         RETURN_ON_EXCEPTION(
   11620             isolate,
   11621             Runtime::SetObjectProperty(
   11622                 isolate, target, key, value, NONE, SLOPPY),
   11623             JSObject);
   11624       }
   11625     }
   11626   }
   11627 
   11628   return target;
   11629 }
   11630 
   11631 
   11632 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
   11633     Isolate* isolate,
   11634     JavaScriptFrame* frame,
   11635     int inlined_jsframe_index) {
   11636   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   11637   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11638 
   11639   Handle<JSObject> local_scope =
   11640       isolate->factory()->NewJSObject(isolate->object_function());
   11641   ASSIGN_RETURN_ON_EXCEPTION(
   11642       isolate, local_scope,
   11643       MaterializeStackLocalsWithFrameInspector(
   11644           isolate, local_scope, function, &frame_inspector),
   11645       JSObject);
   11646 
   11647   return MaterializeLocalContext(isolate, local_scope, function, frame);
   11648 }
   11649 
   11650 
   11651 // Set the context local variable value.
   11652 static bool SetContextLocalValue(Isolate* isolate,
   11653                                  Handle<ScopeInfo> scope_info,
   11654                                  Handle<Context> context,
   11655                                  Handle<String> variable_name,
   11656                                  Handle<Object> new_value) {
   11657   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
   11658     Handle<String> next_name(scope_info->ContextLocalName(i));
   11659     if (String::Equals(variable_name, next_name)) {
   11660       VariableMode mode;
   11661       InitializationFlag init_flag;
   11662       int context_index =
   11663           ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &init_flag);
   11664       context->set(context_index, *new_value);
   11665       return true;
   11666     }
   11667   }
   11668 
   11669   return false;
   11670 }
   11671 
   11672 
   11673 static bool SetLocalVariableValue(Isolate* isolate,
   11674                                   JavaScriptFrame* frame,
   11675                                   int inlined_jsframe_index,
   11676                                   Handle<String> variable_name,
   11677                                   Handle<Object> new_value) {
   11678   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11679     // Optimized frames are not supported.
   11680     return false;
   11681   }
   11682 
   11683   Handle<JSFunction> function(frame->function());
   11684   Handle<SharedFunctionInfo> shared(function->shared());
   11685   Handle<ScopeInfo> scope_info(shared->scope_info());
   11686 
   11687   bool default_result = false;
   11688 
   11689   // Parameters.
   11690   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11691     HandleScope scope(isolate);
   11692     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
   11693       frame->SetParameterValue(i, *new_value);
   11694       // Argument might be shadowed in heap context, don't stop here.
   11695       default_result = true;
   11696     }
   11697   }
   11698 
   11699   // Stack locals.
   11700   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11701     HandleScope scope(isolate);
   11702     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
   11703       frame->SetExpression(i, *new_value);
   11704       return true;
   11705     }
   11706   }
   11707 
   11708   if (scope_info->HasContext()) {
   11709     // Context locals.
   11710     Handle<Context> frame_context(Context::cast(frame->context()));
   11711     Handle<Context> function_context(frame_context->declaration_context());
   11712     if (SetContextLocalValue(
   11713         isolate, scope_info, function_context, variable_name, new_value)) {
   11714       return true;
   11715     }
   11716 
   11717     // Function context extension. These are variables introduced by eval.
   11718     if (function_context->closure() == *function) {
   11719       if (function_context->has_extension() &&
   11720           !function_context->IsNativeContext()) {
   11721         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11722 
   11723         if (JSReceiver::HasProperty(ext, variable_name)) {
   11724           // We don't expect this to do anything except replacing
   11725           // property value.
   11726           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
   11727                                      NONE, SLOPPY).Assert();
   11728           return true;
   11729         }
   11730       }
   11731     }
   11732   }
   11733 
   11734   return default_result;
   11735 }
   11736 
   11737 
   11738 // Create a plain JSObject which materializes the closure content for the
   11739 // context.
   11740 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
   11741     Isolate* isolate,
   11742     Handle<Context> context) {
   11743   ASSERT(context->IsFunctionContext());
   11744 
   11745   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11746   Handle<ScopeInfo> scope_info(shared->scope_info());
   11747 
   11748   // Allocate and initialize a JSObject with all the content of this function
   11749   // closure.
   11750   Handle<JSObject> closure_scope =
   11751       isolate->factory()->NewJSObject(isolate->object_function());
   11752 
   11753   // Fill all context locals to the context extension.
   11754   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11755           scope_info, context, closure_scope)) {
   11756     return MaybeHandle<JSObject>();
   11757   }
   11758 
   11759   // Finally copy any properties from the function context extension. This will
   11760   // be variables introduced by eval.
   11761   if (context->has_extension()) {
   11762     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11763     Handle<FixedArray> keys;
   11764     ASSIGN_RETURN_ON_EXCEPTION(
   11765         isolate, keys,
   11766         JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
   11767 
   11768     for (int i = 0; i < keys->length(); i++) {
   11769       HandleScope scope(isolate);
   11770       // Names of variables introduced by eval are strings.
   11771       ASSERT(keys->get(i)->IsString());
   11772       Handle<String> key(String::cast(keys->get(i)));
   11773       Handle<Object> value;
   11774       ASSIGN_RETURN_ON_EXCEPTION(
   11775           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
   11776       RETURN_ON_EXCEPTION(
   11777           isolate,
   11778           Runtime::SetObjectProperty(
   11779               isolate, closure_scope, key, value, NONE, SLOPPY),
   11780           JSObject);
   11781     }
   11782   }
   11783 
   11784   return closure_scope;
   11785 }
   11786 
   11787 
   11788 // This method copies structure of MaterializeClosure method above.
   11789 static bool SetClosureVariableValue(Isolate* isolate,
   11790                                     Handle<Context> context,
   11791                                     Handle<String> variable_name,
   11792                                     Handle<Object> new_value) {
   11793   ASSERT(context->IsFunctionContext());
   11794 
   11795   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11796   Handle<ScopeInfo> scope_info(shared->scope_info());
   11797 
   11798   // Context locals to the context extension.
   11799   if (SetContextLocalValue(
   11800           isolate, scope_info, context, variable_name, new_value)) {
   11801     return true;
   11802   }
   11803 
   11804   // Properties from the function context extension. This will
   11805   // be variables introduced by eval.
   11806   if (context->has_extension()) {
   11807     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11808     if (JSReceiver::HasProperty(ext, variable_name)) {
   11809       // We don't expect this to do anything except replacing property value.
   11810       Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
   11811                                  NONE, SLOPPY).Assert();
   11812       return true;
   11813     }
   11814   }
   11815 
   11816   return false;
   11817 }
   11818 
   11819 
   11820 // Create a plain JSObject which materializes the scope for the specified
   11821 // catch context.
   11822 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
   11823     Isolate* isolate,
   11824     Handle<Context> context) {
   11825   ASSERT(context->IsCatchContext());
   11826   Handle<String> name(String::cast(context->extension()));
   11827   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
   11828                                isolate);
   11829   Handle<JSObject> catch_scope =
   11830       isolate->factory()->NewJSObject(isolate->object_function());
   11831   RETURN_ON_EXCEPTION(
   11832       isolate,
   11833       Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
   11834                                  NONE, SLOPPY),
   11835       JSObject);
   11836   return catch_scope;
   11837 }
   11838 
   11839 
   11840 static bool SetCatchVariableValue(Isolate* isolate,
   11841                                   Handle<Context> context,
   11842                                   Handle<String> variable_name,
   11843                                   Handle<Object> new_value) {
   11844   ASSERT(context->IsCatchContext());
   11845   Handle<String> name(String::cast(context->extension()));
   11846   if (!String::Equals(name, variable_name)) {
   11847     return false;
   11848   }
   11849   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
   11850   return true;
   11851 }
   11852 
   11853 
   11854 // Create a plain JSObject which materializes the block scope for the specified
   11855 // block context.
   11856 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
   11857     Isolate* isolate,
   11858     Handle<Context> context) {
   11859   ASSERT(context->IsBlockContext());
   11860   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11861 
   11862   // Allocate and initialize a JSObject with all the arguments, stack locals
   11863   // heap locals and extension properties of the debugged function.
   11864   Handle<JSObject> block_scope =
   11865       isolate->factory()->NewJSObject(isolate->object_function());
   11866 
   11867   // Fill all context locals.
   11868   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11869           scope_info, context, block_scope)) {
   11870     return MaybeHandle<JSObject>();
   11871   }
   11872 
   11873   return block_scope;
   11874 }
   11875 
   11876 
   11877 // Create a plain JSObject which materializes the module scope for the specified
   11878 // module context.
   11879 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
   11880     Isolate* isolate,
   11881     Handle<Context> context) {
   11882   ASSERT(context->IsModuleContext());
   11883   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11884 
   11885   // Allocate and initialize a JSObject with all the members of the debugged
   11886   // module.
   11887   Handle<JSObject> module_scope =
   11888       isolate->factory()->NewJSObject(isolate->object_function());
   11889 
   11890   // Fill all context locals.
   11891   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11892           scope_info, context, module_scope)) {
   11893     return MaybeHandle<JSObject>();
   11894   }
   11895 
   11896   return module_scope;
   11897 }
   11898 
   11899 
   11900 // Iterate over the actual scopes visible from a stack frame or from a closure.
   11901 // The iteration proceeds from the innermost visible nested scope outwards.
   11902 // All scopes are backed by an actual context except the local scope,
   11903 // which is inserted "artificially" in the context chain.
   11904 class ScopeIterator {
   11905  public:
   11906   enum ScopeType {
   11907     ScopeTypeGlobal = 0,
   11908     ScopeTypeLocal,
   11909     ScopeTypeWith,
   11910     ScopeTypeClosure,
   11911     ScopeTypeCatch,
   11912     ScopeTypeBlock,
   11913     ScopeTypeModule
   11914   };
   11915 
   11916   ScopeIterator(Isolate* isolate,
   11917                 JavaScriptFrame* frame,
   11918                 int inlined_jsframe_index,
   11919                 bool ignore_nested_scopes = false)
   11920     : isolate_(isolate),
   11921       frame_(frame),
   11922       inlined_jsframe_index_(inlined_jsframe_index),
   11923       function_(frame->function()),
   11924       context_(Context::cast(frame->context())),
   11925       nested_scope_chain_(4),
   11926       failed_(false) {
   11927 
   11928     // Catch the case when the debugger stops in an internal function.
   11929     Handle<SharedFunctionInfo> shared_info(function_->shared());
   11930     Handle<ScopeInfo> scope_info(shared_info->scope_info());
   11931     if (shared_info->script() == isolate->heap()->undefined_value()) {
   11932       while (context_->closure() == *function_) {
   11933         context_ = Handle<Context>(context_->previous(), isolate_);
   11934       }
   11935       return;
   11936     }
   11937 
   11938     // Get the debug info (create it if it does not exist).
   11939     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
   11940       // Return if ensuring debug info failed.
   11941       return;
   11942     }
   11943 
   11944     // Currently it takes too much time to find nested scopes due to script
   11945     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
   11946     // (for example, while collecting async call stacks on every
   11947     // addEventListener call), even if we drop some nested scopes.
   11948     // Later we may optimize getting the nested scopes (cache the result?)
   11949     // and include nested scopes into the "fast" iteration case as well.
   11950     if (!ignore_nested_scopes) {
   11951       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
   11952 
   11953       // Find the break point where execution has stopped.
   11954       BreakLocationIterator break_location_iterator(debug_info,
   11955                                                     ALL_BREAK_LOCATIONS);
   11956       // pc points to the instruction after the current one, possibly a break
   11957       // location as well. So the "- 1" to exclude it from the search.
   11958       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   11959 
   11960       // Within the return sequence at the moment it is not possible to
   11961       // get a source position which is consistent with the current scope chain.
   11962       // Thus all nested with, catch and block contexts are skipped and we only
   11963       // provide the function scope.
   11964       ignore_nested_scopes = break_location_iterator.IsExit();
   11965     }
   11966 
   11967     if (ignore_nested_scopes) {
   11968       if (scope_info->HasContext()) {
   11969         context_ = Handle<Context>(context_->declaration_context(), isolate_);
   11970       } else {
   11971         while (context_->closure() == *function_) {
   11972           context_ = Handle<Context>(context_->previous(), isolate_);
   11973         }
   11974       }
   11975       if (scope_info->scope_type() == FUNCTION_SCOPE) {
   11976         nested_scope_chain_.Add(scope_info);
   11977       }
   11978     } else {
   11979       // Reparse the code and analyze the scopes.
   11980       Handle<Script> script(Script::cast(shared_info->script()));
   11981       Scope* scope = NULL;
   11982 
   11983       // Check whether we are in global, eval or function code.
   11984       Handle<ScopeInfo> scope_info(shared_info->scope_info());
   11985       if (scope_info->scope_type() != FUNCTION_SCOPE) {
   11986         // Global or eval code.
   11987         CompilationInfoWithZone info(script);
   11988         if (scope_info->scope_type() == GLOBAL_SCOPE) {
   11989           info.MarkAsGlobal();
   11990         } else {
   11991           ASSERT(scope_info->scope_type() == EVAL_SCOPE);
   11992           info.MarkAsEval();
   11993           info.SetContext(Handle<Context>(function_->context()));
   11994         }
   11995         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   11996           scope = info.function()->scope();
   11997         }
   11998         RetrieveScopeChain(scope, shared_info);
   11999       } else {
   12000         // Function code
   12001         CompilationInfoWithZone info(shared_info);
   12002         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   12003           scope = info.function()->scope();
   12004         }
   12005         RetrieveScopeChain(scope, shared_info);
   12006       }
   12007     }
   12008   }
   12009 
   12010   ScopeIterator(Isolate* isolate,
   12011                 Handle<JSFunction> function)
   12012     : isolate_(isolate),
   12013       frame_(NULL),
   12014       inlined_jsframe_index_(0),
   12015       function_(function),
   12016       context_(function->context()),
   12017       failed_(false) {
   12018     if (function->IsBuiltin()) {
   12019       context_ = Handle<Context>();
   12020     }
   12021   }
   12022 
   12023   // More scopes?
   12024   bool Done() {
   12025     ASSERT(!failed_);
   12026     return context_.is_null();
   12027   }
   12028 
   12029   bool Failed() { return failed_; }
   12030 
   12031   // Move to the next scope.
   12032   void Next() {
   12033     ASSERT(!failed_);
   12034     ScopeType scope_type = Type();
   12035     if (scope_type == ScopeTypeGlobal) {
   12036       // The global scope is always the last in the chain.
   12037       ASSERT(context_->IsNativeContext());
   12038       context_ = Handle<Context>();
   12039       return;
   12040     }
   12041     if (nested_scope_chain_.is_empty()) {
   12042       context_ = Handle<Context>(context_->previous(), isolate_);
   12043     } else {
   12044       if (nested_scope_chain_.last()->HasContext()) {
   12045         ASSERT(context_->previous() != NULL);
   12046         context_ = Handle<Context>(context_->previous(), isolate_);
   12047       }
   12048       nested_scope_chain_.RemoveLast();
   12049     }
   12050   }
   12051 
   12052   // Return the type of the current scope.
   12053   ScopeType Type() {
   12054     ASSERT(!failed_);
   12055     if (!nested_scope_chain_.is_empty()) {
   12056       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
   12057       switch (scope_info->scope_type()) {
   12058         case FUNCTION_SCOPE:
   12059           ASSERT(context_->IsFunctionContext() ||
   12060                  !scope_info->HasContext());
   12061           return ScopeTypeLocal;
   12062         case MODULE_SCOPE:
   12063           ASSERT(context_->IsModuleContext());
   12064           return ScopeTypeModule;
   12065         case GLOBAL_SCOPE:
   12066           ASSERT(context_->IsNativeContext());
   12067           return ScopeTypeGlobal;
   12068         case WITH_SCOPE:
   12069           ASSERT(context_->IsWithContext());
   12070           return ScopeTypeWith;
   12071         case CATCH_SCOPE:
   12072           ASSERT(context_->IsCatchContext());
   12073           return ScopeTypeCatch;
   12074         case BLOCK_SCOPE:
   12075           ASSERT(!scope_info->HasContext() ||
   12076                  context_->IsBlockContext());
   12077           return ScopeTypeBlock;
   12078         case EVAL_SCOPE:
   12079           UNREACHABLE();
   12080       }
   12081     }
   12082     if (context_->IsNativeContext()) {
   12083       ASSERT(context_->global_object()->IsGlobalObject());
   12084       return ScopeTypeGlobal;
   12085     }
   12086     if (context_->IsFunctionContext()) {
   12087       return ScopeTypeClosure;
   12088     }
   12089     if (context_->IsCatchContext()) {
   12090       return ScopeTypeCatch;
   12091     }
   12092     if (context_->IsBlockContext()) {
   12093       return ScopeTypeBlock;
   12094     }
   12095     if (context_->IsModuleContext()) {
   12096       return ScopeTypeModule;
   12097     }
   12098     ASSERT(context_->IsWithContext());
   12099     return ScopeTypeWith;
   12100   }
   12101 
   12102   // Return the JavaScript object with the content of the current scope.
   12103   MaybeHandle<JSObject> ScopeObject() {
   12104     ASSERT(!failed_);
   12105     switch (Type()) {
   12106       case ScopeIterator::ScopeTypeGlobal:
   12107         return Handle<JSObject>(CurrentContext()->global_object());
   12108       case ScopeIterator::ScopeTypeLocal:
   12109         // Materialize the content of the local scope into a JSObject.
   12110         ASSERT(nested_scope_chain_.length() == 1);
   12111         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
   12112       case ScopeIterator::ScopeTypeWith:
   12113         // Return the with object.
   12114         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
   12115       case ScopeIterator::ScopeTypeCatch:
   12116         return MaterializeCatchScope(isolate_, CurrentContext());
   12117       case ScopeIterator::ScopeTypeClosure:
   12118         // Materialize the content of the closure scope into a JSObject.
   12119         return MaterializeClosure(isolate_, CurrentContext());
   12120       case ScopeIterator::ScopeTypeBlock:
   12121         return MaterializeBlockScope(isolate_, CurrentContext());
   12122       case ScopeIterator::ScopeTypeModule:
   12123         return MaterializeModuleScope(isolate_, CurrentContext());
   12124     }
   12125     UNREACHABLE();
   12126     return Handle<JSObject>();
   12127   }
   12128 
   12129   bool SetVariableValue(Handle<String> variable_name,
   12130                         Handle<Object> new_value) {
   12131     ASSERT(!failed_);
   12132     switch (Type()) {
   12133       case ScopeIterator::ScopeTypeGlobal:
   12134         break;
   12135       case ScopeIterator::ScopeTypeLocal:
   12136         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
   12137             variable_name, new_value);
   12138       case ScopeIterator::ScopeTypeWith:
   12139         break;
   12140       case ScopeIterator::ScopeTypeCatch:
   12141         return SetCatchVariableValue(isolate_, CurrentContext(),
   12142             variable_name, new_value);
   12143       case ScopeIterator::ScopeTypeClosure:
   12144         return SetClosureVariableValue(isolate_, CurrentContext(),
   12145             variable_name, new_value);
   12146       case ScopeIterator::ScopeTypeBlock:
   12147         // TODO(2399): should we implement it?
   12148         break;
   12149       case ScopeIterator::ScopeTypeModule:
   12150         // TODO(2399): should we implement it?
   12151         break;
   12152     }
   12153     return false;
   12154   }
   12155 
   12156   Handle<ScopeInfo> CurrentScopeInfo() {
   12157     ASSERT(!failed_);
   12158     if (!nested_scope_chain_.is_empty()) {
   12159       return nested_scope_chain_.last();
   12160     } else if (context_->IsBlockContext()) {
   12161       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
   12162     } else if (context_->IsFunctionContext()) {
   12163       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
   12164     }
   12165     return Handle<ScopeInfo>::null();
   12166   }
   12167 
   12168   // Return the context for this scope. For the local context there might not
   12169   // be an actual context.
   12170   Handle<Context> CurrentContext() {
   12171     ASSERT(!failed_);
   12172     if (Type() == ScopeTypeGlobal ||
   12173         nested_scope_chain_.is_empty()) {
   12174       return context_;
   12175     } else if (nested_scope_chain_.last()->HasContext()) {
   12176       return context_;
   12177     } else {
   12178       return Handle<Context>();
   12179     }
   12180   }
   12181 
   12182 #ifdef DEBUG
   12183   // Debug print of the content of the current scope.
   12184   void DebugPrint() {
   12185     ASSERT(!failed_);
   12186     switch (Type()) {
   12187       case ScopeIterator::ScopeTypeGlobal:
   12188         PrintF("Global:\n");
   12189         CurrentContext()->Print();
   12190         break;
   12191 
   12192       case ScopeIterator::ScopeTypeLocal: {
   12193         PrintF("Local:\n");
   12194         function_->shared()->scope_info()->Print();
   12195         if (!CurrentContext().is_null()) {
   12196           CurrentContext()->Print();
   12197           if (CurrentContext()->has_extension()) {
   12198             Handle<Object> extension(CurrentContext()->extension(), isolate_);
   12199             if (extension->IsJSContextExtensionObject()) {
   12200               extension->Print();
   12201             }
   12202           }
   12203         }
   12204         break;
   12205       }
   12206 
   12207       case ScopeIterator::ScopeTypeWith:
   12208         PrintF("With:\n");
   12209         CurrentContext()->extension()->Print();
   12210         break;
   12211 
   12212       case ScopeIterator::ScopeTypeCatch:
   12213         PrintF("Catch:\n");
   12214         CurrentContext()->extension()->Print();
   12215         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
   12216         break;
   12217 
   12218       case ScopeIterator::ScopeTypeClosure:
   12219         PrintF("Closure:\n");
   12220         CurrentContext()->Print();
   12221         if (CurrentContext()->has_extension()) {
   12222           Handle<Object> extension(CurrentContext()->extension(), isolate_);
   12223           if (extension->IsJSContextExtensionObject()) {
   12224             extension->Print();
   12225           }
   12226         }
   12227         break;
   12228 
   12229       default:
   12230         UNREACHABLE();
   12231     }
   12232     PrintF("\n");
   12233   }
   12234 #endif
   12235 
   12236  private:
   12237   Isolate* isolate_;
   12238   JavaScriptFrame* frame_;
   12239   int inlined_jsframe_index_;
   12240   Handle<JSFunction> function_;
   12241   Handle<Context> context_;
   12242   List<Handle<ScopeInfo> > nested_scope_chain_;
   12243   bool failed_;
   12244 
   12245   void RetrieveScopeChain(Scope* scope,
   12246                           Handle<SharedFunctionInfo> shared_info) {
   12247     if (scope != NULL) {
   12248       int source_position = shared_info->code()->SourcePosition(frame_->pc());
   12249       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
   12250     } else {
   12251       // A failed reparse indicates that the preparser has diverged from the
   12252       // parser or that the preparse data given to the initial parse has been
   12253       // faulty. We fail in debug mode but in release mode we only provide the
   12254       // information we get from the context chain but nothing about
   12255       // completely stack allocated scopes or stack allocated locals.
   12256       // Or it could be due to stack overflow.
   12257       ASSERT(isolate_->has_pending_exception());
   12258       failed_ = true;
   12259     }
   12260   }
   12261 
   12262   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
   12263 };
   12264 
   12265 
   12266 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
   12267   HandleScope scope(isolate);
   12268   ASSERT(args.length() == 2);
   12269   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12270   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12271 
   12272   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12273 
   12274   // Get the frame where the debugging is performed.
   12275   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12276   JavaScriptFrameIterator it(isolate, id);
   12277   JavaScriptFrame* frame = it.frame();
   12278 
   12279   // Count the visible scopes.
   12280   int n = 0;
   12281   for (ScopeIterator it(isolate, frame, 0);
   12282        !it.Done();
   12283        it.Next()) {
   12284     n++;
   12285   }
   12286 
   12287   return Smi::FromInt(n);
   12288 }
   12289 
   12290 
   12291 // Returns the list of step-in positions (text offset) in a function of the
   12292 // stack frame in a range from the current debug break position to the end
   12293 // of the corresponding statement.
   12294 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
   12295   HandleScope scope(isolate);
   12296   ASSERT(args.length() == 2);
   12297   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12298   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12299 
   12300   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12301 
   12302   // Get the frame where the debugging is performed.
   12303   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12304   JavaScriptFrameIterator frame_it(isolate, id);
   12305   RUNTIME_ASSERT(!frame_it.done());
   12306 
   12307   JavaScriptFrame* frame = frame_it.frame();
   12308 
   12309   Handle<JSFunction> fun =
   12310       Handle<JSFunction>(frame->function());
   12311   Handle<SharedFunctionInfo> shared =
   12312       Handle<SharedFunctionInfo>(fun->shared());
   12313 
   12314   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
   12315     return isolate->heap()->undefined_value();
   12316   }
   12317 
   12318   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
   12319 
   12320   int len = 0;
   12321   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
   12322   // Find the break point where execution has stopped.
   12323   BreakLocationIterator break_location_iterator(debug_info,
   12324                                                 ALL_BREAK_LOCATIONS);
   12325 
   12326   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   12327   int current_statement_pos = break_location_iterator.statement_position();
   12328 
   12329   while (!break_location_iterator.Done()) {
   12330     bool accept;
   12331     if (break_location_iterator.pc() > frame->pc()) {
   12332       accept = true;
   12333     } else {
   12334       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
   12335       // The break point is near our pc. Could be a step-in possibility,
   12336       // that is currently taken by active debugger call.
   12337       if (break_frame_id == StackFrame::NO_ID) {
   12338         // We are not stepping.
   12339         accept = false;
   12340       } else {
   12341         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
   12342         // If our frame is a top frame and we are stepping, we can do step-in
   12343         // at this place.
   12344         accept = additional_frame_it.frame()->id() == id;
   12345       }
   12346     }
   12347     if (accept) {
   12348       if (break_location_iterator.IsStepInLocation(isolate)) {
   12349         Smi* position_value = Smi::FromInt(break_location_iterator.position());
   12350         RETURN_FAILURE_ON_EXCEPTION(
   12351             isolate,
   12352             JSObject::SetElement(array, len,
   12353                                  Handle<Object>(position_value, isolate),
   12354                                  NONE, SLOPPY));
   12355         len++;
   12356       }
   12357     }
   12358     // Advance iterator.
   12359     break_location_iterator.Next();
   12360     if (current_statement_pos !=
   12361         break_location_iterator.statement_position()) {
   12362       break;
   12363     }
   12364   }
   12365   return *array;
   12366 }
   12367 
   12368 
   12369 static const int kScopeDetailsTypeIndex = 0;
   12370 static const int kScopeDetailsObjectIndex = 1;
   12371 static const int kScopeDetailsSize = 2;
   12372 
   12373 
   12374 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
   12375     Isolate* isolate,
   12376     ScopeIterator* it) {
   12377   // Calculate the size of the result.
   12378   int details_size = kScopeDetailsSize;
   12379   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   12380 
   12381   // Fill in scope details.
   12382   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
   12383   Handle<JSObject> scope_object;
   12384   ASSIGN_RETURN_ON_EXCEPTION(
   12385       isolate, scope_object, it->ScopeObject(), JSObject);
   12386   details->set(kScopeDetailsObjectIndex, *scope_object);
   12387 
   12388   return isolate->factory()->NewJSArrayWithElements(details);
   12389 }
   12390 
   12391 
   12392 // Return an array with scope details
   12393 // args[0]: number: break id
   12394 // args[1]: number: frame index
   12395 // args[2]: number: inlined frame index
   12396 // args[3]: number: scope index
   12397 //
   12398 // The array returned contains the following information:
   12399 // 0: Scope type
   12400 // 1: Scope object
   12401 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
   12402   HandleScope scope(isolate);
   12403   ASSERT(args.length() == 4);
   12404   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12405   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12406 
   12407   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12408   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12409   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12410 
   12411   // Get the frame where the debugging is performed.
   12412   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12413   JavaScriptFrameIterator frame_it(isolate, id);
   12414   JavaScriptFrame* frame = frame_it.frame();
   12415 
   12416   // Find the requested scope.
   12417   int n = 0;
   12418   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12419   for (; !it.Done() && n < index; it.Next()) {
   12420     n++;
   12421   }
   12422   if (it.Done()) {
   12423     return isolate->heap()->undefined_value();
   12424   }
   12425   Handle<JSObject> details;
   12426   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12427       isolate, details, MaterializeScopeDetails(isolate, &it));
   12428   return *details;
   12429 }
   12430 
   12431 
   12432 // Return an array of scope details
   12433 // args[0]: number: break id
   12434 // args[1]: number: frame index
   12435 // args[2]: number: inlined frame index
   12436 // args[3]: boolean: ignore nested scopes
   12437 //
   12438 // The array returned contains arrays with the following information:
   12439 // 0: Scope type
   12440 // 1: Scope object
   12441 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
   12442   HandleScope scope(isolate);
   12443   ASSERT(args.length() == 3 || args.length() == 4);
   12444   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12445   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12446 
   12447   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12448   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12449 
   12450   bool ignore_nested_scopes = false;
   12451   if (args.length() == 4) {
   12452     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
   12453     ignore_nested_scopes = flag;
   12454   }
   12455 
   12456   // Get the frame where the debugging is performed.
   12457   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12458   JavaScriptFrameIterator frame_it(isolate, id);
   12459   JavaScriptFrame* frame = frame_it.frame();
   12460 
   12461   List<Handle<JSObject> > result(4);
   12462   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
   12463   for (; !it.Done(); it.Next()) {
   12464     Handle<JSObject> details;
   12465     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12466         isolate, details, MaterializeScopeDetails(isolate, &it));
   12467     result.Add(details);
   12468   }
   12469 
   12470   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
   12471   for (int i = 0; i < result.length(); ++i) {
   12472     array->set(i, *result[i]);
   12473   }
   12474   return *isolate->factory()->NewJSArrayWithElements(array);
   12475 }
   12476 
   12477 
   12478 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
   12479   HandleScope scope(isolate);
   12480   ASSERT(args.length() == 1);
   12481 
   12482   // Check arguments.
   12483   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12484 
   12485   // Count the visible scopes.
   12486   int n = 0;
   12487   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
   12488     n++;
   12489   }
   12490 
   12491   return Smi::FromInt(n);
   12492 }
   12493 
   12494 
   12495 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
   12496   HandleScope scope(isolate);
   12497   ASSERT(args.length() == 2);
   12498 
   12499   // Check arguments.
   12500   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12501   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12502 
   12503   // Find the requested scope.
   12504   int n = 0;
   12505   ScopeIterator it(isolate, fun);
   12506   for (; !it.Done() && n < index; it.Next()) {
   12507     n++;
   12508   }
   12509   if (it.Done()) {
   12510     return isolate->heap()->undefined_value();
   12511   }
   12512 
   12513   Handle<JSObject> details;
   12514   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12515       isolate, details, MaterializeScopeDetails(isolate, &it));
   12516   return *details;
   12517 }
   12518 
   12519 
   12520 static bool SetScopeVariableValue(ScopeIterator* it, int index,
   12521                                   Handle<String> variable_name,
   12522                                   Handle<Object> new_value) {
   12523   for (int n = 0; !it->Done() && n < index; it->Next()) {
   12524     n++;
   12525   }
   12526   if (it->Done()) {
   12527     return false;
   12528   }
   12529   return it->SetVariableValue(variable_name, new_value);
   12530 }
   12531 
   12532 
   12533 // Change variable value in closure or local scope
   12534 // args[0]: number or JsFunction: break id or function
   12535 // args[1]: number: frame index (when arg[0] is break id)
   12536 // args[2]: number: inlined frame index (when arg[0] is break id)
   12537 // args[3]: number: scope index
   12538 // args[4]: string: variable name
   12539 // args[5]: object: new value
   12540 //
   12541 // Return true if success and false otherwise
   12542 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
   12543   HandleScope scope(isolate);
   12544   ASSERT(args.length() == 6);
   12545 
   12546   // Check arguments.
   12547   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12548   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
   12549   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
   12550 
   12551   bool res;
   12552   if (args[0]->IsNumber()) {
   12553     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12554     RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12555 
   12556     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12557     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12558 
   12559     // Get the frame where the debugging is performed.
   12560     StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12561     JavaScriptFrameIterator frame_it(isolate, id);
   12562     JavaScriptFrame* frame = frame_it.frame();
   12563 
   12564     ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12565     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12566   } else {
   12567     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12568     ScopeIterator it(isolate, fun);
   12569     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12570   }
   12571 
   12572   return isolate->heap()->ToBoolean(res);
   12573 }
   12574 
   12575 
   12576 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
   12577   HandleScope scope(isolate);
   12578   ASSERT(args.length() == 0);
   12579 
   12580 #ifdef DEBUG
   12581   // Print the scopes for the top frame.
   12582   StackFrameLocator locator(isolate);
   12583   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
   12584   for (ScopeIterator it(isolate, frame, 0);
   12585        !it.Done();
   12586        it.Next()) {
   12587     it.DebugPrint();
   12588   }
   12589 #endif
   12590   return isolate->heap()->undefined_value();
   12591 }
   12592 
   12593 
   12594 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
   12595   HandleScope scope(isolate);
   12596   ASSERT(args.length() == 1);
   12597   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12598   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12599 
   12600   // Count all archived V8 threads.
   12601   int n = 0;
   12602   for (ThreadState* thread =
   12603           isolate->thread_manager()->FirstThreadStateInUse();
   12604        thread != NULL;
   12605        thread = thread->Next()) {
   12606     n++;
   12607   }
   12608 
   12609   // Total number of threads is current thread and archived threads.
   12610   return Smi::FromInt(n + 1);
   12611 }
   12612 
   12613 
   12614 static const int kThreadDetailsCurrentThreadIndex = 0;
   12615 static const int kThreadDetailsThreadIdIndex = 1;
   12616 static const int kThreadDetailsSize = 2;
   12617 
   12618 // Return an array with thread details
   12619 // args[0]: number: break id
   12620 // args[1]: number: thread index
   12621 //
   12622 // The array returned contains the following information:
   12623 // 0: Is current thread?
   12624 // 1: Thread id
   12625 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
   12626   HandleScope scope(isolate);
   12627   ASSERT(args.length() == 2);
   12628   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12629   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12630 
   12631   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12632 
   12633   // Allocate array for result.
   12634   Handle<FixedArray> details =
   12635       isolate->factory()->NewFixedArray(kThreadDetailsSize);
   12636 
   12637   // Thread index 0 is current thread.
   12638   if (index == 0) {
   12639     // Fill the details.
   12640     details->set(kThreadDetailsCurrentThreadIndex,
   12641                  isolate->heap()->true_value());
   12642     details->set(kThreadDetailsThreadIdIndex,
   12643                  Smi::FromInt(ThreadId::Current().ToInteger()));
   12644   } else {
   12645     // Find the thread with the requested index.
   12646     int n = 1;
   12647     ThreadState* thread =
   12648         isolate->thread_manager()->FirstThreadStateInUse();
   12649     while (index != n && thread != NULL) {
   12650       thread = thread->Next();
   12651       n++;
   12652     }
   12653     if (thread == NULL) {
   12654       return isolate->heap()->undefined_value();
   12655     }
   12656 
   12657     // Fill the details.
   12658     details->set(kThreadDetailsCurrentThreadIndex,
   12659                  isolate->heap()->false_value());
   12660     details->set(kThreadDetailsThreadIdIndex,
   12661                  Smi::FromInt(thread->id().ToInteger()));
   12662   }
   12663 
   12664   // Convert to JS array and return.
   12665   return *isolate->factory()->NewJSArrayWithElements(details);
   12666 }
   12667 
   12668 
   12669 // Sets the disable break state
   12670 // args[0]: disable break state
   12671 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
   12672   HandleScope scope(isolate);
   12673   ASSERT(args.length() == 1);
   12674   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
   12675   isolate->debug()->set_disable_break(disable_break);
   12676   return  isolate->heap()->undefined_value();
   12677 }
   12678 
   12679 
   12680 static bool IsPositionAlignmentCodeCorrect(int alignment) {
   12681   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
   12682 }
   12683 
   12684 
   12685 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
   12686   HandleScope scope(isolate);
   12687   ASSERT(args.length() == 2);
   12688 
   12689   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12690   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
   12691 
   12692   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12693     return isolate->ThrowIllegalOperation();
   12694   }
   12695   BreakPositionAlignment alignment =
   12696       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12697 
   12698   Handle<SharedFunctionInfo> shared(fun->shared());
   12699   // Find the number of break points
   12700   Handle<Object> break_locations =
   12701       Debug::GetSourceBreakLocations(shared, alignment);
   12702   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   12703   // Return array as JS array
   12704   return *isolate->factory()->NewJSArrayWithElements(
   12705       Handle<FixedArray>::cast(break_locations));
   12706 }
   12707 
   12708 
   12709 // Set a break point in a function.
   12710 // args[0]: function
   12711 // args[1]: number: break source position (within the function source)
   12712 // args[2]: number: break point object
   12713 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
   12714   HandleScope scope(isolate);
   12715   ASSERT(args.length() == 3);
   12716   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   12717   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12718   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
   12719                  source_position <= function->shared()->end_position());
   12720   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
   12721 
   12722   // Set break point.
   12723   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
   12724       function, break_point_object_arg, &source_position));
   12725 
   12726   return Smi::FromInt(source_position);
   12727 }
   12728 
   12729 
   12730 // Changes the state of a break point in a script and returns source position
   12731 // where break point was set. NOTE: Regarding performance see the NOTE for
   12732 // GetScriptFromScriptData.
   12733 // args[0]: script to set break point in
   12734 // args[1]: number: break source position (within the script source)
   12735 // args[2]: number, breakpoint position alignment
   12736 // args[3]: number: break point object
   12737 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
   12738   HandleScope scope(isolate);
   12739   ASSERT(args.length() == 4);
   12740   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   12741   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12742   RUNTIME_ASSERT(source_position >= 0);
   12743   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
   12744   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
   12745 
   12746   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12747     return isolate->ThrowIllegalOperation();
   12748   }
   12749   BreakPositionAlignment alignment =
   12750       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12751 
   12752   // Get the script from the script wrapper.
   12753   RUNTIME_ASSERT(wrapper->value()->IsScript());
   12754   Handle<Script> script(Script::cast(wrapper->value()));
   12755 
   12756   // Set break point.
   12757   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
   12758                                                 &source_position,
   12759                                                 alignment)) {
   12760     return isolate->heap()->undefined_value();
   12761   }
   12762 
   12763   return Smi::FromInt(source_position);
   12764 }
   12765 
   12766 
   12767 // Clear a break point
   12768 // args[0]: number: break point object
   12769 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
   12770   HandleScope scope(isolate);
   12771   ASSERT(args.length() == 1);
   12772   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
   12773 
   12774   // Clear break point.
   12775   isolate->debug()->ClearBreakPoint(break_point_object_arg);
   12776 
   12777   return isolate->heap()->undefined_value();
   12778 }
   12779 
   12780 
   12781 // Change the state of break on exceptions.
   12782 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
   12783 // args[1]: Boolean indicating on/off.
   12784 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
   12785   HandleScope scope(isolate);
   12786   ASSERT(args.length() == 2);
   12787   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
   12788   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
   12789 
   12790   // If the number doesn't match an enum value, the ChangeBreakOnException
   12791   // function will default to affecting caught exceptions.
   12792   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
   12793   // Update break point state.
   12794   isolate->debug()->ChangeBreakOnException(type, enable);
   12795   return isolate->heap()->undefined_value();
   12796 }
   12797 
   12798 
   12799 // Returns the state of break on exceptions
   12800 // args[0]: boolean indicating uncaught exceptions
   12801 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
   12802   HandleScope scope(isolate);
   12803   ASSERT(args.length() == 1);
   12804   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
   12805 
   12806   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
   12807   bool result = isolate->debug()->IsBreakOnException(type);
   12808   return Smi::FromInt(result);
   12809 }
   12810 
   12811 
   12812 // Prepare for stepping
   12813 // args[0]: break id for checking execution state
   12814 // args[1]: step action from the enumeration StepAction
   12815 // args[2]: number of times to perform the step, for step out it is the number
   12816 //          of frames to step down.
   12817 RUNTIME_FUNCTION(Runtime_PrepareStep) {
   12818   HandleScope scope(isolate);
   12819   ASSERT(args.length() == 4);
   12820   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12821   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12822 
   12823   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
   12824     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12825   }
   12826 
   12827   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
   12828 
   12829   StackFrame::Id frame_id;
   12830   if (wrapped_frame_id == 0) {
   12831     frame_id = StackFrame::NO_ID;
   12832   } else {
   12833     frame_id = UnwrapFrameId(wrapped_frame_id);
   12834   }
   12835 
   12836   // Get the step action and check validity.
   12837   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   12838   if (step_action != StepIn &&
   12839       step_action != StepNext &&
   12840       step_action != StepOut &&
   12841       step_action != StepInMin &&
   12842       step_action != StepMin) {
   12843     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12844   }
   12845 
   12846   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
   12847       step_action != StepMin && step_action != StepOut) {
   12848     return isolate->ThrowIllegalOperation();
   12849   }
   12850 
   12851   // Get the number of steps.
   12852   int step_count = NumberToInt32(args[2]);
   12853   if (step_count < 1) {
   12854     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12855   }
   12856 
   12857   // Clear all current stepping setup.
   12858   isolate->debug()->ClearStepping();
   12859 
   12860   // Prepare step.
   12861   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
   12862                                 step_count,
   12863                                 frame_id);
   12864   return isolate->heap()->undefined_value();
   12865 }
   12866 
   12867 
   12868 // Clear all stepping set by PrepareStep.
   12869 RUNTIME_FUNCTION(Runtime_ClearStepping) {
   12870   HandleScope scope(isolate);
   12871   ASSERT(args.length() == 0);
   12872   isolate->debug()->ClearStepping();
   12873   return isolate->heap()->undefined_value();
   12874 }
   12875 
   12876 
   12877 // Helper function to find or create the arguments object for
   12878 // Runtime_DebugEvaluate.
   12879 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
   12880     Isolate* isolate,
   12881     Handle<JSObject> target,
   12882     Handle<JSFunction> function) {
   12883   // Do not materialize the arguments object for eval or top-level code.
   12884   // Skip if "arguments" is already taken.
   12885   if (!function->shared()->is_function() ||
   12886       JSReceiver::HasOwnProperty(
   12887           target, isolate->factory()->arguments_string())) {
   12888     return target;
   12889   }
   12890 
   12891   // FunctionGetArguments can't throw an exception.
   12892   Handle<JSObject> arguments = Handle<JSObject>::cast(
   12893       Accessors::FunctionGetArguments(function));
   12894   Handle<String> arguments_str = isolate->factory()->arguments_string();
   12895   RETURN_ON_EXCEPTION(
   12896       isolate,
   12897       Runtime::SetObjectProperty(
   12898           isolate, target, arguments_str, arguments, ::NONE, SLOPPY),
   12899       JSObject);
   12900   return target;
   12901 }
   12902 
   12903 
   12904 // Compile and evaluate source for the given context.
   12905 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
   12906                                          Handle<Context> context,
   12907                                          Handle<Object> context_extension,
   12908                                          Handle<Object> receiver,
   12909                                          Handle<String> source) {
   12910   if (context_extension->IsJSObject()) {
   12911     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
   12912     Handle<JSFunction> closure(context->closure(), isolate);
   12913     context = isolate->factory()->NewWithContext(closure, context, extension);
   12914   }
   12915 
   12916   Handle<JSFunction> eval_fun;
   12917   ASSIGN_RETURN_ON_EXCEPTION(
   12918       isolate, eval_fun,
   12919       Compiler::GetFunctionFromEval(source,
   12920                                     context,
   12921                                     SLOPPY,
   12922                                     NO_PARSE_RESTRICTION,
   12923                                     RelocInfo::kNoPosition),
   12924       Object);
   12925 
   12926   Handle<Object> result;
   12927   ASSIGN_RETURN_ON_EXCEPTION(
   12928       isolate, result,
   12929       Execution::Call(isolate, eval_fun, receiver, 0, NULL),
   12930       Object);
   12931 
   12932   // Skip the global proxy as it has no properties and always delegates to the
   12933   // real global object.
   12934   if (result->IsJSGlobalProxy()) {
   12935     result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
   12936   }
   12937 
   12938   // Clear the oneshot breakpoints so that the debugger does not step further.
   12939   isolate->debug()->ClearStepping();
   12940   return result;
   12941 }
   12942 
   12943 
   12944 // Evaluate a piece of JavaScript in the context of a stack frame for
   12945 // debugging.  Things that need special attention are:
   12946 // - Parameters and stack-allocated locals need to be materialized.  Altered
   12947 //   values need to be written back to the stack afterwards.
   12948 // - The arguments object needs to materialized.
   12949 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
   12950   HandleScope scope(isolate);
   12951 
   12952   // Check the execution state and decode arguments frame and source to be
   12953   // evaluated.
   12954   ASSERT(args.length() == 6);
   12955   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   12956   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   12957 
   12958   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12959   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12960   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
   12961   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
   12962   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
   12963 
   12964   // Handle the processing of break.
   12965   DisableBreak disable_break_scope(isolate->debug(), disable_break);
   12966 
   12967   // Get the frame where the debugging is performed.
   12968   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12969   JavaScriptFrameIterator it(isolate, id);
   12970   JavaScriptFrame* frame = it.frame();
   12971   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   12972   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   12973 
   12974   // Traverse the saved contexts chain to find the active context for the
   12975   // selected frame.
   12976   SaveContext* save = FindSavedContextForFrame(isolate, frame);
   12977 
   12978   SaveContext savex(isolate);
   12979   isolate->set_context(*(save->context()));
   12980 
   12981   // Evaluate on the context of the frame.
   12982   Handle<Context> context(Context::cast(frame->context()));
   12983   ASSERT(!context.is_null());
   12984 
   12985   // Materialize stack locals and the arguments object.
   12986   Handle<JSObject> materialized =
   12987       isolate->factory()->NewJSObject(isolate->object_function());
   12988 
   12989   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12990       isolate, materialized,
   12991       MaterializeStackLocalsWithFrameInspector(
   12992           isolate, materialized, function, &frame_inspector));
   12993 
   12994   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   12995       isolate, materialized,
   12996       MaterializeArgumentsObject(isolate, materialized, function));
   12997 
   12998   // Add the materialized object in a with-scope to shadow the stack locals.
   12999   context = isolate->factory()->NewWithContext(function, context, materialized);
   13000 
   13001   Handle<Object> receiver(frame->receiver(), isolate);
   13002   Handle<Object> result;
   13003   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13004       isolate, result,
   13005       DebugEvaluate(isolate, context, context_extension, receiver, source));
   13006 
   13007   // Write back potential changes to materialized stack locals to the stack.
   13008   UpdateStackLocalsFromMaterializedObject(
   13009       isolate, materialized, function, frame, inlined_jsframe_index);
   13010 
   13011   return *result;
   13012 }
   13013 
   13014 
   13015 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
   13016   HandleScope scope(isolate);
   13017 
   13018   // Check the execution state and decode arguments frame and source to be
   13019   // evaluated.
   13020   ASSERT(args.length() == 4);
   13021   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   13022   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   13023 
   13024   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13025   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
   13026   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
   13027 
   13028   // Handle the processing of break.
   13029   DisableBreak disable_break_scope(isolate->debug(), disable_break);
   13030 
   13031   // Enter the top context from before the debugger was invoked.
   13032   SaveContext save(isolate);
   13033   SaveContext* top = &save;
   13034   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
   13035     top = top->prev();
   13036   }
   13037   if (top != NULL) {
   13038     isolate->set_context(*top->context());
   13039   }
   13040 
   13041   // Get the native context now set to the top context from before the
   13042   // debugger was invoked.
   13043   Handle<Context> context = isolate->native_context();
   13044   Handle<Object> receiver = isolate->global_object();
   13045   Handle<Object> result;
   13046   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13047       isolate, result,
   13048       DebugEvaluate(isolate, context, context_extension, receiver, source));
   13049   return *result;
   13050 }
   13051 
   13052 
   13053 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
   13054   HandleScope scope(isolate);
   13055   ASSERT(args.length() == 0);
   13056 
   13057   // Fill the script objects.
   13058   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
   13059 
   13060   // Convert the script objects to proper JS objects.
   13061   for (int i = 0; i < instances->length(); i++) {
   13062     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
   13063     // Get the script wrapper in a local handle before calling GetScriptWrapper,
   13064     // because using
   13065     //   instances->set(i, *GetScriptWrapper(script))
   13066     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
   13067     // already have dereferenced the instances handle.
   13068     Handle<JSObject> wrapper = Script::GetWrapper(script);
   13069     instances->set(i, *wrapper);
   13070   }
   13071 
   13072   // Return result as a JS array.
   13073   Handle<JSObject> result =
   13074       isolate->factory()->NewJSObject(isolate->array_function());
   13075   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   13076   return *result;
   13077 }
   13078 
   13079 
   13080 // Helper function used by Runtime_DebugReferencedBy below.
   13081 static int DebugReferencedBy(HeapIterator* iterator,
   13082                              JSObject* target,
   13083                              Object* instance_filter, int max_references,
   13084                              FixedArray* instances, int instances_size,
   13085                              JSFunction* arguments_function) {
   13086   Isolate* isolate = target->GetIsolate();
   13087   SealHandleScope shs(isolate);
   13088   DisallowHeapAllocation no_allocation;
   13089 
   13090   // Iterate the heap.
   13091   int count = 0;
   13092   JSObject* last = NULL;
   13093   HeapObject* heap_obj = NULL;
   13094   while (((heap_obj = iterator->next()) != NULL) &&
   13095          (max_references == 0 || count < max_references)) {
   13096     // Only look at all JSObjects.
   13097     if (heap_obj->IsJSObject()) {
   13098       // Skip context extension objects and argument arrays as these are
   13099       // checked in the context of functions using them.
   13100       JSObject* obj = JSObject::cast(heap_obj);
   13101       if (obj->IsJSContextExtensionObject() ||
   13102           obj->map()->constructor() == arguments_function) {
   13103         continue;
   13104       }
   13105 
   13106       // Check if the JS object has a reference to the object looked for.
   13107       if (obj->ReferencesObject(target)) {
   13108         // Check instance filter if supplied. This is normally used to avoid
   13109         // references from mirror objects (see Runtime_IsInPrototypeChain).
   13110         if (!instance_filter->IsUndefined()) {
   13111           Object* V = obj;
   13112           while (true) {
   13113             Object* prototype = V->GetPrototype(isolate);
   13114             if (prototype->IsNull()) {
   13115               break;
   13116             }
   13117             if (instance_filter == prototype) {
   13118               obj = NULL;  // Don't add this object.
   13119               break;
   13120             }
   13121             V = prototype;
   13122           }
   13123         }
   13124 
   13125         if (obj != NULL) {
   13126           // Valid reference found add to instance array if supplied an update
   13127           // count.
   13128           if (instances != NULL && count < instances_size) {
   13129             instances->set(count, obj);
   13130           }
   13131           last = obj;
   13132           count++;
   13133         }
   13134       }
   13135     }
   13136   }
   13137 
   13138   // Check for circular reference only. This can happen when the object is only
   13139   // referenced from mirrors and has a circular reference in which case the
   13140   // object is not really alive and would have been garbage collected if not
   13141   // referenced from the mirror.
   13142   if (count == 1 && last == target) {
   13143     count = 0;
   13144   }
   13145 
   13146   // Return the number of referencing objects found.
   13147   return count;
   13148 }
   13149 
   13150 
   13151 // Scan the heap for objects with direct references to an object
   13152 // args[0]: the object to find references to
   13153 // args[1]: constructor function for instances to exclude (Mirror)
   13154 // args[2]: the the maximum number of objects to return
   13155 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
   13156   HandleScope scope(isolate);
   13157   ASSERT(args.length() == 3);
   13158 
   13159   // Check parameters.
   13160   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
   13161   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
   13162   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
   13163                  instance_filter->IsJSObject());
   13164   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
   13165   RUNTIME_ASSERT(max_references >= 0);
   13166 
   13167 
   13168   // Get the constructor function for context extension and arguments array.
   13169   Handle<JSObject> arguments_boilerplate(
   13170       isolate->context()->native_context()->sloppy_arguments_boilerplate());
   13171   Handle<JSFunction> arguments_function(
   13172       JSFunction::cast(arguments_boilerplate->map()->constructor()));
   13173 
   13174   // Get the number of referencing objects.
   13175   int count;
   13176   // First perform a full GC in order to avoid dead objects and to make the heap
   13177   // iterable.
   13178   Heap* heap = isolate->heap();
   13179   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
   13180   {
   13181     HeapIterator heap_iterator(heap);
   13182     count = DebugReferencedBy(&heap_iterator,
   13183                               *target, *instance_filter, max_references,
   13184                               NULL, 0, *arguments_function);
   13185   }
   13186 
   13187   // Allocate an array to hold the result.
   13188   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
   13189 
   13190   // Fill the referencing objects.
   13191   {
   13192     HeapIterator heap_iterator(heap);
   13193     count = DebugReferencedBy(&heap_iterator,
   13194                               *target, *instance_filter, max_references,
   13195                               *instances, count, *arguments_function);
   13196   }
   13197 
   13198   // Return result as JS array.
   13199   Handle<JSFunction> constructor(
   13200       isolate->context()->native_context()->array_function());
   13201 
   13202   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
   13203   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   13204   return *result;
   13205 }
   13206 
   13207 
   13208 // Helper function used by Runtime_DebugConstructedBy below.
   13209 static int DebugConstructedBy(HeapIterator* iterator,
   13210                               JSFunction* constructor,
   13211                               int max_references,
   13212                               FixedArray* instances,
   13213                               int instances_size) {
   13214   DisallowHeapAllocation no_allocation;
   13215 
   13216   // Iterate the heap.
   13217   int count = 0;
   13218   HeapObject* heap_obj = NULL;
   13219   while (((heap_obj = iterator->next()) != NULL) &&
   13220          (max_references == 0 || count < max_references)) {
   13221     // Only look at all JSObjects.
   13222     if (heap_obj->IsJSObject()) {
   13223       JSObject* obj = JSObject::cast(heap_obj);
   13224       if (obj->map()->constructor() == constructor) {
   13225         // Valid reference found add to instance array if supplied an update
   13226         // count.
   13227         if (instances != NULL && count < instances_size) {
   13228           instances->set(count, obj);
   13229         }
   13230         count++;
   13231       }
   13232     }
   13233   }
   13234 
   13235   // Return the number of referencing objects found.
   13236   return count;
   13237 }
   13238 
   13239 
   13240 // Scan the heap for objects constructed by a specific function.
   13241 // args[0]: the constructor to find instances of
   13242 // args[1]: the the maximum number of objects to return
   13243 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
   13244   HandleScope scope(isolate);
   13245   ASSERT(args.length() == 2);
   13246 
   13247 
   13248   // Check parameters.
   13249   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
   13250   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   13251   RUNTIME_ASSERT(max_references >= 0);
   13252 
   13253   // Get the number of referencing objects.
   13254   int count;
   13255   // First perform a full GC in order to avoid dead objects and to make the heap
   13256   // iterable.
   13257   Heap* heap = isolate->heap();
   13258   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
   13259   {
   13260     HeapIterator heap_iterator(heap);
   13261     count = DebugConstructedBy(&heap_iterator,
   13262                                *constructor,
   13263                                max_references,
   13264                                NULL,
   13265                                0);
   13266   }
   13267 
   13268   // Allocate an array to hold the result.
   13269   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
   13270 
   13271   // Fill the referencing objects.
   13272   {
   13273     HeapIterator heap_iterator2(heap);
   13274     count = DebugConstructedBy(&heap_iterator2,
   13275                                *constructor,
   13276                                max_references,
   13277                                *instances,
   13278                                count);
   13279   }
   13280 
   13281   // Return result as JS array.
   13282   Handle<JSFunction> array_function(
   13283       isolate->context()->native_context()->array_function());
   13284   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
   13285   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   13286   return *result;
   13287 }
   13288 
   13289 
   13290 // Find the effective prototype object as returned by __proto__.
   13291 // args[0]: the object to find the prototype for.
   13292 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
   13293   HandleScope shs(isolate);
   13294   ASSERT(args.length() == 1);
   13295   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   13296   return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
   13297 }
   13298 
   13299 
   13300 // Patches script source (should be called upon BeforeCompile event).
   13301 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
   13302   HandleScope scope(isolate);
   13303   ASSERT(args.length() == 2);
   13304 
   13305   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
   13306   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13307 
   13308   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
   13309   Handle<Script> script(Script::cast(script_wrapper->value()));
   13310 
   13311   int compilation_state = script->compilation_state();
   13312   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
   13313   script->set_source(*source);
   13314 
   13315   return isolate->heap()->undefined_value();
   13316 }
   13317 
   13318 
   13319 RUNTIME_FUNCTION(Runtime_SystemBreak) {
   13320   SealHandleScope shs(isolate);
   13321   ASSERT(args.length() == 0);
   13322   OS::DebugBreak();
   13323   return isolate->heap()->undefined_value();
   13324 }
   13325 
   13326 
   13327 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
   13328   HandleScope scope(isolate);
   13329 #ifdef DEBUG
   13330   ASSERT(args.length() == 1);
   13331   // Get the function and make sure it is compiled.
   13332   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13333   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13334     return isolate->heap()->exception();
   13335   }
   13336   func->code()->PrintLn();
   13337 #endif  // DEBUG
   13338   return isolate->heap()->undefined_value();
   13339 }
   13340 
   13341 
   13342 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
   13343   HandleScope scope(isolate);
   13344 #ifdef DEBUG
   13345   ASSERT(args.length() == 1);
   13346   // Get the function and make sure it is compiled.
   13347   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13348   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13349     return isolate->heap()->exception();
   13350   }
   13351   func->shared()->construct_stub()->PrintLn();
   13352 #endif  // DEBUG
   13353   return isolate->heap()->undefined_value();
   13354 }
   13355 
   13356 
   13357 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
   13358   SealHandleScope shs(isolate);
   13359   ASSERT(args.length() == 1);
   13360 
   13361   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   13362   return f->shared()->inferred_name();
   13363 }
   13364 
   13365 
   13366 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
   13367                                             Script* script,
   13368                                             FixedArray* buffer) {
   13369   DisallowHeapAllocation no_allocation;
   13370   int counter = 0;
   13371   int buffer_size = buffer->length();
   13372   for (HeapObject* obj = iterator->next();
   13373        obj != NULL;
   13374        obj = iterator->next()) {
   13375     ASSERT(obj != NULL);
   13376     if (!obj->IsSharedFunctionInfo()) {
   13377       continue;
   13378     }
   13379     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
   13380     if (shared->script() != script) {
   13381       continue;
   13382     }
   13383     if (counter < buffer_size) {
   13384       buffer->set(counter, shared);
   13385     }
   13386     counter++;
   13387   }
   13388   return counter;
   13389 }
   13390 
   13391 
   13392 // For a script finds all SharedFunctionInfo's in the heap that points
   13393 // to this script. Returns JSArray of SharedFunctionInfo wrapped
   13394 // in OpaqueReferences.
   13395 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
   13396   HandleScope scope(isolate);
   13397   CHECK(isolate->debug()->live_edit_enabled());
   13398   ASSERT(args.length() == 1);
   13399   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
   13400 
   13401   RUNTIME_ASSERT(script_value->value()->IsScript());
   13402   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
   13403 
   13404   const int kBufferSize = 32;
   13405 
   13406   Handle<FixedArray> array;
   13407   array = isolate->factory()->NewFixedArray(kBufferSize);
   13408   int number;
   13409   Heap* heap = isolate->heap();
   13410   {
   13411     HeapIterator heap_iterator(heap);
   13412     Script* scr = *script;
   13413     FixedArray* arr = *array;
   13414     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13415   }
   13416   if (number > kBufferSize) {
   13417     array = isolate->factory()->NewFixedArray(number);
   13418     HeapIterator heap_iterator(heap);
   13419     Script* scr = *script;
   13420     FixedArray* arr = *array;
   13421     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13422   }
   13423 
   13424   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
   13425   result->set_length(Smi::FromInt(number));
   13426 
   13427   LiveEdit::WrapSharedFunctionInfos(result);
   13428 
   13429   return *result;
   13430 }
   13431 
   13432 
   13433 // For a script calculates compilation information about all its functions.
   13434 // The script source is explicitly specified by the second argument.
   13435 // The source of the actual script is not used, however it is important that
   13436 // all generated code keeps references to this particular instance of script.
   13437 // Returns a JSArray of compilation infos. The array is ordered so that
   13438 // each function with all its descendant is always stored in a continues range
   13439 // with the function itself going first. The root function is a script function.
   13440 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
   13441   HandleScope scope(isolate);
   13442   CHECK(isolate->debug()->live_edit_enabled());
   13443   ASSERT(args.length() == 2);
   13444   CONVERT_ARG_CHECKED(JSValue, script, 0);
   13445   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13446 
   13447   RUNTIME_ASSERT(script->value()->IsScript());
   13448   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
   13449 
   13450   Handle<JSArray> result;
   13451   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13452       isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
   13453   return *result;
   13454 }
   13455 
   13456 
   13457 // Changes the source of the script to a new_source.
   13458 // If old_script_name is provided (i.e. is a String), also creates a copy of
   13459 // the script with its original source and sends notification to debugger.
   13460 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
   13461   HandleScope scope(isolate);
   13462   CHECK(isolate->debug()->live_edit_enabled());
   13463   ASSERT(args.length() == 3);
   13464   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
   13465   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
   13466   CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
   13467 
   13468   RUNTIME_ASSERT(original_script_value->value()->IsScript());
   13469   Handle<Script> original_script(Script::cast(original_script_value->value()));
   13470 
   13471   Handle<Object> old_script = LiveEdit::ChangeScriptSource(
   13472       original_script,  new_source,  old_script_name);
   13473 
   13474   if (old_script->IsScript()) {
   13475     Handle<Script> script_handle = Handle<Script>::cast(old_script);
   13476     return *Script::GetWrapper(script_handle);
   13477   } else {
   13478     return isolate->heap()->null_value();
   13479   }
   13480 }
   13481 
   13482 
   13483 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
   13484   HandleScope scope(isolate);
   13485   CHECK(isolate->debug()->live_edit_enabled());
   13486   ASSERT(args.length() == 1);
   13487   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
   13488   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
   13489 
   13490   LiveEdit::FunctionSourceUpdated(shared_info);
   13491   return isolate->heap()->undefined_value();
   13492 }
   13493 
   13494 
   13495 // Replaces code of SharedFunctionInfo with a new one.
   13496 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
   13497   HandleScope scope(isolate);
   13498   CHECK(isolate->debug()->live_edit_enabled());
   13499   ASSERT(args.length() == 2);
   13500   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
   13501   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
   13502   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
   13503 
   13504   LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
   13505   return isolate->heap()->undefined_value();
   13506 }
   13507 
   13508 
   13509 // Connects SharedFunctionInfo to another script.
   13510 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
   13511   HandleScope scope(isolate);
   13512   CHECK(isolate->debug()->live_edit_enabled());
   13513   ASSERT(args.length() == 2);
   13514   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
   13515   CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
   13516 
   13517   if (function_object->IsJSValue()) {
   13518     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
   13519     if (script_object->IsJSValue()) {
   13520       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
   13521       Script* script = Script::cast(JSValue::cast(*script_object)->value());
   13522       script_object = Handle<Object>(script, isolate);
   13523     }
   13524     RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
   13525     LiveEdit::SetFunctionScript(function_wrapper, script_object);
   13526   } else {
   13527     // Just ignore this. We may not have a SharedFunctionInfo for some functions
   13528     // and we check it in this function.
   13529   }
   13530 
   13531   return isolate->heap()->undefined_value();
   13532 }
   13533 
   13534 
   13535 // In a code of a parent function replaces original function as embedded object
   13536 // with a substitution one.
   13537 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
   13538   HandleScope scope(isolate);
   13539   CHECK(isolate->debug()->live_edit_enabled());
   13540   ASSERT(args.length() == 3);
   13541 
   13542   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
   13543   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
   13544   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
   13545   RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
   13546   RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
   13547   RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
   13548 
   13549   LiveEdit::ReplaceRefToNestedFunction(
   13550       parent_wrapper, orig_wrapper, subst_wrapper);
   13551   return isolate->heap()->undefined_value();
   13552 }
   13553 
   13554 
   13555 // Updates positions of a shared function info (first parameter) according
   13556 // to script source change. Text change is described in second parameter as
   13557 // array of groups of 3 numbers:
   13558 // (change_begin, change_end, change_end_new_position).
   13559 // Each group describes a change in text; groups are sorted by change_begin.
   13560 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
   13561   HandleScope scope(isolate);
   13562   CHECK(isolate->debug()->live_edit_enabled());
   13563   ASSERT(args.length() == 2);
   13564   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13565   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
   13566   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
   13567 
   13568   LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
   13569   return isolate->heap()->undefined_value();
   13570 }
   13571 
   13572 
   13573 // For array of SharedFunctionInfo's (each wrapped in JSValue)
   13574 // checks that none of them have activations on stacks (of any thread).
   13575 // Returns array of the same length with corresponding results of
   13576 // LiveEdit::FunctionPatchabilityStatus type.
   13577 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
   13578   HandleScope scope(isolate);
   13579   CHECK(isolate->debug()->live_edit_enabled());
   13580   ASSERT(args.length() == 2);
   13581   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13582   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
   13583   RUNTIME_ASSERT(shared_array->length()->IsSmi());
   13584   int array_length = Smi::cast(shared_array->length())->value();
   13585   for (int i = 0; i < array_length; i++) {
   13586     Handle<Object> element =
   13587         Object::GetElement(isolate, shared_array, i).ToHandleChecked();
   13588     RUNTIME_ASSERT(
   13589         element->IsJSValue() &&
   13590         Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
   13591   }
   13592 
   13593   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
   13594 }
   13595 
   13596 
   13597 // Compares 2 strings line-by-line, then token-wise and returns diff in form
   13598 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
   13599 // of diff chunks.
   13600 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
   13601   HandleScope scope(isolate);
   13602   CHECK(isolate->debug()->live_edit_enabled());
   13603   ASSERT(args.length() == 2);
   13604   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
   13605   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
   13606 
   13607   return *LiveEdit::CompareStrings(s1, s2);
   13608 }
   13609 
   13610 
   13611 // Restarts a call frame and completely drops all frames above.
   13612 // Returns true if successful. Otherwise returns undefined or an error message.
   13613 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
   13614   HandleScope scope(isolate);
   13615   CHECK(isolate->debug()->live_edit_enabled());
   13616   ASSERT(args.length() == 2);
   13617   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   13618   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
   13619 
   13620   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   13621   Heap* heap = isolate->heap();
   13622 
   13623   // Find the relevant frame with the requested index.
   13624   StackFrame::Id id = isolate->debug()->break_frame_id();
   13625   if (id == StackFrame::NO_ID) {
   13626     // If there are no JavaScript stack frames return undefined.
   13627     return heap->undefined_value();
   13628   }
   13629 
   13630   int count = 0;
   13631   JavaScriptFrameIterator it(isolate, id);
   13632   for (; !it.done(); it.Advance()) {
   13633     if (index < count + it.frame()->GetInlineCount()) break;
   13634     count += it.frame()->GetInlineCount();
   13635   }
   13636   if (it.done()) return heap->undefined_value();
   13637 
   13638   const char* error_message = LiveEdit::RestartFrame(it.frame());
   13639   if (error_message) {
   13640     return *(isolate->factory()->InternalizeUtf8String(error_message));
   13641   }
   13642   return heap->true_value();
   13643 }
   13644 
   13645 
   13646 // A testing entry. Returns statement position which is the closest to
   13647 // source_position.
   13648 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
   13649   HandleScope scope(isolate);
   13650   CHECK(isolate->debug()->live_edit_enabled());
   13651   ASSERT(args.length() == 2);
   13652   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13653   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   13654 
   13655   Handle<Code> code(function->code(), isolate);
   13656 
   13657   if (code->kind() != Code::FUNCTION &&
   13658       code->kind() != Code::OPTIMIZED_FUNCTION) {
   13659     return isolate->heap()->undefined_value();
   13660   }
   13661 
   13662   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
   13663   int closest_pc = 0;
   13664   int distance = kMaxInt;
   13665   while (!it.done()) {
   13666     int statement_position = static_cast<int>(it.rinfo()->data());
   13667     // Check if this break point is closer that what was previously found.
   13668     if (source_position <= statement_position &&
   13669         statement_position - source_position < distance) {
   13670       closest_pc =
   13671           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
   13672       distance = statement_position - source_position;
   13673       // Check whether we can't get any closer.
   13674       if (distance == 0) break;
   13675     }
   13676     it.next();
   13677   }
   13678 
   13679   return Smi::FromInt(closest_pc);
   13680 }
   13681 
   13682 
   13683 // Calls specified function with or without entering the debugger.
   13684 // This is used in unit tests to run code as if debugger is entered or simply
   13685 // to have a stack with C++ frame in the middle.
   13686 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
   13687   HandleScope scope(isolate);
   13688   ASSERT(args.length() == 2);
   13689   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13690   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
   13691 
   13692   MaybeHandle<Object> maybe_result;
   13693   if (without_debugger) {
   13694     maybe_result = Execution::Call(isolate,
   13695                                    function,
   13696                                    isolate->global_object(),
   13697                                    0,
   13698                                    NULL);
   13699   } else {
   13700     DebugScope debug_scope(isolate->debug());
   13701     maybe_result = Execution::Call(isolate,
   13702                                    function,
   13703                                    isolate->global_object(),
   13704                                    0,
   13705                                    NULL);
   13706   }
   13707   Handle<Object> result;
   13708   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
   13709   return *result;
   13710 }
   13711 
   13712 
   13713 // Sets a v8 flag.
   13714 RUNTIME_FUNCTION(Runtime_SetFlags) {
   13715   SealHandleScope shs(isolate);
   13716   ASSERT(args.length() == 1);
   13717   CONVERT_ARG_CHECKED(String, arg, 0);
   13718   SmartArrayPointer<char> flags =
   13719       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   13720   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
   13721   return isolate->heap()->undefined_value();
   13722 }
   13723 
   13724 
   13725 // Performs a GC.
   13726 // Presently, it only does a full GC.
   13727 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
   13728   SealHandleScope shs(isolate);
   13729   ASSERT(args.length() == 1);
   13730   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
   13731   return isolate->heap()->undefined_value();
   13732 }
   13733 
   13734 
   13735 // Gets the current heap usage.
   13736 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
   13737   SealHandleScope shs(isolate);
   13738   ASSERT(args.length() == 0);
   13739   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
   13740   if (!Smi::IsValid(usage)) {
   13741     return *isolate->factory()->NewNumberFromInt(usage);
   13742   }
   13743   return Smi::FromInt(usage);
   13744 }
   13745 
   13746 
   13747 #ifdef V8_I18N_SUPPORT
   13748 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
   13749   HandleScope scope(isolate);
   13750   Factory* factory = isolate->factory();
   13751 
   13752   ASSERT(args.length() == 1);
   13753   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
   13754 
   13755   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
   13756 
   13757   // Return value which denotes invalid language tag.
   13758   const char* const kInvalidTag = "invalid-tag";
   13759 
   13760   UErrorCode error = U_ZERO_ERROR;
   13761   char icu_result[ULOC_FULLNAME_CAPACITY];
   13762   int icu_length = 0;
   13763 
   13764   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
   13765                       &icu_length, &error);
   13766   if (U_FAILURE(error) || icu_length == 0) {
   13767     return *factory->NewStringFromAsciiChecked(kInvalidTag);
   13768   }
   13769 
   13770   char result[ULOC_FULLNAME_CAPACITY];
   13771 
   13772   // Force strict BCP47 rules.
   13773   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
   13774 
   13775   if (U_FAILURE(error)) {
   13776     return *factory->NewStringFromAsciiChecked(kInvalidTag);
   13777   }
   13778 
   13779   return *factory->NewStringFromAsciiChecked(result);
   13780 }
   13781 
   13782 
   13783 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
   13784   HandleScope scope(isolate);
   13785   Factory* factory = isolate->factory();
   13786 
   13787   ASSERT(args.length() == 1);
   13788   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
   13789 
   13790   const icu::Locale* available_locales = NULL;
   13791   int32_t count = 0;
   13792 
   13793   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
   13794     available_locales = icu::Collator::getAvailableLocales(count);
   13795   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
   13796     available_locales = icu::NumberFormat::getAvailableLocales(count);
   13797   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
   13798     available_locales = icu::DateFormat::getAvailableLocales(count);
   13799   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
   13800     available_locales = icu::BreakIterator::getAvailableLocales(count);
   13801   }
   13802 
   13803   UErrorCode error = U_ZERO_ERROR;
   13804   char result[ULOC_FULLNAME_CAPACITY];
   13805   Handle<JSObject> locales =
   13806       factory->NewJSObject(isolate->object_function());
   13807 
   13808   for (int32_t i = 0; i < count; ++i) {
   13809     const char* icu_name = available_locales[i].getName();
   13810 
   13811     error = U_ZERO_ERROR;
   13812     // No need to force strict BCP47 rules.
   13813     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13814     if (U_FAILURE(error)) {
   13815       // This shouldn't happen, but lets not break the user.
   13816       continue;
   13817     }
   13818 
   13819     RETURN_FAILURE_ON_EXCEPTION(isolate,
   13820         JSObject::SetOwnPropertyIgnoreAttributes(
   13821             locales,
   13822             factory->NewStringFromAsciiChecked(result),
   13823             factory->NewNumber(i),
   13824             NONE));
   13825   }
   13826 
   13827   return *locales;
   13828 }
   13829 
   13830 
   13831 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
   13832   HandleScope scope(isolate);
   13833   Factory* factory = isolate->factory();
   13834 
   13835   ASSERT(args.length() == 0);
   13836 
   13837   icu::Locale default_locale;
   13838 
   13839   // Set the locale
   13840   char result[ULOC_FULLNAME_CAPACITY];
   13841   UErrorCode status = U_ZERO_ERROR;
   13842   uloc_toLanguageTag(
   13843       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
   13844   if (U_SUCCESS(status)) {
   13845     return *factory->NewStringFromAsciiChecked(result);
   13846   }
   13847 
   13848   return *factory->NewStringFromStaticAscii("und");
   13849 }
   13850 
   13851 
   13852 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
   13853   HandleScope scope(isolate);
   13854   Factory* factory = isolate->factory();
   13855 
   13856   ASSERT(args.length() == 1);
   13857 
   13858   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
   13859 
   13860   uint32_t length = static_cast<uint32_t>(input->length()->Number());
   13861   // Set some limit to prevent fuzz tests from going OOM.
   13862   // Can be bumped when callers' requirements change.
   13863   RUNTIME_ASSERT(length < 100);
   13864   Handle<FixedArray> output = factory->NewFixedArray(length);
   13865   Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
   13866   Handle<Name> base = factory->NewStringFromStaticAscii("base");
   13867   for (unsigned int i = 0; i < length; ++i) {
   13868     Handle<Object> locale_id;
   13869     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   13870         isolate, locale_id, Object::GetElement(isolate, input, i));
   13871     if (!locale_id->IsString()) {
   13872       return isolate->Throw(*factory->illegal_argument_string());
   13873     }
   13874 
   13875     v8::String::Utf8Value utf8_locale_id(
   13876         v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
   13877 
   13878     UErrorCode error = U_ZERO_ERROR;
   13879 
   13880     // Convert from BCP47 to ICU format.
   13881     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
   13882     char icu_locale[ULOC_FULLNAME_CAPACITY];
   13883     int icu_locale_length = 0;
   13884     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
   13885                         &icu_locale_length, &error);
   13886     if (U_FAILURE(error) || icu_locale_length == 0) {
   13887       return isolate->Throw(*factory->illegal_argument_string());
   13888     }
   13889 
   13890     // Maximize the locale.
   13891     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
   13892     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
   13893     uloc_addLikelySubtags(
   13894         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13895 
   13896     // Remove extensions from maximized locale.
   13897     // de_Latn_DE@collation=phonebook -> de_Latn_DE
   13898     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
   13899     uloc_getBaseName(
   13900         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13901 
   13902     // Get original name without extensions.
   13903     // de_DE@collation=phonebook -> de_DE
   13904     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
   13905     uloc_getBaseName(
   13906         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
   13907 
   13908     // Convert from ICU locale format to BCP47 format.
   13909     // de_Latn_DE -> de-Latn-DE
   13910     char base_max_locale[ULOC_FULLNAME_CAPACITY];
   13911     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
   13912                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13913 
   13914     // de_DE -> de-DE
   13915     char base_locale[ULOC_FULLNAME_CAPACITY];
   13916     uloc_toLanguageTag(
   13917         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13918 
   13919     if (U_FAILURE(error)) {
   13920       return isolate->Throw(*factory->illegal_argument_string());
   13921     }
   13922 
   13923     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
   13924     RETURN_FAILURE_ON_EXCEPTION(isolate,
   13925         JSObject::SetOwnPropertyIgnoreAttributes(
   13926             result,
   13927             maximized,
   13928             factory->NewStringFromAsciiChecked(base_max_locale),
   13929             NONE));
   13930     RETURN_FAILURE_ON_EXCEPTION(isolate,
   13931         JSObject::SetOwnPropertyIgnoreAttributes(
   13932             result,
   13933             base,
   13934             factory->NewStringFromAsciiChecked(base_locale),
   13935             NONE));
   13936     output->set(i, *result);
   13937   }
   13938 
   13939   Handle<JSArray> result = factory->NewJSArrayWithElements(output);
   13940   result->set_length(Smi::FromInt(length));
   13941   return *result;
   13942 }
   13943 
   13944 
   13945 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
   13946   HandleScope scope(isolate);
   13947 
   13948   ASSERT(args.length() == 1);
   13949 
   13950   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   13951 
   13952   if (!input->IsJSObject()) return isolate->heap()->false_value();
   13953   Handle<JSObject> obj = Handle<JSObject>::cast(input);
   13954 
   13955   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
   13956   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
   13957   return isolate->heap()->ToBoolean(!tag->IsTheHole());
   13958 }
   13959 
   13960 
   13961 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
   13962   HandleScope scope(isolate);
   13963 
   13964   ASSERT(args.length() == 2);
   13965 
   13966   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   13967   CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
   13968 
   13969   if (!input->IsJSObject()) return isolate->heap()->false_value();
   13970   Handle<JSObject> obj = Handle<JSObject>::cast(input);
   13971 
   13972   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
   13973   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
   13974   return isolate->heap()->ToBoolean(
   13975       tag->IsString() && String::cast(*tag)->Equals(*expected_type));
   13976 }
   13977 
   13978 
   13979 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
   13980   HandleScope scope(isolate);
   13981 
   13982   ASSERT(args.length() == 3);
   13983 
   13984   CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
   13985   CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   13986   CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
   13987 
   13988   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
   13989   JSObject::SetHiddenProperty(input, marker, type);
   13990 
   13991   marker = isolate->factory()->intl_impl_object_string();
   13992   JSObject::SetHiddenProperty(input, marker, impl);
   13993 
   13994   return isolate->heap()->undefined_value();
   13995 }
   13996 
   13997 
   13998 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
   13999   HandleScope scope(isolate);
   14000 
   14001   ASSERT(args.length() == 1);
   14002 
   14003   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
   14004 
   14005   if (!input->IsJSObject()) {
   14006     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
   14007     Handle<Object> type_error =
   14008         isolate->factory()->NewTypeError("not_intl_object", arguments);
   14009     return isolate->Throw(*type_error);
   14010   }
   14011 
   14012   Handle<JSObject> obj = Handle<JSObject>::cast(input);
   14013 
   14014   Handle<String> marker = isolate->factory()->intl_impl_object_string();
   14015   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
   14016   if (impl->IsTheHole()) {
   14017     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
   14018     Handle<Object> type_error =
   14019         isolate->factory()->NewTypeError("not_intl_object", arguments);
   14020     return isolate->Throw(*type_error);
   14021   }
   14022   return *impl;
   14023 }
   14024 
   14025 
   14026 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
   14027   HandleScope scope(isolate);
   14028 
   14029   ASSERT(args.length() == 3);
   14030 
   14031   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14032   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14033   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14034 
   14035   Handle<ObjectTemplateInfo> date_format_template =
   14036       I18N::GetTemplate(isolate);
   14037 
   14038   // Create an empty object wrapper.
   14039   Handle<JSObject> local_object;
   14040   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14041       isolate, local_object,
   14042       Execution::InstantiateObject(date_format_template));
   14043 
   14044   // Set date time formatter as internal field of the resulting JS object.
   14045   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
   14046       isolate, locale, options, resolved);
   14047 
   14048   if (!date_format) return isolate->ThrowIllegalOperation();
   14049 
   14050   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
   14051 
   14052   RETURN_FAILURE_ON_EXCEPTION(isolate,
   14053       JSObject::SetOwnPropertyIgnoreAttributes(
   14054           local_object,
   14055           isolate->factory()->NewStringFromStaticAscii("dateFormat"),
   14056           isolate->factory()->NewStringFromStaticAscii("valid"),
   14057           NONE));
   14058 
   14059   // Make object handle weak so we can delete the data format once GC kicks in.
   14060   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14061   GlobalHandles::MakeWeak(wrapper.location(),
   14062                           reinterpret_cast<void*>(wrapper.location()),
   14063                           DateFormat::DeleteDateFormat);
   14064   return *local_object;
   14065 }
   14066 
   14067 
   14068 RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
   14069   HandleScope scope(isolate);
   14070 
   14071   ASSERT(args.length() == 2);
   14072 
   14073   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   14074   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
   14075 
   14076   Handle<Object> value;
   14077   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14078       isolate, value, Execution::ToNumber(isolate, date));
   14079 
   14080   icu::SimpleDateFormat* date_format =
   14081       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   14082   if (!date_format) return isolate->ThrowIllegalOperation();
   14083 
   14084   icu::UnicodeString result;
   14085   date_format->format(value->Number(), result);
   14086 
   14087   Handle<String> result_str;
   14088   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14089       isolate, result_str,
   14090       isolate->factory()->NewStringFromTwoByte(
   14091           Vector<const uint16_t>(
   14092               reinterpret_cast<const uint16_t*>(result.getBuffer()),
   14093               result.length())));
   14094   return *result_str;
   14095 }
   14096 
   14097 
   14098 RUNTIME_FUNCTION(Runtime_InternalDateParse) {
   14099   HandleScope scope(isolate);
   14100 
   14101   ASSERT(args.length() == 2);
   14102 
   14103   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   14104   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
   14105 
   14106   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
   14107   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
   14108   icu::SimpleDateFormat* date_format =
   14109       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   14110   if (!date_format) return isolate->ThrowIllegalOperation();
   14111 
   14112   UErrorCode status = U_ZERO_ERROR;
   14113   UDate date = date_format->parse(u_date, status);
   14114   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   14115 
   14116   Handle<Object> result;
   14117   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14118       isolate, result,
   14119       Execution::NewDate(isolate, static_cast<double>(date)));
   14120   ASSERT(result->IsJSDate());
   14121   return *result;
   14122 }
   14123 
   14124 
   14125 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
   14126   HandleScope scope(isolate);
   14127 
   14128   ASSERT(args.length() == 3);
   14129 
   14130   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14131   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14132   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14133 
   14134   Handle<ObjectTemplateInfo> number_format_template =
   14135       I18N::GetTemplate(isolate);
   14136 
   14137   // Create an empty object wrapper.
   14138   Handle<JSObject> local_object;
   14139   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14140       isolate, local_object,
   14141       Execution::InstantiateObject(number_format_template));
   14142 
   14143   // Set number formatter as internal field of the resulting JS object.
   14144   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
   14145       isolate, locale, options, resolved);
   14146 
   14147   if (!number_format) return isolate->ThrowIllegalOperation();
   14148 
   14149   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
   14150 
   14151   RETURN_FAILURE_ON_EXCEPTION(isolate,
   14152       JSObject::SetOwnPropertyIgnoreAttributes(
   14153           local_object,
   14154           isolate->factory()->NewStringFromStaticAscii("numberFormat"),
   14155           isolate->factory()->NewStringFromStaticAscii("valid"),
   14156           NONE));
   14157 
   14158   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14159   GlobalHandles::MakeWeak(wrapper.location(),
   14160                           reinterpret_cast<void*>(wrapper.location()),
   14161                           NumberFormat::DeleteNumberFormat);
   14162   return *local_object;
   14163 }
   14164 
   14165 
   14166 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
   14167   HandleScope scope(isolate);
   14168 
   14169   ASSERT(args.length() == 2);
   14170 
   14171   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   14172   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
   14173 
   14174   Handle<Object> value;
   14175   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14176       isolate, value, Execution::ToNumber(isolate, number));
   14177 
   14178   icu::DecimalFormat* number_format =
   14179       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   14180   if (!number_format) return isolate->ThrowIllegalOperation();
   14181 
   14182   icu::UnicodeString result;
   14183   number_format->format(value->Number(), result);
   14184 
   14185   Handle<String> result_str;
   14186   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14187       isolate, result_str,
   14188       isolate->factory()->NewStringFromTwoByte(
   14189           Vector<const uint16_t>(
   14190               reinterpret_cast<const uint16_t*>(result.getBuffer()),
   14191               result.length())));
   14192   return *result_str;
   14193 }
   14194 
   14195 
   14196 RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
   14197   HandleScope scope(isolate);
   14198 
   14199   ASSERT(args.length() == 2);
   14200 
   14201   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   14202   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
   14203 
   14204   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
   14205   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
   14206   icu::DecimalFormat* number_format =
   14207       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   14208   if (!number_format) return isolate->ThrowIllegalOperation();
   14209 
   14210   UErrorCode status = U_ZERO_ERROR;
   14211   icu::Formattable result;
   14212   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
   14213   // to be part of Chrome.
   14214   // TODO(cira): Include currency parsing code using parseCurrency call.
   14215   // We need to check if the formatter parses all currencies or only the
   14216   // one it was constructed with (it will impact the API - how to return ISO
   14217   // code and the value).
   14218   number_format->parse(u_number, result, status);
   14219   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   14220 
   14221   switch (result.getType()) {
   14222   case icu::Formattable::kDouble:
   14223     return *isolate->factory()->NewNumber(result.getDouble());
   14224   case icu::Formattable::kLong:
   14225     return *isolate->factory()->NewNumberFromInt(result.getLong());
   14226   case icu::Formattable::kInt64:
   14227     return *isolate->factory()->NewNumber(
   14228         static_cast<double>(result.getInt64()));
   14229   default:
   14230     return isolate->heap()->undefined_value();
   14231   }
   14232 }
   14233 
   14234 
   14235 RUNTIME_FUNCTION(Runtime_CreateCollator) {
   14236   HandleScope scope(isolate);
   14237 
   14238   ASSERT(args.length() == 3);
   14239 
   14240   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14241   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14242   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14243 
   14244   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
   14245 
   14246   // Create an empty object wrapper.
   14247   Handle<JSObject> local_object;
   14248   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14249       isolate, local_object, Execution::InstantiateObject(collator_template));
   14250 
   14251   // Set collator as internal field of the resulting JS object.
   14252   icu::Collator* collator = Collator::InitializeCollator(
   14253       isolate, locale, options, resolved);
   14254 
   14255   if (!collator) return isolate->ThrowIllegalOperation();
   14256 
   14257   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
   14258 
   14259   RETURN_FAILURE_ON_EXCEPTION(isolate,
   14260       JSObject::SetOwnPropertyIgnoreAttributes(
   14261           local_object,
   14262           isolate->factory()->NewStringFromStaticAscii("collator"),
   14263           isolate->factory()->NewStringFromStaticAscii("valid"),
   14264           NONE));
   14265 
   14266   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14267   GlobalHandles::MakeWeak(wrapper.location(),
   14268                           reinterpret_cast<void*>(wrapper.location()),
   14269                           Collator::DeleteCollator);
   14270   return *local_object;
   14271 }
   14272 
   14273 
   14274 RUNTIME_FUNCTION(Runtime_InternalCompare) {
   14275   HandleScope scope(isolate);
   14276 
   14277   ASSERT(args.length() == 3);
   14278 
   14279   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
   14280   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
   14281   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
   14282 
   14283   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
   14284   if (!collator) return isolate->ThrowIllegalOperation();
   14285 
   14286   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
   14287   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
   14288   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
   14289   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
   14290   UErrorCode status = U_ZERO_ERROR;
   14291   UCollationResult result = collator->compare(u_string1,
   14292                                               string_value1.length(),
   14293                                               u_string2,
   14294                                               string_value2.length(),
   14295                                               status);
   14296   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
   14297 
   14298   return *isolate->factory()->NewNumberFromInt(result);
   14299 }
   14300 
   14301 
   14302 RUNTIME_FUNCTION(Runtime_StringNormalize) {
   14303   HandleScope scope(isolate);
   14304   static const UNormalizationMode normalizationForms[] =
   14305       { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
   14306 
   14307   ASSERT(args.length() == 2);
   14308 
   14309   CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
   14310   CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
   14311   RUNTIME_ASSERT(form_id >= 0 &&
   14312                  static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
   14313 
   14314   v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
   14315   const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
   14316 
   14317   // TODO(mnita): check Normalizer2 (not available in ICU 46)
   14318   UErrorCode status = U_ZERO_ERROR;
   14319   icu::UnicodeString result;
   14320   icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
   14321       result, status);
   14322   if (U_FAILURE(status)) {
   14323     return isolate->heap()->undefined_value();
   14324   }
   14325 
   14326   Handle<String> result_str;
   14327   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14328       isolate, result_str,
   14329       isolate->factory()->NewStringFromTwoByte(
   14330           Vector<const uint16_t>(
   14331               reinterpret_cast<const uint16_t*>(result.getBuffer()),
   14332               result.length())));
   14333   return *result_str;
   14334 }
   14335 
   14336 
   14337 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
   14338   HandleScope scope(isolate);
   14339 
   14340   ASSERT(args.length() == 3);
   14341 
   14342   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14343   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14344   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14345 
   14346   Handle<ObjectTemplateInfo> break_iterator_template =
   14347       I18N::GetTemplate2(isolate);
   14348 
   14349   // Create an empty object wrapper.
   14350   Handle<JSObject> local_object;
   14351   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14352       isolate, local_object,
   14353       Execution::InstantiateObject(break_iterator_template));
   14354 
   14355   // Set break iterator as internal field of the resulting JS object.
   14356   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
   14357       isolate, locale, options, resolved);
   14358 
   14359   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14360 
   14361   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
   14362   // Make sure that the pointer to adopted text is NULL.
   14363   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
   14364 
   14365   RETURN_FAILURE_ON_EXCEPTION(isolate,
   14366       JSObject::SetOwnPropertyIgnoreAttributes(
   14367           local_object,
   14368           isolate->factory()->NewStringFromStaticAscii("breakIterator"),
   14369           isolate->factory()->NewStringFromStaticAscii("valid"),
   14370           NONE));
   14371 
   14372   // Make object handle weak so we can delete the break iterator once GC kicks
   14373   // in.
   14374   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14375   GlobalHandles::MakeWeak(wrapper.location(),
   14376                           reinterpret_cast<void*>(wrapper.location()),
   14377                           BreakIterator::DeleteBreakIterator);
   14378   return *local_object;
   14379 }
   14380 
   14381 
   14382 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
   14383   HandleScope scope(isolate);
   14384 
   14385   ASSERT(args.length() == 2);
   14386 
   14387   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14388   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
   14389 
   14390   icu::BreakIterator* break_iterator =
   14391       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14392   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14393 
   14394   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
   14395       break_iterator_holder->GetInternalField(1));
   14396   delete u_text;
   14397 
   14398   v8::String::Value text_value(v8::Utils::ToLocal(text));
   14399   u_text = new icu::UnicodeString(
   14400       reinterpret_cast<const UChar*>(*text_value), text_value.length());
   14401   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
   14402 
   14403   break_iterator->setText(*u_text);
   14404 
   14405   return isolate->heap()->undefined_value();
   14406 }
   14407 
   14408 
   14409 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
   14410   HandleScope scope(isolate);
   14411 
   14412   ASSERT(args.length() == 1);
   14413 
   14414   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14415 
   14416   icu::BreakIterator* break_iterator =
   14417       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14418   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14419 
   14420   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
   14421 }
   14422 
   14423 
   14424 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
   14425   HandleScope scope(isolate);
   14426 
   14427   ASSERT(args.length() == 1);
   14428 
   14429   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14430 
   14431   icu::BreakIterator* break_iterator =
   14432       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14433   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14434 
   14435   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
   14436 }
   14437 
   14438 
   14439 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
   14440   HandleScope scope(isolate);
   14441 
   14442   ASSERT(args.length() == 1);
   14443 
   14444   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14445 
   14446   icu::BreakIterator* break_iterator =
   14447       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14448   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14449 
   14450   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
   14451 }
   14452 
   14453 
   14454 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
   14455   HandleScope scope(isolate);
   14456 
   14457   ASSERT(args.length() == 1);
   14458 
   14459   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14460 
   14461   icu::BreakIterator* break_iterator =
   14462       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14463   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14464 
   14465   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
   14466   icu::RuleBasedBreakIterator* rule_based_iterator =
   14467       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
   14468   int32_t status = rule_based_iterator->getRuleStatus();
   14469   // Keep return values in sync with JavaScript BreakType enum.
   14470   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
   14471     return *isolate->factory()->NewStringFromStaticAscii("none");
   14472   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
   14473     return *isolate->factory()->NewStringFromStaticAscii("number");
   14474   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
   14475     return *isolate->factory()->NewStringFromStaticAscii("letter");
   14476   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
   14477     return *isolate->factory()->NewStringFromStaticAscii("kana");
   14478   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
   14479     return *isolate->factory()->NewStringFromStaticAscii("ideo");
   14480   } else {
   14481     return *isolate->factory()->NewStringFromStaticAscii("unknown");
   14482   }
   14483 }
   14484 #endif  // V8_I18N_SUPPORT
   14485 
   14486 
   14487 // Finds the script object from the script data. NOTE: This operation uses
   14488 // heap traversal to find the function generated for the source position
   14489 // for the requested break point. For lazily compiled functions several heap
   14490 // traversals might be required rendering this operation as a rather slow
   14491 // operation. However for setting break points which is normally done through
   14492 // some kind of user interaction the performance is not crucial.
   14493 static Handle<Object> Runtime_GetScriptFromScriptName(
   14494     Handle<String> script_name) {
   14495   // Scan the heap for Script objects to find the script with the requested
   14496   // script data.
   14497   Handle<Script> script;
   14498   Factory* factory = script_name->GetIsolate()->factory();
   14499   Heap* heap = script_name->GetHeap();
   14500   HeapIterator iterator(heap);
   14501   HeapObject* obj = NULL;
   14502   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
   14503     // If a script is found check if it has the script data requested.
   14504     if (obj->IsScript()) {
   14505       if (Script::cast(obj)->name()->IsString()) {
   14506         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
   14507           script = Handle<Script>(Script::cast(obj));
   14508         }
   14509       }
   14510     }
   14511   }
   14512 
   14513   // If no script with the requested script data is found return undefined.
   14514   if (script.is_null()) return factory->undefined_value();
   14515 
   14516   // Return the script found.
   14517   return Script::GetWrapper(script);
   14518 }
   14519 
   14520 
   14521 // Get the script object from script data. NOTE: Regarding performance
   14522 // see the NOTE for GetScriptFromScriptData.
   14523 // args[0]: script data for the script to find the source for
   14524 RUNTIME_FUNCTION(Runtime_GetScript) {
   14525   HandleScope scope(isolate);
   14526 
   14527   ASSERT(args.length() == 1);
   14528 
   14529   CONVERT_ARG_CHECKED(String, script_name, 0);
   14530 
   14531   // Find the requested script.
   14532   Handle<Object> result =
   14533       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
   14534   return *result;
   14535 }
   14536 
   14537 
   14538 // Collect the raw data for a stack trace.  Returns an array of 4
   14539 // element segments each containing a receiver, function, code and
   14540 // native code offset.
   14541 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
   14542   HandleScope scope(isolate);
   14543   ASSERT(args.length() == 3);
   14544   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   14545   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
   14546   CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
   14547 
   14548   // Optionally capture a more detailed stack trace for the message.
   14549   isolate->CaptureAndSetDetailedStackTrace(error_object);
   14550   // Capture a simple stack trace for the stack property.
   14551   return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
   14552 }
   14553 
   14554 
   14555 // Retrieve the stack trace.  This is the raw stack trace that yet has to
   14556 // be formatted.  Since we only need this once, clear it afterwards.
   14557 RUNTIME_FUNCTION(Runtime_GetAndClearOverflowedStackTrace) {
   14558   HandleScope scope(isolate);
   14559   ASSERT(args.length() == 1);
   14560   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   14561   Handle<String> key = isolate->factory()->hidden_stack_trace_string();
   14562   Handle<Object> result(error_object->GetHiddenProperty(key), isolate);
   14563   if (result->IsTheHole()) return isolate->heap()->undefined_value();
   14564   RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
   14565   JSObject::DeleteHiddenProperty(error_object, key);
   14566   return *result;
   14567 }
   14568 
   14569 
   14570 // Returns V8 version as a string.
   14571 RUNTIME_FUNCTION(Runtime_GetV8Version) {
   14572   HandleScope scope(isolate);
   14573   ASSERT(args.length() == 0);
   14574 
   14575   const char* version_string = v8::V8::GetVersion();
   14576 
   14577   return *isolate->factory()->NewStringFromAsciiChecked(version_string);
   14578 }
   14579 
   14580 
   14581 RUNTIME_FUNCTION(Runtime_Abort) {
   14582   SealHandleScope shs(isolate);
   14583   ASSERT(args.length() == 1);
   14584   CONVERT_SMI_ARG_CHECKED(message_id, 0);
   14585   const char* message = GetBailoutReason(
   14586       static_cast<BailoutReason>(message_id));
   14587   OS::PrintError("abort: %s\n", message);
   14588   isolate->PrintStack(stderr);
   14589   OS::Abort();
   14590   UNREACHABLE();
   14591   return NULL;
   14592 }
   14593 
   14594 
   14595 RUNTIME_FUNCTION(Runtime_AbortJS) {
   14596   HandleScope scope(isolate);
   14597   ASSERT(args.length() == 1);
   14598   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
   14599   OS::PrintError("abort: %s\n", message->ToCString().get());
   14600   isolate->PrintStack(stderr);
   14601   OS::Abort();
   14602   UNREACHABLE();
   14603   return NULL;
   14604 }
   14605 
   14606 
   14607 RUNTIME_FUNCTION(Runtime_FlattenString) {
   14608   HandleScope scope(isolate);
   14609   ASSERT(args.length() == 1);
   14610   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   14611   return *String::Flatten(str);
   14612 }
   14613 
   14614 
   14615 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
   14616   HandleScope scope(isolate);
   14617   ASSERT(args.length() == 0);
   14618   isolate->heap()->NotifyContextDisposed();
   14619   return isolate->heap()->undefined_value();
   14620 }
   14621 
   14622 
   14623 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
   14624   HandleScope scope(isolate);
   14625   ASSERT(args.length() == 2);
   14626   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   14627   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
   14628   RUNTIME_ASSERT((index->value() & 1) == 1);
   14629   FieldIndex field_index =
   14630       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
   14631   if (field_index.is_inobject()) {
   14632     RUNTIME_ASSERT(field_index.property_index() <
   14633                    object->map()->inobject_properties());
   14634   } else {
   14635     RUNTIME_ASSERT(field_index.outobject_array_index() <
   14636                    object->properties()->length());
   14637   }
   14638   Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
   14639   RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
   14640   return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
   14641 }
   14642 
   14643 
   14644 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
   14645   HandleScope scope(isolate);
   14646   ASSERT(args.length() == 1);
   14647   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   14648   if (!object->IsJSObject()) return Smi::FromInt(0);
   14649   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   14650   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
   14651   // This call must not cause lazy deopts, because it's called from deferred
   14652   // code where we can't handle lazy deopts for lack of a suitable bailout
   14653   // ID. So we just try migration and signal failure if necessary,
   14654   // which will also trigger a deopt.
   14655   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
   14656   return *object;
   14657 }
   14658 
   14659 
   14660 RUNTIME_FUNCTION(RuntimeHidden_GetFromCache) {
   14661   SealHandleScope shs(isolate);
   14662   // This is only called from codegen, so checks might be more lax.
   14663   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
   14664   CONVERT_ARG_CHECKED(Object, key, 1);
   14665 
   14666   {
   14667     DisallowHeapAllocation no_alloc;
   14668 
   14669     int finger_index = cache->finger_index();
   14670     Object* o = cache->get(finger_index);
   14671     if (o == key) {
   14672       // The fastest case: hit the same place again.
   14673       return cache->get(finger_index + 1);
   14674     }
   14675 
   14676     for (int i = finger_index - 2;
   14677          i >= JSFunctionResultCache::kEntriesIndex;
   14678          i -= 2) {
   14679       o = cache->get(i);
   14680       if (o == key) {
   14681         cache->set_finger_index(i);
   14682         return cache->get(i + 1);
   14683       }
   14684     }
   14685 
   14686     int size = cache->size();
   14687     ASSERT(size <= cache->length());
   14688 
   14689     for (int i = size - 2; i > finger_index; i -= 2) {
   14690       o = cache->get(i);
   14691       if (o == key) {
   14692         cache->set_finger_index(i);
   14693         return cache->get(i + 1);
   14694       }
   14695     }
   14696   }
   14697 
   14698   // There is no value in the cache.  Invoke the function and cache result.
   14699   HandleScope scope(isolate);
   14700 
   14701   Handle<JSFunctionResultCache> cache_handle(cache);
   14702   Handle<Object> key_handle(key, isolate);
   14703   Handle<Object> value;
   14704   {
   14705     Handle<JSFunction> factory(JSFunction::cast(
   14706           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
   14707     // TODO(antonm): consider passing a receiver when constructing a cache.
   14708     Handle<Object> receiver(isolate->native_context()->global_object(),
   14709                             isolate);
   14710     // This handle is nor shared, nor used later, so it's safe.
   14711     Handle<Object> argv[] = { key_handle };
   14712     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   14713         isolate, value,
   14714         Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
   14715   }
   14716 
   14717 #ifdef VERIFY_HEAP
   14718   if (FLAG_verify_heap) {
   14719     cache_handle->JSFunctionResultCacheVerify();
   14720   }
   14721 #endif
   14722 
   14723   // Function invocation may have cleared the cache.  Reread all the data.
   14724   int finger_index = cache_handle->finger_index();
   14725   int size = cache_handle->size();
   14726 
   14727   // If we have spare room, put new data into it, otherwise evict post finger
   14728   // entry which is likely to be the least recently used.
   14729   int index = -1;
   14730   if (size < cache_handle->length()) {
   14731     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
   14732     index = size;
   14733   } else {
   14734     index = finger_index + JSFunctionResultCache::kEntrySize;
   14735     if (index == cache_handle->length()) {
   14736       index = JSFunctionResultCache::kEntriesIndex;
   14737     }
   14738   }
   14739 
   14740   ASSERT(index % 2 == 0);
   14741   ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
   14742   ASSERT(index < cache_handle->length());
   14743 
   14744   cache_handle->set(index, *key_handle);
   14745   cache_handle->set(index + 1, *value);
   14746   cache_handle->set_finger_index(index);
   14747 
   14748 #ifdef VERIFY_HEAP
   14749   if (FLAG_verify_heap) {
   14750     cache_handle->JSFunctionResultCacheVerify();
   14751   }
   14752 #endif
   14753 
   14754   return *value;
   14755 }
   14756 
   14757 
   14758 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
   14759   SealHandleScope shs(isolate);
   14760   ASSERT(args.length() == 1);
   14761   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14762   return Smi::FromInt(message->start_position());
   14763 }
   14764 
   14765 
   14766 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
   14767   SealHandleScope shs(isolate);
   14768   ASSERT(args.length() == 1);
   14769   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14770   return message->script();
   14771 }
   14772 
   14773 
   14774 #ifdef DEBUG
   14775 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
   14776 // Exclude the code in release mode.
   14777 RUNTIME_FUNCTION(Runtime_ListNatives) {
   14778   HandleScope scope(isolate);
   14779   ASSERT(args.length() == 0);
   14780 #define COUNT_ENTRY(Name, argc, ressize) + 1
   14781   int entry_count = 0
   14782       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
   14783       RUNTIME_HIDDEN_FUNCTION_LIST(COUNT_ENTRY)
   14784       INLINE_FUNCTION_LIST(COUNT_ENTRY)
   14785       INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
   14786 #undef COUNT_ENTRY
   14787   Factory* factory = isolate->factory();
   14788   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
   14789   int index = 0;
   14790   bool inline_runtime_functions = false;
   14791 #define ADD_ENTRY(Name, argc, ressize)                                       \
   14792   {                                                                          \
   14793     HandleScope inner(isolate);                                              \
   14794     Handle<String> name;                                                     \
   14795     /* Inline runtime functions have an underscore in front of the name. */  \
   14796     if (inline_runtime_functions) {                                          \
   14797       name = factory->NewStringFromStaticAscii("_" #Name);                   \
   14798     } else {                                                                 \
   14799       name = factory->NewStringFromStaticAscii(#Name);                       \
   14800     }                                                                        \
   14801     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
   14802     pair_elements->set(0, *name);                                            \
   14803     pair_elements->set(1, Smi::FromInt(argc));                               \
   14804     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
   14805     elements->set(index++, *pair);                                           \
   14806   }
   14807   inline_runtime_functions = false;
   14808   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   14809   INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
   14810   // Calling hidden runtime functions should just throw.
   14811   RUNTIME_HIDDEN_FUNCTION_LIST(ADD_ENTRY)
   14812   inline_runtime_functions = true;
   14813   INLINE_FUNCTION_LIST(ADD_ENTRY)
   14814 #undef ADD_ENTRY
   14815   ASSERT_EQ(index, entry_count);
   14816   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
   14817   return *result;
   14818 }
   14819 #endif
   14820 
   14821 
   14822 RUNTIME_FUNCTION(Runtime_IS_VAR) {
   14823   UNREACHABLE();  // implemented as macro in the parser
   14824   return NULL;
   14825 }
   14826 
   14827 
   14828 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
   14829   RUNTIME_FUNCTION(Runtime_Has##Name) {          \
   14830     CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
   14831     return isolate->heap()->ToBoolean(obj->Has##Name());  \
   14832   }
   14833 
   14834 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
   14835 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
   14836 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
   14837 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
   14838 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
   14839 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
   14840 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
   14841 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
   14842 // Properties test sitting with elements tests - not fooling anyone.
   14843 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
   14844 
   14845 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
   14846 
   14847 
   14848 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
   14849   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
   14850     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
   14851     return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
   14852   }
   14853 
   14854 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
   14855 
   14856 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
   14857 
   14858 
   14859 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
   14860   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
   14861     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
   14862     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
   14863   }
   14864 
   14865 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
   14866 
   14867 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
   14868 
   14869 
   14870 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
   14871   SealHandleScope shs(isolate);
   14872   ASSERT(args.length() == 2);
   14873   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
   14874   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
   14875   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
   14876 }
   14877 
   14878 
   14879 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
   14880   SealHandleScope shs(isolate);
   14881   ASSERT(args.length() == 1);
   14882   CONVERT_ARG_CHECKED(Object, obj, 0);
   14883   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
   14884 }
   14885 
   14886 
   14887 RUNTIME_FUNCTION(Runtime_IsObserved) {
   14888   SealHandleScope shs(isolate);
   14889   ASSERT(args.length() == 1);
   14890 
   14891   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
   14892   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
   14893   ASSERT(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
   14894   return isolate->heap()->ToBoolean(obj->map()->is_observed());
   14895 }
   14896 
   14897 
   14898 RUNTIME_FUNCTION(Runtime_SetIsObserved) {
   14899   HandleScope scope(isolate);
   14900   ASSERT(args.length() == 1);
   14901   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
   14902   RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
   14903   if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
   14904   RUNTIME_ASSERT(!obj->map()->is_observed());
   14905 
   14906   ASSERT(obj->IsJSObject());
   14907   JSObject::SetObserved(Handle<JSObject>::cast(obj));
   14908   return isolate->heap()->undefined_value();
   14909 }
   14910 
   14911 
   14912 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
   14913   HandleScope scope(isolate);
   14914   ASSERT(args.length() == 1);
   14915   CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
   14916   isolate->EnqueueMicrotask(microtask);
   14917   return isolate->heap()->undefined_value();
   14918 }
   14919 
   14920 
   14921 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
   14922   HandleScope scope(isolate);
   14923   ASSERT(args.length() == 0);
   14924   isolate->RunMicrotasks();
   14925   return isolate->heap()->undefined_value();
   14926 }
   14927 
   14928 
   14929 RUNTIME_FUNCTION(Runtime_GetObservationState) {
   14930   SealHandleScope shs(isolate);
   14931   ASSERT(args.length() == 0);
   14932   return isolate->heap()->observation_state();
   14933 }
   14934 
   14935 
   14936 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
   14937   HandleScope scope(isolate);
   14938   ASSERT(args.length() == 0);
   14939   // TODO(adamk): Currently this runtime function is only called three times per
   14940   // isolate. If it's called more often, the map should be moved into the
   14941   // strong root list.
   14942   Handle<Map> map =
   14943       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
   14944   Handle<JSWeakMap> weakmap =
   14945       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
   14946   return *WeakCollectionInitialize(isolate, weakmap);
   14947 }
   14948 
   14949 
   14950 static bool ContextsHaveSameOrigin(Handle<Context> context1,
   14951                                    Handle<Context> context2) {
   14952   return context1->security_token() == context2->security_token();
   14953 }
   14954 
   14955 
   14956 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
   14957   HandleScope scope(isolate);
   14958   ASSERT(args.length() == 3);
   14959   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
   14960   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
   14961   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
   14962 
   14963   Handle<Context> observer_context(observer->context()->native_context(),
   14964       isolate);
   14965   Handle<Context> object_context(object->GetCreationContext());
   14966   Handle<Context> record_context(record->GetCreationContext());
   14967 
   14968   return isolate->heap()->ToBoolean(
   14969       ContextsHaveSameOrigin(object_context, observer_context) &&
   14970       ContextsHaveSameOrigin(object_context, record_context));
   14971 }
   14972 
   14973 
   14974 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
   14975   HandleScope scope(isolate);
   14976   ASSERT(args.length() == 1);
   14977   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   14978 
   14979   Handle<Context> creation_context(object->GetCreationContext(), isolate);
   14980   return isolate->heap()->ToBoolean(
   14981       ContextsHaveSameOrigin(creation_context, isolate->native_context()));
   14982 }
   14983 
   14984 
   14985 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
   14986   HandleScope scope(isolate);
   14987   ASSERT(args.length() == 1);
   14988   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   14989 
   14990   Handle<Context> context(object->GetCreationContext(), isolate);
   14991   return context->native_object_observe();
   14992 }
   14993 
   14994 
   14995 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
   14996   HandleScope scope(isolate);
   14997   ASSERT(args.length() == 1);
   14998   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   14999 
   15000   Handle<Context> context(object->GetCreationContext(), isolate);
   15001   return context->native_object_get_notifier();
   15002 }
   15003 
   15004 
   15005 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
   15006   HandleScope scope(isolate);
   15007   ASSERT(args.length() == 1);
   15008   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
   15009 
   15010   Handle<Context> context(object_info->GetCreationContext(), isolate);
   15011   return context->native_object_notifier_perform_change();
   15012 }
   15013 
   15014 
   15015 static Object* ArrayConstructorCommon(Isolate* isolate,
   15016                                            Handle<JSFunction> constructor,
   15017                                            Handle<AllocationSite> site,
   15018                                            Arguments* caller_args) {
   15019   Factory* factory = isolate->factory();
   15020 
   15021   bool holey = false;
   15022   bool can_use_type_feedback = true;
   15023   if (caller_args->length() == 1) {
   15024     Handle<Object> argument_one = caller_args->at<Object>(0);
   15025     if (argument_one->IsSmi()) {
   15026       int value = Handle<Smi>::cast(argument_one)->value();
   15027       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
   15028         // the array is a dictionary in this case.
   15029         can_use_type_feedback = false;
   15030       } else if (value != 0) {
   15031         holey = true;
   15032       }
   15033     } else {
   15034       // Non-smi length argument produces a dictionary
   15035       can_use_type_feedback = false;
   15036     }
   15037   }
   15038 
   15039   Handle<JSArray> array;
   15040   if (!site.is_null() && can_use_type_feedback) {
   15041     ElementsKind to_kind = site->GetElementsKind();
   15042     if (holey && !IsFastHoleyElementsKind(to_kind)) {
   15043       to_kind = GetHoleyElementsKind(to_kind);
   15044       // Update the allocation site info to reflect the advice alteration.
   15045       site->SetElementsKind(to_kind);
   15046     }
   15047 
   15048     // We should allocate with an initial map that reflects the allocation site
   15049     // advice. Therefore we use AllocateJSObjectFromMap instead of passing
   15050     // the constructor.
   15051     Handle<Map> initial_map(constructor->initial_map(), isolate);
   15052     if (to_kind != initial_map->elements_kind()) {
   15053       initial_map = Map::AsElementsKind(initial_map, to_kind);
   15054     }
   15055 
   15056     // If we don't care to track arrays of to_kind ElementsKind, then
   15057     // don't emit a memento for them.
   15058     Handle<AllocationSite> allocation_site;
   15059     if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
   15060       allocation_site = site;
   15061     }
   15062 
   15063     array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
   15064         initial_map, NOT_TENURED, true, allocation_site));
   15065   } else {
   15066     array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
   15067 
   15068     // We might need to transition to holey
   15069     ElementsKind kind = constructor->initial_map()->elements_kind();
   15070     if (holey && !IsFastHoleyElementsKind(kind)) {
   15071       kind = GetHoleyElementsKind(kind);
   15072       JSObject::TransitionElementsKind(array, kind);
   15073     }
   15074   }
   15075 
   15076   factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
   15077 
   15078   ElementsKind old_kind = array->GetElementsKind();
   15079   RETURN_FAILURE_ON_EXCEPTION(
   15080       isolate, ArrayConstructInitializeElements(array, caller_args));
   15081   if (!site.is_null() &&
   15082       (old_kind != array->GetElementsKind() ||
   15083        !can_use_type_feedback)) {
   15084     // The arguments passed in caused a transition. This kind of complexity
   15085     // can't be dealt with in the inlined hydrogen array constructor case.
   15086     // We must mark the allocationsite as un-inlinable.
   15087     site->SetDoNotInlineCall();
   15088   }
   15089   return *array;
   15090 }
   15091 
   15092 
   15093 RUNTIME_FUNCTION(RuntimeHidden_ArrayConstructor) {
   15094   HandleScope scope(isolate);
   15095   // If we get 2 arguments then they are the stub parameters (constructor, type
   15096   // info).  If we get 4, then the first one is a pointer to the arguments
   15097   // passed by the caller, and the last one is the length of the arguments
   15098   // passed to the caller (redundant, but useful to check on the deoptimizer
   15099   // with an assert).
   15100   Arguments empty_args(0, NULL);
   15101   bool no_caller_args = args.length() == 2;
   15102   ASSERT(no_caller_args || args.length() == 4);
   15103   int parameters_start = no_caller_args ? 0 : 1;
   15104   Arguments* caller_args = no_caller_args
   15105       ? &empty_args
   15106       : reinterpret_cast<Arguments*>(args[0]);
   15107   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   15108   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
   15109 #ifdef DEBUG
   15110   if (!no_caller_args) {
   15111     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
   15112     ASSERT(arg_count == caller_args->length());
   15113   }
   15114 #endif
   15115 
   15116   Handle<AllocationSite> site;
   15117   if (!type_info.is_null() &&
   15118       *type_info != isolate->heap()->undefined_value()) {
   15119     site = Handle<AllocationSite>::cast(type_info);
   15120     ASSERT(!site->SitePointsToLiteral());
   15121   }
   15122 
   15123   return ArrayConstructorCommon(isolate,
   15124                                 constructor,
   15125                                 site,
   15126                                 caller_args);
   15127 }
   15128 
   15129 
   15130 RUNTIME_FUNCTION(RuntimeHidden_InternalArrayConstructor) {
   15131   HandleScope scope(isolate);
   15132   Arguments empty_args(0, NULL);
   15133   bool no_caller_args = args.length() == 1;
   15134   ASSERT(no_caller_args || args.length() == 3);
   15135   int parameters_start = no_caller_args ? 0 : 1;
   15136   Arguments* caller_args = no_caller_args
   15137       ? &empty_args
   15138       : reinterpret_cast<Arguments*>(args[0]);
   15139   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   15140 #ifdef DEBUG
   15141   if (!no_caller_args) {
   15142     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
   15143     ASSERT(arg_count == caller_args->length());
   15144   }
   15145 #endif
   15146   return ArrayConstructorCommon(isolate,
   15147                                 constructor,
   15148                                 Handle<AllocationSite>::null(),
   15149                                 caller_args);
   15150 }
   15151 
   15152 
   15153 RUNTIME_FUNCTION(Runtime_MaxSmi) {
   15154   ASSERT(args.length() == 0);
   15155   return Smi::FromInt(Smi::kMaxValue);
   15156 }
   15157 
   15158 
   15159 // ----------------------------------------------------------------------------
   15160 // Implementation of Runtime
   15161 
   15162 #define F(name, number_of_args, result_size)                             \
   15163   { Runtime::k##name, Runtime::RUNTIME, #name,   \
   15164     FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
   15165 
   15166 
   15167 #define FH(name, number_of_args, result_size)                             \
   15168   { Runtime::kHidden##name, Runtime::RUNTIME_HIDDEN, NULL,   \
   15169     FUNCTION_ADDR(RuntimeHidden_##name), number_of_args, result_size },
   15170 
   15171 
   15172 #define I(name, number_of_args, result_size)                             \
   15173   { Runtime::kInline##name, Runtime::INLINE,     \
   15174     "_" #name, NULL, number_of_args, result_size },
   15175 
   15176 
   15177 #define IO(name, number_of_args, result_size) \
   15178   { Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, \
   15179     "_" #name, FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
   15180 
   15181 
   15182 static const Runtime::Function kIntrinsicFunctions[] = {
   15183   RUNTIME_FUNCTION_LIST(F)
   15184   INLINE_OPTIMIZED_FUNCTION_LIST(F)
   15185   RUNTIME_HIDDEN_FUNCTION_LIST(FH)
   15186   INLINE_FUNCTION_LIST(I)
   15187   INLINE_OPTIMIZED_FUNCTION_LIST(IO)
   15188 };
   15189 
   15190 #undef IO
   15191 #undef I
   15192 #undef FH
   15193 #undef F
   15194 
   15195 
   15196 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
   15197                                                Handle<NameDictionary> dict) {
   15198   ASSERT(dict->NumberOfElements() == 0);
   15199   HandleScope scope(isolate);
   15200   for (int i = 0; i < kNumFunctions; ++i) {
   15201     const char* name = kIntrinsicFunctions[i].name;
   15202     if (name == NULL) continue;
   15203     Handle<NameDictionary> new_dict = NameDictionary::Add(
   15204         dict,
   15205         isolate->factory()->InternalizeUtf8String(name),
   15206         Handle<Smi>(Smi::FromInt(i), isolate),
   15207         PropertyDetails(NONE, NORMAL, Representation::None()));
   15208     // The dictionary does not need to grow.
   15209     CHECK(new_dict.is_identical_to(dict));
   15210   }
   15211 }
   15212 
   15213 
   15214 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
   15215   Heap* heap = name->GetHeap();
   15216   int entry = heap->intrinsic_function_names()->FindEntry(name);
   15217   if (entry != kNotFound) {
   15218     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
   15219     int function_index = Smi::cast(smi_index)->value();
   15220     return &(kIntrinsicFunctions[function_index]);
   15221   }
   15222   return NULL;
   15223 }
   15224 
   15225 
   15226 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
   15227   return &(kIntrinsicFunctions[static_cast<int>(id)]);
   15228 }
   15229 
   15230 } }  // namespace v8::internal
   15231