Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <stdlib.h>
     29 #include <limits>
     30 
     31 #include "v8.h"
     32 
     33 #include "accessors.h"
     34 #include "allocation-site-scopes.h"
     35 #include "api.h"
     36 #include "arguments.h"
     37 #include "bootstrapper.h"
     38 #include "codegen.h"
     39 #include "compilation-cache.h"
     40 #include "compiler.h"
     41 #include "cpu.h"
     42 #include "cpu-profiler.h"
     43 #include "dateparser-inl.h"
     44 #include "debug.h"
     45 #include "deoptimizer.h"
     46 #include "date.h"
     47 #include "execution.h"
     48 #include "full-codegen.h"
     49 #include "global-handles.h"
     50 #include "isolate-inl.h"
     51 #include "jsregexp.h"
     52 #include "jsregexp-inl.h"
     53 #include "json-parser.h"
     54 #include "json-stringifier.h"
     55 #include "liveedit.h"
     56 #include "misc-intrinsics.h"
     57 #include "parser.h"
     58 #include "platform.h"
     59 #include "runtime-profiler.h"
     60 #include "runtime.h"
     61 #include "scopeinfo.h"
     62 #include "smart-pointers.h"
     63 #include "string-search.h"
     64 #include "stub-cache.h"
     65 #include "uri.h"
     66 #include "v8conversions.h"
     67 #include "v8threads.h"
     68 #include "vm-state-inl.h"
     69 
     70 #ifdef V8_I18N_SUPPORT
     71 #include "i18n.h"
     72 #include "unicode/brkiter.h"
     73 #include "unicode/calendar.h"
     74 #include "unicode/coll.h"
     75 #include "unicode/curramt.h"
     76 #include "unicode/datefmt.h"
     77 #include "unicode/dcfmtsym.h"
     78 #include "unicode/decimfmt.h"
     79 #include "unicode/dtfmtsym.h"
     80 #include "unicode/dtptngen.h"
     81 #include "unicode/locid.h"
     82 #include "unicode/numfmt.h"
     83 #include "unicode/numsys.h"
     84 #include "unicode/rbbi.h"
     85 #include "unicode/smpdtfmt.h"
     86 #include "unicode/timezone.h"
     87 #include "unicode/uchar.h"
     88 #include "unicode/ucol.h"
     89 #include "unicode/ucurr.h"
     90 #include "unicode/uloc.h"
     91 #include "unicode/unum.h"
     92 #include "unicode/uversion.h"
     93 #endif
     94 
     95 #ifndef _STLP_VENDOR_CSTD
     96 // STLPort doesn't import fpclassify and isless into the std namespace.
     97 using std::fpclassify;
     98 using std::isless;
     99 #endif
    100 
    101 namespace v8 {
    102 namespace internal {
    103 
    104 
    105 #define RUNTIME_ASSERT(value) \
    106   if (!(value)) return isolate->ThrowIllegalOperation();
    107 
    108 // Cast the given object to a value of the specified type and store
    109 // it in a variable with the given name.  If the object is not of the
    110 // expected type call IllegalOperation and return.
    111 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
    112   RUNTIME_ASSERT(args[index]->Is##Type());                           \
    113   Type* name = Type::cast(args[index]);
    114 
    115 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
    116   RUNTIME_ASSERT(args[index]->Is##Type());                           \
    117   Handle<Type> name = args.at<Type>(index);
    118 
    119 // Cast the given object to a boolean and store it in a variable with
    120 // the given name.  If the object is not a boolean call IllegalOperation
    121 // and return.
    122 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
    123   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
    124   bool name = args[index]->IsTrue();
    125 
    126 // Cast the given argument to a Smi and store its value in an int variable
    127 // with the given name.  If the argument is not a Smi call IllegalOperation
    128 // and return.
    129 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
    130   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    131   int name = args.smi_at(index);
    132 
    133 // Cast the given argument to a double and store it in a variable with
    134 // the given name.  If the argument is not a number (as opposed to
    135 // the number not-a-number) call IllegalOperation and return.
    136 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
    137   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    138   double name = args.number_at(index);
    139 
    140 // Call the specified converter on the object *comand store the result in
    141 // a variable of the specified type with the given name.  If the
    142 // object is not a Number call IllegalOperation and return.
    143 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
    144   RUNTIME_ASSERT(obj->IsNumber());                                   \
    145   type name = NumberTo##Type(obj);
    146 
    147 
    148 // Cast the given argument to PropertyDetails and store its value in a
    149 // variable with the given name.  If the argument is not a Smi call
    150 // IllegalOperation and return.
    151 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
    152   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    153   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
    154 
    155 
    156 // Assert that the given argument has a valid value for a StrictModeFlag
    157 // and store it in a StrictModeFlag variable with the given name.
    158 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
    159   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    160   RUNTIME_ASSERT(args.smi_at(index) == kStrictMode ||                \
    161                  args.smi_at(index) == kNonStrictMode);              \
    162   StrictModeFlag name =                                              \
    163       static_cast<StrictModeFlag>(args.smi_at(index));
    164 
    165 
    166 // Assert that the given argument has a valid value for a LanguageMode
    167 // and store it in a LanguageMode variable with the given name.
    168 #define CONVERT_LANGUAGE_MODE_ARG(name, index)                       \
    169   ASSERT(args[index]->IsSmi());                                      \
    170   ASSERT(args.smi_at(index) == CLASSIC_MODE ||                       \
    171          args.smi_at(index) == STRICT_MODE ||                        \
    172          args.smi_at(index) == EXTENDED_MODE);                       \
    173   LanguageMode name =                                                \
    174       static_cast<LanguageMode>(args.smi_at(index));
    175 
    176 
    177 static Handle<Map> ComputeObjectLiteralMap(
    178     Handle<Context> context,
    179     Handle<FixedArray> constant_properties,
    180     bool* is_result_from_cache) {
    181   Isolate* isolate = context->GetIsolate();
    182   int properties_length = constant_properties->length();
    183   int number_of_properties = properties_length / 2;
    184   // Check that there are only internal strings and array indices among keys.
    185   int number_of_string_keys = 0;
    186   for (int p = 0; p != properties_length; p += 2) {
    187     Object* key = constant_properties->get(p);
    188     uint32_t element_index = 0;
    189     if (key->IsInternalizedString()) {
    190       number_of_string_keys++;
    191     } else if (key->ToArrayIndex(&element_index)) {
    192       // An index key does not require space in the property backing store.
    193       number_of_properties--;
    194     } else {
    195       // Bail out as a non-internalized-string non-index key makes caching
    196       // impossible.
    197       // ASSERT to make sure that the if condition after the loop is false.
    198       ASSERT(number_of_string_keys != number_of_properties);
    199       break;
    200     }
    201   }
    202   // If we only have internalized strings and array indices among keys then we
    203   // can use the map cache in the native context.
    204   const int kMaxKeys = 10;
    205   if ((number_of_string_keys == number_of_properties) &&
    206       (number_of_string_keys < kMaxKeys)) {
    207     // Create the fixed array with the key.
    208     Handle<FixedArray> keys =
    209         isolate->factory()->NewFixedArray(number_of_string_keys);
    210     if (number_of_string_keys > 0) {
    211       int index = 0;
    212       for (int p = 0; p < properties_length; p += 2) {
    213         Object* key = constant_properties->get(p);
    214         if (key->IsInternalizedString()) {
    215           keys->set(index++, key);
    216         }
    217       }
    218       ASSERT(index == number_of_string_keys);
    219     }
    220     *is_result_from_cache = true;
    221     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
    222   }
    223   *is_result_from_cache = false;
    224   return isolate->factory()->CopyMap(
    225       Handle<Map>(context->object_function()->initial_map()),
    226       number_of_properties);
    227 }
    228 
    229 
    230 static Handle<Object> CreateLiteralBoilerplate(
    231     Isolate* isolate,
    232     Handle<FixedArray> literals,
    233     Handle<FixedArray> constant_properties);
    234 
    235 
    236 static Handle<Object> CreateObjectLiteralBoilerplate(
    237     Isolate* isolate,
    238     Handle<FixedArray> literals,
    239     Handle<FixedArray> constant_properties,
    240     bool should_have_fast_elements,
    241     bool has_function_literal) {
    242   // Get the native context from the literals array.  This is the
    243   // context in which the function was created and we use the object
    244   // function from this context to create the object literal.  We do
    245   // not use the object function from the current native context
    246   // because this might be the object function from another context
    247   // which we should not have access to.
    248   Handle<Context> context =
    249       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
    250 
    251   // In case we have function literals, we want the object to be in
    252   // slow properties mode for now. We don't go in the map cache because
    253   // maps with constant functions can't be shared if the functions are
    254   // not the same (which is the common case).
    255   bool is_result_from_cache = false;
    256   Handle<Map> map = has_function_literal
    257       ? Handle<Map>(context->object_function()->initial_map())
    258       : ComputeObjectLiteralMap(context,
    259                                 constant_properties,
    260                                 &is_result_from_cache);
    261 
    262   Handle<JSObject> boilerplate =
    263       isolate->factory()->NewJSObjectFromMap(
    264           map, isolate->heap()->GetPretenureMode());
    265 
    266   // Normalize the elements of the boilerplate to save space if needed.
    267   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
    268 
    269   // Add the constant properties to the boilerplate.
    270   int length = constant_properties->length();
    271   bool should_transform =
    272       !is_result_from_cache && boilerplate->HasFastProperties();
    273   if (should_transform || has_function_literal) {
    274     // Normalize the properties of object to avoid n^2 behavior
    275     // when extending the object multiple properties. Indicate the number of
    276     // properties to be added.
    277     JSObject::NormalizeProperties(
    278         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
    279   }
    280 
    281   // TODO(verwaest): Support tracking representations in the boilerplate.
    282   for (int index = 0; index < length; index +=2) {
    283     Handle<Object> key(constant_properties->get(index+0), isolate);
    284     Handle<Object> value(constant_properties->get(index+1), isolate);
    285     if (value->IsFixedArray()) {
    286       // The value contains the constant_properties of a
    287       // simple object or array literal.
    288       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
    289       value = CreateLiteralBoilerplate(isolate, literals, array);
    290       if (value.is_null()) return value;
    291     }
    292     Handle<Object> result;
    293     uint32_t element_index = 0;
    294     StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
    295     if (key->IsInternalizedString()) {
    296       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
    297         // Array index as string (uint32).
    298         result = JSObject::SetOwnElement(
    299             boilerplate, element_index, value, kNonStrictMode);
    300       } else {
    301         Handle<String> name(String::cast(*key));
    302         ASSERT(!name->AsArrayIndex(&element_index));
    303         result = JSObject::SetLocalPropertyIgnoreAttributes(
    304             boilerplate, name, value, NONE,
    305             Object::OPTIMAL_REPRESENTATION, mode);
    306       }
    307     } else if (key->ToArrayIndex(&element_index)) {
    308       // Array index (uint32).
    309       result = JSObject::SetOwnElement(
    310           boilerplate, element_index, value, kNonStrictMode);
    311     } else {
    312       // Non-uint32 number.
    313       ASSERT(key->IsNumber());
    314       double num = key->Number();
    315       char arr[100];
    316       Vector<char> buffer(arr, ARRAY_SIZE(arr));
    317       const char* str = DoubleToCString(num, buffer);
    318       Handle<String> name =
    319           isolate->factory()->NewStringFromAscii(CStrVector(str));
    320       result = JSObject::SetLocalPropertyIgnoreAttributes(
    321           boilerplate, name, value, NONE,
    322           Object::OPTIMAL_REPRESENTATION, mode);
    323     }
    324     // If setting the property on the boilerplate throws an
    325     // exception, the exception is converted to an empty handle in
    326     // the handle based operations.  In that case, we need to
    327     // convert back to an exception.
    328     if (result.is_null()) return result;
    329   }
    330 
    331   // Transform to fast properties if necessary. For object literals with
    332   // containing function literals we defer this operation until after all
    333   // computed properties have been assigned so that we can generate
    334   // constant function properties.
    335   if (should_transform && !has_function_literal) {
    336     JSObject::TransformToFastProperties(
    337         boilerplate, boilerplate->map()->unused_property_fields());
    338   }
    339 
    340   return boilerplate;
    341 }
    342 
    343 
    344 MaybeObject* TransitionElements(Handle<Object> object,
    345                                 ElementsKind to_kind,
    346                                 Isolate* isolate) {
    347   HandleScope scope(isolate);
    348   if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
    349   ElementsKind from_kind =
    350       Handle<JSObject>::cast(object)->map()->elements_kind();
    351   if (Map::IsValidElementsTransition(from_kind, to_kind)) {
    352     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
    353     return *object;
    354   }
    355   return isolate->ThrowIllegalOperation();
    356 }
    357 
    358 
    359 static const int kSmiLiteralMinimumLength = 1024;
    360 
    361 
    362 Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
    363     Isolate* isolate,
    364     Handle<FixedArray> literals,
    365     Handle<FixedArray> elements) {
    366   // Create the JSArray.
    367   Handle<JSFunction> constructor(
    368       JSFunction::NativeContextFromLiterals(*literals)->array_function());
    369 
    370   Handle<JSArray> object = Handle<JSArray>::cast(
    371       isolate->factory()->NewJSObject(
    372           constructor, isolate->heap()->GetPretenureMode()));
    373 
    374   ElementsKind constant_elements_kind =
    375       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
    376   Handle<FixedArrayBase> constant_elements_values(
    377       FixedArrayBase::cast(elements->get(1)));
    378 
    379   ASSERT(IsFastElementsKind(constant_elements_kind));
    380   Context* native_context = isolate->context()->native_context();
    381   Object* maybe_maps_array = native_context->js_array_maps();
    382   ASSERT(!maybe_maps_array->IsUndefined());
    383   Object* maybe_map = FixedArray::cast(maybe_maps_array)->get(
    384       constant_elements_kind);
    385   ASSERT(maybe_map->IsMap());
    386   object->set_map(Map::cast(maybe_map));
    387 
    388   Handle<FixedArrayBase> copied_elements_values;
    389   if (IsFastDoubleElementsKind(constant_elements_kind)) {
    390     ASSERT(FLAG_smi_only_arrays);
    391     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
    392         Handle<FixedDoubleArray>::cast(constant_elements_values));
    393   } else {
    394     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
    395     const bool is_cow =
    396         (constant_elements_values->map() ==
    397          isolate->heap()->fixed_cow_array_map());
    398     if (is_cow) {
    399       copied_elements_values = constant_elements_values;
    400 #if DEBUG
    401       Handle<FixedArray> fixed_array_values =
    402           Handle<FixedArray>::cast(copied_elements_values);
    403       for (int i = 0; i < fixed_array_values->length(); i++) {
    404         ASSERT(!fixed_array_values->get(i)->IsFixedArray());
    405       }
    406 #endif
    407     } else {
    408       Handle<FixedArray> fixed_array_values =
    409           Handle<FixedArray>::cast(constant_elements_values);
    410       Handle<FixedArray> fixed_array_values_copy =
    411           isolate->factory()->CopyFixedArray(fixed_array_values);
    412       copied_elements_values = fixed_array_values_copy;
    413       for (int i = 0; i < fixed_array_values->length(); i++) {
    414         Object* current = fixed_array_values->get(i);
    415         if (current->IsFixedArray()) {
    416           // The value contains the constant_properties of a
    417           // simple object or array literal.
    418           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
    419           Handle<Object> result =
    420               CreateLiteralBoilerplate(isolate, literals, fa);
    421           if (result.is_null()) return result;
    422           fixed_array_values_copy->set(i, *result);
    423         }
    424       }
    425     }
    426   }
    427   object->set_elements(*copied_elements_values);
    428   object->set_length(Smi::FromInt(copied_elements_values->length()));
    429 
    430   //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
    431   //  on or the object is larger than the threshold.
    432   if (!FLAG_smi_only_arrays &&
    433       constant_elements_values->length() < kSmiLiteralMinimumLength) {
    434     ElementsKind elements_kind = object->GetElementsKind();
    435     if (!IsFastObjectElementsKind(elements_kind)) {
    436       if (IsFastHoleyElementsKind(elements_kind)) {
    437         CHECK(!TransitionElements(object, FAST_HOLEY_ELEMENTS,
    438                                   isolate)->IsFailure());
    439       } else {
    440         CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
    441       }
    442     }
    443   }
    444 
    445   object->ValidateElements();
    446   return object;
    447 }
    448 
    449 
    450 static Handle<Object> CreateLiteralBoilerplate(
    451     Isolate* isolate,
    452     Handle<FixedArray> literals,
    453     Handle<FixedArray> array) {
    454   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
    455   const bool kHasNoFunctionLiteral = false;
    456   switch (CompileTimeValue::GetLiteralType(array)) {
    457     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
    458       return CreateObjectLiteralBoilerplate(isolate,
    459                                             literals,
    460                                             elements,
    461                                             true,
    462                                             kHasNoFunctionLiteral);
    463     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
    464       return CreateObjectLiteralBoilerplate(isolate,
    465                                             literals,
    466                                             elements,
    467                                             false,
    468                                             kHasNoFunctionLiteral);
    469     case CompileTimeValue::ARRAY_LITERAL:
    470       return Runtime::CreateArrayLiteralBoilerplate(
    471           isolate, literals, elements);
    472     default:
    473       UNREACHABLE();
    474       return Handle<Object>::null();
    475   }
    476 }
    477 
    478 
    479 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
    480   HandleScope scope(isolate);
    481   ASSERT(args.length() == 4);
    482   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    483   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    484   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    485   CONVERT_SMI_ARG_CHECKED(flags, 3);
    486   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    487   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    488 
    489   // Check if boilerplate exists. If not, create it first.
    490   Handle<Object> literal_site(literals->get(literals_index), isolate);
    491   Handle<AllocationSite> site;
    492   Handle<JSObject> boilerplate;
    493   if (*literal_site == isolate->heap()->undefined_value()) {
    494     Handle<Object> raw_boilerplate = CreateObjectLiteralBoilerplate(
    495         isolate,
    496         literals,
    497         constant_properties,
    498         should_have_fast_elements,
    499         has_function_literal);
    500     RETURN_IF_EMPTY_HANDLE(isolate, raw_boilerplate);
    501     boilerplate = Handle<JSObject>::cast(raw_boilerplate);
    502 
    503     AllocationSiteCreationContext creation_context(isolate);
    504     site = creation_context.EnterNewScope();
    505     RETURN_IF_EMPTY_HANDLE(isolate,
    506                            JSObject::DeepWalk(boilerplate, &creation_context));
    507     creation_context.ExitScope(site, boilerplate);
    508 
    509     // Update the functions literal and return the boilerplate.
    510     literals->set(literals_index, *site);
    511   } else {
    512     site = Handle<AllocationSite>::cast(literal_site);
    513     boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
    514                                    isolate);
    515   }
    516 
    517   AllocationSiteUsageContext usage_context(isolate, site, true);
    518   usage_context.EnterNewScope();
    519   Handle<Object> copy = JSObject::DeepCopy(boilerplate, &usage_context);
    520   usage_context.ExitScope(site, boilerplate);
    521   RETURN_IF_EMPTY_HANDLE(isolate, copy);
    522   return *copy;
    523 }
    524 
    525 
    526 static Handle<AllocationSite> GetLiteralAllocationSite(
    527     Isolate* isolate,
    528     Handle<FixedArray> literals,
    529     int literals_index,
    530     Handle<FixedArray> elements) {
    531   // Check if boilerplate exists. If not, create it first.
    532   Handle<Object> literal_site(literals->get(literals_index), isolate);
    533   Handle<AllocationSite> site;
    534   if (*literal_site == isolate->heap()->undefined_value()) {
    535     ASSERT(*elements != isolate->heap()->empty_fixed_array());
    536     Handle<Object> boilerplate =
    537         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
    538     if (boilerplate.is_null()) return Handle<AllocationSite>::null();
    539 
    540     AllocationSiteCreationContext creation_context(isolate);
    541     site = creation_context.EnterNewScope();
    542     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
    543                            &creation_context).is_null()) {
    544       return Handle<AllocationSite>::null();
    545     }
    546     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
    547 
    548     literals->set(literals_index, *site);
    549   } else {
    550     site = Handle<AllocationSite>::cast(literal_site);
    551   }
    552 
    553   return site;
    554 }
    555 
    556 
    557 static MaybeObject* CreateArrayLiteralImpl(Isolate* isolate,
    558                                            Handle<FixedArray> literals,
    559                                            int literals_index,
    560                                            Handle<FixedArray> elements,
    561                                            int flags) {
    562   Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
    563       literals_index, elements);
    564   RETURN_IF_EMPTY_HANDLE(isolate, site);
    565 
    566   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
    567   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
    568   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
    569   usage_context.EnterNewScope();
    570   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
    571       ? JSObject::kNoHints
    572       : JSObject::kObjectIsShallowArray;
    573   Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
    574                                              hints);
    575   usage_context.ExitScope(site, boilerplate);
    576   RETURN_IF_EMPTY_HANDLE(isolate, copy);
    577   return *copy;
    578 }
    579 
    580 
    581 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
    582   HandleScope scope(isolate);
    583   ASSERT(args.length() == 4);
    584   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    585   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    586   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    587   CONVERT_SMI_ARG_CHECKED(flags, 3);
    588 
    589   return CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
    590                                 flags);
    591 }
    592 
    593 
    594 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralStubBailout) {
    595   HandleScope scope(isolate);
    596   ASSERT(args.length() == 3);
    597   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    598   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    599   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    600 
    601   return CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
    602                                 ArrayLiteral::kShallowElements);
    603 }
    604 
    605 
    606 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
    607   HandleScope scope(isolate);
    608   ASSERT(args.length() == 1);
    609   Handle<Object> name(args[0], isolate);
    610   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    611   Symbol* symbol;
    612   MaybeObject* maybe = isolate->heap()->AllocateSymbol();
    613   if (!maybe->To(&symbol)) return maybe;
    614   if (name->IsString()) symbol->set_name(*name);
    615   return symbol;
    616 }
    617 
    618 
    619 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreatePrivateSymbol) {
    620   HandleScope scope(isolate);
    621   ASSERT(args.length() == 1);
    622   Handle<Object> name(args[0], isolate);
    623   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    624   Symbol* symbol;
    625   MaybeObject* maybe = isolate->heap()->AllocatePrivateSymbol();
    626   if (!maybe->To(&symbol)) return maybe;
    627   if (name->IsString()) symbol->set_name(*name);
    628   return symbol;
    629 }
    630 
    631 
    632 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) {
    633   SealHandleScope shs(isolate);
    634   ASSERT(args.length() == 1);
    635   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    636   return symbol->name();
    637 }
    638 
    639 
    640 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) {
    641   SealHandleScope shs(isolate);
    642   ASSERT(args.length() == 1);
    643   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    644   return isolate->heap()->ToBoolean(symbol->is_private());
    645 }
    646 
    647 
    648 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
    649   SealHandleScope shs(isolate);
    650   ASSERT(args.length() == 2);
    651   CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
    652   Object* prototype = args[1];
    653   Object* used_prototype =
    654       prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
    655   return isolate->heap()->AllocateJSProxy(handler, used_prototype);
    656 }
    657 
    658 
    659 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) {
    660   SealHandleScope shs(isolate);
    661   ASSERT(args.length() == 4);
    662   CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
    663   Object* call_trap = args[1];
    664   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
    665   CONVERT_ARG_CHECKED(JSFunction, construct_trap, 2);
    666   Object* prototype = args[3];
    667   Object* used_prototype =
    668       prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
    669   return isolate->heap()->AllocateJSFunctionProxy(
    670       handler, call_trap, construct_trap, used_prototype);
    671 }
    672 
    673 
    674 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
    675   SealHandleScope shs(isolate);
    676   ASSERT(args.length() == 1);
    677   Object* obj = args[0];
    678   return isolate->heap()->ToBoolean(obj->IsJSProxy());
    679 }
    680 
    681 
    682 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) {
    683   SealHandleScope shs(isolate);
    684   ASSERT(args.length() == 1);
    685   Object* obj = args[0];
    686   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
    687 }
    688 
    689 
    690 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
    691   SealHandleScope shs(isolate);
    692   ASSERT(args.length() == 1);
    693   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    694   return proxy->handler();
    695 }
    696 
    697 
    698 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
    699   SealHandleScope shs(isolate);
    700   ASSERT(args.length() == 1);
    701   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    702   return proxy->call_trap();
    703 }
    704 
    705 
    706 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
    707   SealHandleScope shs(isolate);
    708   ASSERT(args.length() == 1);
    709   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    710   return proxy->construct_trap();
    711 }
    712 
    713 
    714 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
    715   HandleScope scope(isolate);
    716   ASSERT(args.length() == 1);
    717   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
    718   JSProxy::Fix(proxy);
    719   return isolate->heap()->undefined_value();
    720 }
    721 
    722 
    723 void Runtime::FreeArrayBuffer(Isolate* isolate,
    724                               JSArrayBuffer* phantom_array_buffer) {
    725   if (phantom_array_buffer->should_be_freed()) {
    726     ASSERT(phantom_array_buffer->is_external());
    727     free(phantom_array_buffer->backing_store());
    728   }
    729   if (phantom_array_buffer->is_external()) return;
    730 
    731   size_t allocated_length = NumberToSize(
    732       isolate, phantom_array_buffer->byte_length());
    733 
    734   isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
    735       -static_cast<int64_t>(allocated_length));
    736   CHECK(V8::ArrayBufferAllocator() != NULL);
    737   V8::ArrayBufferAllocator()->Free(
    738       phantom_array_buffer->backing_store(),
    739       allocated_length);
    740 }
    741 
    742 
    743 void Runtime::SetupArrayBuffer(Isolate* isolate,
    744                                Handle<JSArrayBuffer> array_buffer,
    745                                bool is_external,
    746                                void* data,
    747                                size_t allocated_length) {
    748   ASSERT(array_buffer->GetInternalFieldCount() ==
    749       v8::ArrayBuffer::kInternalFieldCount);
    750   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
    751     array_buffer->SetInternalField(i, Smi::FromInt(0));
    752   }
    753   array_buffer->set_backing_store(data);
    754   array_buffer->set_flag(Smi::FromInt(0));
    755   array_buffer->set_is_external(is_external);
    756 
    757   Handle<Object> byte_length =
    758       isolate->factory()->NewNumberFromSize(allocated_length);
    759   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
    760   array_buffer->set_byte_length(*byte_length);
    761 
    762   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
    763   isolate->heap()->set_array_buffers_list(*array_buffer);
    764   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
    765 }
    766 
    767 
    768 bool Runtime::SetupArrayBufferAllocatingData(
    769     Isolate* isolate,
    770     Handle<JSArrayBuffer> array_buffer,
    771     size_t allocated_length,
    772     bool initialize) {
    773   void* data;
    774   CHECK(V8::ArrayBufferAllocator() != NULL);
    775   if (allocated_length != 0) {
    776     if (initialize) {
    777       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
    778     } else {
    779       data =
    780         V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
    781     }
    782     if (data == NULL) return false;
    783   } else {
    784     data = NULL;
    785   }
    786 
    787   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
    788 
    789   isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
    790 
    791   return true;
    792 }
    793 
    794 
    795 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
    796   HandleScope scope(isolate);
    797   ASSERT(args.length() == 2);
    798   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
    799   CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
    800   size_t allocated_length;
    801   if (byteLength->IsSmi()) {
    802     allocated_length = Smi::cast(*byteLength)->value();
    803   } else {
    804     ASSERT(byteLength->IsHeapNumber());
    805     double value = HeapNumber::cast(*byteLength)->value();
    806 
    807     ASSERT(value >= 0);
    808 
    809     if (value > std::numeric_limits<size_t>::max()) {
    810       return isolate->Throw(
    811           *isolate->factory()->NewRangeError("invalid_array_buffer_length",
    812             HandleVector<Object>(NULL, 0)));
    813     }
    814 
    815     allocated_length = static_cast<size_t>(value);
    816   }
    817 
    818   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
    819                                                holder, allocated_length)) {
    820       return isolate->Throw(*isolate->factory()->
    821           NewRangeError("invalid_array_buffer_length",
    822             HandleVector<Object>(NULL, 0)));
    823   }
    824 
    825   return *holder;
    826 }
    827 
    828 
    829 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
    830   SealHandleScope shs(isolate);
    831   ASSERT(args.length() == 1);
    832   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
    833   return holder->byte_length();
    834 }
    835 
    836 
    837 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
    838   HandleScope scope(isolate);
    839   ASSERT(args.length() == 3);
    840   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
    841   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
    842   CONVERT_DOUBLE_ARG_CHECKED(first, 2);
    843   size_t start = static_cast<size_t>(first);
    844   size_t target_length = NumberToSize(isolate, target->byte_length());
    845 
    846   if (target_length == 0) return isolate->heap()->undefined_value();
    847 
    848   ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start);
    849   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
    850   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
    851   CopyBytes(target_data, source_data + start, target_length);
    852   return isolate->heap()->undefined_value();
    853 }
    854 
    855 
    856 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) {
    857   HandleScope scope(isolate);
    858   ASSERT(args.length() == 1);
    859   CONVERT_ARG_CHECKED(Object, object, 0);
    860   return object->IsJSArrayBufferView()
    861     ? isolate->heap()->true_value()
    862     : isolate->heap()->false_value();
    863 }
    864 
    865 
    866 void Runtime::ArrayIdToTypeAndSize(
    867     int arrayId, ExternalArrayType* array_type, size_t* element_size) {
    868   switch (arrayId) {
    869     case ARRAY_ID_UINT8:
    870       *array_type = kExternalUnsignedByteArray;
    871       *element_size = 1;
    872       break;
    873     case ARRAY_ID_INT8:
    874       *array_type = kExternalByteArray;
    875       *element_size = 1;
    876       break;
    877     case ARRAY_ID_UINT16:
    878       *array_type = kExternalUnsignedShortArray;
    879       *element_size = 2;
    880       break;
    881     case ARRAY_ID_INT16:
    882       *array_type = kExternalShortArray;
    883       *element_size = 2;
    884       break;
    885     case ARRAY_ID_UINT32:
    886       *array_type = kExternalUnsignedIntArray;
    887       *element_size = 4;
    888       break;
    889     case ARRAY_ID_INT32:
    890       *array_type = kExternalIntArray;
    891       *element_size = 4;
    892       break;
    893     case ARRAY_ID_FLOAT32:
    894       *array_type = kExternalFloatArray;
    895       *element_size = 4;
    896       break;
    897     case ARRAY_ID_FLOAT64:
    898       *array_type = kExternalDoubleArray;
    899       *element_size = 8;
    900       break;
    901     case ARRAY_ID_UINT8C:
    902       *array_type = kExternalPixelArray;
    903       *element_size = 1;
    904       break;
    905     default:
    906       UNREACHABLE();
    907   }
    908 }
    909 
    910 
    911 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
    912   HandleScope scope(isolate);
    913   ASSERT(args.length() == 5);
    914   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
    915   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
    916   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2);
    917   CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
    918   CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
    919 
    920   ASSERT(holder->GetInternalFieldCount() ==
    921       v8::ArrayBufferView::kInternalFieldCount);
    922   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
    923     holder->SetInternalField(i, Smi::FromInt(0));
    924   }
    925 
    926   ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
    927   size_t element_size = 1;  // Bogus initialization.
    928   Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
    929 
    930   holder->set_buffer(*buffer);
    931   holder->set_byte_offset(*byte_offset_object);
    932   holder->set_byte_length(*byte_length_object);
    933 
    934   size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
    935   size_t byte_length = NumberToSize(isolate, *byte_length_object);
    936   ASSERT(byte_length % element_size == 0);
    937   size_t length = byte_length / element_size;
    938 
    939   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
    940     return isolate->Throw(*isolate->factory()->
    941           NewRangeError("invalid_typed_array_length",
    942             HandleVector<Object>(NULL, 0)));
    943   }
    944 
    945   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
    946   holder->set_length(*length_obj);
    947   holder->set_weak_next(buffer->weak_first_view());
    948   buffer->set_weak_first_view(*holder);
    949 
    950   Handle<ExternalArray> elements =
    951       isolate->factory()->NewExternalArray(
    952           static_cast<int>(length), array_type,
    953           static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
    954   holder->set_elements(*elements);
    955   return isolate->heap()->undefined_value();
    956 }
    957 
    958 
    959 // Initializes a typed array from an array-like object.
    960 // If an array-like object happens to be a typed array of the same type,
    961 // initializes backing store using memove.
    962 //
    963 // Returns true if backing store was initialized or false otherwise.
    964 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
    965   HandleScope scope(isolate);
    966   ASSERT(args.length() == 4);
    967   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
    968   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
    969   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
    970   CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3);
    971 
    972   ASSERT(holder->GetInternalFieldCount() ==
    973       v8::ArrayBufferView::kInternalFieldCount);
    974   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
    975     holder->SetInternalField(i, Smi::FromInt(0));
    976   }
    977 
    978   ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
    979   size_t element_size = 1;  // Bogus initialization.
    980   Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
    981 
    982   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
    983   if (source->IsJSTypedArray() &&
    984       JSTypedArray::cast(*source)->type() == array_type) {
    985     length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
    986   }
    987   size_t length = NumberToSize(isolate, *length_obj);
    988 
    989   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
    990       (length > (kMaxInt / element_size))) {
    991     return isolate->Throw(*isolate->factory()->
    992           NewRangeError("invalid_typed_array_length",
    993             HandleVector<Object>(NULL, 0)));
    994   }
    995   size_t byte_length = length * element_size;
    996 
    997   // NOTE: not initializing backing store.
    998   // We assume that the caller of this function will initialize holder
    999   // with the loop
   1000   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
   1001   // We assume that the caller of this function is always a typed array
   1002   // constructor.
   1003   // If source is a typed array, this loop will always run to completion,
   1004   // so we are sure that the backing store will be initialized.
   1005   // Otherwise, the indexing operation might throw, so the loop will not
   1006   // run to completion and the typed array might remain partly initialized.
   1007   // However we further assume that the caller of this function is a typed array
   1008   // constructor, and the exception will propagate out of the constructor,
   1009   // therefore uninitialized memory will not be accessible by a user program.
   1010   //
   1011   // TODO(dslomov): revise this once we support subclassing.
   1012 
   1013   if (!Runtime::SetupArrayBufferAllocatingData(
   1014         isolate, buffer, byte_length, false)) {
   1015     return isolate->Throw(*isolate->factory()->
   1016           NewRangeError("invalid_array_buffer_length",
   1017             HandleVector<Object>(NULL, 0)));
   1018   }
   1019 
   1020   holder->set_buffer(*buffer);
   1021   holder->set_byte_offset(Smi::FromInt(0));
   1022   Handle<Object> byte_length_obj(
   1023       isolate->factory()->NewNumberFromSize(byte_length));
   1024   holder->set_byte_length(*byte_length_obj);
   1025   holder->set_length(*length_obj);
   1026   holder->set_weak_next(buffer->weak_first_view());
   1027   buffer->set_weak_first_view(*holder);
   1028 
   1029   Handle<ExternalArray> elements =
   1030       isolate->factory()->NewExternalArray(
   1031           static_cast<int>(length), array_type,
   1032           static_cast<uint8_t*>(buffer->backing_store()));
   1033   holder->set_elements(*elements);
   1034 
   1035   if (source->IsJSTypedArray()) {
   1036     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
   1037 
   1038     if (typed_array->type() == holder->type()) {
   1039       uint8_t* backing_store =
   1040         static_cast<uint8_t*>(
   1041           JSArrayBuffer::cast(typed_array->buffer())->backing_store());
   1042       size_t source_byte_offset =
   1043           NumberToSize(isolate, typed_array->byte_offset());
   1044       memcpy(
   1045           buffer->backing_store(),
   1046           backing_store + source_byte_offset,
   1047           byte_length);
   1048       return *isolate->factory()->true_value();
   1049     } else {
   1050       return *isolate->factory()->false_value();
   1051     }
   1052   }
   1053 
   1054   return *isolate->factory()->false_value();
   1055 }
   1056 
   1057 
   1058 #define TYPED_ARRAY_GETTER(getter, accessor) \
   1059   RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) {             \
   1060     HandleScope scope(isolate);                                               \
   1061     ASSERT(args.length() == 1);                                               \
   1062     CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);                            \
   1063     if (!holder->IsJSTypedArray())                                            \
   1064       return isolate->Throw(*isolate->factory()->NewTypeError(                \
   1065           "not_typed_array", HandleVector<Object>(NULL, 0)));                 \
   1066     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));            \
   1067     return typed_array->accessor();                                           \
   1068   }
   1069 
   1070 TYPED_ARRAY_GETTER(Buffer, buffer)
   1071 TYPED_ARRAY_GETTER(ByteLength, byte_length)
   1072 TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
   1073 TYPED_ARRAY_GETTER(Length, length)
   1074 
   1075 #undef TYPED_ARRAY_GETTER
   1076 
   1077 // Return codes for Runtime_TypedArraySetFastCases.
   1078 // Should be synchronized with typedarray.js natives.
   1079 enum TypedArraySetResultCodes {
   1080   // Set from typed array of the same type.
   1081   // This is processed by TypedArraySetFastCases
   1082   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
   1083   // Set from typed array of the different type, overlapping in memory.
   1084   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
   1085   // Set from typed array of the different type, non-overlapping.
   1086   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
   1087   // Set from non-typed array.
   1088   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
   1089 };
   1090 
   1091 
   1092 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
   1093   HandleScope scope(isolate);
   1094   CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
   1095   CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
   1096   CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
   1097 
   1098   if (!target_obj->IsJSTypedArray())
   1099     return isolate->Throw(*isolate->factory()->NewTypeError(
   1100         "not_typed_array", HandleVector<Object>(NULL, 0)));
   1101 
   1102   if (!source_obj->IsJSTypedArray())
   1103     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
   1104 
   1105   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
   1106   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
   1107   size_t offset = NumberToSize(isolate, *offset_obj);
   1108   size_t target_length = NumberToSize(isolate, target->length());
   1109   size_t source_length = NumberToSize(isolate, source->length());
   1110   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
   1111   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
   1112   if (offset > target_length ||
   1113       offset + source_length > target_length ||
   1114       offset + source_length < offset)  // overflow
   1115     return isolate->Throw(*isolate->factory()->NewRangeError(
   1116           "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
   1117 
   1118   size_t target_offset = NumberToSize(isolate, target->byte_offset());
   1119   size_t source_offset = NumberToSize(isolate, source->byte_offset());
   1120   uint8_t* target_base =
   1121       static_cast<uint8_t*>(
   1122         JSArrayBuffer::cast(target->buffer())->backing_store()) + target_offset;
   1123   uint8_t* source_base =
   1124       static_cast<uint8_t*>(
   1125         JSArrayBuffer::cast(source->buffer())->backing_store()) + source_offset;
   1126 
   1127   // Typed arrays of the same type: use memmove.
   1128   if (target->type() == source->type()) {
   1129     memmove(target_base + offset * target->element_size(),
   1130         source_base, source_byte_length);
   1131     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
   1132   }
   1133 
   1134   // Typed arrays of different types over the same backing store
   1135   if ((source_base <= target_base &&
   1136         source_base + source_byte_length > target_base) ||
   1137       (target_base <= source_base &&
   1138         target_base + target_byte_length > source_base)) {
   1139     // We do not support overlapping ArrayBuffers
   1140     ASSERT(
   1141       JSArrayBuffer::cast(target->buffer())->backing_store() ==
   1142       JSArrayBuffer::cast(source->buffer())->backing_store());
   1143     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
   1144   } else {  // Non-overlapping typed arrays
   1145     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
   1146   }
   1147 }
   1148 
   1149 
   1150 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
   1151   HandleScope scope(isolate);
   1152   ASSERT(args.length() == 4);
   1153   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
   1154   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
   1155   CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2);
   1156   CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3);
   1157 
   1158   ASSERT(holder->GetInternalFieldCount() ==
   1159       v8::ArrayBufferView::kInternalFieldCount);
   1160   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1161     holder->SetInternalField(i, Smi::FromInt(0));
   1162   }
   1163 
   1164   holder->set_buffer(*buffer);
   1165   ASSERT(byte_offset->IsNumber());
   1166   ASSERT(
   1167       NumberToSize(isolate, buffer->byte_length()) >=
   1168         NumberToSize(isolate, *byte_offset)
   1169         + NumberToSize(isolate, *byte_length));
   1170   holder->set_byte_offset(*byte_offset);
   1171   ASSERT(byte_length->IsNumber());
   1172   holder->set_byte_length(*byte_length);
   1173 
   1174   holder->set_weak_next(buffer->weak_first_view());
   1175   buffer->set_weak_first_view(*holder);
   1176 
   1177   return isolate->heap()->undefined_value();
   1178 }
   1179 
   1180 
   1181 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
   1182   HandleScope scope(isolate);
   1183   ASSERT(args.length() == 1);
   1184   CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
   1185   return data_view->buffer();
   1186 }
   1187 
   1188 
   1189 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
   1190   HandleScope scope(isolate);
   1191   ASSERT(args.length() == 1);
   1192   CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
   1193   return data_view->byte_offset();
   1194 }
   1195 
   1196 
   1197 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
   1198   HandleScope scope(isolate);
   1199   ASSERT(args.length() == 1);
   1200   CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
   1201   return data_view->byte_length();
   1202 }
   1203 
   1204 
   1205 inline static bool NeedToFlipBytes(bool is_little_endian) {
   1206 #ifdef V8_TARGET_LITTLE_ENDIAN
   1207   return !is_little_endian;
   1208 #else
   1209   return is_little_endian;
   1210 #endif
   1211 }
   1212 
   1213 
   1214 template<int n>
   1215 inline void CopyBytes(uint8_t* target, uint8_t* source) {
   1216   for (int i = 0; i < n; i++) {
   1217     *(target++) = *(source++);
   1218   }
   1219 }
   1220 
   1221 
   1222 template<int n>
   1223 inline void FlipBytes(uint8_t* target, uint8_t* source) {
   1224   source = source + (n-1);
   1225   for (int i = 0; i < n; i++) {
   1226     *(target++) = *(source--);
   1227   }
   1228 }
   1229 
   1230 
   1231 template<typename T>
   1232 inline static bool DataViewGetValue(
   1233     Isolate* isolate,
   1234     Handle<JSDataView> data_view,
   1235     Handle<Object> byte_offset_obj,
   1236     bool is_little_endian,
   1237     T* result) {
   1238   size_t byte_offset = 0;
   1239   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
   1240     return false;
   1241   }
   1242   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1243 
   1244   size_t data_view_byte_offset =
   1245       NumberToSize(isolate, data_view->byte_offset());
   1246   size_t data_view_byte_length =
   1247       NumberToSize(isolate, data_view->byte_length());
   1248   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1249       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1250     return false;
   1251   }
   1252 
   1253   union Value {
   1254     T data;
   1255     uint8_t bytes[sizeof(T)];
   1256   };
   1257 
   1258   Value value;
   1259   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1260   ASSERT(
   1261       NumberToSize(isolate, buffer->byte_length())
   1262       >= buffer_offset + sizeof(T));
   1263   uint8_t* source =
   1264         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1265   if (NeedToFlipBytes(is_little_endian)) {
   1266     FlipBytes<sizeof(T)>(value.bytes, source);
   1267   } else {
   1268     CopyBytes<sizeof(T)>(value.bytes, source);
   1269   }
   1270   *result = value.data;
   1271   return true;
   1272 }
   1273 
   1274 
   1275 template<typename T>
   1276 static bool DataViewSetValue(
   1277     Isolate* isolate,
   1278     Handle<JSDataView> data_view,
   1279     Handle<Object> byte_offset_obj,
   1280     bool is_little_endian,
   1281     T data) {
   1282   size_t byte_offset = 0;
   1283   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
   1284     return false;
   1285   }
   1286   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1287 
   1288   size_t data_view_byte_offset =
   1289       NumberToSize(isolate, data_view->byte_offset());
   1290   size_t data_view_byte_length =
   1291       NumberToSize(isolate, data_view->byte_length());
   1292   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1293       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1294     return false;
   1295   }
   1296 
   1297   union Value {
   1298     T data;
   1299     uint8_t bytes[sizeof(T)];
   1300   };
   1301 
   1302   Value value;
   1303   value.data = data;
   1304   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1305   ASSERT(
   1306       NumberToSize(isolate, buffer->byte_length())
   1307       >= buffer_offset + sizeof(T));
   1308   uint8_t* target =
   1309         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1310   if (NeedToFlipBytes(is_little_endian)) {
   1311     FlipBytes<sizeof(T)>(target, value.bytes);
   1312   } else {
   1313     CopyBytes<sizeof(T)>(target, value.bytes);
   1314   }
   1315   return true;
   1316 }
   1317 
   1318 
   1319 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
   1320   RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) {             \
   1321     HandleScope scope(isolate);                                               \
   1322     ASSERT(args.length() == 3);                                               \
   1323     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
   1324     CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
   1325     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
   1326     Type result;                                                              \
   1327     if (DataViewGetValue(                                                     \
   1328           isolate, holder, offset, is_little_endian, &result)) {              \
   1329       return isolate->heap()->Converter(result);                              \
   1330     } else {                                                                  \
   1331       return isolate->Throw(*isolate->factory()->NewRangeError(               \
   1332           "invalid_data_view_accessor_offset",                                \
   1333           HandleVector<Object>(NULL, 0)));                                    \
   1334     }                                                                         \
   1335   }
   1336 
   1337 DATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32)
   1338 DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32)
   1339 DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32)
   1340 DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32)
   1341 DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32)
   1342 DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32)
   1343 DATA_VIEW_GETTER(Float32, float, NumberFromDouble)
   1344 DATA_VIEW_GETTER(Float64, double, NumberFromDouble)
   1345 
   1346 #undef DATA_VIEW_GETTER
   1347 
   1348 
   1349 template <typename T>
   1350 static T DataViewConvertValue(double value);
   1351 
   1352 
   1353 template <>
   1354 int8_t DataViewConvertValue<int8_t>(double value) {
   1355   return static_cast<int8_t>(DoubleToInt32(value));
   1356 }
   1357 
   1358 
   1359 template <>
   1360 int16_t DataViewConvertValue<int16_t>(double value) {
   1361   return static_cast<int16_t>(DoubleToInt32(value));
   1362 }
   1363 
   1364 
   1365 template <>
   1366 int32_t DataViewConvertValue<int32_t>(double value) {
   1367   return DoubleToInt32(value);
   1368 }
   1369 
   1370 
   1371 template <>
   1372 uint8_t DataViewConvertValue<uint8_t>(double value) {
   1373   return static_cast<uint8_t>(DoubleToUint32(value));
   1374 }
   1375 
   1376 
   1377 template <>
   1378 uint16_t DataViewConvertValue<uint16_t>(double value) {
   1379   return static_cast<uint16_t>(DoubleToUint32(value));
   1380 }
   1381 
   1382 
   1383 template <>
   1384 uint32_t DataViewConvertValue<uint32_t>(double value) {
   1385   return DoubleToUint32(value);
   1386 }
   1387 
   1388 
   1389 template <>
   1390 float DataViewConvertValue<float>(double value) {
   1391   return static_cast<float>(value);
   1392 }
   1393 
   1394 
   1395 template <>
   1396 double DataViewConvertValue<double>(double value) {
   1397   return value;
   1398 }
   1399 
   1400 
   1401 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
   1402   RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) {             \
   1403     HandleScope scope(isolate);                                               \
   1404     ASSERT(args.length() == 4);                                               \
   1405     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
   1406     CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
   1407     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);                             \
   1408     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
   1409     Type v = DataViewConvertValue<Type>(value->Number());                     \
   1410     if (DataViewSetValue(                                                     \
   1411           isolate, holder, offset, is_little_endian, v)) {                    \
   1412       return isolate->heap()->undefined_value();                              \
   1413     } else {                                                                  \
   1414       return isolate->Throw(*isolate->factory()->NewRangeError(               \
   1415           "invalid_data_view_accessor_offset",                                \
   1416           HandleVector<Object>(NULL, 0)));                                    \
   1417     }                                                                         \
   1418   }
   1419 
   1420 DATA_VIEW_SETTER(Uint8, uint8_t)
   1421 DATA_VIEW_SETTER(Int8, int8_t)
   1422 DATA_VIEW_SETTER(Uint16, uint16_t)
   1423 DATA_VIEW_SETTER(Int16, int16_t)
   1424 DATA_VIEW_SETTER(Uint32, uint32_t)
   1425 DATA_VIEW_SETTER(Int32, int32_t)
   1426 DATA_VIEW_SETTER(Float32, float)
   1427 DATA_VIEW_SETTER(Float64, double)
   1428 
   1429 #undef DATA_VIEW_SETTER
   1430 
   1431 
   1432 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
   1433   HandleScope scope(isolate);
   1434   ASSERT(args.length() == 1);
   1435   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1436   Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
   1437   holder->set_table(*table);
   1438   return *holder;
   1439 }
   1440 
   1441 
   1442 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
   1443   HandleScope scope(isolate);
   1444   ASSERT(args.length() == 2);
   1445   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1446   Handle<Object> key(args[1], isolate);
   1447   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1448   table = ObjectHashSet::Add(table, key);
   1449   holder->set_table(*table);
   1450   return isolate->heap()->undefined_value();
   1451 }
   1452 
   1453 
   1454 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
   1455   HandleScope scope(isolate);
   1456   ASSERT(args.length() == 2);
   1457   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1458   Handle<Object> key(args[1], isolate);
   1459   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1460   return isolate->heap()->ToBoolean(table->Contains(*key));
   1461 }
   1462 
   1463 
   1464 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
   1465   HandleScope scope(isolate);
   1466   ASSERT(args.length() == 2);
   1467   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1468   Handle<Object> key(args[1], isolate);
   1469   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1470   table = ObjectHashSet::Remove(table, key);
   1471   holder->set_table(*table);
   1472   return isolate->heap()->undefined_value();
   1473 }
   1474 
   1475 
   1476 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
   1477   HandleScope scope(isolate);
   1478   ASSERT(args.length() == 1);
   1479   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1480   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1481   return Smi::FromInt(table->NumberOfElements());
   1482 }
   1483 
   1484 
   1485 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
   1486   HandleScope scope(isolate);
   1487   ASSERT(args.length() == 1);
   1488   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1489   Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
   1490   holder->set_table(*table);
   1491   return *holder;
   1492 }
   1493 
   1494 
   1495 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
   1496   HandleScope scope(isolate);
   1497   ASSERT(args.length() == 2);
   1498   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1499   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1500   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1501   Handle<Object> lookup(table->Lookup(*key), isolate);
   1502   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1503 }
   1504 
   1505 
   1506 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
   1507   HandleScope scope(isolate);
   1508   ASSERT(args.length() == 2);
   1509   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1510   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1511   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1512   Handle<Object> lookup(table->Lookup(*key), isolate);
   1513   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1514 }
   1515 
   1516 
   1517 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
   1518   HandleScope scope(isolate);
   1519   ASSERT(args.length() == 2);
   1520   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1521   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1522   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1523   Handle<Object> lookup(table->Lookup(*key), isolate);
   1524   Handle<ObjectHashTable> new_table =
   1525       ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
   1526   holder->set_table(*new_table);
   1527   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1528 }
   1529 
   1530 
   1531 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
   1532   HandleScope scope(isolate);
   1533   ASSERT(args.length() == 3);
   1534   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1535   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1536   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   1537   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1538   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
   1539   holder->set_table(*new_table);
   1540   return isolate->heap()->undefined_value();
   1541 }
   1542 
   1543 
   1544 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
   1545   HandleScope scope(isolate);
   1546   ASSERT(args.length() == 1);
   1547   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1548   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1549   return Smi::FromInt(table->NumberOfElements());
   1550 }
   1551 
   1552 
   1553 static JSWeakCollection* WeakCollectionInitialize(Isolate* isolate,
   1554     Handle<JSWeakCollection> weak_collection) {
   1555   ASSERT(weak_collection->map()->inobject_properties() == 0);
   1556   Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
   1557   weak_collection->set_table(*table);
   1558   weak_collection->set_next(Smi::FromInt(0));
   1559   return *weak_collection;
   1560 }
   1561 
   1562 
   1563 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionInitialize) {
   1564   HandleScope scope(isolate);
   1565   ASSERT(args.length() == 1);
   1566   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1567   return WeakCollectionInitialize(isolate, weak_collection);
   1568 }
   1569 
   1570 
   1571 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionGet) {
   1572   HandleScope scope(isolate);
   1573   ASSERT(args.length() == 2);
   1574   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1575   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1576   Handle<ObjectHashTable> table(
   1577       ObjectHashTable::cast(weak_collection->table()));
   1578   Handle<Object> lookup(table->Lookup(*key), isolate);
   1579   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1580 }
   1581 
   1582 
   1583 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionHas) {
   1584   HandleScope scope(isolate);
   1585   ASSERT(args.length() == 2);
   1586   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1587   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1588   Handle<ObjectHashTable> table(
   1589       ObjectHashTable::cast(weak_collection->table()));
   1590   Handle<Object> lookup(table->Lookup(*key), isolate);
   1591   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1592 }
   1593 
   1594 
   1595 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
   1596   HandleScope scope(isolate);
   1597   ASSERT(args.length() == 2);
   1598   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1599   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1600   Handle<ObjectHashTable> table(ObjectHashTable::cast(
   1601       weak_collection->table()));
   1602   Handle<Object> lookup(table->Lookup(*key), isolate);
   1603   Handle<ObjectHashTable> new_table =
   1604       ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
   1605   weak_collection->set_table(*new_table);
   1606   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1607 }
   1608 
   1609 
   1610 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
   1611   HandleScope scope(isolate);
   1612   ASSERT(args.length() == 3);
   1613   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1614   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1615   Handle<Object> value(args[2], isolate);
   1616   Handle<ObjectHashTable> table(
   1617       ObjectHashTable::cast(weak_collection->table()));
   1618   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
   1619   weak_collection->set_table(*new_table);
   1620   return isolate->heap()->undefined_value();
   1621 }
   1622 
   1623 
   1624 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
   1625   SealHandleScope shs(isolate);
   1626   ASSERT(args.length() == 1);
   1627   Object* obj = args[0];
   1628   if (!obj->IsJSObject()) return isolate->heap()->null_value();
   1629   return JSObject::cast(obj)->class_name();
   1630 }
   1631 
   1632 
   1633 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
   1634   HandleScope scope(isolate);
   1635   ASSERT(args.length() == 1);
   1636   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
   1637   // We don't expect access checks to be needed on JSProxy objects.
   1638   ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
   1639   do {
   1640     if (obj->IsAccessCheckNeeded() &&
   1641         !isolate->MayNamedAccessWrapper(Handle<JSObject>::cast(obj),
   1642                                         isolate->factory()->proto_string(),
   1643                                         v8::ACCESS_GET)) {
   1644       isolate->ReportFailedAccessCheck(JSObject::cast(*obj), v8::ACCESS_GET);
   1645       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   1646       return isolate->heap()->undefined_value();
   1647     }
   1648     obj = handle(obj->GetPrototype(isolate), isolate);
   1649   } while (obj->IsJSObject() &&
   1650            JSObject::cast(*obj)->map()->is_hidden_prototype());
   1651   return *obj;
   1652 }
   1653 
   1654 
   1655 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate,
   1656                                                        Object* receiver) {
   1657   Object* current = receiver->GetPrototype(isolate);
   1658   while (current->IsJSObject() &&
   1659          JSObject::cast(current)->map()->is_hidden_prototype()) {
   1660     current = current->GetPrototype(isolate);
   1661   }
   1662   return current;
   1663 }
   1664 
   1665 
   1666 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
   1667   HandleScope scope(isolate);
   1668   ASSERT(args.length() == 2);
   1669   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1670   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   1671   if (FLAG_harmony_observation && obj->map()->is_observed()) {
   1672     Handle<Object> old_value(
   1673         GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
   1674 
   1675     Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
   1676     RETURN_IF_EMPTY_HANDLE(isolate, result);
   1677 
   1678     Handle<Object> new_value(
   1679         GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
   1680     if (!new_value->SameValue(*old_value)) {
   1681       JSObject::EnqueueChangeRecord(obj, "setPrototype",
   1682                                     isolate->factory()->proto_string(),
   1683                                     old_value);
   1684     }
   1685     return *result;
   1686   }
   1687   Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
   1688   RETURN_IF_EMPTY_HANDLE(isolate, result);
   1689   return *result;
   1690 }
   1691 
   1692 
   1693 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
   1694   SealHandleScope shs(isolate);
   1695   ASSERT(args.length() == 2);
   1696   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
   1697   Object* O = args[0];
   1698   Object* V = args[1];
   1699   while (true) {
   1700     Object* prototype = V->GetPrototype(isolate);
   1701     if (prototype->IsNull()) return isolate->heap()->false_value();
   1702     if (O == prototype) return isolate->heap()->true_value();
   1703     V = prototype;
   1704   }
   1705 }
   1706 
   1707 
   1708 static bool CheckAccessException(Object* callback,
   1709                                  v8::AccessType access_type) {
   1710   DisallowHeapAllocation no_gc;
   1711   if (callback->IsAccessorInfo()) {
   1712     AccessorInfo* info = AccessorInfo::cast(callback);
   1713     return
   1714         (access_type == v8::ACCESS_HAS &&
   1715            (info->all_can_read() || info->all_can_write())) ||
   1716         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
   1717         (access_type == v8::ACCESS_SET && info->all_can_write());
   1718   }
   1719   if (callback->IsAccessorPair()) {
   1720     AccessorPair* info = AccessorPair::cast(callback);
   1721     return
   1722         (access_type == v8::ACCESS_HAS &&
   1723            (info->all_can_read() || info->all_can_write())) ||
   1724         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
   1725         (access_type == v8::ACCESS_SET && info->all_can_write());
   1726   }
   1727   return false;
   1728 }
   1729 
   1730 
   1731 template<class Key>
   1732 static bool CheckGenericAccess(
   1733     Handle<JSObject> receiver,
   1734     Handle<JSObject> holder,
   1735     Key key,
   1736     v8::AccessType access_type,
   1737     bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
   1738   Isolate* isolate = receiver->GetIsolate();
   1739   for (Handle<JSObject> current = receiver;
   1740        true;
   1741        current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
   1742     if (current->IsAccessCheckNeeded() &&
   1743         !(isolate->*mayAccess)(current, key, access_type)) {
   1744       return false;
   1745     }
   1746     if (current.is_identical_to(holder)) break;
   1747   }
   1748   return true;
   1749 }
   1750 
   1751 
   1752 enum AccessCheckResult {
   1753   ACCESS_FORBIDDEN,
   1754   ACCESS_ALLOWED,
   1755   ACCESS_ABSENT
   1756 };
   1757 
   1758 
   1759 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
   1760                                              Handle<Name> name,
   1761                                              v8::AccessType access_type) {
   1762   uint32_t index;
   1763   if (name->AsArrayIndex(&index)) {
   1764     // TODO(1095): we should traverse hidden prototype hierachy as well.
   1765     if (CheckGenericAccess(
   1766             obj, obj, index, access_type, &Isolate::MayIndexedAccessWrapper)) {
   1767       return ACCESS_ALLOWED;
   1768     }
   1769 
   1770     obj->GetIsolate()->ReportFailedAccessCheck(*obj, access_type);
   1771     return ACCESS_FORBIDDEN;
   1772   }
   1773 
   1774   Isolate* isolate = obj->GetIsolate();
   1775   LookupResult lookup(isolate);
   1776   obj->LocalLookup(*name, &lookup, true);
   1777 
   1778   if (!lookup.IsProperty()) return ACCESS_ABSENT;
   1779   Handle<JSObject> holder(lookup.holder(), isolate);
   1780   if (CheckGenericAccess<Handle<Object> >(
   1781           obj, holder, name, access_type, &Isolate::MayNamedAccessWrapper)) {
   1782     return ACCESS_ALLOWED;
   1783   }
   1784 
   1785   // Access check callback denied the access, but some properties
   1786   // can have a special permissions which override callbacks descision
   1787   // (currently see v8::AccessControl).
   1788   // API callbacks can have per callback access exceptions.
   1789   switch (lookup.type()) {
   1790     case CALLBACKS:
   1791       if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
   1792         return ACCESS_ALLOWED;
   1793       }
   1794       break;
   1795     case INTERCEPTOR:
   1796       // If the object has an interceptor, try real named properties.
   1797       // Overwrite the result to fetch the correct property later.
   1798       holder->LookupRealNamedProperty(*name, &lookup);
   1799       if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
   1800         if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
   1801           return ACCESS_ALLOWED;
   1802         }
   1803       }
   1804       break;
   1805     default:
   1806       break;
   1807   }
   1808 
   1809   isolate->ReportFailedAccessCheck(*obj, access_type);
   1810   return ACCESS_FORBIDDEN;
   1811 }
   1812 
   1813 
   1814 // Enumerator used as indices into the array returned from GetOwnProperty
   1815 enum PropertyDescriptorIndices {
   1816   IS_ACCESSOR_INDEX,
   1817   VALUE_INDEX,
   1818   GETTER_INDEX,
   1819   SETTER_INDEX,
   1820   WRITABLE_INDEX,
   1821   ENUMERABLE_INDEX,
   1822   CONFIGURABLE_INDEX,
   1823   DESCRIPTOR_SIZE
   1824 };
   1825 
   1826 
   1827 static Handle<Object> GetOwnProperty(Isolate* isolate,
   1828                                      Handle<JSObject> obj,
   1829                                      Handle<Name> name) {
   1830   Heap* heap = isolate->heap();
   1831   Factory* factory = isolate->factory();
   1832   // Due to some WebKit tests, we want to make sure that we do not log
   1833   // more than one access failure here.
   1834   AccessCheckResult access_check_result =
   1835       CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
   1836   RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
   1837   switch (access_check_result) {
   1838     case ACCESS_FORBIDDEN: return factory->false_value();
   1839     case ACCESS_ALLOWED: break;
   1840     case ACCESS_ABSENT: return factory->undefined_value();
   1841   }
   1842 
   1843   PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name);
   1844   if (attrs == ABSENT) {
   1845     RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
   1846     return factory->undefined_value();
   1847   }
   1848   ASSERT(!isolate->has_scheduled_exception());
   1849   AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name);
   1850   Handle<AccessorPair> accessors(raw_accessors, isolate);
   1851   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   1852   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
   1853   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
   1854   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL));
   1855 
   1856   if (raw_accessors == NULL) {
   1857     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
   1858     // GetProperty does access check.
   1859     Handle<Object> value = GetProperty(isolate, obj, name);
   1860     RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<Object>::null());
   1861     elms->set(VALUE_INDEX, *value);
   1862   } else {
   1863     // Access checks are performed for both accessors separately.
   1864     // When they fail, the respective field is not set in the descriptor.
   1865     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
   1866     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
   1867 
   1868     if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) {
   1869       ASSERT(!isolate->has_scheduled_exception());
   1870       elms->set(GETTER_INDEX, *getter);
   1871     } else {
   1872       RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
   1873     }
   1874 
   1875     if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
   1876       ASSERT(!isolate->has_scheduled_exception());
   1877       elms->set(SETTER_INDEX, *setter);
   1878     } else {
   1879       RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
   1880     }
   1881   }
   1882 
   1883   return isolate->factory()->NewJSArrayWithElements(elms);
   1884 }
   1885 
   1886 
   1887 // Returns an array with the property description:
   1888 //  if args[1] is not a property on args[0]
   1889 //          returns undefined
   1890 //  if args[1] is a data property on args[0]
   1891 //         [false, value, Writeable, Enumerable, Configurable]
   1892 //  if args[1] is an accessor on args[0]
   1893 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
   1894 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
   1895   HandleScope scope(isolate);
   1896   ASSERT(args.length() == 2);
   1897   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1898   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   1899   Handle<Object> result = GetOwnProperty(isolate, obj, name);
   1900   RETURN_IF_EMPTY_HANDLE(isolate, result);
   1901   return *result;
   1902 }
   1903 
   1904 
   1905 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
   1906   HandleScope scope(isolate);
   1907   ASSERT(args.length() == 1);
   1908   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1909   Handle<Object> result = JSObject::PreventExtensions(obj);
   1910   RETURN_IF_EMPTY_HANDLE(isolate, result);
   1911   return *result;
   1912 }
   1913 
   1914 
   1915 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
   1916   SealHandleScope shs(isolate);
   1917   ASSERT(args.length() == 1);
   1918   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   1919   if (obj->IsJSGlobalProxy()) {
   1920     Object* proto = obj->GetPrototype();
   1921     if (proto->IsNull()) return isolate->heap()->false_value();
   1922     ASSERT(proto->IsJSGlobalObject());
   1923     obj = JSObject::cast(proto);
   1924   }
   1925   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
   1926 }
   1927 
   1928 
   1929 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
   1930   HandleScope scope(isolate);
   1931   ASSERT(args.length() == 3);
   1932   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
   1933   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   1934   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
   1935   Handle<Object> result = RegExpImpl::Compile(re, pattern, flags);
   1936   RETURN_IF_EMPTY_HANDLE(isolate, result);
   1937   return *result;
   1938 }
   1939 
   1940 
   1941 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) {
   1942   HandleScope scope(isolate);
   1943   ASSERT(args.length() == 1);
   1944   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
   1945   return *isolate->factory()->CreateApiFunction(data);
   1946 }
   1947 
   1948 
   1949 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsTemplate) {
   1950   SealHandleScope shs(isolate);
   1951   ASSERT(args.length() == 1);
   1952   Object* arg = args[0];
   1953   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
   1954   return isolate->heap()->ToBoolean(result);
   1955 }
   1956 
   1957 
   1958 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
   1959   SealHandleScope shs(isolate);
   1960   ASSERT(args.length() == 2);
   1961   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
   1962   CONVERT_SMI_ARG_CHECKED(index, 1)
   1963   int offset = index * kPointerSize + HeapObject::kHeaderSize;
   1964   InstanceType type = templ->map()->instance_type();
   1965   RUNTIME_ASSERT(type ==  FUNCTION_TEMPLATE_INFO_TYPE ||
   1966                  type ==  OBJECT_TEMPLATE_INFO_TYPE);
   1967   RUNTIME_ASSERT(offset > 0);
   1968   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
   1969     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
   1970   } else {
   1971     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
   1972   }
   1973   return *HeapObject::RawField(templ, offset);
   1974 }
   1975 
   1976 
   1977 RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
   1978   SealHandleScope shs(isolate);
   1979   ASSERT(args.length() == 1);
   1980   CONVERT_ARG_CHECKED(HeapObject, object, 0);
   1981   Map* old_map = object->map();
   1982   bool needs_access_checks = old_map->is_access_check_needed();
   1983   if (needs_access_checks) {
   1984     // Copy map so it won't interfere constructor's initial map.
   1985     Map* new_map;
   1986     MaybeObject* maybe_new_map = old_map->Copy();
   1987     if (!maybe_new_map->To(&new_map)) return maybe_new_map;
   1988 
   1989     new_map->set_is_access_check_needed(false);
   1990     object->set_map(new_map);
   1991   }
   1992   return isolate->heap()->ToBoolean(needs_access_checks);
   1993 }
   1994 
   1995 
   1996 RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
   1997   SealHandleScope shs(isolate);
   1998   ASSERT(args.length() == 1);
   1999   CONVERT_ARG_CHECKED(HeapObject, object, 0);
   2000   Map* old_map = object->map();
   2001   if (!old_map->is_access_check_needed()) {
   2002     // Copy map so it won't interfere constructor's initial map.
   2003     Map* new_map;
   2004     MaybeObject* maybe_new_map = old_map->Copy();
   2005     if (!maybe_new_map->To(&new_map)) return maybe_new_map;
   2006 
   2007     new_map->set_is_access_check_needed(true);
   2008     object->set_map(new_map);
   2009   }
   2010   return isolate->heap()->undefined_value();
   2011 }
   2012 
   2013 
   2014 // Transform getter or setter into something DefineAccessor can handle.
   2015 static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
   2016                                                    Handle<Object> component) {
   2017   if (component->IsUndefined()) return isolate->factory()->null_value();
   2018   Handle<FunctionTemplateInfo> info =
   2019       Handle<FunctionTemplateInfo>::cast(component);
   2020   return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
   2021 }
   2022 
   2023 
   2024 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAccessorProperty) {
   2025   HandleScope scope(isolate);
   2026   ASSERT(args.length() == 6);
   2027   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2028   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   2029   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   2030   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   2031   CONVERT_SMI_ARG_CHECKED(attribute, 4);
   2032   CONVERT_SMI_ARG_CHECKED(access_control, 5);
   2033   JSObject::DefineAccessor(object,
   2034                            name,
   2035                            InstantiateAccessorComponent(isolate, getter),
   2036                            InstantiateAccessorComponent(isolate, setter),
   2037                            static_cast<PropertyAttributes>(attribute),
   2038                            static_cast<v8::AccessControl>(access_control));
   2039   return isolate->heap()->undefined_value();
   2040 }
   2041 
   2042 
   2043 static Failure* ThrowRedeclarationError(Isolate* isolate,
   2044                                         const char* type,
   2045                                         Handle<String> name) {
   2046   HandleScope scope(isolate);
   2047   Handle<Object> type_handle =
   2048       isolate->factory()->NewStringFromAscii(CStrVector(type));
   2049   Handle<Object> args[2] = { type_handle, name };
   2050   Handle<Object> error =
   2051       isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2));
   2052   return isolate->Throw(*error);
   2053 }
   2054 
   2055 
   2056 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
   2057   HandleScope scope(isolate);
   2058   ASSERT(args.length() == 3);
   2059   Handle<GlobalObject> global = Handle<GlobalObject>(
   2060       isolate->context()->global_object());
   2061 
   2062   Handle<Context> context = args.at<Context>(0);
   2063   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
   2064   CONVERT_SMI_ARG_CHECKED(flags, 2);
   2065 
   2066   // Traverse the name/value pairs and set the properties.
   2067   int length = pairs->length();
   2068   for (int i = 0; i < length; i += 2) {
   2069     HandleScope scope(isolate);
   2070     Handle<String> name(String::cast(pairs->get(i)));
   2071     Handle<Object> value(pairs->get(i + 1), isolate);
   2072 
   2073     // We have to declare a global const property. To capture we only
   2074     // assign to it when evaluating the assignment for "const x =
   2075     // <expr>" the initial value is the hole.
   2076     bool is_var = value->IsUndefined();
   2077     bool is_const = value->IsTheHole();
   2078     bool is_function = value->IsSharedFunctionInfo();
   2079     ASSERT(is_var + is_const + is_function == 1);
   2080 
   2081     if (is_var || is_const) {
   2082       // Lookup the property in the global object, and don't set the
   2083       // value of the variable if the property is already there.
   2084       // Do the lookup locally only, see ES5 erratum.
   2085       LookupResult lookup(isolate);
   2086       if (FLAG_es52_globals) {
   2087         global->LocalLookup(*name, &lookup, true);
   2088       } else {
   2089         global->Lookup(*name, &lookup);
   2090       }
   2091       if (lookup.IsFound()) {
   2092         // We found an existing property. Unless it was an interceptor
   2093         // that claims the property is absent, skip this declaration.
   2094         if (!lookup.IsInterceptor()) continue;
   2095         PropertyAttributes attributes = global->GetPropertyAttribute(*name);
   2096         if (attributes != ABSENT) continue;
   2097         // Fall-through and introduce the absent property by using
   2098         // SetProperty.
   2099       }
   2100     } else if (is_function) {
   2101       // Copy the function and update its context. Use it as value.
   2102       Handle<SharedFunctionInfo> shared =
   2103           Handle<SharedFunctionInfo>::cast(value);
   2104       Handle<JSFunction> function =
   2105           isolate->factory()->NewFunctionFromSharedFunctionInfo(
   2106               shared, context, TENURED);
   2107       value = function;
   2108     }
   2109 
   2110     LookupResult lookup(isolate);
   2111     global->LocalLookup(*name, &lookup, true);
   2112 
   2113     // Compute the property attributes. According to ECMA-262,
   2114     // the property must be non-configurable except in eval.
   2115     int attr = NONE;
   2116     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
   2117     if (!is_eval) {
   2118       attr |= DONT_DELETE;
   2119     }
   2120     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
   2121     if (is_const || (is_native && is_function)) {
   2122       attr |= READ_ONLY;
   2123     }
   2124 
   2125     LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
   2126 
   2127     if (!lookup.IsFound() || is_function) {
   2128       // If the local property exists, check that we can reconfigure it
   2129       // as required for function declarations.
   2130       if (lookup.IsFound() && lookup.IsDontDelete()) {
   2131         if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
   2132             lookup.IsPropertyCallbacks()) {
   2133           return ThrowRedeclarationError(isolate, "function", name);
   2134         }
   2135         // If the existing property is not configurable, keep its attributes.
   2136         attr = lookup.GetAttributes();
   2137       }
   2138       // Define or redefine own property.
   2139       RETURN_IF_EMPTY_HANDLE(isolate,
   2140           JSObject::SetLocalPropertyIgnoreAttributes(
   2141               global, name, value, static_cast<PropertyAttributes>(attr)));
   2142     } else {
   2143       // Do a [[Put]] on the existing (own) property.
   2144       RETURN_IF_EMPTY_HANDLE(isolate,
   2145           JSObject::SetProperty(
   2146               global, name, value, static_cast<PropertyAttributes>(attr),
   2147               language_mode == CLASSIC_MODE ? kNonStrictMode : kStrictMode));
   2148     }
   2149   }
   2150 
   2151   ASSERT(!isolate->has_pending_exception());
   2152   return isolate->heap()->undefined_value();
   2153 }
   2154 
   2155 
   2156 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
   2157   HandleScope scope(isolate);
   2158   ASSERT(args.length() == 4);
   2159 
   2160   // Declarations are always made in a function or native context.  In the
   2161   // case of eval code, the context passed is the context of the caller,
   2162   // which may be some nested context and not the declaration context.
   2163   RUNTIME_ASSERT(args[0]->IsContext());
   2164   Handle<Context> context(Context::cast(args[0])->declaration_context());
   2165 
   2166   Handle<String> name(String::cast(args[1]));
   2167   PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
   2168   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
   2169   Handle<Object> initial_value(args[3], isolate);
   2170 
   2171   int index;
   2172   PropertyAttributes attributes;
   2173   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   2174   BindingFlags binding_flags;
   2175   Handle<Object> holder =
   2176       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2177 
   2178   if (attributes != ABSENT) {
   2179     // The name was declared before; check for conflicting re-declarations.
   2180     // Note: this is actually inconsistent with what happens for globals (where
   2181     // we silently ignore such declarations).
   2182     if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
   2183       // Functions are not read-only.
   2184       ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
   2185       const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
   2186       return ThrowRedeclarationError(isolate, type, name);
   2187     }
   2188 
   2189     // Initialize it if necessary.
   2190     if (*initial_value != NULL) {
   2191       if (index >= 0) {
   2192         ASSERT(holder.is_identical_to(context));
   2193         if (((attributes & READ_ONLY) == 0) ||
   2194             context->get(index)->IsTheHole()) {
   2195           context->set(index, *initial_value);
   2196         }
   2197       } else {
   2198         // Slow case: The property is in the context extension object of a
   2199         // function context or the global object of a native context.
   2200         Handle<JSObject> object = Handle<JSObject>::cast(holder);
   2201         RETURN_IF_EMPTY_HANDLE(
   2202             isolate,
   2203             JSReceiver::SetProperty(object, name, initial_value, mode,
   2204                                     kNonStrictMode));
   2205       }
   2206     }
   2207 
   2208   } else {
   2209     // The property is not in the function context. It needs to be
   2210     // "declared" in the function context's extension context or as a
   2211     // property of the the global object.
   2212     Handle<JSObject> object;
   2213     if (context->has_extension()) {
   2214       object = Handle<JSObject>(JSObject::cast(context->extension()));
   2215     } else {
   2216       // Context extension objects are allocated lazily.
   2217       ASSERT(context->IsFunctionContext());
   2218       object = isolate->factory()->NewJSObject(
   2219           isolate->context_extension_function());
   2220       context->set_extension(*object);
   2221     }
   2222     ASSERT(*object != NULL);
   2223 
   2224     // Declare the property by setting it to the initial value if provided,
   2225     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
   2226     // constant declarations).
   2227     ASSERT(!JSReceiver::HasLocalProperty(object, name));
   2228     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
   2229     if (*initial_value != NULL) value = initial_value;
   2230     // Declaring a const context slot is a conflicting declaration if
   2231     // there is a callback with that name in a prototype. It is
   2232     // allowed to introduce const variables in
   2233     // JSContextExtensionObjects. They are treated specially in
   2234     // SetProperty and no setters are invoked for those since they are
   2235     // not real JSObjects.
   2236     if (initial_value->IsTheHole() &&
   2237         !object->IsJSContextExtensionObject()) {
   2238       LookupResult lookup(isolate);
   2239       object->Lookup(*name, &lookup);
   2240       if (lookup.IsPropertyCallbacks()) {
   2241         return ThrowRedeclarationError(isolate, "const", name);
   2242       }
   2243     }
   2244     if (object->IsJSGlobalObject()) {
   2245       // Define own property on the global object.
   2246       RETURN_IF_EMPTY_HANDLE(isolate,
   2247          JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
   2248     } else {
   2249       RETURN_IF_EMPTY_HANDLE(isolate,
   2250          JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
   2251     }
   2252   }
   2253 
   2254   return isolate->heap()->undefined_value();
   2255 }
   2256 
   2257 
   2258 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
   2259   HandleScope scope(isolate);
   2260   // args[0] == name
   2261   // args[1] == language_mode
   2262   // args[2] == value (optional)
   2263 
   2264   // Determine if we need to assign to the variable if it already
   2265   // exists (based on the number of arguments).
   2266   RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
   2267   bool assign = args.length() == 3;
   2268 
   2269   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2270   RUNTIME_ASSERT(args[1]->IsSmi());
   2271   CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
   2272   StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
   2273       ? kNonStrictMode : kStrictMode;
   2274 
   2275   // According to ECMA-262, section 12.2, page 62, the property must
   2276   // not be deletable.
   2277   PropertyAttributes attributes = DONT_DELETE;
   2278 
   2279   // Lookup the property locally in the global object. If it isn't
   2280   // there, there is a property with this name in the prototype chain.
   2281   // We follow Safari and Firefox behavior and only set the property
   2282   // locally if there is an explicit initialization value that we have
   2283   // to assign to the property.
   2284   // Note that objects can have hidden prototypes, so we need to traverse
   2285   // the whole chain of hidden prototypes to do a 'local' lookup.
   2286   LookupResult lookup(isolate);
   2287   isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
   2288   if (lookup.IsInterceptor()) {
   2289     PropertyAttributes intercepted =
   2290         lookup.holder()->GetPropertyAttribute(*name);
   2291     if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
   2292       // Found an interceptor that's not read only.
   2293       if (assign) {
   2294         CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   2295         Handle<Object> result = JSObject::SetPropertyForResult(
   2296             handle(lookup.holder()), &lookup, name, value, attributes,
   2297             strict_mode_flag);
   2298         RETURN_IF_EMPTY_HANDLE(isolate, result);
   2299         return *result;
   2300       } else {
   2301         return isolate->heap()->undefined_value();
   2302       }
   2303     }
   2304   }
   2305 
   2306   if (assign) {
   2307     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   2308     Handle<GlobalObject> global(isolate->context()->global_object());
   2309     Handle<Object> result = JSReceiver::SetProperty(
   2310         global, name, value, attributes, strict_mode_flag);
   2311     RETURN_IF_EMPTY_HANDLE(isolate, result);
   2312     return *result;
   2313   }
   2314   return isolate->heap()->undefined_value();
   2315 }
   2316 
   2317 
   2318 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
   2319   SealHandleScope shs(isolate);
   2320   // All constants are declared with an initial value. The name
   2321   // of the constant is the first argument and the initial value
   2322   // is the second.
   2323   RUNTIME_ASSERT(args.length() == 2);
   2324   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2325   Handle<Object> value = args.at<Object>(1);
   2326 
   2327   // Get the current global object from top.
   2328   GlobalObject* global = isolate->context()->global_object();
   2329 
   2330   // According to ECMA-262, section 12.2, page 62, the property must
   2331   // not be deletable. Since it's a const, it must be READ_ONLY too.
   2332   PropertyAttributes attributes =
   2333       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
   2334 
   2335   // Lookup the property locally in the global object. If it isn't
   2336   // there, we add the property and take special precautions to always
   2337   // add it as a local property even in case of callbacks in the
   2338   // prototype chain (this rules out using SetProperty).
   2339   // We use SetLocalPropertyIgnoreAttributes instead
   2340   LookupResult lookup(isolate);
   2341   global->LocalLookup(*name, &lookup);
   2342   if (!lookup.IsFound()) {
   2343     HandleScope handle_scope(isolate);
   2344     Handle<GlobalObject> global(isolate->context()->global_object());
   2345     RETURN_IF_EMPTY_HANDLE(
   2346         isolate,
   2347         JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
   2348                                                    attributes));
   2349     return *value;
   2350   }
   2351 
   2352   if (!lookup.IsReadOnly()) {
   2353     // Restore global object from context (in case of GC) and continue
   2354     // with setting the value.
   2355     HandleScope handle_scope(isolate);
   2356     Handle<GlobalObject> global(isolate->context()->global_object());
   2357 
   2358     // BUG 1213575: Handle the case where we have to set a read-only
   2359     // property through an interceptor and only do it if it's
   2360     // uninitialized, e.g. the hole. Nirk...
   2361     // Passing non-strict mode because the property is writable.
   2362     RETURN_IF_EMPTY_HANDLE(
   2363         isolate,
   2364         JSReceiver::SetProperty(global, name, value, attributes,
   2365                                 kNonStrictMode));
   2366     return *value;
   2367   }
   2368 
   2369   // Set the value, but only if we're assigning the initial value to a
   2370   // constant. For now, we determine this by checking if the
   2371   // current value is the hole.
   2372   // Strict mode handling not needed (const is disallowed in strict mode).
   2373   if (lookup.IsField()) {
   2374     FixedArray* properties = global->properties();
   2375     int index = lookup.GetFieldIndex().field_index();
   2376     if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
   2377       properties->set(index, *value);
   2378     }
   2379   } else if (lookup.IsNormal()) {
   2380     if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
   2381         !lookup.IsReadOnly()) {
   2382       HandleScope scope(isolate);
   2383       JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
   2384     }
   2385   } else {
   2386     // Ignore re-initialization of constants that have already been
   2387     // assigned a constant value.
   2388     ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
   2389   }
   2390 
   2391   // Use the set value as the result of the operation.
   2392   return *value;
   2393 }
   2394 
   2395 
   2396 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
   2397   HandleScope scope(isolate);
   2398   ASSERT(args.length() == 3);
   2399 
   2400   Handle<Object> value(args[0], isolate);
   2401   ASSERT(!value->IsTheHole());
   2402 
   2403   // Initializations are always done in a function or native context.
   2404   RUNTIME_ASSERT(args[1]->IsContext());
   2405   Handle<Context> context(Context::cast(args[1])->declaration_context());
   2406 
   2407   Handle<String> name(String::cast(args[2]));
   2408 
   2409   int index;
   2410   PropertyAttributes attributes;
   2411   ContextLookupFlags flags = FOLLOW_CHAINS;
   2412   BindingFlags binding_flags;
   2413   Handle<Object> holder =
   2414       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2415 
   2416   if (index >= 0) {
   2417     ASSERT(holder->IsContext());
   2418     // Property was found in a context.  Perform the assignment if we
   2419     // found some non-constant or an uninitialized constant.
   2420     Handle<Context> context = Handle<Context>::cast(holder);
   2421     if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
   2422       context->set(index, *value);
   2423     }
   2424     return *value;
   2425   }
   2426 
   2427   // The property could not be found, we introduce it as a property of the
   2428   // global object.
   2429   if (attributes == ABSENT) {
   2430     Handle<JSObject> global = Handle<JSObject>(
   2431         isolate->context()->global_object());
   2432     // Strict mode not needed (const disallowed in strict mode).
   2433     RETURN_IF_EMPTY_HANDLE(
   2434         isolate,
   2435         JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode));
   2436     return *value;
   2437   }
   2438 
   2439   // The property was present in some function's context extension object,
   2440   // as a property on the subject of a with, or as a property of the global
   2441   // object.
   2442   //
   2443   // In most situations, eval-introduced consts should still be present in
   2444   // the context extension object.  However, because declaration and
   2445   // initialization are separate, the property might have been deleted
   2446   // before we reach the initialization point.
   2447   //
   2448   // Example:
   2449   //
   2450   //    function f() { eval("delete x; const x;"); }
   2451   //
   2452   // In that case, the initialization behaves like a normal assignment.
   2453   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   2454 
   2455   if (*object == context->extension()) {
   2456     // This is the property that was introduced by the const declaration.
   2457     // Set it if it hasn't been set before.  NOTE: We cannot use
   2458     // GetProperty() to get the current value as it 'unholes' the value.
   2459     LookupResult lookup(isolate);
   2460     object->LocalLookupRealNamedProperty(*name, &lookup);
   2461     ASSERT(lookup.IsFound());  // the property was declared
   2462     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
   2463 
   2464     if (lookup.IsField()) {
   2465       FixedArray* properties = object->properties();
   2466       int index = lookup.GetFieldIndex().field_index();
   2467       if (properties->get(index)->IsTheHole()) {
   2468         properties->set(index, *value);
   2469       }
   2470     } else if (lookup.IsNormal()) {
   2471       if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
   2472         JSObject::SetNormalizedProperty(object, &lookup, value);
   2473       }
   2474     } else {
   2475       // We should not reach here. Any real, named property should be
   2476       // either a field or a dictionary slot.
   2477       UNREACHABLE();
   2478     }
   2479   } else {
   2480     // The property was found on some other object.  Set it if it is not a
   2481     // read-only property.
   2482     if ((attributes & READ_ONLY) == 0) {
   2483       // Strict mode not needed (const disallowed in strict mode).
   2484       RETURN_IF_EMPTY_HANDLE(
   2485           isolate,
   2486           JSReceiver::SetProperty(object, name, value, attributes,
   2487                                   kNonStrictMode));
   2488     }
   2489   }
   2490 
   2491   return *value;
   2492 }
   2493 
   2494 
   2495 RUNTIME_FUNCTION(MaybeObject*,
   2496                  Runtime_OptimizeObjectForAddingMultipleProperties) {
   2497   HandleScope scope(isolate);
   2498   ASSERT(args.length() == 2);
   2499   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2500   CONVERT_SMI_ARG_CHECKED(properties, 1);
   2501   if (object->HasFastProperties()) {
   2502     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
   2503   }
   2504   return *object;
   2505 }
   2506 
   2507 
   2508 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
   2509   HandleScope scope(isolate);
   2510   ASSERT(args.length() == 4);
   2511   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2512   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   2513   // Due to the way the JS calls are constructed this must be less than the
   2514   // length of a string, i.e. it is always a Smi.  We check anyway for security.
   2515   CONVERT_SMI_ARG_CHECKED(index, 2);
   2516   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   2517   RUNTIME_ASSERT(index >= 0);
   2518   RUNTIME_ASSERT(index <= subject->length());
   2519   isolate->counters()->regexp_entry_runtime()->Increment();
   2520   Handle<Object> result = RegExpImpl::Exec(regexp,
   2521                                            subject,
   2522                                            index,
   2523                                            last_match_info);
   2524   RETURN_IF_EMPTY_HANDLE(isolate, result);
   2525   return *result;
   2526 }
   2527 
   2528 
   2529 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
   2530   SealHandleScope shs(isolate);
   2531   ASSERT(args.length() == 3);
   2532   CONVERT_SMI_ARG_CHECKED(elements_count, 0);
   2533   if (elements_count < 0 ||
   2534       elements_count > FixedArray::kMaxLength ||
   2535       !Smi::IsValid(elements_count)) {
   2536     return isolate->ThrowIllegalOperation();
   2537   }
   2538   Object* new_object;
   2539   { MaybeObject* maybe_new_object =
   2540         isolate->heap()->AllocateFixedArray(elements_count);
   2541     if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
   2542   }
   2543   FixedArray* elements = FixedArray::cast(new_object);
   2544   { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw(
   2545       JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
   2546     if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
   2547   }
   2548   {
   2549     DisallowHeapAllocation no_gc;
   2550     HandleScope scope(isolate);
   2551     reinterpret_cast<HeapObject*>(new_object)->
   2552         set_map(isolate->native_context()->regexp_result_map());
   2553   }
   2554   JSArray* array = JSArray::cast(new_object);
   2555   array->set_properties(isolate->heap()->empty_fixed_array());
   2556   array->set_elements(elements);
   2557   array->set_length(Smi::FromInt(elements_count));
   2558   // Write in-object properties after the length of the array.
   2559   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
   2560   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
   2561   return array;
   2562 }
   2563 
   2564 
   2565 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
   2566   HandleScope scope(isolate);
   2567   DisallowHeapAllocation no_allocation;
   2568   ASSERT(args.length() == 5);
   2569   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2570   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   2571   // If source is the empty string we set it to "(?:)" instead as
   2572   // suggested by ECMA-262, 5th, section 15.10.4.1.
   2573   if (source->length() == 0) source = isolate->factory()->query_colon_string();
   2574 
   2575   CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
   2576   if (!global->IsTrue()) global = isolate->factory()->false_value();
   2577 
   2578   CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
   2579   if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
   2580 
   2581   CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
   2582   if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
   2583 
   2584   Map* map = regexp->map();
   2585   Object* constructor = map->constructor();
   2586   if (constructor->IsJSFunction() &&
   2587       JSFunction::cast(constructor)->initial_map() == map) {
   2588     // If we still have the original map, set in-object properties directly.
   2589     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
   2590     // Both true and false are immovable immortal objects so no need for write
   2591     // barrier.
   2592     regexp->InObjectPropertyAtPut(
   2593         JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
   2594     regexp->InObjectPropertyAtPut(
   2595         JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
   2596     regexp->InObjectPropertyAtPut(
   2597         JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
   2598     regexp->InObjectPropertyAtPut(
   2599         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
   2600     return *regexp;
   2601   }
   2602 
   2603   // Map has changed, so use generic, but slower, method.
   2604   PropertyAttributes final =
   2605       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
   2606   PropertyAttributes writable =
   2607       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
   2608   Handle<Object> zero(Smi::FromInt(0), isolate);
   2609   Factory* factory = isolate->factory();
   2610   CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
   2611       regexp, factory->source_string(), source, final));
   2612   CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
   2613       regexp, factory->global_string(), global, final));
   2614   CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
   2615       regexp, factory->ignore_case_string(), ignoreCase, final));
   2616   CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
   2617       regexp, factory->multiline_string(), multiline, final));
   2618   CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
   2619       regexp, factory->last_index_string(), zero, writable));
   2620   return *regexp;
   2621 }
   2622 
   2623 
   2624 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
   2625   HandleScope scope(isolate);
   2626   ASSERT(args.length() == 1);
   2627   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
   2628   // This is necessary to enable fast checks for absence of elements
   2629   // on Array.prototype and below.
   2630   prototype->set_elements(isolate->heap()->empty_fixed_array());
   2631   return Smi::FromInt(0);
   2632 }
   2633 
   2634 
   2635 static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
   2636                                          Handle<JSObject> holder,
   2637                                          const char* name,
   2638                                          Builtins::Name builtin_name) {
   2639   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
   2640   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
   2641   Handle<JSFunction> optimized =
   2642       isolate->factory()->NewFunction(key,
   2643                                       JS_OBJECT_TYPE,
   2644                                       JSObject::kHeaderSize,
   2645                                       code,
   2646                                       false);
   2647   optimized->shared()->DontAdaptArguments();
   2648   JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode);
   2649   return optimized;
   2650 }
   2651 
   2652 
   2653 RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
   2654   HandleScope scope(isolate);
   2655   ASSERT(args.length() == 1);
   2656   CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
   2657 
   2658   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
   2659   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
   2660   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
   2661   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
   2662   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
   2663   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
   2664   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
   2665 
   2666   return *holder;
   2667 }
   2668 
   2669 
   2670 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsCallable) {
   2671   SealHandleScope shs(isolate);
   2672   ASSERT(args.length() == 1);
   2673   CONVERT_ARG_CHECKED(Object, obj, 0);
   2674   return isolate->heap()->ToBoolean(obj->IsCallable());
   2675 }
   2676 
   2677 
   2678 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsClassicModeFunction) {
   2679   SealHandleScope shs(isolate);
   2680   ASSERT(args.length() == 1);
   2681   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2682   if (!callable->IsJSFunction()) {
   2683     HandleScope scope(isolate);
   2684     bool threw = false;
   2685     Handle<Object> delegate = Execution::TryGetFunctionDelegate(
   2686         isolate, Handle<JSReceiver>(callable), &threw);
   2687     if (threw) return Failure::Exception();
   2688     callable = JSFunction::cast(*delegate);
   2689   }
   2690   JSFunction* function = JSFunction::cast(callable);
   2691   SharedFunctionInfo* shared = function->shared();
   2692   return isolate->heap()->ToBoolean(shared->is_classic_mode());
   2693 }
   2694 
   2695 
   2696 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
   2697   SealHandleScope shs(isolate);
   2698   ASSERT(args.length() == 1);
   2699   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2700 
   2701   if (!callable->IsJSFunction()) {
   2702     HandleScope scope(isolate);
   2703     bool threw = false;
   2704     Handle<Object> delegate = Execution::TryGetFunctionDelegate(
   2705         isolate, Handle<JSReceiver>(callable), &threw);
   2706     if (threw) return Failure::Exception();
   2707     callable = JSFunction::cast(*delegate);
   2708   }
   2709   JSFunction* function = JSFunction::cast(callable);
   2710 
   2711   SharedFunctionInfo* shared = function->shared();
   2712   if (shared->native() || !shared->is_classic_mode()) {
   2713     return isolate->heap()->undefined_value();
   2714   }
   2715   // Returns undefined for strict or native functions, or
   2716   // the associated global receiver for "normal" functions.
   2717 
   2718   Context* native_context =
   2719       function->context()->global_object()->native_context();
   2720   return native_context->global_object()->global_receiver();
   2721 }
   2722 
   2723 
   2724 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
   2725   HandleScope scope(isolate);
   2726   ASSERT(args.length() == 4);
   2727   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
   2728   int index = args.smi_at(1);
   2729   Handle<String> pattern = args.at<String>(2);
   2730   Handle<String> flags = args.at<String>(3);
   2731 
   2732   // Get the RegExp function from the context in the literals array.
   2733   // This is the RegExp function from the context in which the
   2734   // function was created.  We do not use the RegExp function from the
   2735   // current native context because this might be the RegExp function
   2736   // from another context which we should not have access to.
   2737   Handle<JSFunction> constructor =
   2738       Handle<JSFunction>(
   2739           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
   2740   // Compute the regular expression literal.
   2741   bool has_pending_exception;
   2742   Handle<Object> regexp =
   2743       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags,
   2744                                       &has_pending_exception);
   2745   if (has_pending_exception) {
   2746     ASSERT(isolate->has_pending_exception());
   2747     return Failure::Exception();
   2748   }
   2749   literals->set(index, *regexp);
   2750   return *regexp;
   2751 }
   2752 
   2753 
   2754 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetName) {
   2755   SealHandleScope shs(isolate);
   2756   ASSERT(args.length() == 1);
   2757 
   2758   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2759   return f->shared()->name();
   2760 }
   2761 
   2762 
   2763 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
   2764   SealHandleScope shs(isolate);
   2765   ASSERT(args.length() == 2);
   2766 
   2767   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2768   CONVERT_ARG_CHECKED(String, name, 1);
   2769   f->shared()->set_name(name);
   2770   return isolate->heap()->undefined_value();
   2771 }
   2772 
   2773 
   2774 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
   2775   SealHandleScope shs(isolate);
   2776   ASSERT(args.length() == 1);
   2777   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2778   return isolate->heap()->ToBoolean(
   2779       f->shared()->name_should_print_as_anonymous());
   2780 }
   2781 
   2782 
   2783 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
   2784   SealHandleScope shs(isolate);
   2785   ASSERT(args.length() == 1);
   2786   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2787   f->shared()->set_name_should_print_as_anonymous(true);
   2788   return isolate->heap()->undefined_value();
   2789 }
   2790 
   2791 
   2792 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsGenerator) {
   2793   SealHandleScope shs(isolate);
   2794   ASSERT(args.length() == 1);
   2795   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2796   return isolate->heap()->ToBoolean(f->shared()->is_generator());
   2797 }
   2798 
   2799 
   2800 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
   2801   SealHandleScope shs(isolate);
   2802   ASSERT(args.length() == 1);
   2803 
   2804   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2805   f->RemovePrototype();
   2806 
   2807   return isolate->heap()->undefined_value();
   2808 }
   2809 
   2810 
   2811 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScript) {
   2812   HandleScope scope(isolate);
   2813   ASSERT(args.length() == 1);
   2814 
   2815   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2816   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
   2817   if (!script->IsScript()) return isolate->heap()->undefined_value();
   2818 
   2819   return *GetScriptWrapper(Handle<Script>::cast(script));
   2820 }
   2821 
   2822 
   2823 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetSourceCode) {
   2824   HandleScope scope(isolate);
   2825   ASSERT(args.length() == 1);
   2826 
   2827   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
   2828   Handle<SharedFunctionInfo> shared(f->shared());
   2829   return *shared->GetSourceCode();
   2830 }
   2831 
   2832 
   2833 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScriptSourcePosition) {
   2834   SealHandleScope shs(isolate);
   2835   ASSERT(args.length() == 1);
   2836 
   2837   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2838   int pos = fun->shared()->start_position();
   2839   return Smi::FromInt(pos);
   2840 }
   2841 
   2842 
   2843 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
   2844   SealHandleScope shs(isolate);
   2845   ASSERT(args.length() == 2);
   2846 
   2847   CONVERT_ARG_CHECKED(Code, code, 0);
   2848   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
   2849 
   2850   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
   2851 
   2852   Address pc = code->address() + offset;
   2853   return Smi::FromInt(code->SourcePosition(pc));
   2854 }
   2855 
   2856 
   2857 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetInstanceClassName) {
   2858   SealHandleScope shs(isolate);
   2859   ASSERT(args.length() == 2);
   2860 
   2861   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2862   CONVERT_ARG_CHECKED(String, name, 1);
   2863   fun->SetInstanceClassName(name);
   2864   return isolate->heap()->undefined_value();
   2865 }
   2866 
   2867 
   2868 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
   2869   SealHandleScope shs(isolate);
   2870   ASSERT(args.length() == 2);
   2871 
   2872   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2873   CONVERT_SMI_ARG_CHECKED(length, 1);
   2874   fun->shared()->set_length(length);
   2875   return isolate->heap()->undefined_value();
   2876 }
   2877 
   2878 
   2879 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
   2880   HandleScope scope(isolate);
   2881   ASSERT(args.length() == 2);
   2882 
   2883   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   2884   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
   2885   ASSERT(fun->should_have_prototype());
   2886   Accessors::FunctionSetPrototype(fun, value);
   2887   return args[0];  // return TOS
   2888 }
   2889 
   2890 
   2891 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
   2892   SealHandleScope shs(isolate);
   2893   RUNTIME_ASSERT(args.length() == 1);
   2894   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   2895 
   2896   String* name = isolate->heap()->prototype_string();
   2897 
   2898   if (function->HasFastProperties()) {
   2899     // Construct a new field descriptor with updated attributes.
   2900     DescriptorArray* instance_desc = function->map()->instance_descriptors();
   2901 
   2902     int index = instance_desc->SearchWithCache(name, function->map());
   2903     ASSERT(index != DescriptorArray::kNotFound);
   2904     PropertyDetails details = instance_desc->GetDetails(index);
   2905 
   2906     CallbacksDescriptor new_desc(name,
   2907         instance_desc->GetValue(index),
   2908         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
   2909 
   2910     // Create a new map featuring the new field descriptors array.
   2911     Map* new_map;
   2912     MaybeObject* maybe_map =
   2913         function->map()->CopyReplaceDescriptor(
   2914             instance_desc, &new_desc, index, OMIT_TRANSITION);
   2915     if (!maybe_map->To(&new_map)) return maybe_map;
   2916 
   2917     function->set_map(new_map);
   2918   } else {  // Dictionary properties.
   2919     // Directly manipulate the property details.
   2920     int entry = function->property_dictionary()->FindEntry(name);
   2921     ASSERT(entry != NameDictionary::kNotFound);
   2922     PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
   2923     PropertyDetails new_details(
   2924         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
   2925         details.type(),
   2926         details.dictionary_index());
   2927     function->property_dictionary()->DetailsAtPut(entry, new_details);
   2928   }
   2929   return function;
   2930 }
   2931 
   2932 
   2933 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
   2934   SealHandleScope shs(isolate);
   2935   ASSERT(args.length() == 1);
   2936 
   2937   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2938   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
   2939 }
   2940 
   2941 
   2942 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
   2943   SealHandleScope shs(isolate);
   2944   ASSERT(args.length() == 1);
   2945 
   2946   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2947   return isolate->heap()->ToBoolean(f->IsBuiltin());
   2948 }
   2949 
   2950 
   2951 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
   2952   HandleScope scope(isolate);
   2953   ASSERT(args.length() == 2);
   2954 
   2955   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
   2956   Handle<Object> code = args.at<Object>(1);
   2957 
   2958   if (code->IsNull()) return *target;
   2959   RUNTIME_ASSERT(code->IsJSFunction());
   2960   Handle<JSFunction> source = Handle<JSFunction>::cast(code);
   2961   Handle<SharedFunctionInfo> target_shared(target->shared());
   2962   Handle<SharedFunctionInfo> source_shared(source->shared());
   2963 
   2964   if (!JSFunction::EnsureCompiled(source, KEEP_EXCEPTION)) {
   2965     return Failure::Exception();
   2966   }
   2967 
   2968   // Mark both, the source and the target, as un-flushable because the
   2969   // shared unoptimized code makes them impossible to enqueue in a list.
   2970   ASSERT(target_shared->code()->gc_metadata() == NULL);
   2971   ASSERT(source_shared->code()->gc_metadata() == NULL);
   2972   target_shared->set_dont_flush(true);
   2973   source_shared->set_dont_flush(true);
   2974 
   2975   // Set the code, scope info, formal parameter count, and the length
   2976   // of the target shared function info.
   2977   target_shared->ReplaceCode(source_shared->code());
   2978   target_shared->set_scope_info(source_shared->scope_info());
   2979   target_shared->set_length(source_shared->length());
   2980   target_shared->set_formal_parameter_count(
   2981       source_shared->formal_parameter_count());
   2982   target_shared->set_script(source_shared->script());
   2983   target_shared->set_start_position_and_type(
   2984       source_shared->start_position_and_type());
   2985   target_shared->set_end_position(source_shared->end_position());
   2986   bool was_native = target_shared->native();
   2987   target_shared->set_compiler_hints(source_shared->compiler_hints());
   2988   target_shared->set_native(was_native);
   2989 
   2990   // Set the code of the target function.
   2991   target->ReplaceCode(source_shared->code());
   2992   ASSERT(target->next_function_link()->IsUndefined());
   2993 
   2994   // Make sure we get a fresh copy of the literal vector to avoid cross
   2995   // context contamination.
   2996   Handle<Context> context(source->context());
   2997   int number_of_literals = source->NumberOfLiterals();
   2998   Handle<FixedArray> literals =
   2999       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
   3000   if (number_of_literals > 0) {
   3001     literals->set(JSFunction::kLiteralNativeContextIndex,
   3002                   context->native_context());
   3003   }
   3004   target->set_context(*context);
   3005   target->set_literals(*literals);
   3006 
   3007   if (isolate->logger()->is_logging_code_events() ||
   3008       isolate->cpu_profiler()->is_profiling()) {
   3009     isolate->logger()->LogExistingFunction(
   3010         source_shared, Handle<Code>(source_shared->code()));
   3011   }
   3012 
   3013   return *target;
   3014 }
   3015 
   3016 
   3017 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
   3018   HandleScope scope(isolate);
   3019   ASSERT(args.length() == 2);
   3020   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   3021   CONVERT_SMI_ARG_CHECKED(num, 1);
   3022   RUNTIME_ASSERT(num >= 0);
   3023   // If objects constructed from this function exist then changing
   3024   // 'estimated_nof_properties' is dangerous since the previous value might
   3025   // have been compiled into the fast construct stub. Moreover, the inobject
   3026   // slack tracking logic might have adjusted the previous value, so even
   3027   // passing the same value is risky.
   3028   if (!func->shared()->live_objects_may_exist()) {
   3029     func->shared()->set_expected_nof_properties(num);
   3030     if (func->has_initial_map()) {
   3031       Handle<Map> new_initial_map =
   3032           func->GetIsolate()->factory()->CopyMap(
   3033               Handle<Map>(func->initial_map()));
   3034       new_initial_map->set_unused_property_fields(num);
   3035       func->set_initial_map(*new_initial_map);
   3036     }
   3037   }
   3038   return isolate->heap()->undefined_value();
   3039 }
   3040 
   3041 
   3042 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
   3043   HandleScope scope(isolate);
   3044   ASSERT(args.length() == 0);
   3045 
   3046   JavaScriptFrameIterator it(isolate);
   3047   JavaScriptFrame* frame = it.frame();
   3048   Handle<JSFunction> function(frame->function());
   3049   RUNTIME_ASSERT(function->shared()->is_generator());
   3050 
   3051   Handle<JSGeneratorObject> generator;
   3052   if (frame->IsConstructor()) {
   3053     generator = handle(JSGeneratorObject::cast(frame->receiver()));
   3054   } else {
   3055     generator = isolate->factory()->NewJSGeneratorObject(function);
   3056   }
   3057   generator->set_function(*function);
   3058   generator->set_context(Context::cast(frame->context()));
   3059   generator->set_receiver(frame->receiver());
   3060   generator->set_continuation(0);
   3061   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
   3062   generator->set_stack_handler_index(-1);
   3063 
   3064   return *generator;
   3065 }
   3066 
   3067 
   3068 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) {
   3069   SealHandleScope shs(isolate);
   3070   ASSERT(args.length() == 1);
   3071   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
   3072 
   3073   JavaScriptFrameIterator stack_iterator(isolate);
   3074   JavaScriptFrame* frame = stack_iterator.frame();
   3075   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
   3076   ASSERT_EQ(frame->function(), generator_object->function());
   3077 
   3078   // The caller should have saved the context and continuation already.
   3079   ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
   3080   ASSERT_LT(0, generator_object->continuation());
   3081 
   3082   // We expect there to be at least two values on the operand stack: the return
   3083   // value of the yield expression, and the argument to this runtime call.
   3084   // Neither of those should be saved.
   3085   int operands_count = frame->ComputeOperandsCount();
   3086   ASSERT_GE(operands_count, 2);
   3087   operands_count -= 2;
   3088 
   3089   if (operands_count == 0) {
   3090     // Although it's semantically harmless to call this function with an
   3091     // operands_count of zero, it is also unnecessary.
   3092     ASSERT_EQ(generator_object->operand_stack(),
   3093               isolate->heap()->empty_fixed_array());
   3094     ASSERT_EQ(generator_object->stack_handler_index(), -1);
   3095     // If there are no operands on the stack, there shouldn't be a handler
   3096     // active either.
   3097     ASSERT(!frame->HasHandler());
   3098   } else {
   3099     int stack_handler_index = -1;
   3100     MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count);
   3101     FixedArray* operand_stack;
   3102     if (!alloc->To(&operand_stack)) return alloc;
   3103     frame->SaveOperandStack(operand_stack, &stack_handler_index);
   3104     generator_object->set_operand_stack(operand_stack);
   3105     generator_object->set_stack_handler_index(stack_handler_index);
   3106   }
   3107 
   3108   return isolate->heap()->undefined_value();
   3109 }
   3110 
   3111 
   3112 // Note that this function is the slow path for resuming generators.  It is only
   3113 // called if the suspended activation had operands on the stack, stack handlers
   3114 // needing rewinding, or if the resume should throw an exception.  The fast path
   3115 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
   3116 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
   3117 // called in any case, as it needs to reconstruct the stack frame and make space
   3118 // for arguments and operands.
   3119 RUNTIME_FUNCTION(MaybeObject*, Runtime_ResumeJSGeneratorObject) {
   3120   SealHandleScope shs(isolate);
   3121   ASSERT(args.length() == 3);
   3122   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
   3123   CONVERT_ARG_CHECKED(Object, value, 1);
   3124   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
   3125   JavaScriptFrameIterator stack_iterator(isolate);
   3126   JavaScriptFrame* frame = stack_iterator.frame();
   3127 
   3128   ASSERT_EQ(frame->function(), generator_object->function());
   3129   ASSERT(frame->function()->is_compiled());
   3130 
   3131   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0);
   3132   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0);
   3133 
   3134   Address pc = generator_object->function()->code()->instruction_start();
   3135   int offset = generator_object->continuation();
   3136   ASSERT(offset > 0);
   3137   frame->set_pc(pc + offset);
   3138   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
   3139 
   3140   FixedArray* operand_stack = generator_object->operand_stack();
   3141   int operands_count = operand_stack->length();
   3142   if (operands_count != 0) {
   3143     frame->RestoreOperandStack(operand_stack,
   3144                                generator_object->stack_handler_index());
   3145     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
   3146     generator_object->set_stack_handler_index(-1);
   3147   }
   3148 
   3149   JSGeneratorObject::ResumeMode resume_mode =
   3150       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
   3151   switch (resume_mode) {
   3152     case JSGeneratorObject::NEXT:
   3153       return value;
   3154     case JSGeneratorObject::THROW:
   3155       return isolate->Throw(value);
   3156   }
   3157 
   3158   UNREACHABLE();
   3159   return isolate->ThrowIllegalOperation();
   3160 }
   3161 
   3162 
   3163 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowGeneratorStateError) {
   3164   HandleScope scope(isolate);
   3165   ASSERT(args.length() == 1);
   3166   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   3167   int continuation = generator->continuation();
   3168   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
   3169       "generator_finished" : "generator_running";
   3170   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
   3171   Handle<Object> error = isolate->factory()->NewError(message, argv);
   3172   return isolate->Throw(*error);
   3173 }
   3174 
   3175 
   3176 RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) {
   3177   HandleScope scope(isolate);
   3178   ASSERT(args.length() == 1);
   3179   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   3180   Handle<Object> result = JSObject::Freeze(object);
   3181   RETURN_IF_EMPTY_HANDLE(isolate, result);
   3182   return *result;
   3183 }
   3184 
   3185 
   3186 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
   3187                                                  Object* char_code) {
   3188   if (char_code->IsNumber()) {
   3189     return isolate->heap()->LookupSingleCharacterStringFromCode(
   3190         NumberToUint32(char_code) & 0xffff);
   3191   }
   3192   return isolate->heap()->empty_string();
   3193 }
   3194 
   3195 
   3196 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAt) {
   3197   SealHandleScope shs(isolate);
   3198   ASSERT(args.length() == 2);
   3199 
   3200   CONVERT_ARG_CHECKED(String, subject, 0);
   3201   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
   3202 
   3203   // Flatten the string.  If someone wants to get a char at an index
   3204   // in a cons string, it is likely that more indices will be
   3205   // accessed.
   3206   Object* flat;
   3207   { MaybeObject* maybe_flat = subject->TryFlatten();
   3208     if (!maybe_flat->ToObject(&flat)) return maybe_flat;
   3209   }
   3210   subject = String::cast(flat);
   3211 
   3212   if (i >= static_cast<uint32_t>(subject->length())) {
   3213     return isolate->heap()->nan_value();
   3214   }
   3215 
   3216   return Smi::FromInt(subject->Get(i));
   3217 }
   3218 
   3219 
   3220 RUNTIME_FUNCTION(MaybeObject*, Runtime_CharFromCode) {
   3221   SealHandleScope shs(isolate);
   3222   ASSERT(args.length() == 1);
   3223   return CharFromCode(isolate, args[0]);
   3224 }
   3225 
   3226 
   3227 class FixedArrayBuilder {
   3228  public:
   3229   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
   3230       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
   3231         length_(0),
   3232         has_non_smi_elements_(false) {
   3233     // Require a non-zero initial size. Ensures that doubling the size to
   3234     // extend the array will work.
   3235     ASSERT(initial_capacity > 0);
   3236   }
   3237 
   3238   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
   3239       : array_(backing_store),
   3240         length_(0),
   3241         has_non_smi_elements_(false) {
   3242     // Require a non-zero initial size. Ensures that doubling the size to
   3243     // extend the array will work.
   3244     ASSERT(backing_store->length() > 0);
   3245   }
   3246 
   3247   bool HasCapacity(int elements) {
   3248     int length = array_->length();
   3249     int required_length = length_ + elements;
   3250     return (length >= required_length);
   3251   }
   3252 
   3253   void EnsureCapacity(int elements) {
   3254     int length = array_->length();
   3255     int required_length = length_ + elements;
   3256     if (length < required_length) {
   3257       int new_length = length;
   3258       do {
   3259         new_length *= 2;
   3260       } while (new_length < required_length);
   3261       Handle<FixedArray> extended_array =
   3262           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
   3263       array_->CopyTo(0, *extended_array, 0, length_);
   3264       array_ = extended_array;
   3265     }
   3266   }
   3267 
   3268   void Add(Object* value) {
   3269     ASSERT(!value->IsSmi());
   3270     ASSERT(length_ < capacity());
   3271     array_->set(length_, value);
   3272     length_++;
   3273     has_non_smi_elements_ = true;
   3274   }
   3275 
   3276   void Add(Smi* value) {
   3277     ASSERT(value->IsSmi());
   3278     ASSERT(length_ < capacity());
   3279     array_->set(length_, value);
   3280     length_++;
   3281   }
   3282 
   3283   Handle<FixedArray> array() {
   3284     return array_;
   3285   }
   3286 
   3287   int length() {
   3288     return length_;
   3289   }
   3290 
   3291   int capacity() {
   3292     return array_->length();
   3293   }
   3294 
   3295   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
   3296     Factory* factory = target_array->GetIsolate()->factory();
   3297     factory->SetContent(target_array, array_);
   3298     target_array->set_length(Smi::FromInt(length_));
   3299     return target_array;
   3300   }
   3301 
   3302 
   3303  private:
   3304   Handle<FixedArray> array_;
   3305   int length_;
   3306   bool has_non_smi_elements_;
   3307 };
   3308 
   3309 
   3310 // Forward declarations.
   3311 const int kStringBuilderConcatHelperLengthBits = 11;
   3312 const int kStringBuilderConcatHelperPositionBits = 19;
   3313 
   3314 template <typename schar>
   3315 static inline void StringBuilderConcatHelper(String*,
   3316                                              schar*,
   3317                                              FixedArray*,
   3318                                              int);
   3319 
   3320 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
   3321     StringBuilderSubstringLength;
   3322 typedef BitField<int,
   3323                  kStringBuilderConcatHelperLengthBits,
   3324                  kStringBuilderConcatHelperPositionBits>
   3325     StringBuilderSubstringPosition;
   3326 
   3327 
   3328 class ReplacementStringBuilder {
   3329  public:
   3330   ReplacementStringBuilder(Heap* heap,
   3331                            Handle<String> subject,
   3332                            int estimated_part_count)
   3333       : heap_(heap),
   3334         array_builder_(heap->isolate(), estimated_part_count),
   3335         subject_(subject),
   3336         character_count_(0),
   3337         is_ascii_(subject->IsOneByteRepresentation()) {
   3338     // Require a non-zero initial size. Ensures that doubling the size to
   3339     // extend the array will work.
   3340     ASSERT(estimated_part_count > 0);
   3341   }
   3342 
   3343   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
   3344                                      int from,
   3345                                      int to) {
   3346     ASSERT(from >= 0);
   3347     int length = to - from;
   3348     ASSERT(length > 0);
   3349     if (StringBuilderSubstringLength::is_valid(length) &&
   3350         StringBuilderSubstringPosition::is_valid(from)) {
   3351       int encoded_slice = StringBuilderSubstringLength::encode(length) |
   3352           StringBuilderSubstringPosition::encode(from);
   3353       builder->Add(Smi::FromInt(encoded_slice));
   3354     } else {
   3355       // Otherwise encode as two smis.
   3356       builder->Add(Smi::FromInt(-length));
   3357       builder->Add(Smi::FromInt(from));
   3358     }
   3359   }
   3360 
   3361 
   3362   void EnsureCapacity(int elements) {
   3363     array_builder_.EnsureCapacity(elements);
   3364   }
   3365 
   3366 
   3367   void AddSubjectSlice(int from, int to) {
   3368     AddSubjectSlice(&array_builder_, from, to);
   3369     IncrementCharacterCount(to - from);
   3370   }
   3371 
   3372 
   3373   void AddString(Handle<String> string) {
   3374     int length = string->length();
   3375     ASSERT(length > 0);
   3376     AddElement(*string);
   3377     if (!string->IsOneByteRepresentation()) {
   3378       is_ascii_ = false;
   3379     }
   3380     IncrementCharacterCount(length);
   3381   }
   3382 
   3383 
   3384   Handle<String> ToString() {
   3385     if (array_builder_.length() == 0) {
   3386       return heap_->isolate()->factory()->empty_string();
   3387     }
   3388 
   3389     Handle<String> joined_string;
   3390     if (is_ascii_) {
   3391       Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_);
   3392       DisallowHeapAllocation no_gc;
   3393       uint8_t* char_buffer = seq->GetChars();
   3394       StringBuilderConcatHelper(*subject_,
   3395                                 char_buffer,
   3396                                 *array_builder_.array(),
   3397                                 array_builder_.length());
   3398       joined_string = Handle<String>::cast(seq);
   3399     } else {
   3400       // Non-ASCII.
   3401       Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
   3402       DisallowHeapAllocation no_gc;
   3403       uc16* char_buffer = seq->GetChars();
   3404       StringBuilderConcatHelper(*subject_,
   3405                                 char_buffer,
   3406                                 *array_builder_.array(),
   3407                                 array_builder_.length());
   3408       joined_string = Handle<String>::cast(seq);
   3409     }
   3410     return joined_string;
   3411   }
   3412 
   3413 
   3414   void IncrementCharacterCount(int by) {
   3415     if (character_count_ > String::kMaxLength - by) {
   3416       V8::FatalProcessOutOfMemory("String.replace result too large.");
   3417     }
   3418     character_count_ += by;
   3419   }
   3420 
   3421  private:
   3422   Handle<SeqOneByteString> NewRawOneByteString(int length) {
   3423     return heap_->isolate()->factory()->NewRawOneByteString(length);
   3424   }
   3425 
   3426 
   3427   Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
   3428     return heap_->isolate()->factory()->NewRawTwoByteString(length);
   3429   }
   3430 
   3431 
   3432   void AddElement(Object* element) {
   3433     ASSERT(element->IsSmi() || element->IsString());
   3434     ASSERT(array_builder_.capacity() > array_builder_.length());
   3435     array_builder_.Add(element);
   3436   }
   3437 
   3438   Heap* heap_;
   3439   FixedArrayBuilder array_builder_;
   3440   Handle<String> subject_;
   3441   int character_count_;
   3442   bool is_ascii_;
   3443 };
   3444 
   3445 
   3446 class CompiledReplacement {
   3447  public:
   3448   explicit CompiledReplacement(Zone* zone)
   3449       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
   3450 
   3451   // Return whether the replacement is simple.
   3452   bool Compile(Handle<String> replacement,
   3453                int capture_count,
   3454                int subject_length);
   3455 
   3456   // Use Apply only if Compile returned false.
   3457   void Apply(ReplacementStringBuilder* builder,
   3458              int match_from,
   3459              int match_to,
   3460              int32_t* match);
   3461 
   3462   // Number of distinct parts of the replacement pattern.
   3463   int parts() {
   3464     return parts_.length();
   3465   }
   3466 
   3467   Zone* zone() const { return zone_; }
   3468 
   3469  private:
   3470   enum PartType {
   3471     SUBJECT_PREFIX = 1,
   3472     SUBJECT_SUFFIX,
   3473     SUBJECT_CAPTURE,
   3474     REPLACEMENT_SUBSTRING,
   3475     REPLACEMENT_STRING,
   3476 
   3477     NUMBER_OF_PART_TYPES
   3478   };
   3479 
   3480   struct ReplacementPart {
   3481     static inline ReplacementPart SubjectMatch() {
   3482       return ReplacementPart(SUBJECT_CAPTURE, 0);
   3483     }
   3484     static inline ReplacementPart SubjectCapture(int capture_index) {
   3485       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
   3486     }
   3487     static inline ReplacementPart SubjectPrefix() {
   3488       return ReplacementPart(SUBJECT_PREFIX, 0);
   3489     }
   3490     static inline ReplacementPart SubjectSuffix(int subject_length) {
   3491       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
   3492     }
   3493     static inline ReplacementPart ReplacementString() {
   3494       return ReplacementPart(REPLACEMENT_STRING, 0);
   3495     }
   3496     static inline ReplacementPart ReplacementSubString(int from, int to) {
   3497       ASSERT(from >= 0);
   3498       ASSERT(to > from);
   3499       return ReplacementPart(-from, to);
   3500     }
   3501 
   3502     // If tag <= 0 then it is the negation of a start index of a substring of
   3503     // the replacement pattern, otherwise it's a value from PartType.
   3504     ReplacementPart(int tag, int data)
   3505         : tag(tag), data(data) {
   3506       // Must be non-positive or a PartType value.
   3507       ASSERT(tag < NUMBER_OF_PART_TYPES);
   3508     }
   3509     // Either a value of PartType or a non-positive number that is
   3510     // the negation of an index into the replacement string.
   3511     int tag;
   3512     // The data value's interpretation depends on the value of tag:
   3513     // tag == SUBJECT_PREFIX ||
   3514     // tag == SUBJECT_SUFFIX:  data is unused.
   3515     // tag == SUBJECT_CAPTURE: data is the number of the capture.
   3516     // tag == REPLACEMENT_SUBSTRING ||
   3517     // tag == REPLACEMENT_STRING:    data is index into array of substrings
   3518     //                               of the replacement string.
   3519     // tag <= 0: Temporary representation of the substring of the replacement
   3520     //           string ranging over -tag .. data.
   3521     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
   3522     //           substring objects.
   3523     int data;
   3524   };
   3525 
   3526   template<typename Char>
   3527   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
   3528                                Vector<Char> characters,
   3529                                int capture_count,
   3530                                int subject_length,
   3531                                Zone* zone) {
   3532     int length = characters.length();
   3533     int last = 0;
   3534     for (int i = 0; i < length; i++) {
   3535       Char c = characters[i];
   3536       if (c == '$') {
   3537         int next_index = i + 1;
   3538         if (next_index == length) {  // No next character!
   3539           break;
   3540         }
   3541         Char c2 = characters[next_index];
   3542         switch (c2) {
   3543         case '$':
   3544           if (i > last) {
   3545             // There is a substring before. Include the first "$".
   3546             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
   3547                        zone);
   3548             last = next_index + 1;  // Continue after the second "$".
   3549           } else {
   3550             // Let the next substring start with the second "$".
   3551             last = next_index;
   3552           }
   3553           i = next_index;
   3554           break;
   3555         case '`':
   3556           if (i > last) {
   3557             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3558           }
   3559           parts->Add(ReplacementPart::SubjectPrefix(), zone);
   3560           i = next_index;
   3561           last = i + 1;
   3562           break;
   3563         case '\'':
   3564           if (i > last) {
   3565             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3566           }
   3567           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
   3568           i = next_index;
   3569           last = i + 1;
   3570           break;
   3571         case '&':
   3572           if (i > last) {
   3573             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3574           }
   3575           parts->Add(ReplacementPart::SubjectMatch(), zone);
   3576           i = next_index;
   3577           last = i + 1;
   3578           break;
   3579         case '0':
   3580         case '1':
   3581         case '2':
   3582         case '3':
   3583         case '4':
   3584         case '5':
   3585         case '6':
   3586         case '7':
   3587         case '8':
   3588         case '9': {
   3589           int capture_ref = c2 - '0';
   3590           if (capture_ref > capture_count) {
   3591             i = next_index;
   3592             continue;
   3593           }
   3594           int second_digit_index = next_index + 1;
   3595           if (second_digit_index < length) {
   3596             // Peek ahead to see if we have two digits.
   3597             Char c3 = characters[second_digit_index];
   3598             if ('0' <= c3 && c3 <= '9') {  // Double digits.
   3599               int double_digit_ref = capture_ref * 10 + c3 - '0';
   3600               if (double_digit_ref <= capture_count) {
   3601                 next_index = second_digit_index;
   3602                 capture_ref = double_digit_ref;
   3603               }
   3604             }
   3605           }
   3606           if (capture_ref > 0) {
   3607             if (i > last) {
   3608               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3609             }
   3610             ASSERT(capture_ref <= capture_count);
   3611             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
   3612             last = next_index + 1;
   3613           }
   3614           i = next_index;
   3615           break;
   3616         }
   3617         default:
   3618           i = next_index;
   3619           break;
   3620         }
   3621       }
   3622     }
   3623     if (length > last) {
   3624       if (last == 0) {
   3625         // Replacement is simple.  Do not use Apply to do the replacement.
   3626         return true;
   3627       } else {
   3628         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
   3629       }
   3630     }
   3631     return false;
   3632   }
   3633 
   3634   ZoneList<ReplacementPart> parts_;
   3635   ZoneList<Handle<String> > replacement_substrings_;
   3636   Zone* zone_;
   3637 };
   3638 
   3639 
   3640 bool CompiledReplacement::Compile(Handle<String> replacement,
   3641                                   int capture_count,
   3642                                   int subject_length) {
   3643   {
   3644     DisallowHeapAllocation no_gc;
   3645     String::FlatContent content = replacement->GetFlatContent();
   3646     ASSERT(content.IsFlat());
   3647     bool simple = false;
   3648     if (content.IsAscii()) {
   3649       simple = ParseReplacementPattern(&parts_,
   3650                                        content.ToOneByteVector(),
   3651                                        capture_count,
   3652                                        subject_length,
   3653                                        zone());
   3654     } else {
   3655       ASSERT(content.IsTwoByte());
   3656       simple = ParseReplacementPattern(&parts_,
   3657                                        content.ToUC16Vector(),
   3658                                        capture_count,
   3659                                        subject_length,
   3660                                        zone());
   3661     }
   3662     if (simple) return true;
   3663   }
   3664 
   3665   Isolate* isolate = replacement->GetIsolate();
   3666   // Find substrings of replacement string and create them as String objects.
   3667   int substring_index = 0;
   3668   for (int i = 0, n = parts_.length(); i < n; i++) {
   3669     int tag = parts_[i].tag;
   3670     if (tag <= 0) {  // A replacement string slice.
   3671       int from = -tag;
   3672       int to = parts_[i].data;
   3673       replacement_substrings_.Add(
   3674           isolate->factory()->NewSubString(replacement, from, to), zone());
   3675       parts_[i].tag = REPLACEMENT_SUBSTRING;
   3676       parts_[i].data = substring_index;
   3677       substring_index++;
   3678     } else if (tag == REPLACEMENT_STRING) {
   3679       replacement_substrings_.Add(replacement, zone());
   3680       parts_[i].data = substring_index;
   3681       substring_index++;
   3682     }
   3683   }
   3684   return false;
   3685 }
   3686 
   3687 
   3688 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
   3689                                 int match_from,
   3690                                 int match_to,
   3691                                 int32_t* match) {
   3692   ASSERT_LT(0, parts_.length());
   3693   for (int i = 0, n = parts_.length(); i < n; i++) {
   3694     ReplacementPart part = parts_[i];
   3695     switch (part.tag) {
   3696       case SUBJECT_PREFIX:
   3697         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
   3698         break;
   3699       case SUBJECT_SUFFIX: {
   3700         int subject_length = part.data;
   3701         if (match_to < subject_length) {
   3702           builder->AddSubjectSlice(match_to, subject_length);
   3703         }
   3704         break;
   3705       }
   3706       case SUBJECT_CAPTURE: {
   3707         int capture = part.data;
   3708         int from = match[capture * 2];
   3709         int to = match[capture * 2 + 1];
   3710         if (from >= 0 && to > from) {
   3711           builder->AddSubjectSlice(from, to);
   3712         }
   3713         break;
   3714       }
   3715       case REPLACEMENT_SUBSTRING:
   3716       case REPLACEMENT_STRING:
   3717         builder->AddString(replacement_substrings_[part.data]);
   3718         break;
   3719       default:
   3720         UNREACHABLE();
   3721     }
   3722   }
   3723 }
   3724 
   3725 
   3726 void FindAsciiStringIndices(Vector<const uint8_t> subject,
   3727                             char pattern,
   3728                             ZoneList<int>* indices,
   3729                             unsigned int limit,
   3730                             Zone* zone) {
   3731   ASSERT(limit > 0);
   3732   // Collect indices of pattern in subject using memchr.
   3733   // Stop after finding at most limit values.
   3734   const uint8_t* subject_start = subject.start();
   3735   const uint8_t* subject_end = subject_start + subject.length();
   3736   const uint8_t* pos = subject_start;
   3737   while (limit > 0) {
   3738     pos = reinterpret_cast<const uint8_t*>(
   3739         memchr(pos, pattern, subject_end - pos));
   3740     if (pos == NULL) return;
   3741     indices->Add(static_cast<int>(pos - subject_start), zone);
   3742     pos++;
   3743     limit--;
   3744   }
   3745 }
   3746 
   3747 
   3748 void FindTwoByteStringIndices(const Vector<const uc16> subject,
   3749                               uc16 pattern,
   3750                               ZoneList<int>* indices,
   3751                               unsigned int limit,
   3752                               Zone* zone) {
   3753   ASSERT(limit > 0);
   3754   const uc16* subject_start = subject.start();
   3755   const uc16* subject_end = subject_start + subject.length();
   3756   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
   3757     if (*pos == pattern) {
   3758       indices->Add(static_cast<int>(pos - subject_start), zone);
   3759       limit--;
   3760     }
   3761   }
   3762 }
   3763 
   3764 
   3765 template <typename SubjectChar, typename PatternChar>
   3766 void FindStringIndices(Isolate* isolate,
   3767                        Vector<const SubjectChar> subject,
   3768                        Vector<const PatternChar> pattern,
   3769                        ZoneList<int>* indices,
   3770                        unsigned int limit,
   3771                        Zone* zone) {
   3772   ASSERT(limit > 0);
   3773   // Collect indices of pattern in subject.
   3774   // Stop after finding at most limit values.
   3775   int pattern_length = pattern.length();
   3776   int index = 0;
   3777   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   3778   while (limit > 0) {
   3779     index = search.Search(subject, index);
   3780     if (index < 0) return;
   3781     indices->Add(index, zone);
   3782     index += pattern_length;
   3783     limit--;
   3784   }
   3785 }
   3786 
   3787 
   3788 void FindStringIndicesDispatch(Isolate* isolate,
   3789                                String* subject,
   3790                                String* pattern,
   3791                                ZoneList<int>* indices,
   3792                                unsigned int limit,
   3793                                Zone* zone) {
   3794   {
   3795     DisallowHeapAllocation no_gc;
   3796     String::FlatContent subject_content = subject->GetFlatContent();
   3797     String::FlatContent pattern_content = pattern->GetFlatContent();
   3798     ASSERT(subject_content.IsFlat());
   3799     ASSERT(pattern_content.IsFlat());
   3800     if (subject_content.IsAscii()) {
   3801       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
   3802       if (pattern_content.IsAscii()) {
   3803         Vector<const uint8_t> pattern_vector =
   3804             pattern_content.ToOneByteVector();
   3805         if (pattern_vector.length() == 1) {
   3806           FindAsciiStringIndices(subject_vector,
   3807                                  pattern_vector[0],
   3808                                  indices,
   3809                                  limit,
   3810                                  zone);
   3811         } else {
   3812           FindStringIndices(isolate,
   3813                             subject_vector,
   3814                             pattern_vector,
   3815                             indices,
   3816                             limit,
   3817                             zone);
   3818         }
   3819       } else {
   3820         FindStringIndices(isolate,
   3821                           subject_vector,
   3822                           pattern_content.ToUC16Vector(),
   3823                           indices,
   3824                           limit,
   3825                           zone);
   3826       }
   3827     } else {
   3828       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
   3829       if (pattern_content.IsAscii()) {
   3830         Vector<const uint8_t> pattern_vector =
   3831             pattern_content.ToOneByteVector();
   3832         if (pattern_vector.length() == 1) {
   3833           FindTwoByteStringIndices(subject_vector,
   3834                                    pattern_vector[0],
   3835                                    indices,
   3836                                    limit,
   3837                                    zone);
   3838         } else {
   3839           FindStringIndices(isolate,
   3840                             subject_vector,
   3841                             pattern_vector,
   3842                             indices,
   3843                             limit,
   3844                             zone);
   3845         }
   3846       } else {
   3847         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
   3848         if (pattern_vector.length() == 1) {
   3849           FindTwoByteStringIndices(subject_vector,
   3850                                    pattern_vector[0],
   3851                                    indices,
   3852                                    limit,
   3853                                    zone);
   3854         } else {
   3855           FindStringIndices(isolate,
   3856                             subject_vector,
   3857                             pattern_vector,
   3858                             indices,
   3859                             limit,
   3860                             zone);
   3861         }
   3862       }
   3863     }
   3864   }
   3865 }
   3866 
   3867 
   3868 template<typename ResultSeqString>
   3869 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
   3870     Isolate* isolate,
   3871     Handle<String> subject,
   3872     Handle<JSRegExp> pattern_regexp,
   3873     Handle<String> replacement,
   3874     Handle<JSArray> last_match_info) {
   3875   ASSERT(subject->IsFlat());
   3876   ASSERT(replacement->IsFlat());
   3877 
   3878   ZoneScope zone_scope(isolate->runtime_zone());
   3879   ZoneList<int> indices(8, zone_scope.zone());
   3880   ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
   3881   String* pattern =
   3882       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
   3883   int subject_len = subject->length();
   3884   int pattern_len = pattern->length();
   3885   int replacement_len = replacement->length();
   3886 
   3887   FindStringIndicesDispatch(
   3888       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
   3889 
   3890   int matches = indices.length();
   3891   if (matches == 0) return *subject;
   3892 
   3893   // Detect integer overflow.
   3894   int64_t result_len_64 =
   3895       (static_cast<int64_t>(replacement_len) -
   3896        static_cast<int64_t>(pattern_len)) *
   3897       static_cast<int64_t>(matches) +
   3898       static_cast<int64_t>(subject_len);
   3899   if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11);
   3900   int result_len = static_cast<int>(result_len_64);
   3901 
   3902   int subject_pos = 0;
   3903   int result_pos = 0;
   3904 
   3905   Handle<ResultSeqString> result;
   3906   if (ResultSeqString::kHasAsciiEncoding) {
   3907     result = Handle<ResultSeqString>::cast(
   3908         isolate->factory()->NewRawOneByteString(result_len));
   3909   } else {
   3910     result = Handle<ResultSeqString>::cast(
   3911         isolate->factory()->NewRawTwoByteString(result_len));
   3912   }
   3913 
   3914   for (int i = 0; i < matches; i++) {
   3915     // Copy non-matched subject content.
   3916     if (subject_pos < indices.at(i)) {
   3917       String::WriteToFlat(*subject,
   3918                           result->GetChars() + result_pos,
   3919                           subject_pos,
   3920                           indices.at(i));
   3921       result_pos += indices.at(i) - subject_pos;
   3922     }
   3923 
   3924     // Replace match.
   3925     if (replacement_len > 0) {
   3926       String::WriteToFlat(*replacement,
   3927                           result->GetChars() + result_pos,
   3928                           0,
   3929                           replacement_len);
   3930       result_pos += replacement_len;
   3931     }
   3932 
   3933     subject_pos = indices.at(i) + pattern_len;
   3934   }
   3935   // Add remaining subject content at the end.
   3936   if (subject_pos < subject_len) {
   3937     String::WriteToFlat(*subject,
   3938                         result->GetChars() + result_pos,
   3939                         subject_pos,
   3940                         subject_len);
   3941   }
   3942 
   3943   int32_t match_indices[] = { indices.at(matches - 1),
   3944                               indices.at(matches - 1) + pattern_len };
   3945   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
   3946 
   3947   return *result;
   3948 }
   3949 
   3950 
   3951 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
   3952     Isolate* isolate,
   3953     Handle<String> subject,
   3954     Handle<JSRegExp> regexp,
   3955     Handle<String> replacement,
   3956     Handle<JSArray> last_match_info) {
   3957   ASSERT(subject->IsFlat());
   3958   ASSERT(replacement->IsFlat());
   3959 
   3960   int capture_count = regexp->CaptureCount();
   3961   int subject_length = subject->length();
   3962 
   3963   // CompiledReplacement uses zone allocation.
   3964   ZoneScope zone_scope(isolate->runtime_zone());
   3965   CompiledReplacement compiled_replacement(zone_scope.zone());
   3966   bool simple_replace = compiled_replacement.Compile(replacement,
   3967                                                      capture_count,
   3968                                                      subject_length);
   3969 
   3970   // Shortcut for simple non-regexp global replacements
   3971   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
   3972     if (subject->HasOnlyOneByteChars() &&
   3973         replacement->HasOnlyOneByteChars()) {
   3974       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   3975           isolate, subject, regexp, replacement, last_match_info);
   3976     } else {
   3977       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   3978           isolate, subject, regexp, replacement, last_match_info);
   3979     }
   3980   }
   3981 
   3982   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   3983   if (global_cache.HasException()) return Failure::Exception();
   3984 
   3985   int32_t* current_match = global_cache.FetchNext();
   3986   if (current_match == NULL) {
   3987     if (global_cache.HasException()) return Failure::Exception();
   3988     return *subject;
   3989   }
   3990 
   3991   // Guessing the number of parts that the final result string is built
   3992   // from. Global regexps can match any number of times, so we guess
   3993   // conservatively.
   3994   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
   3995   ReplacementStringBuilder builder(isolate->heap(),
   3996                                    subject,
   3997                                    expected_parts);
   3998 
   3999   // Number of parts added by compiled replacement plus preceeding
   4000   // string and possibly suffix after last match.  It is possible for
   4001   // all components to use two elements when encoded as two smis.
   4002   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
   4003 
   4004   int prev = 0;
   4005 
   4006   do {
   4007     builder.EnsureCapacity(parts_added_per_loop);
   4008 
   4009     int start = current_match[0];
   4010     int end = current_match[1];
   4011 
   4012     if (prev < start) {
   4013       builder.AddSubjectSlice(prev, start);
   4014     }
   4015 
   4016     if (simple_replace) {
   4017       builder.AddString(replacement);
   4018     } else {
   4019       compiled_replacement.Apply(&builder,
   4020                                  start,
   4021                                  end,
   4022                                  current_match);
   4023     }
   4024     prev = end;
   4025 
   4026     current_match = global_cache.FetchNext();
   4027   } while (current_match != NULL);
   4028 
   4029   if (global_cache.HasException()) return Failure::Exception();
   4030 
   4031   if (prev < subject_length) {
   4032     builder.EnsureCapacity(2);
   4033     builder.AddSubjectSlice(prev, subject_length);
   4034   }
   4035 
   4036   RegExpImpl::SetLastMatchInfo(last_match_info,
   4037                                subject,
   4038                                capture_count,
   4039                                global_cache.LastSuccessfulMatch());
   4040 
   4041   return *(builder.ToString());
   4042 }
   4043 
   4044 
   4045 template <typename ResultSeqString>
   4046 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
   4047     Isolate* isolate,
   4048     Handle<String> subject,
   4049     Handle<JSRegExp> regexp,
   4050     Handle<JSArray> last_match_info) {
   4051   ASSERT(subject->IsFlat());
   4052 
   4053   // Shortcut for simple non-regexp global replacements
   4054   if (regexp->TypeTag() == JSRegExp::ATOM) {
   4055     Handle<String> empty_string = isolate->factory()->empty_string();
   4056     if (subject->IsOneByteRepresentation()) {
   4057       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   4058           isolate, subject, regexp, empty_string, last_match_info);
   4059     } else {
   4060       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   4061           isolate, subject, regexp, empty_string, last_match_info);
   4062     }
   4063   }
   4064 
   4065   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4066   if (global_cache.HasException()) return Failure::Exception();
   4067 
   4068   int32_t* current_match = global_cache.FetchNext();
   4069   if (current_match == NULL) {
   4070     if (global_cache.HasException()) return Failure::Exception();
   4071     return *subject;
   4072   }
   4073 
   4074   int start = current_match[0];
   4075   int end = current_match[1];
   4076   int capture_count = regexp->CaptureCount();
   4077   int subject_length = subject->length();
   4078 
   4079   int new_length = subject_length - (end - start);
   4080   if (new_length == 0) return isolate->heap()->empty_string();
   4081 
   4082   Handle<ResultSeqString> answer;
   4083   if (ResultSeqString::kHasAsciiEncoding) {
   4084     answer = Handle<ResultSeqString>::cast(
   4085         isolate->factory()->NewRawOneByteString(new_length));
   4086   } else {
   4087     answer = Handle<ResultSeqString>::cast(
   4088         isolate->factory()->NewRawTwoByteString(new_length));
   4089   }
   4090 
   4091   int prev = 0;
   4092   int position = 0;
   4093 
   4094   do {
   4095     start = current_match[0];
   4096     end = current_match[1];
   4097     if (prev < start) {
   4098       // Add substring subject[prev;start] to answer string.
   4099       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
   4100       position += start - prev;
   4101     }
   4102     prev = end;
   4103 
   4104     current_match = global_cache.FetchNext();
   4105   } while (current_match != NULL);
   4106 
   4107   if (global_cache.HasException()) return Failure::Exception();
   4108 
   4109   RegExpImpl::SetLastMatchInfo(last_match_info,
   4110                                subject,
   4111                                capture_count,
   4112                                global_cache.LastSuccessfulMatch());
   4113 
   4114   if (prev < subject_length) {
   4115     // Add substring subject[prev;length] to answer string.
   4116     String::WriteToFlat(
   4117         *subject, answer->GetChars() + position, prev, subject_length);
   4118     position += subject_length - prev;
   4119   }
   4120 
   4121   if (position == 0) return isolate->heap()->empty_string();
   4122 
   4123   // Shorten string and fill
   4124   int string_size = ResultSeqString::SizeFor(position);
   4125   int allocated_string_size = ResultSeqString::SizeFor(new_length);
   4126   int delta = allocated_string_size - string_size;
   4127 
   4128   answer->set_length(position);
   4129   if (delta == 0) return *answer;
   4130 
   4131   Address end_of_string = answer->address() + string_size;
   4132   isolate->heap()->CreateFillerObjectAt(end_of_string, delta);
   4133   if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) {
   4134     MemoryChunk::IncrementLiveBytesFromMutator(answer->address(), -delta);
   4135   }
   4136 
   4137   return *answer;
   4138 }
   4139 
   4140 
   4141 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) {
   4142   HandleScope scope(isolate);
   4143   ASSERT(args.length() == 4);
   4144 
   4145   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4146   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
   4147   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4148   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   4149 
   4150   ASSERT(regexp->GetFlags().is_global());
   4151 
   4152   if (!subject->IsFlat()) subject = FlattenGetString(subject);
   4153 
   4154   if (replacement->length() == 0) {
   4155     if (subject->HasOnlyOneByteChars()) {
   4156       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
   4157           isolate, subject, regexp, last_match_info);
   4158     } else {
   4159       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
   4160           isolate, subject, regexp, last_match_info);
   4161     }
   4162   }
   4163 
   4164   if (!replacement->IsFlat()) replacement = FlattenGetString(replacement);
   4165 
   4166   return StringReplaceGlobalRegExpWithString(
   4167       isolate, subject, regexp, replacement, last_match_info);
   4168 }
   4169 
   4170 
   4171 Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
   4172                                               Handle<String> subject,
   4173                                               Handle<String> search,
   4174                                               Handle<String> replace,
   4175                                               bool* found,
   4176                                               int recursion_limit) {
   4177   if (recursion_limit == 0) return Handle<String>::null();
   4178   if (subject->IsConsString()) {
   4179     ConsString* cons = ConsString::cast(*subject);
   4180     Handle<String> first = Handle<String>(cons->first());
   4181     Handle<String> second = Handle<String>(cons->second());
   4182     Handle<String> new_first =
   4183         StringReplaceOneCharWithString(isolate,
   4184                                        first,
   4185                                        search,
   4186                                        replace,
   4187                                        found,
   4188                                        recursion_limit - 1);
   4189     if (*found) return isolate->factory()->NewConsString(new_first, second);
   4190     if (new_first.is_null()) return new_first;
   4191 
   4192     Handle<String> new_second =
   4193         StringReplaceOneCharWithString(isolate,
   4194                                        second,
   4195                                        search,
   4196                                        replace,
   4197                                        found,
   4198                                        recursion_limit - 1);
   4199     if (*found) return isolate->factory()->NewConsString(first, new_second);
   4200     if (new_second.is_null()) return new_second;
   4201 
   4202     return subject;
   4203   } else {
   4204     int index = Runtime::StringMatch(isolate, subject, search, 0);
   4205     if (index == -1) return subject;
   4206     *found = true;
   4207     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
   4208     Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
   4209     Handle<String> second =
   4210         isolate->factory()->NewSubString(subject, index + 1, subject->length());
   4211     return isolate->factory()->NewConsString(cons1, second);
   4212   }
   4213 }
   4214 
   4215 
   4216 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
   4217   HandleScope scope(isolate);
   4218   ASSERT(args.length() == 3);
   4219   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4220   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
   4221   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
   4222 
   4223   // If the cons string tree is too deep, we simply abort the recursion and
   4224   // retry with a flattened subject string.
   4225   const int kRecursionLimit = 0x1000;
   4226   bool found = false;
   4227   Handle<String> result = StringReplaceOneCharWithString(isolate,
   4228                                                          subject,
   4229                                                          search,
   4230                                                          replace,
   4231                                                          &found,
   4232                                                          kRecursionLimit);
   4233   if (!result.is_null()) return *result;
   4234   return *StringReplaceOneCharWithString(isolate,
   4235                                          FlattenGetString(subject),
   4236                                          search,
   4237                                          replace,
   4238                                          &found,
   4239                                          kRecursionLimit);
   4240 }
   4241 
   4242 
   4243 // Perform string match of pattern on subject, starting at start index.
   4244 // Caller must ensure that 0 <= start_index <= sub->length(),
   4245 // and should check that pat->length() + start_index <= sub->length().
   4246 int Runtime::StringMatch(Isolate* isolate,
   4247                          Handle<String> sub,
   4248                          Handle<String> pat,
   4249                          int start_index) {
   4250   ASSERT(0 <= start_index);
   4251   ASSERT(start_index <= sub->length());
   4252 
   4253   int pattern_length = pat->length();
   4254   if (pattern_length == 0) return start_index;
   4255 
   4256   int subject_length = sub->length();
   4257   if (start_index + pattern_length > subject_length) return -1;
   4258 
   4259   if (!sub->IsFlat()) FlattenString(sub);
   4260   if (!pat->IsFlat()) FlattenString(pat);
   4261 
   4262   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4263   // Extract flattened substrings of cons strings before determining asciiness.
   4264   String::FlatContent seq_sub = sub->GetFlatContent();
   4265   String::FlatContent seq_pat = pat->GetFlatContent();
   4266 
   4267   // dispatch on type of strings
   4268   if (seq_pat.IsAscii()) {
   4269     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
   4270     if (seq_sub.IsAscii()) {
   4271       return SearchString(isolate,
   4272                           seq_sub.ToOneByteVector(),
   4273                           pat_vector,
   4274                           start_index);
   4275     }
   4276     return SearchString(isolate,
   4277                         seq_sub.ToUC16Vector(),
   4278                         pat_vector,
   4279                         start_index);
   4280   }
   4281   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
   4282   if (seq_sub.IsAscii()) {
   4283     return SearchString(isolate,
   4284                         seq_sub.ToOneByteVector(),
   4285                         pat_vector,
   4286                         start_index);
   4287   }
   4288   return SearchString(isolate,
   4289                       seq_sub.ToUC16Vector(),
   4290                       pat_vector,
   4291                       start_index);
   4292 }
   4293 
   4294 
   4295 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) {
   4296   HandleScope scope(isolate);
   4297   ASSERT(args.length() == 3);
   4298 
   4299   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4300   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4301 
   4302   Object* index = args[2];
   4303   uint32_t start_index;
   4304   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4305 
   4306   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
   4307   int position =
   4308       Runtime::StringMatch(isolate, sub, pat, start_index);
   4309   return Smi::FromInt(position);
   4310 }
   4311 
   4312 
   4313 template <typename schar, typename pchar>
   4314 static int StringMatchBackwards(Vector<const schar> subject,
   4315                                 Vector<const pchar> pattern,
   4316                                 int idx) {
   4317   int pattern_length = pattern.length();
   4318   ASSERT(pattern_length >= 1);
   4319   ASSERT(idx + pattern_length <= subject.length());
   4320 
   4321   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   4322     for (int i = 0; i < pattern_length; i++) {
   4323       uc16 c = pattern[i];
   4324       if (c > String::kMaxOneByteCharCode) {
   4325         return -1;
   4326       }
   4327     }
   4328   }
   4329 
   4330   pchar pattern_first_char = pattern[0];
   4331   for (int i = idx; i >= 0; i--) {
   4332     if (subject[i] != pattern_first_char) continue;
   4333     int j = 1;
   4334     while (j < pattern_length) {
   4335       if (pattern[j] != subject[i+j]) {
   4336         break;
   4337       }
   4338       j++;
   4339     }
   4340     if (j == pattern_length) {
   4341       return i;
   4342     }
   4343   }
   4344   return -1;
   4345 }
   4346 
   4347 
   4348 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
   4349   HandleScope scope(isolate);
   4350   ASSERT(args.length() == 3);
   4351 
   4352   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4353   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4354 
   4355   Object* index = args[2];
   4356   uint32_t start_index;
   4357   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4358 
   4359   uint32_t pat_length = pat->length();
   4360   uint32_t sub_length = sub->length();
   4361 
   4362   if (start_index + pat_length > sub_length) {
   4363     start_index = sub_length - pat_length;
   4364   }
   4365 
   4366   if (pat_length == 0) {
   4367     return Smi::FromInt(start_index);
   4368   }
   4369 
   4370   if (!sub->IsFlat()) FlattenString(sub);
   4371   if (!pat->IsFlat()) FlattenString(pat);
   4372 
   4373   int position = -1;
   4374   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4375 
   4376   String::FlatContent sub_content = sub->GetFlatContent();
   4377   String::FlatContent pat_content = pat->GetFlatContent();
   4378 
   4379   if (pat_content.IsAscii()) {
   4380     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
   4381     if (sub_content.IsAscii()) {
   4382       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4383                                       pat_vector,
   4384                                       start_index);
   4385     } else {
   4386       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4387                                       pat_vector,
   4388                                       start_index);
   4389     }
   4390   } else {
   4391     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
   4392     if (sub_content.IsAscii()) {
   4393       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4394                                       pat_vector,
   4395                                       start_index);
   4396     } else {
   4397       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4398                                       pat_vector,
   4399                                       start_index);
   4400     }
   4401   }
   4402 
   4403   return Smi::FromInt(position);
   4404 }
   4405 
   4406 
   4407 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
   4408   SealHandleScope shs(isolate);
   4409   ASSERT(args.length() == 2);
   4410 
   4411   CONVERT_ARG_CHECKED(String, str1, 0);
   4412   CONVERT_ARG_CHECKED(String, str2, 1);
   4413 
   4414   if (str1 == str2) return Smi::FromInt(0);  // Equal.
   4415   int str1_length = str1->length();
   4416   int str2_length = str2->length();
   4417 
   4418   // Decide trivial cases without flattening.
   4419   if (str1_length == 0) {
   4420     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
   4421     return Smi::FromInt(-str2_length);
   4422   } else {
   4423     if (str2_length == 0) return Smi::FromInt(str1_length);
   4424   }
   4425 
   4426   int end = str1_length < str2_length ? str1_length : str2_length;
   4427 
   4428   // No need to flatten if we are going to find the answer on the first
   4429   // character.  At this point we know there is at least one character
   4430   // in each string, due to the trivial case handling above.
   4431   int d = str1->Get(0) - str2->Get(0);
   4432   if (d != 0) return Smi::FromInt(d);
   4433 
   4434   str1->TryFlatten();
   4435   str2->TryFlatten();
   4436 
   4437   ConsStringIteratorOp* op1 =
   4438       isolate->runtime_state()->string_locale_compare_it1();
   4439   ConsStringIteratorOp* op2 =
   4440       isolate->runtime_state()->string_locale_compare_it2();
   4441   // TODO(dcarney) Can do array compares here more efficiently.
   4442   StringCharacterStream stream1(str1, op1);
   4443   StringCharacterStream stream2(str2, op2);
   4444 
   4445   for (int i = 0; i < end; i++) {
   4446     uint16_t char1 = stream1.GetNext();
   4447     uint16_t char2 = stream2.GetNext();
   4448     if (char1 != char2) return Smi::FromInt(char1 - char2);
   4449   }
   4450 
   4451   return Smi::FromInt(str1_length - str2_length);
   4452 }
   4453 
   4454 
   4455 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
   4456   SealHandleScope shs(isolate);
   4457   ASSERT(args.length() == 3);
   4458 
   4459   CONVERT_ARG_CHECKED(String, value, 0);
   4460   int start, end;
   4461   // We have a fast integer-only case here to avoid a conversion to double in
   4462   // the common case where from and to are Smis.
   4463   if (args[1]->IsSmi() && args[2]->IsSmi()) {
   4464     CONVERT_SMI_ARG_CHECKED(from_number, 1);
   4465     CONVERT_SMI_ARG_CHECKED(to_number, 2);
   4466     start = from_number;
   4467     end = to_number;
   4468   } else {
   4469     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
   4470     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
   4471     start = FastD2IChecked(from_number);
   4472     end = FastD2IChecked(to_number);
   4473   }
   4474   RUNTIME_ASSERT(end >= start);
   4475   RUNTIME_ASSERT(start >= 0);
   4476   RUNTIME_ASSERT(end <= value->length());
   4477   isolate->counters()->sub_string_runtime()->Increment();
   4478   return value->SubString(start, end);
   4479 }
   4480 
   4481 
   4482 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
   4483   HandleScope handles(isolate);
   4484   ASSERT_EQ(3, args.length());
   4485 
   4486   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4487   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4488   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
   4489 
   4490   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4491   if (global_cache.HasException()) return Failure::Exception();
   4492 
   4493   int capture_count = regexp->CaptureCount();
   4494 
   4495   ZoneScope zone_scope(isolate->runtime_zone());
   4496   ZoneList<int> offsets(8, zone_scope.zone());
   4497 
   4498   while (true) {
   4499     int32_t* match = global_cache.FetchNext();
   4500     if (match == NULL) break;
   4501     offsets.Add(match[0], zone_scope.zone());  // start
   4502     offsets.Add(match[1], zone_scope.zone());  // end
   4503   }
   4504 
   4505   if (global_cache.HasException()) return Failure::Exception();
   4506 
   4507   if (offsets.length() == 0) {
   4508     // Not a single match.
   4509     return isolate->heap()->null_value();
   4510   }
   4511 
   4512   RegExpImpl::SetLastMatchInfo(regexp_info,
   4513                                subject,
   4514                                capture_count,
   4515                                global_cache.LastSuccessfulMatch());
   4516 
   4517   int matches = offsets.length() / 2;
   4518   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
   4519   Handle<String> substring =
   4520       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
   4521   elements->set(0, *substring);
   4522   for (int i = 1; i < matches; i++) {
   4523     HandleScope temp_scope(isolate);
   4524     int from = offsets.at(i * 2);
   4525     int to = offsets.at(i * 2 + 1);
   4526     Handle<String> substring =
   4527         isolate->factory()->NewProperSubString(subject, from, to);
   4528     elements->set(i, *substring);
   4529   }
   4530   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
   4531   result->set_length(Smi::FromInt(matches));
   4532   return *result;
   4533 }
   4534 
   4535 
   4536 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
   4537 // separate last match info.  See comment on that function.
   4538 template<bool has_capture>
   4539 static MaybeObject* SearchRegExpMultiple(
   4540     Isolate* isolate,
   4541     Handle<String> subject,
   4542     Handle<JSRegExp> regexp,
   4543     Handle<JSArray> last_match_array,
   4544     Handle<JSArray> result_array) {
   4545   ASSERT(subject->IsFlat());
   4546   ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
   4547 
   4548   int capture_count = regexp->CaptureCount();
   4549   int subject_length = subject->length();
   4550 
   4551   static const int kMinLengthToCache = 0x1000;
   4552 
   4553   if (subject_length > kMinLengthToCache) {
   4554     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
   4555         isolate->heap(),
   4556         *subject,
   4557         regexp->data(),
   4558         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
   4559     if (*cached_answer != Smi::FromInt(0)) {
   4560       Handle<FixedArray> cached_fixed_array =
   4561           Handle<FixedArray>(FixedArray::cast(*cached_answer));
   4562       // The cache FixedArray is a COW-array and can therefore be reused.
   4563       isolate->factory()->SetContent(result_array, cached_fixed_array);
   4564       // The actual length of the result array is stored in the last element of
   4565       // the backing store (the backing FixedArray may have a larger capacity).
   4566       Object* cached_fixed_array_last_element =
   4567           cached_fixed_array->get(cached_fixed_array->length() - 1);
   4568       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
   4569       result_array->set_length(js_array_length);
   4570       RegExpImpl::SetLastMatchInfo(
   4571           last_match_array, subject, capture_count, NULL);
   4572       return *result_array;
   4573     }
   4574   }
   4575 
   4576   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4577   if (global_cache.HasException()) return Failure::Exception();
   4578 
   4579   Handle<FixedArray> result_elements;
   4580   if (result_array->HasFastObjectElements()) {
   4581     result_elements =
   4582         Handle<FixedArray>(FixedArray::cast(result_array->elements()));
   4583   }
   4584   if (result_elements.is_null() || result_elements->length() < 16) {
   4585     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   4586   }
   4587 
   4588   FixedArrayBuilder builder(result_elements);
   4589 
   4590   // Position to search from.
   4591   int match_start = -1;
   4592   int match_end = 0;
   4593   bool first = true;
   4594 
   4595   // Two smis before and after the match, for very long strings.
   4596   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
   4597 
   4598   while (true) {
   4599     int32_t* current_match = global_cache.FetchNext();
   4600     if (current_match == NULL) break;
   4601     match_start = current_match[0];
   4602     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   4603     if (match_end < match_start) {
   4604       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4605                                                 match_end,
   4606                                                 match_start);
   4607     }
   4608     match_end = current_match[1];
   4609     {
   4610       // Avoid accumulating new handles inside loop.
   4611       HandleScope temp_scope(isolate);
   4612       Handle<String> match;
   4613       if (!first) {
   4614         match = isolate->factory()->NewProperSubString(subject,
   4615                                                        match_start,
   4616                                                        match_end);
   4617       } else {
   4618         match = isolate->factory()->NewSubString(subject,
   4619                                                  match_start,
   4620                                                  match_end);
   4621         first = false;
   4622       }
   4623 
   4624       if (has_capture) {
   4625         // Arguments array to replace function is match, captures, index and
   4626         // subject, i.e., 3 + capture count in total.
   4627         Handle<FixedArray> elements =
   4628             isolate->factory()->NewFixedArray(3 + capture_count);
   4629 
   4630         elements->set(0, *match);
   4631         for (int i = 1; i <= capture_count; i++) {
   4632           int start = current_match[i * 2];
   4633           if (start >= 0) {
   4634             int end = current_match[i * 2 + 1];
   4635             ASSERT(start <= end);
   4636             Handle<String> substring =
   4637                 isolate->factory()->NewSubString(subject, start, end);
   4638             elements->set(i, *substring);
   4639           } else {
   4640             ASSERT(current_match[i * 2 + 1] < 0);
   4641             elements->set(i, isolate->heap()->undefined_value());
   4642           }
   4643         }
   4644         elements->set(capture_count + 1, Smi::FromInt(match_start));
   4645         elements->set(capture_count + 2, *subject);
   4646         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
   4647       } else {
   4648         builder.Add(*match);
   4649       }
   4650     }
   4651   }
   4652 
   4653   if (global_cache.HasException()) return Failure::Exception();
   4654 
   4655   if (match_start >= 0) {
   4656     // Finished matching, with at least one match.
   4657     if (match_end < subject_length) {
   4658       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4659                                                 match_end,
   4660                                                 subject_length);
   4661     }
   4662 
   4663     RegExpImpl::SetLastMatchInfo(
   4664         last_match_array, subject, capture_count, NULL);
   4665 
   4666     if (subject_length > kMinLengthToCache) {
   4667       // Store the length of the result array into the last element of the
   4668       // backing FixedArray.
   4669       builder.EnsureCapacity(1);
   4670       Handle<FixedArray> fixed_array = builder.array();
   4671       fixed_array->set(fixed_array->length() - 1,
   4672                        Smi::FromInt(builder.length()));
   4673       // Cache the result and turn the FixedArray into a COW array.
   4674       RegExpResultsCache::Enter(isolate->heap(),
   4675                                 *subject,
   4676                                 regexp->data(),
   4677                                 *fixed_array,
   4678                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
   4679     }
   4680     return *builder.ToJSArray(result_array);
   4681   } else {
   4682     return isolate->heap()->null_value();  // No matches at all.
   4683   }
   4684 }
   4685 
   4686 
   4687 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
   4688 // lastMatchInfoOverride to maintain the last match info, so we don't need to
   4689 // set any other last match array info.
   4690 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
   4691   HandleScope handles(isolate);
   4692   ASSERT(args.length() == 4);
   4693 
   4694   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   4695   if (!subject->IsFlat()) FlattenString(subject);
   4696   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   4697   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
   4698   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
   4699 
   4700   ASSERT(regexp->GetFlags().is_global());
   4701 
   4702   if (regexp->CaptureCount() == 0) {
   4703     return SearchRegExpMultiple<false>(
   4704         isolate, subject, regexp, last_match_info, result_array);
   4705   } else {
   4706     return SearchRegExpMultiple<true>(
   4707         isolate, subject, regexp, last_match_info, result_array);
   4708   }
   4709 }
   4710 
   4711 
   4712 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
   4713   SealHandleScope shs(isolate);
   4714   ASSERT(args.length() == 2);
   4715   CONVERT_SMI_ARG_CHECKED(radix, 1);
   4716   RUNTIME_ASSERT(2 <= radix && radix <= 36);
   4717 
   4718   // Fast case where the result is a one character string.
   4719   if (args[0]->IsSmi()) {
   4720     int value = args.smi_at(0);
   4721     if (value >= 0 && value < radix) {
   4722       // Character array used for conversion.
   4723       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   4724       return isolate->heap()->
   4725           LookupSingleCharacterStringFromCode(kCharTable[value]);
   4726     }
   4727   }
   4728 
   4729   // Slow case.
   4730   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4731   if (std::isnan(value)) {
   4732     return *isolate->factory()->nan_string();
   4733   }
   4734   if (std::isinf(value)) {
   4735     if (value < 0) {
   4736       return *isolate->factory()->minus_infinity_string();
   4737     }
   4738     return *isolate->factory()->infinity_string();
   4739   }
   4740   char* str = DoubleToRadixCString(value, radix);
   4741   MaybeObject* result =
   4742       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4743   DeleteArray(str);
   4744   return result;
   4745 }
   4746 
   4747 
   4748 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
   4749   SealHandleScope shs(isolate);
   4750   ASSERT(args.length() == 2);
   4751 
   4752   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4753   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4754   int f = FastD2IChecked(f_number);
   4755   RUNTIME_ASSERT(f >= 0);
   4756   char* str = DoubleToFixedCString(value, f);
   4757   MaybeObject* res =
   4758       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4759   DeleteArray(str);
   4760   return res;
   4761 }
   4762 
   4763 
   4764 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
   4765   SealHandleScope shs(isolate);
   4766   ASSERT(args.length() == 2);
   4767 
   4768   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4769   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4770   int f = FastD2IChecked(f_number);
   4771   RUNTIME_ASSERT(f >= -1 && f <= 20);
   4772   char* str = DoubleToExponentialCString(value, f);
   4773   MaybeObject* res =
   4774       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4775   DeleteArray(str);
   4776   return res;
   4777 }
   4778 
   4779 
   4780 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
   4781   SealHandleScope shs(isolate);
   4782   ASSERT(args.length() == 2);
   4783 
   4784   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4785   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4786   int f = FastD2IChecked(f_number);
   4787   RUNTIME_ASSERT(f >= 1 && f <= 21);
   4788   char* str = DoubleToPrecisionCString(value, f);
   4789   MaybeObject* res =
   4790       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4791   DeleteArray(str);
   4792   return res;
   4793 }
   4794 
   4795 
   4796 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsValidSmi) {
   4797   HandleScope shs(isolate);
   4798   ASSERT(args.length() == 1);
   4799 
   4800   CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
   4801   if (Smi::IsValid(number)) {
   4802     return isolate->heap()->true_value();
   4803   } else {
   4804     return isolate->heap()->false_value();
   4805   }
   4806 }
   4807 
   4808 
   4809 // Returns a single character string where first character equals
   4810 // string->Get(index).
   4811 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
   4812   if (index < static_cast<uint32_t>(string->length())) {
   4813     string->TryFlatten();
   4814     return LookupSingleCharacterStringFromCode(
   4815         string->GetIsolate(),
   4816         string->Get(index));
   4817   }
   4818   return Execution::CharAt(string, index);
   4819 }
   4820 
   4821 
   4822 MaybeObject* Runtime::GetElementOrCharAtOrFail(Isolate* isolate,
   4823                                                Handle<Object> object,
   4824                                                uint32_t index) {
   4825   CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
   4826       GetElementOrCharAt(isolate, object, index));
   4827 }
   4828 
   4829 
   4830 MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
   4831                                          Handle<Object> object,
   4832                                          uint32_t index) {
   4833   // Handle [] indexing on Strings
   4834   if (object->IsString()) {
   4835     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
   4836     if (!result->IsUndefined()) return *result;
   4837   }
   4838 
   4839   // Handle [] indexing on String objects
   4840   if (object->IsStringObjectWithCharacterAt(index)) {
   4841     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
   4842     Handle<Object> result =
   4843         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
   4844     if (!result->IsUndefined()) return *result;
   4845   }
   4846 
   4847   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
   4848     return object->GetPrototype(isolate)->GetElement(isolate, index);
   4849   }
   4850 
   4851   return object->GetElement(isolate, index);
   4852 }
   4853 
   4854 
   4855 static Handle<Name> ToName(Isolate* isolate, Handle<Object> key) {
   4856   if (key->IsName()) {
   4857     return Handle<Name>::cast(key);
   4858   } else {
   4859     bool has_pending_exception = false;
   4860     Handle<Object> converted =
   4861         Execution::ToString(isolate, key, &has_pending_exception);
   4862     if (has_pending_exception) return Handle<Name>();
   4863     return Handle<Name>::cast(converted);
   4864   }
   4865 }
   4866 
   4867 
   4868 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
   4869                                         Handle<JSReceiver> object,
   4870                                         Handle<Object> key) {
   4871   HandleScope scope(isolate);
   4872 
   4873   // Check if the given key is an array index.
   4874   uint32_t index;
   4875   if (key->ToArrayIndex(&index)) {
   4876     return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index));
   4877   }
   4878 
   4879   // Convert the key to a name - possibly by calling back into JavaScript.
   4880   Handle<Name> name = ToName(isolate, key);
   4881   RETURN_IF_EMPTY_HANDLE(isolate, name);
   4882 
   4883   return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
   4884 }
   4885 
   4886 MaybeObject* Runtime::GetObjectPropertyOrFail(
   4887     Isolate* isolate,
   4888     Handle<Object> object,
   4889     Handle<Object> key) {
   4890   CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
   4891       GetObjectProperty(isolate, object, key));
   4892 }
   4893 
   4894 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
   4895                                         Handle<Object> object,
   4896                                         Handle<Object> key) {
   4897   HandleScope scope(isolate);
   4898 
   4899   if (object->IsUndefined() || object->IsNull()) {
   4900     Handle<Object> args[2] = { key, object };
   4901     Handle<Object> error =
   4902         isolate->factory()->NewTypeError("non_object_property_load",
   4903                                          HandleVector(args, 2));
   4904     return isolate->Throw(*error);
   4905   }
   4906 
   4907   // Check if the given key is an array index.
   4908   uint32_t index;
   4909   if (key->ToArrayIndex(&index)) {
   4910     return GetElementOrCharAt(isolate, object, index);
   4911   }
   4912 
   4913   // Convert the key to a name - possibly by calling back into JavaScript.
   4914   Handle<Name> name = ToName(isolate, key);
   4915   RETURN_IF_EMPTY_HANDLE(isolate, name);
   4916 
   4917   // Check if the name is trivially convertible to an index and get
   4918   // the element if so.
   4919   if (name->AsArrayIndex(&index)) {
   4920     return GetElementOrCharAt(isolate, object, index);
   4921   } else {
   4922     return object->GetProperty(*name);
   4923   }
   4924 }
   4925 
   4926 
   4927 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
   4928   SealHandleScope shs(isolate);
   4929   ASSERT(args.length() == 2);
   4930 
   4931   Handle<Object> object = args.at<Object>(0);
   4932   Handle<Object> key = args.at<Object>(1);
   4933 
   4934   return Runtime::GetObjectProperty(isolate, object, key);
   4935 }
   4936 
   4937 
   4938 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
   4939 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
   4940   SealHandleScope shs(isolate);
   4941   ASSERT(args.length() == 2);
   4942 
   4943   // Fast cases for getting named properties of the receiver JSObject
   4944   // itself.
   4945   //
   4946   // The global proxy objects has to be excluded since LocalLookup on
   4947   // the global proxy object can return a valid result even though the
   4948   // global proxy object never has properties.  This is the case
   4949   // because the global proxy object forwards everything to its hidden
   4950   // prototype including local lookups.
   4951   //
   4952   // Additionally, we need to make sure that we do not cache results
   4953   // for objects that require access checks.
   4954   if (args[0]->IsJSObject()) {
   4955     if (!args[0]->IsJSGlobalProxy() &&
   4956         !args[0]->IsAccessCheckNeeded() &&
   4957         args[1]->IsName()) {
   4958       JSObject* receiver = JSObject::cast(args[0]);
   4959       Name* key = Name::cast(args[1]);
   4960       if (receiver->HasFastProperties()) {
   4961         // Attempt to use lookup cache.
   4962         Map* receiver_map = receiver->map();
   4963         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
   4964         int offset = keyed_lookup_cache->Lookup(receiver_map, key);
   4965         if (offset != -1) {
   4966           // Doubles are not cached, so raw read the value.
   4967           Object* value = receiver->RawFastPropertyAt(offset);
   4968           return value->IsTheHole()
   4969               ? isolate->heap()->undefined_value()
   4970               : value;
   4971         }
   4972         // Lookup cache miss.  Perform lookup and update the cache if
   4973         // appropriate.
   4974         LookupResult result(isolate);
   4975         receiver->LocalLookup(key, &result);
   4976         if (result.IsField()) {
   4977           int offset = result.GetFieldIndex().field_index();
   4978           // Do not track double fields in the keyed lookup cache. Reading
   4979           // double values requires boxing.
   4980           if (!FLAG_track_double_fields ||
   4981               !result.representation().IsDouble()) {
   4982             keyed_lookup_cache->Update(receiver_map, key, offset);
   4983           }
   4984           return receiver->FastPropertyAt(result.representation(), offset);
   4985         }
   4986       } else {
   4987         // Attempt dictionary lookup.
   4988         NameDictionary* dictionary = receiver->property_dictionary();
   4989         int entry = dictionary->FindEntry(key);
   4990         if ((entry != NameDictionary::kNotFound) &&
   4991             (dictionary->DetailsAt(entry).type() == NORMAL)) {
   4992           Object* value = dictionary->ValueAt(entry);
   4993           if (!receiver->IsGlobalObject()) return value;
   4994           value = PropertyCell::cast(value)->value();
   4995           if (!value->IsTheHole()) return value;
   4996           // If value is the hole do the general lookup.
   4997         }
   4998       }
   4999     } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
   5000       // JSObject without a name key. If the key is a Smi, check for a
   5001       // definite out-of-bounds access to elements, which is a strong indicator
   5002       // that subsequent accesses will also call the runtime. Proactively
   5003       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
   5004       // doubles for those future calls in the case that the elements would
   5005       // become FAST_DOUBLE_ELEMENTS.
   5006       Handle<JSObject> js_object(args.at<JSObject>(0));
   5007       ElementsKind elements_kind = js_object->GetElementsKind();
   5008       if (IsFastDoubleElementsKind(elements_kind)) {
   5009         FixedArrayBase* elements = js_object->elements();
   5010         if (args.at<Smi>(1)->value() >= elements->length()) {
   5011           if (IsFastHoleyElementsKind(elements_kind)) {
   5012             elements_kind = FAST_HOLEY_ELEMENTS;
   5013           } else {
   5014             elements_kind = FAST_ELEMENTS;
   5015           }
   5016           MaybeObject* maybe_object = TransitionElements(js_object,
   5017                                                          elements_kind,
   5018                                                          isolate);
   5019           if (maybe_object->IsFailure()) return maybe_object;
   5020         }
   5021       } else {
   5022         ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
   5023                !IsFastElementsKind(elements_kind));
   5024       }
   5025     }
   5026   } else if (args[0]->IsString() && args[1]->IsSmi()) {
   5027     // Fast case for string indexing using [] with a smi index.
   5028     HandleScope scope(isolate);
   5029     Handle<String> str = args.at<String>(0);
   5030     int index = args.smi_at(1);
   5031     if (index >= 0 && index < str->length()) {
   5032       Handle<Object> result = GetCharAt(str, index);
   5033       return *result;
   5034     }
   5035   }
   5036 
   5037   // Fall back to GetObjectProperty.
   5038   return Runtime::GetObjectProperty(isolate,
   5039                                     args.at<Object>(0),
   5040                                     args.at<Object>(1));
   5041 }
   5042 
   5043 
   5044 static bool IsValidAccessor(Handle<Object> obj) {
   5045   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
   5046 }
   5047 
   5048 
   5049 // Implements part of 8.12.9 DefineOwnProperty.
   5050 // There are 3 cases that lead here:
   5051 // Step 4b - define a new accessor property.
   5052 // Steps 9c & 12 - replace an existing data property with an accessor property.
   5053 // Step 12 - update an existing accessor property with an accessor or generic
   5054 //           descriptor.
   5055 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
   5056   HandleScope scope(isolate);
   5057   ASSERT(args.length() == 5);
   5058   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5059   RUNTIME_ASSERT(!obj->IsNull());
   5060   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5061   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   5062   RUNTIME_ASSERT(IsValidAccessor(getter));
   5063   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   5064   RUNTIME_ASSERT(IsValidAccessor(setter));
   5065   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
   5066   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5067   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   5068 
   5069   bool fast = obj->HasFastProperties();
   5070   JSObject::DefineAccessor(obj, name, getter, setter, attr);
   5071   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5072   if (fast) JSObject::TransformToFastProperties(obj, 0);
   5073   return isolate->heap()->undefined_value();
   5074 }
   5075 
   5076 
   5077 // Implements part of 8.12.9 DefineOwnProperty.
   5078 // There are 3 cases that lead here:
   5079 // Step 4a - define a new data property.
   5080 // Steps 9b & 12 - replace an existing accessor property with a data property.
   5081 // Step 12 - update an existing data property with a data or generic
   5082 //           descriptor.
   5083 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
   5084   HandleScope scope(isolate);
   5085   ASSERT(args.length() == 4);
   5086   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
   5087   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5088   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
   5089   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
   5090   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5091   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   5092 
   5093   LookupResult lookup(isolate);
   5094   js_object->LocalLookupRealNamedProperty(*name, &lookup);
   5095 
   5096   // Special case for callback properties.
   5097   if (lookup.IsPropertyCallbacks()) {
   5098     Handle<Object> callback(lookup.GetCallbackObject(), isolate);
   5099     // To be compatible with Safari we do not change the value on API objects
   5100     // in Object.defineProperty(). Firefox disagrees here, and actually changes
   5101     // the value.
   5102     if (callback->IsAccessorInfo()) {
   5103       return isolate->heap()->undefined_value();
   5104     }
   5105     // Avoid redefining foreign callback as data property, just use the stored
   5106     // setter to update the value instead.
   5107     // TODO(mstarzinger): So far this only works if property attributes don't
   5108     // change, this should be fixed once we cleanup the underlying code.
   5109     if (callback->IsForeign() && lookup.GetAttributes() == attr) {
   5110       Handle<Object> result_object =
   5111           JSObject::SetPropertyWithCallback(js_object,
   5112                                             callback,
   5113                                             name,
   5114                                             obj_value,
   5115                                             handle(lookup.holder()),
   5116                                             kStrictMode);
   5117       RETURN_IF_EMPTY_HANDLE(isolate, result_object);
   5118       return *result_object;
   5119     }
   5120   }
   5121 
   5122   // Take special care when attributes are different and there is already
   5123   // a property. For simplicity we normalize the property which enables us
   5124   // to not worry about changing the instance_descriptor and creating a new
   5125   // map. The current version of SetObjectProperty does not handle attributes
   5126   // correctly in the case where a property is a field and is reset with
   5127   // new attributes.
   5128   if (lookup.IsFound() &&
   5129       (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
   5130     // New attributes - normalize to avoid writing to instance descriptor
   5131     if (js_object->IsJSGlobalProxy()) {
   5132       // Since the result is a property, the prototype will exist so
   5133       // we don't have to check for null.
   5134       js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
   5135     }
   5136     JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
   5137     // Use IgnoreAttributes version since a readonly property may be
   5138     // overridden and SetProperty does not allow this.
   5139     Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
   5140         js_object, name, obj_value, attr);
   5141     RETURN_IF_EMPTY_HANDLE(isolate, result);
   5142     return *result;
   5143   }
   5144 
   5145   Handle<Object> result = Runtime::ForceSetObjectProperty(isolate, js_object,
   5146                                                           name,
   5147                                                           obj_value,
   5148                                                           attr);
   5149   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5150   return *result;
   5151 }
   5152 
   5153 
   5154 // Return property without being observable by accessors or interceptors.
   5155 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
   5156   SealHandleScope shs(isolate);
   5157   ASSERT(args.length() == 2);
   5158   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5159   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5160   LookupResult lookup(isolate);
   5161   object->LookupRealNamedProperty(*key, &lookup);
   5162   if (!lookup.IsFound()) return isolate->heap()->undefined_value();
   5163   switch (lookup.type()) {
   5164     case NORMAL:
   5165       return lookup.holder()->GetNormalizedProperty(&lookup);
   5166     case FIELD:
   5167       return lookup.holder()->FastPropertyAt(
   5168           lookup.representation(),
   5169           lookup.GetFieldIndex().field_index());
   5170     case CONSTANT:
   5171       return lookup.GetConstant();
   5172     case CALLBACKS:
   5173     case HANDLER:
   5174     case INTERCEPTOR:
   5175     case TRANSITION:
   5176       return isolate->heap()->undefined_value();
   5177     case NONEXISTENT:
   5178       UNREACHABLE();
   5179   }
   5180   return isolate->heap()->undefined_value();
   5181 }
   5182 
   5183 
   5184 Handle<Object> Runtime::SetObjectProperty(Isolate* isolate,
   5185                                           Handle<Object> object,
   5186                                           Handle<Object> key,
   5187                                           Handle<Object> value,
   5188                                           PropertyAttributes attr,
   5189                                           StrictModeFlag strict_mode) {
   5190   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
   5191 
   5192   if (object->IsUndefined() || object->IsNull()) {
   5193     Handle<Object> args[2] = { key, object };
   5194     Handle<Object> error =
   5195         isolate->factory()->NewTypeError("non_object_property_store",
   5196                                          HandleVector(args, 2));
   5197     isolate->Throw(*error);
   5198     return Handle<Object>();
   5199   }
   5200 
   5201   if (object->IsJSProxy()) {
   5202     bool has_pending_exception = false;
   5203     Handle<Object> name_object = key->IsSymbol()
   5204         ? key : Execution::ToString(isolate, key, &has_pending_exception);
   5205     if (has_pending_exception) return Handle<Object>();  // exception
   5206     Handle<Name> name = Handle<Name>::cast(name_object);
   5207     return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
   5208                                    attr,
   5209                                    strict_mode);
   5210   }
   5211 
   5212   // If the object isn't a JavaScript object, we ignore the store.
   5213   if (!object->IsJSObject()) return value;
   5214 
   5215   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   5216 
   5217   // Check if the given key is an array index.
   5218   uint32_t index;
   5219   if (key->ToArrayIndex(&index)) {
   5220     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5221     // of a string using [] notation.  We need to support this too in
   5222     // JavaScript.
   5223     // In the case of a String object we just need to redirect the assignment to
   5224     // the underlying string if the index is in range.  Since the underlying
   5225     // string does nothing with the assignment then we can ignore such
   5226     // assignments.
   5227     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5228       return value;
   5229     }
   5230 
   5231     js_object->ValidateElements();
   5232     if (js_object->HasExternalArrayElements()) {
   5233       if (!value->IsNumber() && !value->IsUndefined()) {
   5234         bool has_exception;
   5235         Handle<Object> number =
   5236             Execution::ToNumber(isolate, value, &has_exception);
   5237         if (has_exception) return Handle<Object>();  // exception
   5238         value = number;
   5239       }
   5240     }
   5241     Handle<Object> result = JSObject::SetElement(js_object, index, value, attr,
   5242                                                  strict_mode,
   5243                                                  true,
   5244                                                  set_mode);
   5245     js_object->ValidateElements();
   5246     return result.is_null() ? result : value;
   5247   }
   5248 
   5249   if (key->IsName()) {
   5250     Handle<Name> name = Handle<Name>::cast(key);
   5251     if (name->AsArrayIndex(&index)) {
   5252       if (js_object->HasExternalArrayElements()) {
   5253         if (!value->IsNumber() && !value->IsUndefined()) {
   5254           bool has_exception;
   5255           Handle<Object> number =
   5256               Execution::ToNumber(isolate, value, &has_exception);
   5257           if (has_exception) return Handle<Object>();  // exception
   5258           value = number;
   5259         }
   5260       }
   5261       return JSObject::SetElement(js_object, index, value, attr, strict_mode,
   5262                                   true,
   5263                                   set_mode);
   5264     } else {
   5265       if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
   5266       return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
   5267     }
   5268   }
   5269 
   5270   // Call-back into JavaScript to convert the key to a string.
   5271   bool has_pending_exception = false;
   5272   Handle<Object> converted =
   5273       Execution::ToString(isolate, key, &has_pending_exception);
   5274   if (has_pending_exception) return Handle<Object>();  // exception
   5275   Handle<String> name = Handle<String>::cast(converted);
   5276 
   5277   if (name->AsArrayIndex(&index)) {
   5278     return JSObject::SetElement(js_object, index, value, attr, strict_mode,
   5279                                 true,
   5280                                 set_mode);
   5281   } else {
   5282     return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
   5283   }
   5284 }
   5285 
   5286 
   5287 Handle<Object> Runtime::ForceSetObjectProperty(Isolate* isolate,
   5288                                                Handle<JSObject> js_object,
   5289                                                Handle<Object> key,
   5290                                                Handle<Object> value,
   5291                                                PropertyAttributes attr) {
   5292   // Check if the given key is an array index.
   5293   uint32_t index;
   5294   if (key->ToArrayIndex(&index)) {
   5295     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5296     // of a string using [] notation.  We need to support this too in
   5297     // JavaScript.
   5298     // In the case of a String object we just need to redirect the assignment to
   5299     // the underlying string if the index is in range.  Since the underlying
   5300     // string does nothing with the assignment then we can ignore such
   5301     // assignments.
   5302     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5303       return value;
   5304     }
   5305 
   5306     return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
   5307                                 false,
   5308                                 DEFINE_PROPERTY);
   5309   }
   5310 
   5311   if (key->IsName()) {
   5312     Handle<Name> name = Handle<Name>::cast(key);
   5313     if (name->AsArrayIndex(&index)) {
   5314       return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
   5315                                   false,
   5316                                   DEFINE_PROPERTY);
   5317     } else {
   5318       if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
   5319       return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name,
   5320                                                         value, attr);
   5321     }
   5322   }
   5323 
   5324   // Call-back into JavaScript to convert the key to a string.
   5325   bool has_pending_exception = false;
   5326   Handle<Object> converted =
   5327       Execution::ToString(isolate, key, &has_pending_exception);
   5328   if (has_pending_exception) return Handle<Object>();  // exception
   5329   Handle<String> name = Handle<String>::cast(converted);
   5330 
   5331   if (name->AsArrayIndex(&index)) {
   5332     return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
   5333                                 false,
   5334                                 DEFINE_PROPERTY);
   5335   } else {
   5336     return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name, value,
   5337                                                       attr);
   5338   }
   5339 }
   5340 
   5341 
   5342 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
   5343                                            Handle<JSReceiver> receiver,
   5344                                            Handle<Object> key,
   5345                                            JSReceiver::DeleteMode mode) {
   5346   HandleScope scope(isolate);
   5347 
   5348   // Check if the given key is an array index.
   5349   uint32_t index;
   5350   if (key->ToArrayIndex(&index)) {
   5351     // In Firefox/SpiderMonkey, Safari and Opera you can access the
   5352     // characters of a string using [] notation.  In the case of a
   5353     // String object we just need to redirect the deletion to the
   5354     // underlying string if the index is in range.  Since the
   5355     // underlying string does nothing with the deletion, we can ignore
   5356     // such deletions.
   5357     if (receiver->IsStringObjectWithCharacterAt(index)) {
   5358       return isolate->heap()->true_value();
   5359     }
   5360 
   5361     Handle<Object> result = JSReceiver::DeleteElement(receiver, index, mode);
   5362     RETURN_IF_EMPTY_HANDLE(isolate, result);
   5363     return *result;
   5364   }
   5365 
   5366   Handle<Name> name;
   5367   if (key->IsName()) {
   5368     name = Handle<Name>::cast(key);
   5369   } else {
   5370     // Call-back into JavaScript to convert the key to a string.
   5371     bool has_pending_exception = false;
   5372     Handle<Object> converted = Execution::ToString(
   5373         isolate, key, &has_pending_exception);
   5374     if (has_pending_exception) return Failure::Exception();
   5375     name = Handle<String>::cast(converted);
   5376   }
   5377 
   5378   if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
   5379   Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode);
   5380   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5381   return *result;
   5382 }
   5383 
   5384 
   5385 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
   5386   HandleScope scope(isolate);
   5387   RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
   5388 
   5389   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   5390   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   5391   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5392   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   5393   RUNTIME_ASSERT(
   5394       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5395   // Compute attributes.
   5396   PropertyAttributes attributes =
   5397       static_cast<PropertyAttributes>(unchecked_attributes);
   5398 
   5399   StrictModeFlag strict_mode = kNonStrictMode;
   5400   if (args.length() == 5) {
   5401     CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
   5402     strict_mode = strict_mode_flag;
   5403   }
   5404 
   5405   Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
   5406                                                      value,
   5407                                                      attributes,
   5408                                                      strict_mode);
   5409   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5410   return *result;
   5411 }
   5412 
   5413 
   5414 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) {
   5415   HandleScope scope(isolate);
   5416   RUNTIME_ASSERT(args.length() == 2);
   5417   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   5418   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
   5419   JSObject::TransitionElementsKind(array, map->elements_kind());
   5420   return *array;
   5421 }
   5422 
   5423 
   5424 // Set the native flag on the function.
   5425 // This is used to decide if we should transform null and undefined
   5426 // into the global object when doing call and apply.
   5427 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
   5428   SealHandleScope shs(isolate);
   5429   RUNTIME_ASSERT(args.length() == 1);
   5430 
   5431   CONVERT_ARG_CHECKED(Object, object, 0);
   5432 
   5433   if (object->IsJSFunction()) {
   5434     JSFunction* func = JSFunction::cast(object);
   5435     func->shared()->set_native(true);
   5436   }
   5437   return isolate->heap()->undefined_value();
   5438 }
   5439 
   5440 
   5441 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) {
   5442   SealHandleScope shs(isolate);
   5443   RUNTIME_ASSERT(args.length() == 1);
   5444 
   5445   Handle<Object> object = args.at<Object>(0);
   5446 
   5447   if (object->IsJSFunction()) {
   5448     JSFunction* func = JSFunction::cast(*object);
   5449     func->shared()->set_inline_builtin(true);
   5450   }
   5451   return isolate->heap()->undefined_value();
   5452 }
   5453 
   5454 
   5455 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
   5456   HandleScope scope(isolate);
   5457   RUNTIME_ASSERT(args.length() == 5);
   5458   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5459   CONVERT_SMI_ARG_CHECKED(store_index, 1);
   5460   Handle<Object> value = args.at<Object>(2);
   5461   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
   5462   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
   5463 
   5464   Object* raw_literal_cell = literals->get(literal_index);
   5465   JSArray* boilerplate = NULL;
   5466   if (raw_literal_cell->IsAllocationSite()) {
   5467     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
   5468     boilerplate = JSArray::cast(site->transition_info());
   5469   } else {
   5470     boilerplate = JSArray::cast(raw_literal_cell);
   5471   }
   5472   Handle<JSArray> boilerplate_object(boilerplate);
   5473   ElementsKind elements_kind = object->GetElementsKind();
   5474   ASSERT(IsFastElementsKind(elements_kind));
   5475   // Smis should never trigger transitions.
   5476   ASSERT(!value->IsSmi());
   5477 
   5478   if (value->IsNumber()) {
   5479     ASSERT(IsFastSmiElementsKind(elements_kind));
   5480     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5481         ? FAST_HOLEY_DOUBLE_ELEMENTS
   5482         : FAST_DOUBLE_ELEMENTS;
   5483     if (IsMoreGeneralElementsKindTransition(
   5484             boilerplate_object->GetElementsKind(),
   5485             transitioned_kind)) {
   5486       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5487     }
   5488     JSObject::TransitionElementsKind(object, transitioned_kind);
   5489     ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
   5490     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
   5491     HeapNumber* number = HeapNumber::cast(*value);
   5492     double_array->set(store_index, number->Number());
   5493   } else {
   5494     ASSERT(IsFastSmiElementsKind(elements_kind) ||
   5495            IsFastDoubleElementsKind(elements_kind));
   5496     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5497         ? FAST_HOLEY_ELEMENTS
   5498         : FAST_ELEMENTS;
   5499     JSObject::TransitionElementsKind(object, transitioned_kind);
   5500     if (IsMoreGeneralElementsKindTransition(
   5501             boilerplate_object->GetElementsKind(),
   5502             transitioned_kind)) {
   5503       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5504     }
   5505     FixedArray* object_array = FixedArray::cast(object->elements());
   5506     object_array->set(store_index, *value);
   5507   }
   5508   return *object;
   5509 }
   5510 
   5511 
   5512 // Check whether debugger and is about to step into the callback that is passed
   5513 // to a built-in function such as Array.forEach.
   5514 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) {
   5515   SealHandleScope shs(isolate);
   5516 #ifdef ENABLE_DEBUGGER_SUPPORT
   5517   if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
   5518     return isolate->heap()->false_value();
   5519   }
   5520   CONVERT_ARG_CHECKED(Object, callback, 0);
   5521   // We do not step into the callback if it's a builtin or not even a function.
   5522   if (!callback->IsJSFunction() || JSFunction::cast(callback)->IsBuiltin()) {
   5523     return isolate->heap()->false_value();
   5524   }
   5525   return isolate->heap()->true_value();
   5526 #else
   5527   return isolate->heap()->false_value();
   5528 #endif  // ENABLE_DEBUGGER_SUPPORT
   5529 }
   5530 
   5531 
   5532 // Set one shot breakpoints for the callback function that is passed to a
   5533 // built-in function such as Array.forEach to enable stepping into the callback.
   5534 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
   5535   SealHandleScope shs(isolate);
   5536 #ifdef ENABLE_DEBUGGER_SUPPORT
   5537   Debug* debug = isolate->debug();
   5538   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
   5539   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
   5540   HandleScope scope(isolate);
   5541   // When leaving the callback, step out has been activated, but not performed
   5542   // if we do not leave the builtin.  To be able to step into the callback
   5543   // again, we need to clear the step out at this point.
   5544   debug->ClearStepOut();
   5545   debug->FloodWithOneShot(callback);
   5546 #endif  // ENABLE_DEBUGGER_SUPPORT
   5547   return isolate->heap()->undefined_value();
   5548 }
   5549 
   5550 
   5551 // Set a local property, even if it is READ_ONLY.  If the property does not
   5552 // exist, it will be added with attributes NONE.
   5553 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
   5554   HandleScope scope(isolate);
   5555   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
   5556   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5557   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   5558   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   5559   // Compute attributes.
   5560   PropertyAttributes attributes = NONE;
   5561   if (args.length() == 4) {
   5562     CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
   5563     // Only attribute bits should be set.
   5564     RUNTIME_ASSERT(
   5565         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5566     attributes = static_cast<PropertyAttributes>(unchecked_value);
   5567   }
   5568   Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
   5569       object, name, value, attributes);
   5570   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5571   return *result;
   5572 }
   5573 
   5574 
   5575 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
   5576   HandleScope scope(isolate);
   5577   ASSERT(args.length() == 3);
   5578   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5579   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5580   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
   5581   JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode)
   5582       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
   5583   Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode);
   5584   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5585   return *result;
   5586 }
   5587 
   5588 
   5589 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
   5590                                                    Handle<JSObject> object,
   5591                                                    Handle<Name> key) {
   5592   if (JSReceiver::HasLocalProperty(object, key)) {
   5593     return isolate->heap()->true_value();
   5594   }
   5595   // Handle hidden prototypes.  If there's a hidden prototype above this thing
   5596   // then we have to check it for properties, because they are supposed to
   5597   // look like they are on this object.
   5598   Handle<Object> proto(object->GetPrototype(), isolate);
   5599   if (proto->IsJSObject() &&
   5600       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
   5601     return HasLocalPropertyImplementation(isolate,
   5602                                           Handle<JSObject>::cast(proto),
   5603                                           key);
   5604   }
   5605   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5606   return isolate->heap()->false_value();
   5607 }
   5608 
   5609 
   5610 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
   5611   HandleScope scope(isolate);
   5612   ASSERT(args.length() == 2);
   5613   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5614   Handle<Object> object = args.at<Object>(0);
   5615 
   5616   uint32_t index;
   5617   const bool key_is_array_index = key->AsArrayIndex(&index);
   5618 
   5619   // Only JS objects can have properties.
   5620   if (object->IsJSObject()) {
   5621     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
   5622     // Fast case: either the key is a real named property or it is not
   5623     // an array index and there are no interceptors or hidden
   5624     // prototypes.
   5625     if (JSObject::HasRealNamedProperty(js_obj, key)) {
   5626       ASSERT(!isolate->has_scheduled_exception());
   5627       return isolate->heap()->true_value();
   5628     } else {
   5629       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5630     }
   5631     Map* map = js_obj->map();
   5632     if (!key_is_array_index &&
   5633         !map->has_named_interceptor() &&
   5634         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
   5635       return isolate->heap()->false_value();
   5636     }
   5637     // Slow case.
   5638     return HasLocalPropertyImplementation(isolate,
   5639                                           Handle<JSObject>(js_obj),
   5640                                           Handle<Name>(key));
   5641   } else if (object->IsString() && key_is_array_index) {
   5642     // Well, there is one exception:  Handle [] on strings.
   5643     Handle<String> string = Handle<String>::cast(object);
   5644     if (index < static_cast<uint32_t>(string->length())) {
   5645       return isolate->heap()->true_value();
   5646     }
   5647   }
   5648   return isolate->heap()->false_value();
   5649 }
   5650 
   5651 
   5652 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
   5653   HandleScope scope(isolate);
   5654   ASSERT(args.length() == 2);
   5655   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   5656   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5657 
   5658   bool result = JSReceiver::HasProperty(receiver, key);
   5659   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5660   if (isolate->has_pending_exception()) return Failure::Exception();
   5661   return isolate->heap()->ToBoolean(result);
   5662 }
   5663 
   5664 
   5665 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
   5666   HandleScope scope(isolate);
   5667   ASSERT(args.length() == 2);
   5668   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   5669   CONVERT_SMI_ARG_CHECKED(index, 1);
   5670 
   5671   bool result = JSReceiver::HasElement(receiver, index);
   5672   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5673   if (isolate->has_pending_exception()) return Failure::Exception();
   5674   return isolate->heap()->ToBoolean(result);
   5675 }
   5676 
   5677 
   5678 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
   5679   SealHandleScope shs(isolate);
   5680   ASSERT(args.length() == 2);
   5681 
   5682   CONVERT_ARG_CHECKED(JSObject, object, 0);
   5683   CONVERT_ARG_CHECKED(Name, key, 1);
   5684 
   5685   PropertyAttributes att = object->GetLocalPropertyAttribute(key);
   5686   if (att == ABSENT || (att & DONT_ENUM) != 0) {
   5687     RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5688     return isolate->heap()->false_value();
   5689   }
   5690   ASSERT(!isolate->has_scheduled_exception());
   5691   return isolate->heap()->true_value();
   5692 }
   5693 
   5694 
   5695 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
   5696   HandleScope scope(isolate);
   5697   ASSERT(args.length() == 1);
   5698   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5699   bool threw = false;
   5700   Handle<JSArray> result = GetKeysFor(object, &threw);
   5701   if (threw) return Failure::Exception();
   5702   return *result;
   5703 }
   5704 
   5705 
   5706 // Returns either a FixedArray as Runtime_GetPropertyNames,
   5707 // or, if the given object has an enum cache that contains
   5708 // all enumerable properties of the object and its prototypes
   5709 // have none, the map of the object. This is used to speed up
   5710 // the check for deletions during a for-in.
   5711 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
   5712   SealHandleScope shs(isolate);
   5713   ASSERT(args.length() == 1);
   5714 
   5715   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
   5716 
   5717   if (raw_object->IsSimpleEnum()) return raw_object->map();
   5718 
   5719   HandleScope scope(isolate);
   5720   Handle<JSReceiver> object(raw_object);
   5721   bool threw = false;
   5722   Handle<FixedArray> content =
   5723       GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw);
   5724   if (threw) return Failure::Exception();
   5725 
   5726   // Test again, since cache may have been built by preceding call.
   5727   if (object->IsSimpleEnum()) return object->map();
   5728 
   5729   return *content;
   5730 }
   5731 
   5732 
   5733 // Find the length of the prototype chain that is to to handled as one. If a
   5734 // prototype object is hidden it is to be viewed as part of the the object it
   5735 // is prototype for.
   5736 static int LocalPrototypeChainLength(JSObject* obj) {
   5737   int count = 1;
   5738   Object* proto = obj->GetPrototype();
   5739   while (proto->IsJSObject() &&
   5740          JSObject::cast(proto)->map()->is_hidden_prototype()) {
   5741     count++;
   5742     proto = JSObject::cast(proto)->GetPrototype();
   5743   }
   5744   return count;
   5745 }
   5746 
   5747 
   5748 // Return the names of the local named properties.
   5749 // args[0]: object
   5750 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
   5751   HandleScope scope(isolate);
   5752   ASSERT(args.length() == 2);
   5753   if (!args[0]->IsJSObject()) {
   5754     return isolate->heap()->undefined_value();
   5755   }
   5756   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5757   CONVERT_BOOLEAN_ARG_CHECKED(include_symbols, 1);
   5758   PropertyAttributes filter = include_symbols ? NONE : SYMBOLIC;
   5759 
   5760   // Skip the global proxy as it has no properties and always delegates to the
   5761   // real global object.
   5762   if (obj->IsJSGlobalProxy()) {
   5763     // Only collect names if access is permitted.
   5764     if (obj->IsAccessCheckNeeded() &&
   5765         !isolate->MayNamedAccess(*obj,
   5766                                  isolate->heap()->undefined_value(),
   5767                                  v8::ACCESS_KEYS)) {
   5768       isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS);
   5769       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5770       return *isolate->factory()->NewJSArray(0);
   5771     }
   5772     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   5773   }
   5774 
   5775   // Find the number of objects making up this.
   5776   int length = LocalPrototypeChainLength(*obj);
   5777 
   5778   // Find the number of local properties for each of the objects.
   5779   ScopedVector<int> local_property_count(length);
   5780   int total_property_count = 0;
   5781   Handle<JSObject> jsproto = obj;
   5782   for (int i = 0; i < length; i++) {
   5783     // Only collect names if access is permitted.
   5784     if (jsproto->IsAccessCheckNeeded() &&
   5785         !isolate->MayNamedAccess(*jsproto,
   5786                                  isolate->heap()->undefined_value(),
   5787                                  v8::ACCESS_KEYS)) {
   5788       isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS);
   5789       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5790       return *isolate->factory()->NewJSArray(0);
   5791     }
   5792     int n;
   5793     n = jsproto->NumberOfLocalProperties(filter);
   5794     local_property_count[i] = n;
   5795     total_property_count += n;
   5796     if (i < length - 1) {
   5797       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   5798     }
   5799   }
   5800 
   5801   // Allocate an array with storage for all the property names.
   5802   Handle<FixedArray> names =
   5803       isolate->factory()->NewFixedArray(total_property_count);
   5804 
   5805   // Get the property names.
   5806   jsproto = obj;
   5807   int proto_with_hidden_properties = 0;
   5808   int next_copy_index = 0;
   5809   for (int i = 0; i < length; i++) {
   5810     jsproto->GetLocalPropertyNames(*names, next_copy_index, filter);
   5811     next_copy_index += local_property_count[i];
   5812     if (jsproto->HasHiddenProperties()) {
   5813       proto_with_hidden_properties++;
   5814     }
   5815     if (i < length - 1) {
   5816       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   5817     }
   5818   }
   5819 
   5820   // Filter out name of hidden properties object.
   5821   if (proto_with_hidden_properties > 0) {
   5822     Handle<FixedArray> old_names = names;
   5823     names = isolate->factory()->NewFixedArray(
   5824         names->length() - proto_with_hidden_properties);
   5825     int dest_pos = 0;
   5826     for (int i = 0; i < total_property_count; i++) {
   5827       Object* name = old_names->get(i);
   5828       if (name == isolate->heap()->hidden_string()) {
   5829         continue;
   5830       }
   5831       names->set(dest_pos++, name);
   5832     }
   5833   }
   5834 
   5835   return *isolate->factory()->NewJSArrayWithElements(names);
   5836 }
   5837 
   5838 
   5839 // Return the names of the local indexed properties.
   5840 // args[0]: object
   5841 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalElementNames) {
   5842   HandleScope scope(isolate);
   5843   ASSERT(args.length() == 1);
   5844   if (!args[0]->IsJSObject()) {
   5845     return isolate->heap()->undefined_value();
   5846   }
   5847   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5848 
   5849   int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
   5850   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
   5851   obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
   5852   return *isolate->factory()->NewJSArrayWithElements(names);
   5853 }
   5854 
   5855 
   5856 // Return information on whether an object has a named or indexed interceptor.
   5857 // args[0]: object
   5858 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetInterceptorInfo) {
   5859   HandleScope scope(isolate);
   5860   ASSERT(args.length() == 1);
   5861   if (!args[0]->IsJSObject()) {
   5862     return Smi::FromInt(0);
   5863   }
   5864   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5865 
   5866   int result = 0;
   5867   if (obj->HasNamedInterceptor()) result |= 2;
   5868   if (obj->HasIndexedInterceptor()) result |= 1;
   5869 
   5870   return Smi::FromInt(result);
   5871 }
   5872 
   5873 
   5874 // Return property names from named interceptor.
   5875 // args[0]: object
   5876 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
   5877   HandleScope scope(isolate);
   5878   ASSERT(args.length() == 1);
   5879   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5880 
   5881   if (obj->HasNamedInterceptor()) {
   5882     v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
   5883     if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
   5884   }
   5885   return isolate->heap()->undefined_value();
   5886 }
   5887 
   5888 
   5889 // Return element names from indexed interceptor.
   5890 // args[0]: object
   5891 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetIndexedInterceptorElementNames) {
   5892   HandleScope scope(isolate);
   5893   ASSERT(args.length() == 1);
   5894   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5895 
   5896   if (obj->HasIndexedInterceptor()) {
   5897     v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
   5898     if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
   5899   }
   5900   return isolate->heap()->undefined_value();
   5901 }
   5902 
   5903 
   5904 RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
   5905   HandleScope scope(isolate);
   5906   ASSERT_EQ(args.length(), 1);
   5907   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
   5908   Handle<JSObject> object(raw_object);
   5909 
   5910   if (object->IsJSGlobalProxy()) {
   5911     // Do access checks before going to the global object.
   5912     if (object->IsAccessCheckNeeded() &&
   5913         !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
   5914                              v8::ACCESS_KEYS)) {
   5915       isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
   5916       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5917       return *isolate->factory()->NewJSArray(0);
   5918     }
   5919 
   5920     Handle<Object> proto(object->GetPrototype(), isolate);
   5921     // If proxy is detached we simply return an empty array.
   5922     if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
   5923     object = Handle<JSObject>::cast(proto);
   5924   }
   5925 
   5926   bool threw = false;
   5927   Handle<FixedArray> contents =
   5928       GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
   5929   if (threw) return Failure::Exception();
   5930 
   5931   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
   5932   // property array and since the result is mutable we have to create
   5933   // a fresh clone on each invocation.
   5934   int length = contents->length();
   5935   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
   5936   for (int i = 0; i < length; i++) {
   5937     Object* entry = contents->get(i);
   5938     if (entry->IsString()) {
   5939       copy->set(i, entry);
   5940     } else {
   5941       ASSERT(entry->IsNumber());
   5942       HandleScope scope(isolate);
   5943       Handle<Object> entry_handle(entry, isolate);
   5944       Handle<Object> entry_str =
   5945           isolate->factory()->NumberToString(entry_handle);
   5946       copy->set(i, *entry_str);
   5947     }
   5948   }
   5949   return *isolate->factory()->NewJSArrayWithElements(copy);
   5950 }
   5951 
   5952 
   5953 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
   5954   SealHandleScope shs(isolate);
   5955   ASSERT(args.length() == 1);
   5956 
   5957   // Compute the frame holding the arguments.
   5958   JavaScriptFrameIterator it(isolate);
   5959   it.AdvanceToArgumentsFrame();
   5960   JavaScriptFrame* frame = it.frame();
   5961 
   5962   // Get the actual number of provided arguments.
   5963   const uint32_t n = frame->ComputeParametersCount();
   5964 
   5965   // Try to convert the key to an index. If successful and within
   5966   // index return the the argument from the frame.
   5967   uint32_t index;
   5968   if (args[0]->ToArrayIndex(&index) && index < n) {
   5969     return frame->GetParameter(index);
   5970   }
   5971 
   5972   if (args[0]->IsSymbol()) {
   5973     // Lookup in the initial Object.prototype object.
   5974     return isolate->initial_object_prototype()->GetProperty(
   5975         Symbol::cast(args[0]));
   5976   }
   5977 
   5978   // Convert the key to a string.
   5979   HandleScope scope(isolate);
   5980   bool exception = false;
   5981   Handle<Object> converted =
   5982       Execution::ToString(isolate, args.at<Object>(0), &exception);
   5983   if (exception) return Failure::Exception();
   5984   Handle<String> key = Handle<String>::cast(converted);
   5985 
   5986   // Try to convert the string key into an array index.
   5987   if (key->AsArrayIndex(&index)) {
   5988     if (index < n) {
   5989       return frame->GetParameter(index);
   5990     } else {
   5991       return isolate->initial_object_prototype()->GetElement(isolate, index);
   5992     }
   5993   }
   5994 
   5995   // Handle special arguments properties.
   5996   if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n);
   5997   if (key->Equals(isolate->heap()->callee_string())) {
   5998     JSFunction* function = frame->function();
   5999     if (!function->shared()->is_classic_mode()) {
   6000       return isolate->Throw(*isolate->factory()->NewTypeError(
   6001           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
   6002     }
   6003     return function;
   6004   }
   6005 
   6006   // Lookup in the initial Object.prototype object.
   6007   return isolate->initial_object_prototype()->GetProperty(*key);
   6008 }
   6009 
   6010 
   6011 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
   6012   HandleScope scope(isolate);
   6013   ASSERT(args.length() == 1);
   6014   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   6015   if (object->IsJSObject() && !object->IsGlobalObject()) {
   6016     JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0);
   6017   }
   6018   return *object;
   6019 }
   6020 
   6021 
   6022 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
   6023   SealHandleScope shs(isolate);
   6024   ASSERT(args.length() == 1);
   6025 
   6026   return isolate->heap()->ToBoolean(args[0]->BooleanValue());
   6027 }
   6028 
   6029 
   6030 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
   6031 // Possible optimizations: put the type string into the oddballs.
   6032 RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
   6033   SealHandleScope shs(isolate);
   6034 
   6035   Object* obj = args[0];
   6036   if (obj->IsNumber()) return isolate->heap()->number_string();
   6037   HeapObject* heap_obj = HeapObject::cast(obj);
   6038 
   6039   // typeof an undetectable object is 'undefined'
   6040   if (heap_obj->map()->is_undetectable()) {
   6041     return isolate->heap()->undefined_string();
   6042   }
   6043 
   6044   InstanceType instance_type = heap_obj->map()->instance_type();
   6045   if (instance_type < FIRST_NONSTRING_TYPE) {
   6046     return isolate->heap()->string_string();
   6047   }
   6048 
   6049   switch (instance_type) {
   6050     case ODDBALL_TYPE:
   6051       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
   6052         return isolate->heap()->boolean_string();
   6053       }
   6054       if (heap_obj->IsNull()) {
   6055         return FLAG_harmony_typeof
   6056             ? isolate->heap()->null_string()
   6057             : isolate->heap()->object_string();
   6058       }
   6059       ASSERT(heap_obj->IsUndefined());
   6060       return isolate->heap()->undefined_string();
   6061     case SYMBOL_TYPE:
   6062       return isolate->heap()->symbol_string();
   6063     case JS_FUNCTION_TYPE:
   6064     case JS_FUNCTION_PROXY_TYPE:
   6065       return isolate->heap()->function_string();
   6066     default:
   6067       // For any kind of object not handled above, the spec rule for
   6068       // host objects gives that it is okay to return "object"
   6069       return isolate->heap()->object_string();
   6070   }
   6071 }
   6072 
   6073 
   6074 static bool AreDigits(const uint8_t*s, int from, int to) {
   6075   for (int i = from; i < to; i++) {
   6076     if (s[i] < '0' || s[i] > '9') return false;
   6077   }
   6078 
   6079   return true;
   6080 }
   6081 
   6082 
   6083 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
   6084   ASSERT(to - from < 10);  // Overflow is not possible.
   6085   ASSERT(from < to);
   6086   int d = s[from] - '0';
   6087 
   6088   for (int i = from + 1; i < to; i++) {
   6089     d = 10 * d + (s[i] - '0');
   6090   }
   6091 
   6092   return d;
   6093 }
   6094 
   6095 
   6096 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
   6097   SealHandleScope shs(isolate);
   6098   ASSERT(args.length() == 1);
   6099   CONVERT_ARG_CHECKED(String, subject, 0);
   6100   subject->TryFlatten();
   6101 
   6102   // Fast case: short integer or some sorts of junk values.
   6103   int len = subject->length();
   6104   if (subject->IsSeqOneByteString()) {
   6105     if (len == 0) return Smi::FromInt(0);
   6106 
   6107     uint8_t const* data = SeqOneByteString::cast(subject)->GetChars();
   6108     bool minus = (data[0] == '-');
   6109     int start_pos = (minus ? 1 : 0);
   6110 
   6111     if (start_pos == len) {
   6112       return isolate->heap()->nan_value();
   6113     } else if (data[start_pos] > '9') {
   6114       // Fast check for a junk value. A valid string may start from a
   6115       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
   6116       // the 'I' character ('Infinity'). All of that have codes not greater than
   6117       // '9' except 'I' and &nbsp;.
   6118       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   6119         return isolate->heap()->nan_value();
   6120       }
   6121     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   6122       // The maximal/minimal smi has 10 digits. If the string has less digits we
   6123       // know it will fit into the smi-data type.
   6124       int d = ParseDecimalInteger(data, start_pos, len);
   6125       if (minus) {
   6126         if (d == 0) return isolate->heap()->minus_zero_value();
   6127         d = -d;
   6128       } else if (!subject->HasHashCode() &&
   6129                  len <= String::kMaxArrayIndexSize &&
   6130                  (len == 1 || data[0] != '0')) {
   6131         // String hash is not calculated yet but all the data are present.
   6132         // Update the hash field to speed up sequential convertions.
   6133         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   6134 #ifdef DEBUG
   6135         subject->Hash();  // Force hash calculation.
   6136         ASSERT_EQ(static_cast<int>(subject->hash_field()),
   6137                   static_cast<int>(hash));
   6138 #endif
   6139         subject->set_hash_field(hash);
   6140       }
   6141       return Smi::FromInt(d);
   6142     }
   6143   }
   6144 
   6145   // Slower case.
   6146   int flags = ALLOW_HEX;
   6147   if (FLAG_harmony_numeric_literals) {
   6148     // The current spec draft has not updated "ToNumber Applied to the String
   6149     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
   6150     flags |= ALLOW_OCTAL | ALLOW_BINARY;
   6151   }
   6152   return isolate->heap()->NumberFromDouble(
   6153       StringToDouble(isolate->unicode_cache(), subject, flags));
   6154 }
   6155 
   6156 
   6157 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) {
   6158   SealHandleScope shs(isolate);
   6159   CONVERT_SMI_ARG_CHECKED(length, 0);
   6160   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
   6161   if (length == 0) return isolate->heap()->empty_string();
   6162   if (is_one_byte) {
   6163     return isolate->heap()->AllocateRawOneByteString(length);
   6164   } else {
   6165     return isolate->heap()->AllocateRawTwoByteString(length);
   6166   }
   6167 }
   6168 
   6169 
   6170 RUNTIME_FUNCTION(MaybeObject*, Runtime_TruncateString) {
   6171   HandleScope scope(isolate);
   6172   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
   6173   CONVERT_SMI_ARG_CHECKED(new_length, 1);
   6174   return *SeqString::Truncate(string, new_length);
   6175 }
   6176 
   6177 
   6178 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
   6179   HandleScope scope(isolate);
   6180   ASSERT(args.length() == 1);
   6181   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6182   Handle<String> string = FlattenGetString(source);
   6183   ASSERT(string->IsFlat());
   6184   Handle<String> result = string->IsOneByteRepresentationUnderneath()
   6185       ? URIEscape::Escape<uint8_t>(isolate, source)
   6186       : URIEscape::Escape<uc16>(isolate, source);
   6187   if (result.is_null()) return Failure::OutOfMemoryException(0x12);
   6188   return *result;
   6189 }
   6190 
   6191 
   6192 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
   6193   HandleScope scope(isolate);
   6194   ASSERT(args.length() == 1);
   6195   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6196   Handle<String> string = FlattenGetString(source);
   6197   ASSERT(string->IsFlat());
   6198   return string->IsOneByteRepresentationUnderneath()
   6199       ? *URIUnescape::Unescape<uint8_t>(isolate, source)
   6200       : *URIUnescape::Unescape<uc16>(isolate, source);
   6201 }
   6202 
   6203 
   6204 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
   6205   HandleScope scope(isolate);
   6206   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   6207   ASSERT(args.length() == 1);
   6208   return BasicJsonStringifier::StringifyString(isolate, string);
   6209 }
   6210 
   6211 
   6212 RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
   6213   HandleScope scope(isolate);
   6214   ASSERT(args.length() == 1);
   6215   BasicJsonStringifier stringifier(isolate);
   6216   return stringifier.Stringify(Handle<Object>(args[0], isolate));
   6217 }
   6218 
   6219 
   6220 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
   6221   SealHandleScope shs(isolate);
   6222 
   6223   CONVERT_ARG_CHECKED(String, s, 0);
   6224   CONVERT_SMI_ARG_CHECKED(radix, 1);
   6225 
   6226   s->TryFlatten();
   6227 
   6228   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
   6229   double value = StringToInt(isolate->unicode_cache(), s, radix);
   6230   return isolate->heap()->NumberFromDouble(value);
   6231 }
   6232 
   6233 
   6234 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
   6235   SealHandleScope shs(isolate);
   6236   CONVERT_ARG_CHECKED(String, str, 0);
   6237 
   6238   // ECMA-262 section 15.1.2.3, empty string is NaN
   6239   double value = StringToDouble(isolate->unicode_cache(),
   6240                                 str, ALLOW_TRAILING_JUNK, OS::nan_value());
   6241 
   6242   // Create a number object from the value.
   6243   return isolate->heap()->NumberFromDouble(value);
   6244 }
   6245 
   6246 
   6247 template <class Converter>
   6248 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
   6249     Isolate* isolate,
   6250     String* s,
   6251     String::Encoding result_encoding,
   6252     int length,
   6253     int input_string_length,
   6254     unibrow::Mapping<Converter, 128>* mapping) {
   6255   // We try this twice, once with the assumption that the result is no longer
   6256   // than the input and, if that assumption breaks, again with the exact
   6257   // length.  This may not be pretty, but it is nicer than what was here before
   6258   // and I hereby claim my vaffel-is.
   6259   //
   6260   // Allocate the resulting string.
   6261   //
   6262   // NOTE: This assumes that the upper/lower case of an ASCII
   6263   // character is also ASCII.  This is currently the case, but it
   6264   // might break in the future if we implement more context and locale
   6265   // dependent upper/lower conversions.
   6266   Object* o;
   6267   { MaybeObject* maybe_o = result_encoding == String::ONE_BYTE_ENCODING
   6268         ? isolate->heap()->AllocateRawOneByteString(length)
   6269         : isolate->heap()->AllocateRawTwoByteString(length);
   6270     if (!maybe_o->ToObject(&o)) return maybe_o;
   6271   }
   6272   String* result = String::cast(o);
   6273   bool has_changed_character = false;
   6274 
   6275   DisallowHeapAllocation no_gc;
   6276 
   6277   // Convert all characters to upper case, assuming that they will fit
   6278   // in the buffer
   6279   Access<ConsStringIteratorOp> op(
   6280       isolate->runtime_state()->string_iterator());
   6281   StringCharacterStream stream(s, op.value());
   6282   unibrow::uchar chars[Converter::kMaxWidth];
   6283   // We can assume that the string is not empty
   6284   uc32 current = stream.GetNext();
   6285   // y with umlauts is the only character that stops fitting into one-byte
   6286   // when converting to uppercase.
   6287   static const uc32 yuml_code = 0xff;
   6288   bool ignore_yuml = result->IsSeqTwoByteString() || Converter::kIsToLower;
   6289   for (int i = 0; i < length;) {
   6290     bool has_next = stream.HasMore();
   6291     uc32 next = has_next ? stream.GetNext() : 0;
   6292     int char_length = mapping->get(current, next, chars);
   6293     if (char_length == 0) {
   6294       // The case conversion of this character is the character itself.
   6295       result->Set(i, current);
   6296       i++;
   6297     } else if (char_length == 1 && (ignore_yuml || current != yuml_code)) {
   6298       // Common case: converting the letter resulted in one character.
   6299       ASSERT(static_cast<uc32>(chars[0]) != current);
   6300       result->Set(i, chars[0]);
   6301       has_changed_character = true;
   6302       i++;
   6303     } else if (length == input_string_length) {
   6304       bool found_yuml = (current == yuml_code);
   6305       // We've assumed that the result would be as long as the
   6306       // input but here is a character that converts to several
   6307       // characters.  No matter, we calculate the exact length
   6308       // of the result and try the whole thing again.
   6309       //
   6310       // Note that this leaves room for optimization.  We could just
   6311       // memcpy what we already have to the result string.  Also,
   6312       // the result string is the last object allocated we could
   6313       // "realloc" it and probably, in the vast majority of cases,
   6314       // extend the existing string to be able to hold the full
   6315       // result.
   6316       int next_length = 0;
   6317       if (has_next) {
   6318         next_length = mapping->get(next, 0, chars);
   6319         if (next_length == 0) next_length = 1;
   6320       }
   6321       int current_length = i + char_length + next_length;
   6322       while (stream.HasMore()) {
   6323         current = stream.GetNext();
   6324         found_yuml |= (current == yuml_code);
   6325         // NOTE: we use 0 as the next character here because, while
   6326         // the next character may affect what a character converts to,
   6327         // it does not in any case affect the length of what it convert
   6328         // to.
   6329         int char_length = mapping->get(current, 0, chars);
   6330         if (char_length == 0) char_length = 1;
   6331         current_length += char_length;
   6332         if (current_length > Smi::kMaxValue) {
   6333           isolate->context()->mark_out_of_memory();
   6334           return Failure::OutOfMemoryException(0x13);
   6335         }
   6336       }
   6337       // Try again with the real length.  Return signed if we need
   6338       // to allocate a two-byte string for y-umlaut to uppercase.
   6339       return (found_yuml && !ignore_yuml) ? Smi::FromInt(-current_length)
   6340                                           : Smi::FromInt(current_length);
   6341     } else {
   6342       for (int j = 0; j < char_length; j++) {
   6343         result->Set(i, chars[j]);
   6344         i++;
   6345       }
   6346       has_changed_character = true;
   6347     }
   6348     current = next;
   6349   }
   6350   if (has_changed_character) {
   6351     return result;
   6352   } else {
   6353     // If we didn't actually change anything in doing the conversion
   6354     // we simple return the result and let the converted string
   6355     // become garbage; there is no reason to keep two identical strings
   6356     // alive.
   6357     return s;
   6358   }
   6359 }
   6360 
   6361 
   6362 namespace {
   6363 
   6364 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
   6365 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
   6366 
   6367 // Given a word and two range boundaries returns a word with high bit
   6368 // set in every byte iff the corresponding input byte was strictly in
   6369 // the range (m, n). All the other bits in the result are cleared.
   6370 // This function is only useful when it can be inlined and the
   6371 // boundaries are statically known.
   6372 // Requires: all bytes in the input word and the boundaries must be
   6373 // ASCII (less than 0x7F).
   6374 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
   6375   // Use strict inequalities since in edge cases the function could be
   6376   // further simplified.
   6377   ASSERT(0 < m && m < n);
   6378   // Has high bit set in every w byte less than n.
   6379   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   6380   // Has high bit set in every w byte greater than m.
   6381   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
   6382   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
   6383 }
   6384 
   6385 
   6386 #ifdef DEBUG
   6387 static bool CheckFastAsciiConvert(char* dst,
   6388                                   char* src,
   6389                                   int length,
   6390                                   bool changed,
   6391                                   bool is_to_lower) {
   6392   bool expected_changed = false;
   6393   for (int i = 0; i < length; i++) {
   6394     if (dst[i] == src[i]) continue;
   6395     expected_changed = true;
   6396     if (is_to_lower) {
   6397       ASSERT('A' <= src[i] && src[i] <= 'Z');
   6398       ASSERT(dst[i] == src[i] + ('a' - 'A'));
   6399     } else {
   6400       ASSERT('a' <= src[i] && src[i] <= 'z');
   6401       ASSERT(dst[i] == src[i] - ('a' - 'A'));
   6402     }
   6403   }
   6404   return (expected_changed == changed);
   6405 }
   6406 #endif
   6407 
   6408 
   6409 template<class Converter>
   6410 static bool FastAsciiConvert(char* dst,
   6411                              char* src,
   6412                              int length,
   6413                              bool* changed_out) {
   6414 #ifdef DEBUG
   6415     char* saved_dst = dst;
   6416     char* saved_src = src;
   6417 #endif
   6418   DisallowHeapAllocation no_gc;
   6419   // We rely on the distance between upper and lower case letters
   6420   // being a known power of 2.
   6421   ASSERT('a' - 'A' == (1 << 5));
   6422   // Boundaries for the range of input characters than require conversion.
   6423   static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
   6424   static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
   6425   bool changed = false;
   6426   uintptr_t or_acc = 0;
   6427   char* const limit = src + length;
   6428 #ifdef V8_HOST_CAN_READ_UNALIGNED
   6429   // Process the prefix of the input that requires no conversion one
   6430   // (machine) word at a time.
   6431   while (src <= limit - sizeof(uintptr_t)) {
   6432     uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
   6433     or_acc |= w;
   6434     if (AsciiRangeMask(w, lo, hi) != 0) {
   6435       changed = true;
   6436       break;
   6437     }
   6438     *reinterpret_cast<uintptr_t*>(dst) = w;
   6439     src += sizeof(uintptr_t);
   6440     dst += sizeof(uintptr_t);
   6441   }
   6442   // Process the remainder of the input performing conversion when
   6443   // required one word at a time.
   6444   while (src <= limit - sizeof(uintptr_t)) {
   6445     uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
   6446     or_acc |= w;
   6447     uintptr_t m = AsciiRangeMask(w, lo, hi);
   6448     // The mask has high (7th) bit set in every byte that needs
   6449     // conversion and we know that the distance between cases is
   6450     // 1 << 5.
   6451     *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
   6452     src += sizeof(uintptr_t);
   6453     dst += sizeof(uintptr_t);
   6454   }
   6455 #endif
   6456   // Process the last few bytes of the input (or the whole input if
   6457   // unaligned access is not supported).
   6458   while (src < limit) {
   6459     char c = *src;
   6460     or_acc |= c;
   6461     if (lo < c && c < hi) {
   6462       c ^= (1 << 5);
   6463       changed = true;
   6464     }
   6465     *dst = c;
   6466     ++src;
   6467     ++dst;
   6468   }
   6469   if ((or_acc & kAsciiMask) != 0) {
   6470     return false;
   6471   }
   6472 
   6473   ASSERT(CheckFastAsciiConvert(
   6474              saved_dst, saved_src, length, changed, Converter::kIsToLower));
   6475 
   6476   *changed_out = changed;
   6477   return true;
   6478 }
   6479 
   6480 }  // namespace
   6481 
   6482 
   6483 template <class Converter>
   6484 MUST_USE_RESULT static MaybeObject* ConvertCase(
   6485     Arguments args,
   6486     Isolate* isolate,
   6487     unibrow::Mapping<Converter, 128>* mapping) {
   6488   SealHandleScope shs(isolate);
   6489   CONVERT_ARG_CHECKED(String, s, 0);
   6490   s = s->TryFlattenGetString();
   6491 
   6492   const int length = s->length();
   6493   // Assume that the string is not empty; we need this assumption later
   6494   if (length == 0) return s;
   6495 
   6496   // Simpler handling of ASCII strings.
   6497   //
   6498   // NOTE: This assumes that the upper/lower case of an ASCII
   6499   // character is also ASCII.  This is currently the case, but it
   6500   // might break in the future if we implement more context and locale
   6501   // dependent upper/lower conversions.
   6502   if (s->IsSeqOneByteString()) {
   6503     Object* o;
   6504     { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length);
   6505       if (!maybe_o->ToObject(&o)) return maybe_o;
   6506     }
   6507     SeqOneByteString* result = SeqOneByteString::cast(o);
   6508     bool has_changed_character;
   6509     bool is_ascii = FastAsciiConvert<Converter>(
   6510         reinterpret_cast<char*>(result->GetChars()),
   6511         reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
   6512         length,
   6513         &has_changed_character);
   6514     // If not ASCII, we discard the result and take the 2 byte path.
   6515     if (is_ascii) {
   6516       return has_changed_character ? result : s;
   6517     }
   6518   }
   6519 
   6520   String::Encoding result_encoding = s->IsOneByteRepresentation()
   6521       ? String::ONE_BYTE_ENCODING : String::TWO_BYTE_ENCODING;
   6522   Object* answer;
   6523   { MaybeObject* maybe_answer = ConvertCaseHelper(
   6524         isolate, s, result_encoding, length, length, mapping);
   6525     if (!maybe_answer->ToObject(&answer)) return maybe_answer;
   6526   }
   6527   if (answer->IsSmi()) {
   6528     int new_length = Smi::cast(answer)->value();
   6529     if (new_length < 0) {
   6530       result_encoding = String::TWO_BYTE_ENCODING;
   6531       new_length = -new_length;
   6532     }
   6533     MaybeObject* maybe_answer = ConvertCaseHelper(
   6534         isolate, s, result_encoding, new_length, length, mapping);
   6535     if (!maybe_answer->ToObject(&answer)) return maybe_answer;
   6536   }
   6537   return answer;
   6538 }
   6539 
   6540 
   6541 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
   6542   return ConvertCase(
   6543       args, isolate, isolate->runtime_state()->to_lower_mapping());
   6544 }
   6545 
   6546 
   6547 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
   6548   return ConvertCase(
   6549       args, isolate, isolate->runtime_state()->to_upper_mapping());
   6550 }
   6551 
   6552 
   6553 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
   6554   return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
   6555 }
   6556 
   6557 
   6558 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
   6559   SealHandleScope shs(isolate);
   6560   ASSERT(args.length() == 3);
   6561 
   6562   CONVERT_ARG_CHECKED(String, s, 0);
   6563   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
   6564   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
   6565 
   6566   s->TryFlatten();
   6567   int length = s->length();
   6568 
   6569   int left = 0;
   6570   if (trimLeft) {
   6571     while (left < length && IsTrimWhiteSpace(s->Get(left))) {
   6572       left++;
   6573     }
   6574   }
   6575 
   6576   int right = length;
   6577   if (trimRight) {
   6578     while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) {
   6579       right--;
   6580     }
   6581   }
   6582   return s->SubString(left, right);
   6583 }
   6584 
   6585 
   6586 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
   6587   HandleScope handle_scope(isolate);
   6588   ASSERT(args.length() == 3);
   6589   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6590   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   6591   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
   6592 
   6593   int subject_length = subject->length();
   6594   int pattern_length = pattern->length();
   6595   RUNTIME_ASSERT(pattern_length > 0);
   6596 
   6597   if (limit == 0xffffffffu) {
   6598     Handle<Object> cached_answer(
   6599         RegExpResultsCache::Lookup(isolate->heap(),
   6600                                    *subject,
   6601                                    *pattern,
   6602                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
   6603         isolate);
   6604     if (*cached_answer != Smi::FromInt(0)) {
   6605       // The cache FixedArray is a COW-array and can therefore be reused.
   6606       Handle<JSArray> result =
   6607           isolate->factory()->NewJSArrayWithElements(
   6608               Handle<FixedArray>::cast(cached_answer));
   6609       return *result;
   6610     }
   6611   }
   6612 
   6613   // The limit can be very large (0xffffffffu), but since the pattern
   6614   // isn't empty, we can never create more parts than ~half the length
   6615   // of the subject.
   6616 
   6617   if (!subject->IsFlat()) FlattenString(subject);
   6618 
   6619   static const int kMaxInitialListCapacity = 16;
   6620 
   6621   ZoneScope zone_scope(isolate->runtime_zone());
   6622 
   6623   // Find (up to limit) indices of separator and end-of-string in subject
   6624   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
   6625   ZoneList<int> indices(initial_capacity, zone_scope.zone());
   6626   if (!pattern->IsFlat()) FlattenString(pattern);
   6627 
   6628   FindStringIndicesDispatch(isolate, *subject, *pattern,
   6629                             &indices, limit, zone_scope.zone());
   6630 
   6631   if (static_cast<uint32_t>(indices.length()) < limit) {
   6632     indices.Add(subject_length, zone_scope.zone());
   6633   }
   6634 
   6635   // The list indices now contains the end of each part to create.
   6636 
   6637   // Create JSArray of substrings separated by separator.
   6638   int part_count = indices.length();
   6639 
   6640   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
   6641   JSObject::EnsureCanContainHeapObjectElements(result);
   6642   result->set_length(Smi::FromInt(part_count));
   6643 
   6644   ASSERT(result->HasFastObjectElements());
   6645 
   6646   if (part_count == 1 && indices.at(0) == subject_length) {
   6647     FixedArray::cast(result->elements())->set(0, *subject);
   6648     return *result;
   6649   }
   6650 
   6651   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
   6652   int part_start = 0;
   6653   for (int i = 0; i < part_count; i++) {
   6654     HandleScope local_loop_handle(isolate);
   6655     int part_end = indices.at(i);
   6656     Handle<String> substring =
   6657         isolate->factory()->NewProperSubString(subject, part_start, part_end);
   6658     elements->set(i, *substring);
   6659     part_start = part_end + pattern_length;
   6660   }
   6661 
   6662   if (limit == 0xffffffffu) {
   6663     if (result->HasFastObjectElements()) {
   6664       RegExpResultsCache::Enter(isolate->heap(),
   6665                                 *subject,
   6666                                 *pattern,
   6667                                 *elements,
   6668                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
   6669     }
   6670   }
   6671 
   6672   return *result;
   6673 }
   6674 
   6675 
   6676 // Copies ASCII characters to the given fixed array looking up
   6677 // one-char strings in the cache. Gives up on the first char that is
   6678 // not in the cache and fills the remainder with smi zeros. Returns
   6679 // the length of the successfully copied prefix.
   6680 static int CopyCachedAsciiCharsToArray(Heap* heap,
   6681                                        const uint8_t* chars,
   6682                                        FixedArray* elements,
   6683                                        int length) {
   6684   DisallowHeapAllocation no_gc;
   6685   FixedArray* ascii_cache = heap->single_character_string_cache();
   6686   Object* undefined = heap->undefined_value();
   6687   int i;
   6688   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   6689   for (i = 0; i < length; ++i) {
   6690     Object* value = ascii_cache->get(chars[i]);
   6691     if (value == undefined) break;
   6692     elements->set(i, value, mode);
   6693   }
   6694   if (i < length) {
   6695     ASSERT(Smi::FromInt(0) == 0);
   6696     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
   6697   }
   6698 #ifdef DEBUG
   6699   for (int j = 0; j < length; ++j) {
   6700     Object* element = elements->get(j);
   6701     ASSERT(element == Smi::FromInt(0) ||
   6702            (element->IsString() && String::cast(element)->LooksValid()));
   6703   }
   6704 #endif
   6705   return i;
   6706 }
   6707 
   6708 
   6709 // Converts a String to JSArray.
   6710 // For example, "foo" => ["f", "o", "o"].
   6711 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
   6712   HandleScope scope(isolate);
   6713   ASSERT(args.length() == 2);
   6714   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6715   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   6716 
   6717   s = FlattenGetString(s);
   6718   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
   6719 
   6720   Handle<FixedArray> elements;
   6721   int position = 0;
   6722   if (s->IsFlat() && s->IsOneByteRepresentation()) {
   6723     // Try using cached chars where possible.
   6724     Object* obj;
   6725     { MaybeObject* maybe_obj =
   6726           isolate->heap()->AllocateUninitializedFixedArray(length);
   6727       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   6728     }
   6729     elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
   6730     DisallowHeapAllocation no_gc;
   6731     String::FlatContent content = s->GetFlatContent();
   6732     if (content.IsAscii()) {
   6733       Vector<const uint8_t> chars = content.ToOneByteVector();
   6734       // Note, this will initialize all elements (not only the prefix)
   6735       // to prevent GC from seeing partially initialized array.
   6736       position = CopyCachedAsciiCharsToArray(isolate->heap(),
   6737                                              chars.start(),
   6738                                              *elements,
   6739                                              length);
   6740     } else {
   6741       MemsetPointer(elements->data_start(),
   6742                     isolate->heap()->undefined_value(),
   6743                     length);
   6744     }
   6745   } else {
   6746     elements = isolate->factory()->NewFixedArray(length);
   6747   }
   6748   for (int i = position; i < length; ++i) {
   6749     Handle<Object> str =
   6750         LookupSingleCharacterStringFromCode(isolate, s->Get(i));
   6751     elements->set(i, *str);
   6752   }
   6753 
   6754 #ifdef DEBUG
   6755   for (int i = 0; i < length; ++i) {
   6756     ASSERT(String::cast(elements->get(i))->length() == 1);
   6757   }
   6758 #endif
   6759 
   6760   return *isolate->factory()->NewJSArrayWithElements(elements);
   6761 }
   6762 
   6763 
   6764 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
   6765   SealHandleScope shs(isolate);
   6766   ASSERT(args.length() == 1);
   6767   CONVERT_ARG_CHECKED(String, value, 0);
   6768   return value->ToObject(isolate);
   6769 }
   6770 
   6771 
   6772 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
   6773   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
   6774   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
   6775   return char_length == 0;
   6776 }
   6777 
   6778 
   6779 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToString) {
   6780   SealHandleScope shs(isolate);
   6781   ASSERT(args.length() == 1);
   6782 
   6783   Object* number = args[0];
   6784   RUNTIME_ASSERT(number->IsNumber());
   6785 
   6786   return isolate->heap()->NumberToString(number);
   6787 }
   6788 
   6789 
   6790 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToStringSkipCache) {
   6791   SealHandleScope shs(isolate);
   6792   ASSERT(args.length() == 1);
   6793 
   6794   Object* number = args[0];
   6795   RUNTIME_ASSERT(number->IsNumber());
   6796 
   6797   return isolate->heap()->NumberToString(
   6798       number, false, isolate->heap()->GetPretenureMode());
   6799 }
   6800 
   6801 
   6802 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
   6803   SealHandleScope shs(isolate);
   6804   ASSERT(args.length() == 1);
   6805 
   6806   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6807 
   6808   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6809   if (number > 0 && number <= Smi::kMaxValue) {
   6810     return Smi::FromInt(static_cast<int>(number));
   6811   }
   6812   return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
   6813 }
   6814 
   6815 
   6816 // ES6 draft 9.1.11
   6817 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPositiveInteger) {
   6818   SealHandleScope shs(isolate);
   6819   ASSERT(args.length() == 1);
   6820 
   6821   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6822 
   6823   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6824   if (number > 0 && number <= Smi::kMaxValue) {
   6825     return Smi::FromInt(static_cast<int>(number));
   6826   }
   6827   if (number <= 0) {
   6828     return Smi::FromInt(0);
   6829   }
   6830   return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
   6831 }
   6832 
   6833 
   6834 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
   6835   SealHandleScope shs(isolate);
   6836   ASSERT(args.length() == 1);
   6837 
   6838   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6839 
   6840   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6841   if (number > 0 && number <= Smi::kMaxValue) {
   6842     return Smi::FromInt(static_cast<int>(number));
   6843   }
   6844 
   6845   double double_value = DoubleToInteger(number);
   6846   // Map both -0 and +0 to +0.
   6847   if (double_value == 0) double_value = 0;
   6848 
   6849   return isolate->heap()->NumberFromDouble(double_value);
   6850 }
   6851 
   6852 
   6853 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) {
   6854   SealHandleScope shs(isolate);
   6855   ASSERT(args.length() == 1);
   6856 
   6857   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
   6858   return isolate->heap()->NumberFromUint32(number);
   6859 }
   6860 
   6861 
   6862 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
   6863   SealHandleScope shs(isolate);
   6864   ASSERT(args.length() == 1);
   6865 
   6866   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6867 
   6868   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6869   if (number > 0 && number <= Smi::kMaxValue) {
   6870     return Smi::FromInt(static_cast<int>(number));
   6871   }
   6872   return isolate->heap()->NumberFromInt32(DoubleToInt32(number));
   6873 }
   6874 
   6875 
   6876 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
   6877 // a small integer.
   6878 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToSmi) {
   6879   SealHandleScope shs(isolate);
   6880   ASSERT(args.length() == 1);
   6881 
   6882   Object* obj = args[0];
   6883   if (obj->IsSmi()) {
   6884     return obj;
   6885   }
   6886   if (obj->IsHeapNumber()) {
   6887     double value = HeapNumber::cast(obj)->value();
   6888     int int_value = FastD2I(value);
   6889     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
   6890       return Smi::FromInt(int_value);
   6891     }
   6892   }
   6893   return isolate->heap()->nan_value();
   6894 }
   6895 
   6896 
   6897 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateHeapNumber) {
   6898   SealHandleScope shs(isolate);
   6899   ASSERT(args.length() == 0);
   6900   return isolate->heap()->AllocateHeapNumber(0);
   6901 }
   6902 
   6903 
   6904 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
   6905   SealHandleScope shs(isolate);
   6906   ASSERT(args.length() == 2);
   6907 
   6908   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6909   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6910   return isolate->heap()->NumberFromDouble(x + y);
   6911 }
   6912 
   6913 
   6914 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
   6915   SealHandleScope shs(isolate);
   6916   ASSERT(args.length() == 2);
   6917 
   6918   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6919   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6920   return isolate->heap()->NumberFromDouble(x - y);
   6921 }
   6922 
   6923 
   6924 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
   6925   SealHandleScope shs(isolate);
   6926   ASSERT(args.length() == 2);
   6927 
   6928   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6929   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6930   return isolate->heap()->NumberFromDouble(x * y);
   6931 }
   6932 
   6933 
   6934 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
   6935   SealHandleScope shs(isolate);
   6936   ASSERT(args.length() == 1);
   6937 
   6938   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6939   return isolate->heap()->NumberFromDouble(-x);
   6940 }
   6941 
   6942 
   6943 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) {
   6944   SealHandleScope shs(isolate);
   6945   ASSERT(args.length() == 0);
   6946 
   6947   return isolate->heap()->NumberFromDouble(9876543210.0);
   6948 }
   6949 
   6950 
   6951 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
   6952   SealHandleScope shs(isolate);
   6953   ASSERT(args.length() == 2);
   6954 
   6955   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6956   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6957   return isolate->heap()->NumberFromDouble(x / y);
   6958 }
   6959 
   6960 
   6961 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
   6962   SealHandleScope shs(isolate);
   6963   ASSERT(args.length() == 2);
   6964 
   6965   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6966   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6967 
   6968   x = modulo(x, y);
   6969   // NumberFromDouble may return a Smi instead of a Number object
   6970   return isolate->heap()->NumberFromDouble(x);
   6971 }
   6972 
   6973 
   6974 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberImul) {
   6975   SealHandleScope shs(isolate);
   6976   ASSERT(args.length() == 2);
   6977 
   6978   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   6979   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   6980   return isolate->heap()->NumberFromInt32(x * y);
   6981 }
   6982 
   6983 
   6984 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) {
   6985   SealHandleScope shs(isolate);
   6986   ASSERT(args.length() == 2);
   6987   CONVERT_ARG_CHECKED(String, str1, 0);
   6988   CONVERT_ARG_CHECKED(String, str2, 1);
   6989   isolate->counters()->string_add_runtime()->Increment();
   6990   return isolate->heap()->AllocateConsString(str1, str2);
   6991 }
   6992 
   6993 
   6994 template <typename sinkchar>
   6995 static inline void StringBuilderConcatHelper(String* special,
   6996                                              sinkchar* sink,
   6997                                              FixedArray* fixed_array,
   6998                                              int array_length) {
   6999   int position = 0;
   7000   for (int i = 0; i < array_length; i++) {
   7001     Object* element = fixed_array->get(i);
   7002     if (element->IsSmi()) {
   7003       // Smi encoding of position and length.
   7004       int encoded_slice = Smi::cast(element)->value();
   7005       int pos;
   7006       int len;
   7007       if (encoded_slice > 0) {
   7008         // Position and length encoded in one smi.
   7009         pos = StringBuilderSubstringPosition::decode(encoded_slice);
   7010         len = StringBuilderSubstringLength::decode(encoded_slice);
   7011       } else {
   7012         // Position and length encoded in two smis.
   7013         Object* obj = fixed_array->get(++i);
   7014         ASSERT(obj->IsSmi());
   7015         pos = Smi::cast(obj)->value();
   7016         len = -encoded_slice;
   7017       }
   7018       String::WriteToFlat(special,
   7019                           sink + position,
   7020                           pos,
   7021                           pos + len);
   7022       position += len;
   7023     } else {
   7024       String* string = String::cast(element);
   7025       int element_length = string->length();
   7026       String::WriteToFlat(string, sink + position, 0, element_length);
   7027       position += element_length;
   7028     }
   7029   }
   7030 }
   7031 
   7032 
   7033 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
   7034   HandleScope scope(isolate);
   7035   ASSERT(args.length() == 3);
   7036   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   7037   if (!args[1]->IsSmi()) {
   7038     isolate->context()->mark_out_of_memory();
   7039     return Failure::OutOfMemoryException(0x14);
   7040   }
   7041   int array_length = args.smi_at(1);
   7042   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
   7043 
   7044   // This assumption is used by the slice encoding in one or two smis.
   7045   ASSERT(Smi::kMaxValue >= String::kMaxLength);
   7046 
   7047   JSObject::EnsureCanContainHeapObjectElements(array);
   7048 
   7049   int special_length = special->length();
   7050   if (!array->HasFastObjectElements()) {
   7051     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7052   }
   7053   FixedArray* fixed_array = FixedArray::cast(array->elements());
   7054   if (fixed_array->length() < array_length) {
   7055     array_length = fixed_array->length();
   7056   }
   7057 
   7058   if (array_length == 0) {
   7059     return isolate->heap()->empty_string();
   7060   } else if (array_length == 1) {
   7061     Object* first = fixed_array->get(0);
   7062     if (first->IsString()) return first;
   7063   }
   7064 
   7065   bool one_byte = special->HasOnlyOneByteChars();
   7066   int position = 0;
   7067   for (int i = 0; i < array_length; i++) {
   7068     int increment = 0;
   7069     Object* elt = fixed_array->get(i);
   7070     if (elt->IsSmi()) {
   7071       // Smi encoding of position and length.
   7072       int smi_value = Smi::cast(elt)->value();
   7073       int pos;
   7074       int len;
   7075       if (smi_value > 0) {
   7076         // Position and length encoded in one smi.
   7077         pos = StringBuilderSubstringPosition::decode(smi_value);
   7078         len = StringBuilderSubstringLength::decode(smi_value);
   7079       } else {
   7080         // Position and length encoded in two smis.
   7081         len = -smi_value;
   7082         // Get the position and check that it is a positive smi.
   7083         i++;
   7084         if (i >= array_length) {
   7085           return isolate->Throw(isolate->heap()->illegal_argument_string());
   7086         }
   7087         Object* next_smi = fixed_array->get(i);
   7088         if (!next_smi->IsSmi()) {
   7089           return isolate->Throw(isolate->heap()->illegal_argument_string());
   7090         }
   7091         pos = Smi::cast(next_smi)->value();
   7092         if (pos < 0) {
   7093           return isolate->Throw(isolate->heap()->illegal_argument_string());
   7094         }
   7095       }
   7096       ASSERT(pos >= 0);
   7097       ASSERT(len >= 0);
   7098       if (pos > special_length || len > special_length - pos) {
   7099         return isolate->Throw(isolate->heap()->illegal_argument_string());
   7100       }
   7101       increment = len;
   7102     } else if (elt->IsString()) {
   7103       String* element = String::cast(elt);
   7104       int element_length = element->length();
   7105       increment = element_length;
   7106       if (one_byte && !element->HasOnlyOneByteChars()) {
   7107         one_byte = false;
   7108       }
   7109     } else {
   7110       ASSERT(!elt->IsTheHole());
   7111       return isolate->Throw(isolate->heap()->illegal_argument_string());
   7112     }
   7113     if (increment > String::kMaxLength - position) {
   7114       isolate->context()->mark_out_of_memory();
   7115       return Failure::OutOfMemoryException(0x15);
   7116     }
   7117     position += increment;
   7118   }
   7119 
   7120   int length = position;
   7121   Object* object;
   7122 
   7123   if (one_byte) {
   7124     { MaybeObject* maybe_object =
   7125           isolate->heap()->AllocateRawOneByteString(length);
   7126       if (!maybe_object->ToObject(&object)) return maybe_object;
   7127     }
   7128     SeqOneByteString* answer = SeqOneByteString::cast(object);
   7129     StringBuilderConcatHelper(*special,
   7130                               answer->GetChars(),
   7131                               fixed_array,
   7132                               array_length);
   7133     return answer;
   7134   } else {
   7135     { MaybeObject* maybe_object =
   7136           isolate->heap()->AllocateRawTwoByteString(length);
   7137       if (!maybe_object->ToObject(&object)) return maybe_object;
   7138     }
   7139     SeqTwoByteString* answer = SeqTwoByteString::cast(object);
   7140     StringBuilderConcatHelper(*special,
   7141                               answer->GetChars(),
   7142                               fixed_array,
   7143                               array_length);
   7144     return answer;
   7145   }
   7146 }
   7147 
   7148 
   7149 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
   7150   SealHandleScope shs(isolate);
   7151   ASSERT(args.length() == 3);
   7152   CONVERT_ARG_CHECKED(JSArray, array, 0);
   7153   if (!args[1]->IsSmi()) {
   7154     isolate->context()->mark_out_of_memory();
   7155     return Failure::OutOfMemoryException(0x16);
   7156   }
   7157   int array_length = args.smi_at(1);
   7158   CONVERT_ARG_CHECKED(String, separator, 2);
   7159 
   7160   if (!array->HasFastObjectElements()) {
   7161     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7162   }
   7163   FixedArray* fixed_array = FixedArray::cast(array->elements());
   7164   if (fixed_array->length() < array_length) {
   7165     array_length = fixed_array->length();
   7166   }
   7167 
   7168   if (array_length == 0) {
   7169     return isolate->heap()->empty_string();
   7170   } else if (array_length == 1) {
   7171     Object* first = fixed_array->get(0);
   7172     if (first->IsString()) return first;
   7173   }
   7174 
   7175   int separator_length = separator->length();
   7176   int max_nof_separators =
   7177       (String::kMaxLength + separator_length - 1) / separator_length;
   7178   if (max_nof_separators < (array_length - 1)) {
   7179       isolate->context()->mark_out_of_memory();
   7180       return Failure::OutOfMemoryException(0x17);
   7181   }
   7182   int length = (array_length - 1) * separator_length;
   7183   for (int i = 0; i < array_length; i++) {
   7184     Object* element_obj = fixed_array->get(i);
   7185     if (!element_obj->IsString()) {
   7186       // TODO(1161): handle this case.
   7187       return isolate->Throw(isolate->heap()->illegal_argument_string());
   7188     }
   7189     String* element = String::cast(element_obj);
   7190     int increment = element->length();
   7191     if (increment > String::kMaxLength - length) {
   7192       isolate->context()->mark_out_of_memory();
   7193       return Failure::OutOfMemoryException(0x18);
   7194     }
   7195     length += increment;
   7196   }
   7197 
   7198   Object* object;
   7199   { MaybeObject* maybe_object =
   7200         isolate->heap()->AllocateRawTwoByteString(length);
   7201     if (!maybe_object->ToObject(&object)) return maybe_object;
   7202   }
   7203   SeqTwoByteString* answer = SeqTwoByteString::cast(object);
   7204 
   7205   uc16* sink = answer->GetChars();
   7206 #ifdef DEBUG
   7207   uc16* end = sink + length;
   7208 #endif
   7209 
   7210   String* first = String::cast(fixed_array->get(0));
   7211   int first_length = first->length();
   7212   String::WriteToFlat(first, sink, 0, first_length);
   7213   sink += first_length;
   7214 
   7215   for (int i = 1; i < array_length; i++) {
   7216     ASSERT(sink + separator_length <= end);
   7217     String::WriteToFlat(separator, sink, 0, separator_length);
   7218     sink += separator_length;
   7219 
   7220     String* element = String::cast(fixed_array->get(i));
   7221     int element_length = element->length();
   7222     ASSERT(sink + element_length <= end);
   7223     String::WriteToFlat(element, sink, 0, element_length);
   7224     sink += element_length;
   7225   }
   7226   ASSERT(sink == end);
   7227 
   7228   // Use %_FastAsciiArrayJoin instead.
   7229   ASSERT(!answer->IsOneByteRepresentation());
   7230   return answer;
   7231 }
   7232 
   7233 template <typename Char>
   7234 static void JoinSparseArrayWithSeparator(FixedArray* elements,
   7235                                          int elements_length,
   7236                                          uint32_t array_length,
   7237                                          String* separator,
   7238                                          Vector<Char> buffer) {
   7239   int previous_separator_position = 0;
   7240   int separator_length = separator->length();
   7241   int cursor = 0;
   7242   for (int i = 0; i < elements_length; i += 2) {
   7243     int position = NumberToInt32(elements->get(i));
   7244     String* string = String::cast(elements->get(i + 1));
   7245     int string_length = string->length();
   7246     if (string->length() > 0) {
   7247       while (previous_separator_position < position) {
   7248         String::WriteToFlat<Char>(separator, &buffer[cursor],
   7249                                   0, separator_length);
   7250         cursor += separator_length;
   7251         previous_separator_position++;
   7252       }
   7253       String::WriteToFlat<Char>(string, &buffer[cursor],
   7254                                 0, string_length);
   7255       cursor += string->length();
   7256     }
   7257   }
   7258   if (separator_length > 0) {
   7259     // Array length must be representable as a signed 32-bit number,
   7260     // otherwise the total string length would have been too large.
   7261     ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
   7262     int last_array_index = static_cast<int>(array_length - 1);
   7263     while (previous_separator_position < last_array_index) {
   7264       String::WriteToFlat<Char>(separator, &buffer[cursor],
   7265                                 0, separator_length);
   7266       cursor += separator_length;
   7267       previous_separator_position++;
   7268     }
   7269   }
   7270   ASSERT(cursor <= buffer.length());
   7271 }
   7272 
   7273 
   7274 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
   7275   SealHandleScope shs(isolate);
   7276   ASSERT(args.length() == 3);
   7277   CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
   7278   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
   7279   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
   7280   CONVERT_ARG_CHECKED(String, separator, 2);
   7281   // elements_array is fast-mode JSarray of alternating positions
   7282   // (increasing order) and strings.
   7283   // array_length is length of original array (used to add separators);
   7284   // separator is string to put between elements. Assumed to be non-empty.
   7285 
   7286   // Find total length of join result.
   7287   int string_length = 0;
   7288   bool is_ascii = separator->IsOneByteRepresentation();
   7289   int max_string_length;
   7290   if (is_ascii) {
   7291     max_string_length = SeqOneByteString::kMaxLength;
   7292   } else {
   7293     max_string_length = SeqTwoByteString::kMaxLength;
   7294   }
   7295   bool overflow = false;
   7296   CONVERT_NUMBER_CHECKED(int, elements_length,
   7297                          Int32, elements_array->length());
   7298   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
   7299   FixedArray* elements = FixedArray::cast(elements_array->elements());
   7300   for (int i = 0; i < elements_length; i += 2) {
   7301     RUNTIME_ASSERT(elements->get(i)->IsNumber());
   7302     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
   7303     String* string = String::cast(elements->get(i + 1));
   7304     int length = string->length();
   7305     if (is_ascii && !string->IsOneByteRepresentation()) {
   7306       is_ascii = false;
   7307       max_string_length = SeqTwoByteString::kMaxLength;
   7308     }
   7309     if (length > max_string_length ||
   7310         max_string_length - length < string_length) {
   7311       overflow = true;
   7312       break;
   7313     }
   7314     string_length += length;
   7315   }
   7316   int separator_length = separator->length();
   7317   if (!overflow && separator_length > 0) {
   7318     if (array_length <= 0x7fffffffu) {
   7319       int separator_count = static_cast<int>(array_length) - 1;
   7320       int remaining_length = max_string_length - string_length;
   7321       if ((remaining_length / separator_length) >= separator_count) {
   7322         string_length += separator_length * (array_length - 1);
   7323       } else {
   7324         // Not room for the separators within the maximal string length.
   7325         overflow = true;
   7326       }
   7327     } else {
   7328       // Nonempty separator and at least 2^31-1 separators necessary
   7329       // means that the string is too large to create.
   7330       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
   7331       overflow = true;
   7332     }
   7333   }
   7334   if (overflow) {
   7335     // Throw OutOfMemory exception for creating too large a string.
   7336     V8::FatalProcessOutOfMemory("Array join result too large.");
   7337   }
   7338 
   7339   if (is_ascii) {
   7340     MaybeObject* result_allocation =
   7341         isolate->heap()->AllocateRawOneByteString(string_length);
   7342     if (result_allocation->IsFailure()) return result_allocation;
   7343     SeqOneByteString* result_string =
   7344         SeqOneByteString::cast(result_allocation->ToObjectUnchecked());
   7345     JoinSparseArrayWithSeparator<uint8_t>(elements,
   7346                                           elements_length,
   7347                                           array_length,
   7348                                           separator,
   7349                                           Vector<uint8_t>(
   7350                                               result_string->GetChars(),
   7351                                               string_length));
   7352     return result_string;
   7353   } else {
   7354     MaybeObject* result_allocation =
   7355         isolate->heap()->AllocateRawTwoByteString(string_length);
   7356     if (result_allocation->IsFailure()) return result_allocation;
   7357     SeqTwoByteString* result_string =
   7358         SeqTwoByteString::cast(result_allocation->ToObjectUnchecked());
   7359     JoinSparseArrayWithSeparator<uc16>(elements,
   7360                                        elements_length,
   7361                                        array_length,
   7362                                        separator,
   7363                                        Vector<uc16>(result_string->GetChars(),
   7364                                                     string_length));
   7365     return result_string;
   7366   }
   7367 }
   7368 
   7369 
   7370 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberOr) {
   7371   SealHandleScope shs(isolate);
   7372   ASSERT(args.length() == 2);
   7373 
   7374   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7375   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7376   return isolate->heap()->NumberFromInt32(x | y);
   7377 }
   7378 
   7379 
   7380 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAnd) {
   7381   SealHandleScope shs(isolate);
   7382   ASSERT(args.length() == 2);
   7383 
   7384   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7385   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7386   return isolate->heap()->NumberFromInt32(x & y);
   7387 }
   7388 
   7389 
   7390 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) {
   7391   SealHandleScope shs(isolate);
   7392   ASSERT(args.length() == 2);
   7393 
   7394   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7395   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7396   return isolate->heap()->NumberFromInt32(x ^ y);
   7397 }
   7398 
   7399 
   7400 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) {
   7401   SealHandleScope shs(isolate);
   7402   ASSERT(args.length() == 2);
   7403 
   7404   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7405   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7406   return isolate->heap()->NumberFromInt32(x << (y & 0x1f));
   7407 }
   7408 
   7409 
   7410 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShr) {
   7411   SealHandleScope shs(isolate);
   7412   ASSERT(args.length() == 2);
   7413 
   7414   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
   7415   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7416   return isolate->heap()->NumberFromUint32(x >> (y & 0x1f));
   7417 }
   7418 
   7419 
   7420 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSar) {
   7421   SealHandleScope shs(isolate);
   7422   ASSERT(args.length() == 2);
   7423 
   7424   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7425   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7426   return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
   7427 }
   7428 
   7429 
   7430 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
   7431   SealHandleScope shs(isolate);
   7432   ASSERT(args.length() == 2);
   7433 
   7434   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7435   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7436   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
   7437   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
   7438   if (x == y) return Smi::FromInt(EQUAL);
   7439   Object* result;
   7440   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
   7441     result = Smi::FromInt(EQUAL);
   7442   } else {
   7443     result = Smi::FromInt(NOT_EQUAL);
   7444   }
   7445   return result;
   7446 }
   7447 
   7448 
   7449 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
   7450   SealHandleScope shs(isolate);
   7451   ASSERT(args.length() == 2);
   7452 
   7453   CONVERT_ARG_CHECKED(String, x, 0);
   7454   CONVERT_ARG_CHECKED(String, y, 1);
   7455 
   7456   bool not_equal = !x->Equals(y);
   7457   // This is slightly convoluted because the value that signifies
   7458   // equality is 0 and inequality is 1 so we have to negate the result
   7459   // from String::Equals.
   7460   ASSERT(not_equal == 0 || not_equal == 1);
   7461   STATIC_CHECK(EQUAL == 0);
   7462   STATIC_CHECK(NOT_EQUAL == 1);
   7463   return Smi::FromInt(not_equal);
   7464 }
   7465 
   7466 
   7467 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
   7468   SealHandleScope shs(isolate);
   7469   ASSERT(args.length() == 3);
   7470 
   7471   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7472   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7473   if (std::isnan(x) || std::isnan(y)) return args[2];
   7474   if (x == y) return Smi::FromInt(EQUAL);
   7475   if (isless(x, y)) return Smi::FromInt(LESS);
   7476   return Smi::FromInt(GREATER);
   7477 }
   7478 
   7479 
   7480 // Compare two Smis as if they were converted to strings and then
   7481 // compared lexicographically.
   7482 RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
   7483   SealHandleScope shs(isolate);
   7484   ASSERT(args.length() == 2);
   7485   CONVERT_SMI_ARG_CHECKED(x_value, 0);
   7486   CONVERT_SMI_ARG_CHECKED(y_value, 1);
   7487 
   7488   // If the integers are equal so are the string representations.
   7489   if (x_value == y_value) return Smi::FromInt(EQUAL);
   7490 
   7491   // If one of the integers is zero the normal integer order is the
   7492   // same as the lexicographic order of the string representations.
   7493   if (x_value == 0 || y_value == 0)
   7494     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
   7495 
   7496   // If only one of the integers is negative the negative number is
   7497   // smallest because the char code of '-' is less than the char code
   7498   // of any digit.  Otherwise, we make both values positive.
   7499 
   7500   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
   7501   // architectures using 32-bit Smis.
   7502   uint32_t x_scaled = x_value;
   7503   uint32_t y_scaled = y_value;
   7504   if (x_value < 0 || y_value < 0) {
   7505     if (y_value >= 0) return Smi::FromInt(LESS);
   7506     if (x_value >= 0) return Smi::FromInt(GREATER);
   7507     x_scaled = -x_value;
   7508     y_scaled = -y_value;
   7509   }
   7510 
   7511   static const uint32_t kPowersOf10[] = {
   7512     1, 10, 100, 1000, 10*1000, 100*1000,
   7513     1000*1000, 10*1000*1000, 100*1000*1000,
   7514     1000*1000*1000
   7515   };
   7516 
   7517   // If the integers have the same number of decimal digits they can be
   7518   // compared directly as the numeric order is the same as the
   7519   // lexicographic order.  If one integer has fewer digits, it is scaled
   7520   // by some power of 10 to have the same number of digits as the longer
   7521   // integer.  If the scaled integers are equal it means the shorter
   7522   // integer comes first in the lexicographic order.
   7523 
   7524   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
   7525   int x_log2 = IntegerLog2(x_scaled);
   7526   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
   7527   x_log10 -= x_scaled < kPowersOf10[x_log10];
   7528 
   7529   int y_log2 = IntegerLog2(y_scaled);
   7530   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
   7531   y_log10 -= y_scaled < kPowersOf10[y_log10];
   7532 
   7533   int tie = EQUAL;
   7534 
   7535   if (x_log10 < y_log10) {
   7536     // X has fewer digits.  We would like to simply scale up X but that
   7537     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
   7538     // be scaled up to 9_000_000_000. So we scale up by the next
   7539     // smallest power and scale down Y to drop one digit. It is OK to
   7540     // drop one digit from the longer integer since the final digit is
   7541     // past the length of the shorter integer.
   7542     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
   7543     y_scaled /= 10;
   7544     tie = LESS;
   7545   } else if (y_log10 < x_log10) {
   7546     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
   7547     x_scaled /= 10;
   7548     tie = GREATER;
   7549   }
   7550 
   7551   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
   7552   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
   7553   return Smi::FromInt(tie);
   7554 }
   7555 
   7556 
   7557 static Object* StringCharacterStreamCompare(RuntimeState* state,
   7558                                         String* x,
   7559                                         String* y) {
   7560   StringCharacterStream stream_x(x, state->string_iterator_compare_x());
   7561   StringCharacterStream stream_y(y, state->string_iterator_compare_y());
   7562   while (stream_x.HasMore() && stream_y.HasMore()) {
   7563     int d = stream_x.GetNext() - stream_y.GetNext();
   7564     if (d < 0) return Smi::FromInt(LESS);
   7565     else if (d > 0) return Smi::FromInt(GREATER);
   7566   }
   7567 
   7568   // x is (non-trivial) prefix of y:
   7569   if (stream_y.HasMore()) return Smi::FromInt(LESS);
   7570   // y is prefix of x:
   7571   return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL);
   7572 }
   7573 
   7574 
   7575 static Object* FlatStringCompare(String* x, String* y) {
   7576   ASSERT(x->IsFlat());
   7577   ASSERT(y->IsFlat());
   7578   Object* equal_prefix_result = Smi::FromInt(EQUAL);
   7579   int prefix_length = x->length();
   7580   if (y->length() < prefix_length) {
   7581     prefix_length = y->length();
   7582     equal_prefix_result = Smi::FromInt(GREATER);
   7583   } else if (y->length() > prefix_length) {
   7584     equal_prefix_result = Smi::FromInt(LESS);
   7585   }
   7586   int r;
   7587   DisallowHeapAllocation no_gc;
   7588   String::FlatContent x_content = x->GetFlatContent();
   7589   String::FlatContent y_content = y->GetFlatContent();
   7590   if (x_content.IsAscii()) {
   7591     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   7592     if (y_content.IsAscii()) {
   7593       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7594       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7595     } else {
   7596       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7597       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7598     }
   7599   } else {
   7600     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   7601     if (y_content.IsAscii()) {
   7602       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7603       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7604     } else {
   7605       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7606       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7607     }
   7608   }
   7609   Object* result;
   7610   if (r == 0) {
   7611     result = equal_prefix_result;
   7612   } else {
   7613     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
   7614   }
   7615   ASSERT(result ==
   7616       StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y));
   7617   return result;
   7618 }
   7619 
   7620 
   7621 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) {
   7622   SealHandleScope shs(isolate);
   7623   ASSERT(args.length() == 2);
   7624 
   7625   CONVERT_ARG_CHECKED(String, x, 0);
   7626   CONVERT_ARG_CHECKED(String, y, 1);
   7627 
   7628   isolate->counters()->string_compare_runtime()->Increment();
   7629 
   7630   // A few fast case tests before we flatten.
   7631   if (x == y) return Smi::FromInt(EQUAL);
   7632   if (y->length() == 0) {
   7633     if (x->length() == 0) return Smi::FromInt(EQUAL);
   7634     return Smi::FromInt(GREATER);
   7635   } else if (x->length() == 0) {
   7636     return Smi::FromInt(LESS);
   7637   }
   7638 
   7639   int d = x->Get(0) - y->Get(0);
   7640   if (d < 0) return Smi::FromInt(LESS);
   7641   else if (d > 0) return Smi::FromInt(GREATER);
   7642 
   7643   Object* obj;
   7644   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
   7645     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7646   }
   7647   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
   7648     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7649   }
   7650 
   7651   return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
   7652       : StringCharacterStreamCompare(isolate->runtime_state(), x, y);
   7653 }
   7654 
   7655 
   7656 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
   7657   SealHandleScope shs(isolate);
   7658   ASSERT(args.length() == 1);
   7659   isolate->counters()->math_acos()->Increment();
   7660 
   7661   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7662   return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
   7663 }
   7664 
   7665 
   7666 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
   7667   SealHandleScope shs(isolate);
   7668   ASSERT(args.length() == 1);
   7669   isolate->counters()->math_asin()->Increment();
   7670 
   7671   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7672   return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
   7673 }
   7674 
   7675 
   7676 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
   7677   SealHandleScope shs(isolate);
   7678   ASSERT(args.length() == 1);
   7679   isolate->counters()->math_atan()->Increment();
   7680 
   7681   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7682   return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
   7683 }
   7684 
   7685 
   7686 static const double kPiDividedBy4 = 0.78539816339744830962;
   7687 
   7688 
   7689 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
   7690   SealHandleScope shs(isolate);
   7691   ASSERT(args.length() == 2);
   7692   isolate->counters()->math_atan2()->Increment();
   7693 
   7694   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7695   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7696   double result;
   7697   if (std::isinf(x) && std::isinf(y)) {
   7698     // Make sure that the result in case of two infinite arguments
   7699     // is a multiple of Pi / 4. The sign of the result is determined
   7700     // by the first argument (x) and the sign of the second argument
   7701     // determines the multiplier: one or three.
   7702     int multiplier = (x < 0) ? -1 : 1;
   7703     if (y < 0) multiplier *= 3;
   7704     result = multiplier * kPiDividedBy4;
   7705   } else {
   7706     result = atan2(x, y);
   7707   }
   7708   return isolate->heap()->AllocateHeapNumber(result);
   7709 }
   7710 
   7711 
   7712 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
   7713   SealHandleScope shs(isolate);
   7714   ASSERT(args.length() == 1);
   7715   isolate->counters()->math_cos()->Increment();
   7716 
   7717   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7718   return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
   7719 }
   7720 
   7721 
   7722 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
   7723   SealHandleScope shs(isolate);
   7724   ASSERT(args.length() == 1);
   7725   isolate->counters()->math_exp()->Increment();
   7726 
   7727   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7728   lazily_initialize_fast_exp();
   7729   return isolate->heap()->NumberFromDouble(fast_exp(x));
   7730 }
   7731 
   7732 
   7733 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
   7734   SealHandleScope shs(isolate);
   7735   ASSERT(args.length() == 1);
   7736   isolate->counters()->math_floor()->Increment();
   7737 
   7738   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7739   return isolate->heap()->NumberFromDouble(floor(x));
   7740 }
   7741 
   7742 
   7743 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
   7744   SealHandleScope shs(isolate);
   7745   ASSERT(args.length() == 1);
   7746   isolate->counters()->math_log()->Increment();
   7747 
   7748   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7749   return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
   7750 }
   7751 
   7752 
   7753 // Slow version of Math.pow.  We check for fast paths for special cases.
   7754 // Used if SSE2/VFP3 is not available.
   7755 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
   7756   SealHandleScope shs(isolate);
   7757   ASSERT(args.length() == 2);
   7758   isolate->counters()->math_pow()->Increment();
   7759 
   7760   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7761 
   7762   // If the second argument is a smi, it is much faster to call the
   7763   // custom powi() function than the generic pow().
   7764   if (args[1]->IsSmi()) {
   7765     int y = args.smi_at(1);
   7766     return isolate->heap()->NumberFromDouble(power_double_int(x, y));
   7767   }
   7768 
   7769   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7770   double result = power_helper(x, y);
   7771   if (std::isnan(result)) return isolate->heap()->nan_value();
   7772   return isolate->heap()->AllocateHeapNumber(result);
   7773 }
   7774 
   7775 
   7776 // Fast version of Math.pow if we know that y is not an integer and y is not
   7777 // -0.5 or 0.5.  Used as slow case from full codegen.
   7778 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
   7779   SealHandleScope shs(isolate);
   7780   ASSERT(args.length() == 2);
   7781   isolate->counters()->math_pow()->Increment();
   7782 
   7783   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7784   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7785   if (y == 0) {
   7786     return Smi::FromInt(1);
   7787   } else {
   7788     double result = power_double_double(x, y);
   7789     if (std::isnan(result)) return isolate->heap()->nan_value();
   7790     return isolate->heap()->AllocateHeapNumber(result);
   7791   }
   7792 }
   7793 
   7794 
   7795 RUNTIME_FUNCTION(MaybeObject*, Runtime_RoundNumber) {
   7796   SealHandleScope shs(isolate);
   7797   ASSERT(args.length() == 1);
   7798   isolate->counters()->math_round()->Increment();
   7799 
   7800   if (!args[0]->IsHeapNumber()) {
   7801     // Must be smi. Return the argument unchanged for all the other types
   7802     // to make fuzz-natives test happy.
   7803     return args[0];
   7804   }
   7805 
   7806   HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
   7807 
   7808   double value = number->value();
   7809   int exponent = number->get_exponent();
   7810   int sign = number->get_sign();
   7811 
   7812   if (exponent < -1) {
   7813     // Number in range ]-0.5..0.5[. These always round to +/-zero.
   7814     if (sign) return isolate->heap()->minus_zero_value();
   7815     return Smi::FromInt(0);
   7816   }
   7817 
   7818   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
   7819   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
   7820   // argument holds for 32-bit smis).
   7821   if (!sign && exponent < kSmiValueSize - 2) {
   7822     return Smi::FromInt(static_cast<int>(value + 0.5));
   7823   }
   7824 
   7825   // If the magnitude is big enough, there's no place for fraction part. If we
   7826   // try to add 0.5 to this number, 1.0 will be added instead.
   7827   if (exponent >= 52) {
   7828     return number;
   7829   }
   7830 
   7831   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
   7832 
   7833   // Do not call NumberFromDouble() to avoid extra checks.
   7834   return isolate->heap()->AllocateHeapNumber(floor(value + 0.5));
   7835 }
   7836 
   7837 
   7838 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
   7839   SealHandleScope shs(isolate);
   7840   ASSERT(args.length() == 1);
   7841   isolate->counters()->math_sin()->Increment();
   7842 
   7843   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7844   return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
   7845 }
   7846 
   7847 
   7848 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
   7849   SealHandleScope shs(isolate);
   7850   ASSERT(args.length() == 1);
   7851   isolate->counters()->math_sqrt()->Increment();
   7852 
   7853   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7854   return isolate->heap()->AllocateHeapNumber(fast_sqrt(x));
   7855 }
   7856 
   7857 
   7858 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
   7859   SealHandleScope shs(isolate);
   7860   ASSERT(args.length() == 1);
   7861   isolate->counters()->math_tan()->Increment();
   7862 
   7863   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7864   return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
   7865 }
   7866 
   7867 
   7868 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
   7869   SealHandleScope shs(isolate);
   7870   ASSERT(args.length() == 2);
   7871 
   7872   CONVERT_SMI_ARG_CHECKED(year, 0);
   7873   CONVERT_SMI_ARG_CHECKED(month, 1);
   7874 
   7875   return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
   7876 }
   7877 
   7878 
   7879 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
   7880   HandleScope scope(isolate);
   7881   ASSERT(args.length() == 3);
   7882 
   7883   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
   7884   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
   7885   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
   7886 
   7887   DateCache* date_cache = isolate->date_cache();
   7888 
   7889   Object* value = NULL;
   7890   bool is_value_nan = false;
   7891   if (std::isnan(time)) {
   7892     value = isolate->heap()->nan_value();
   7893     is_value_nan = true;
   7894   } else if (!is_utc &&
   7895              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
   7896               time > DateCache::kMaxTimeBeforeUTCInMs)) {
   7897     value = isolate->heap()->nan_value();
   7898     is_value_nan = true;
   7899   } else {
   7900     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
   7901     if (time < -DateCache::kMaxTimeInMs ||
   7902         time > DateCache::kMaxTimeInMs) {
   7903       value = isolate->heap()->nan_value();
   7904       is_value_nan = true;
   7905     } else  {
   7906       MaybeObject* maybe_result =
   7907           isolate->heap()->AllocateHeapNumber(DoubleToInteger(time));
   7908       if (!maybe_result->ToObject(&value)) return maybe_result;
   7909     }
   7910   }
   7911   date->SetValue(value, is_value_nan);
   7912   return value;
   7913 }
   7914 
   7915 
   7916 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
   7917   HandleScope scope(isolate);
   7918   ASSERT(args.length() == 3);
   7919 
   7920   Handle<JSFunction> callee = args.at<JSFunction>(0);
   7921   Object** parameters = reinterpret_cast<Object**>(args[1]);
   7922   const int argument_count = Smi::cast(args[2])->value();
   7923 
   7924   Handle<JSObject> result =
   7925       isolate->factory()->NewArgumentsObject(callee, argument_count);
   7926   // Allocate the elements if needed.
   7927   int parameter_count = callee->shared()->formal_parameter_count();
   7928   if (argument_count > 0) {
   7929     if (parameter_count > 0) {
   7930       int mapped_count = Min(argument_count, parameter_count);
   7931       Handle<FixedArray> parameter_map =
   7932           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
   7933       parameter_map->set_map(
   7934           isolate->heap()->non_strict_arguments_elements_map());
   7935 
   7936       Handle<Map> old_map(result->map());
   7937       Handle<Map> new_map = isolate->factory()->CopyMap(old_map);
   7938       new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
   7939 
   7940       result->set_map(*new_map);
   7941       result->set_elements(*parameter_map);
   7942 
   7943       // Store the context and the arguments array at the beginning of the
   7944       // parameter map.
   7945       Handle<Context> context(isolate->context());
   7946       Handle<FixedArray> arguments =
   7947           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   7948       parameter_map->set(0, *context);
   7949       parameter_map->set(1, *arguments);
   7950 
   7951       // Loop over the actual parameters backwards.
   7952       int index = argument_count - 1;
   7953       while (index >= mapped_count) {
   7954         // These go directly in the arguments array and have no
   7955         // corresponding slot in the parameter map.
   7956         arguments->set(index, *(parameters - index - 1));
   7957         --index;
   7958       }
   7959 
   7960       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
   7961       while (index >= 0) {
   7962         // Detect duplicate names to the right in the parameter list.
   7963         Handle<String> name(scope_info->ParameterName(index));
   7964         int context_local_count = scope_info->ContextLocalCount();
   7965         bool duplicate = false;
   7966         for (int j = index + 1; j < parameter_count; ++j) {
   7967           if (scope_info->ParameterName(j) == *name) {
   7968             duplicate = true;
   7969             break;
   7970           }
   7971         }
   7972 
   7973         if (duplicate) {
   7974           // This goes directly in the arguments array with a hole in the
   7975           // parameter map.
   7976           arguments->set(index, *(parameters - index - 1));
   7977           parameter_map->set_the_hole(index + 2);
   7978         } else {
   7979           // The context index goes in the parameter map with a hole in the
   7980           // arguments array.
   7981           int context_index = -1;
   7982           for (int j = 0; j < context_local_count; ++j) {
   7983             if (scope_info->ContextLocalName(j) == *name) {
   7984               context_index = j;
   7985               break;
   7986             }
   7987           }
   7988           ASSERT(context_index >= 0);
   7989           arguments->set_the_hole(index);
   7990           parameter_map->set(index + 2, Smi::FromInt(
   7991               Context::MIN_CONTEXT_SLOTS + context_index));
   7992         }
   7993 
   7994         --index;
   7995       }
   7996     } else {
   7997       // If there is no aliasing, the arguments object elements are not
   7998       // special in any way.
   7999       Handle<FixedArray> elements =
   8000           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   8001       result->set_elements(*elements);
   8002       for (int i = 0; i < argument_count; ++i) {
   8003         elements->set(i, *(parameters - i - 1));
   8004       }
   8005     }
   8006   }
   8007   return *result;
   8008 }
   8009 
   8010 
   8011 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
   8012   SealHandleScope shs(isolate);
   8013   ASSERT(args.length() == 3);
   8014 
   8015   JSFunction* callee = JSFunction::cast(args[0]);
   8016   Object** parameters = reinterpret_cast<Object**>(args[1]);
   8017   const int length = args.smi_at(2);
   8018 
   8019   Object* result;
   8020   { MaybeObject* maybe_result =
   8021         isolate->heap()->AllocateArgumentsObject(callee, length);
   8022     if (!maybe_result->ToObject(&result)) return maybe_result;
   8023   }
   8024   // Allocate the elements if needed.
   8025   if (length > 0) {
   8026     // Allocate the fixed array.
   8027     FixedArray* array;
   8028     { MaybeObject* maybe_obj =
   8029           isolate->heap()->AllocateUninitializedFixedArray(length);
   8030       if (!maybe_obj->To(&array)) return maybe_obj;
   8031     }
   8032 
   8033     DisallowHeapAllocation no_gc;
   8034     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   8035     for (int i = 0; i < length; i++) {
   8036       array->set(i, *--parameters, mode);
   8037     }
   8038     JSObject::cast(result)->set_elements(array);
   8039   }
   8040   return result;
   8041 }
   8042 
   8043 
   8044 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosureFromStubFailure) {
   8045   HandleScope scope(isolate);
   8046   ASSERT(args.length() == 1);
   8047   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
   8048   Handle<Context> context(isolate->context());
   8049   PretenureFlag pretenure_flag = NOT_TENURED;
   8050   Handle<JSFunction> result =
   8051       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   8052                                                             context,
   8053                                                             pretenure_flag);
   8054   return *result;
   8055 }
   8056 
   8057 
   8058 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
   8059   HandleScope scope(isolate);
   8060   ASSERT(args.length() == 3);
   8061   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   8062   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
   8063   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
   8064 
   8065   // The caller ensures that we pretenure closures that are assigned
   8066   // directly to properties.
   8067   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   8068   Handle<JSFunction> result =
   8069       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   8070                                                             context,
   8071                                                             pretenure_flag);
   8072   return *result;
   8073 }
   8074 
   8075 
   8076 // Find the arguments of the JavaScript function invocation that called
   8077 // into C++ code. Collect these in a newly allocated array of handles (possibly
   8078 // prefixed by a number of empty handles).
   8079 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
   8080     Isolate* isolate,
   8081     int prefix_argc,
   8082     int* total_argc) {
   8083   // Find frame containing arguments passed to the caller.
   8084   JavaScriptFrameIterator it(isolate);
   8085   JavaScriptFrame* frame = it.frame();
   8086   List<JSFunction*> functions(2);
   8087   frame->GetFunctions(&functions);
   8088   if (functions.length() > 1) {
   8089     int inlined_jsframe_index = functions.length() - 1;
   8090     JSFunction* inlined_function = functions[inlined_jsframe_index];
   8091     Vector<SlotRef> args_slots =
   8092         SlotRef::ComputeSlotMappingForArguments(
   8093             frame,
   8094             inlined_jsframe_index,
   8095             inlined_function->shared()->formal_parameter_count());
   8096 
   8097     int args_count = args_slots.length();
   8098 
   8099     *total_argc = prefix_argc + args_count;
   8100     SmartArrayPointer<Handle<Object> > param_data(
   8101         NewArray<Handle<Object> >(*total_argc));
   8102     for (int i = 0; i < args_count; i++) {
   8103       Handle<Object> val = args_slots[i].GetValue(isolate);
   8104       param_data[prefix_argc + i] = val;
   8105     }
   8106 
   8107     args_slots.Dispose();
   8108 
   8109     return param_data;
   8110   } else {
   8111     it.AdvanceToArgumentsFrame();
   8112     frame = it.frame();
   8113     int args_count = frame->ComputeParametersCount();
   8114 
   8115     *total_argc = prefix_argc + args_count;
   8116     SmartArrayPointer<Handle<Object> > param_data(
   8117         NewArray<Handle<Object> >(*total_argc));
   8118     for (int i = 0; i < args_count; i++) {
   8119       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
   8120       param_data[prefix_argc + i] = val;
   8121     }
   8122     return param_data;
   8123   }
   8124 }
   8125 
   8126 
   8127 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
   8128   HandleScope scope(isolate);
   8129   ASSERT(args.length() == 4);
   8130   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
   8131   RUNTIME_ASSERT(args[3]->IsNumber());
   8132   Handle<Object> bindee = args.at<Object>(1);
   8133 
   8134   // TODO(lrn): Create bound function in C++ code from premade shared info.
   8135   bound_function->shared()->set_bound(true);
   8136   // Get all arguments of calling function (Function.prototype.bind).
   8137   int argc = 0;
   8138   SmartArrayPointer<Handle<Object> > arguments =
   8139       GetCallerArguments(isolate, 0, &argc);
   8140   // Don't count the this-arg.
   8141   if (argc > 0) {
   8142     ASSERT(*arguments[0] == args[2]);
   8143     argc--;
   8144   } else {
   8145     ASSERT(args[2]->IsUndefined());
   8146   }
   8147   // Initialize array of bindings (function, this, and any existing arguments
   8148   // if the function was already bound).
   8149   Handle<FixedArray> new_bindings;
   8150   int i;
   8151   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
   8152     Handle<FixedArray> old_bindings(
   8153         JSFunction::cast(*bindee)->function_bindings());
   8154     new_bindings =
   8155         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
   8156     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
   8157                             isolate);
   8158     i = 0;
   8159     for (int n = old_bindings->length(); i < n; i++) {
   8160       new_bindings->set(i, old_bindings->get(i));
   8161     }
   8162   } else {
   8163     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
   8164     new_bindings = isolate->factory()->NewFixedArray(array_size);
   8165     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
   8166     new_bindings->set(JSFunction::kBoundThisIndex, args[2]);
   8167     i = 2;
   8168   }
   8169   // Copy arguments, skipping the first which is "this_arg".
   8170   for (int j = 0; j < argc; j++, i++) {
   8171     new_bindings->set(i, *arguments[j + 1]);
   8172   }
   8173   new_bindings->set_map_no_write_barrier(
   8174       isolate->heap()->fixed_cow_array_map());
   8175   bound_function->set_function_bindings(*new_bindings);
   8176 
   8177   // Update length.
   8178   Handle<String> length_string = isolate->factory()->length_string();
   8179   Handle<Object> new_length(args.at<Object>(3));
   8180   PropertyAttributes attr =
   8181       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
   8182   ForceSetProperty(bound_function, length_string, new_length, attr);
   8183   return *bound_function;
   8184 }
   8185 
   8186 
   8187 RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
   8188   HandleScope handles(isolate);
   8189   ASSERT(args.length() == 1);
   8190   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
   8191   if (callable->IsJSFunction()) {
   8192     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
   8193     if (function->shared()->bound()) {
   8194       Handle<FixedArray> bindings(function->function_bindings());
   8195       ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
   8196       return *isolate->factory()->NewJSArrayWithElements(bindings);
   8197     }
   8198   }
   8199   return isolate->heap()->undefined_value();
   8200 }
   8201 
   8202 
   8203 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
   8204   HandleScope scope(isolate);
   8205   ASSERT(args.length() == 1);
   8206   // First argument is a function to use as a constructor.
   8207   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8208   RUNTIME_ASSERT(function->shared()->bound());
   8209 
   8210   // The argument is a bound function. Extract its bound arguments
   8211   // and callable.
   8212   Handle<FixedArray> bound_args =
   8213       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
   8214   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
   8215   Handle<Object> bound_function(
   8216       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
   8217       isolate);
   8218   ASSERT(!bound_function->IsJSFunction() ||
   8219          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
   8220 
   8221   int total_argc = 0;
   8222   SmartArrayPointer<Handle<Object> > param_data =
   8223       GetCallerArguments(isolate, bound_argc, &total_argc);
   8224   for (int i = 0; i < bound_argc; i++) {
   8225     param_data[i] = Handle<Object>(bound_args->get(
   8226         JSFunction::kBoundArgumentsStartIndex + i), isolate);
   8227   }
   8228 
   8229   if (!bound_function->IsJSFunction()) {
   8230     bool exception_thrown;
   8231     bound_function = Execution::TryGetConstructorDelegate(isolate,
   8232                                                           bound_function,
   8233                                                           &exception_thrown);
   8234     if (exception_thrown) return Failure::Exception();
   8235   }
   8236   ASSERT(bound_function->IsJSFunction());
   8237 
   8238   bool exception = false;
   8239   Handle<Object> result =
   8240       Execution::New(Handle<JSFunction>::cast(bound_function),
   8241                      total_argc, *param_data, &exception);
   8242   if (exception) {
   8243     return Failure::Exception();
   8244   }
   8245   ASSERT(!result.is_null());
   8246   return *result;
   8247 }
   8248 
   8249 
   8250 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
   8251   HandleScope scope(isolate);
   8252   ASSERT(args.length() == 1);
   8253 
   8254   Handle<Object> constructor = args.at<Object>(0);
   8255 
   8256   // If the constructor isn't a proper function we throw a type error.
   8257   if (!constructor->IsJSFunction()) {
   8258     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8259     Handle<Object> type_error =
   8260         isolate->factory()->NewTypeError("not_constructor", arguments);
   8261     return isolate->Throw(*type_error);
   8262   }
   8263 
   8264   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
   8265 
   8266   // If function should not have prototype, construction is not allowed. In this
   8267   // case generated code bailouts here, since function has no initial_map.
   8268   if (!function->should_have_prototype() && !function->shared()->bound()) {
   8269     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8270     Handle<Object> type_error =
   8271         isolate->factory()->NewTypeError("not_constructor", arguments);
   8272     return isolate->Throw(*type_error);
   8273   }
   8274 
   8275 #ifdef ENABLE_DEBUGGER_SUPPORT
   8276   Debug* debug = isolate->debug();
   8277   // Handle stepping into constructors if step into is active.
   8278   if (debug->StepInActive()) {
   8279     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
   8280   }
   8281 #endif
   8282 
   8283   if (function->has_initial_map()) {
   8284     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
   8285       // The 'Function' function ignores the receiver object when
   8286       // called using 'new' and creates a new JSFunction object that
   8287       // is returned.  The receiver object is only used for error
   8288       // reporting if an error occurs when constructing the new
   8289       // JSFunction. Factory::NewJSObject() should not be used to
   8290       // allocate JSFunctions since it does not properly initialize
   8291       // the shared part of the function. Since the receiver is
   8292       // ignored anyway, we use the global object as the receiver
   8293       // instead of a new JSFunction object. This way, errors are
   8294       // reported the same way whether or not 'Function' is called
   8295       // using 'new'.
   8296       return isolate->context()->global_object();
   8297     }
   8298   }
   8299 
   8300   // The function should be compiled for the optimization hints to be
   8301   // available.
   8302   JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION);
   8303 
   8304   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
   8305   if (!function->has_initial_map() &&
   8306       shared->IsInobjectSlackTrackingInProgress()) {
   8307     // The tracking is already in progress for another function. We can only
   8308     // track one initial_map at a time, so we force the completion before the
   8309     // function is called as a constructor for the first time.
   8310     shared->CompleteInobjectSlackTracking();
   8311   }
   8312 
   8313   Handle<JSObject> result = isolate->factory()->NewJSObject(function);
   8314   RETURN_IF_EMPTY_HANDLE(isolate, result);
   8315 
   8316   isolate->counters()->constructed_objects()->Increment();
   8317   isolate->counters()->constructed_objects_runtime()->Increment();
   8318 
   8319   return *result;
   8320 }
   8321 
   8322 
   8323 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) {
   8324   HandleScope scope(isolate);
   8325   ASSERT(args.length() == 1);
   8326 
   8327   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8328   function->shared()->CompleteInobjectSlackTracking();
   8329 
   8330   return isolate->heap()->undefined_value();
   8331 }
   8332 
   8333 
   8334 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
   8335   HandleScope scope(isolate);
   8336   ASSERT(args.length() == 1);
   8337 
   8338   Handle<JSFunction> function = args.at<JSFunction>(0);
   8339 #ifdef DEBUG
   8340   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
   8341     PrintF("[lazy: ");
   8342     function->PrintName();
   8343     PrintF("]\n");
   8344   }
   8345 #endif
   8346 
   8347   // Compile the target function.
   8348   ASSERT(!function->is_compiled());
   8349   if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) {
   8350     return Failure::Exception();
   8351   }
   8352 
   8353   // All done. Return the compiled code.
   8354   ASSERT(function->is_compiled());
   8355   return function->code();
   8356 }
   8357 
   8358 
   8359 bool AllowOptimization(Isolate* isolate, Handle<JSFunction> function) {
   8360   // If the function is not compiled ignore the lazy
   8361   // recompilation. This can happen if the debugger is activated and
   8362   // the function is returned to the not compiled state.
   8363   if (!function->shared()->is_compiled()) return false;
   8364 
   8365   // If the function is not optimizable or debugger is active continue using the
   8366   // code from the full compiler.
   8367   if (!isolate->use_crankshaft() ||
   8368       function->shared()->optimization_disabled() ||
   8369       isolate->DebuggerHasBreakPoints()) {
   8370     if (FLAG_trace_opt) {
   8371       PrintF("[failed to optimize ");
   8372       function->PrintName();
   8373       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
   8374           function->shared()->optimization_disabled() ? "F" : "T",
   8375           isolate->DebuggerHasBreakPoints() ? "T" : "F");
   8376     }
   8377     return false;
   8378   }
   8379   return true;
   8380 }
   8381 
   8382 
   8383 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
   8384   HandleScope scope(isolate);
   8385   ASSERT(args.length() == 1);
   8386   Handle<JSFunction> function = args.at<JSFunction>(0);
   8387 
   8388   if (!AllowOptimization(isolate, function)) {
   8389     function->ReplaceCode(function->shared()->code());
   8390     return function->code();
   8391   }
   8392   function->shared()->code()->set_profiler_ticks(0);
   8393   if (JSFunction::CompileOptimized(function, CLEAR_EXCEPTION)) {
   8394     return function->code();
   8395   }
   8396   if (FLAG_trace_opt) {
   8397     PrintF("[failed to optimize ");
   8398     function->PrintName();
   8399     PrintF(": optimized compilation failed]\n");
   8400   }
   8401   function->ReplaceCode(function->shared()->code());
   8402   return function->code();
   8403 }
   8404 
   8405 
   8406 RUNTIME_FUNCTION(MaybeObject*, Runtime_ConcurrentRecompile) {
   8407   HandleScope handle_scope(isolate);
   8408   ASSERT(args.length() == 1);
   8409   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8410   if (!AllowOptimization(isolate, function)) {
   8411     function->ReplaceCode(function->shared()->code());
   8412     return isolate->heap()->undefined_value();
   8413   }
   8414   function->shared()->code()->set_profiler_ticks(0);
   8415   ASSERT(isolate->concurrent_recompilation_enabled());
   8416   if (!Compiler::RecompileConcurrent(function)) {
   8417     function->ReplaceCode(function->shared()->code());
   8418   }
   8419   return isolate->heap()->undefined_value();
   8420 }
   8421 
   8422 
   8423 class ActivationsFinder : public ThreadVisitor {
   8424  public:
   8425   Code* code_;
   8426   bool has_code_activations_;
   8427 
   8428   explicit ActivationsFinder(Code* code)
   8429     : code_(code),
   8430       has_code_activations_(false) { }
   8431 
   8432   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
   8433     JavaScriptFrameIterator it(isolate, top);
   8434     VisitFrames(&it);
   8435   }
   8436 
   8437   void VisitFrames(JavaScriptFrameIterator* it) {
   8438     for (; !it->done(); it->Advance()) {
   8439       JavaScriptFrame* frame = it->frame();
   8440       if (code_->contains(frame->pc())) has_code_activations_ = true;
   8441     }
   8442   }
   8443 };
   8444 
   8445 
   8446 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) {
   8447   HandleScope scope(isolate);
   8448   ASSERT(args.length() == 0);
   8449   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8450   ASSERT(AllowHeapAllocation::IsAllowed());
   8451   delete deoptimizer;
   8452   return isolate->heap()->undefined_value();
   8453 }
   8454 
   8455 
   8456 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
   8457   HandleScope scope(isolate);
   8458   ASSERT(args.length() == 1);
   8459   RUNTIME_ASSERT(args[0]->IsSmi());
   8460   Deoptimizer::BailoutType type =
   8461       static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
   8462   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8463   ASSERT(AllowHeapAllocation::IsAllowed());
   8464 
   8465   Handle<JSFunction> function = deoptimizer->function();
   8466   Handle<Code> optimized_code = deoptimizer->compiled_code();
   8467 
   8468   ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
   8469   ASSERT(type == deoptimizer->bailout_type());
   8470 
   8471   // Make sure to materialize objects before causing any allocation.
   8472   JavaScriptFrameIterator it(isolate);
   8473   deoptimizer->MaterializeHeapObjects(&it);
   8474   delete deoptimizer;
   8475 
   8476   JavaScriptFrame* frame = it.frame();
   8477   RUNTIME_ASSERT(frame->function()->IsJSFunction());
   8478   ASSERT(frame->function() == *function);
   8479 
   8480   // Avoid doing too much work when running with --always-opt and keep
   8481   // the optimized code around.
   8482   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
   8483     return isolate->heap()->undefined_value();
   8484   }
   8485 
   8486   // Search for other activations of the same function and code.
   8487   ActivationsFinder activations_finder(*optimized_code);
   8488   activations_finder.VisitFrames(&it);
   8489   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
   8490 
   8491   if (!activations_finder.has_code_activations_) {
   8492     if (function->code() == *optimized_code) {
   8493       if (FLAG_trace_deopt) {
   8494         PrintF("[removing optimized code for: ");
   8495         function->PrintName();
   8496         PrintF("]\n");
   8497       }
   8498       function->ReplaceCode(function->shared()->code());
   8499     }
   8500   } else {
   8501     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
   8502     // unconditionally if the code is not already marked for deoptimization.
   8503     // If there is an index by shared function info, all the better.
   8504     Deoptimizer::DeoptimizeFunction(*function);
   8505   }
   8506   // Evict optimized code for this function from the cache so that it doesn't
   8507   // get used for new closures.
   8508   function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
   8509                                                 "notify deoptimized");
   8510 
   8511   return isolate->heap()->undefined_value();
   8512 }
   8513 
   8514 
   8515 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
   8516   HandleScope scope(isolate);
   8517   ASSERT(args.length() == 1);
   8518   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8519   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
   8520 
   8521   Deoptimizer::DeoptimizeFunction(*function);
   8522 
   8523   return isolate->heap()->undefined_value();
   8524 }
   8525 
   8526 
   8527 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearFunctionTypeFeedback) {
   8528   HandleScope scope(isolate);
   8529   ASSERT(args.length() == 1);
   8530   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8531   Code* unoptimized = function->shared()->code();
   8532   if (unoptimized->kind() == Code::FUNCTION) {
   8533     unoptimized->ClearInlineCaches();
   8534     unoptimized->ClearTypeFeedbackCells(isolate->heap());
   8535   }
   8536   return isolate->heap()->undefined_value();
   8537 }
   8538 
   8539 
   8540 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
   8541   SealHandleScope shs(isolate);
   8542 #if defined(USE_SIMULATOR)
   8543   return isolate->heap()->true_value();
   8544 #else
   8545   return isolate->heap()->false_value();
   8546 #endif
   8547 }
   8548 
   8549 
   8550 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsConcurrentRecompilationSupported) {
   8551   HandleScope scope(isolate);
   8552   return isolate->concurrent_recompilation_enabled()
   8553       ? isolate->heap()->true_value() : isolate->heap()->false_value();
   8554 }
   8555 
   8556 
   8557 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
   8558   HandleScope scope(isolate);
   8559   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8560   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8561 
   8562   if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
   8563   function->MarkForLazyRecompilation();
   8564 
   8565   Code* unoptimized = function->shared()->code();
   8566   if (args.length() == 2 &&
   8567       unoptimized->kind() == Code::FUNCTION) {
   8568     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   8569     if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
   8570       // Start patching from the currently patched loop nesting level.
   8571       int current_level = unoptimized->allow_osr_at_loop_nesting_level();
   8572       ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
   8573       for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
   8574         unoptimized->set_allow_osr_at_loop_nesting_level(i);
   8575         isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
   8576       }
   8577     } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent"))) {
   8578       function->MarkForConcurrentRecompilation();
   8579     }
   8580   }
   8581 
   8582   return isolate->heap()->undefined_value();
   8583 }
   8584 
   8585 
   8586 RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimizeFunction) {
   8587   HandleScope scope(isolate);
   8588   ASSERT(args.length() == 1);
   8589   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8590   ASSERT(!function->IsOptimized());
   8591   function->shared()->set_optimization_disabled(true);
   8592   return isolate->heap()->undefined_value();
   8593 }
   8594 
   8595 
   8596 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
   8597   HandleScope scope(isolate);
   8598   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8599   if (!isolate->use_crankshaft()) {
   8600     return Smi::FromInt(4);  // 4 == "never".
   8601   }
   8602   bool sync_with_compiler_thread = true;
   8603   if (args.length() == 2) {
   8604     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
   8605     if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
   8606       sync_with_compiler_thread = false;
   8607     }
   8608   }
   8609   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8610   if (isolate->concurrent_recompilation_enabled() &&
   8611       sync_with_compiler_thread) {
   8612     while (function->IsInRecompileQueue()) {
   8613       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   8614       OS::Sleep(50);
   8615     }
   8616   }
   8617   if (FLAG_always_opt) {
   8618     // We may have always opt, but that is more best-effort than a real
   8619     // promise, so we still say "no" if it is not optimized.
   8620     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
   8621                                    : Smi::FromInt(2);  // 2 == "no".
   8622   }
   8623   if (FLAG_deopt_every_n_times) {
   8624     return Smi::FromInt(6);  // 6 == "maybe deopted".
   8625   }
   8626   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
   8627                                  : Smi::FromInt(2);  // 2 == "no".
   8628 }
   8629 
   8630 
   8631 RUNTIME_FUNCTION(MaybeObject*, Runtime_UnblockConcurrentRecompilation) {
   8632   RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
   8633   isolate->optimizing_compiler_thread()->Unblock();
   8634   return isolate->heap()->undefined_value();
   8635 }
   8636 
   8637 
   8638 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
   8639   HandleScope scope(isolate);
   8640   ASSERT(args.length() == 1);
   8641   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8642   return Smi::FromInt(function->shared()->opt_count());
   8643 }
   8644 
   8645 
   8646 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
   8647                                             Handle<JSFunction> function,
   8648                                             Handle<Code> unoptimized) {
   8649   // Keep track of whether we've succeeded in optimizing.
   8650   if (!isolate->use_crankshaft() || !unoptimized->optimizable()) return false;
   8651   // If we are trying to do OSR when there are already optimized
   8652   // activations of the function, it means (a) the function is directly or
   8653   // indirectly recursive and (b) an optimized invocation has been
   8654   // deoptimized so that we are currently in an unoptimized activation.
   8655   // Check for optimized activations of this function.
   8656   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
   8657     JavaScriptFrame* frame = it.frame();
   8658     if (frame->is_optimized() && frame->function() == *function) return false;
   8659   }
   8660 
   8661   return true;
   8662 }
   8663 
   8664 
   8665 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
   8666   HandleScope scope(isolate);
   8667   ASSERT(args.length() == 2);
   8668   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8669   CONVERT_NUMBER_CHECKED(uint32_t, pc_offset, Uint32, args[1]);
   8670   Handle<Code> unoptimized(function->shared()->code(), isolate);
   8671 
   8672 #ifdef DEBUG
   8673   JavaScriptFrameIterator it(isolate);
   8674   JavaScriptFrame* frame = it.frame();
   8675   ASSERT_EQ(frame->function(), *function);
   8676   ASSERT_EQ(frame->LookupCode(), *unoptimized);
   8677   ASSERT(unoptimized->contains(frame->pc()));
   8678 
   8679   ASSERT(pc_offset ==
   8680          static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()));
   8681 #endif  // DEBUG
   8682 
   8683   // We're not prepared to handle a function with arguments object.
   8684   ASSERT(!function->shared()->uses_arguments());
   8685 
   8686   Handle<Code> result = Handle<Code>::null();
   8687   BailoutId ast_id = BailoutId::None();
   8688 
   8689   if (isolate->concurrent_osr_enabled()) {
   8690     if (isolate->optimizing_compiler_thread()->
   8691             IsQueuedForOSR(function, pc_offset)) {
   8692       // Still waiting for the optimizing compiler thread to finish.  Carry on.
   8693       if (FLAG_trace_osr) {
   8694         PrintF("[COSR - polling recompile tasks for ");
   8695         function->PrintName();
   8696         PrintF("]\n");
   8697       }
   8698       return NULL;
   8699     }
   8700 
   8701     RecompileJob* job = isolate->optimizing_compiler_thread()->
   8702         FindReadyOSRCandidate(function, pc_offset);
   8703 
   8704     if (job == NULL) {
   8705       if (IsSuitableForOnStackReplacement(isolate, function, unoptimized) &&
   8706           Compiler::RecompileConcurrent(function, pc_offset)) {
   8707         if (function->IsMarkedForLazyRecompilation() ||
   8708             function->IsMarkedForConcurrentRecompilation()) {
   8709           // Prevent regular recompilation if we queue this for OSR.
   8710           // TODO(yangguo): remove this as soon as OSR becomes one-shot.
   8711           function->ReplaceCode(*unoptimized);
   8712         }
   8713         return NULL;
   8714       }
   8715       // Fall through to the end in case of failure.
   8716     } else {
   8717       // TODO(titzer): don't install the OSR code into the function.
   8718       ast_id = job->info()->osr_ast_id();
   8719       result = Compiler::InstallOptimizedCode(job);
   8720     }
   8721   } else if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
   8722     ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
   8723     ASSERT(!ast_id.IsNone());
   8724     if (FLAG_trace_osr) {
   8725       PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
   8726       function->PrintName();
   8727       PrintF("]\n");
   8728     }
   8729     // Attempt OSR compilation.
   8730     result = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION);
   8731   }
   8732 
   8733   // Revert the patched back edge table, regardless of whether OSR succeeds.
   8734   BackEdgeTable::Revert(isolate, *unoptimized);
   8735 
   8736   // Check whether we ended up with usable optimized code.
   8737   if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
   8738     DeoptimizationInputData* data =
   8739         DeoptimizationInputData::cast(result->deoptimization_data());
   8740 
   8741     if (data->OsrPcOffset()->value() >= 0) {
   8742       ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
   8743       if (FLAG_trace_osr) {
   8744         PrintF("[OSR - entry at AST id %d, offset %d in optimized code]\n",
   8745                ast_id.ToInt(), data->OsrPcOffset()->value());
   8746       }
   8747       // TODO(titzer): this is a massive hack to make the deopt counts
   8748       // match. Fix heuristics for reenabling optimizations!
   8749       function->shared()->increment_deopt_count();
   8750       return *result;
   8751     }
   8752   }
   8753 
   8754   if (FLAG_trace_osr) {
   8755     PrintF("[OSR - optimization failed for ");
   8756     function->PrintName();
   8757     PrintF("]\n");
   8758   }
   8759 
   8760   if (function->IsMarkedForLazyRecompilation() ||
   8761       function->IsMarkedForConcurrentRecompilation()) {
   8762     function->ReplaceCode(function->shared()->code());
   8763   }
   8764   return NULL;
   8765 }
   8766 
   8767 
   8768 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
   8769   SealHandleScope shs(isolate);
   8770   ASSERT(args.length() == 2);
   8771 #ifdef DEBUG
   8772   CONVERT_SMI_ARG_CHECKED(interval, 0);
   8773   CONVERT_SMI_ARG_CHECKED(timeout, 1);
   8774   isolate->heap()->set_allocation_timeout(timeout);
   8775   FLAG_gc_interval = interval;
   8776 #endif
   8777   return isolate->heap()->undefined_value();
   8778 }
   8779 
   8780 
   8781 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
   8782   SealHandleScope shs(isolate);
   8783   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8784   return isolate->heap()->undefined_value();
   8785 }
   8786 
   8787 
   8788 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
   8789   SealHandleScope shs(isolate);
   8790   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8791   return isolate->heap()->nan_value();
   8792 }
   8793 
   8794 
   8795 RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
   8796   HandleScope scope(isolate);
   8797   ASSERT(args.length() >= 2);
   8798   int argc = args.length() - 2;
   8799   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
   8800   Object* receiver = args[0];
   8801 
   8802   // If there are too many arguments, allocate argv via malloc.
   8803   const int argv_small_size = 10;
   8804   Handle<Object> argv_small_buffer[argv_small_size];
   8805   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8806   Handle<Object>* argv = argv_small_buffer;
   8807   if (argc > argv_small_size) {
   8808     argv = new Handle<Object>[argc];
   8809     if (argv == NULL) return isolate->StackOverflow();
   8810     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8811   }
   8812 
   8813   for (int i = 0; i < argc; ++i) {
   8814      MaybeObject* maybe = args[1 + i];
   8815      Object* object;
   8816      if (!maybe->To<Object>(&object)) return maybe;
   8817      argv[i] = Handle<Object>(object, isolate);
   8818   }
   8819 
   8820   bool threw;
   8821   Handle<JSReceiver> hfun(fun);
   8822   Handle<Object> hreceiver(receiver, isolate);
   8823   Handle<Object> result = Execution::Call(
   8824       isolate, hfun, hreceiver, argc, argv, &threw, true);
   8825 
   8826   if (threw) return Failure::Exception();
   8827   return *result;
   8828 }
   8829 
   8830 
   8831 RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
   8832   HandleScope scope(isolate);
   8833   ASSERT(args.length() == 5);
   8834   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
   8835   Handle<Object> receiver = args.at<Object>(1);
   8836   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
   8837   CONVERT_SMI_ARG_CHECKED(offset, 3);
   8838   CONVERT_SMI_ARG_CHECKED(argc, 4);
   8839   RUNTIME_ASSERT(offset >= 0);
   8840   RUNTIME_ASSERT(argc >= 0);
   8841 
   8842   // If there are too many arguments, allocate argv via malloc.
   8843   const int argv_small_size = 10;
   8844   Handle<Object> argv_small_buffer[argv_small_size];
   8845   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8846   Handle<Object>* argv = argv_small_buffer;
   8847   if (argc > argv_small_size) {
   8848     argv = new Handle<Object>[argc];
   8849     if (argv == NULL) return isolate->StackOverflow();
   8850     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8851   }
   8852 
   8853   for (int i = 0; i < argc; ++i) {
   8854     argv[i] = Object::GetElement(isolate, arguments, offset + i);
   8855   }
   8856 
   8857   bool threw;
   8858   Handle<Object> result = Execution::Call(
   8859       isolate, fun, receiver, argc, argv, &threw, true);
   8860 
   8861   if (threw) return Failure::Exception();
   8862   return *result;
   8863 }
   8864 
   8865 
   8866 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
   8867   HandleScope scope(isolate);
   8868   ASSERT(args.length() == 1);
   8869   RUNTIME_ASSERT(!args[0]->IsJSFunction());
   8870   return *Execution::GetFunctionDelegate(isolate, args.at<Object>(0));
   8871 }
   8872 
   8873 
   8874 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
   8875   HandleScope scope(isolate);
   8876   ASSERT(args.length() == 1);
   8877   RUNTIME_ASSERT(!args[0]->IsJSFunction());
   8878   return *Execution::GetConstructorDelegate(isolate, args.at<Object>(0));
   8879 }
   8880 
   8881 
   8882 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewGlobalContext) {
   8883   SealHandleScope shs(isolate);
   8884   ASSERT(args.length() == 2);
   8885 
   8886   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8887   CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 1);
   8888   Context* result;
   8889   MaybeObject* maybe_result =
   8890       isolate->heap()->AllocateGlobalContext(function, scope_info);
   8891   if (!maybe_result->To(&result)) return maybe_result;
   8892 
   8893   ASSERT(function->context() == isolate->context());
   8894   ASSERT(function->context()->global_object() == result->global_object());
   8895   isolate->set_context(result);
   8896   result->global_object()->set_global_context(result);
   8897 
   8898   return result;  // non-failure
   8899 }
   8900 
   8901 
   8902 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
   8903   SealHandleScope shs(isolate);
   8904   ASSERT(args.length() == 1);
   8905 
   8906   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8907   int length = function->shared()->scope_info()->ContextLength();
   8908   Context* result;
   8909   MaybeObject* maybe_result =
   8910       isolate->heap()->AllocateFunctionContext(length, function);
   8911   if (!maybe_result->To(&result)) return maybe_result;
   8912 
   8913   isolate->set_context(result);
   8914 
   8915   return result;  // non-failure
   8916 }
   8917 
   8918 
   8919 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
   8920   SealHandleScope shs(isolate);
   8921   ASSERT(args.length() == 2);
   8922   JSReceiver* extension_object;
   8923   if (args[0]->IsJSReceiver()) {
   8924     extension_object = JSReceiver::cast(args[0]);
   8925   } else {
   8926     // Convert the object to a proper JavaScript object.
   8927     MaybeObject* maybe_js_object = args[0]->ToObject(isolate);
   8928     if (!maybe_js_object->To(&extension_object)) {
   8929       if (Failure::cast(maybe_js_object)->IsInternalError()) {
   8930         HandleScope scope(isolate);
   8931         Handle<Object> handle = args.at<Object>(0);
   8932         Handle<Object> result =
   8933             isolate->factory()->NewTypeError("with_expression",
   8934                                              HandleVector(&handle, 1));
   8935         return isolate->Throw(*result);
   8936       } else {
   8937         return maybe_js_object;
   8938       }
   8939     }
   8940   }
   8941 
   8942   JSFunction* function;
   8943   if (args[1]->IsSmi()) {
   8944     // A smi sentinel indicates a context nested inside global code rather
   8945     // than some function.  There is a canonical empty function that can be
   8946     // gotten from the native context.
   8947     function = isolate->context()->native_context()->closure();
   8948   } else {
   8949     function = JSFunction::cast(args[1]);
   8950   }
   8951 
   8952   Context* context;
   8953   MaybeObject* maybe_context =
   8954       isolate->heap()->AllocateWithContext(function,
   8955                                            isolate->context(),
   8956                                            extension_object);
   8957   if (!maybe_context->To(&context)) return maybe_context;
   8958   isolate->set_context(context);
   8959   return context;
   8960 }
   8961 
   8962 
   8963 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
   8964   SealHandleScope shs(isolate);
   8965   ASSERT(args.length() == 3);
   8966   String* name = String::cast(args[0]);
   8967   Object* thrown_object = args[1];
   8968   JSFunction* function;
   8969   if (args[2]->IsSmi()) {
   8970     // A smi sentinel indicates a context nested inside global code rather
   8971     // than some function.  There is a canonical empty function that can be
   8972     // gotten from the native context.
   8973     function = isolate->context()->native_context()->closure();
   8974   } else {
   8975     function = JSFunction::cast(args[2]);
   8976   }
   8977   Context* context;
   8978   MaybeObject* maybe_context =
   8979       isolate->heap()->AllocateCatchContext(function,
   8980                                             isolate->context(),
   8981                                             name,
   8982                                             thrown_object);
   8983   if (!maybe_context->To(&context)) return maybe_context;
   8984   isolate->set_context(context);
   8985   return context;
   8986 }
   8987 
   8988 
   8989 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
   8990   SealHandleScope shs(isolate);
   8991   ASSERT(args.length() == 2);
   8992   ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
   8993   JSFunction* function;
   8994   if (args[1]->IsSmi()) {
   8995     // A smi sentinel indicates a context nested inside global code rather
   8996     // than some function.  There is a canonical empty function that can be
   8997     // gotten from the native context.
   8998     function = isolate->context()->native_context()->closure();
   8999   } else {
   9000     function = JSFunction::cast(args[1]);
   9001   }
   9002   Context* context;
   9003   MaybeObject* maybe_context =
   9004       isolate->heap()->AllocateBlockContext(function,
   9005                                             isolate->context(),
   9006                                             scope_info);
   9007   if (!maybe_context->To(&context)) return maybe_context;
   9008   isolate->set_context(context);
   9009   return context;
   9010 }
   9011 
   9012 
   9013 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSModule) {
   9014   SealHandleScope shs(isolate);
   9015   ASSERT(args.length() == 1);
   9016   Object* obj = args[0];
   9017   return isolate->heap()->ToBoolean(obj->IsJSModule());
   9018 }
   9019 
   9020 
   9021 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushModuleContext) {
   9022   SealHandleScope shs(isolate);
   9023   ASSERT(args.length() == 2);
   9024   CONVERT_SMI_ARG_CHECKED(index, 0);
   9025 
   9026   if (!args[1]->IsScopeInfo()) {
   9027     // Module already initialized. Find hosting context and retrieve context.
   9028     Context* host = Context::cast(isolate->context())->global_context();
   9029     Context* context = Context::cast(host->get(index));
   9030     ASSERT(context->previous() == isolate->context());
   9031     isolate->set_context(context);
   9032     return context;
   9033   }
   9034 
   9035   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
   9036 
   9037   // Allocate module context.
   9038   HandleScope scope(isolate);
   9039   Factory* factory = isolate->factory();
   9040   Handle<Context> context = factory->NewModuleContext(scope_info);
   9041   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
   9042   context->set_module(*module);
   9043   Context* previous = isolate->context();
   9044   context->set_previous(previous);
   9045   context->set_closure(previous->closure());
   9046   context->set_global_object(previous->global_object());
   9047   isolate->set_context(*context);
   9048 
   9049   // Find hosting scope and initialize internal variable holding module there.
   9050   previous->global_context()->set(index, *context);
   9051 
   9052   return *context;
   9053 }
   9054 
   9055 
   9056 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareModules) {
   9057   HandleScope scope(isolate);
   9058   ASSERT(args.length() == 1);
   9059   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
   9060   Context* host_context = isolate->context();
   9061 
   9062   for (int i = 0; i < descriptions->length(); ++i) {
   9063     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
   9064     int host_index = description->host_index();
   9065     Handle<Context> context(Context::cast(host_context->get(host_index)));
   9066     Handle<JSModule> module(context->module());
   9067 
   9068     for (int j = 0; j < description->length(); ++j) {
   9069       Handle<String> name(description->name(j));
   9070       VariableMode mode = description->mode(j);
   9071       int index = description->index(j);
   9072       switch (mode) {
   9073         case VAR:
   9074         case LET:
   9075         case CONST:
   9076         case CONST_HARMONY: {
   9077           PropertyAttributes attr =
   9078               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
   9079           Handle<AccessorInfo> info =
   9080               Accessors::MakeModuleExport(name, index, attr);
   9081           Handle<Object> result = JSObject::SetAccessor(module, info);
   9082           ASSERT(!(result.is_null() || result->IsUndefined()));
   9083           USE(result);
   9084           break;
   9085         }
   9086         case MODULE: {
   9087           Object* referenced_context = Context::cast(host_context)->get(index);
   9088           Handle<JSModule> value(Context::cast(referenced_context)->module());
   9089           JSReceiver::SetProperty(module, name, value, FROZEN, kStrictMode);
   9090           break;
   9091         }
   9092         case INTERNAL:
   9093         case TEMPORARY:
   9094         case DYNAMIC:
   9095         case DYNAMIC_GLOBAL:
   9096         case DYNAMIC_LOCAL:
   9097           UNREACHABLE();
   9098       }
   9099     }
   9100 
   9101     JSObject::PreventExtensions(module);
   9102   }
   9103 
   9104   ASSERT(!isolate->has_pending_exception());
   9105   return isolate->heap()->undefined_value();
   9106 }
   9107 
   9108 
   9109 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
   9110   HandleScope scope(isolate);
   9111   ASSERT(args.length() == 2);
   9112 
   9113   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   9114   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   9115 
   9116   int index;
   9117   PropertyAttributes attributes;
   9118   ContextLookupFlags flags = FOLLOW_CHAINS;
   9119   BindingFlags binding_flags;
   9120   Handle<Object> holder = context->Lookup(name,
   9121                                           flags,
   9122                                           &index,
   9123                                           &attributes,
   9124                                           &binding_flags);
   9125 
   9126   // If the slot was not found the result is true.
   9127   if (holder.is_null()) {
   9128     return isolate->heap()->true_value();
   9129   }
   9130 
   9131   // If the slot was found in a context, it should be DONT_DELETE.
   9132   if (holder->IsContext()) {
   9133     return isolate->heap()->false_value();
   9134   }
   9135 
   9136   // The slot was found in a JSObject, either a context extension object,
   9137   // the global object, or the subject of a with.  Try to delete it
   9138   // (respecting DONT_DELETE).
   9139   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   9140   Handle<Object> result = JSReceiver::DeleteProperty(object, name);
   9141   RETURN_IF_EMPTY_HANDLE(isolate, result);
   9142   return *result;
   9143 }
   9144 
   9145 
   9146 // A mechanism to return a pair of Object pointers in registers (if possible).
   9147 // How this is achieved is calling convention-dependent.
   9148 // All currently supported x86 compiles uses calling conventions that are cdecl
   9149 // variants where a 64-bit value is returned in two 32-bit registers
   9150 // (edx:eax on ia32, r1:r0 on ARM).
   9151 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
   9152 // In Win64 calling convention, a struct of two pointers is returned in memory,
   9153 // allocated by the caller, and passed as a pointer in a hidden first parameter.
   9154 #ifdef V8_HOST_ARCH_64_BIT
   9155 struct ObjectPair {
   9156   MaybeObject* x;
   9157   MaybeObject* y;
   9158 };
   9159 
   9160 
   9161 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
   9162   ObjectPair result = {x, y};
   9163   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
   9164   // In Win64 they are assigned to a hidden first argument.
   9165   return result;
   9166 }
   9167 #else
   9168 typedef uint64_t ObjectPair;
   9169 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
   9170   return reinterpret_cast<uint32_t>(x) |
   9171       (reinterpret_cast<ObjectPair>(y) << 32);
   9172 }
   9173 #endif
   9174 
   9175 
   9176 static inline MaybeObject* Unhole(Heap* heap,
   9177                                   MaybeObject* x,
   9178                                   PropertyAttributes attributes) {
   9179   ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
   9180   USE(attributes);
   9181   return x->IsTheHole() ? heap->undefined_value() : x;
   9182 }
   9183 
   9184 
   9185 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
   9186                                            JSObject* holder) {
   9187   ASSERT(!holder->IsGlobalObject());
   9188   Context* top = isolate->context();
   9189   // Get the context extension function.
   9190   JSFunction* context_extension_function =
   9191       top->native_context()->context_extension_function();
   9192   // If the holder isn't a context extension object, we just return it
   9193   // as the receiver. This allows arguments objects to be used as
   9194   // receivers, but only if they are put in the context scope chain
   9195   // explicitly via a with-statement.
   9196   Object* constructor = holder->map()->constructor();
   9197   if (constructor != context_extension_function) return holder;
   9198   // Fall back to using the global object as the implicit receiver if
   9199   // the property turns out to be a local variable allocated in a
   9200   // context extension object - introduced via eval. Implicit global
   9201   // receivers are indicated with the hole value.
   9202   return isolate->heap()->the_hole_value();
   9203 }
   9204 
   9205 
   9206 static ObjectPair LoadContextSlotHelper(Arguments args,
   9207                                         Isolate* isolate,
   9208                                         bool throw_error) {
   9209   HandleScope scope(isolate);
   9210   ASSERT_EQ(2, args.length());
   9211 
   9212   if (!args[0]->IsContext() || !args[1]->IsString()) {
   9213     return MakePair(isolate->ThrowIllegalOperation(), NULL);
   9214   }
   9215   Handle<Context> context = args.at<Context>(0);
   9216   Handle<String> name = args.at<String>(1);
   9217 
   9218   int index;
   9219   PropertyAttributes attributes;
   9220   ContextLookupFlags flags = FOLLOW_CHAINS;
   9221   BindingFlags binding_flags;
   9222   Handle<Object> holder = context->Lookup(name,
   9223                                           flags,
   9224                                           &index,
   9225                                           &attributes,
   9226                                           &binding_flags);
   9227   if (isolate->has_pending_exception()) {
   9228     return MakePair(Failure::Exception(), NULL);
   9229   }
   9230 
   9231   // If the index is non-negative, the slot has been found in a context.
   9232   if (index >= 0) {
   9233     ASSERT(holder->IsContext());
   9234     // If the "property" we were looking for is a local variable, the
   9235     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
   9236     //
   9237     // Use the hole as the receiver to signal that the receiver is implicit
   9238     // and that the global receiver should be used (as distinguished from an
   9239     // explicit receiver that happens to be a global object).
   9240     Handle<Object> receiver = isolate->factory()->the_hole_value();
   9241     Object* value = Context::cast(*holder)->get(index);
   9242     // Check for uninitialized bindings.
   9243     switch (binding_flags) {
   9244       case MUTABLE_CHECK_INITIALIZED:
   9245       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
   9246         if (value->IsTheHole()) {
   9247           Handle<Object> reference_error =
   9248               isolate->factory()->NewReferenceError("not_defined",
   9249                                                     HandleVector(&name, 1));
   9250           return MakePair(isolate->Throw(*reference_error), NULL);
   9251         }
   9252         // FALLTHROUGH
   9253       case MUTABLE_IS_INITIALIZED:
   9254       case IMMUTABLE_IS_INITIALIZED:
   9255       case IMMUTABLE_IS_INITIALIZED_HARMONY:
   9256         ASSERT(!value->IsTheHole());
   9257         return MakePair(value, *receiver);
   9258       case IMMUTABLE_CHECK_INITIALIZED:
   9259         return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
   9260       case MISSING_BINDING:
   9261         UNREACHABLE();
   9262         return MakePair(NULL, NULL);
   9263     }
   9264   }
   9265 
   9266   // Otherwise, if the slot was found the holder is a context extension
   9267   // object, subject of a with, or a global object.  We read the named
   9268   // property from it.
   9269   if (!holder.is_null()) {
   9270     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
   9271     ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
   9272     // GetProperty below can cause GC.
   9273     Handle<Object> receiver_handle(
   9274         object->IsGlobalObject()
   9275             ? GlobalObject::cast(*object)->global_receiver()
   9276             : object->IsJSProxy() ? static_cast<Object*>(*object)
   9277                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
   9278         isolate);
   9279 
   9280     // No need to unhole the value here.  This is taken care of by the
   9281     // GetProperty function.
   9282     MaybeObject* value = object->GetProperty(*name);
   9283     return MakePair(value, *receiver_handle);
   9284   }
   9285 
   9286   if (throw_error) {
   9287     // The property doesn't exist - throw exception.
   9288     Handle<Object> reference_error =
   9289         isolate->factory()->NewReferenceError("not_defined",
   9290                                               HandleVector(&name, 1));
   9291     return MakePair(isolate->Throw(*reference_error), NULL);
   9292   } else {
   9293     // The property doesn't exist - return undefined.
   9294     return MakePair(isolate->heap()->undefined_value(),
   9295                     isolate->heap()->undefined_value());
   9296   }
   9297 }
   9298 
   9299 
   9300 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) {
   9301   return LoadContextSlotHelper(args, isolate, true);
   9302 }
   9303 
   9304 
   9305 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlotNoReferenceError) {
   9306   return LoadContextSlotHelper(args, isolate, false);
   9307 }
   9308 
   9309 
   9310 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
   9311   HandleScope scope(isolate);
   9312   ASSERT(args.length() == 4);
   9313 
   9314   Handle<Object> value(args[0], isolate);
   9315   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   9316   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   9317   CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
   9318   StrictModeFlag strict_mode = (language_mode == CLASSIC_MODE)
   9319       ? kNonStrictMode : kStrictMode;
   9320 
   9321   int index;
   9322   PropertyAttributes attributes;
   9323   ContextLookupFlags flags = FOLLOW_CHAINS;
   9324   BindingFlags binding_flags;
   9325   Handle<Object> holder = context->Lookup(name,
   9326                                           flags,
   9327                                           &index,
   9328                                           &attributes,
   9329                                           &binding_flags);
   9330   if (isolate->has_pending_exception()) return Failure::Exception();
   9331 
   9332   if (index >= 0) {
   9333     // The property was found in a context slot.
   9334     Handle<Context> context = Handle<Context>::cast(holder);
   9335     if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
   9336         context->get(index)->IsTheHole()) {
   9337       Handle<Object> error =
   9338           isolate->factory()->NewReferenceError("not_defined",
   9339                                                 HandleVector(&name, 1));
   9340       return isolate->Throw(*error);
   9341     }
   9342     // Ignore if read_only variable.
   9343     if ((attributes & READ_ONLY) == 0) {
   9344       // Context is a fixed array and set cannot fail.
   9345       context->set(index, *value);
   9346     } else if (strict_mode == kStrictMode) {
   9347       // Setting read only property in strict mode.
   9348       Handle<Object> error =
   9349           isolate->factory()->NewTypeError("strict_cannot_assign",
   9350                                            HandleVector(&name, 1));
   9351       return isolate->Throw(*error);
   9352     }
   9353     return *value;
   9354   }
   9355 
   9356   // Slow case: The property is not in a context slot.  It is either in a
   9357   // context extension object, a property of the subject of a with, or a
   9358   // property of the global object.
   9359   Handle<JSReceiver> object;
   9360 
   9361   if (!holder.is_null()) {
   9362     // The property exists on the holder.
   9363     object = Handle<JSReceiver>::cast(holder);
   9364   } else {
   9365     // The property was not found.
   9366     ASSERT(attributes == ABSENT);
   9367 
   9368     if (strict_mode == kStrictMode) {
   9369       // Throw in strict mode (assignment to undefined variable).
   9370       Handle<Object> error =
   9371           isolate->factory()->NewReferenceError(
   9372               "not_defined", HandleVector(&name, 1));
   9373       return isolate->Throw(*error);
   9374     }
   9375     // In non-strict mode, the property is added to the global object.
   9376     attributes = NONE;
   9377     object = Handle<JSReceiver>(isolate->context()->global_object());
   9378   }
   9379 
   9380   // Set the property if it's not read only or doesn't yet exist.
   9381   if ((attributes & READ_ONLY) == 0 ||
   9382       (object->GetLocalPropertyAttribute(*name) == ABSENT)) {
   9383     RETURN_IF_EMPTY_HANDLE(
   9384         isolate,
   9385         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
   9386   } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
   9387     // Setting read only property in strict mode.
   9388     Handle<Object> error =
   9389       isolate->factory()->NewTypeError(
   9390           "strict_cannot_assign", HandleVector(&name, 1));
   9391     return isolate->Throw(*error);
   9392   }
   9393   return *value;
   9394 }
   9395 
   9396 
   9397 RUNTIME_FUNCTION(MaybeObject*, Runtime_Throw) {
   9398   HandleScope scope(isolate);
   9399   ASSERT(args.length() == 1);
   9400 
   9401   return isolate->Throw(args[0]);
   9402 }
   9403 
   9404 
   9405 RUNTIME_FUNCTION(MaybeObject*, Runtime_ReThrow) {
   9406   HandleScope scope(isolate);
   9407   ASSERT(args.length() == 1);
   9408 
   9409   return isolate->ReThrow(args[0]);
   9410 }
   9411 
   9412 
   9413 RUNTIME_FUNCTION(MaybeObject*, Runtime_PromoteScheduledException) {
   9414   SealHandleScope shs(isolate);
   9415   ASSERT_EQ(0, args.length());
   9416   return isolate->PromoteScheduledException();
   9417 }
   9418 
   9419 
   9420 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowReferenceError) {
   9421   HandleScope scope(isolate);
   9422   ASSERT(args.length() == 1);
   9423 
   9424   Handle<Object> name(args[0], isolate);
   9425   Handle<Object> reference_error =
   9426     isolate->factory()->NewReferenceError("not_defined",
   9427                                           HandleVector(&name, 1));
   9428   return isolate->Throw(*reference_error);
   9429 }
   9430 
   9431 
   9432 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowNotDateError) {
   9433   HandleScope scope(isolate);
   9434   ASSERT(args.length() == 0);
   9435   return isolate->Throw(*isolate->factory()->NewTypeError(
   9436       "not_date_object", HandleVector<Object>(NULL, 0)));
   9437 }
   9438 
   9439 
   9440 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowMessage) {
   9441   HandleScope scope(isolate);
   9442   ASSERT(args.length() == 1);
   9443   CONVERT_SMI_ARG_CHECKED(message_id, 0);
   9444   const char* message = GetBailoutReason(
   9445       static_cast<BailoutReason>(message_id));
   9446   Handle<Name> message_handle =
   9447       isolate->factory()->NewStringFromAscii(CStrVector(message));
   9448   return isolate->Throw(*message_handle);
   9449 }
   9450 
   9451 
   9452 RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
   9453   SealHandleScope shs(isolate);
   9454   ASSERT(args.length() == 0);
   9455 
   9456   // First check if this is a real stack overflow.
   9457   if (isolate->stack_guard()->IsStackOverflow()) {
   9458     return isolate->StackOverflow();
   9459   }
   9460 
   9461   return Execution::HandleStackGuardInterrupt(isolate);
   9462 }
   9463 
   9464 
   9465 RUNTIME_FUNCTION(MaybeObject*, Runtime_TryInstallRecompiledCode) {
   9466   HandleScope scope(isolate);
   9467   ASSERT(args.length() == 1);
   9468   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   9469 
   9470   // First check if this is a real stack overflow.
   9471   if (isolate->stack_guard()->IsStackOverflow()) {
   9472     SealHandleScope shs(isolate);
   9473     return isolate->StackOverflow();
   9474   }
   9475 
   9476   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   9477   return (function->IsOptimized()) ? function->code()
   9478                                    : function->shared()->code();
   9479 }
   9480 
   9481 
   9482 RUNTIME_FUNCTION(MaybeObject*, Runtime_Interrupt) {
   9483   SealHandleScope shs(isolate);
   9484   ASSERT(args.length() == 0);
   9485   return Execution::HandleStackGuardInterrupt(isolate);
   9486 }
   9487 
   9488 
   9489 static int StackSize(Isolate* isolate) {
   9490   int n = 0;
   9491   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
   9492   return n;
   9493 }
   9494 
   9495 
   9496 static void PrintTransition(Isolate* isolate, Object* result) {
   9497   // indentation
   9498   { const int nmax = 80;
   9499     int n = StackSize(isolate);
   9500     if (n <= nmax)
   9501       PrintF("%4d:%*s", n, n, "");
   9502     else
   9503       PrintF("%4d:%*s", n, nmax, "...");
   9504   }
   9505 
   9506   if (result == NULL) {
   9507     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
   9508     PrintF(" {\n");
   9509   } else {
   9510     // function result
   9511     PrintF("} -> ");
   9512     result->ShortPrint();
   9513     PrintF("\n");
   9514   }
   9515 }
   9516 
   9517 
   9518 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
   9519   SealHandleScope shs(isolate);
   9520   ASSERT(args.length() == 0);
   9521   PrintTransition(isolate, NULL);
   9522   return isolate->heap()->undefined_value();
   9523 }
   9524 
   9525 
   9526 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) {
   9527   SealHandleScope shs(isolate);
   9528   PrintTransition(isolate, args[0]);
   9529   return args[0];  // return TOS
   9530 }
   9531 
   9532 
   9533 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrint) {
   9534   SealHandleScope shs(isolate);
   9535   ASSERT(args.length() == 1);
   9536 
   9537 #ifdef DEBUG
   9538   if (args[0]->IsString()) {
   9539     // If we have a string, assume it's a code "marker"
   9540     // and print some interesting cpu debugging info.
   9541     JavaScriptFrameIterator it(isolate);
   9542     JavaScriptFrame* frame = it.frame();
   9543     PrintF("fp = %p, sp = %p, caller_sp = %p: ",
   9544            frame->fp(), frame->sp(), frame->caller_sp());
   9545   } else {
   9546     PrintF("DebugPrint: ");
   9547   }
   9548   args[0]->Print();
   9549   if (args[0]->IsHeapObject()) {
   9550     PrintF("\n");
   9551     HeapObject::cast(args[0])->map()->Print();
   9552   }
   9553 #else
   9554   // ShortPrint is available in release mode. Print is not.
   9555   args[0]->ShortPrint();
   9556 #endif
   9557   PrintF("\n");
   9558   Flush();
   9559 
   9560   return args[0];  // return TOS
   9561 }
   9562 
   9563 
   9564 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugTrace) {
   9565   SealHandleScope shs(isolate);
   9566   ASSERT(args.length() == 0);
   9567   isolate->PrintStack(stdout);
   9568   return isolate->heap()->undefined_value();
   9569 }
   9570 
   9571 
   9572 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
   9573   SealHandleScope shs(isolate);
   9574   ASSERT(args.length() == 0);
   9575 
   9576   // According to ECMA-262, section 15.9.1, page 117, the precision of
   9577   // the number in a Date object representing a particular instant in
   9578   // time is milliseconds. Therefore, we floor the result of getting
   9579   // the OS time.
   9580   double millis = floor(OS::TimeCurrentMillis());
   9581   return isolate->heap()->NumberFromDouble(millis);
   9582 }
   9583 
   9584 
   9585 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
   9586   HandleScope scope(isolate);
   9587   ASSERT(args.length() == 2);
   9588 
   9589   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   9590   FlattenString(str);
   9591 
   9592   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
   9593 
   9594   JSObject::EnsureCanContainHeapObjectElements(output);
   9595   RUNTIME_ASSERT(output->HasFastObjectElements());
   9596 
   9597   DisallowHeapAllocation no_gc;
   9598 
   9599   FixedArray* output_array = FixedArray::cast(output->elements());
   9600   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
   9601   bool result;
   9602   String::FlatContent str_content = str->GetFlatContent();
   9603   if (str_content.IsAscii()) {
   9604     result = DateParser::Parse(str_content.ToOneByteVector(),
   9605                                output_array,
   9606                                isolate->unicode_cache());
   9607   } else {
   9608     ASSERT(str_content.IsTwoByte());
   9609     result = DateParser::Parse(str_content.ToUC16Vector(),
   9610                                output_array,
   9611                                isolate->unicode_cache());
   9612   }
   9613 
   9614   if (result) {
   9615     return *output;
   9616   } else {
   9617     return isolate->heap()->null_value();
   9618   }
   9619 }
   9620 
   9621 
   9622 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
   9623   SealHandleScope shs(isolate);
   9624   ASSERT(args.length() == 1);
   9625 
   9626   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9627   int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x));
   9628   const char* zone = OS::LocalTimezone(static_cast<double>(time));
   9629   return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
   9630 }
   9631 
   9632 
   9633 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateToUTC) {
   9634   SealHandleScope shs(isolate);
   9635   ASSERT(args.length() == 1);
   9636 
   9637   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9638   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
   9639 
   9640   return isolate->heap()->NumberFromDouble(static_cast<double>(time));
   9641 }
   9642 
   9643 
   9644 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
   9645   SealHandleScope shs(isolate);
   9646   ASSERT(args.length() == 1);
   9647   Object* global = args[0];
   9648   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
   9649   return JSGlobalObject::cast(global)->global_receiver();
   9650 }
   9651 
   9652 
   9653 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAttachedGlobal) {
   9654   SealHandleScope shs(isolate);
   9655   ASSERT(args.length() == 1);
   9656   Object* global = args[0];
   9657   if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
   9658   return isolate->heap()->ToBoolean(
   9659       !JSGlobalObject::cast(global)->IsDetached());
   9660 }
   9661 
   9662 
   9663 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
   9664   HandleScope scope(isolate);
   9665   ASSERT_EQ(1, args.length());
   9666   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9667 
   9668   source = Handle<String>(FlattenGetString(source));
   9669   // Optimized fast case where we only have ASCII characters.
   9670   Handle<Object> result;
   9671   if (source->IsSeqOneByteString()) {
   9672     result = JsonParser<true>::Parse(source);
   9673   } else {
   9674     result = JsonParser<false>::Parse(source);
   9675   }
   9676   if (result.is_null()) {
   9677     // Syntax error or stack overflow in scanner.
   9678     ASSERT(isolate->has_pending_exception());
   9679     return Failure::Exception();
   9680   }
   9681   return *result;
   9682 }
   9683 
   9684 
   9685 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   9686                                       Handle<Context> context) {
   9687   ASSERT(context->allow_code_gen_from_strings()->IsFalse());
   9688   // Check with callback if set.
   9689   AllowCodeGenerationFromStringsCallback callback =
   9690       isolate->allow_code_gen_callback();
   9691   if (callback == NULL) {
   9692     // No callback set and code generation disallowed.
   9693     return false;
   9694   } else {
   9695     // Callback set. Let it decide if code generation is allowed.
   9696     VMState<EXTERNAL> state(isolate);
   9697     return callback(v8::Utils::ToLocal(context));
   9698   }
   9699 }
   9700 
   9701 
   9702 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
   9703   HandleScope scope(isolate);
   9704   ASSERT_EQ(2, args.length());
   9705   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9706   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
   9707 
   9708   // Extract native context.
   9709   Handle<Context> context(isolate->context()->native_context());
   9710 
   9711   // Check if native context allows code generation from
   9712   // strings. Throw an exception if it doesn't.
   9713   if (context->allow_code_gen_from_strings()->IsFalse() &&
   9714       !CodeGenerationFromStringsAllowed(isolate, context)) {
   9715     Handle<Object> error_message =
   9716         context->ErrorMessageForCodeGenerationFromStrings();
   9717     return isolate->Throw(*isolate->factory()->NewEvalError(
   9718         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
   9719   }
   9720 
   9721   // Compile source string in the native context.
   9722   ParseRestriction restriction = function_literal_only
   9723       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
   9724   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   9725       source, context, true, CLASSIC_MODE, restriction, RelocInfo::kNoPosition);
   9726   RETURN_IF_EMPTY_HANDLE(isolate, shared);
   9727   Handle<JSFunction> fun =
   9728       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   9729                                                             context,
   9730                                                             NOT_TENURED);
   9731   return *fun;
   9732 }
   9733 
   9734 
   9735 static ObjectPair CompileGlobalEval(Isolate* isolate,
   9736                                     Handle<String> source,
   9737                                     Handle<Object> receiver,
   9738                                     LanguageMode language_mode,
   9739                                     int scope_position) {
   9740   Handle<Context> context = Handle<Context>(isolate->context());
   9741   Handle<Context> native_context = Handle<Context>(context->native_context());
   9742 
   9743   // Check if native context allows code generation from
   9744   // strings. Throw an exception if it doesn't.
   9745   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
   9746       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
   9747     Handle<Object> error_message =
   9748         native_context->ErrorMessageForCodeGenerationFromStrings();
   9749     isolate->Throw(*isolate->factory()->NewEvalError(
   9750         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
   9751     return MakePair(Failure::Exception(), NULL);
   9752   }
   9753 
   9754   // Deal with a normal eval call with a string argument. Compile it
   9755   // and return the compiled function bound in the local context.
   9756   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   9757       source,
   9758       context,
   9759       context->IsNativeContext(),
   9760       language_mode,
   9761       NO_PARSE_RESTRICTION,
   9762       scope_position);
   9763   RETURN_IF_EMPTY_HANDLE_VALUE(isolate, shared,
   9764                                MakePair(Failure::Exception(), NULL));
   9765   Handle<JSFunction> compiled =
   9766       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   9767           shared, context, NOT_TENURED);
   9768   return MakePair(*compiled, *receiver);
   9769 }
   9770 
   9771 
   9772 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
   9773   HandleScope scope(isolate);
   9774   ASSERT(args.length() == 5);
   9775 
   9776   Handle<Object> callee = args.at<Object>(0);
   9777 
   9778   // If "eval" didn't refer to the original GlobalEval, it's not a
   9779   // direct call to eval.
   9780   // (And even if it is, but the first argument isn't a string, just let
   9781   // execution default to an indirect call to eval, which will also return
   9782   // the first argument without doing anything).
   9783   if (*callee != isolate->native_context()->global_eval_fun() ||
   9784       !args[1]->IsString()) {
   9785     return MakePair(*callee, isolate->heap()->the_hole_value());
   9786   }
   9787 
   9788   CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
   9789   ASSERT(args[4]->IsSmi());
   9790   return CompileGlobalEval(isolate,
   9791                            args.at<String>(1),
   9792                            args.at<Object>(2),
   9793                            language_mode,
   9794                            args.smi_at(4));
   9795 }
   9796 
   9797 
   9798 // Allocate a block of memory in the given space (filled with a filler).
   9799 // Used as a fall-back for generated code when the space is full.
   9800 static MaybeObject* Allocate(Isolate* isolate,
   9801                              int size,
   9802                              bool double_align,
   9803                              AllocationSpace space) {
   9804   Heap* heap = isolate->heap();
   9805   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9806   RUNTIME_ASSERT(size > 0);
   9807   RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize());
   9808   HeapObject* allocation;
   9809   { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space);
   9810     if (!maybe_allocation->To(&allocation)) return maybe_allocation;
   9811   }
   9812 #ifdef DEBUG
   9813   MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address());
   9814   ASSERT(chunk->owner()->identity() == space);
   9815 #endif
   9816   heap->CreateFillerObjectAt(allocation->address(), size);
   9817   return allocation;
   9818 }
   9819 
   9820 
   9821 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) {
   9822   SealHandleScope shs(isolate);
   9823   ASSERT(args.length() == 1);
   9824   CONVERT_SMI_ARG_CHECKED(size, 0);
   9825   return Allocate(isolate, size, false, NEW_SPACE);
   9826 }
   9827 
   9828 
   9829 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInTargetSpace) {
   9830   SealHandleScope shs(isolate);
   9831   ASSERT(args.length() == 2);
   9832   CONVERT_SMI_ARG_CHECKED(size, 0);
   9833   CONVERT_SMI_ARG_CHECKED(flags, 1);
   9834   bool double_align = AllocateDoubleAlignFlag::decode(flags);
   9835   AllocationSpace space = AllocateTargetSpace::decode(flags);
   9836   return Allocate(isolate, size, double_align, space);
   9837 }
   9838 
   9839 
   9840 // Push an object unto an array of objects if it is not already in the
   9841 // array.  Returns true if the element was pushed on the stack and
   9842 // false otherwise.
   9843 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
   9844   HandleScope scope(isolate);
   9845   ASSERT(args.length() == 2);
   9846   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   9847   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
   9848   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
   9849   int length = Smi::cast(array->length())->value();
   9850   FixedArray* elements = FixedArray::cast(array->elements());
   9851   for (int i = 0; i < length; i++) {
   9852     if (elements->get(i) == *element) return isolate->heap()->false_value();
   9853   }
   9854 
   9855   // Strict not needed. Used for cycle detection in Array join implementation.
   9856   RETURN_IF_EMPTY_HANDLE(isolate, JSObject::SetFastElement(array, length,
   9857                                                            element,
   9858                                                            kNonStrictMode,
   9859                                                            true));
   9860   return isolate->heap()->true_value();
   9861 }
   9862 
   9863 
   9864 /**
   9865  * A simple visitor visits every element of Array's.
   9866  * The backend storage can be a fixed array for fast elements case,
   9867  * or a dictionary for sparse array. Since Dictionary is a subtype
   9868  * of FixedArray, the class can be used by both fast and slow cases.
   9869  * The second parameter of the constructor, fast_elements, specifies
   9870  * whether the storage is a FixedArray or Dictionary.
   9871  *
   9872  * An index limit is used to deal with the situation that a result array
   9873  * length overflows 32-bit non-negative integer.
   9874  */
   9875 class ArrayConcatVisitor {
   9876  public:
   9877   ArrayConcatVisitor(Isolate* isolate,
   9878                      Handle<FixedArray> storage,
   9879                      bool fast_elements) :
   9880       isolate_(isolate),
   9881       storage_(Handle<FixedArray>::cast(
   9882           isolate->global_handles()->Create(*storage))),
   9883       index_offset_(0u),
   9884       fast_elements_(fast_elements),
   9885       exceeds_array_limit_(false) { }
   9886 
   9887   ~ArrayConcatVisitor() {
   9888     clear_storage();
   9889   }
   9890 
   9891   void visit(uint32_t i, Handle<Object> elm) {
   9892     if (i > JSObject::kMaxElementCount - index_offset_) {
   9893       exceeds_array_limit_ = true;
   9894       return;
   9895     }
   9896     uint32_t index = index_offset_ + i;
   9897 
   9898     if (fast_elements_) {
   9899       if (index < static_cast<uint32_t>(storage_->length())) {
   9900         storage_->set(index, *elm);
   9901         return;
   9902       }
   9903       // Our initial estimate of length was foiled, possibly by
   9904       // getters on the arrays increasing the length of later arrays
   9905       // during iteration.
   9906       // This shouldn't happen in anything but pathological cases.
   9907       SetDictionaryMode(index);
   9908       // Fall-through to dictionary mode.
   9909     }
   9910     ASSERT(!fast_elements_);
   9911     Handle<SeededNumberDictionary> dict(
   9912         SeededNumberDictionary::cast(*storage_));
   9913     Handle<SeededNumberDictionary> result =
   9914         isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
   9915     if (!result.is_identical_to(dict)) {
   9916       // Dictionary needed to grow.
   9917       clear_storage();
   9918       set_storage(*result);
   9919     }
   9920   }
   9921 
   9922   void increase_index_offset(uint32_t delta) {
   9923     if (JSObject::kMaxElementCount - index_offset_ < delta) {
   9924       index_offset_ = JSObject::kMaxElementCount;
   9925     } else {
   9926       index_offset_ += delta;
   9927     }
   9928   }
   9929 
   9930   bool exceeds_array_limit() {
   9931     return exceeds_array_limit_;
   9932   }
   9933 
   9934   Handle<JSArray> ToArray() {
   9935     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
   9936     Handle<Object> length =
   9937         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
   9938     Handle<Map> map;
   9939     if (fast_elements_) {
   9940       map = isolate_->factory()->GetElementsTransitionMap(array,
   9941                                                           FAST_HOLEY_ELEMENTS);
   9942     } else {
   9943       map = isolate_->factory()->GetElementsTransitionMap(array,
   9944                                                           DICTIONARY_ELEMENTS);
   9945     }
   9946     array->set_map(*map);
   9947     array->set_length(*length);
   9948     array->set_elements(*storage_);
   9949     return array;
   9950   }
   9951 
   9952  private:
   9953   // Convert storage to dictionary mode.
   9954   void SetDictionaryMode(uint32_t index) {
   9955     ASSERT(fast_elements_);
   9956     Handle<FixedArray> current_storage(*storage_);
   9957     Handle<SeededNumberDictionary> slow_storage(
   9958         isolate_->factory()->NewSeededNumberDictionary(
   9959             current_storage->length()));
   9960     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
   9961     for (uint32_t i = 0; i < current_length; i++) {
   9962       HandleScope loop_scope(isolate_);
   9963       Handle<Object> element(current_storage->get(i), isolate_);
   9964       if (!element->IsTheHole()) {
   9965         Handle<SeededNumberDictionary> new_storage =
   9966           isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
   9967         if (!new_storage.is_identical_to(slow_storage)) {
   9968           slow_storage = loop_scope.CloseAndEscape(new_storage);
   9969         }
   9970       }
   9971     }
   9972     clear_storage();
   9973     set_storage(*slow_storage);
   9974     fast_elements_ = false;
   9975   }
   9976 
   9977   inline void clear_storage() {
   9978     isolate_->global_handles()->Destroy(
   9979         Handle<Object>::cast(storage_).location());
   9980   }
   9981 
   9982   inline void set_storage(FixedArray* storage) {
   9983     storage_ = Handle<FixedArray>::cast(
   9984         isolate_->global_handles()->Create(storage));
   9985   }
   9986 
   9987   Isolate* isolate_;
   9988   Handle<FixedArray> storage_;  // Always a global handle.
   9989   // Index after last seen index. Always less than or equal to
   9990   // JSObject::kMaxElementCount.
   9991   uint32_t index_offset_;
   9992   bool fast_elements_ : 1;
   9993   bool exceeds_array_limit_ : 1;
   9994 };
   9995 
   9996 
   9997 static uint32_t EstimateElementCount(Handle<JSArray> array) {
   9998   uint32_t length = static_cast<uint32_t>(array->length()->Number());
   9999   int element_count = 0;
   10000   switch (array->GetElementsKind()) {
   10001     case FAST_SMI_ELEMENTS:
   10002     case FAST_HOLEY_SMI_ELEMENTS:
   10003     case FAST_ELEMENTS:
   10004     case FAST_HOLEY_ELEMENTS: {
   10005       // Fast elements can't have lengths that are not representable by
   10006       // a 32-bit signed integer.
   10007       ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
   10008       int fast_length = static_cast<int>(length);
   10009       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
   10010       for (int i = 0; i < fast_length; i++) {
   10011         if (!elements->get(i)->IsTheHole()) element_count++;
   10012       }
   10013       break;
   10014     }
   10015     case FAST_DOUBLE_ELEMENTS:
   10016     case FAST_HOLEY_DOUBLE_ELEMENTS: {
   10017       // Fast elements can't have lengths that are not representable by
   10018       // a 32-bit signed integer.
   10019       ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
   10020       int fast_length = static_cast<int>(length);
   10021       if (array->elements()->IsFixedArray()) {
   10022         ASSERT(FixedArray::cast(array->elements())->length() == 0);
   10023         break;
   10024       }
   10025       Handle<FixedDoubleArray> elements(
   10026           FixedDoubleArray::cast(array->elements()));
   10027       for (int i = 0; i < fast_length; i++) {
   10028         if (!elements->is_the_hole(i)) element_count++;
   10029       }
   10030       break;
   10031     }
   10032     case DICTIONARY_ELEMENTS: {
   10033       Handle<SeededNumberDictionary> dictionary(
   10034           SeededNumberDictionary::cast(array->elements()));
   10035       int capacity = dictionary->Capacity();
   10036       for (int i = 0; i < capacity; i++) {
   10037         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
   10038         if (dictionary->IsKey(*key)) {
   10039           element_count++;
   10040         }
   10041       }
   10042       break;
   10043     }
   10044     case NON_STRICT_ARGUMENTS_ELEMENTS:
   10045     case EXTERNAL_BYTE_ELEMENTS:
   10046     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
   10047     case EXTERNAL_SHORT_ELEMENTS:
   10048     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
   10049     case EXTERNAL_INT_ELEMENTS:
   10050     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
   10051     case EXTERNAL_FLOAT_ELEMENTS:
   10052     case EXTERNAL_DOUBLE_ELEMENTS:
   10053     case EXTERNAL_PIXEL_ELEMENTS:
   10054       // External arrays are always dense.
   10055       return length;
   10056   }
   10057   // As an estimate, we assume that the prototype doesn't contain any
   10058   // inherited elements.
   10059   return element_count;
   10060 }
   10061 
   10062 
   10063 
   10064 template<class ExternalArrayClass, class ElementType>
   10065 static void IterateExternalArrayElements(Isolate* isolate,
   10066                                          Handle<JSObject> receiver,
   10067                                          bool elements_are_ints,
   10068                                          bool elements_are_guaranteed_smis,
   10069                                          ArrayConcatVisitor* visitor) {
   10070   Handle<ExternalArrayClass> array(
   10071       ExternalArrayClass::cast(receiver->elements()));
   10072   uint32_t len = static_cast<uint32_t>(array->length());
   10073 
   10074   ASSERT(visitor != NULL);
   10075   if (elements_are_ints) {
   10076     if (elements_are_guaranteed_smis) {
   10077       for (uint32_t j = 0; j < len; j++) {
   10078         HandleScope loop_scope(isolate);
   10079         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
   10080                       isolate);
   10081         visitor->visit(j, e);
   10082       }
   10083     } else {
   10084       for (uint32_t j = 0; j < len; j++) {
   10085         HandleScope loop_scope(isolate);
   10086         int64_t val = static_cast<int64_t>(array->get_scalar(j));
   10087         if (Smi::IsValid(static_cast<intptr_t>(val))) {
   10088           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
   10089           visitor->visit(j, e);
   10090         } else {
   10091           Handle<Object> e =
   10092               isolate->factory()->NewNumber(static_cast<ElementType>(val));
   10093           visitor->visit(j, e);
   10094         }
   10095       }
   10096     }
   10097   } else {
   10098     for (uint32_t j = 0; j < len; j++) {
   10099       HandleScope loop_scope(isolate);
   10100       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
   10101       visitor->visit(j, e);
   10102     }
   10103   }
   10104 }
   10105 
   10106 
   10107 // Used for sorting indices in a List<uint32_t>.
   10108 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
   10109   uint32_t a = *ap;
   10110   uint32_t b = *bp;
   10111   return (a == b) ? 0 : (a < b) ? -1 : 1;
   10112 }
   10113 
   10114 
   10115 static void CollectElementIndices(Handle<JSObject> object,
   10116                                   uint32_t range,
   10117                                   List<uint32_t>* indices) {
   10118   Isolate* isolate = object->GetIsolate();
   10119   ElementsKind kind = object->GetElementsKind();
   10120   switch (kind) {
   10121     case FAST_SMI_ELEMENTS:
   10122     case FAST_ELEMENTS:
   10123     case FAST_HOLEY_SMI_ELEMENTS:
   10124     case FAST_HOLEY_ELEMENTS: {
   10125       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
   10126       uint32_t length = static_cast<uint32_t>(elements->length());
   10127       if (range < length) length = range;
   10128       for (uint32_t i = 0; i < length; i++) {
   10129         if (!elements->get(i)->IsTheHole()) {
   10130           indices->Add(i);
   10131         }
   10132       }
   10133       break;
   10134     }
   10135     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10136     case FAST_DOUBLE_ELEMENTS: {
   10137       // TODO(1810): Decide if it's worthwhile to implement this.
   10138       UNREACHABLE();
   10139       break;
   10140     }
   10141     case DICTIONARY_ELEMENTS: {
   10142       Handle<SeededNumberDictionary> dict(
   10143           SeededNumberDictionary::cast(object->elements()));
   10144       uint32_t capacity = dict->Capacity();
   10145       for (uint32_t j = 0; j < capacity; j++) {
   10146         HandleScope loop_scope(isolate);
   10147         Handle<Object> k(dict->KeyAt(j), isolate);
   10148         if (dict->IsKey(*k)) {
   10149           ASSERT(k->IsNumber());
   10150           uint32_t index = static_cast<uint32_t>(k->Number());
   10151           if (index < range) {
   10152             indices->Add(index);
   10153           }
   10154         }
   10155       }
   10156       break;
   10157     }
   10158     default: {
   10159       int dense_elements_length;
   10160       switch (kind) {
   10161         case EXTERNAL_PIXEL_ELEMENTS: {
   10162           dense_elements_length =
   10163               ExternalPixelArray::cast(object->elements())->length();
   10164           break;
   10165         }
   10166         case EXTERNAL_BYTE_ELEMENTS: {
   10167           dense_elements_length =
   10168               ExternalByteArray::cast(object->elements())->length();
   10169           break;
   10170         }
   10171         case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
   10172           dense_elements_length =
   10173               ExternalUnsignedByteArray::cast(object->elements())->length();
   10174           break;
   10175         }
   10176         case EXTERNAL_SHORT_ELEMENTS: {
   10177           dense_elements_length =
   10178               ExternalShortArray::cast(object->elements())->length();
   10179           break;
   10180         }
   10181         case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
   10182           dense_elements_length =
   10183               ExternalUnsignedShortArray::cast(object->elements())->length();
   10184           break;
   10185         }
   10186         case EXTERNAL_INT_ELEMENTS: {
   10187           dense_elements_length =
   10188               ExternalIntArray::cast(object->elements())->length();
   10189           break;
   10190         }
   10191         case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
   10192           dense_elements_length =
   10193               ExternalUnsignedIntArray::cast(object->elements())->length();
   10194           break;
   10195         }
   10196         case EXTERNAL_FLOAT_ELEMENTS: {
   10197           dense_elements_length =
   10198               ExternalFloatArray::cast(object->elements())->length();
   10199           break;
   10200         }
   10201         case EXTERNAL_DOUBLE_ELEMENTS: {
   10202           dense_elements_length =
   10203               ExternalDoubleArray::cast(object->elements())->length();
   10204           break;
   10205         }
   10206         default:
   10207           UNREACHABLE();
   10208           dense_elements_length = 0;
   10209           break;
   10210       }
   10211       uint32_t length = static_cast<uint32_t>(dense_elements_length);
   10212       if (range <= length) {
   10213         length = range;
   10214         // We will add all indices, so we might as well clear it first
   10215         // and avoid duplicates.
   10216         indices->Clear();
   10217       }
   10218       for (uint32_t i = 0; i < length; i++) {
   10219         indices->Add(i);
   10220       }
   10221       if (length == range) return;  // All indices accounted for already.
   10222       break;
   10223     }
   10224   }
   10225 
   10226   Handle<Object> prototype(object->GetPrototype(), isolate);
   10227   if (prototype->IsJSObject()) {
   10228     // The prototype will usually have no inherited element indices,
   10229     // but we have to check.
   10230     CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
   10231   }
   10232 }
   10233 
   10234 
   10235 /**
   10236  * A helper function that visits elements of a JSArray in numerical
   10237  * order.
   10238  *
   10239  * The visitor argument called for each existing element in the array
   10240  * with the element index and the element's value.
   10241  * Afterwards it increments the base-index of the visitor by the array
   10242  * length.
   10243  * Returns false if any access threw an exception, otherwise true.
   10244  */
   10245 static bool IterateElements(Isolate* isolate,
   10246                             Handle<JSArray> receiver,
   10247                             ArrayConcatVisitor* visitor) {
   10248   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
   10249   switch (receiver->GetElementsKind()) {
   10250     case FAST_SMI_ELEMENTS:
   10251     case FAST_ELEMENTS:
   10252     case FAST_HOLEY_SMI_ELEMENTS:
   10253     case FAST_HOLEY_ELEMENTS: {
   10254       // Run through the elements FixedArray and use HasElement and GetElement
   10255       // to check the prototype for missing elements.
   10256       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
   10257       int fast_length = static_cast<int>(length);
   10258       ASSERT(fast_length <= elements->length());
   10259       for (int j = 0; j < fast_length; j++) {
   10260         HandleScope loop_scope(isolate);
   10261         Handle<Object> element_value(elements->get(j), isolate);
   10262         if (!element_value->IsTheHole()) {
   10263           visitor->visit(j, element_value);
   10264         } else if (JSReceiver::HasElement(receiver, j)) {
   10265           // Call GetElement on receiver, not its prototype, or getters won't
   10266           // have the correct receiver.
   10267           element_value = Object::GetElement(isolate, receiver, j);
   10268           RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
   10269           visitor->visit(j, element_value);
   10270         }
   10271       }
   10272       break;
   10273     }
   10274     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10275     case FAST_DOUBLE_ELEMENTS: {
   10276       // Run through the elements FixedArray and use HasElement and GetElement
   10277       // to check the prototype for missing elements.
   10278       Handle<FixedDoubleArray> elements(
   10279           FixedDoubleArray::cast(receiver->elements()));
   10280       int fast_length = static_cast<int>(length);
   10281       ASSERT(fast_length <= elements->length());
   10282       for (int j = 0; j < fast_length; j++) {
   10283         HandleScope loop_scope(isolate);
   10284         if (!elements->is_the_hole(j)) {
   10285           double double_value = elements->get_scalar(j);
   10286           Handle<Object> element_value =
   10287               isolate->factory()->NewNumber(double_value);
   10288           visitor->visit(j, element_value);
   10289         } else if (JSReceiver::HasElement(receiver, j)) {
   10290           // Call GetElement on receiver, not its prototype, or getters won't
   10291           // have the correct receiver.
   10292           Handle<Object> element_value =
   10293               Object::GetElement(isolate, receiver, j);
   10294           RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
   10295           visitor->visit(j, element_value);
   10296         }
   10297       }
   10298       break;
   10299     }
   10300     case DICTIONARY_ELEMENTS: {
   10301       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
   10302       List<uint32_t> indices(dict->Capacity() / 2);
   10303       // Collect all indices in the object and the prototypes less
   10304       // than length. This might introduce duplicates in the indices list.
   10305       CollectElementIndices(receiver, length, &indices);
   10306       indices.Sort(&compareUInt32);
   10307       int j = 0;
   10308       int n = indices.length();
   10309       while (j < n) {
   10310         HandleScope loop_scope(isolate);
   10311         uint32_t index = indices[j];
   10312         Handle<Object> element = Object::GetElement(isolate, receiver, index);
   10313         RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
   10314         visitor->visit(index, element);
   10315         // Skip to next different index (i.e., omit duplicates).
   10316         do {
   10317           j++;
   10318         } while (j < n && indices[j] == index);
   10319       }
   10320       break;
   10321     }
   10322     case EXTERNAL_PIXEL_ELEMENTS: {
   10323       Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
   10324           receiver->elements()));
   10325       for (uint32_t j = 0; j < length; j++) {
   10326         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
   10327         visitor->visit(j, e);
   10328       }
   10329       break;
   10330     }
   10331     case EXTERNAL_BYTE_ELEMENTS: {
   10332       IterateExternalArrayElements<ExternalByteArray, int8_t>(
   10333           isolate, receiver, true, true, visitor);
   10334       break;
   10335     }
   10336     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
   10337       IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>(
   10338           isolate, receiver, true, true, visitor);
   10339       break;
   10340     }
   10341     case EXTERNAL_SHORT_ELEMENTS: {
   10342       IterateExternalArrayElements<ExternalShortArray, int16_t>(
   10343           isolate, receiver, true, true, visitor);
   10344       break;
   10345     }
   10346     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
   10347       IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>(
   10348           isolate, receiver, true, true, visitor);
   10349       break;
   10350     }
   10351     case EXTERNAL_INT_ELEMENTS: {
   10352       IterateExternalArrayElements<ExternalIntArray, int32_t>(
   10353           isolate, receiver, true, false, visitor);
   10354       break;
   10355     }
   10356     case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
   10357       IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>(
   10358           isolate, receiver, true, false, visitor);
   10359       break;
   10360     }
   10361     case EXTERNAL_FLOAT_ELEMENTS: {
   10362       IterateExternalArrayElements<ExternalFloatArray, float>(
   10363           isolate, receiver, false, false, visitor);
   10364       break;
   10365     }
   10366     case EXTERNAL_DOUBLE_ELEMENTS: {
   10367       IterateExternalArrayElements<ExternalDoubleArray, double>(
   10368           isolate, receiver, false, false, visitor);
   10369       break;
   10370     }
   10371     default:
   10372       UNREACHABLE();
   10373       break;
   10374   }
   10375   visitor->increase_index_offset(length);
   10376   return true;
   10377 }
   10378 
   10379 
   10380 /**
   10381  * Array::concat implementation.
   10382  * See ECMAScript 262, 15.4.4.4.
   10383  * TODO(581): Fix non-compliance for very large concatenations and update to
   10384  * following the ECMAScript 5 specification.
   10385  */
   10386 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
   10387   HandleScope handle_scope(isolate);
   10388   ASSERT(args.length() == 1);
   10389 
   10390   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
   10391   int argument_count = static_cast<int>(arguments->length()->Number());
   10392   RUNTIME_ASSERT(arguments->HasFastObjectElements());
   10393   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
   10394 
   10395   // Pass 1: estimate the length and number of elements of the result.
   10396   // The actual length can be larger if any of the arguments have getters
   10397   // that mutate other arguments (but will otherwise be precise).
   10398   // The number of elements is precise if there are no inherited elements.
   10399 
   10400   ElementsKind kind = FAST_SMI_ELEMENTS;
   10401 
   10402   uint32_t estimate_result_length = 0;
   10403   uint32_t estimate_nof_elements = 0;
   10404   for (int i = 0; i < argument_count; i++) {
   10405     HandleScope loop_scope(isolate);
   10406     Handle<Object> obj(elements->get(i), isolate);
   10407     uint32_t length_estimate;
   10408     uint32_t element_estimate;
   10409     if (obj->IsJSArray()) {
   10410       Handle<JSArray> array(Handle<JSArray>::cast(obj));
   10411       length_estimate = static_cast<uint32_t>(array->length()->Number());
   10412       if (length_estimate != 0) {
   10413         ElementsKind array_kind =
   10414             GetPackedElementsKind(array->map()->elements_kind());
   10415         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
   10416           kind = array_kind;
   10417         }
   10418       }
   10419       element_estimate = EstimateElementCount(array);
   10420     } else {
   10421       if (obj->IsHeapObject()) {
   10422         if (obj->IsNumber()) {
   10423           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
   10424             kind = FAST_DOUBLE_ELEMENTS;
   10425           }
   10426         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
   10427           kind = FAST_ELEMENTS;
   10428         }
   10429       }
   10430       length_estimate = 1;
   10431       element_estimate = 1;
   10432     }
   10433     // Avoid overflows by capping at kMaxElementCount.
   10434     if (JSObject::kMaxElementCount - estimate_result_length <
   10435         length_estimate) {
   10436       estimate_result_length = JSObject::kMaxElementCount;
   10437     } else {
   10438       estimate_result_length += length_estimate;
   10439     }
   10440     if (JSObject::kMaxElementCount - estimate_nof_elements <
   10441         element_estimate) {
   10442       estimate_nof_elements = JSObject::kMaxElementCount;
   10443     } else {
   10444       estimate_nof_elements += element_estimate;
   10445     }
   10446   }
   10447 
   10448   // If estimated number of elements is more than half of length, a
   10449   // fixed array (fast case) is more time and space-efficient than a
   10450   // dictionary.
   10451   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
   10452 
   10453   Handle<FixedArray> storage;
   10454   if (fast_case) {
   10455     if (kind == FAST_DOUBLE_ELEMENTS) {
   10456       Handle<FixedDoubleArray> double_storage =
   10457           isolate->factory()->NewFixedDoubleArray(estimate_result_length);
   10458       int j = 0;
   10459       bool failure = false;
   10460       for (int i = 0; i < argument_count; i++) {
   10461         Handle<Object> obj(elements->get(i), isolate);
   10462         if (obj->IsSmi()) {
   10463           double_storage->set(j, Smi::cast(*obj)->value());
   10464           j++;
   10465         } else if (obj->IsNumber()) {
   10466           double_storage->set(j, obj->Number());
   10467           j++;
   10468         } else {
   10469           JSArray* array = JSArray::cast(*obj);
   10470           uint32_t length = static_cast<uint32_t>(array->length()->Number());
   10471           switch (array->map()->elements_kind()) {
   10472             case FAST_HOLEY_DOUBLE_ELEMENTS:
   10473             case FAST_DOUBLE_ELEMENTS: {
   10474               // Empty fixed array indicates that there are no elements.
   10475               if (array->elements()->IsFixedArray()) break;
   10476               FixedDoubleArray* elements =
   10477                   FixedDoubleArray::cast(array->elements());
   10478               for (uint32_t i = 0; i < length; i++) {
   10479                 if (elements->is_the_hole(i)) {
   10480                   failure = true;
   10481                   break;
   10482                 }
   10483                 double double_value = elements->get_scalar(i);
   10484                 double_storage->set(j, double_value);
   10485                 j++;
   10486               }
   10487               break;
   10488             }
   10489             case FAST_HOLEY_SMI_ELEMENTS:
   10490             case FAST_SMI_ELEMENTS: {
   10491               FixedArray* elements(
   10492                   FixedArray::cast(array->elements()));
   10493               for (uint32_t i = 0; i < length; i++) {
   10494                 Object* element = elements->get(i);
   10495                 if (element->IsTheHole()) {
   10496                   failure = true;
   10497                   break;
   10498                 }
   10499                 int32_t int_value = Smi::cast(element)->value();
   10500                 double_storage->set(j, int_value);
   10501                 j++;
   10502               }
   10503               break;
   10504             }
   10505             case FAST_HOLEY_ELEMENTS:
   10506               ASSERT_EQ(0, length);
   10507               break;
   10508             default:
   10509               UNREACHABLE();
   10510           }
   10511         }
   10512         if (failure) break;
   10513       }
   10514       Handle<JSArray> array = isolate->factory()->NewJSArray(0);
   10515       Smi* length = Smi::FromInt(j);
   10516       Handle<Map> map;
   10517       map = isolate->factory()->GetElementsTransitionMap(array, kind);
   10518       array->set_map(*map);
   10519       array->set_length(length);
   10520       array->set_elements(*double_storage);
   10521       return *array;
   10522     }
   10523     // The backing storage array must have non-existing elements to preserve
   10524     // holes across concat operations.
   10525     storage = isolate->factory()->NewFixedArrayWithHoles(
   10526         estimate_result_length);
   10527   } else {
   10528     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
   10529     uint32_t at_least_space_for = estimate_nof_elements +
   10530                                   (estimate_nof_elements >> 2);
   10531     storage = Handle<FixedArray>::cast(
   10532         isolate->factory()->NewSeededNumberDictionary(at_least_space_for));
   10533   }
   10534 
   10535   ArrayConcatVisitor visitor(isolate, storage, fast_case);
   10536 
   10537   for (int i = 0; i < argument_count; i++) {
   10538     Handle<Object> obj(elements->get(i), isolate);
   10539     if (obj->IsJSArray()) {
   10540       Handle<JSArray> array = Handle<JSArray>::cast(obj);
   10541       if (!IterateElements(isolate, array, &visitor)) {
   10542         return Failure::Exception();
   10543       }
   10544     } else {
   10545       visitor.visit(0, obj);
   10546       visitor.increase_index_offset(1);
   10547     }
   10548   }
   10549 
   10550   if (visitor.exceeds_array_limit()) {
   10551     return isolate->Throw(
   10552         *isolate->factory()->NewRangeError("invalid_array_length",
   10553                                            HandleVector<Object>(NULL, 0)));
   10554   }
   10555   return *visitor.ToArray();
   10556 }
   10557 
   10558 
   10559 // This will not allocate (flatten the string), but it may run
   10560 // very slowly for very deeply nested ConsStrings.  For debugging use only.
   10561 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
   10562   SealHandleScope shs(isolate);
   10563   ASSERT(args.length() == 1);
   10564 
   10565   CONVERT_ARG_CHECKED(String, string, 0);
   10566   ConsStringIteratorOp op;
   10567   StringCharacterStream stream(string, &op);
   10568   while (stream.HasMore()) {
   10569     uint16_t character = stream.GetNext();
   10570     PrintF("%c", character);
   10571   }
   10572   return string;
   10573 }
   10574 
   10575 
   10576 // Moves all own elements of an object, that are below a limit, to positions
   10577 // starting at zero. All undefined values are placed after non-undefined values,
   10578 // and are followed by non-existing element. Does not change the length
   10579 // property.
   10580 // Returns the number of non-undefined elements collected.
   10581 RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
   10582   HandleScope scope(isolate);
   10583   ASSERT(args.length() == 2);
   10584   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   10585   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   10586   return *JSObject::PrepareElementsForSort(object, limit);
   10587 }
   10588 
   10589 
   10590 // Move contents of argument 0 (an array) to argument 1 (an array)
   10591 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
   10592   SealHandleScope shs(isolate);
   10593   ASSERT(args.length() == 2);
   10594   CONVERT_ARG_CHECKED(JSArray, from, 0);
   10595   CONVERT_ARG_CHECKED(JSArray, to, 1);
   10596   from->ValidateElements();
   10597   to->ValidateElements();
   10598   FixedArrayBase* new_elements = from->elements();
   10599   ElementsKind from_kind = from->GetElementsKind();
   10600   MaybeObject* maybe_new_map;
   10601   maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind);
   10602   Object* new_map;
   10603   if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
   10604   to->set_map_and_elements(Map::cast(new_map), new_elements);
   10605   to->set_length(from->length());
   10606   Object* obj;
   10607   { MaybeObject* maybe_obj = from->ResetElements();
   10608     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   10609   }
   10610   from->set_length(Smi::FromInt(0));
   10611   to->ValidateElements();
   10612   return to;
   10613 }
   10614 
   10615 
   10616 // How many elements does this object/array have?
   10617 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
   10618   SealHandleScope shs(isolate);
   10619   ASSERT(args.length() == 1);
   10620   CONVERT_ARG_CHECKED(JSObject, object, 0);
   10621   HeapObject* elements = object->elements();
   10622   if (elements->IsDictionary()) {
   10623     int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
   10624     return Smi::FromInt(result);
   10625   } else if (object->IsJSArray()) {
   10626     return JSArray::cast(object)->length();
   10627   } else {
   10628     return Smi::FromInt(FixedArray::cast(elements)->length());
   10629   }
   10630 }
   10631 
   10632 
   10633 // Returns an array that tells you where in the [0, length) interval an array
   10634 // might have elements.  Can either return an array of keys (positive integers
   10635 // or undefined) or a number representing the positive length of an interval
   10636 // starting at index 0.
   10637 // Intervals can span over some keys that are not in the object.
   10638 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
   10639   HandleScope scope(isolate);
   10640   ASSERT(args.length() == 2);
   10641   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   10642   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
   10643   if (array->elements()->IsDictionary()) {
   10644     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
   10645     for (Handle<Object> p = array;
   10646          !p->IsNull();
   10647          p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
   10648       if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
   10649         // Bail out if we find a proxy or interceptor, likely not worth
   10650         // collecting keys in that case.
   10651         return *isolate->factory()->NewNumberFromUint(length);
   10652       }
   10653       Handle<JSObject> current = Handle<JSObject>::cast(p);
   10654       Handle<FixedArray> current_keys =
   10655           isolate->factory()->NewFixedArray(
   10656               current->NumberOfLocalElements(NONE));
   10657       current->GetLocalElementKeys(*current_keys, NONE);
   10658       keys = UnionOfKeys(keys, current_keys);
   10659     }
   10660     // Erase any keys >= length.
   10661     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
   10662     // is changed to let this happen on the JS side.
   10663     for (int i = 0; i < keys->length(); i++) {
   10664       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
   10665     }
   10666     return *isolate->factory()->NewJSArrayWithElements(keys);
   10667   } else {
   10668     ASSERT(array->HasFastSmiOrObjectElements() ||
   10669            array->HasFastDoubleElements());
   10670     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
   10671     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
   10672   }
   10673 }
   10674 
   10675 
   10676 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
   10677   HandleScope scope(isolate);
   10678   ASSERT(args.length() == 3);
   10679   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
   10680   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10681   CONVERT_SMI_ARG_CHECKED(flag, 2);
   10682   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
   10683   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
   10684   Handle<Object> result =
   10685       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component);
   10686   RETURN_IF_EMPTY_HANDLE(isolate, result);
   10687   return *result;
   10688 }
   10689 
   10690 
   10691 #ifdef ENABLE_DEBUGGER_SUPPORT
   10692 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
   10693   SealHandleScope shs(isolate);
   10694   ASSERT(args.length() == 0);
   10695   return Execution::DebugBreakHelper(isolate);
   10696 }
   10697 
   10698 
   10699 // Helper functions for wrapping and unwrapping stack frame ids.
   10700 static Smi* WrapFrameId(StackFrame::Id id) {
   10701   ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
   10702   return Smi::FromInt(id >> 2);
   10703 }
   10704 
   10705 
   10706 static StackFrame::Id UnwrapFrameId(int wrapped) {
   10707   return static_cast<StackFrame::Id>(wrapped << 2);
   10708 }
   10709 
   10710 
   10711 // Adds a JavaScript function as a debug event listener.
   10712 // args[0]: debug event listener function to set or null or undefined for
   10713 //          clearing the event listener function
   10714 // args[1]: object supplied during callback
   10715 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDebugEventListener) {
   10716   SealHandleScope shs(isolate);
   10717   ASSERT(args.length() == 2);
   10718   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
   10719                  args[0]->IsUndefined() ||
   10720                  args[0]->IsNull());
   10721   Handle<Object> callback = args.at<Object>(0);
   10722   Handle<Object> data = args.at<Object>(1);
   10723   isolate->debugger()->SetEventListener(callback, data);
   10724 
   10725   return isolate->heap()->undefined_value();
   10726 }
   10727 
   10728 
   10729 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
   10730   SealHandleScope shs(isolate);
   10731   ASSERT(args.length() == 0);
   10732   isolate->stack_guard()->DebugBreak();
   10733   return isolate->heap()->undefined_value();
   10734 }
   10735 
   10736 
   10737 static MaybeObject* DebugLookupResultValue(Heap* heap,
   10738                                            Object* receiver,
   10739                                            Name* name,
   10740                                            LookupResult* result,
   10741                                            bool* caught_exception) {
   10742   Object* value;
   10743   switch (result->type()) {
   10744     case NORMAL:
   10745       value = result->holder()->GetNormalizedProperty(result);
   10746       if (value->IsTheHole()) {
   10747         return heap->undefined_value();
   10748       }
   10749       return value;
   10750     case FIELD: {
   10751       Object* value;
   10752       MaybeObject* maybe_value =
   10753           JSObject::cast(result->holder())->FastPropertyAt(
   10754               result->representation(),
   10755               result->GetFieldIndex().field_index());
   10756       if (!maybe_value->To(&value)) return maybe_value;
   10757       if (value->IsTheHole()) {
   10758         return heap->undefined_value();
   10759       }
   10760       return value;
   10761     }
   10762     case CONSTANT:
   10763       return result->GetConstant();
   10764     case CALLBACKS: {
   10765       Object* structure = result->GetCallbackObject();
   10766       if (structure->IsForeign() || structure->IsAccessorInfo()) {
   10767         Isolate* isolate = heap->isolate();
   10768         HandleScope scope(isolate);
   10769         Handle<Object> value = JSObject::GetPropertyWithCallback(
   10770             handle(result->holder(), isolate),
   10771             handle(receiver, isolate),
   10772             handle(structure, isolate),
   10773             handle(name, isolate));
   10774         if (value.is_null()) {
   10775           MaybeObject* exception = heap->isolate()->pending_exception();
   10776           heap->isolate()->clear_pending_exception();
   10777           if (caught_exception != NULL) *caught_exception = true;
   10778           return exception;
   10779         }
   10780         return *value;
   10781       } else {
   10782         return heap->undefined_value();
   10783       }
   10784     }
   10785     case INTERCEPTOR:
   10786     case TRANSITION:
   10787       return heap->undefined_value();
   10788     case HANDLER:
   10789     case NONEXISTENT:
   10790       UNREACHABLE();
   10791       return heap->undefined_value();
   10792   }
   10793   UNREACHABLE();  // keep the compiler happy
   10794   return heap->undefined_value();
   10795 }
   10796 
   10797 
   10798 // Get debugger related details for an object property.
   10799 // args[0]: object holding property
   10800 // args[1]: name of the property
   10801 //
   10802 // The array returned contains the following information:
   10803 // 0: Property value
   10804 // 1: Property details
   10805 // 2: Property value is exception
   10806 // 3: Getter function if defined
   10807 // 4: Setter function if defined
   10808 // Items 2-4 are only filled if the property has either a getter or a setter
   10809 // defined through __defineGetter__ and/or __defineSetter__.
   10810 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
   10811   HandleScope scope(isolate);
   10812 
   10813   ASSERT(args.length() == 2);
   10814 
   10815   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10816   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10817 
   10818   // Make sure to set the current context to the context before the debugger was
   10819   // entered (if the debugger is entered). The reason for switching context here
   10820   // is that for some property lookups (accessors and interceptors) callbacks
   10821   // into the embedding application can occour, and the embedding application
   10822   // could have the assumption that its own native context is the current
   10823   // context and not some internal debugger context.
   10824   SaveContext save(isolate);
   10825   if (isolate->debug()->InDebugger()) {
   10826     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
   10827   }
   10828 
   10829   // Skip the global proxy as it has no properties and always delegates to the
   10830   // real global object.
   10831   if (obj->IsJSGlobalProxy()) {
   10832     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   10833   }
   10834 
   10835 
   10836   // Check if the name is trivially convertible to an index and get the element
   10837   // if so.
   10838   uint32_t index;
   10839   if (name->AsArrayIndex(&index)) {
   10840     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
   10841     Object* element_or_char;
   10842     { MaybeObject* maybe_element_or_char =
   10843           Runtime::GetElementOrCharAt(isolate, obj, index);
   10844       if (!maybe_element_or_char->ToObject(&element_or_char)) {
   10845         return maybe_element_or_char;
   10846       }
   10847     }
   10848     details->set(0, element_or_char);
   10849     details->set(
   10850         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
   10851     return *isolate->factory()->NewJSArrayWithElements(details);
   10852   }
   10853 
   10854   // Find the number of objects making up this.
   10855   int length = LocalPrototypeChainLength(*obj);
   10856 
   10857   // Try local lookup on each of the objects.
   10858   Handle<JSObject> jsproto = obj;
   10859   for (int i = 0; i < length; i++) {
   10860     LookupResult result(isolate);
   10861     jsproto->LocalLookup(*name, &result);
   10862     if (result.IsFound()) {
   10863       // LookupResult is not GC safe as it holds raw object pointers.
   10864       // GC can happen later in this code so put the required fields into
   10865       // local variables using handles when required for later use.
   10866       Handle<Object> result_callback_obj;
   10867       if (result.IsPropertyCallbacks()) {
   10868         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
   10869                                              isolate);
   10870       }
   10871       Smi* property_details = result.GetPropertyDetails().AsSmi();
   10872       // DebugLookupResultValue can cause GC so details from LookupResult needs
   10873       // to be copied to handles before this.
   10874       bool caught_exception = false;
   10875       Object* raw_value;
   10876       { MaybeObject* maybe_raw_value =
   10877             DebugLookupResultValue(isolate->heap(), *obj, *name,
   10878                                    &result, &caught_exception);
   10879         if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value;
   10880       }
   10881       Handle<Object> value(raw_value, isolate);
   10882 
   10883       // If the callback object is a fixed array then it contains JavaScript
   10884       // getter and/or setter.
   10885       bool hasJavaScriptAccessors = result.IsPropertyCallbacks() &&
   10886                                     result_callback_obj->IsAccessorPair();
   10887       Handle<FixedArray> details =
   10888           isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
   10889       details->set(0, *value);
   10890       details->set(1, property_details);
   10891       if (hasJavaScriptAccessors) {
   10892         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
   10893         details->set(2, isolate->heap()->ToBoolean(caught_exception));
   10894         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
   10895         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
   10896       }
   10897 
   10898       return *isolate->factory()->NewJSArrayWithElements(details);
   10899     }
   10900     if (i < length - 1) {
   10901       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   10902     }
   10903   }
   10904 
   10905   return isolate->heap()->undefined_value();
   10906 }
   10907 
   10908 
   10909 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
   10910   HandleScope scope(isolate);
   10911 
   10912   ASSERT(args.length() == 2);
   10913 
   10914   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10915   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10916 
   10917   LookupResult result(isolate);
   10918   obj->Lookup(*name, &result);
   10919   if (result.IsFound()) {
   10920     return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
   10921   }
   10922   return isolate->heap()->undefined_value();
   10923 }
   10924 
   10925 
   10926 // Return the property type calculated from the property details.
   10927 // args[0]: smi with property details.
   10928 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
   10929   SealHandleScope shs(isolate);
   10930   ASSERT(args.length() == 1);
   10931   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10932   return Smi::FromInt(static_cast<int>(details.type()));
   10933 }
   10934 
   10935 
   10936 // Return the property attribute calculated from the property details.
   10937 // args[0]: smi with property details.
   10938 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
   10939   SealHandleScope shs(isolate);
   10940   ASSERT(args.length() == 1);
   10941   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10942   return Smi::FromInt(static_cast<int>(details.attributes()));
   10943 }
   10944 
   10945 
   10946 // Return the property insertion index calculated from the property details.
   10947 // args[0]: smi with property details.
   10948 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
   10949   SealHandleScope shs(isolate);
   10950   ASSERT(args.length() == 1);
   10951   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10952   // TODO(verwaest): Depends on the type of details.
   10953   return Smi::FromInt(details.dictionary_index());
   10954 }
   10955 
   10956 
   10957 // Return property value from named interceptor.
   10958 // args[0]: object
   10959 // args[1]: property name
   10960 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
   10961   HandleScope scope(isolate);
   10962   ASSERT(args.length() == 2);
   10963   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10964   RUNTIME_ASSERT(obj->HasNamedInterceptor());
   10965   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10966 
   10967   PropertyAttributes attributes;
   10968   Handle<Object> result =
   10969       JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes);
   10970   RETURN_IF_EMPTY_HANDLE(isolate, result);
   10971   return *result;
   10972 }
   10973 
   10974 
   10975 // Return element value from indexed interceptor.
   10976 // args[0]: object
   10977 // args[1]: index
   10978 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
   10979   HandleScope scope(isolate);
   10980   ASSERT(args.length() == 2);
   10981   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10982   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
   10983   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
   10984 
   10985   return obj->GetElementWithInterceptor(*obj, index);
   10986 }
   10987 
   10988 
   10989 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckExecutionState) {
   10990   SealHandleScope shs(isolate);
   10991   ASSERT(args.length() >= 1);
   10992   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   10993   // Check that the break id is valid.
   10994   if (isolate->debug()->break_id() == 0 ||
   10995       break_id != isolate->debug()->break_id()) {
   10996     return isolate->Throw(
   10997         isolate->heap()->illegal_execution_state_string());
   10998   }
   10999 
   11000   return isolate->heap()->true_value();
   11001 }
   11002 
   11003 
   11004 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
   11005   HandleScope scope(isolate);
   11006   ASSERT(args.length() == 1);
   11007 
   11008   // Check arguments.
   11009   Object* result;
   11010   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   11011       RUNTIME_ARGUMENTS(isolate, args));
   11012     if (!maybe_result->ToObject(&result)) return maybe_result;
   11013   }
   11014 
   11015   // Count all frames which are relevant to debugging stack trace.
   11016   int n = 0;
   11017   StackFrame::Id id = isolate->debug()->break_frame_id();
   11018   if (id == StackFrame::NO_ID) {
   11019     // If there is no JavaScript stack frame count is 0.
   11020     return Smi::FromInt(0);
   11021   }
   11022 
   11023   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
   11024     n += it.frame()->GetInlineCount();
   11025   }
   11026   return Smi::FromInt(n);
   11027 }
   11028 
   11029 
   11030 class FrameInspector {
   11031  public:
   11032   FrameInspector(JavaScriptFrame* frame,
   11033                  int inlined_jsframe_index,
   11034                  Isolate* isolate)
   11035       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
   11036     // Calculate the deoptimized frame.
   11037     if (frame->is_optimized()) {
   11038       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
   11039           frame, inlined_jsframe_index, isolate);
   11040     }
   11041     has_adapted_arguments_ = frame_->has_adapted_arguments();
   11042     is_bottommost_ = inlined_jsframe_index == 0;
   11043     is_optimized_ = frame_->is_optimized();
   11044   }
   11045 
   11046   ~FrameInspector() {
   11047     // Get rid of the calculated deoptimized frame if any.
   11048     if (deoptimized_frame_ != NULL) {
   11049       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
   11050                                                   isolate_);
   11051     }
   11052   }
   11053 
   11054   int GetParametersCount() {
   11055     return is_optimized_
   11056         ? deoptimized_frame_->parameters_count()
   11057         : frame_->ComputeParametersCount();
   11058   }
   11059   int expression_count() { return deoptimized_frame_->expression_count(); }
   11060   Object* GetFunction() {
   11061     return is_optimized_
   11062         ? deoptimized_frame_->GetFunction()
   11063         : frame_->function();
   11064   }
   11065   Object* GetParameter(int index) {
   11066     return is_optimized_
   11067         ? deoptimized_frame_->GetParameter(index)
   11068         : frame_->GetParameter(index);
   11069   }
   11070   Object* GetExpression(int index) {
   11071     return is_optimized_
   11072         ? deoptimized_frame_->GetExpression(index)
   11073         : frame_->GetExpression(index);
   11074   }
   11075   int GetSourcePosition() {
   11076     return is_optimized_
   11077         ? deoptimized_frame_->GetSourcePosition()
   11078         : frame_->LookupCode()->SourcePosition(frame_->pc());
   11079   }
   11080   bool IsConstructor() {
   11081     return is_optimized_ && !is_bottommost_
   11082         ? deoptimized_frame_->HasConstructStub()
   11083         : frame_->IsConstructor();
   11084   }
   11085 
   11086   // To inspect all the provided arguments the frame might need to be
   11087   // replaced with the arguments frame.
   11088   void SetArgumentsFrame(JavaScriptFrame* frame) {
   11089     ASSERT(has_adapted_arguments_);
   11090     frame_ = frame;
   11091     is_optimized_ = frame_->is_optimized();
   11092     ASSERT(!is_optimized_);
   11093   }
   11094 
   11095  private:
   11096   JavaScriptFrame* frame_;
   11097   DeoptimizedFrameInfo* deoptimized_frame_;
   11098   Isolate* isolate_;
   11099   bool is_optimized_;
   11100   bool is_bottommost_;
   11101   bool has_adapted_arguments_;
   11102 
   11103   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
   11104 };
   11105 
   11106 
   11107 static const int kFrameDetailsFrameIdIndex = 0;
   11108 static const int kFrameDetailsReceiverIndex = 1;
   11109 static const int kFrameDetailsFunctionIndex = 2;
   11110 static const int kFrameDetailsArgumentCountIndex = 3;
   11111 static const int kFrameDetailsLocalCountIndex = 4;
   11112 static const int kFrameDetailsSourcePositionIndex = 5;
   11113 static const int kFrameDetailsConstructCallIndex = 6;
   11114 static const int kFrameDetailsAtReturnIndex = 7;
   11115 static const int kFrameDetailsFlagsIndex = 8;
   11116 static const int kFrameDetailsFirstDynamicIndex = 9;
   11117 
   11118 
   11119 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
   11120                                              JavaScriptFrame* frame) {
   11121   SaveContext* save = isolate->save_context();
   11122   while (save != NULL && !save->IsBelowFrame(frame)) {
   11123     save = save->prev();
   11124   }
   11125   ASSERT(save != NULL);
   11126   return save;
   11127 }
   11128 
   11129 
   11130 // Return an array with frame details
   11131 // args[0]: number: break id
   11132 // args[1]: number: frame index
   11133 //
   11134 // The array returned contains the following information:
   11135 // 0: Frame id
   11136 // 1: Receiver
   11137 // 2: Function
   11138 // 3: Argument count
   11139 // 4: Local count
   11140 // 5: Source position
   11141 // 6: Constructor call
   11142 // 7: Is at return
   11143 // 8: Flags
   11144 // Arguments name, value
   11145 // Locals name, value
   11146 // Return value if any
   11147 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   11148   HandleScope scope(isolate);
   11149   ASSERT(args.length() == 2);
   11150 
   11151   // Check arguments.
   11152   Object* check;
   11153   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   11154       RUNTIME_ARGUMENTS(isolate, args));
   11155     if (!maybe_check->ToObject(&check)) return maybe_check;
   11156   }
   11157   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   11158   Heap* heap = isolate->heap();
   11159 
   11160   // Find the relevant frame with the requested index.
   11161   StackFrame::Id id = isolate->debug()->break_frame_id();
   11162   if (id == StackFrame::NO_ID) {
   11163     // If there are no JavaScript stack frames return undefined.
   11164     return heap->undefined_value();
   11165   }
   11166 
   11167   int count = 0;
   11168   JavaScriptFrameIterator it(isolate, id);
   11169   for (; !it.done(); it.Advance()) {
   11170     if (index < count + it.frame()->GetInlineCount()) break;
   11171     count += it.frame()->GetInlineCount();
   11172   }
   11173   if (it.done()) return heap->undefined_value();
   11174 
   11175   bool is_optimized = it.frame()->is_optimized();
   11176 
   11177   int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
   11178   if (is_optimized) {
   11179     inlined_jsframe_index =
   11180         it.frame()->GetInlineCount() - (index - count) - 1;
   11181   }
   11182   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
   11183 
   11184   // Traverse the saved contexts chain to find the active context for the
   11185   // selected frame.
   11186   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
   11187 
   11188   // Get the frame id.
   11189   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
   11190 
   11191   // Find source position in unoptimized code.
   11192   int position = frame_inspector.GetSourcePosition();
   11193 
   11194   // Check for constructor frame.
   11195   bool constructor = frame_inspector.IsConstructor();
   11196 
   11197   // Get scope info and read from it for local variable information.
   11198   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11199   Handle<SharedFunctionInfo> shared(function->shared());
   11200   Handle<ScopeInfo> scope_info(shared->scope_info());
   11201   ASSERT(*scope_info != ScopeInfo::Empty(isolate));
   11202 
   11203   // Get the locals names and values into a temporary array.
   11204   //
   11205   // TODO(1240907): Hide compiler-introduced stack variables
   11206   // (e.g. .result)?  For users of the debugger, they will probably be
   11207   // confusing.
   11208   Handle<FixedArray> locals =
   11209       isolate->factory()->NewFixedArray(scope_info->LocalCount() * 2);
   11210 
   11211   // Fill in the values of the locals.
   11212   int i = 0;
   11213   for (; i < scope_info->StackLocalCount(); ++i) {
   11214     // Use the value from the stack.
   11215     locals->set(i * 2, scope_info->LocalName(i));
   11216     locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
   11217   }
   11218   if (i < scope_info->LocalCount()) {
   11219     // Get the context containing declarations.
   11220     Handle<Context> context(
   11221         Context::cast(it.frame()->context())->declaration_context());
   11222     for (; i < scope_info->LocalCount(); ++i) {
   11223       Handle<String> name(scope_info->LocalName(i));
   11224       VariableMode mode;
   11225       InitializationFlag init_flag;
   11226       locals->set(i * 2, *name);
   11227       locals->set(i * 2 + 1, context->get(
   11228           scope_info->ContextSlotIndex(*name, &mode, &init_flag)));
   11229     }
   11230   }
   11231 
   11232   // Check whether this frame is positioned at return. If not top
   11233   // frame or if the frame is optimized it cannot be at a return.
   11234   bool at_return = false;
   11235   if (!is_optimized && index == 0) {
   11236     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
   11237   }
   11238 
   11239   // If positioned just before return find the value to be returned and add it
   11240   // to the frame information.
   11241   Handle<Object> return_value = isolate->factory()->undefined_value();
   11242   if (at_return) {
   11243     StackFrameIterator it2(isolate);
   11244     Address internal_frame_sp = NULL;
   11245     while (!it2.done()) {
   11246       if (it2.frame()->is_internal()) {
   11247         internal_frame_sp = it2.frame()->sp();
   11248       } else {
   11249         if (it2.frame()->is_java_script()) {
   11250           if (it2.frame()->id() == it.frame()->id()) {
   11251             // The internal frame just before the JavaScript frame contains the
   11252             // value to return on top. A debug break at return will create an
   11253             // internal frame to store the return value (eax/rax/r0) before
   11254             // entering the debug break exit frame.
   11255             if (internal_frame_sp != NULL) {
   11256               return_value =
   11257                   Handle<Object>(Memory::Object_at(internal_frame_sp),
   11258                                  isolate);
   11259               break;
   11260             }
   11261           }
   11262         }
   11263 
   11264         // Indicate that the previous frame was not an internal frame.
   11265         internal_frame_sp = NULL;
   11266       }
   11267       it2.Advance();
   11268     }
   11269   }
   11270 
   11271   // Now advance to the arguments adapter frame (if any). It contains all
   11272   // the provided parameters whereas the function frame always have the number
   11273   // of arguments matching the functions parameters. The rest of the
   11274   // information (except for what is collected above) is the same.
   11275   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
   11276     it.AdvanceToArgumentsFrame();
   11277     frame_inspector.SetArgumentsFrame(it.frame());
   11278   }
   11279 
   11280   // Find the number of arguments to fill. At least fill the number of
   11281   // parameters for the function and fill more if more parameters are provided.
   11282   int argument_count = scope_info->ParameterCount();
   11283   if (argument_count < frame_inspector.GetParametersCount()) {
   11284     argument_count = frame_inspector.GetParametersCount();
   11285   }
   11286 
   11287   // Calculate the size of the result.
   11288   int details_size = kFrameDetailsFirstDynamicIndex +
   11289                      2 * (argument_count + scope_info->LocalCount()) +
   11290                      (at_return ? 1 : 0);
   11291   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   11292 
   11293   // Add the frame id.
   11294   details->set(kFrameDetailsFrameIdIndex, *frame_id);
   11295 
   11296   // Add the function (same as in function frame).
   11297   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
   11298 
   11299   // Add the arguments count.
   11300   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
   11301 
   11302   // Add the locals count
   11303   details->set(kFrameDetailsLocalCountIndex,
   11304                Smi::FromInt(scope_info->LocalCount()));
   11305 
   11306   // Add the source position.
   11307   if (position != RelocInfo::kNoPosition) {
   11308     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
   11309   } else {
   11310     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
   11311   }
   11312 
   11313   // Add the constructor information.
   11314   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
   11315 
   11316   // Add the at return information.
   11317   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
   11318 
   11319   // Add flags to indicate information on whether this frame is
   11320   //   bit 0: invoked in the debugger context.
   11321   //   bit 1: optimized frame.
   11322   //   bit 2: inlined in optimized frame
   11323   int flags = 0;
   11324   if (*save->context() == *isolate->debug()->debug_context()) {
   11325     flags |= 1 << 0;
   11326   }
   11327   if (is_optimized) {
   11328     flags |= 1 << 1;
   11329     flags |= inlined_jsframe_index << 2;
   11330   }
   11331   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
   11332 
   11333   // Fill the dynamic part.
   11334   int details_index = kFrameDetailsFirstDynamicIndex;
   11335 
   11336   // Add arguments name and value.
   11337   for (int i = 0; i < argument_count; i++) {
   11338     // Name of the argument.
   11339     if (i < scope_info->ParameterCount()) {
   11340       details->set(details_index++, scope_info->ParameterName(i));
   11341     } else {
   11342       details->set(details_index++, heap->undefined_value());
   11343     }
   11344 
   11345     // Parameter value.
   11346     if (i < frame_inspector.GetParametersCount()) {
   11347       // Get the value from the stack.
   11348       details->set(details_index++, frame_inspector.GetParameter(i));
   11349     } else {
   11350       details->set(details_index++, heap->undefined_value());
   11351     }
   11352   }
   11353 
   11354   // Add locals name and value from the temporary copy from the function frame.
   11355   for (int i = 0; i < scope_info->LocalCount() * 2; i++) {
   11356     details->set(details_index++, locals->get(i));
   11357   }
   11358 
   11359   // Add the value being returned.
   11360   if (at_return) {
   11361     details->set(details_index++, *return_value);
   11362   }
   11363 
   11364   // Add the receiver (same as in function frame).
   11365   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
   11366   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
   11367   Handle<Object> receiver(it.frame()->receiver(), isolate);
   11368   if (!receiver->IsJSObject() &&
   11369       shared->is_classic_mode() &&
   11370       !function->IsBuiltin()) {
   11371     // If the receiver is not a JSObject and the function is not a
   11372     // builtin or strict-mode we have hit an optimization where a
   11373     // value object is not converted into a wrapped JS objects. To
   11374     // hide this optimization from the debugger, we wrap the receiver
   11375     // by creating correct wrapper object based on the calling frame's
   11376     // native context.
   11377     it.Advance();
   11378     Handle<Context> calling_frames_native_context(
   11379         Context::cast(Context::cast(it.frame()->context())->native_context()));
   11380     ASSERT(!receiver->IsUndefined() && !receiver->IsNull());
   11381     receiver =
   11382         isolate->factory()->ToObject(receiver, calling_frames_native_context);
   11383   }
   11384   details->set(kFrameDetailsReceiverIndex, *receiver);
   11385 
   11386   ASSERT_EQ(details_size, details_index);
   11387   return *isolate->factory()->NewJSArrayWithElements(details);
   11388 }
   11389 
   11390 
   11391 // Create a plain JSObject which materializes the local scope for the specified
   11392 // frame.
   11393 static Handle<JSObject> MaterializeStackLocalsWithFrameInspector(
   11394     Isolate* isolate,
   11395     Handle<JSObject> target,
   11396     Handle<JSFunction> function,
   11397     FrameInspector* frame_inspector) {
   11398   Handle<SharedFunctionInfo> shared(function->shared());
   11399   Handle<ScopeInfo> scope_info(shared->scope_info());
   11400 
   11401   // First fill all parameters.
   11402   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11403     Handle<Object> value(i < frame_inspector->GetParametersCount()
   11404                              ? frame_inspector->GetParameter(i)
   11405                              : isolate->heap()->undefined_value(),
   11406                          isolate);
   11407     ASSERT(!value->IsTheHole());
   11408 
   11409     RETURN_IF_EMPTY_HANDLE_VALUE(
   11410         isolate,
   11411         Runtime::SetObjectProperty(isolate,
   11412                                    target,
   11413                                    Handle<String>(scope_info->ParameterName(i)),
   11414                                    value,
   11415                                    NONE,
   11416                                    kNonStrictMode),
   11417         Handle<JSObject>());
   11418   }
   11419 
   11420   // Second fill all stack locals.
   11421   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11422     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
   11423     if (value->IsTheHole()) continue;
   11424 
   11425     RETURN_IF_EMPTY_HANDLE_VALUE(
   11426         isolate,
   11427         Runtime::SetObjectProperty(
   11428             isolate,
   11429             target,
   11430             Handle<String>(scope_info->StackLocalName(i)),
   11431             value,
   11432             NONE,
   11433             kNonStrictMode),
   11434         Handle<JSObject>());
   11435   }
   11436 
   11437   return target;
   11438 }
   11439 
   11440 
   11441 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
   11442                                                     Handle<JSObject> target,
   11443                                                     Handle<JSFunction> function,
   11444                                                     JavaScriptFrame* frame,
   11445                                                     int inlined_jsframe_index) {
   11446   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11447     // Optimized frames are not supported.
   11448     // TODO(yangguo): make sure all code deoptimized when debugger is active
   11449     //                and assert that this cannot happen.
   11450     return;
   11451   }
   11452 
   11453   Handle<SharedFunctionInfo> shared(function->shared());
   11454   Handle<ScopeInfo> scope_info(shared->scope_info());
   11455 
   11456   // Parameters.
   11457   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11458     ASSERT(!frame->GetParameter(i)->IsTheHole());
   11459     HandleScope scope(isolate);
   11460     Handle<Object> value = GetProperty(
   11461         isolate, target, Handle<String>(scope_info->ParameterName(i)));
   11462     frame->SetParameterValue(i, *value);
   11463   }
   11464 
   11465   // Stack locals.
   11466   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11467     if (frame->GetExpression(i)->IsTheHole()) continue;
   11468     HandleScope scope(isolate);
   11469     Handle<Object> value = GetProperty(
   11470         isolate, target, Handle<String>(scope_info->StackLocalName(i)));
   11471     frame->SetExpression(i, *value);
   11472   }
   11473 }
   11474 
   11475 
   11476 static Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
   11477                                                 Handle<JSObject> target,
   11478                                                 Handle<JSFunction> function,
   11479                                                 JavaScriptFrame* frame) {
   11480   HandleScope scope(isolate);
   11481   Handle<SharedFunctionInfo> shared(function->shared());
   11482   Handle<ScopeInfo> scope_info(shared->scope_info());
   11483 
   11484   if (!scope_info->HasContext()) return target;
   11485 
   11486   // Third fill all context locals.
   11487   Handle<Context> frame_context(Context::cast(frame->context()));
   11488   Handle<Context> function_context(frame_context->declaration_context());
   11489   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11490           scope_info, function_context, target)) {
   11491     return Handle<JSObject>();
   11492   }
   11493 
   11494   // Finally copy any properties from the function context extension.
   11495   // These will be variables introduced by eval.
   11496   if (function_context->closure() == *function) {
   11497     if (function_context->has_extension() &&
   11498         !function_context->IsNativeContext()) {
   11499       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11500       bool threw = false;
   11501       Handle<FixedArray> keys =
   11502           GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
   11503       if (threw) return Handle<JSObject>();
   11504 
   11505       for (int i = 0; i < keys->length(); i++) {
   11506         // Names of variables introduced by eval are strings.
   11507         ASSERT(keys->get(i)->IsString());
   11508         Handle<String> key(String::cast(keys->get(i)));
   11509         RETURN_IF_EMPTY_HANDLE_VALUE(
   11510             isolate,
   11511             Runtime::SetObjectProperty(isolate,
   11512                                        target,
   11513                                        key,
   11514                                        GetProperty(isolate, ext, key),
   11515                                        NONE,
   11516                                        kNonStrictMode),
   11517             Handle<JSObject>());
   11518       }
   11519     }
   11520   }
   11521 
   11522   return target;
   11523 }
   11524 
   11525 
   11526 static Handle<JSObject> MaterializeLocalScope(
   11527     Isolate* isolate,
   11528     JavaScriptFrame* frame,
   11529     int inlined_jsframe_index) {
   11530   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   11531   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11532 
   11533   Handle<JSObject> local_scope =
   11534       isolate->factory()->NewJSObject(isolate->object_function());
   11535   local_scope = MaterializeStackLocalsWithFrameInspector(
   11536                     isolate, local_scope, function, &frame_inspector);
   11537   RETURN_IF_EMPTY_HANDLE_VALUE(isolate, local_scope, Handle<JSObject>());
   11538 
   11539   return MaterializeLocalContext(isolate, local_scope, function, frame);
   11540 }
   11541 
   11542 
   11543 // Set the context local variable value.
   11544 static bool SetContextLocalValue(Isolate* isolate,
   11545                                  Handle<ScopeInfo> scope_info,
   11546                                  Handle<Context> context,
   11547                                  Handle<String> variable_name,
   11548                                  Handle<Object> new_value) {
   11549   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
   11550     Handle<String> next_name(scope_info->ContextLocalName(i));
   11551     if (variable_name->Equals(*next_name)) {
   11552       VariableMode mode;
   11553       InitializationFlag init_flag;
   11554       int context_index =
   11555           scope_info->ContextSlotIndex(*next_name, &mode, &init_flag);
   11556       context->set(context_index, *new_value);
   11557       return true;
   11558     }
   11559   }
   11560 
   11561   return false;
   11562 }
   11563 
   11564 
   11565 static bool SetLocalVariableValue(Isolate* isolate,
   11566                                   JavaScriptFrame* frame,
   11567                                   int inlined_jsframe_index,
   11568                                   Handle<String> variable_name,
   11569                                   Handle<Object> new_value) {
   11570   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11571     // Optimized frames are not supported.
   11572     return false;
   11573   }
   11574 
   11575   Handle<JSFunction> function(frame->function());
   11576   Handle<SharedFunctionInfo> shared(function->shared());
   11577   Handle<ScopeInfo> scope_info(shared->scope_info());
   11578 
   11579   bool default_result = false;
   11580 
   11581   // Parameters.
   11582   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11583     if (scope_info->ParameterName(i)->Equals(*variable_name)) {
   11584       frame->SetParameterValue(i, *new_value);
   11585       // Argument might be shadowed in heap context, don't stop here.
   11586       default_result = true;
   11587     }
   11588   }
   11589 
   11590   // Stack locals.
   11591   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11592     if (scope_info->StackLocalName(i)->Equals(*variable_name)) {
   11593       frame->SetExpression(i, *new_value);
   11594       return true;
   11595     }
   11596   }
   11597 
   11598   if (scope_info->HasContext()) {
   11599     // Context locals.
   11600     Handle<Context> frame_context(Context::cast(frame->context()));
   11601     Handle<Context> function_context(frame_context->declaration_context());
   11602     if (SetContextLocalValue(
   11603         isolate, scope_info, function_context, variable_name, new_value)) {
   11604       return true;
   11605     }
   11606 
   11607     // Function context extension. These are variables introduced by eval.
   11608     if (function_context->closure() == *function) {
   11609       if (function_context->has_extension() &&
   11610           !function_context->IsNativeContext()) {
   11611         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11612 
   11613         if (JSReceiver::HasProperty(ext, variable_name)) {
   11614           // We don't expect this to do anything except replacing
   11615           // property value.
   11616           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
   11617                                      NONE,
   11618                                      kNonStrictMode);
   11619           return true;
   11620         }
   11621       }
   11622     }
   11623   }
   11624 
   11625   return default_result;
   11626 }
   11627 
   11628 
   11629 // Create a plain JSObject which materializes the closure content for the
   11630 // context.
   11631 static Handle<JSObject> MaterializeClosure(Isolate* isolate,
   11632                                            Handle<Context> context) {
   11633   ASSERT(context->IsFunctionContext());
   11634 
   11635   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11636   Handle<ScopeInfo> scope_info(shared->scope_info());
   11637 
   11638   // Allocate and initialize a JSObject with all the content of this function
   11639   // closure.
   11640   Handle<JSObject> closure_scope =
   11641       isolate->factory()->NewJSObject(isolate->object_function());
   11642 
   11643   // Fill all context locals to the context extension.
   11644   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11645           scope_info, context, closure_scope)) {
   11646     return Handle<JSObject>();
   11647   }
   11648 
   11649   // Finally copy any properties from the function context extension. This will
   11650   // be variables introduced by eval.
   11651   if (context->has_extension()) {
   11652     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11653     bool threw = false;
   11654     Handle<FixedArray> keys =
   11655         GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
   11656     if (threw) return Handle<JSObject>();
   11657 
   11658     for (int i = 0; i < keys->length(); i++) {
   11659       // Names of variables introduced by eval are strings.
   11660       ASSERT(keys->get(i)->IsString());
   11661       Handle<String> key(String::cast(keys->get(i)));
   11662        RETURN_IF_EMPTY_HANDLE_VALUE(
   11663           isolate,
   11664           Runtime::SetObjectProperty(isolate, closure_scope, key,
   11665                                      GetProperty(isolate, ext, key),
   11666                                      NONE,
   11667                                      kNonStrictMode),
   11668           Handle<JSObject>());
   11669     }
   11670   }
   11671 
   11672   return closure_scope;
   11673 }
   11674 
   11675 
   11676 // This method copies structure of MaterializeClosure method above.
   11677 static bool SetClosureVariableValue(Isolate* isolate,
   11678                                     Handle<Context> context,
   11679                                     Handle<String> variable_name,
   11680                                     Handle<Object> new_value) {
   11681   ASSERT(context->IsFunctionContext());
   11682 
   11683   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11684   Handle<ScopeInfo> scope_info(shared->scope_info());
   11685 
   11686   // Context locals to the context extension.
   11687   if (SetContextLocalValue(
   11688           isolate, scope_info, context, variable_name, new_value)) {
   11689     return true;
   11690   }
   11691 
   11692   // Properties from the function context extension. This will
   11693   // be variables introduced by eval.
   11694   if (context->has_extension()) {
   11695     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11696     if (JSReceiver::HasProperty(ext, variable_name)) {
   11697       // We don't expect this to do anything except replacing property value.
   11698       Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
   11699                                  NONE,
   11700                                  kNonStrictMode);
   11701       return true;
   11702     }
   11703   }
   11704 
   11705   return false;
   11706 }
   11707 
   11708 
   11709 // Create a plain JSObject which materializes the scope for the specified
   11710 // catch context.
   11711 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
   11712                                               Handle<Context> context) {
   11713   ASSERT(context->IsCatchContext());
   11714   Handle<String> name(String::cast(context->extension()));
   11715   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
   11716                                isolate);
   11717   Handle<JSObject> catch_scope =
   11718       isolate->factory()->NewJSObject(isolate->object_function());
   11719   RETURN_IF_EMPTY_HANDLE_VALUE(
   11720       isolate,
   11721       Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
   11722                                  NONE,
   11723                                  kNonStrictMode),
   11724       Handle<JSObject>());
   11725   return catch_scope;
   11726 }
   11727 
   11728 
   11729 static bool SetCatchVariableValue(Isolate* isolate,
   11730                                   Handle<Context> context,
   11731                                   Handle<String> variable_name,
   11732                                   Handle<Object> new_value) {
   11733   ASSERT(context->IsCatchContext());
   11734   Handle<String> name(String::cast(context->extension()));
   11735   if (!name->Equals(*variable_name)) {
   11736     return false;
   11737   }
   11738   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
   11739   return true;
   11740 }
   11741 
   11742 
   11743 // Create a plain JSObject which materializes the block scope for the specified
   11744 // block context.
   11745 static Handle<JSObject> MaterializeBlockScope(
   11746     Isolate* isolate,
   11747     Handle<Context> context) {
   11748   ASSERT(context->IsBlockContext());
   11749   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11750 
   11751   // Allocate and initialize a JSObject with all the arguments, stack locals
   11752   // heap locals and extension properties of the debugged function.
   11753   Handle<JSObject> block_scope =
   11754       isolate->factory()->NewJSObject(isolate->object_function());
   11755 
   11756   // Fill all context locals.
   11757   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11758           scope_info, context, block_scope)) {
   11759     return Handle<JSObject>();
   11760   }
   11761 
   11762   return block_scope;
   11763 }
   11764 
   11765 
   11766 // Create a plain JSObject which materializes the module scope for the specified
   11767 // module context.
   11768 static Handle<JSObject> MaterializeModuleScope(
   11769     Isolate* isolate,
   11770     Handle<Context> context) {
   11771   ASSERT(context->IsModuleContext());
   11772   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11773 
   11774   // Allocate and initialize a JSObject with all the members of the debugged
   11775   // module.
   11776   Handle<JSObject> module_scope =
   11777       isolate->factory()->NewJSObject(isolate->object_function());
   11778 
   11779   // Fill all context locals.
   11780   if (!ScopeInfo::CopyContextLocalsToScopeObject(
   11781           scope_info, context, module_scope)) {
   11782     return Handle<JSObject>();
   11783   }
   11784 
   11785   return module_scope;
   11786 }
   11787 
   11788 
   11789 // Iterate over the actual scopes visible from a stack frame or from a closure.
   11790 // The iteration proceeds from the innermost visible nested scope outwards.
   11791 // All scopes are backed by an actual context except the local scope,
   11792 // which is inserted "artificially" in the context chain.
   11793 class ScopeIterator {
   11794  public:
   11795   enum ScopeType {
   11796     ScopeTypeGlobal = 0,
   11797     ScopeTypeLocal,
   11798     ScopeTypeWith,
   11799     ScopeTypeClosure,
   11800     ScopeTypeCatch,
   11801     ScopeTypeBlock,
   11802     ScopeTypeModule
   11803   };
   11804 
   11805   ScopeIterator(Isolate* isolate,
   11806                 JavaScriptFrame* frame,
   11807                 int inlined_jsframe_index)
   11808     : isolate_(isolate),
   11809       frame_(frame),
   11810       inlined_jsframe_index_(inlined_jsframe_index),
   11811       function_(frame->function()),
   11812       context_(Context::cast(frame->context())),
   11813       nested_scope_chain_(4),
   11814       failed_(false) {
   11815 
   11816     // Catch the case when the debugger stops in an internal function.
   11817     Handle<SharedFunctionInfo> shared_info(function_->shared());
   11818     Handle<ScopeInfo> scope_info(shared_info->scope_info());
   11819     if (shared_info->script() == isolate->heap()->undefined_value()) {
   11820       while (context_->closure() == *function_) {
   11821         context_ = Handle<Context>(context_->previous(), isolate_);
   11822       }
   11823       return;
   11824     }
   11825 
   11826     // Get the debug info (create it if it does not exist).
   11827     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
   11828       // Return if ensuring debug info failed.
   11829       return;
   11830     }
   11831     Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
   11832 
   11833     // Find the break point where execution has stopped.
   11834     BreakLocationIterator break_location_iterator(debug_info,
   11835                                                   ALL_BREAK_LOCATIONS);
   11836     // pc points to the instruction after the current one, possibly a break
   11837     // location as well. So the "- 1" to exclude it from the search.
   11838     break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   11839     if (break_location_iterator.IsExit()) {
   11840       // We are within the return sequence. At the momemt it is not possible to
   11841       // get a source position which is consistent with the current scope chain.
   11842       // Thus all nested with, catch and block contexts are skipped and we only
   11843       // provide the function scope.
   11844       if (scope_info->HasContext()) {
   11845         context_ = Handle<Context>(context_->declaration_context(), isolate_);
   11846       } else {
   11847         while (context_->closure() == *function_) {
   11848           context_ = Handle<Context>(context_->previous(), isolate_);
   11849         }
   11850       }
   11851       if (scope_info->scope_type() != EVAL_SCOPE) {
   11852         nested_scope_chain_.Add(scope_info);
   11853       }
   11854     } else {
   11855       // Reparse the code and analyze the scopes.
   11856       Handle<Script> script(Script::cast(shared_info->script()));
   11857       Scope* scope = NULL;
   11858 
   11859       // Check whether we are in global, eval or function code.
   11860       Handle<ScopeInfo> scope_info(shared_info->scope_info());
   11861       if (scope_info->scope_type() != FUNCTION_SCOPE) {
   11862         // Global or eval code.
   11863         CompilationInfoWithZone info(script);
   11864         if (scope_info->scope_type() == GLOBAL_SCOPE) {
   11865           info.MarkAsGlobal();
   11866         } else {
   11867           ASSERT(scope_info->scope_type() == EVAL_SCOPE);
   11868           info.MarkAsEval();
   11869           info.SetContext(Handle<Context>(function_->context()));
   11870         }
   11871         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   11872           scope = info.function()->scope();
   11873         }
   11874         RetrieveScopeChain(scope, shared_info);
   11875       } else {
   11876         // Function code
   11877         CompilationInfoWithZone info(shared_info);
   11878         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   11879           scope = info.function()->scope();
   11880         }
   11881         RetrieveScopeChain(scope, shared_info);
   11882       }
   11883     }
   11884   }
   11885 
   11886   ScopeIterator(Isolate* isolate,
   11887                 Handle<JSFunction> function)
   11888     : isolate_(isolate),
   11889       frame_(NULL),
   11890       inlined_jsframe_index_(0),
   11891       function_(function),
   11892       context_(function->context()),
   11893       failed_(false) {
   11894     if (function->IsBuiltin()) {
   11895       context_ = Handle<Context>();
   11896     }
   11897   }
   11898 
   11899   // More scopes?
   11900   bool Done() {
   11901     ASSERT(!failed_);
   11902     return context_.is_null();
   11903   }
   11904 
   11905   bool Failed() { return failed_; }
   11906 
   11907   // Move to the next scope.
   11908   void Next() {
   11909     ASSERT(!failed_);
   11910     ScopeType scope_type = Type();
   11911     if (scope_type == ScopeTypeGlobal) {
   11912       // The global scope is always the last in the chain.
   11913       ASSERT(context_->IsNativeContext());
   11914       context_ = Handle<Context>();
   11915       return;
   11916     }
   11917     if (nested_scope_chain_.is_empty()) {
   11918       context_ = Handle<Context>(context_->previous(), isolate_);
   11919     } else {
   11920       if (nested_scope_chain_.last()->HasContext()) {
   11921         ASSERT(context_->previous() != NULL);
   11922         context_ = Handle<Context>(context_->previous(), isolate_);
   11923       }
   11924       nested_scope_chain_.RemoveLast();
   11925     }
   11926   }
   11927 
   11928   // Return the type of the current scope.
   11929   ScopeType Type() {
   11930     ASSERT(!failed_);
   11931     if (!nested_scope_chain_.is_empty()) {
   11932       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
   11933       switch (scope_info->scope_type()) {
   11934         case FUNCTION_SCOPE:
   11935           ASSERT(context_->IsFunctionContext() ||
   11936                  !scope_info->HasContext());
   11937           return ScopeTypeLocal;
   11938         case MODULE_SCOPE:
   11939           ASSERT(context_->IsModuleContext());
   11940           return ScopeTypeModule;
   11941         case GLOBAL_SCOPE:
   11942           ASSERT(context_->IsNativeContext());
   11943           return ScopeTypeGlobal;
   11944         case WITH_SCOPE:
   11945           ASSERT(context_->IsWithContext());
   11946           return ScopeTypeWith;
   11947         case CATCH_SCOPE:
   11948           ASSERT(context_->IsCatchContext());
   11949           return ScopeTypeCatch;
   11950         case BLOCK_SCOPE:
   11951           ASSERT(!scope_info->HasContext() ||
   11952                  context_->IsBlockContext());
   11953           return ScopeTypeBlock;
   11954         case EVAL_SCOPE:
   11955           UNREACHABLE();
   11956       }
   11957     }
   11958     if (context_->IsNativeContext()) {
   11959       ASSERT(context_->global_object()->IsGlobalObject());
   11960       return ScopeTypeGlobal;
   11961     }
   11962     if (context_->IsFunctionContext()) {
   11963       return ScopeTypeClosure;
   11964     }
   11965     if (context_->IsCatchContext()) {
   11966       return ScopeTypeCatch;
   11967     }
   11968     if (context_->IsBlockContext()) {
   11969       return ScopeTypeBlock;
   11970     }
   11971     if (context_->IsModuleContext()) {
   11972       return ScopeTypeModule;
   11973     }
   11974     ASSERT(context_->IsWithContext());
   11975     return ScopeTypeWith;
   11976   }
   11977 
   11978   // Return the JavaScript object with the content of the current scope.
   11979   Handle<JSObject> ScopeObject() {
   11980     ASSERT(!failed_);
   11981     switch (Type()) {
   11982       case ScopeIterator::ScopeTypeGlobal:
   11983         return Handle<JSObject>(CurrentContext()->global_object());
   11984       case ScopeIterator::ScopeTypeLocal:
   11985         // Materialize the content of the local scope into a JSObject.
   11986         ASSERT(nested_scope_chain_.length() == 1);
   11987         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
   11988       case ScopeIterator::ScopeTypeWith:
   11989         // Return the with object.
   11990         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
   11991       case ScopeIterator::ScopeTypeCatch:
   11992         return MaterializeCatchScope(isolate_, CurrentContext());
   11993       case ScopeIterator::ScopeTypeClosure:
   11994         // Materialize the content of the closure scope into a JSObject.
   11995         return MaterializeClosure(isolate_, CurrentContext());
   11996       case ScopeIterator::ScopeTypeBlock:
   11997         return MaterializeBlockScope(isolate_, CurrentContext());
   11998       case ScopeIterator::ScopeTypeModule:
   11999         return MaterializeModuleScope(isolate_, CurrentContext());
   12000     }
   12001     UNREACHABLE();
   12002     return Handle<JSObject>();
   12003   }
   12004 
   12005   bool SetVariableValue(Handle<String> variable_name,
   12006                         Handle<Object> new_value) {
   12007     ASSERT(!failed_);
   12008     switch (Type()) {
   12009       case ScopeIterator::ScopeTypeGlobal:
   12010         break;
   12011       case ScopeIterator::ScopeTypeLocal:
   12012         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
   12013             variable_name, new_value);
   12014       case ScopeIterator::ScopeTypeWith:
   12015         break;
   12016       case ScopeIterator::ScopeTypeCatch:
   12017         return SetCatchVariableValue(isolate_, CurrentContext(),
   12018             variable_name, new_value);
   12019       case ScopeIterator::ScopeTypeClosure:
   12020         return SetClosureVariableValue(isolate_, CurrentContext(),
   12021             variable_name, new_value);
   12022       case ScopeIterator::ScopeTypeBlock:
   12023         // TODO(2399): should we implement it?
   12024         break;
   12025       case ScopeIterator::ScopeTypeModule:
   12026         // TODO(2399): should we implement it?
   12027         break;
   12028     }
   12029     return false;
   12030   }
   12031 
   12032   Handle<ScopeInfo> CurrentScopeInfo() {
   12033     ASSERT(!failed_);
   12034     if (!nested_scope_chain_.is_empty()) {
   12035       return nested_scope_chain_.last();
   12036     } else if (context_->IsBlockContext()) {
   12037       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
   12038     } else if (context_->IsFunctionContext()) {
   12039       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
   12040     }
   12041     return Handle<ScopeInfo>::null();
   12042   }
   12043 
   12044   // Return the context for this scope. For the local context there might not
   12045   // be an actual context.
   12046   Handle<Context> CurrentContext() {
   12047     ASSERT(!failed_);
   12048     if (Type() == ScopeTypeGlobal ||
   12049         nested_scope_chain_.is_empty()) {
   12050       return context_;
   12051     } else if (nested_scope_chain_.last()->HasContext()) {
   12052       return context_;
   12053     } else {
   12054       return Handle<Context>();
   12055     }
   12056   }
   12057 
   12058 #ifdef DEBUG
   12059   // Debug print of the content of the current scope.
   12060   void DebugPrint() {
   12061     ASSERT(!failed_);
   12062     switch (Type()) {
   12063       case ScopeIterator::ScopeTypeGlobal:
   12064         PrintF("Global:\n");
   12065         CurrentContext()->Print();
   12066         break;
   12067 
   12068       case ScopeIterator::ScopeTypeLocal: {
   12069         PrintF("Local:\n");
   12070         function_->shared()->scope_info()->Print();
   12071         if (!CurrentContext().is_null()) {
   12072           CurrentContext()->Print();
   12073           if (CurrentContext()->has_extension()) {
   12074             Handle<Object> extension(CurrentContext()->extension(), isolate_);
   12075             if (extension->IsJSContextExtensionObject()) {
   12076               extension->Print();
   12077             }
   12078           }
   12079         }
   12080         break;
   12081       }
   12082 
   12083       case ScopeIterator::ScopeTypeWith:
   12084         PrintF("With:\n");
   12085         CurrentContext()->extension()->Print();
   12086         break;
   12087 
   12088       case ScopeIterator::ScopeTypeCatch:
   12089         PrintF("Catch:\n");
   12090         CurrentContext()->extension()->Print();
   12091         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
   12092         break;
   12093 
   12094       case ScopeIterator::ScopeTypeClosure:
   12095         PrintF("Closure:\n");
   12096         CurrentContext()->Print();
   12097         if (CurrentContext()->has_extension()) {
   12098           Handle<Object> extension(CurrentContext()->extension(), isolate_);
   12099           if (extension->IsJSContextExtensionObject()) {
   12100             extension->Print();
   12101           }
   12102         }
   12103         break;
   12104 
   12105       default:
   12106         UNREACHABLE();
   12107     }
   12108     PrintF("\n");
   12109   }
   12110 #endif
   12111 
   12112  private:
   12113   Isolate* isolate_;
   12114   JavaScriptFrame* frame_;
   12115   int inlined_jsframe_index_;
   12116   Handle<JSFunction> function_;
   12117   Handle<Context> context_;
   12118   List<Handle<ScopeInfo> > nested_scope_chain_;
   12119   bool failed_;
   12120 
   12121   void RetrieveScopeChain(Scope* scope,
   12122                           Handle<SharedFunctionInfo> shared_info) {
   12123     if (scope != NULL) {
   12124       int source_position = shared_info->code()->SourcePosition(frame_->pc());
   12125       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
   12126     } else {
   12127       // A failed reparse indicates that the preparser has diverged from the
   12128       // parser or that the preparse data given to the initial parse has been
   12129       // faulty. We fail in debug mode but in release mode we only provide the
   12130       // information we get from the context chain but nothing about
   12131       // completely stack allocated scopes or stack allocated locals.
   12132       // Or it could be due to stack overflow.
   12133       ASSERT(isolate_->has_pending_exception());
   12134       failed_ = true;
   12135     }
   12136   }
   12137 
   12138   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
   12139 };
   12140 
   12141 
   12142 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
   12143   HandleScope scope(isolate);
   12144   ASSERT(args.length() == 2);
   12145 
   12146   // Check arguments.
   12147   Object* check;
   12148   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12149       RUNTIME_ARGUMENTS(isolate, args));
   12150     if (!maybe_check->ToObject(&check)) return maybe_check;
   12151   }
   12152   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12153 
   12154   // Get the frame where the debugging is performed.
   12155   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12156   JavaScriptFrameIterator it(isolate, id);
   12157   JavaScriptFrame* frame = it.frame();
   12158 
   12159   // Count the visible scopes.
   12160   int n = 0;
   12161   for (ScopeIterator it(isolate, frame, 0);
   12162        !it.Done();
   12163        it.Next()) {
   12164     n++;
   12165   }
   12166 
   12167   return Smi::FromInt(n);
   12168 }
   12169 
   12170 
   12171 // Returns the list of step-in positions (text offset) in a function of the
   12172 // stack frame in a range from the current debug break position to the end
   12173 // of the corresponding statement.
   12174 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
   12175   HandleScope scope(isolate);
   12176   ASSERT(args.length() == 2);
   12177 
   12178   // Check arguments.
   12179   Object* check;
   12180   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12181       RUNTIME_ARGUMENTS(isolate, args));
   12182     if (!maybe_check->ToObject(&check)) return maybe_check;
   12183   }
   12184   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12185 
   12186   // Get the frame where the debugging is performed.
   12187   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12188   JavaScriptFrameIterator frame_it(isolate, id);
   12189   RUNTIME_ASSERT(!frame_it.done());
   12190 
   12191   JavaScriptFrame* frame = frame_it.frame();
   12192 
   12193   Handle<JSFunction> fun =
   12194       Handle<JSFunction>(frame->function());
   12195   Handle<SharedFunctionInfo> shared =
   12196       Handle<SharedFunctionInfo>(fun->shared());
   12197 
   12198   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
   12199     return isolate->heap()->undefined_value();
   12200   }
   12201 
   12202   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
   12203 
   12204   int len = 0;
   12205   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
   12206   // Find the break point where execution has stopped.
   12207   BreakLocationIterator break_location_iterator(debug_info,
   12208                                                 ALL_BREAK_LOCATIONS);
   12209 
   12210   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   12211   int current_statement_pos = break_location_iterator.statement_position();
   12212 
   12213   while (!break_location_iterator.Done()) {
   12214     bool accept;
   12215     if (break_location_iterator.pc() > frame->pc()) {
   12216       accept = true;
   12217     } else {
   12218       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
   12219       // The break point is near our pc. Could be a step-in possibility,
   12220       // that is currently taken by active debugger call.
   12221       if (break_frame_id == StackFrame::NO_ID) {
   12222         // We are not stepping.
   12223         accept = false;
   12224       } else {
   12225         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
   12226         // If our frame is a top frame and we are stepping, we can do step-in
   12227         // at this place.
   12228         accept = additional_frame_it.frame()->id() == id;
   12229       }
   12230     }
   12231     if (accept) {
   12232       if (break_location_iterator.IsStepInLocation(isolate)) {
   12233         Smi* position_value = Smi::FromInt(break_location_iterator.position());
   12234         JSObject::SetElement(array, len,
   12235             Handle<Object>(position_value, isolate),
   12236             NONE, kNonStrictMode);
   12237         len++;
   12238       }
   12239     }
   12240     // Advance iterator.
   12241     break_location_iterator.Next();
   12242     if (current_statement_pos !=
   12243         break_location_iterator.statement_position()) {
   12244       break;
   12245     }
   12246   }
   12247   return *array;
   12248 }
   12249 
   12250 
   12251 static const int kScopeDetailsTypeIndex = 0;
   12252 static const int kScopeDetailsObjectIndex = 1;
   12253 static const int kScopeDetailsSize = 2;
   12254 
   12255 
   12256 static MaybeObject* MaterializeScopeDetails(Isolate* isolate,
   12257     ScopeIterator* it) {
   12258   // Calculate the size of the result.
   12259   int details_size = kScopeDetailsSize;
   12260   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   12261 
   12262   // Fill in scope details.
   12263   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
   12264   Handle<JSObject> scope_object = it->ScopeObject();
   12265   RETURN_IF_EMPTY_HANDLE(isolate, scope_object);
   12266   details->set(kScopeDetailsObjectIndex, *scope_object);
   12267 
   12268   return *isolate->factory()->NewJSArrayWithElements(details);
   12269 }
   12270 
   12271 
   12272 // Return an array with scope details
   12273 // args[0]: number: break id
   12274 // args[1]: number: frame index
   12275 // args[2]: number: inlined frame index
   12276 // args[3]: number: scope index
   12277 //
   12278 // The array returned contains the following information:
   12279 // 0: Scope type
   12280 // 1: Scope object
   12281 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
   12282   HandleScope scope(isolate);
   12283   ASSERT(args.length() == 4);
   12284 
   12285   // Check arguments.
   12286   Object* check;
   12287   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12288       RUNTIME_ARGUMENTS(isolate, args));
   12289     if (!maybe_check->ToObject(&check)) return maybe_check;
   12290   }
   12291   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12292   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12293   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12294 
   12295   // Get the frame where the debugging is performed.
   12296   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12297   JavaScriptFrameIterator frame_it(isolate, id);
   12298   JavaScriptFrame* frame = frame_it.frame();
   12299 
   12300   // Find the requested scope.
   12301   int n = 0;
   12302   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12303   for (; !it.Done() && n < index; it.Next()) {
   12304     n++;
   12305   }
   12306   if (it.Done()) {
   12307     return isolate->heap()->undefined_value();
   12308   }
   12309   return MaterializeScopeDetails(isolate, &it);
   12310 }
   12311 
   12312 
   12313 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
   12314   HandleScope scope(isolate);
   12315   ASSERT(args.length() == 1);
   12316 
   12317   // Check arguments.
   12318   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12319 
   12320   // Count the visible scopes.
   12321   int n = 0;
   12322   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
   12323     n++;
   12324   }
   12325 
   12326   return Smi::FromInt(n);
   12327 }
   12328 
   12329 
   12330 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) {
   12331   HandleScope scope(isolate);
   12332   ASSERT(args.length() == 2);
   12333 
   12334   // Check arguments.
   12335   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12336   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12337 
   12338   // Find the requested scope.
   12339   int n = 0;
   12340   ScopeIterator it(isolate, fun);
   12341   for (; !it.Done() && n < index; it.Next()) {
   12342     n++;
   12343   }
   12344   if (it.Done()) {
   12345     return isolate->heap()->undefined_value();
   12346   }
   12347 
   12348   return MaterializeScopeDetails(isolate, &it);
   12349 }
   12350 
   12351 
   12352 static bool SetScopeVariableValue(ScopeIterator* it, int index,
   12353                                   Handle<String> variable_name,
   12354                                   Handle<Object> new_value) {
   12355   for (int n = 0; !it->Done() && n < index; it->Next()) {
   12356     n++;
   12357   }
   12358   if (it->Done()) {
   12359     return false;
   12360   }
   12361   return it->SetVariableValue(variable_name, new_value);
   12362 }
   12363 
   12364 
   12365 // Change variable value in closure or local scope
   12366 // args[0]: number or JsFunction: break id or function
   12367 // args[1]: number: frame index (when arg[0] is break id)
   12368 // args[2]: number: inlined frame index (when arg[0] is break id)
   12369 // args[3]: number: scope index
   12370 // args[4]: string: variable name
   12371 // args[5]: object: new value
   12372 //
   12373 // Return true if success and false otherwise
   12374 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) {
   12375   HandleScope scope(isolate);
   12376   ASSERT(args.length() == 6);
   12377 
   12378   // Check arguments.
   12379   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12380   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
   12381   Handle<Object> new_value = args.at<Object>(5);
   12382 
   12383   bool res;
   12384   if (args[0]->IsNumber()) {
   12385     Object* check;
   12386     { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12387         RUNTIME_ARGUMENTS(isolate, args));
   12388       if (!maybe_check->ToObject(&check)) return maybe_check;
   12389     }
   12390     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12391     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12392 
   12393     // Get the frame where the debugging is performed.
   12394     StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12395     JavaScriptFrameIterator frame_it(isolate, id);
   12396     JavaScriptFrame* frame = frame_it.frame();
   12397 
   12398     ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12399     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12400   } else {
   12401     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12402     ScopeIterator it(isolate, fun);
   12403     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12404   }
   12405 
   12406   return isolate->heap()->ToBoolean(res);
   12407 }
   12408 
   12409 
   12410 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
   12411   HandleScope scope(isolate);
   12412   ASSERT(args.length() == 0);
   12413 
   12414 #ifdef DEBUG
   12415   // Print the scopes for the top frame.
   12416   StackFrameLocator locator(isolate);
   12417   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
   12418   for (ScopeIterator it(isolate, frame, 0);
   12419        !it.Done();
   12420        it.Next()) {
   12421     it.DebugPrint();
   12422   }
   12423 #endif
   12424   return isolate->heap()->undefined_value();
   12425 }
   12426 
   12427 
   12428 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
   12429   HandleScope scope(isolate);
   12430   ASSERT(args.length() == 1);
   12431 
   12432   // Check arguments.
   12433   Object* result;
   12434   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   12435       RUNTIME_ARGUMENTS(isolate, args));
   12436     if (!maybe_result->ToObject(&result)) return maybe_result;
   12437   }
   12438 
   12439   // Count all archived V8 threads.
   12440   int n = 0;
   12441   for (ThreadState* thread =
   12442           isolate->thread_manager()->FirstThreadStateInUse();
   12443        thread != NULL;
   12444        thread = thread->Next()) {
   12445     n++;
   12446   }
   12447 
   12448   // Total number of threads is current thread and archived threads.
   12449   return Smi::FromInt(n + 1);
   12450 }
   12451 
   12452 
   12453 static const int kThreadDetailsCurrentThreadIndex = 0;
   12454 static const int kThreadDetailsThreadIdIndex = 1;
   12455 static const int kThreadDetailsSize = 2;
   12456 
   12457 // Return an array with thread details
   12458 // args[0]: number: break id
   12459 // args[1]: number: thread index
   12460 //
   12461 // The array returned contains the following information:
   12462 // 0: Is current thread?
   12463 // 1: Thread id
   12464 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
   12465   HandleScope scope(isolate);
   12466   ASSERT(args.length() == 2);
   12467 
   12468   // Check arguments.
   12469   Object* check;
   12470   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12471       RUNTIME_ARGUMENTS(isolate, args));
   12472     if (!maybe_check->ToObject(&check)) return maybe_check;
   12473   }
   12474   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12475 
   12476   // Allocate array for result.
   12477   Handle<FixedArray> details =
   12478       isolate->factory()->NewFixedArray(kThreadDetailsSize);
   12479 
   12480   // Thread index 0 is current thread.
   12481   if (index == 0) {
   12482     // Fill the details.
   12483     details->set(kThreadDetailsCurrentThreadIndex,
   12484                  isolate->heap()->true_value());
   12485     details->set(kThreadDetailsThreadIdIndex,
   12486                  Smi::FromInt(ThreadId::Current().ToInteger()));
   12487   } else {
   12488     // Find the thread with the requested index.
   12489     int n = 1;
   12490     ThreadState* thread =
   12491         isolate->thread_manager()->FirstThreadStateInUse();
   12492     while (index != n && thread != NULL) {
   12493       thread = thread->Next();
   12494       n++;
   12495     }
   12496     if (thread == NULL) {
   12497       return isolate->heap()->undefined_value();
   12498     }
   12499 
   12500     // Fill the details.
   12501     details->set(kThreadDetailsCurrentThreadIndex,
   12502                  isolate->heap()->false_value());
   12503     details->set(kThreadDetailsThreadIdIndex,
   12504                  Smi::FromInt(thread->id().ToInteger()));
   12505   }
   12506 
   12507   // Convert to JS array and return.
   12508   return *isolate->factory()->NewJSArrayWithElements(details);
   12509 }
   12510 
   12511 
   12512 // Sets the disable break state
   12513 // args[0]: disable break state
   12514 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDisableBreak) {
   12515   HandleScope scope(isolate);
   12516   ASSERT(args.length() == 1);
   12517   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
   12518   isolate->debug()->set_disable_break(disable_break);
   12519   return  isolate->heap()->undefined_value();
   12520 }
   12521 
   12522 
   12523 static bool IsPositionAlignmentCodeCorrect(int alignment) {
   12524   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
   12525 }
   12526 
   12527 
   12528 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
   12529   HandleScope scope(isolate);
   12530   ASSERT(args.length() == 2);
   12531 
   12532   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12533   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
   12534 
   12535   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12536     return isolate->ThrowIllegalOperation();
   12537   }
   12538   BreakPositionAlignment alignment =
   12539       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12540 
   12541   Handle<SharedFunctionInfo> shared(fun->shared());
   12542   // Find the number of break points
   12543   Handle<Object> break_locations =
   12544       Debug::GetSourceBreakLocations(shared, alignment);
   12545   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   12546   // Return array as JS array
   12547   return *isolate->factory()->NewJSArrayWithElements(
   12548       Handle<FixedArray>::cast(break_locations));
   12549 }
   12550 
   12551 
   12552 // Set a break point in a function.
   12553 // args[0]: function
   12554 // args[1]: number: break source position (within the function source)
   12555 // args[2]: number: break point object
   12556 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
   12557   HandleScope scope(isolate);
   12558   ASSERT(args.length() == 3);
   12559   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   12560   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12561   RUNTIME_ASSERT(source_position >= 0);
   12562   Handle<Object> break_point_object_arg = args.at<Object>(2);
   12563 
   12564   // Set break point.
   12565   isolate->debug()->SetBreakPoint(function, break_point_object_arg,
   12566                                   &source_position);
   12567 
   12568   return Smi::FromInt(source_position);
   12569 }
   12570 
   12571 
   12572 // Changes the state of a break point in a script and returns source position
   12573 // where break point was set. NOTE: Regarding performance see the NOTE for
   12574 // GetScriptFromScriptData.
   12575 // args[0]: script to set break point in
   12576 // args[1]: number: break source position (within the script source)
   12577 // args[2]: number, breakpoint position alignment
   12578 // args[3]: number: break point object
   12579 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
   12580   HandleScope scope(isolate);
   12581   ASSERT(args.length() == 4);
   12582   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   12583   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12584   RUNTIME_ASSERT(source_position >= 0);
   12585   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
   12586   Handle<Object> break_point_object_arg = args.at<Object>(3);
   12587 
   12588   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12589     return isolate->ThrowIllegalOperation();
   12590   }
   12591   BreakPositionAlignment alignment =
   12592       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12593 
   12594   // Get the script from the script wrapper.
   12595   RUNTIME_ASSERT(wrapper->value()->IsScript());
   12596   Handle<Script> script(Script::cast(wrapper->value()));
   12597 
   12598   // Set break point.
   12599   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
   12600                                                 &source_position,
   12601                                                 alignment)) {
   12602     return  isolate->heap()->undefined_value();
   12603   }
   12604 
   12605   return Smi::FromInt(source_position);
   12606 }
   12607 
   12608 
   12609 // Clear a break point
   12610 // args[0]: number: break point object
   12611 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
   12612   HandleScope scope(isolate);
   12613   ASSERT(args.length() == 1);
   12614   Handle<Object> break_point_object_arg = args.at<Object>(0);
   12615 
   12616   // Clear break point.
   12617   isolate->debug()->ClearBreakPoint(break_point_object_arg);
   12618 
   12619   return isolate->heap()->undefined_value();
   12620 }
   12621 
   12622 
   12623 // Change the state of break on exceptions.
   12624 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
   12625 // args[1]: Boolean indicating on/off.
   12626 RUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
   12627   HandleScope scope(isolate);
   12628   ASSERT(args.length() == 2);
   12629   RUNTIME_ASSERT(args[0]->IsNumber());
   12630   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
   12631 
   12632   // If the number doesn't match an enum value, the ChangeBreakOnException
   12633   // function will default to affecting caught exceptions.
   12634   ExceptionBreakType type =
   12635       static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
   12636   // Update break point state.
   12637   isolate->debug()->ChangeBreakOnException(type, enable);
   12638   return isolate->heap()->undefined_value();
   12639 }
   12640 
   12641 
   12642 // Returns the state of break on exceptions
   12643 // args[0]: boolean indicating uncaught exceptions
   12644 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
   12645   HandleScope scope(isolate);
   12646   ASSERT(args.length() == 1);
   12647   RUNTIME_ASSERT(args[0]->IsNumber());
   12648 
   12649   ExceptionBreakType type =
   12650       static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
   12651   bool result = isolate->debug()->IsBreakOnException(type);
   12652   return Smi::FromInt(result);
   12653 }
   12654 
   12655 
   12656 // Prepare for stepping
   12657 // args[0]: break id for checking execution state
   12658 // args[1]: step action from the enumeration StepAction
   12659 // args[2]: number of times to perform the step, for step out it is the number
   12660 //          of frames to step down.
   12661 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
   12662   HandleScope scope(isolate);
   12663   ASSERT(args.length() == 4);
   12664   // Check arguments.
   12665   Object* check;
   12666   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12667       RUNTIME_ARGUMENTS(isolate, args));
   12668     if (!maybe_check->ToObject(&check)) return maybe_check;
   12669   }
   12670   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
   12671     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12672   }
   12673 
   12674   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
   12675 
   12676   StackFrame::Id frame_id;
   12677   if (wrapped_frame_id == 0) {
   12678     frame_id = StackFrame::NO_ID;
   12679   } else {
   12680     frame_id = UnwrapFrameId(wrapped_frame_id);
   12681   }
   12682 
   12683   // Get the step action and check validity.
   12684   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   12685   if (step_action != StepIn &&
   12686       step_action != StepNext &&
   12687       step_action != StepOut &&
   12688       step_action != StepInMin &&
   12689       step_action != StepMin) {
   12690     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12691   }
   12692 
   12693   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
   12694       step_action != StepMin && step_action != StepOut) {
   12695     return isolate->ThrowIllegalOperation();
   12696   }
   12697 
   12698   // Get the number of steps.
   12699   int step_count = NumberToInt32(args[2]);
   12700   if (step_count < 1) {
   12701     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12702   }
   12703 
   12704   // Clear all current stepping setup.
   12705   isolate->debug()->ClearStepping();
   12706 
   12707   // Prepare step.
   12708   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
   12709                                 step_count,
   12710                                 frame_id);
   12711   return isolate->heap()->undefined_value();
   12712 }
   12713 
   12714 
   12715 // Clear all stepping set by PrepareStep.
   12716 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
   12717   HandleScope scope(isolate);
   12718   ASSERT(args.length() == 0);
   12719   isolate->debug()->ClearStepping();
   12720   return isolate->heap()->undefined_value();
   12721 }
   12722 
   12723 
   12724 // Helper function to find or create the arguments object for
   12725 // Runtime_DebugEvaluate.
   12726 static Handle<JSObject> MaterializeArgumentsObject(
   12727     Isolate* isolate,
   12728     Handle<JSObject> target,
   12729     Handle<JSFunction> function) {
   12730   // Do not materialize the arguments object for eval or top-level code.
   12731   // Skip if "arguments" is already taken.
   12732   if (!function->shared()->is_function() ||
   12733       JSReceiver::HasLocalProperty(target,
   12734                                    isolate->factory()->arguments_string())) {
   12735     return target;
   12736   }
   12737 
   12738   // FunctionGetArguments can't throw an exception.
   12739   Handle<JSObject> arguments = Handle<JSObject>::cast(
   12740       Accessors::FunctionGetArguments(function));
   12741   Runtime::SetObjectProperty(isolate, target,
   12742                              isolate->factory()->arguments_string(),
   12743                              arguments,
   12744                              ::NONE,
   12745                              kNonStrictMode);
   12746   return target;
   12747 }
   12748 
   12749 
   12750 // Compile and evaluate source for the given context.
   12751 static MaybeObject* DebugEvaluate(Isolate* isolate,
   12752                                   Handle<Context> context,
   12753                                   Handle<Object> context_extension,
   12754                                   Handle<Object> receiver,
   12755                                   Handle<String> source) {
   12756   if (context_extension->IsJSObject()) {
   12757     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
   12758     Handle<JSFunction> closure(context->closure(), isolate);
   12759     context = isolate->factory()->NewWithContext(closure, context, extension);
   12760   }
   12761 
   12762   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   12763       source,
   12764       context,
   12765       context->IsNativeContext(),
   12766       CLASSIC_MODE,
   12767       NO_PARSE_RESTRICTION,
   12768       RelocInfo::kNoPosition);
   12769   RETURN_IF_EMPTY_HANDLE(isolate, shared);
   12770 
   12771   Handle<JSFunction> eval_fun =
   12772       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   12773           shared, context, NOT_TENURED);
   12774   bool pending_exception;
   12775   Handle<Object> result = Execution::Call(
   12776       isolate, eval_fun, receiver, 0, NULL, &pending_exception);
   12777 
   12778   if (pending_exception) return Failure::Exception();
   12779 
   12780   // Skip the global proxy as it has no properties and always delegates to the
   12781   // real global object.
   12782   if (result->IsJSGlobalProxy()) {
   12783     result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
   12784   }
   12785 
   12786   // Clear the oneshot breakpoints so that the debugger does not step further.
   12787   isolate->debug()->ClearStepping();
   12788   return *result;
   12789 }
   12790 
   12791 
   12792 // Evaluate a piece of JavaScript in the context of a stack frame for
   12793 // debugging.  Things that need special attention are:
   12794 // - Parameters and stack-allocated locals need to be materialized.  Altered
   12795 //   values need to be written back to the stack afterwards.
   12796 // - The arguments object needs to materialized.
   12797 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   12798   HandleScope scope(isolate);
   12799 
   12800   // Check the execution state and decode arguments frame and source to be
   12801   // evaluated.
   12802   ASSERT(args.length() == 6);
   12803   Object* check_result;
   12804   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   12805       RUNTIME_ARGUMENTS(isolate, args));
   12806     if (!maybe_result->ToObject(&check_result)) return maybe_result;
   12807   }
   12808   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12809   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12810   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
   12811   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
   12812   Handle<Object> context_extension(args[5], isolate);
   12813 
   12814   // Handle the processing of break.
   12815   DisableBreak disable_break_save(isolate, disable_break);
   12816 
   12817   // Get the frame where the debugging is performed.
   12818   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12819   JavaScriptFrameIterator it(isolate, id);
   12820   JavaScriptFrame* frame = it.frame();
   12821   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   12822   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   12823 
   12824   // Traverse the saved contexts chain to find the active context for the
   12825   // selected frame.
   12826   SaveContext* save = FindSavedContextForFrame(isolate, frame);
   12827 
   12828   SaveContext savex(isolate);
   12829   isolate->set_context(*(save->context()));
   12830 
   12831   // Evaluate on the context of the frame.
   12832   Handle<Context> context(Context::cast(frame->context()));
   12833   ASSERT(!context.is_null());
   12834 
   12835   // Materialize stack locals and the arguments object.
   12836   Handle<JSObject> materialized =
   12837       isolate->factory()->NewJSObject(isolate->object_function());
   12838 
   12839   materialized = MaterializeStackLocalsWithFrameInspector(
   12840       isolate, materialized, function, &frame_inspector);
   12841   RETURN_IF_EMPTY_HANDLE(isolate, materialized);
   12842 
   12843   materialized = MaterializeArgumentsObject(isolate, materialized, function);
   12844   RETURN_IF_EMPTY_HANDLE(isolate, materialized);
   12845 
   12846   // Add the materialized object in a with-scope to shadow the stack locals.
   12847   context = isolate->factory()->NewWithContext(function, context, materialized);
   12848 
   12849   Handle<Object> receiver(frame->receiver(), isolate);
   12850   Object* evaluate_result_object;
   12851   { MaybeObject* maybe_result =
   12852     DebugEvaluate(isolate, context, context_extension, receiver, source);
   12853     if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result;
   12854   }
   12855 
   12856   Handle<Object> result(evaluate_result_object, isolate);
   12857 
   12858   // Write back potential changes to materialized stack locals to the stack.
   12859   UpdateStackLocalsFromMaterializedObject(
   12860       isolate, materialized, function, frame, inlined_jsframe_index);
   12861 
   12862   return *result;
   12863 }
   12864 
   12865 
   12866 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
   12867   HandleScope scope(isolate);
   12868 
   12869   // Check the execution state and decode arguments frame and source to be
   12870   // evaluated.
   12871   ASSERT(args.length() == 4);
   12872   Object* check_result;
   12873   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   12874       RUNTIME_ARGUMENTS(isolate, args));
   12875     if (!maybe_result->ToObject(&check_result)) return maybe_result;
   12876   }
   12877   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   12878   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
   12879   Handle<Object> context_extension(args[3], isolate);
   12880 
   12881   // Handle the processing of break.
   12882   DisableBreak disable_break_save(isolate, disable_break);
   12883 
   12884   // Enter the top context from before the debugger was invoked.
   12885   SaveContext save(isolate);
   12886   SaveContext* top = &save;
   12887   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
   12888     top = top->prev();
   12889   }
   12890   if (top != NULL) {
   12891     isolate->set_context(*top->context());
   12892   }
   12893 
   12894   // Get the native context now set to the top context from before the
   12895   // debugger was invoked.
   12896   Handle<Context> context = isolate->native_context();
   12897   Handle<Object> receiver = isolate->global_object();
   12898   return DebugEvaluate(isolate, context, context_extension, receiver, source);
   12899 }
   12900 
   12901 
   12902 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
   12903   HandleScope scope(isolate);
   12904   ASSERT(args.length() == 0);
   12905 
   12906   // Fill the script objects.
   12907   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
   12908 
   12909   // Convert the script objects to proper JS objects.
   12910   for (int i = 0; i < instances->length(); i++) {
   12911     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
   12912     // Get the script wrapper in a local handle before calling GetScriptWrapper,
   12913     // because using
   12914     //   instances->set(i, *GetScriptWrapper(script))
   12915     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
   12916     // already have dereferenced the instances handle.
   12917     Handle<JSValue> wrapper = GetScriptWrapper(script);
   12918     instances->set(i, *wrapper);
   12919   }
   12920 
   12921   // Return result as a JS array.
   12922   Handle<JSObject> result =
   12923       isolate->factory()->NewJSObject(isolate->array_function());
   12924   isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
   12925   return *result;
   12926 }
   12927 
   12928 
   12929 // Helper function used by Runtime_DebugReferencedBy below.
   12930 static int DebugReferencedBy(HeapIterator* iterator,
   12931                              JSObject* target,
   12932                              Object* instance_filter, int max_references,
   12933                              FixedArray* instances, int instances_size,
   12934                              JSFunction* arguments_function) {
   12935   Isolate* isolate = target->GetIsolate();
   12936   SealHandleScope shs(isolate);
   12937   DisallowHeapAllocation no_allocation;
   12938 
   12939   // Iterate the heap.
   12940   int count = 0;
   12941   JSObject* last = NULL;
   12942   HeapObject* heap_obj = NULL;
   12943   while (((heap_obj = iterator->next()) != NULL) &&
   12944          (max_references == 0 || count < max_references)) {
   12945     // Only look at all JSObjects.
   12946     if (heap_obj->IsJSObject()) {
   12947       // Skip context extension objects and argument arrays as these are
   12948       // checked in the context of functions using them.
   12949       JSObject* obj = JSObject::cast(heap_obj);
   12950       if (obj->IsJSContextExtensionObject() ||
   12951           obj->map()->constructor() == arguments_function) {
   12952         continue;
   12953       }
   12954 
   12955       // Check if the JS object has a reference to the object looked for.
   12956       if (obj->ReferencesObject(target)) {
   12957         // Check instance filter if supplied. This is normally used to avoid
   12958         // references from mirror objects (see Runtime_IsInPrototypeChain).
   12959         if (!instance_filter->IsUndefined()) {
   12960           Object* V = obj;
   12961           while (true) {
   12962             Object* prototype = V->GetPrototype(isolate);
   12963             if (prototype->IsNull()) {
   12964               break;
   12965             }
   12966             if (instance_filter == prototype) {
   12967               obj = NULL;  // Don't add this object.
   12968               break;
   12969             }
   12970             V = prototype;
   12971           }
   12972         }
   12973 
   12974         if (obj != NULL) {
   12975           // Valid reference found add to instance array if supplied an update
   12976           // count.
   12977           if (instances != NULL && count < instances_size) {
   12978             instances->set(count, obj);
   12979           }
   12980           last = obj;
   12981           count++;
   12982         }
   12983       }
   12984     }
   12985   }
   12986 
   12987   // Check for circular reference only. This can happen when the object is only
   12988   // referenced from mirrors and has a circular reference in which case the
   12989   // object is not really alive and would have been garbage collected if not
   12990   // referenced from the mirror.
   12991   if (count == 1 && last == target) {
   12992     count = 0;
   12993   }
   12994 
   12995   // Return the number of referencing objects found.
   12996   return count;
   12997 }
   12998 
   12999 
   13000 // Scan the heap for objects with direct references to an object
   13001 // args[0]: the object to find references to
   13002 // args[1]: constructor function for instances to exclude (Mirror)
   13003 // args[2]: the the maximum number of objects to return
   13004 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
   13005   SealHandleScope shs(isolate);
   13006   ASSERT(args.length() == 3);
   13007 
   13008   // First perform a full GC in order to avoid references from dead objects.
   13009   isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
   13010                                      "%DebugReferencedBy");
   13011   // The heap iterator reserves the right to do a GC to make the heap iterable.
   13012   // Due to the GC above we know it won't need to do that, but it seems cleaner
   13013   // to get the heap iterator constructed before we start having unprotected
   13014   // Object* locals that are not protected by handles.
   13015 
   13016   // Check parameters.
   13017   CONVERT_ARG_CHECKED(JSObject, target, 0);
   13018   Object* instance_filter = args[1];
   13019   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
   13020                  instance_filter->IsJSObject());
   13021   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
   13022   RUNTIME_ASSERT(max_references >= 0);
   13023 
   13024 
   13025   // Get the constructor function for context extension and arguments array.
   13026   JSObject* arguments_boilerplate =
   13027       isolate->context()->native_context()->arguments_boilerplate();
   13028   JSFunction* arguments_function =
   13029       JSFunction::cast(arguments_boilerplate->map()->constructor());
   13030 
   13031   // Get the number of referencing objects.
   13032   int count;
   13033   Heap* heap = isolate->heap();
   13034   HeapIterator heap_iterator(heap);
   13035   count = DebugReferencedBy(&heap_iterator,
   13036                             target, instance_filter, max_references,
   13037                             NULL, 0, arguments_function);
   13038 
   13039   // Allocate an array to hold the result.
   13040   Object* object;
   13041   { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
   13042     if (!maybe_object->ToObject(&object)) return maybe_object;
   13043   }
   13044   FixedArray* instances = FixedArray::cast(object);
   13045 
   13046   // Fill the referencing objects.
   13047   // AllocateFixedArray above does not make the heap non-iterable.
   13048   ASSERT(heap->IsHeapIterable());
   13049   HeapIterator heap_iterator2(heap);
   13050   count = DebugReferencedBy(&heap_iterator2,
   13051                             target, instance_filter, max_references,
   13052                             instances, count, arguments_function);
   13053 
   13054   // Return result as JS array.
   13055   Object* result;
   13056   MaybeObject* maybe_result = heap->AllocateJSObject(
   13057       isolate->context()->native_context()->array_function());
   13058   if (!maybe_result->ToObject(&result)) return maybe_result;
   13059   return JSArray::cast(result)->SetContent(instances);
   13060 }
   13061 
   13062 
   13063 // Helper function used by Runtime_DebugConstructedBy below.
   13064 static int DebugConstructedBy(HeapIterator* iterator,
   13065                               JSFunction* constructor,
   13066                               int max_references,
   13067                               FixedArray* instances,
   13068                               int instances_size) {
   13069   DisallowHeapAllocation no_allocation;
   13070 
   13071   // Iterate the heap.
   13072   int count = 0;
   13073   HeapObject* heap_obj = NULL;
   13074   while (((heap_obj = iterator->next()) != NULL) &&
   13075          (max_references == 0 || count < max_references)) {
   13076     // Only look at all JSObjects.
   13077     if (heap_obj->IsJSObject()) {
   13078       JSObject* obj = JSObject::cast(heap_obj);
   13079       if (obj->map()->constructor() == constructor) {
   13080         // Valid reference found add to instance array if supplied an update
   13081         // count.
   13082         if (instances != NULL && count < instances_size) {
   13083           instances->set(count, obj);
   13084         }
   13085         count++;
   13086       }
   13087     }
   13088   }
   13089 
   13090   // Return the number of referencing objects found.
   13091   return count;
   13092 }
   13093 
   13094 
   13095 // Scan the heap for objects constructed by a specific function.
   13096 // args[0]: the constructor to find instances of
   13097 // args[1]: the the maximum number of objects to return
   13098 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
   13099   SealHandleScope shs(isolate);
   13100   ASSERT(args.length() == 2);
   13101 
   13102   // First perform a full GC in order to avoid dead objects.
   13103   Heap* heap = isolate->heap();
   13104   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
   13105 
   13106   // Check parameters.
   13107   CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
   13108   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   13109   RUNTIME_ASSERT(max_references >= 0);
   13110 
   13111   // Get the number of referencing objects.
   13112   int count;
   13113   HeapIterator heap_iterator(heap);
   13114   count = DebugConstructedBy(&heap_iterator,
   13115                              constructor,
   13116                              max_references,
   13117                              NULL,
   13118                              0);
   13119 
   13120   // Allocate an array to hold the result.
   13121   Object* object;
   13122   { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
   13123     if (!maybe_object->ToObject(&object)) return maybe_object;
   13124   }
   13125   FixedArray* instances = FixedArray::cast(object);
   13126 
   13127   ASSERT(isolate->heap()->IsHeapIterable());
   13128   // Fill the referencing objects.
   13129   HeapIterator heap_iterator2(heap);
   13130   count = DebugConstructedBy(&heap_iterator2,
   13131                              constructor,
   13132                              max_references,
   13133                              instances,
   13134                              count);
   13135 
   13136   // Return result as JS array.
   13137   Object* result;
   13138   { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
   13139       isolate->context()->native_context()->array_function());
   13140     if (!maybe_result->ToObject(&result)) return maybe_result;
   13141   }
   13142   return JSArray::cast(result)->SetContent(instances);
   13143 }
   13144 
   13145 
   13146 // Find the effective prototype object as returned by __proto__.
   13147 // args[0]: the object to find the prototype for.
   13148 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
   13149   SealHandleScope shs(isolate);
   13150   ASSERT(args.length() == 1);
   13151   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   13152   return GetPrototypeSkipHiddenPrototypes(isolate, obj);
   13153 }
   13154 
   13155 
   13156 // Patches script source (should be called upon BeforeCompile event).
   13157 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
   13158   HandleScope scope(isolate);
   13159   ASSERT(args.length() == 2);
   13160 
   13161   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
   13162   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13163 
   13164   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
   13165   Handle<Script> script(Script::cast(script_wrapper->value()));
   13166 
   13167   int compilation_state = script->compilation_state();
   13168   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
   13169   script->set_source(*source);
   13170 
   13171   return isolate->heap()->undefined_value();
   13172 }
   13173 
   13174 
   13175 RUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
   13176   SealHandleScope shs(isolate);
   13177   ASSERT(args.length() == 0);
   13178   OS::DebugBreak();
   13179   return isolate->heap()->undefined_value();
   13180 }
   13181 
   13182 
   13183 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
   13184   HandleScope scope(isolate);
   13185 #ifdef DEBUG
   13186   ASSERT(args.length() == 1);
   13187   // Get the function and make sure it is compiled.
   13188   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13189   if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13190     return Failure::Exception();
   13191   }
   13192   func->code()->PrintLn();
   13193 #endif  // DEBUG
   13194   return isolate->heap()->undefined_value();
   13195 }
   13196 
   13197 
   13198 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
   13199   HandleScope scope(isolate);
   13200 #ifdef DEBUG
   13201   ASSERT(args.length() == 1);
   13202   // Get the function and make sure it is compiled.
   13203   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13204   if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13205     return Failure::Exception();
   13206   }
   13207   func->shared()->construct_stub()->PrintLn();
   13208 #endif  // DEBUG
   13209   return isolate->heap()->undefined_value();
   13210 }
   13211 
   13212 
   13213 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
   13214   SealHandleScope shs(isolate);
   13215   ASSERT(args.length() == 1);
   13216 
   13217   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   13218   return f->shared()->inferred_name();
   13219 }
   13220 
   13221 
   13222 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
   13223                                             Script* script,
   13224                                             FixedArray* buffer) {
   13225   DisallowHeapAllocation no_allocation;
   13226   int counter = 0;
   13227   int buffer_size = buffer->length();
   13228   for (HeapObject* obj = iterator->next();
   13229        obj != NULL;
   13230        obj = iterator->next()) {
   13231     ASSERT(obj != NULL);
   13232     if (!obj->IsSharedFunctionInfo()) {
   13233       continue;
   13234     }
   13235     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
   13236     if (shared->script() != script) {
   13237       continue;
   13238     }
   13239     if (counter < buffer_size) {
   13240       buffer->set(counter, shared);
   13241     }
   13242     counter++;
   13243   }
   13244   return counter;
   13245 }
   13246 
   13247 
   13248 // For a script finds all SharedFunctionInfo's in the heap that points
   13249 // to this script. Returns JSArray of SharedFunctionInfo wrapped
   13250 // in OpaqueReferences.
   13251 RUNTIME_FUNCTION(MaybeObject*,
   13252                  Runtime_LiveEditFindSharedFunctionInfosForScript) {
   13253   HandleScope scope(isolate);
   13254   CHECK(isolate->debugger()->live_edit_enabled());
   13255   ASSERT(args.length() == 1);
   13256   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
   13257 
   13258   RUNTIME_ASSERT(script_value->value()->IsScript());
   13259   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
   13260 
   13261   const int kBufferSize = 32;
   13262 
   13263   Handle<FixedArray> array;
   13264   array = isolate->factory()->NewFixedArray(kBufferSize);
   13265   int number;
   13266   Heap* heap = isolate->heap();
   13267   {
   13268     heap->EnsureHeapIsIterable();
   13269     DisallowHeapAllocation no_allocation;
   13270     HeapIterator heap_iterator(heap);
   13271     Script* scr = *script;
   13272     FixedArray* arr = *array;
   13273     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13274   }
   13275   if (number > kBufferSize) {
   13276     array = isolate->factory()->NewFixedArray(number);
   13277     heap->EnsureHeapIsIterable();
   13278     DisallowHeapAllocation no_allocation;
   13279     HeapIterator heap_iterator(heap);
   13280     Script* scr = *script;
   13281     FixedArray* arr = *array;
   13282     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13283   }
   13284 
   13285   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
   13286   result->set_length(Smi::FromInt(number));
   13287 
   13288   LiveEdit::WrapSharedFunctionInfos(result);
   13289 
   13290   return *result;
   13291 }
   13292 
   13293 
   13294 // For a script calculates compilation information about all its functions.
   13295 // The script source is explicitly specified by the second argument.
   13296 // The source of the actual script is not used, however it is important that
   13297 // all generated code keeps references to this particular instance of script.
   13298 // Returns a JSArray of compilation infos. The array is ordered so that
   13299 // each function with all its descendant is always stored in a continues range
   13300 // with the function itself going first. The root function is a script function.
   13301 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
   13302   HandleScope scope(isolate);
   13303   CHECK(isolate->debugger()->live_edit_enabled());
   13304   ASSERT(args.length() == 2);
   13305   CONVERT_ARG_CHECKED(JSValue, script, 0);
   13306   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13307 
   13308   RUNTIME_ASSERT(script->value()->IsScript());
   13309   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
   13310 
   13311   JSArray* result =  LiveEdit::GatherCompileInfo(script_handle, source);
   13312 
   13313   if (isolate->has_pending_exception()) {
   13314     return Failure::Exception();
   13315   }
   13316 
   13317   return result;
   13318 }
   13319 
   13320 
   13321 // Changes the source of the script to a new_source.
   13322 // If old_script_name is provided (i.e. is a String), also creates a copy of
   13323 // the script with its original source and sends notification to debugger.
   13324 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
   13325   HandleScope scope(isolate);
   13326   CHECK(isolate->debugger()->live_edit_enabled());
   13327   ASSERT(args.length() == 3);
   13328   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
   13329   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
   13330   Handle<Object> old_script_name(args[2], isolate);
   13331 
   13332   RUNTIME_ASSERT(original_script_value->value()->IsScript());
   13333   Handle<Script> original_script(Script::cast(original_script_value->value()));
   13334 
   13335   Object* old_script = LiveEdit::ChangeScriptSource(original_script,
   13336                                                     new_source,
   13337                                                     old_script_name);
   13338 
   13339   if (old_script->IsScript()) {
   13340     Handle<Script> script_handle(Script::cast(old_script));
   13341     return *(GetScriptWrapper(script_handle));
   13342   } else {
   13343     return isolate->heap()->null_value();
   13344   }
   13345 }
   13346 
   13347 
   13348 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
   13349   HandleScope scope(isolate);
   13350   CHECK(isolate->debugger()->live_edit_enabled());
   13351   ASSERT(args.length() == 1);
   13352   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
   13353   return LiveEdit::FunctionSourceUpdated(shared_info);
   13354 }
   13355 
   13356 
   13357 // Replaces code of SharedFunctionInfo with a new one.
   13358 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
   13359   HandleScope scope(isolate);
   13360   CHECK(isolate->debugger()->live_edit_enabled());
   13361   ASSERT(args.length() == 2);
   13362   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
   13363   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
   13364 
   13365   return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
   13366 }
   13367 
   13368 
   13369 // Connects SharedFunctionInfo to another script.
   13370 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
   13371   HandleScope scope(isolate);
   13372   CHECK(isolate->debugger()->live_edit_enabled());
   13373   ASSERT(args.length() == 2);
   13374   Handle<Object> function_object(args[0], isolate);
   13375   Handle<Object> script_object(args[1], isolate);
   13376 
   13377   if (function_object->IsJSValue()) {
   13378     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
   13379     if (script_object->IsJSValue()) {
   13380       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
   13381       Script* script = Script::cast(JSValue::cast(*script_object)->value());
   13382       script_object = Handle<Object>(script, isolate);
   13383     }
   13384 
   13385     LiveEdit::SetFunctionScript(function_wrapper, script_object);
   13386   } else {
   13387     // Just ignore this. We may not have a SharedFunctionInfo for some functions
   13388     // and we check it in this function.
   13389   }
   13390 
   13391   return isolate->heap()->undefined_value();
   13392 }
   13393 
   13394 
   13395 // In a code of a parent function replaces original function as embedded object
   13396 // with a substitution one.
   13397 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
   13398   HandleScope scope(isolate);
   13399   CHECK(isolate->debugger()->live_edit_enabled());
   13400   ASSERT(args.length() == 3);
   13401 
   13402   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
   13403   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
   13404   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
   13405 
   13406   LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
   13407                                        subst_wrapper);
   13408 
   13409   return isolate->heap()->undefined_value();
   13410 }
   13411 
   13412 
   13413 // Updates positions of a shared function info (first parameter) according
   13414 // to script source change. Text change is described in second parameter as
   13415 // array of groups of 3 numbers:
   13416 // (change_begin, change_end, change_end_new_position).
   13417 // Each group describes a change in text; groups are sorted by change_begin.
   13418 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
   13419   HandleScope scope(isolate);
   13420   CHECK(isolate->debugger()->live_edit_enabled());
   13421   ASSERT(args.length() == 2);
   13422   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13423   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
   13424 
   13425   return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
   13426 }
   13427 
   13428 
   13429 // For array of SharedFunctionInfo's (each wrapped in JSValue)
   13430 // checks that none of them have activations on stacks (of any thread).
   13431 // Returns array of the same length with corresponding results of
   13432 // LiveEdit::FunctionPatchabilityStatus type.
   13433 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
   13434   HandleScope scope(isolate);
   13435   CHECK(isolate->debugger()->live_edit_enabled());
   13436   ASSERT(args.length() == 2);
   13437   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13438   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
   13439 
   13440   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
   13441 }
   13442 
   13443 
   13444 // Compares 2 strings line-by-line, then token-wise and returns diff in form
   13445 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
   13446 // of diff chunks.
   13447 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
   13448   HandleScope scope(isolate);
   13449   CHECK(isolate->debugger()->live_edit_enabled());
   13450   ASSERT(args.length() == 2);
   13451   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
   13452   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
   13453 
   13454   return *LiveEdit::CompareStrings(s1, s2);
   13455 }
   13456 
   13457 
   13458 // Restarts a call frame and completely drops all frames above.
   13459 // Returns true if successful. Otherwise returns undefined or an error message.
   13460 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditRestartFrame) {
   13461   HandleScope scope(isolate);
   13462   CHECK(isolate->debugger()->live_edit_enabled());
   13463   ASSERT(args.length() == 2);
   13464 
   13465   // Check arguments.
   13466   Object* check;
   13467   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   13468       RUNTIME_ARGUMENTS(isolate, args));
   13469     if (!maybe_check->ToObject(&check)) return maybe_check;
   13470   }
   13471   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   13472   Heap* heap = isolate->heap();
   13473 
   13474   // Find the relevant frame with the requested index.
   13475   StackFrame::Id id = isolate->debug()->break_frame_id();
   13476   if (id == StackFrame::NO_ID) {
   13477     // If there are no JavaScript stack frames return undefined.
   13478     return heap->undefined_value();
   13479   }
   13480 
   13481   int count = 0;
   13482   JavaScriptFrameIterator it(isolate, id);
   13483   for (; !it.done(); it.Advance()) {
   13484     if (index < count + it.frame()->GetInlineCount()) break;
   13485     count += it.frame()->GetInlineCount();
   13486   }
   13487   if (it.done()) return heap->undefined_value();
   13488 
   13489   const char* error_message = LiveEdit::RestartFrame(it.frame());
   13490   if (error_message) {
   13491     return *(isolate->factory()->InternalizeUtf8String(error_message));
   13492   }
   13493   return heap->true_value();
   13494 }
   13495 
   13496 
   13497 // A testing entry. Returns statement position which is the closest to
   13498 // source_position.
   13499 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
   13500   HandleScope scope(isolate);
   13501   CHECK(isolate->debugger()->live_edit_enabled());
   13502   ASSERT(args.length() == 2);
   13503   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13504   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   13505 
   13506   Handle<Code> code(function->code(), isolate);
   13507 
   13508   if (code->kind() != Code::FUNCTION &&
   13509       code->kind() != Code::OPTIMIZED_FUNCTION) {
   13510     return isolate->heap()->undefined_value();
   13511   }
   13512 
   13513   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
   13514   int closest_pc = 0;
   13515   int distance = kMaxInt;
   13516   while (!it.done()) {
   13517     int statement_position = static_cast<int>(it.rinfo()->data());
   13518     // Check if this break point is closer that what was previously found.
   13519     if (source_position <= statement_position &&
   13520         statement_position - source_position < distance) {
   13521       closest_pc =
   13522           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
   13523       distance = statement_position - source_position;
   13524       // Check whether we can't get any closer.
   13525       if (distance == 0) break;
   13526     }
   13527     it.next();
   13528   }
   13529 
   13530   return Smi::FromInt(closest_pc);
   13531 }
   13532 
   13533 
   13534 // Calls specified function with or without entering the debugger.
   13535 // This is used in unit tests to run code as if debugger is entered or simply
   13536 // to have a stack with C++ frame in the middle.
   13537 RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
   13538   HandleScope scope(isolate);
   13539   ASSERT(args.length() == 2);
   13540   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13541   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
   13542 
   13543   Handle<Object> result;
   13544   bool pending_exception;
   13545   {
   13546     if (without_debugger) {
   13547       result = Execution::Call(isolate,
   13548                                function,
   13549                                isolate->global_object(),
   13550                                0,
   13551                                NULL,
   13552                                &pending_exception);
   13553     } else {
   13554       EnterDebugger enter_debugger(isolate);
   13555       result = Execution::Call(isolate,
   13556                                function,
   13557                                isolate->global_object(),
   13558                                0,
   13559                                NULL,
   13560                                &pending_exception);
   13561     }
   13562   }
   13563   if (!pending_exception) {
   13564     return *result;
   13565   } else {
   13566     return Failure::Exception();
   13567   }
   13568 }
   13569 
   13570 
   13571 // Sets a v8 flag.
   13572 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
   13573   SealHandleScope shs(isolate);
   13574   CONVERT_ARG_CHECKED(String, arg, 0);
   13575   SmartArrayPointer<char> flags =
   13576       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   13577   FlagList::SetFlagsFromString(*flags, StrLength(*flags));
   13578   return isolate->heap()->undefined_value();
   13579 }
   13580 
   13581 
   13582 // Performs a GC.
   13583 // Presently, it only does a full GC.
   13584 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectGarbage) {
   13585   SealHandleScope shs(isolate);
   13586   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
   13587   return isolate->heap()->undefined_value();
   13588 }
   13589 
   13590 
   13591 // Gets the current heap usage.
   13592 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
   13593   SealHandleScope shs(isolate);
   13594   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
   13595   if (!Smi::IsValid(usage)) {
   13596     return *isolate->factory()->NewNumberFromInt(usage);
   13597   }
   13598   return Smi::FromInt(usage);
   13599 }
   13600 
   13601 #endif  // ENABLE_DEBUGGER_SUPPORT
   13602 
   13603 
   13604 #ifdef V8_I18N_SUPPORT
   13605 RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
   13606   HandleScope scope(isolate);
   13607 
   13608   ASSERT(args.length() == 1);
   13609   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
   13610 
   13611   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
   13612 
   13613   // Return value which denotes invalid language tag.
   13614   const char* const kInvalidTag = "invalid-tag";
   13615 
   13616   UErrorCode error = U_ZERO_ERROR;
   13617   char icu_result[ULOC_FULLNAME_CAPACITY];
   13618   int icu_length = 0;
   13619 
   13620   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
   13621                       &icu_length, &error);
   13622   if (U_FAILURE(error) || icu_length == 0) {
   13623     return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
   13624   }
   13625 
   13626   char result[ULOC_FULLNAME_CAPACITY];
   13627 
   13628   // Force strict BCP47 rules.
   13629   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
   13630 
   13631   if (U_FAILURE(error)) {
   13632     return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
   13633   }
   13634 
   13635   return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
   13636 }
   13637 
   13638 
   13639 RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
   13640   HandleScope scope(isolate);
   13641 
   13642   ASSERT(args.length() == 1);
   13643   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
   13644 
   13645   const icu::Locale* available_locales = NULL;
   13646   int32_t count = 0;
   13647 
   13648   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
   13649     available_locales = icu::Collator::getAvailableLocales(count);
   13650   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
   13651     available_locales = icu::NumberFormat::getAvailableLocales(count);
   13652   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
   13653     available_locales = icu::DateFormat::getAvailableLocales(count);
   13654   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
   13655     available_locales = icu::BreakIterator::getAvailableLocales(count);
   13656   }
   13657 
   13658   UErrorCode error = U_ZERO_ERROR;
   13659   char result[ULOC_FULLNAME_CAPACITY];
   13660   Handle<JSObject> locales =
   13661       isolate->factory()->NewJSObject(isolate->object_function());
   13662 
   13663   for (int32_t i = 0; i < count; ++i) {
   13664     const char* icu_name = available_locales[i].getName();
   13665 
   13666     error = U_ZERO_ERROR;
   13667     // No need to force strict BCP47 rules.
   13668     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13669     if (U_FAILURE(error)) {
   13670       // This shouldn't happen, but lets not break the user.
   13671       continue;
   13672     }
   13673 
   13674     RETURN_IF_EMPTY_HANDLE(isolate,
   13675         JSObject::SetLocalPropertyIgnoreAttributes(
   13676             locales,
   13677             isolate->factory()->NewStringFromAscii(CStrVector(result)),
   13678             isolate->factory()->NewNumber(i),
   13679             NONE));
   13680   }
   13681 
   13682   return *locales;
   13683 }
   13684 
   13685 
   13686 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) {
   13687   SealHandleScope shs(isolate);
   13688 
   13689   ASSERT(args.length() == 0);
   13690 
   13691   icu::Locale default_locale;
   13692 
   13693   // Set the locale
   13694   char result[ULOC_FULLNAME_CAPACITY];
   13695   UErrorCode status = U_ZERO_ERROR;
   13696   uloc_toLanguageTag(
   13697       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
   13698   if (U_SUCCESS(status)) {
   13699     return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
   13700   }
   13701 
   13702   return isolate->heap()->AllocateStringFromOneByte(CStrVector("und"));
   13703 }
   13704 
   13705 
   13706 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
   13707   HandleScope scope(isolate);
   13708 
   13709   ASSERT(args.length() == 1);
   13710 
   13711   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
   13712 
   13713   uint32_t length = static_cast<uint32_t>(input->length()->Number());
   13714   Handle<FixedArray> output = isolate->factory()->NewFixedArray(length);
   13715   Handle<Name> maximized =
   13716       isolate->factory()->NewStringFromAscii(CStrVector("maximized"));
   13717   Handle<Name> base =
   13718       isolate->factory()->NewStringFromAscii(CStrVector("base"));
   13719   for (unsigned int i = 0; i < length; ++i) {
   13720     MaybeObject* maybe_string = input->GetElement(isolate, i);
   13721     Object* locale_id;
   13722     if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) {
   13723       return isolate->Throw(isolate->heap()->illegal_argument_string());
   13724     }
   13725 
   13726     v8::String::Utf8Value utf8_locale_id(
   13727         v8::Utils::ToLocal(Handle<String>(String::cast(locale_id))));
   13728 
   13729     UErrorCode error = U_ZERO_ERROR;
   13730 
   13731     // Convert from BCP47 to ICU format.
   13732     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
   13733     char icu_locale[ULOC_FULLNAME_CAPACITY];
   13734     int icu_locale_length = 0;
   13735     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
   13736                         &icu_locale_length, &error);
   13737     if (U_FAILURE(error) || icu_locale_length == 0) {
   13738       return isolate->Throw(isolate->heap()->illegal_argument_string());
   13739     }
   13740 
   13741     // Maximize the locale.
   13742     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
   13743     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
   13744     uloc_addLikelySubtags(
   13745         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13746 
   13747     // Remove extensions from maximized locale.
   13748     // de_Latn_DE@collation=phonebook -> de_Latn_DE
   13749     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
   13750     uloc_getBaseName(
   13751         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13752 
   13753     // Get original name without extensions.
   13754     // de_DE@collation=phonebook -> de_DE
   13755     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
   13756     uloc_getBaseName(
   13757         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
   13758 
   13759     // Convert from ICU locale format to BCP47 format.
   13760     // de_Latn_DE -> de-Latn-DE
   13761     char base_max_locale[ULOC_FULLNAME_CAPACITY];
   13762     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
   13763                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13764 
   13765     // de_DE -> de-DE
   13766     char base_locale[ULOC_FULLNAME_CAPACITY];
   13767     uloc_toLanguageTag(
   13768         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13769 
   13770     if (U_FAILURE(error)) {
   13771       return isolate->Throw(isolate->heap()->illegal_argument_string());
   13772     }
   13773 
   13774     Handle<JSObject> result =
   13775         isolate->factory()->NewJSObject(isolate->object_function());
   13776     RETURN_IF_EMPTY_HANDLE(isolate,
   13777         JSObject::SetLocalPropertyIgnoreAttributes(
   13778             result,
   13779             maximized,
   13780             isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)),
   13781             NONE));
   13782     RETURN_IF_EMPTY_HANDLE(isolate,
   13783         JSObject::SetLocalPropertyIgnoreAttributes(
   13784             result,
   13785             base,
   13786             isolate->factory()->NewStringFromAscii(CStrVector(base_locale)),
   13787             NONE));
   13788     output->set(i, *result);
   13789   }
   13790 
   13791   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output);
   13792   result->set_length(Smi::FromInt(length));
   13793   return *result;
   13794 }
   13795 
   13796 
   13797 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
   13798   HandleScope scope(isolate);
   13799 
   13800   ASSERT(args.length() == 3);
   13801 
   13802   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   13803   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   13804   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   13805 
   13806   Handle<ObjectTemplateInfo> date_format_template =
   13807       I18N::GetTemplate(isolate);
   13808 
   13809   // Create an empty object wrapper.
   13810   bool has_pending_exception = false;
   13811   Handle<JSObject> local_object = Execution::InstantiateObject(
   13812       date_format_template, &has_pending_exception);
   13813   if (has_pending_exception) {
   13814     ASSERT(isolate->has_pending_exception());
   13815     return Failure::Exception();
   13816   }
   13817 
   13818   // Set date time formatter as internal field of the resulting JS object.
   13819   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
   13820       isolate, locale, options, resolved);
   13821 
   13822   if (!date_format) return isolate->ThrowIllegalOperation();
   13823 
   13824   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
   13825 
   13826   RETURN_IF_EMPTY_HANDLE(isolate,
   13827       JSObject::SetLocalPropertyIgnoreAttributes(
   13828           local_object,
   13829           isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")),
   13830           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   13831           NONE));
   13832 
   13833   // Make object handle weak so we can delete the data format once GC kicks in.
   13834   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   13835   GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
   13836                           NULL,
   13837                           DateFormat::DeleteDateFormat);
   13838   return *local_object;
   13839 }
   13840 
   13841 
   13842 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
   13843   HandleScope scope(isolate);
   13844 
   13845   ASSERT(args.length() == 2);
   13846 
   13847   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   13848   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
   13849 
   13850   bool has_pending_exception = false;
   13851   Handle<Object> value =
   13852       Execution::ToNumber(isolate, date, &has_pending_exception);
   13853   if (has_pending_exception) {
   13854     ASSERT(isolate->has_pending_exception());
   13855     return Failure::Exception();
   13856   }
   13857 
   13858   icu::SimpleDateFormat* date_format =
   13859       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   13860   if (!date_format) return isolate->ThrowIllegalOperation();
   13861 
   13862   icu::UnicodeString result;
   13863   date_format->format(value->Number(), result);
   13864 
   13865   return *isolate->factory()->NewStringFromTwoByte(
   13866       Vector<const uint16_t>(
   13867           reinterpret_cast<const uint16_t*>(result.getBuffer()),
   13868           result.length()));
   13869 }
   13870 
   13871 
   13872 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) {
   13873   HandleScope scope(isolate);
   13874 
   13875   ASSERT(args.length() == 2);
   13876 
   13877   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   13878   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
   13879 
   13880   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
   13881   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
   13882   icu::SimpleDateFormat* date_format =
   13883       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   13884   if (!date_format) return isolate->ThrowIllegalOperation();
   13885 
   13886   UErrorCode status = U_ZERO_ERROR;
   13887   UDate date = date_format->parse(u_date, status);
   13888   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   13889 
   13890   bool has_pending_exception = false;
   13891   Handle<JSDate> result = Handle<JSDate>::cast(
   13892       Execution::NewDate(
   13893           isolate, static_cast<double>(date), &has_pending_exception));
   13894   if (has_pending_exception) {
   13895     ASSERT(isolate->has_pending_exception());
   13896     return Failure::Exception();
   13897   }
   13898   return *result;
   13899 }
   13900 
   13901 
   13902 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
   13903   HandleScope scope(isolate);
   13904 
   13905   ASSERT(args.length() == 3);
   13906 
   13907   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   13908   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   13909   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   13910 
   13911   Handle<ObjectTemplateInfo> number_format_template =
   13912       I18N::GetTemplate(isolate);
   13913 
   13914   // Create an empty object wrapper.
   13915   bool has_pending_exception = false;
   13916   Handle<JSObject> local_object = Execution::InstantiateObject(
   13917       number_format_template, &has_pending_exception);
   13918   if (has_pending_exception) {
   13919     ASSERT(isolate->has_pending_exception());
   13920     return Failure::Exception();
   13921   }
   13922 
   13923   // Set number formatter as internal field of the resulting JS object.
   13924   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
   13925       isolate, locale, options, resolved);
   13926 
   13927   if (!number_format) return isolate->ThrowIllegalOperation();
   13928 
   13929   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
   13930 
   13931   RETURN_IF_EMPTY_HANDLE(isolate,
   13932       JSObject::SetLocalPropertyIgnoreAttributes(
   13933           local_object,
   13934           isolate->factory()->NewStringFromAscii(CStrVector("numberFormat")),
   13935           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   13936           NONE));
   13937 
   13938   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   13939   GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
   13940                           NULL,
   13941                           NumberFormat::DeleteNumberFormat);
   13942   return *local_object;
   13943 }
   13944 
   13945 
   13946 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
   13947   HandleScope scope(isolate);
   13948 
   13949   ASSERT(args.length() == 2);
   13950 
   13951   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   13952   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
   13953 
   13954   bool has_pending_exception = false;
   13955   Handle<Object> value = Execution::ToNumber(
   13956       isolate, number, &has_pending_exception);
   13957   if (has_pending_exception) {
   13958     ASSERT(isolate->has_pending_exception());
   13959     return Failure::Exception();
   13960   }
   13961 
   13962   icu::DecimalFormat* number_format =
   13963       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   13964   if (!number_format) return isolate->ThrowIllegalOperation();
   13965 
   13966   icu::UnicodeString result;
   13967   number_format->format(value->Number(), result);
   13968 
   13969   return *isolate->factory()->NewStringFromTwoByte(
   13970       Vector<const uint16_t>(
   13971           reinterpret_cast<const uint16_t*>(result.getBuffer()),
   13972           result.length()));
   13973 }
   13974 
   13975 
   13976 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) {
   13977   HandleScope scope(isolate);
   13978 
   13979   ASSERT(args.length() == 2);
   13980 
   13981   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   13982   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
   13983 
   13984   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
   13985   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
   13986   icu::DecimalFormat* number_format =
   13987       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   13988   if (!number_format) return isolate->ThrowIllegalOperation();
   13989 
   13990   UErrorCode status = U_ZERO_ERROR;
   13991   icu::Formattable result;
   13992   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
   13993   // to be part of Chrome.
   13994   // TODO(cira): Include currency parsing code using parseCurrency call.
   13995   // We need to check if the formatter parses all currencies or only the
   13996   // one it was constructed with (it will impact the API - how to return ISO
   13997   // code and the value).
   13998   number_format->parse(u_number, result, status);
   13999   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   14000 
   14001   switch (result.getType()) {
   14002   case icu::Formattable::kDouble:
   14003     return *isolate->factory()->NewNumber(result.getDouble());
   14004   case icu::Formattable::kLong:
   14005     return *isolate->factory()->NewNumberFromInt(result.getLong());
   14006   case icu::Formattable::kInt64:
   14007     return *isolate->factory()->NewNumber(
   14008         static_cast<double>(result.getInt64()));
   14009   default:
   14010     return isolate->heap()->undefined_value();
   14011   }
   14012 }
   14013 
   14014 
   14015 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
   14016   HandleScope scope(isolate);
   14017 
   14018   ASSERT(args.length() == 3);
   14019 
   14020   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14021   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14022   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14023 
   14024   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
   14025 
   14026   // Create an empty object wrapper.
   14027   bool has_pending_exception = false;
   14028   Handle<JSObject> local_object = Execution::InstantiateObject(
   14029       collator_template, &has_pending_exception);
   14030   if (has_pending_exception) {
   14031     ASSERT(isolate->has_pending_exception());
   14032     return Failure::Exception();
   14033   }
   14034 
   14035   // Set collator as internal field of the resulting JS object.
   14036   icu::Collator* collator = Collator::InitializeCollator(
   14037       isolate, locale, options, resolved);
   14038 
   14039   if (!collator) return isolate->ThrowIllegalOperation();
   14040 
   14041   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
   14042 
   14043   RETURN_IF_EMPTY_HANDLE(isolate,
   14044       JSObject::SetLocalPropertyIgnoreAttributes(
   14045           local_object,
   14046           isolate->factory()->NewStringFromAscii(CStrVector("collator")),
   14047           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   14048           NONE));
   14049 
   14050   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14051   GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
   14052                           NULL,
   14053                           Collator::DeleteCollator);
   14054   return *local_object;
   14055 }
   14056 
   14057 
   14058 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalCompare) {
   14059   HandleScope scope(isolate);
   14060 
   14061   ASSERT(args.length() == 3);
   14062 
   14063   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
   14064   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
   14065   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
   14066 
   14067   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
   14068   if (!collator) return isolate->ThrowIllegalOperation();
   14069 
   14070   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
   14071   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
   14072   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
   14073   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
   14074   UErrorCode status = U_ZERO_ERROR;
   14075   UCollationResult result = collator->compare(u_string1,
   14076                                               string_value1.length(),
   14077                                               u_string2,
   14078                                               string_value2.length(),
   14079                                               status);
   14080   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
   14081 
   14082   return *isolate->factory()->NewNumberFromInt(result);
   14083 }
   14084 
   14085 
   14086 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
   14087   HandleScope scope(isolate);
   14088 
   14089   ASSERT(args.length() == 3);
   14090 
   14091   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   14092   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   14093   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   14094 
   14095   Handle<ObjectTemplateInfo> break_iterator_template =
   14096       I18N::GetTemplate2(isolate);
   14097 
   14098   // Create an empty object wrapper.
   14099   bool has_pending_exception = false;
   14100   Handle<JSObject> local_object = Execution::InstantiateObject(
   14101       break_iterator_template, &has_pending_exception);
   14102   if (has_pending_exception) {
   14103     ASSERT(isolate->has_pending_exception());
   14104     return Failure::Exception();
   14105   }
   14106 
   14107   // Set break iterator as internal field of the resulting JS object.
   14108   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
   14109       isolate, locale, options, resolved);
   14110 
   14111   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14112 
   14113   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
   14114   // Make sure that the pointer to adopted text is NULL.
   14115   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
   14116 
   14117   RETURN_IF_EMPTY_HANDLE(isolate,
   14118       JSObject::SetLocalPropertyIgnoreAttributes(
   14119           local_object,
   14120           isolate->factory()->NewStringFromAscii(CStrVector("breakIterator")),
   14121           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   14122           NONE));
   14123 
   14124   // Make object handle weak so we can delete the break iterator once GC kicks
   14125   // in.
   14126   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
   14127   GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
   14128                           NULL,
   14129                           BreakIterator::DeleteBreakIterator);
   14130   return *local_object;
   14131 }
   14132 
   14133 
   14134 RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorAdoptText) {
   14135   HandleScope scope(isolate);
   14136 
   14137   ASSERT(args.length() == 2);
   14138 
   14139   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14140   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
   14141 
   14142   icu::BreakIterator* break_iterator =
   14143       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14144   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14145 
   14146   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
   14147       break_iterator_holder->GetInternalField(1));
   14148   delete u_text;
   14149 
   14150   v8::String::Value text_value(v8::Utils::ToLocal(text));
   14151   u_text = new icu::UnicodeString(
   14152       reinterpret_cast<const UChar*>(*text_value), text_value.length());
   14153   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
   14154 
   14155   break_iterator->setText(*u_text);
   14156 
   14157   return isolate->heap()->undefined_value();
   14158 }
   14159 
   14160 
   14161 RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorFirst) {
   14162   HandleScope scope(isolate);
   14163 
   14164   ASSERT(args.length() == 1);
   14165 
   14166   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14167 
   14168   icu::BreakIterator* break_iterator =
   14169       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14170   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14171 
   14172   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
   14173 }
   14174 
   14175 
   14176 RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorNext) {
   14177   HandleScope scope(isolate);
   14178 
   14179   ASSERT(args.length() == 1);
   14180 
   14181   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14182 
   14183   icu::BreakIterator* break_iterator =
   14184       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14185   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14186 
   14187   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
   14188 }
   14189 
   14190 
   14191 RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorCurrent) {
   14192   HandleScope scope(isolate);
   14193 
   14194   ASSERT(args.length() == 1);
   14195 
   14196   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14197 
   14198   icu::BreakIterator* break_iterator =
   14199       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14200   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14201 
   14202   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
   14203 }
   14204 
   14205 
   14206 RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorBreakType) {
   14207   HandleScope scope(isolate);
   14208 
   14209   ASSERT(args.length() == 1);
   14210 
   14211   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
   14212 
   14213   icu::BreakIterator* break_iterator =
   14214       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
   14215   if (!break_iterator) return isolate->ThrowIllegalOperation();
   14216 
   14217   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
   14218   icu::RuleBasedBreakIterator* rule_based_iterator =
   14219       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
   14220   int32_t status = rule_based_iterator->getRuleStatus();
   14221   // Keep return values in sync with JavaScript BreakType enum.
   14222   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
   14223     return *isolate->factory()->NewStringFromAscii(CStrVector("none"));
   14224   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
   14225     return *isolate->factory()->NewStringFromAscii(CStrVector("number"));
   14226   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
   14227     return *isolate->factory()->NewStringFromAscii(CStrVector("letter"));
   14228   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
   14229     return *isolate->factory()->NewStringFromAscii(CStrVector("kana"));
   14230   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
   14231     return *isolate->factory()->NewStringFromAscii(CStrVector("ideo"));
   14232   } else {
   14233     return *isolate->factory()->NewStringFromAscii(CStrVector("unknown"));
   14234   }
   14235 }
   14236 #endif  // V8_I18N_SUPPORT
   14237 
   14238 
   14239 // Finds the script object from the script data. NOTE: This operation uses
   14240 // heap traversal to find the function generated for the source position
   14241 // for the requested break point. For lazily compiled functions several heap
   14242 // traversals might be required rendering this operation as a rather slow
   14243 // operation. However for setting break points which is normally done through
   14244 // some kind of user interaction the performance is not crucial.
   14245 static Handle<Object> Runtime_GetScriptFromScriptName(
   14246     Handle<String> script_name) {
   14247   // Scan the heap for Script objects to find the script with the requested
   14248   // script data.
   14249   Handle<Script> script;
   14250   Factory* factory = script_name->GetIsolate()->factory();
   14251   Heap* heap = script_name->GetHeap();
   14252   heap->EnsureHeapIsIterable();
   14253   DisallowHeapAllocation no_allocation_during_heap_iteration;
   14254   HeapIterator iterator(heap);
   14255   HeapObject* obj = NULL;
   14256   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
   14257     // If a script is found check if it has the script data requested.
   14258     if (obj->IsScript()) {
   14259       if (Script::cast(obj)->name()->IsString()) {
   14260         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
   14261           script = Handle<Script>(Script::cast(obj));
   14262         }
   14263       }
   14264     }
   14265   }
   14266 
   14267   // If no script with the requested script data is found return undefined.
   14268   if (script.is_null()) return factory->undefined_value();
   14269 
   14270   // Return the script found.
   14271   return GetScriptWrapper(script);
   14272 }
   14273 
   14274 
   14275 // Get the script object from script data. NOTE: Regarding performance
   14276 // see the NOTE for GetScriptFromScriptData.
   14277 // args[0]: script data for the script to find the source for
   14278 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
   14279   HandleScope scope(isolate);
   14280 
   14281   ASSERT(args.length() == 1);
   14282 
   14283   CONVERT_ARG_CHECKED(String, script_name, 0);
   14284 
   14285   // Find the requested script.
   14286   Handle<Object> result =
   14287       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
   14288   return *result;
   14289 }
   14290 
   14291 
   14292 // Collect the raw data for a stack trace.  Returns an array of 4
   14293 // element segments each containing a receiver, function, code and
   14294 // native code offset.
   14295 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
   14296   HandleScope scope(isolate);
   14297   ASSERT_EQ(args.length(), 3);
   14298   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   14299   Handle<Object> caller = args.at<Object>(1);
   14300   CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
   14301 
   14302   // Optionally capture a more detailed stack trace for the message.
   14303   isolate->CaptureAndSetDetailedStackTrace(error_object);
   14304   // Capture a simple stack trace for the stack property.
   14305   return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
   14306 }
   14307 
   14308 
   14309 // Retrieve the stack trace.  This is the raw stack trace that yet has to
   14310 // be formatted.  Since we only need this once, clear it afterwards.
   14311 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
   14312   HandleScope scope(isolate);
   14313   ASSERT_EQ(args.length(), 1);
   14314   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   14315   Handle<String> key = isolate->factory()->hidden_stack_trace_string();
   14316   Handle<Object> result(error_object->GetHiddenProperty(*key), isolate);
   14317   if (result->IsTheHole()) return isolate->heap()->undefined_value();
   14318   RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
   14319   JSObject::DeleteHiddenProperty(error_object, key);
   14320   return *result;
   14321 }
   14322 
   14323 
   14324 // Returns V8 version as a string.
   14325 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
   14326   SealHandleScope shs(isolate);
   14327   ASSERT_EQ(args.length(), 0);
   14328 
   14329   const char* version_string = v8::V8::GetVersion();
   14330 
   14331   return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string),
   14332                                                   NOT_TENURED);
   14333 }
   14334 
   14335 
   14336 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
   14337   SealHandleScope shs(isolate);
   14338   ASSERT(args.length() == 2);
   14339   OS::PrintError("abort: %s\n",
   14340                  reinterpret_cast<char*>(args[0]) + args.smi_at(1));
   14341   isolate->PrintStack(stderr);
   14342   OS::Abort();
   14343   UNREACHABLE();
   14344   return NULL;
   14345 }
   14346 
   14347 
   14348 RUNTIME_FUNCTION(MaybeObject*, Runtime_AbortJS) {
   14349   HandleScope scope(isolate);
   14350   ASSERT(args.length() == 1);
   14351   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
   14352   OS::PrintError("abort: %s\n", *message->ToCString());
   14353   isolate->PrintStack(stderr);
   14354   OS::Abort();
   14355   UNREACHABLE();
   14356   return NULL;
   14357 }
   14358 
   14359 
   14360 RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) {
   14361   HandleScope scope(isolate);
   14362   ASSERT(args.length() == 1);
   14363   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   14364   FlattenString(str);
   14365   return isolate->heap()->undefined_value();
   14366 }
   14367 
   14368 
   14369 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
   14370   HandleScope scope(isolate);
   14371   ASSERT(args.length() == 0);
   14372   isolate->heap()->NotifyContextDisposed();
   14373   return isolate->heap()->undefined_value();
   14374 }
   14375 
   14376 
   14377 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) {
   14378   HandleScope scope(isolate);
   14379   ASSERT(args.length() == 1);
   14380   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   14381   if (!object->IsJSObject()) return Smi::FromInt(0);
   14382   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   14383   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
   14384   JSObject::MigrateInstance(js_object);
   14385   return *object;
   14386 }
   14387 
   14388 
   14389 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
   14390   SealHandleScope shs(isolate);
   14391   // This is only called from codegen, so checks might be more lax.
   14392   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
   14393   Object* key = args[1];
   14394 
   14395   int finger_index = cache->finger_index();
   14396   Object* o = cache->get(finger_index);
   14397   if (o == key) {
   14398     // The fastest case: hit the same place again.
   14399     return cache->get(finger_index + 1);
   14400   }
   14401 
   14402   for (int i = finger_index - 2;
   14403        i >= JSFunctionResultCache::kEntriesIndex;
   14404        i -= 2) {
   14405     o = cache->get(i);
   14406     if (o == key) {
   14407       cache->set_finger_index(i);
   14408       return cache->get(i + 1);
   14409     }
   14410   }
   14411 
   14412   int size = cache->size();
   14413   ASSERT(size <= cache->length());
   14414 
   14415   for (int i = size - 2; i > finger_index; i -= 2) {
   14416     o = cache->get(i);
   14417     if (o == key) {
   14418       cache->set_finger_index(i);
   14419       return cache->get(i + 1);
   14420     }
   14421   }
   14422 
   14423   // There is no value in the cache.  Invoke the function and cache result.
   14424   HandleScope scope(isolate);
   14425 
   14426   Handle<JSFunctionResultCache> cache_handle(cache);
   14427   Handle<Object> key_handle(key, isolate);
   14428   Handle<Object> value;
   14429   {
   14430     Handle<JSFunction> factory(JSFunction::cast(
   14431           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
   14432     // TODO(antonm): consider passing a receiver when constructing a cache.
   14433     Handle<Object> receiver(isolate->native_context()->global_object(),
   14434                             isolate);
   14435     // This handle is nor shared, nor used later, so it's safe.
   14436     Handle<Object> argv[] = { key_handle };
   14437     bool pending_exception;
   14438     value = Execution::Call(isolate,
   14439                             factory,
   14440                             receiver,
   14441                             ARRAY_SIZE(argv),
   14442                             argv,
   14443                             &pending_exception);
   14444     if (pending_exception) return Failure::Exception();
   14445   }
   14446 
   14447 #ifdef VERIFY_HEAP
   14448   if (FLAG_verify_heap) {
   14449     cache_handle->JSFunctionResultCacheVerify();
   14450   }
   14451 #endif
   14452 
   14453   // Function invocation may have cleared the cache.  Reread all the data.
   14454   finger_index = cache_handle->finger_index();
   14455   size = cache_handle->size();
   14456 
   14457   // If we have spare room, put new data into it, otherwise evict post finger
   14458   // entry which is likely to be the least recently used.
   14459   int index = -1;
   14460   if (size < cache_handle->length()) {
   14461     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
   14462     index = size;
   14463   } else {
   14464     index = finger_index + JSFunctionResultCache::kEntrySize;
   14465     if (index == cache_handle->length()) {
   14466       index = JSFunctionResultCache::kEntriesIndex;
   14467     }
   14468   }
   14469 
   14470   ASSERT(index % 2 == 0);
   14471   ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
   14472   ASSERT(index < cache_handle->length());
   14473 
   14474   cache_handle->set(index, *key_handle);
   14475   cache_handle->set(index + 1, *value);
   14476   cache_handle->set_finger_index(index);
   14477 
   14478 #ifdef VERIFY_HEAP
   14479   if (FLAG_verify_heap) {
   14480     cache_handle->JSFunctionResultCacheVerify();
   14481   }
   14482 #endif
   14483 
   14484   return *value;
   14485 }
   14486 
   14487 
   14488 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
   14489   SealHandleScope shs(isolate);
   14490   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14491   return Smi::FromInt(message->start_position());
   14492 }
   14493 
   14494 
   14495 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
   14496   SealHandleScope shs(isolate);
   14497   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14498   return message->script();
   14499 }
   14500 
   14501 
   14502 #ifdef DEBUG
   14503 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
   14504 // Exclude the code in release mode.
   14505 RUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
   14506   HandleScope scope(isolate);
   14507   ASSERT(args.length() == 0);
   14508 #define COUNT_ENTRY(Name, argc, ressize) + 1
   14509   int entry_count = 0
   14510       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
   14511       INLINE_FUNCTION_LIST(COUNT_ENTRY)
   14512       INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY);
   14513 #undef COUNT_ENTRY
   14514   Factory* factory = isolate->factory();
   14515   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
   14516   int index = 0;
   14517   bool inline_runtime_functions = false;
   14518 #define ADD_ENTRY(Name, argc, ressize)                                       \
   14519   {                                                                          \
   14520     HandleScope inner(isolate);                                              \
   14521     Handle<String> name;                                                     \
   14522     /* Inline runtime functions have an underscore in front of the name. */  \
   14523     if (inline_runtime_functions) {                                          \
   14524       name = factory->NewStringFromAscii(                                    \
   14525           Vector<const char>("_" #Name, StrLength("_" #Name)));              \
   14526     } else {                                                                 \
   14527       name = factory->NewStringFromAscii(                                    \
   14528           Vector<const char>(#Name, StrLength(#Name)));                      \
   14529     }                                                                        \
   14530     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
   14531     pair_elements->set(0, *name);                                            \
   14532     pair_elements->set(1, Smi::FromInt(argc));                               \
   14533     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
   14534     elements->set(index++, *pair);                                           \
   14535   }
   14536   inline_runtime_functions = false;
   14537   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   14538   inline_runtime_functions = true;
   14539   INLINE_FUNCTION_LIST(ADD_ENTRY)
   14540   INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   14541 #undef ADD_ENTRY
   14542   ASSERT_EQ(index, entry_count);
   14543   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
   14544   return *result;
   14545 }
   14546 #endif
   14547 
   14548 
   14549 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
   14550   SealHandleScope shs(isolate);
   14551   ASSERT(args.length() == 2);
   14552   CONVERT_ARG_CHECKED(String, format, 0);
   14553   CONVERT_ARG_CHECKED(JSArray, elms, 1);
   14554   DisallowHeapAllocation no_gc;
   14555   String::FlatContent format_content = format->GetFlatContent();
   14556   RUNTIME_ASSERT(format_content.IsAscii());
   14557   Vector<const uint8_t> chars = format_content.ToOneByteVector();
   14558   isolate->logger()->LogRuntime(Vector<const char>::cast(chars), elms);
   14559   return isolate->heap()->undefined_value();
   14560 }
   14561 
   14562 
   14563 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
   14564   UNREACHABLE();  // implemented as macro in the parser
   14565   return NULL;
   14566 }
   14567 
   14568 
   14569 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
   14570   RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) {     \
   14571     CONVERT_ARG_CHECKED(JSObject, obj, 0);              \
   14572     return isolate->heap()->ToBoolean(obj->Has##Name());  \
   14573   }
   14574 
   14575 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
   14576 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
   14577 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
   14578 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
   14579 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
   14580 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
   14581 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(NonStrictArgumentsElements)
   14582 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
   14583 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
   14584 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
   14585 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
   14586 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
   14587 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
   14588 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
   14589 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
   14590 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
   14591 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
   14592 // Properties test sitting with elements tests - not fooling anyone.
   14593 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
   14594 
   14595 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
   14596 
   14597 
   14598 RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
   14599   SealHandleScope shs(isolate);
   14600   ASSERT(args.length() == 2);
   14601   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
   14602   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
   14603   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
   14604 }
   14605 
   14606 
   14607 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessCheckNeeded) {
   14608   SealHandleScope shs(isolate);
   14609   ASSERT(args.length() == 1);
   14610   CONVERT_ARG_CHECKED(HeapObject, obj, 0);
   14611   return isolate->heap()->ToBoolean(obj->IsAccessCheckNeeded());
   14612 }
   14613 
   14614 
   14615 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
   14616   SealHandleScope shs(isolate);
   14617   ASSERT(args.length() == 1);
   14618 
   14619   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
   14620   JSReceiver* obj = JSReceiver::cast(args[0]);
   14621   if (obj->IsJSGlobalProxy()) {
   14622     Object* proto = obj->GetPrototype();
   14623     if (proto->IsNull()) return isolate->heap()->false_value();
   14624     ASSERT(proto->IsJSGlobalObject());
   14625     obj = JSReceiver::cast(proto);
   14626   }
   14627   return isolate->heap()->ToBoolean(obj->map()->is_observed());
   14628 }
   14629 
   14630 
   14631 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) {
   14632   HandleScope scope(isolate);
   14633   ASSERT(args.length() == 1);
   14634   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
   14635   if (obj->IsJSGlobalProxy()) {
   14636     Object* proto = obj->GetPrototype();
   14637     if (proto->IsNull()) return isolate->heap()->undefined_value();
   14638     ASSERT(proto->IsJSGlobalObject());
   14639     obj = handle(JSReceiver::cast(proto));
   14640   }
   14641   if (obj->IsJSProxy())
   14642     return isolate->heap()->undefined_value();
   14643 
   14644   ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() &&
   14645            Handle<JSObject>::cast(obj)->HasFastElements()));
   14646   ASSERT(obj->IsJSObject());
   14647   JSObject::SetObserved(Handle<JSObject>::cast(obj));
   14648   return isolate->heap()->undefined_value();
   14649 }
   14650 
   14651 
   14652 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetMicrotaskPending) {
   14653   SealHandleScope shs(isolate);
   14654   ASSERT(args.length() == 1);
   14655   CONVERT_BOOLEAN_ARG_CHECKED(new_state, 0);
   14656   bool old_state = isolate->microtask_pending();
   14657   isolate->set_microtask_pending(new_state);
   14658   return isolate->heap()->ToBoolean(old_state);
   14659 }
   14660 
   14661 
   14662 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetObservationState) {
   14663   SealHandleScope shs(isolate);
   14664   ASSERT(args.length() == 0);
   14665   return isolate->heap()->observation_state();
   14666 }
   14667 
   14668 
   14669 RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapCreate) {
   14670   HandleScope scope(isolate);
   14671   ASSERT(args.length() == 0);
   14672   // TODO(adamk): Currently this runtime function is only called three times per
   14673   // isolate. If it's called more often, the map should be moved into the
   14674   // strong root list.
   14675   Handle<Map> map =
   14676       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
   14677   Handle<JSWeakMap> weakmap =
   14678       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
   14679   return WeakCollectionInitialize(isolate, weakmap);
   14680 }
   14681 
   14682 
   14683 RUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) {
   14684   SealHandleScope shs(isolate);
   14685   ASSERT(args.length() == 1);
   14686   Object* object = args[0];
   14687   if (object->IsJSGlobalProxy()) {
   14688     object = object->GetPrototype(isolate);
   14689     if (object->IsNull()) return isolate->heap()->undefined_value();
   14690   }
   14691   return object;
   14692 }
   14693 
   14694 
   14695 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) {
   14696   HandleScope scope(isolate);
   14697   ASSERT(args.length() == 3);
   14698   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
   14699   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
   14700   ASSERT(object->IsAccessCheckNeeded());
   14701   Handle<Object> key = args.at<Object>(2);
   14702   SaveContext save(isolate);
   14703   isolate->set_context(observer->context());
   14704   if (!isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
   14705                                v8::ACCESS_KEYS)) {
   14706     return isolate->heap()->false_value();
   14707   }
   14708   bool access_allowed = false;
   14709   uint32_t index = 0;
   14710   if (key->ToArrayIndex(&index) ||
   14711       (key->IsString() && String::cast(*key)->AsArrayIndex(&index))) {
   14712     access_allowed =
   14713         isolate->MayIndexedAccess(*object, index, v8::ACCESS_GET) &&
   14714         isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS);
   14715   } else {
   14716     access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) &&
   14717         isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS);
   14718   }
   14719   return isolate->heap()->ToBoolean(access_allowed);
   14720 }
   14721 
   14722 
   14723 static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
   14724                                            Handle<JSFunction> constructor,
   14725                                            Handle<AllocationSite> site,
   14726                                            Arguments* caller_args) {
   14727   bool holey = false;
   14728   bool can_use_type_feedback = true;
   14729   if (caller_args->length() == 1) {
   14730     Object* argument_one = (*caller_args)[0];
   14731     if (argument_one->IsSmi()) {
   14732       int value = Smi::cast(argument_one)->value();
   14733       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
   14734         // the array is a dictionary in this case.
   14735         can_use_type_feedback = false;
   14736       } else if (value != 0) {
   14737         holey = true;
   14738       }
   14739     } else {
   14740       // Non-smi length argument produces a dictionary
   14741       can_use_type_feedback = false;
   14742     }
   14743   }
   14744 
   14745   JSArray* array;
   14746   MaybeObject* maybe_array;
   14747   if (!site.is_null() && can_use_type_feedback) {
   14748     ElementsKind to_kind = site->GetElementsKind();
   14749     if (holey && !IsFastHoleyElementsKind(to_kind)) {
   14750       to_kind = GetHoleyElementsKind(to_kind);
   14751       // Update the allocation site info to reflect the advice alteration.
   14752       site->SetElementsKind(to_kind);
   14753     }
   14754 
   14755     maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
   14756         *constructor, site);
   14757     if (!maybe_array->To(&array)) return maybe_array;
   14758   } else {
   14759     maybe_array = isolate->heap()->AllocateJSObject(*constructor);
   14760     if (!maybe_array->To(&array)) return maybe_array;
   14761     // We might need to transition to holey
   14762     ElementsKind kind = constructor->initial_map()->elements_kind();
   14763     if (holey && !IsFastHoleyElementsKind(kind)) {
   14764       kind = GetHoleyElementsKind(kind);
   14765       maybe_array = array->TransitionElementsKind(kind);
   14766       if (maybe_array->IsFailure()) return maybe_array;
   14767     }
   14768   }
   14769 
   14770   maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0,
   14771       DONT_INITIALIZE_ARRAY_ELEMENTS);
   14772   if (maybe_array->IsFailure()) return maybe_array;
   14773   ElementsKind old_kind = array->GetElementsKind();
   14774   maybe_array = ArrayConstructInitializeElements(array, caller_args);
   14775   if (maybe_array->IsFailure()) return maybe_array;
   14776   if (!site.is_null() &&
   14777       (old_kind != array->GetElementsKind() ||
   14778        !can_use_type_feedback)) {
   14779     // The arguments passed in caused a transition. This kind of complexity
   14780     // can't be dealt with in the inlined hydrogen array constructor case.
   14781     // We must mark the allocationsite as un-inlinable.
   14782     site->SetDoNotInlineCall();
   14783   }
   14784   return array;
   14785 }
   14786 
   14787 
   14788 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
   14789   HandleScope scope(isolate);
   14790   // If we get 2 arguments then they are the stub parameters (constructor, type
   14791   // info).  If we get 4, then the first one is a pointer to the arguments
   14792   // passed by the caller, and the last one is the length of the arguments
   14793   // passed to the caller (redundant, but useful to check on the deoptimizer
   14794   // with an assert).
   14795   Arguments empty_args(0, NULL);
   14796   bool no_caller_args = args.length() == 2;
   14797   ASSERT(no_caller_args || args.length() == 4);
   14798   int parameters_start = no_caller_args ? 0 : 1;
   14799   Arguments* caller_args = no_caller_args
   14800       ? &empty_args
   14801       : reinterpret_cast<Arguments*>(args[0]);
   14802   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   14803   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
   14804 #ifdef DEBUG
   14805   if (!no_caller_args) {
   14806     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
   14807     ASSERT(arg_count == caller_args->length());
   14808   }
   14809 #endif
   14810 
   14811   Handle<AllocationSite> site;
   14812   if (!type_info.is_null() &&
   14813       *type_info != isolate->heap()->undefined_value() &&
   14814       Cell::cast(*type_info)->value()->IsAllocationSite()) {
   14815     site = Handle<AllocationSite>(
   14816         AllocationSite::cast(Cell::cast(*type_info)->value()), isolate);
   14817     ASSERT(!site->SitePointsToLiteral());
   14818   }
   14819 
   14820   return ArrayConstructorCommon(isolate,
   14821                                 constructor,
   14822                                 site,
   14823                                 caller_args);
   14824 }
   14825 
   14826 
   14827 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) {
   14828   HandleScope scope(isolate);
   14829   Arguments empty_args(0, NULL);
   14830   bool no_caller_args = args.length() == 1;
   14831   ASSERT(no_caller_args || args.length() == 3);
   14832   int parameters_start = no_caller_args ? 0 : 1;
   14833   Arguments* caller_args = no_caller_args
   14834       ? &empty_args
   14835       : reinterpret_cast<Arguments*>(args[0]);
   14836   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   14837 #ifdef DEBUG
   14838   if (!no_caller_args) {
   14839     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
   14840     ASSERT(arg_count == caller_args->length());
   14841   }
   14842 #endif
   14843   return ArrayConstructorCommon(isolate,
   14844                                 constructor,
   14845                                 Handle<AllocationSite>::null(),
   14846                                 caller_args);
   14847 }
   14848 
   14849 
   14850 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaxSmi) {
   14851   return Smi::FromInt(Smi::kMaxValue);
   14852 }
   14853 
   14854 
   14855 // ----------------------------------------------------------------------------
   14856 // Implementation of Runtime
   14857 
   14858 #define F(name, number_of_args, result_size)                             \
   14859   { Runtime::k##name, Runtime::RUNTIME, #name,   \
   14860     FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
   14861 
   14862 
   14863 #define I(name, number_of_args, result_size)                             \
   14864   { Runtime::kInline##name, Runtime::INLINE,     \
   14865     "_" #name, NULL, number_of_args, result_size },
   14866 
   14867 static const Runtime::Function kIntrinsicFunctions[] = {
   14868   RUNTIME_FUNCTION_LIST(F)
   14869   INLINE_FUNCTION_LIST(I)
   14870   INLINE_RUNTIME_FUNCTION_LIST(I)
   14871 };
   14872 
   14873 
   14874 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
   14875                                                        Object* dictionary) {
   14876   ASSERT(dictionary != NULL);
   14877   ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0);
   14878   for (int i = 0; i < kNumFunctions; ++i) {
   14879     Object* name_string;
   14880     { MaybeObject* maybe_name_string =
   14881           heap->InternalizeUtf8String(kIntrinsicFunctions[i].name);
   14882       if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
   14883     }
   14884     NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
   14885     { MaybeObject* maybe_dictionary = name_dictionary->Add(
   14886           String::cast(name_string),
   14887           Smi::FromInt(i),
   14888           PropertyDetails(NONE, NORMAL, Representation::None()));
   14889       if (!maybe_dictionary->ToObject(&dictionary)) {
   14890         // Non-recoverable failure.  Calling code must restart heap
   14891         // initialization.
   14892         return maybe_dictionary;
   14893       }
   14894     }
   14895   }
   14896   return dictionary;
   14897 }
   14898 
   14899 
   14900 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
   14901   Heap* heap = name->GetHeap();
   14902   int entry = heap->intrinsic_function_names()->FindEntry(*name);
   14903   if (entry != kNotFound) {
   14904     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
   14905     int function_index = Smi::cast(smi_index)->value();
   14906     return &(kIntrinsicFunctions[function_index]);
   14907   }
   14908   return NULL;
   14909 }
   14910 
   14911 
   14912 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
   14913   return &(kIntrinsicFunctions[static_cast<int>(id)]);
   14914 }
   14915 
   14916 
   14917 void Runtime::PerformGC(Object* result, Isolate* isolate) {
   14918   Failure* failure = Failure::cast(result);
   14919   if (failure->IsRetryAfterGC()) {
   14920     if (isolate->heap()->new_space()->AddFreshPage()) {
   14921       return;
   14922     }
   14923 
   14924     // Try to do a garbage collection; ignore it if it fails. The C
   14925     // entry stub will throw an out-of-memory exception in that case.
   14926     isolate->heap()->CollectGarbage(failure->allocation_space(),
   14927                                     "Runtime::PerformGC");
   14928   } else {
   14929     // Handle last resort GC and make sure to allow future allocations
   14930     // to grow the heap without causing GCs (if possible).
   14931     isolate->counters()->gc_last_resort_from_js()->Increment();
   14932     isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
   14933                                        "Runtime::PerformGC");
   14934   }
   14935 }
   14936 
   14937 
   14938 } }  // namespace v8::internal
   14939