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 "api.h"
     35 #include "arguments.h"
     36 #include "bootstrapper.h"
     37 #include "codegen.h"
     38 #include "compilation-cache.h"
     39 #include "compiler.h"
     40 #include "cpu.h"
     41 #include "cpu-profiler.h"
     42 #include "dateparser-inl.h"
     43 #include "debug.h"
     44 #include "deoptimizer.h"
     45 #include "date.h"
     46 #include "execution.h"
     47 #include "full-codegen.h"
     48 #include "global-handles.h"
     49 #include "isolate-inl.h"
     50 #include "jsregexp.h"
     51 #include "jsregexp-inl.h"
     52 #include "json-parser.h"
     53 #include "json-stringifier.h"
     54 #include "liveedit.h"
     55 #include "misc-intrinsics.h"
     56 #include "parser.h"
     57 #include "platform.h"
     58 #include "runtime-profiler.h"
     59 #include "runtime.h"
     60 #include "scopeinfo.h"
     61 #include "smart-pointers.h"
     62 #include "string-search.h"
     63 #include "stub-cache.h"
     64 #include "uri.h"
     65 #include "v8conversions.h"
     66 #include "v8threads.h"
     67 #include "vm-state-inl.h"
     68 
     69 #ifdef V8_I18N_SUPPORT
     70 #include "i18n.h"
     71 #include "unicode/brkiter.h"
     72 #include "unicode/calendar.h"
     73 #include "unicode/coll.h"
     74 #include "unicode/curramt.h"
     75 #include "unicode/datefmt.h"
     76 #include "unicode/dcfmtsym.h"
     77 #include "unicode/decimfmt.h"
     78 #include "unicode/dtfmtsym.h"
     79 #include "unicode/dtptngen.h"
     80 #include "unicode/locid.h"
     81 #include "unicode/numfmt.h"
     82 #include "unicode/numsys.h"
     83 #include "unicode/smpdtfmt.h"
     84 #include "unicode/timezone.h"
     85 #include "unicode/uchar.h"
     86 #include "unicode/ucol.h"
     87 #include "unicode/ucurr.h"
     88 #include "unicode/uloc.h"
     89 #include "unicode/unum.h"
     90 #include "unicode/uversion.h"
     91 #endif
     92 
     93 #ifndef _STLP_VENDOR_CSTD
     94 // STLPort doesn't import fpclassify and isless into the std namespace.
     95 using std::fpclassify;
     96 using std::isless;
     97 #endif
     98 
     99 namespace v8 {
    100 namespace internal {
    101 
    102 
    103 #define RUNTIME_ASSERT(value) \
    104   if (!(value)) return isolate->ThrowIllegalOperation();
    105 
    106 // Cast the given object to a value of the specified type and store
    107 // it in a variable with the given name.  If the object is not of the
    108 // expected type call IllegalOperation and return.
    109 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
    110   RUNTIME_ASSERT(args[index]->Is##Type());                           \
    111   Type* name = Type::cast(args[index]);
    112 
    113 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
    114   RUNTIME_ASSERT(args[index]->Is##Type());                           \
    115   Handle<Type> name = args.at<Type>(index);
    116 
    117 // Cast the given object to a boolean and store it in a variable with
    118 // the given name.  If the object is not a boolean call IllegalOperation
    119 // and return.
    120 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
    121   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
    122   bool name = args[index]->IsTrue();
    123 
    124 // Cast the given argument to a Smi and store its value in an int variable
    125 // with the given name.  If the argument is not a Smi call IllegalOperation
    126 // and return.
    127 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
    128   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    129   int name = args.smi_at(index);
    130 
    131 // Cast the given argument to a double and store it in a variable with
    132 // the given name.  If the argument is not a number (as opposed to
    133 // the number not-a-number) call IllegalOperation and return.
    134 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
    135   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    136   double name = args.number_at(index);
    137 
    138 // Call the specified converter on the object *comand store the result in
    139 // a variable of the specified type with the given name.  If the
    140 // object is not a Number call IllegalOperation and return.
    141 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
    142   RUNTIME_ASSERT(obj->IsNumber());                                   \
    143   type name = NumberTo##Type(obj);
    144 
    145 
    146 // Cast the given argument to PropertyDetails and store its value in a
    147 // variable with the given name.  If the argument is not a Smi call
    148 // IllegalOperation and return.
    149 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
    150   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    151   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
    152 
    153 
    154 // Assert that the given argument has a valid value for a StrictModeFlag
    155 // and store it in a StrictModeFlag variable with the given name.
    156 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
    157   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    158   RUNTIME_ASSERT(args.smi_at(index) == kStrictMode ||                \
    159                  args.smi_at(index) == kNonStrictMode);              \
    160   StrictModeFlag name =                                              \
    161       static_cast<StrictModeFlag>(args.smi_at(index));
    162 
    163 
    164 // Assert that the given argument has a valid value for a LanguageMode
    165 // and store it in a LanguageMode variable with the given name.
    166 #define CONVERT_LANGUAGE_MODE_ARG(name, index)                       \
    167   ASSERT(args[index]->IsSmi());                                      \
    168   ASSERT(args.smi_at(index) == CLASSIC_MODE ||                       \
    169          args.smi_at(index) == STRICT_MODE ||                        \
    170          args.smi_at(index) == EXTENDED_MODE);                       \
    171   LanguageMode name =                                                \
    172       static_cast<LanguageMode>(args.smi_at(index));
    173 
    174 
    175 static Handle<Map> ComputeObjectLiteralMap(
    176     Handle<Context> context,
    177     Handle<FixedArray> constant_properties,
    178     bool* is_result_from_cache) {
    179   Isolate* isolate = context->GetIsolate();
    180   int properties_length = constant_properties->length();
    181   int number_of_properties = properties_length / 2;
    182   // Check that there are only internal strings and array indices among keys.
    183   int number_of_string_keys = 0;
    184   for (int p = 0; p != properties_length; p += 2) {
    185     Object* key = constant_properties->get(p);
    186     uint32_t element_index = 0;
    187     if (key->IsInternalizedString()) {
    188       number_of_string_keys++;
    189     } else if (key->ToArrayIndex(&element_index)) {
    190       // An index key does not require space in the property backing store.
    191       number_of_properties--;
    192     } else {
    193       // Bail out as a non-internalized-string non-index key makes caching
    194       // impossible.
    195       // ASSERT to make sure that the if condition after the loop is false.
    196       ASSERT(number_of_string_keys != number_of_properties);
    197       break;
    198     }
    199   }
    200   // If we only have internalized strings and array indices among keys then we
    201   // can use the map cache in the native context.
    202   const int kMaxKeys = 10;
    203   if ((number_of_string_keys == number_of_properties) &&
    204       (number_of_string_keys < kMaxKeys)) {
    205     // Create the fixed array with the key.
    206     Handle<FixedArray> keys =
    207         isolate->factory()->NewFixedArray(number_of_string_keys);
    208     if (number_of_string_keys > 0) {
    209       int index = 0;
    210       for (int p = 0; p < properties_length; p += 2) {
    211         Object* key = constant_properties->get(p);
    212         if (key->IsInternalizedString()) {
    213           keys->set(index++, key);
    214         }
    215       }
    216       ASSERT(index == number_of_string_keys);
    217     }
    218     *is_result_from_cache = true;
    219     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
    220   }
    221   *is_result_from_cache = false;
    222   return isolate->factory()->CopyMap(
    223       Handle<Map>(context->object_function()->initial_map()),
    224       number_of_properties);
    225 }
    226 
    227 
    228 static Handle<Object> CreateLiteralBoilerplate(
    229     Isolate* isolate,
    230     Handle<FixedArray> literals,
    231     Handle<FixedArray> constant_properties);
    232 
    233 
    234 static Handle<Object> CreateObjectLiteralBoilerplate(
    235     Isolate* isolate,
    236     Handle<FixedArray> literals,
    237     Handle<FixedArray> constant_properties,
    238     bool should_have_fast_elements,
    239     bool has_function_literal) {
    240   // Get the native context from the literals array.  This is the
    241   // context in which the function was created and we use the object
    242   // function from this context to create the object literal.  We do
    243   // not use the object function from the current native context
    244   // because this might be the object function from another context
    245   // which we should not have access to.
    246   Handle<Context> context =
    247       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
    248 
    249   // In case we have function literals, we want the object to be in
    250   // slow properties mode for now. We don't go in the map cache because
    251   // maps with constant functions can't be shared if the functions are
    252   // not the same (which is the common case).
    253   bool is_result_from_cache = false;
    254   Handle<Map> map = has_function_literal
    255       ? Handle<Map>(context->object_function()->initial_map())
    256       : ComputeObjectLiteralMap(context,
    257                                 constant_properties,
    258                                 &is_result_from_cache);
    259 
    260   Handle<JSObject> boilerplate =
    261       isolate->factory()->NewJSObjectFromMap(
    262           map, isolate->heap()->GetPretenureMode());
    263 
    264   // Normalize the elements of the boilerplate to save space if needed.
    265   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
    266 
    267   // Add the constant properties to the boilerplate.
    268   int length = constant_properties->length();
    269   bool should_transform =
    270       !is_result_from_cache && boilerplate->HasFastProperties();
    271   if (should_transform || has_function_literal) {
    272     // Normalize the properties of object to avoid n^2 behavior
    273     // when extending the object multiple properties. Indicate the number of
    274     // properties to be added.
    275     JSObject::NormalizeProperties(
    276         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
    277   }
    278 
    279   // TODO(verwaest): Support tracking representations in the boilerplate.
    280   for (int index = 0; index < length; index +=2) {
    281     Handle<Object> key(constant_properties->get(index+0), isolate);
    282     Handle<Object> value(constant_properties->get(index+1), isolate);
    283     if (value->IsFixedArray()) {
    284       // The value contains the constant_properties of a
    285       // simple object or array literal.
    286       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
    287       value = CreateLiteralBoilerplate(isolate, literals, array);
    288       if (value.is_null()) return value;
    289     }
    290     Handle<Object> result;
    291     uint32_t element_index = 0;
    292     JSReceiver::StoreMode mode = value->IsJSObject()
    293         ? JSReceiver::FORCE_FIELD
    294         : JSReceiver::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     Handle<Object> result = JSObject::TransitionElementsKind(
    353         Handle<JSObject>::cast(object), to_kind);
    354     if (result.is_null()) return isolate->ThrowIllegalOperation();
    355     return *result;
    356   }
    357   return isolate->ThrowIllegalOperation();
    358 }
    359 
    360 
    361 static const int kSmiLiteralMinimumLength = 1024;
    362 
    363 
    364 Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
    365     Isolate* isolate,
    366     Handle<FixedArray> literals,
    367     Handle<FixedArray> elements) {
    368   // Create the JSArray.
    369   Handle<JSFunction> constructor(
    370       JSFunction::NativeContextFromLiterals(*literals)->array_function());
    371 
    372   Handle<JSArray> object = Handle<JSArray>::cast(
    373       isolate->factory()->NewJSObject(
    374           constructor, isolate->heap()->GetPretenureMode()));
    375 
    376   ElementsKind constant_elements_kind =
    377       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
    378   Handle<FixedArrayBase> constant_elements_values(
    379       FixedArrayBase::cast(elements->get(1)));
    380 
    381   ASSERT(IsFastElementsKind(constant_elements_kind));
    382   Context* native_context = isolate->context()->native_context();
    383   Object* maybe_maps_array = native_context->js_array_maps();
    384   ASSERT(!maybe_maps_array->IsUndefined());
    385   Object* maybe_map = FixedArray::cast(maybe_maps_array)->get(
    386       constant_elements_kind);
    387   ASSERT(maybe_map->IsMap());
    388   object->set_map(Map::cast(maybe_map));
    389 
    390   Handle<FixedArrayBase> copied_elements_values;
    391   if (IsFastDoubleElementsKind(constant_elements_kind)) {
    392     ASSERT(FLAG_smi_only_arrays);
    393     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
    394         Handle<FixedDoubleArray>::cast(constant_elements_values));
    395   } else {
    396     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
    397     const bool is_cow =
    398         (constant_elements_values->map() ==
    399          isolate->heap()->fixed_cow_array_map());
    400     if (is_cow) {
    401       copied_elements_values = constant_elements_values;
    402 #if DEBUG
    403       Handle<FixedArray> fixed_array_values =
    404           Handle<FixedArray>::cast(copied_elements_values);
    405       for (int i = 0; i < fixed_array_values->length(); i++) {
    406         ASSERT(!fixed_array_values->get(i)->IsFixedArray());
    407       }
    408 #endif
    409     } else {
    410       Handle<FixedArray> fixed_array_values =
    411           Handle<FixedArray>::cast(constant_elements_values);
    412       Handle<FixedArray> fixed_array_values_copy =
    413           isolate->factory()->CopyFixedArray(fixed_array_values);
    414       copied_elements_values = fixed_array_values_copy;
    415       for (int i = 0; i < fixed_array_values->length(); i++) {
    416         Object* current = fixed_array_values->get(i);
    417         if (current->IsFixedArray()) {
    418           // The value contains the constant_properties of a
    419           // simple object or array literal.
    420           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
    421           Handle<Object> result =
    422               CreateLiteralBoilerplate(isolate, literals, fa);
    423           if (result.is_null()) return result;
    424           fixed_array_values_copy->set(i, *result);
    425         }
    426       }
    427     }
    428   }
    429   object->set_elements(*copied_elements_values);
    430   object->set_length(Smi::FromInt(copied_elements_values->length()));
    431 
    432   //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
    433   //  on or the object is larger than the threshold.
    434   if (!FLAG_smi_only_arrays &&
    435       constant_elements_values->length() < kSmiLiteralMinimumLength) {
    436     ElementsKind elements_kind = object->GetElementsKind();
    437     if (!IsFastObjectElementsKind(elements_kind)) {
    438       if (IsFastHoleyElementsKind(elements_kind)) {
    439         CHECK(!TransitionElements(object, FAST_HOLEY_ELEMENTS,
    440                                   isolate)->IsFailure());
    441       } else {
    442         CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
    443       }
    444     }
    445   }
    446 
    447   object->ValidateElements();
    448   return object;
    449 }
    450 
    451 
    452 static Handle<Object> CreateLiteralBoilerplate(
    453     Isolate* isolate,
    454     Handle<FixedArray> literals,
    455     Handle<FixedArray> array) {
    456   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
    457   const bool kHasNoFunctionLiteral = false;
    458   switch (CompileTimeValue::GetLiteralType(array)) {
    459     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
    460       return CreateObjectLiteralBoilerplate(isolate,
    461                                             literals,
    462                                             elements,
    463                                             true,
    464                                             kHasNoFunctionLiteral);
    465     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
    466       return CreateObjectLiteralBoilerplate(isolate,
    467                                             literals,
    468                                             elements,
    469                                             false,
    470                                             kHasNoFunctionLiteral);
    471     case CompileTimeValue::ARRAY_LITERAL:
    472       return Runtime::CreateArrayLiteralBoilerplate(
    473           isolate, literals, elements);
    474     default:
    475       UNREACHABLE();
    476       return Handle<Object>::null();
    477   }
    478 }
    479 
    480 
    481 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
    482   HandleScope scope(isolate);
    483   ASSERT(args.length() == 4);
    484   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    485   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    486   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    487   CONVERT_SMI_ARG_CHECKED(flags, 3);
    488   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    489   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    490 
    491   // Check if boilerplate exists. If not, create it first.
    492   Handle<Object> boilerplate(literals->get(literals_index), isolate);
    493   if (*boilerplate == isolate->heap()->undefined_value()) {
    494     boilerplate = CreateObjectLiteralBoilerplate(isolate,
    495                                                  literals,
    496                                                  constant_properties,
    497                                                  should_have_fast_elements,
    498                                                  has_function_literal);
    499     RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
    500     // Update the functions literal and return the boilerplate.
    501     literals->set(literals_index, *boilerplate);
    502   }
    503   return JSObject::cast(*boilerplate)->DeepCopy(isolate);
    504 }
    505 
    506 
    507 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
    508   HandleScope scope(isolate);
    509   ASSERT(args.length() == 4);
    510   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    511   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    512   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    513   CONVERT_SMI_ARG_CHECKED(flags, 3);
    514   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    515   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    516 
    517   // Check if boilerplate exists. If not, create it first.
    518   Handle<Object> boilerplate(literals->get(literals_index), isolate);
    519   if (*boilerplate == isolate->heap()->undefined_value()) {
    520     boilerplate = CreateObjectLiteralBoilerplate(isolate,
    521                                                  literals,
    522                                                  constant_properties,
    523                                                  should_have_fast_elements,
    524                                                  has_function_literal);
    525     RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
    526     // Update the functions literal and return the boilerplate.
    527     literals->set(literals_index, *boilerplate);
    528   }
    529   return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
    530 }
    531 
    532 
    533 static Handle<AllocationSite> GetLiteralAllocationSite(
    534     Isolate* isolate,
    535     Handle<FixedArray> literals,
    536     int literals_index,
    537     Handle<FixedArray> elements) {
    538   // Check if boilerplate exists. If not, create it first.
    539   Handle<Object> literal_site(literals->get(literals_index), isolate);
    540   Handle<AllocationSite> site;
    541   if (*literal_site == isolate->heap()->undefined_value()) {
    542     ASSERT(*elements != isolate->heap()->empty_fixed_array());
    543     Handle<Object> boilerplate =
    544         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
    545     if (boilerplate.is_null()) return site;
    546     site = isolate->factory()->NewAllocationSite();
    547     site->set_transition_info(*boilerplate);
    548     literals->set(literals_index, *site);
    549   } else {
    550     site = Handle<AllocationSite>::cast(literal_site);
    551   }
    552 
    553   return site;
    554 }
    555 
    556 
    557 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
    558   HandleScope scope(isolate);
    559   ASSERT(args.length() == 3);
    560   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    561   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    562   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    563 
    564   Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
    565       literals_index, elements);
    566   RETURN_IF_EMPTY_HANDLE(isolate, site);
    567 
    568   JSObject* boilerplate = JSObject::cast(site->transition_info());
    569   return boilerplate->DeepCopy(isolate);
    570 }
    571 
    572 
    573 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
    574   HandleScope scope(isolate);
    575   ASSERT(args.length() == 3);
    576   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    577   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    578   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    579 
    580   Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
    581       literals_index, elements);
    582   RETURN_IF_EMPTY_HANDLE(isolate, site);
    583 
    584   JSObject* boilerplate = JSObject::cast(site->transition_info());
    585   if (boilerplate->elements()->map() ==
    586       isolate->heap()->fixed_cow_array_map()) {
    587     isolate->counters()->cow_arrays_created_runtime()->Increment();
    588   }
    589 
    590   AllocationSiteMode mode = AllocationSite::GetMode(
    591       boilerplate->GetElementsKind());
    592   if (mode == TRACK_ALLOCATION_SITE) {
    593     return isolate->heap()->CopyJSObjectWithAllocationSite(
    594         boilerplate, *site);
    595   }
    596 
    597   return isolate->heap()->CopyJSObject(boilerplate);
    598 }
    599 
    600 
    601 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
    602   HandleScope scope(isolate);
    603   ASSERT(args.length() == 1);
    604   Handle<Object> name(args[0], isolate);
    605   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
    606   Symbol* symbol;
    607   MaybeObject* maybe = isolate->heap()->AllocateSymbol();
    608   if (!maybe->To(&symbol)) return maybe;
    609   if (name->IsString()) symbol->set_name(*name);
    610   return symbol;
    611 }
    612 
    613 
    614 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) {
    615   SealHandleScope shs(isolate);
    616   ASSERT(args.length() == 1);
    617   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
    618   return symbol->name();
    619 }
    620 
    621 
    622 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
    623   SealHandleScope shs(isolate);
    624   ASSERT(args.length() == 2);
    625   CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
    626   Object* prototype = args[1];
    627   Object* used_prototype =
    628       prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
    629   return isolate->heap()->AllocateJSProxy(handler, used_prototype);
    630 }
    631 
    632 
    633 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) {
    634   SealHandleScope shs(isolate);
    635   ASSERT(args.length() == 4);
    636   CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
    637   Object* call_trap = args[1];
    638   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
    639   CONVERT_ARG_CHECKED(JSFunction, construct_trap, 2);
    640   Object* prototype = args[3];
    641   Object* used_prototype =
    642       prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
    643   return isolate->heap()->AllocateJSFunctionProxy(
    644       handler, call_trap, construct_trap, used_prototype);
    645 }
    646 
    647 
    648 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
    649   SealHandleScope shs(isolate);
    650   ASSERT(args.length() == 1);
    651   Object* obj = args[0];
    652   return isolate->heap()->ToBoolean(obj->IsJSProxy());
    653 }
    654 
    655 
    656 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) {
    657   SealHandleScope shs(isolate);
    658   ASSERT(args.length() == 1);
    659   Object* obj = args[0];
    660   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
    661 }
    662 
    663 
    664 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
    665   SealHandleScope shs(isolate);
    666   ASSERT(args.length() == 1);
    667   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    668   return proxy->handler();
    669 }
    670 
    671 
    672 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
    673   SealHandleScope shs(isolate);
    674   ASSERT(args.length() == 1);
    675   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    676   return proxy->call_trap();
    677 }
    678 
    679 
    680 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
    681   SealHandleScope shs(isolate);
    682   ASSERT(args.length() == 1);
    683   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    684   return proxy->construct_trap();
    685 }
    686 
    687 
    688 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
    689   SealHandleScope shs(isolate);
    690   ASSERT(args.length() == 1);
    691   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    692   proxy->Fix();
    693   return isolate->heap()->undefined_value();
    694 }
    695 
    696 
    697 void Runtime::FreeArrayBuffer(Isolate* isolate,
    698                               JSArrayBuffer* phantom_array_buffer) {
    699   if (phantom_array_buffer->is_external()) return;
    700 
    701   size_t allocated_length = NumberToSize(
    702       isolate, phantom_array_buffer->byte_length());
    703 
    704   isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
    705       -static_cast<intptr_t>(allocated_length));
    706   CHECK(V8::ArrayBufferAllocator() != NULL);
    707   V8::ArrayBufferAllocator()->Free(
    708       phantom_array_buffer->backing_store(),
    709       allocated_length);
    710 }
    711 
    712 
    713 void Runtime::SetupArrayBuffer(Isolate* isolate,
    714                                Handle<JSArrayBuffer> array_buffer,
    715                                bool is_external,
    716                                void* data,
    717                                size_t allocated_length) {
    718   ASSERT(array_buffer->GetInternalFieldCount() ==
    719       v8::ArrayBuffer::kInternalFieldCount);
    720   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
    721     array_buffer->SetInternalField(i, Smi::FromInt(0));
    722   }
    723   array_buffer->set_backing_store(data);
    724   array_buffer->set_flag(Smi::FromInt(0));
    725   array_buffer->set_is_external(is_external);
    726 
    727   Handle<Object> byte_length =
    728       isolate->factory()->NewNumberFromSize(allocated_length);
    729   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
    730   array_buffer->set_byte_length(*byte_length);
    731 
    732   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
    733   isolate->heap()->set_array_buffers_list(*array_buffer);
    734   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
    735 }
    736 
    737 
    738 bool Runtime::SetupArrayBufferAllocatingData(
    739     Isolate* isolate,
    740     Handle<JSArrayBuffer> array_buffer,
    741     size_t allocated_length,
    742     bool initialize) {
    743   void* data;
    744   CHECK(V8::ArrayBufferAllocator() != NULL);
    745   if (allocated_length != 0) {
    746     if (initialize) {
    747       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
    748     } else {
    749       data =
    750         V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
    751     }
    752     if (data == NULL) return false;
    753   } else {
    754     data = NULL;
    755   }
    756 
    757   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
    758 
    759   isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
    760 
    761   return true;
    762 }
    763 
    764 
    765 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
    766   HandleScope scope(isolate);
    767   ASSERT(args.length() == 2);
    768   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
    769   CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
    770   size_t allocated_length;
    771   if (byteLength->IsSmi()) {
    772     allocated_length = Smi::cast(*byteLength)->value();
    773   } else {
    774     ASSERT(byteLength->IsHeapNumber());
    775     double value = HeapNumber::cast(*byteLength)->value();
    776 
    777     ASSERT(value >= 0);
    778 
    779     if (value > std::numeric_limits<size_t>::max()) {
    780       return isolate->Throw(
    781           *isolate->factory()->NewRangeError("invalid_array_buffer_length",
    782             HandleVector<Object>(NULL, 0)));
    783     }
    784 
    785     allocated_length = static_cast<size_t>(value);
    786   }
    787 
    788   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
    789                                                holder, allocated_length)) {
    790       return isolate->Throw(*isolate->factory()->
    791           NewRangeError("invalid_array_buffer_length",
    792             HandleVector<Object>(NULL, 0)));
    793   }
    794 
    795   return *holder;
    796 }
    797 
    798 
    799 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
    800   SealHandleScope shs(isolate);
    801   ASSERT(args.length() == 1);
    802   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
    803   return holder->byte_length();
    804 }
    805 
    806 
    807 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
    808   HandleScope scope(isolate);
    809   ASSERT(args.length() == 3);
    810   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
    811   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
    812   CONVERT_DOUBLE_ARG_CHECKED(first, 2);
    813   size_t start = static_cast<size_t>(first);
    814   size_t target_length = NumberToSize(isolate, target->byte_length());
    815 
    816   if (target_length == 0) return isolate->heap()->undefined_value();
    817 
    818   ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start);
    819   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
    820   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
    821   CopyBytes(target_data, source_data + start, target_length);
    822   return isolate->heap()->undefined_value();
    823 }
    824 
    825 
    826 enum TypedArrayId {
    827   // arrayIds below should be synchromized with typedarray.js natives.
    828   ARRAY_ID_UINT8 = 1,
    829   ARRAY_ID_INT8 = 2,
    830   ARRAY_ID_UINT16 = 3,
    831   ARRAY_ID_INT16 = 4,
    832   ARRAY_ID_UINT32 = 5,
    833   ARRAY_ID_INT32 = 6,
    834   ARRAY_ID_FLOAT32 = 7,
    835   ARRAY_ID_FLOAT64 = 8,
    836   ARRAY_ID_UINT8C = 9
    837 };
    838 
    839 static void ArrayIdToTypeAndSize(
    840     int arrayId, ExternalArrayType* array_type, size_t* element_size) {
    841   switch (arrayId) {
    842     case ARRAY_ID_UINT8:
    843       *array_type = kExternalUnsignedByteArray;
    844       *element_size = 1;
    845       break;
    846     case ARRAY_ID_INT8:
    847       *array_type = kExternalByteArray;
    848       *element_size = 1;
    849       break;
    850     case ARRAY_ID_UINT16:
    851       *array_type = kExternalUnsignedShortArray;
    852       *element_size = 2;
    853       break;
    854     case ARRAY_ID_INT16:
    855       *array_type = kExternalShortArray;
    856       *element_size = 2;
    857       break;
    858     case ARRAY_ID_UINT32:
    859       *array_type = kExternalUnsignedIntArray;
    860       *element_size = 4;
    861       break;
    862     case ARRAY_ID_INT32:
    863       *array_type = kExternalIntArray;
    864       *element_size = 4;
    865       break;
    866     case ARRAY_ID_FLOAT32:
    867       *array_type = kExternalFloatArray;
    868       *element_size = 4;
    869       break;
    870     case ARRAY_ID_FLOAT64:
    871       *array_type = kExternalDoubleArray;
    872       *element_size = 8;
    873       break;
    874     case ARRAY_ID_UINT8C:
    875       *array_type = kExternalPixelArray;
    876       *element_size = 1;
    877       break;
    878     default:
    879       UNREACHABLE();
    880   }
    881 }
    882 
    883 
    884 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
    885   HandleScope scope(isolate);
    886   ASSERT(args.length() == 5);
    887   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
    888   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
    889   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2);
    890   CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
    891   CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
    892 
    893   ASSERT(holder->GetInternalFieldCount() ==
    894       v8::ArrayBufferView::kInternalFieldCount);
    895   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
    896     holder->SetInternalField(i, Smi::FromInt(0));
    897   }
    898 
    899   ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
    900   size_t element_size = 1;  // Bogus initialization.
    901   ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
    902 
    903   holder->set_buffer(*buffer);
    904   holder->set_byte_offset(*byte_offset_object);
    905   holder->set_byte_length(*byte_length_object);
    906 
    907   size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
    908   size_t byte_length = NumberToSize(isolate, *byte_length_object);
    909   ASSERT(byte_length % element_size == 0);
    910   size_t length = byte_length / element_size;
    911 
    912   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
    913   holder->set_length(*length_obj);
    914   holder->set_weak_next(buffer->weak_first_view());
    915   buffer->set_weak_first_view(*holder);
    916 
    917   Handle<ExternalArray> elements =
    918       isolate->factory()->NewExternalArray(
    919           static_cast<int>(length), array_type,
    920           static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
    921   holder->set_elements(*elements);
    922   return isolate->heap()->undefined_value();
    923 }
    924 
    925 
    926 // Initializes a typed array from an array-like object.
    927 // If an array-like object happens to be a typed array of the same type,
    928 // initializes backing store using memove.
    929 //
    930 // Returns true if backing store was initialized or false otherwise.
    931 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
    932   HandleScope scope(isolate);
    933   ASSERT(args.length() == 4);
    934   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
    935   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
    936   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
    937   CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3);
    938 
    939   ASSERT(holder->GetInternalFieldCount() ==
    940       v8::ArrayBufferView::kInternalFieldCount);
    941   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
    942     holder->SetInternalField(i, Smi::FromInt(0));
    943   }
    944 
    945   ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
    946   size_t element_size = 1;  // Bogus initialization.
    947   ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
    948 
    949   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
    950   size_t length = NumberToSize(isolate, *length_obj);
    951   if (length > (kMaxInt / element_size)) {
    952     return isolate->Throw(*isolate->factory()->
    953           NewRangeError("invalid_array_buffer_length",
    954             HandleVector<Object>(NULL, 0)));
    955   }
    956   size_t byte_length = length * element_size;
    957 
    958   // We assume that the caller of this function will initialize holder
    959   // with the loop
    960   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
    961   // If source is a typed array, this loop will always run to completion,
    962   // so we are sure that the backing store will be initialized.
    963   // Otherwise, we do not know (the indexing operation might throw).
    964   // Hence we require zero initialization unless our source is a typed array.
    965   bool should_zero_initialize = !source->IsJSTypedArray();
    966 
    967   if (!Runtime::SetupArrayBufferAllocatingData(
    968         isolate, buffer, byte_length, should_zero_initialize)) {
    969     return isolate->Throw(*isolate->factory()->
    970           NewRangeError("invalid_array_buffer_length",
    971             HandleVector<Object>(NULL, 0)));
    972   }
    973 
    974   holder->set_buffer(*buffer);
    975   holder->set_byte_offset(Smi::FromInt(0));
    976   Handle<Object> byte_length_obj(
    977       isolate->factory()->NewNumberFromSize(byte_length));
    978   holder->set_byte_length(*byte_length_obj);
    979   holder->set_length(*length_obj);
    980   holder->set_weak_next(buffer->weak_first_view());
    981   buffer->set_weak_first_view(*holder);
    982 
    983   Handle<ExternalArray> elements =
    984       isolate->factory()->NewExternalArray(
    985           static_cast<int>(length), array_type,
    986           static_cast<uint8_t*>(buffer->backing_store()));
    987   holder->set_elements(*elements);
    988 
    989   if (source->IsJSTypedArray()) {
    990     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
    991 
    992     if (typed_array->type() == holder->type()) {
    993       uint8_t* backing_store =
    994         static_cast<uint8_t*>(
    995           JSArrayBuffer::cast(typed_array->buffer())->backing_store());
    996       size_t source_byte_offset =
    997           NumberToSize(isolate, typed_array->byte_offset());
    998       OS::MemCopy(
    999           buffer->backing_store(),
   1000           backing_store + source_byte_offset,
   1001           byte_length);
   1002       return *isolate->factory()->true_value();
   1003     } else {
   1004       return *isolate->factory()->false_value();
   1005     }
   1006   }
   1007 
   1008   return *isolate->factory()->false_value();
   1009 }
   1010 
   1011 
   1012 #define TYPED_ARRAY_GETTER(getter, accessor) \
   1013   RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) {             \
   1014     HandleScope scope(isolate);                                               \
   1015     ASSERT(args.length() == 1);                                               \
   1016     CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);                            \
   1017     if (!holder->IsJSTypedArray())                                            \
   1018       return isolate->Throw(*isolate->factory()->NewTypeError(                \
   1019           "not_typed_array", HandleVector<Object>(NULL, 0)));                 \
   1020     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));            \
   1021     return typed_array->accessor();                                           \
   1022   }
   1023 
   1024 TYPED_ARRAY_GETTER(Buffer, buffer)
   1025 TYPED_ARRAY_GETTER(ByteLength, byte_length)
   1026 TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
   1027 TYPED_ARRAY_GETTER(Length, length)
   1028 
   1029 #undef TYPED_ARRAY_GETTER
   1030 
   1031 // Return codes for Runtime_TypedArraySetFastCases.
   1032 // Should be synchronized with typedarray.js natives.
   1033 enum TypedArraySetResultCodes {
   1034   // Set from typed array of the same type.
   1035   // This is processed by TypedArraySetFastCases
   1036   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
   1037   // Set from typed array of the different type, overlapping in memory.
   1038   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
   1039   // Set from typed array of the different type, non-overlapping.
   1040   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
   1041   // Set from non-typed array.
   1042   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
   1043 };
   1044 
   1045 
   1046 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
   1047   HandleScope scope(isolate);
   1048   CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
   1049   CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
   1050   CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
   1051 
   1052   if (!target_obj->IsJSTypedArray())
   1053     return isolate->Throw(*isolate->factory()->NewTypeError(
   1054         "not_typed_array", HandleVector<Object>(NULL, 0)));
   1055 
   1056   if (!source_obj->IsJSTypedArray())
   1057     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
   1058 
   1059   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
   1060   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
   1061   size_t offset = NumberToSize(isolate, *offset_obj);
   1062   size_t target_length = NumberToSize(isolate, target->length());
   1063   size_t source_length = NumberToSize(isolate, source->length());
   1064   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
   1065   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
   1066   if (offset > target_length ||
   1067       offset + source_length > target_length ||
   1068       offset + source_length < offset)  // overflow
   1069     return isolate->Throw(*isolate->factory()->NewRangeError(
   1070           "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
   1071 
   1072   size_t target_offset = NumberToSize(isolate, target->byte_offset());
   1073   size_t source_offset = NumberToSize(isolate, source->byte_offset());
   1074   uint8_t* target_base =
   1075       static_cast<uint8_t*>(
   1076         JSArrayBuffer::cast(target->buffer())->backing_store()) + target_offset;
   1077   uint8_t* source_base =
   1078       static_cast<uint8_t*>(
   1079         JSArrayBuffer::cast(source->buffer())->backing_store()) + source_offset;
   1080 
   1081   // Typed arrays of the same type: use memmove.
   1082   if (target->type() == source->type()) {
   1083     memmove(target_base + offset * target->element_size(),
   1084         source_base, source_byte_length);
   1085     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
   1086   }
   1087 
   1088   // Typed arrays of different types over the same backing store
   1089   if ((source_base <= target_base &&
   1090         source_base + source_byte_length > target_base) ||
   1091       (target_base <= source_base &&
   1092         target_base + target_byte_length > source_base)) {
   1093     // We do not support overlapping ArrayBuffers
   1094     ASSERT(
   1095       JSArrayBuffer::cast(target->buffer())->backing_store() ==
   1096       JSArrayBuffer::cast(source->buffer())->backing_store());
   1097     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
   1098   } else {  // Non-overlapping typed arrays
   1099     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
   1100   }
   1101 }
   1102 
   1103 
   1104 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
   1105   HandleScope scope(isolate);
   1106   ASSERT(args.length() == 4);
   1107   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
   1108   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
   1109   CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2);
   1110   CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3);
   1111 
   1112   ASSERT(holder->GetInternalFieldCount() ==
   1113       v8::ArrayBufferView::kInternalFieldCount);
   1114   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
   1115     holder->SetInternalField(i, Smi::FromInt(0));
   1116   }
   1117 
   1118   holder->set_buffer(*buffer);
   1119   ASSERT(byte_offset->IsNumber());
   1120   ASSERT(
   1121       NumberToSize(isolate, buffer->byte_length()) >=
   1122         NumberToSize(isolate, *byte_offset)
   1123         + NumberToSize(isolate, *byte_length));
   1124   holder->set_byte_offset(*byte_offset);
   1125   ASSERT(byte_length->IsNumber());
   1126   holder->set_byte_length(*byte_length);
   1127 
   1128   holder->set_weak_next(buffer->weak_first_view());
   1129   buffer->set_weak_first_view(*holder);
   1130 
   1131   return isolate->heap()->undefined_value();
   1132 }
   1133 
   1134 
   1135 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
   1136   HandleScope scope(isolate);
   1137   ASSERT(args.length() == 1);
   1138   CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
   1139   return data_view->buffer();
   1140 }
   1141 
   1142 
   1143 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
   1144   HandleScope scope(isolate);
   1145   ASSERT(args.length() == 1);
   1146   CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
   1147   return data_view->byte_offset();
   1148 }
   1149 
   1150 
   1151 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
   1152   HandleScope scope(isolate);
   1153   ASSERT(args.length() == 1);
   1154   CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
   1155   return data_view->byte_length();
   1156 }
   1157 
   1158 
   1159 inline static bool NeedToFlipBytes(bool is_little_endian) {
   1160 #ifdef V8_TARGET_LITTLE_ENDIAN
   1161   return !is_little_endian;
   1162 #else
   1163   return is_little_endian;
   1164 #endif
   1165 }
   1166 
   1167 
   1168 template<int n>
   1169 inline void CopyBytes(uint8_t* target, uint8_t* source) {
   1170   for (int i = 0; i < n; i++) {
   1171     *(target++) = *(source++);
   1172   }
   1173 }
   1174 
   1175 
   1176 template<int n>
   1177 inline void FlipBytes(uint8_t* target, uint8_t* source) {
   1178   source = source + (n-1);
   1179   for (int i = 0; i < n; i++) {
   1180     *(target++) = *(source--);
   1181   }
   1182 }
   1183 
   1184 
   1185 template<typename T>
   1186 inline static bool DataViewGetValue(
   1187     Isolate* isolate,
   1188     Handle<JSDataView> data_view,
   1189     Handle<Object> byte_offset_obj,
   1190     bool is_little_endian,
   1191     T* result) {
   1192   size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
   1193   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1194 
   1195   size_t data_view_byte_offset =
   1196       NumberToSize(isolate, data_view->byte_offset());
   1197   size_t data_view_byte_length =
   1198       NumberToSize(isolate, data_view->byte_length());
   1199   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1200       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1201     return false;
   1202   }
   1203 
   1204   union Value {
   1205     T data;
   1206     uint8_t bytes[sizeof(T)];
   1207   };
   1208 
   1209   Value value;
   1210   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1211   ASSERT(
   1212       NumberToSize(isolate, buffer->byte_length())
   1213       >= buffer_offset + sizeof(T));
   1214   uint8_t* source =
   1215         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1216   if (NeedToFlipBytes(is_little_endian)) {
   1217     FlipBytes<sizeof(T)>(value.bytes, source);
   1218   } else {
   1219     CopyBytes<sizeof(T)>(value.bytes, source);
   1220   }
   1221   *result = value.data;
   1222   return true;
   1223 }
   1224 
   1225 
   1226 template<typename T>
   1227 static bool DataViewSetValue(
   1228     Isolate* isolate,
   1229     Handle<JSDataView> data_view,
   1230     Handle<Object> byte_offset_obj,
   1231     bool is_little_endian,
   1232     T data) {
   1233   size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
   1234   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
   1235 
   1236   size_t data_view_byte_offset =
   1237       NumberToSize(isolate, data_view->byte_offset());
   1238   size_t data_view_byte_length =
   1239       NumberToSize(isolate, data_view->byte_length());
   1240   if (byte_offset + sizeof(T) > data_view_byte_length ||
   1241       byte_offset + sizeof(T) < byte_offset)  {  // overflow
   1242     return false;
   1243   }
   1244 
   1245   union Value {
   1246     T data;
   1247     uint8_t bytes[sizeof(T)];
   1248   };
   1249 
   1250   Value value;
   1251   value.data = data;
   1252   size_t buffer_offset = data_view_byte_offset + byte_offset;
   1253   ASSERT(
   1254       NumberToSize(isolate, buffer->byte_length())
   1255       >= buffer_offset + sizeof(T));
   1256   uint8_t* target =
   1257         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
   1258   if (NeedToFlipBytes(is_little_endian)) {
   1259     FlipBytes<sizeof(T)>(target, value.bytes);
   1260   } else {
   1261     CopyBytes<sizeof(T)>(target, value.bytes);
   1262   }
   1263   return true;
   1264 }
   1265 
   1266 
   1267 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
   1268   RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) {             \
   1269     HandleScope scope(isolate);                                               \
   1270     ASSERT(args.length() == 3);                                               \
   1271     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
   1272     CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
   1273     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
   1274     Type result;                                                              \
   1275     if (DataViewGetValue(                                                     \
   1276           isolate, holder, offset, is_little_endian, &result)) {              \
   1277       return isolate->heap()->Converter(result);                              \
   1278     } else {                                                                  \
   1279       return isolate->Throw(*isolate->factory()->NewRangeError(               \
   1280           "invalid_data_view_accessor_offset",                                \
   1281           HandleVector<Object>(NULL, 0)));                                    \
   1282     }                                                                         \
   1283   }
   1284 
   1285 DATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32)
   1286 DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32)
   1287 DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32)
   1288 DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32)
   1289 DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32)
   1290 DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32)
   1291 DATA_VIEW_GETTER(Float32, float, NumberFromDouble)
   1292 DATA_VIEW_GETTER(Float64, double, NumberFromDouble)
   1293 
   1294 #undef DATA_VIEW_GETTER
   1295 
   1296 
   1297 template <typename T>
   1298 static T DataViewConvertValue(double value);
   1299 
   1300 
   1301 template <>
   1302 int8_t DataViewConvertValue<int8_t>(double value) {
   1303   return static_cast<int8_t>(DoubleToInt32(value));
   1304 }
   1305 
   1306 
   1307 template <>
   1308 int16_t DataViewConvertValue<int16_t>(double value) {
   1309   return static_cast<int16_t>(DoubleToInt32(value));
   1310 }
   1311 
   1312 
   1313 template <>
   1314 int32_t DataViewConvertValue<int32_t>(double value) {
   1315   return DoubleToInt32(value);
   1316 }
   1317 
   1318 
   1319 template <>
   1320 uint8_t DataViewConvertValue<uint8_t>(double value) {
   1321   return static_cast<uint8_t>(DoubleToUint32(value));
   1322 }
   1323 
   1324 
   1325 template <>
   1326 uint16_t DataViewConvertValue<uint16_t>(double value) {
   1327   return static_cast<uint16_t>(DoubleToUint32(value));
   1328 }
   1329 
   1330 
   1331 template <>
   1332 uint32_t DataViewConvertValue<uint32_t>(double value) {
   1333   return DoubleToUint32(value);
   1334 }
   1335 
   1336 
   1337 template <>
   1338 float DataViewConvertValue<float>(double value) {
   1339   return static_cast<float>(value);
   1340 }
   1341 
   1342 
   1343 template <>
   1344 double DataViewConvertValue<double>(double value) {
   1345   return value;
   1346 }
   1347 
   1348 
   1349 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
   1350   RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) {             \
   1351     HandleScope scope(isolate);                                               \
   1352     ASSERT(args.length() == 4);                                               \
   1353     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
   1354     CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
   1355     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);                             \
   1356     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
   1357     Type v = DataViewConvertValue<Type>(value->Number());                     \
   1358     if (DataViewSetValue(                                                     \
   1359           isolate, holder, offset, is_little_endian, v)) {                    \
   1360       return isolate->heap()->undefined_value();                              \
   1361     } else {                                                                  \
   1362       return isolate->Throw(*isolate->factory()->NewRangeError(               \
   1363           "invalid_data_view_accessor_offset",                                \
   1364           HandleVector<Object>(NULL, 0)));                                    \
   1365     }                                                                         \
   1366   }
   1367 
   1368 DATA_VIEW_SETTER(Uint8, uint8_t)
   1369 DATA_VIEW_SETTER(Int8, int8_t)
   1370 DATA_VIEW_SETTER(Uint16, uint16_t)
   1371 DATA_VIEW_SETTER(Int16, int16_t)
   1372 DATA_VIEW_SETTER(Uint32, uint32_t)
   1373 DATA_VIEW_SETTER(Int32, int32_t)
   1374 DATA_VIEW_SETTER(Float32, float)
   1375 DATA_VIEW_SETTER(Float64, double)
   1376 
   1377 #undef DATA_VIEW_SETTER
   1378 
   1379 
   1380 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
   1381   HandleScope scope(isolate);
   1382   ASSERT(args.length() == 1);
   1383   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1384   Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
   1385   holder->set_table(*table);
   1386   return *holder;
   1387 }
   1388 
   1389 
   1390 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
   1391   HandleScope scope(isolate);
   1392   ASSERT(args.length() == 2);
   1393   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1394   Handle<Object> key(args[1], isolate);
   1395   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1396   table = ObjectHashSetAdd(table, key);
   1397   holder->set_table(*table);
   1398   return isolate->heap()->undefined_value();
   1399 }
   1400 
   1401 
   1402 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
   1403   HandleScope scope(isolate);
   1404   ASSERT(args.length() == 2);
   1405   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1406   Handle<Object> key(args[1], isolate);
   1407   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1408   return isolate->heap()->ToBoolean(table->Contains(*key));
   1409 }
   1410 
   1411 
   1412 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
   1413   HandleScope scope(isolate);
   1414   ASSERT(args.length() == 2);
   1415   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1416   Handle<Object> key(args[1], isolate);
   1417   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1418   table = ObjectHashSetRemove(table, key);
   1419   holder->set_table(*table);
   1420   return isolate->heap()->undefined_value();
   1421 }
   1422 
   1423 
   1424 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
   1425   HandleScope scope(isolate);
   1426   ASSERT(args.length() == 1);
   1427   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
   1428   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
   1429   return Smi::FromInt(table->NumberOfElements());
   1430 }
   1431 
   1432 
   1433 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
   1434   HandleScope scope(isolate);
   1435   ASSERT(args.length() == 1);
   1436   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1437   Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
   1438   holder->set_table(*table);
   1439   return *holder;
   1440 }
   1441 
   1442 
   1443 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
   1444   HandleScope scope(isolate);
   1445   ASSERT(args.length() == 2);
   1446   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1447   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1448   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1449   Handle<Object> lookup(table->Lookup(*key), isolate);
   1450   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1451 }
   1452 
   1453 
   1454 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
   1455   HandleScope scope(isolate);
   1456   ASSERT(args.length() == 2);
   1457   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1458   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1459   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1460   Handle<Object> lookup(table->Lookup(*key), isolate);
   1461   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1462 }
   1463 
   1464 
   1465 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
   1466   HandleScope scope(isolate);
   1467   ASSERT(args.length() == 2);
   1468   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1469   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1470   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1471   Handle<Object> lookup(table->Lookup(*key), isolate);
   1472   Handle<ObjectHashTable> new_table =
   1473       PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
   1474   holder->set_table(*new_table);
   1475   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1476 }
   1477 
   1478 
   1479 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
   1480   HandleScope scope(isolate);
   1481   ASSERT(args.length() == 3);
   1482   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1483   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1484   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   1485   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1486   Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
   1487   holder->set_table(*new_table);
   1488   return isolate->heap()->undefined_value();
   1489 }
   1490 
   1491 
   1492 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
   1493   HandleScope scope(isolate);
   1494   ASSERT(args.length() == 1);
   1495   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
   1496   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
   1497   return Smi::FromInt(table->NumberOfElements());
   1498 }
   1499 
   1500 
   1501 static JSWeakCollection* WeakCollectionInitialize(Isolate* isolate,
   1502     Handle<JSWeakCollection> weak_collection) {
   1503   ASSERT(weak_collection->map()->inobject_properties() == 0);
   1504   Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
   1505   weak_collection->set_table(*table);
   1506   weak_collection->set_next(Smi::FromInt(0));
   1507   return *weak_collection;
   1508 }
   1509 
   1510 
   1511 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionInitialize) {
   1512   HandleScope scope(isolate);
   1513   ASSERT(args.length() == 1);
   1514   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1515   return WeakCollectionInitialize(isolate, weak_collection);
   1516 }
   1517 
   1518 
   1519 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionGet) {
   1520   HandleScope scope(isolate);
   1521   ASSERT(args.length() == 2);
   1522   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1523   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1524   Handle<ObjectHashTable> table(
   1525       ObjectHashTable::cast(weak_collection->table()));
   1526   Handle<Object> lookup(table->Lookup(*key), isolate);
   1527   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
   1528 }
   1529 
   1530 
   1531 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionHas) {
   1532   HandleScope scope(isolate);
   1533   ASSERT(args.length() == 2);
   1534   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1535   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1536   Handle<ObjectHashTable> table(
   1537       ObjectHashTable::cast(weak_collection->table()));
   1538   Handle<Object> lookup(table->Lookup(*key), isolate);
   1539   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1540 }
   1541 
   1542 
   1543 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
   1544   HandleScope scope(isolate);
   1545   ASSERT(args.length() == 2);
   1546   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1547   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1548   Handle<ObjectHashTable> table(ObjectHashTable::cast(
   1549       weak_collection->table()));
   1550   Handle<Object> lookup(table->Lookup(*key), isolate);
   1551   Handle<ObjectHashTable> new_table =
   1552       PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
   1553   weak_collection->set_table(*new_table);
   1554   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
   1555 }
   1556 
   1557 
   1558 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
   1559   HandleScope scope(isolate);
   1560   ASSERT(args.length() == 3);
   1561   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
   1562   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
   1563   Handle<Object> value(args[2], isolate);
   1564   Handle<ObjectHashTable> table(
   1565       ObjectHashTable::cast(weak_collection->table()));
   1566   Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
   1567   weak_collection->set_table(*new_table);
   1568   return isolate->heap()->undefined_value();
   1569 }
   1570 
   1571 
   1572 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
   1573   SealHandleScope shs(isolate);
   1574   ASSERT(args.length() == 1);
   1575   Object* obj = args[0];
   1576   if (!obj->IsJSObject()) return isolate->heap()->null_value();
   1577   return JSObject::cast(obj)->class_name();
   1578 }
   1579 
   1580 
   1581 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
   1582   SealHandleScope shs(isolate);
   1583   ASSERT(args.length() == 1);
   1584   CONVERT_ARG_CHECKED(Object, obj, 0);
   1585   // We don't expect access checks to be needed on JSProxy objects.
   1586   ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
   1587   do {
   1588     if (obj->IsAccessCheckNeeded() &&
   1589         !isolate->MayNamedAccess(JSObject::cast(obj),
   1590                                  isolate->heap()->proto_string(),
   1591                                  v8::ACCESS_GET)) {
   1592       isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
   1593       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   1594       return isolate->heap()->undefined_value();
   1595     }
   1596     obj = obj->GetPrototype(isolate);
   1597   } while (obj->IsJSObject() &&
   1598            JSObject::cast(obj)->map()->is_hidden_prototype());
   1599   return obj;
   1600 }
   1601 
   1602 
   1603 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate,
   1604                                                        Object* receiver) {
   1605   Object* current = receiver->GetPrototype(isolate);
   1606   while (current->IsJSObject() &&
   1607          JSObject::cast(current)->map()->is_hidden_prototype()) {
   1608     current = current->GetPrototype(isolate);
   1609   }
   1610   return current;
   1611 }
   1612 
   1613 
   1614 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
   1615   HandleScope scope(isolate);
   1616   ASSERT(args.length() == 2);
   1617   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1618   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
   1619   if (FLAG_harmony_observation && obj->map()->is_observed()) {
   1620     Handle<Object> old_value(
   1621         GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
   1622 
   1623     Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
   1624     RETURN_IF_EMPTY_HANDLE(isolate, result);
   1625 
   1626     Handle<Object> new_value(
   1627         GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
   1628     if (!new_value->SameValue(*old_value)) {
   1629       JSObject::EnqueueChangeRecord(obj, "prototype",
   1630                                     isolate->factory()->proto_string(),
   1631                                     old_value);
   1632     }
   1633     return *result;
   1634   }
   1635   Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
   1636   RETURN_IF_EMPTY_HANDLE(isolate, result);
   1637   return *result;
   1638 }
   1639 
   1640 
   1641 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
   1642   SealHandleScope shs(isolate);
   1643   ASSERT(args.length() == 2);
   1644   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
   1645   Object* O = args[0];
   1646   Object* V = args[1];
   1647   while (true) {
   1648     Object* prototype = V->GetPrototype(isolate);
   1649     if (prototype->IsNull()) return isolate->heap()->false_value();
   1650     if (O == prototype) return isolate->heap()->true_value();
   1651     V = prototype;
   1652   }
   1653 }
   1654 
   1655 
   1656 static bool CheckAccessException(Object* callback,
   1657                                  v8::AccessType access_type) {
   1658   if (callback->IsAccessorInfo()) {
   1659     AccessorInfo* info = AccessorInfo::cast(callback);
   1660     return
   1661         (access_type == v8::ACCESS_HAS &&
   1662            (info->all_can_read() || info->all_can_write())) ||
   1663         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
   1664         (access_type == v8::ACCESS_SET && info->all_can_write());
   1665   }
   1666   return false;
   1667 }
   1668 
   1669 
   1670 template<class Key>
   1671 static bool CheckGenericAccess(
   1672     JSObject* receiver,
   1673     JSObject* holder,
   1674     Key key,
   1675     v8::AccessType access_type,
   1676     bool (Isolate::*mayAccess)(JSObject*, Key, v8::AccessType)) {
   1677   Isolate* isolate = receiver->GetIsolate();
   1678   for (JSObject* current = receiver;
   1679        true;
   1680        current = JSObject::cast(current->GetPrototype())) {
   1681     if (current->IsAccessCheckNeeded() &&
   1682         !(isolate->*mayAccess)(current, key, access_type)) {
   1683       return false;
   1684     }
   1685     if (current == holder) break;
   1686   }
   1687   return true;
   1688 }
   1689 
   1690 
   1691 enum AccessCheckResult {
   1692   ACCESS_FORBIDDEN,
   1693   ACCESS_ALLOWED,
   1694   ACCESS_ABSENT
   1695 };
   1696 
   1697 
   1698 static AccessCheckResult CheckPropertyAccess(
   1699     JSObject* obj,
   1700     Name* name,
   1701     v8::AccessType access_type) {
   1702   uint32_t index;
   1703   if (name->AsArrayIndex(&index)) {
   1704     // TODO(1095): we should traverse hidden prototype hierachy as well.
   1705     if (CheckGenericAccess(
   1706             obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
   1707       return ACCESS_ALLOWED;
   1708     }
   1709 
   1710     obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
   1711     return ACCESS_FORBIDDEN;
   1712   }
   1713 
   1714   LookupResult lookup(obj->GetIsolate());
   1715   obj->LocalLookup(name, &lookup, true);
   1716 
   1717   if (!lookup.IsProperty()) return ACCESS_ABSENT;
   1718   if (CheckGenericAccess<Object*>(
   1719           obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) {
   1720     return ACCESS_ALLOWED;
   1721   }
   1722 
   1723   // Access check callback denied the access, but some properties
   1724   // can have a special permissions which override callbacks descision
   1725   // (currently see v8::AccessControl).
   1726   // API callbacks can have per callback access exceptions.
   1727   switch (lookup.type()) {
   1728     case CALLBACKS:
   1729       if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
   1730         return ACCESS_ALLOWED;
   1731       }
   1732       break;
   1733     case INTERCEPTOR:
   1734       // If the object has an interceptor, try real named properties.
   1735       // Overwrite the result to fetch the correct property later.
   1736       lookup.holder()->LookupRealNamedProperty(name, &lookup);
   1737       if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
   1738         if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
   1739           return ACCESS_ALLOWED;
   1740         }
   1741       }
   1742       break;
   1743     default:
   1744       break;
   1745   }
   1746 
   1747   obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
   1748   return ACCESS_FORBIDDEN;
   1749 }
   1750 
   1751 
   1752 // Enumerator used as indices into the array returned from GetOwnProperty
   1753 enum PropertyDescriptorIndices {
   1754   IS_ACCESSOR_INDEX,
   1755   VALUE_INDEX,
   1756   GETTER_INDEX,
   1757   SETTER_INDEX,
   1758   WRITABLE_INDEX,
   1759   ENUMERABLE_INDEX,
   1760   CONFIGURABLE_INDEX,
   1761   DESCRIPTOR_SIZE
   1762 };
   1763 
   1764 
   1765 static MaybeObject* GetOwnProperty(Isolate* isolate,
   1766                                    Handle<JSObject> obj,
   1767                                    Handle<Name> name) {
   1768   Heap* heap = isolate->heap();
   1769   // Due to some WebKit tests, we want to make sure that we do not log
   1770   // more than one access failure here.
   1771   AccessCheckResult access_check_result =
   1772       CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS);
   1773   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   1774   switch (access_check_result) {
   1775     case ACCESS_FORBIDDEN: return heap->false_value();
   1776     case ACCESS_ALLOWED: break;
   1777     case ACCESS_ABSENT: return heap->undefined_value();
   1778   }
   1779 
   1780   PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name);
   1781   if (attrs == ABSENT) {
   1782     RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   1783     return heap->undefined_value();
   1784   }
   1785   ASSERT(!isolate->has_scheduled_exception());
   1786   AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name);
   1787   Handle<AccessorPair> accessors(raw_accessors, isolate);
   1788 
   1789   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   1790   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
   1791   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
   1792   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL));
   1793 
   1794   if (raw_accessors == NULL) {
   1795     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
   1796     // GetProperty does access check.
   1797     Handle<Object> value = GetProperty(isolate, obj, name);
   1798     RETURN_IF_EMPTY_HANDLE(isolate, value);
   1799     elms->set(VALUE_INDEX, *value);
   1800   } else {
   1801     // Access checks are performed for both accessors separately.
   1802     // When they fail, the respective field is not set in the descriptor.
   1803     Object* getter = accessors->GetComponent(ACCESSOR_GETTER);
   1804     Object* setter = accessors->GetComponent(ACCESSOR_SETTER);
   1805     if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) {
   1806       ASSERT(!isolate->has_scheduled_exception());
   1807       elms->set(GETTER_INDEX, getter);
   1808     } else {
   1809       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   1810     }
   1811     if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) {
   1812       ASSERT(!isolate->has_scheduled_exception());
   1813       elms->set(SETTER_INDEX, setter);
   1814     } else {
   1815       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   1816     }
   1817   }
   1818 
   1819   return *isolate->factory()->NewJSArrayWithElements(elms);
   1820 }
   1821 
   1822 
   1823 // Returns an array with the property description:
   1824 //  if args[1] is not a property on args[0]
   1825 //          returns undefined
   1826 //  if args[1] is a data property on args[0]
   1827 //         [false, value, Writeable, Enumerable, Configurable]
   1828 //  if args[1] is an accessor on args[0]
   1829 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
   1830 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
   1831   HandleScope scope(isolate);
   1832   ASSERT(args.length() == 2);
   1833   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1834   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   1835   return GetOwnProperty(isolate, obj, name);
   1836 }
   1837 
   1838 
   1839 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
   1840   SealHandleScope shs(isolate);
   1841   ASSERT(args.length() == 1);
   1842   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   1843   return obj->PreventExtensions();
   1844 }
   1845 
   1846 
   1847 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
   1848   SealHandleScope shs(isolate);
   1849   ASSERT(args.length() == 1);
   1850   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   1851   if (obj->IsJSGlobalProxy()) {
   1852     Object* proto = obj->GetPrototype();
   1853     if (proto->IsNull()) return isolate->heap()->false_value();
   1854     ASSERT(proto->IsJSGlobalObject());
   1855     obj = JSObject::cast(proto);
   1856   }
   1857   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
   1858 }
   1859 
   1860 
   1861 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
   1862   HandleScope scope(isolate);
   1863   ASSERT(args.length() == 3);
   1864   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
   1865   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   1866   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
   1867   Handle<Object> result =
   1868       RegExpImpl::Compile(re, pattern, flags);
   1869   RETURN_IF_EMPTY_HANDLE(isolate, result);
   1870   return *result;
   1871 }
   1872 
   1873 
   1874 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) {
   1875   HandleScope scope(isolate);
   1876   ASSERT(args.length() == 1);
   1877   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
   1878   return *isolate->factory()->CreateApiFunction(data);
   1879 }
   1880 
   1881 
   1882 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsTemplate) {
   1883   SealHandleScope shs(isolate);
   1884   ASSERT(args.length() == 1);
   1885   Object* arg = args[0];
   1886   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
   1887   return isolate->heap()->ToBoolean(result);
   1888 }
   1889 
   1890 
   1891 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
   1892   SealHandleScope shs(isolate);
   1893   ASSERT(args.length() == 2);
   1894   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
   1895   CONVERT_SMI_ARG_CHECKED(index, 1)
   1896   int offset = index * kPointerSize + HeapObject::kHeaderSize;
   1897   InstanceType type = templ->map()->instance_type();
   1898   RUNTIME_ASSERT(type ==  FUNCTION_TEMPLATE_INFO_TYPE ||
   1899                  type ==  OBJECT_TEMPLATE_INFO_TYPE);
   1900   RUNTIME_ASSERT(offset > 0);
   1901   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
   1902     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
   1903   } else {
   1904     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
   1905   }
   1906   return *HeapObject::RawField(templ, offset);
   1907 }
   1908 
   1909 
   1910 RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
   1911   SealHandleScope shs(isolate);
   1912   ASSERT(args.length() == 1);
   1913   CONVERT_ARG_CHECKED(HeapObject, object, 0);
   1914   Map* old_map = object->map();
   1915   bool needs_access_checks = old_map->is_access_check_needed();
   1916   if (needs_access_checks) {
   1917     // Copy map so it won't interfere constructor's initial map.
   1918     Map* new_map;
   1919     MaybeObject* maybe_new_map = old_map->Copy();
   1920     if (!maybe_new_map->To(&new_map)) return maybe_new_map;
   1921 
   1922     new_map->set_is_access_check_needed(false);
   1923     object->set_map(new_map);
   1924   }
   1925   return isolate->heap()->ToBoolean(needs_access_checks);
   1926 }
   1927 
   1928 
   1929 RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
   1930   SealHandleScope shs(isolate);
   1931   ASSERT(args.length() == 1);
   1932   CONVERT_ARG_CHECKED(HeapObject, object, 0);
   1933   Map* old_map = object->map();
   1934   if (!old_map->is_access_check_needed()) {
   1935     // Copy map so it won't interfere constructor's initial map.
   1936     Map* new_map;
   1937     MaybeObject* maybe_new_map = old_map->Copy();
   1938     if (!maybe_new_map->To(&new_map)) return maybe_new_map;
   1939 
   1940     new_map->set_is_access_check_needed(true);
   1941     object->set_map(new_map);
   1942   }
   1943   return isolate->heap()->undefined_value();
   1944 }
   1945 
   1946 
   1947 static Failure* ThrowRedeclarationError(Isolate* isolate,
   1948                                         const char* type,
   1949                                         Handle<String> name) {
   1950   HandleScope scope(isolate);
   1951   Handle<Object> type_handle =
   1952       isolate->factory()->NewStringFromAscii(CStrVector(type));
   1953   Handle<Object> args[2] = { type_handle, name };
   1954   Handle<Object> error =
   1955       isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2));
   1956   return isolate->Throw(*error);
   1957 }
   1958 
   1959 
   1960 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
   1961   HandleScope scope(isolate);
   1962   ASSERT(args.length() == 3);
   1963   Handle<GlobalObject> global = Handle<GlobalObject>(
   1964       isolate->context()->global_object());
   1965 
   1966   Handle<Context> context = args.at<Context>(0);
   1967   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
   1968   CONVERT_SMI_ARG_CHECKED(flags, 2);
   1969 
   1970   // Traverse the name/value pairs and set the properties.
   1971   int length = pairs->length();
   1972   for (int i = 0; i < length; i += 2) {
   1973     HandleScope scope(isolate);
   1974     Handle<String> name(String::cast(pairs->get(i)));
   1975     Handle<Object> value(pairs->get(i + 1), isolate);
   1976 
   1977     // We have to declare a global const property. To capture we only
   1978     // assign to it when evaluating the assignment for "const x =
   1979     // <expr>" the initial value is the hole.
   1980     bool is_var = value->IsUndefined();
   1981     bool is_const = value->IsTheHole();
   1982     bool is_function = value->IsSharedFunctionInfo();
   1983     ASSERT(is_var + is_const + is_function == 1);
   1984 
   1985     if (is_var || is_const) {
   1986       // Lookup the property in the global object, and don't set the
   1987       // value of the variable if the property is already there.
   1988       // Do the lookup locally only, see ES5 erratum.
   1989       LookupResult lookup(isolate);
   1990       if (FLAG_es52_globals) {
   1991         global->LocalLookup(*name, &lookup, true);
   1992       } else {
   1993         global->Lookup(*name, &lookup);
   1994       }
   1995       if (lookup.IsFound()) {
   1996         // We found an existing property. Unless it was an interceptor
   1997         // that claims the property is absent, skip this declaration.
   1998         if (!lookup.IsInterceptor()) continue;
   1999         PropertyAttributes attributes = global->GetPropertyAttribute(*name);
   2000         if (attributes != ABSENT) continue;
   2001         // Fall-through and introduce the absent property by using
   2002         // SetProperty.
   2003       }
   2004     } else if (is_function) {
   2005       // Copy the function and update its context. Use it as value.
   2006       Handle<SharedFunctionInfo> shared =
   2007           Handle<SharedFunctionInfo>::cast(value);
   2008       Handle<JSFunction> function =
   2009           isolate->factory()->NewFunctionFromSharedFunctionInfo(
   2010               shared, context, TENURED);
   2011       value = function;
   2012     }
   2013 
   2014     LookupResult lookup(isolate);
   2015     global->LocalLookup(*name, &lookup, true);
   2016 
   2017     // Compute the property attributes. According to ECMA-262,
   2018     // the property must be non-configurable except in eval.
   2019     int attr = NONE;
   2020     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
   2021     if (!is_eval) {
   2022       attr |= DONT_DELETE;
   2023     }
   2024     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
   2025     if (is_const || (is_native && is_function)) {
   2026       attr |= READ_ONLY;
   2027     }
   2028 
   2029     LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
   2030 
   2031     if (!lookup.IsFound() || is_function) {
   2032       // If the local property exists, check that we can reconfigure it
   2033       // as required for function declarations.
   2034       if (lookup.IsFound() && lookup.IsDontDelete()) {
   2035         if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
   2036             lookup.IsPropertyCallbacks()) {
   2037           return ThrowRedeclarationError(isolate, "function", name);
   2038         }
   2039         // If the existing property is not configurable, keep its attributes.
   2040         attr = lookup.GetAttributes();
   2041       }
   2042       // Define or redefine own property.
   2043       RETURN_IF_EMPTY_HANDLE(isolate,
   2044           JSObject::SetLocalPropertyIgnoreAttributes(
   2045               global, name, value, static_cast<PropertyAttributes>(attr)));
   2046     } else {
   2047       // Do a [[Put]] on the existing (own) property.
   2048       RETURN_IF_EMPTY_HANDLE(isolate,
   2049           JSObject::SetProperty(
   2050               global, name, value, static_cast<PropertyAttributes>(attr),
   2051               language_mode == CLASSIC_MODE ? kNonStrictMode : kStrictMode));
   2052     }
   2053   }
   2054 
   2055   ASSERT(!isolate->has_pending_exception());
   2056   return isolate->heap()->undefined_value();
   2057 }
   2058 
   2059 
   2060 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
   2061   HandleScope scope(isolate);
   2062   ASSERT(args.length() == 4);
   2063 
   2064   // Declarations are always made in a function or native context.  In the
   2065   // case of eval code, the context passed is the context of the caller,
   2066   // which may be some nested context and not the declaration context.
   2067   RUNTIME_ASSERT(args[0]->IsContext());
   2068   Handle<Context> context(Context::cast(args[0])->declaration_context());
   2069 
   2070   Handle<String> name(String::cast(args[1]));
   2071   PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
   2072   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
   2073   Handle<Object> initial_value(args[3], isolate);
   2074 
   2075   int index;
   2076   PropertyAttributes attributes;
   2077   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   2078   BindingFlags binding_flags;
   2079   Handle<Object> holder =
   2080       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2081 
   2082   if (attributes != ABSENT) {
   2083     // The name was declared before; check for conflicting re-declarations.
   2084     // Note: this is actually inconsistent with what happens for globals (where
   2085     // we silently ignore such declarations).
   2086     if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
   2087       // Functions are not read-only.
   2088       ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
   2089       const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
   2090       return ThrowRedeclarationError(isolate, type, name);
   2091     }
   2092 
   2093     // Initialize it if necessary.
   2094     if (*initial_value != NULL) {
   2095       if (index >= 0) {
   2096         ASSERT(holder.is_identical_to(context));
   2097         if (((attributes & READ_ONLY) == 0) ||
   2098             context->get(index)->IsTheHole()) {
   2099           context->set(index, *initial_value);
   2100         }
   2101       } else {
   2102         // Slow case: The property is in the context extension object of a
   2103         // function context or the global object of a native context.
   2104         Handle<JSObject> object = Handle<JSObject>::cast(holder);
   2105         RETURN_IF_EMPTY_HANDLE(
   2106             isolate,
   2107             JSReceiver::SetProperty(object, name, initial_value, mode,
   2108                                     kNonStrictMode));
   2109       }
   2110     }
   2111 
   2112   } else {
   2113     // The property is not in the function context. It needs to be
   2114     // "declared" in the function context's extension context or as a
   2115     // property of the the global object.
   2116     Handle<JSObject> object;
   2117     if (context->has_extension()) {
   2118       object = Handle<JSObject>(JSObject::cast(context->extension()));
   2119     } else {
   2120       // Context extension objects are allocated lazily.
   2121       ASSERT(context->IsFunctionContext());
   2122       object = isolate->factory()->NewJSObject(
   2123           isolate->context_extension_function());
   2124       context->set_extension(*object);
   2125     }
   2126     ASSERT(*object != NULL);
   2127 
   2128     // Declare the property by setting it to the initial value if provided,
   2129     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
   2130     // constant declarations).
   2131     ASSERT(!object->HasLocalProperty(*name));
   2132     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
   2133     if (*initial_value != NULL) value = initial_value;
   2134     // Declaring a const context slot is a conflicting declaration if
   2135     // there is a callback with that name in a prototype. It is
   2136     // allowed to introduce const variables in
   2137     // JSContextExtensionObjects. They are treated specially in
   2138     // SetProperty and no setters are invoked for those since they are
   2139     // not real JSObjects.
   2140     if (initial_value->IsTheHole() &&
   2141         !object->IsJSContextExtensionObject()) {
   2142       LookupResult lookup(isolate);
   2143       object->Lookup(*name, &lookup);
   2144       if (lookup.IsPropertyCallbacks()) {
   2145         return ThrowRedeclarationError(isolate, "const", name);
   2146       }
   2147     }
   2148     if (object->IsJSGlobalObject()) {
   2149       // Define own property on the global object.
   2150       RETURN_IF_EMPTY_HANDLE(isolate,
   2151          JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
   2152     } else {
   2153       RETURN_IF_EMPTY_HANDLE(isolate,
   2154          JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
   2155     }
   2156   }
   2157 
   2158   return isolate->heap()->undefined_value();
   2159 }
   2160 
   2161 
   2162 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
   2163   SealHandleScope shs(isolate);
   2164   // args[0] == name
   2165   // args[1] == language_mode
   2166   // args[2] == value (optional)
   2167 
   2168   // Determine if we need to assign to the variable if it already
   2169   // exists (based on the number of arguments).
   2170   RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
   2171   bool assign = args.length() == 3;
   2172 
   2173   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2174   GlobalObject* global = isolate->context()->global_object();
   2175   RUNTIME_ASSERT(args[1]->IsSmi());
   2176   CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
   2177   StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
   2178       ? kNonStrictMode : kStrictMode;
   2179 
   2180   // According to ECMA-262, section 12.2, page 62, the property must
   2181   // not be deletable.
   2182   PropertyAttributes attributes = DONT_DELETE;
   2183 
   2184   // Lookup the property locally in the global object. If it isn't
   2185   // there, there is a property with this name in the prototype chain.
   2186   // We follow Safari and Firefox behavior and only set the property
   2187   // locally if there is an explicit initialization value that we have
   2188   // to assign to the property.
   2189   // Note that objects can have hidden prototypes, so we need to traverse
   2190   // the whole chain of hidden prototypes to do a 'local' lookup.
   2191   Object* object = global;
   2192   LookupResult lookup(isolate);
   2193   JSObject::cast(object)->LocalLookup(*name, &lookup, true);
   2194   if (lookup.IsInterceptor()) {
   2195     HandleScope handle_scope(isolate);
   2196     PropertyAttributes intercepted =
   2197         lookup.holder()->GetPropertyAttribute(*name);
   2198     if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
   2199       // Found an interceptor that's not read only.
   2200       if (assign) {
   2201         return lookup.holder()->SetProperty(
   2202             &lookup, *name, args[2], attributes, strict_mode_flag);
   2203       } else {
   2204         return isolate->heap()->undefined_value();
   2205       }
   2206     }
   2207   }
   2208 
   2209   // Reload global in case the loop above performed a GC.
   2210   global = isolate->context()->global_object();
   2211   if (assign) {
   2212     return global->SetProperty(*name, args[2], attributes, strict_mode_flag);
   2213   }
   2214   return isolate->heap()->undefined_value();
   2215 }
   2216 
   2217 
   2218 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
   2219   SealHandleScope shs(isolate);
   2220   // All constants are declared with an initial value. The name
   2221   // of the constant is the first argument and the initial value
   2222   // is the second.
   2223   RUNTIME_ASSERT(args.length() == 2);
   2224   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   2225   Handle<Object> value = args.at<Object>(1);
   2226 
   2227   // Get the current global object from top.
   2228   GlobalObject* global = isolate->context()->global_object();
   2229 
   2230   // According to ECMA-262, section 12.2, page 62, the property must
   2231   // not be deletable. Since it's a const, it must be READ_ONLY too.
   2232   PropertyAttributes attributes =
   2233       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
   2234 
   2235   // Lookup the property locally in the global object. If it isn't
   2236   // there, we add the property and take special precautions to always
   2237   // add it as a local property even in case of callbacks in the
   2238   // prototype chain (this rules out using SetProperty).
   2239   // We use SetLocalPropertyIgnoreAttributes instead
   2240   LookupResult lookup(isolate);
   2241   global->LocalLookup(*name, &lookup);
   2242   if (!lookup.IsFound()) {
   2243     return global->SetLocalPropertyIgnoreAttributes(*name,
   2244                                                     *value,
   2245                                                     attributes);
   2246   }
   2247 
   2248   if (!lookup.IsReadOnly()) {
   2249     // Restore global object from context (in case of GC) and continue
   2250     // with setting the value.
   2251     HandleScope handle_scope(isolate);
   2252     Handle<GlobalObject> global(isolate->context()->global_object());
   2253 
   2254     // BUG 1213575: Handle the case where we have to set a read-only
   2255     // property through an interceptor and only do it if it's
   2256     // uninitialized, e.g. the hole. Nirk...
   2257     // Passing non-strict mode because the property is writable.
   2258     RETURN_IF_EMPTY_HANDLE(
   2259         isolate,
   2260         JSReceiver::SetProperty(global, name, value, attributes,
   2261                                 kNonStrictMode));
   2262     return *value;
   2263   }
   2264 
   2265   // Set the value, but only if we're assigning the initial value to a
   2266   // constant. For now, we determine this by checking if the
   2267   // current value is the hole.
   2268   // Strict mode handling not needed (const is disallowed in strict mode).
   2269   if (lookup.IsField()) {
   2270     FixedArray* properties = global->properties();
   2271     int index = lookup.GetFieldIndex().field_index();
   2272     if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
   2273       properties->set(index, *value);
   2274     }
   2275   } else if (lookup.IsNormal()) {
   2276     if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
   2277         !lookup.IsReadOnly()) {
   2278       HandleScope scope(isolate);
   2279       JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
   2280     }
   2281   } else {
   2282     // Ignore re-initialization of constants that have already been
   2283     // assigned a constant value.
   2284     ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
   2285   }
   2286 
   2287   // Use the set value as the result of the operation.
   2288   return *value;
   2289 }
   2290 
   2291 
   2292 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
   2293   HandleScope scope(isolate);
   2294   ASSERT(args.length() == 3);
   2295 
   2296   Handle<Object> value(args[0], isolate);
   2297   ASSERT(!value->IsTheHole());
   2298 
   2299   // Initializations are always done in a function or native context.
   2300   RUNTIME_ASSERT(args[1]->IsContext());
   2301   Handle<Context> context(Context::cast(args[1])->declaration_context());
   2302 
   2303   Handle<String> name(String::cast(args[2]));
   2304 
   2305   int index;
   2306   PropertyAttributes attributes;
   2307   ContextLookupFlags flags = FOLLOW_CHAINS;
   2308   BindingFlags binding_flags;
   2309   Handle<Object> holder =
   2310       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   2311 
   2312   if (index >= 0) {
   2313     ASSERT(holder->IsContext());
   2314     // Property was found in a context.  Perform the assignment if we
   2315     // found some non-constant or an uninitialized constant.
   2316     Handle<Context> context = Handle<Context>::cast(holder);
   2317     if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
   2318       context->set(index, *value);
   2319     }
   2320     return *value;
   2321   }
   2322 
   2323   // The property could not be found, we introduce it as a property of the
   2324   // global object.
   2325   if (attributes == ABSENT) {
   2326     Handle<JSObject> global = Handle<JSObject>(
   2327         isolate->context()->global_object());
   2328     // Strict mode not needed (const disallowed in strict mode).
   2329     RETURN_IF_EMPTY_HANDLE(
   2330         isolate,
   2331         JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode));
   2332     return *value;
   2333   }
   2334 
   2335   // The property was present in some function's context extension object,
   2336   // as a property on the subject of a with, or as a property of the global
   2337   // object.
   2338   //
   2339   // In most situations, eval-introduced consts should still be present in
   2340   // the context extension object.  However, because declaration and
   2341   // initialization are separate, the property might have been deleted
   2342   // before we reach the initialization point.
   2343   //
   2344   // Example:
   2345   //
   2346   //    function f() { eval("delete x; const x;"); }
   2347   //
   2348   // In that case, the initialization behaves like a normal assignment.
   2349   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   2350 
   2351   if (*object == context->extension()) {
   2352     // This is the property that was introduced by the const declaration.
   2353     // Set it if it hasn't been set before.  NOTE: We cannot use
   2354     // GetProperty() to get the current value as it 'unholes' the value.
   2355     LookupResult lookup(isolate);
   2356     object->LocalLookupRealNamedProperty(*name, &lookup);
   2357     ASSERT(lookup.IsFound());  // the property was declared
   2358     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
   2359 
   2360     if (lookup.IsField()) {
   2361       FixedArray* properties = object->properties();
   2362       int index = lookup.GetFieldIndex().field_index();
   2363       if (properties->get(index)->IsTheHole()) {
   2364         properties->set(index, *value);
   2365       }
   2366     } else if (lookup.IsNormal()) {
   2367       if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
   2368         JSObject::SetNormalizedProperty(object, &lookup, value);
   2369       }
   2370     } else {
   2371       // We should not reach here. Any real, named property should be
   2372       // either a field or a dictionary slot.
   2373       UNREACHABLE();
   2374     }
   2375   } else {
   2376     // The property was found on some other object.  Set it if it is not a
   2377     // read-only property.
   2378     if ((attributes & READ_ONLY) == 0) {
   2379       // Strict mode not needed (const disallowed in strict mode).
   2380       RETURN_IF_EMPTY_HANDLE(
   2381           isolate,
   2382           JSReceiver::SetProperty(object, name, value, attributes,
   2383                                   kNonStrictMode));
   2384     }
   2385   }
   2386 
   2387   return *value;
   2388 }
   2389 
   2390 
   2391 RUNTIME_FUNCTION(MaybeObject*,
   2392                  Runtime_OptimizeObjectForAddingMultipleProperties) {
   2393   HandleScope scope(isolate);
   2394   ASSERT(args.length() == 2);
   2395   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   2396   CONVERT_SMI_ARG_CHECKED(properties, 1);
   2397   if (object->HasFastProperties()) {
   2398     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
   2399   }
   2400   return *object;
   2401 }
   2402 
   2403 
   2404 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
   2405   HandleScope scope(isolate);
   2406   ASSERT(args.length() == 4);
   2407   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   2408   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   2409   // Due to the way the JS calls are constructed this must be less than the
   2410   // length of a string, i.e. it is always a Smi.  We check anyway for security.
   2411   CONVERT_SMI_ARG_CHECKED(index, 2);
   2412   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   2413   RUNTIME_ASSERT(index >= 0);
   2414   RUNTIME_ASSERT(index <= subject->length());
   2415   isolate->counters()->regexp_entry_runtime()->Increment();
   2416   Handle<Object> result = RegExpImpl::Exec(regexp,
   2417                                            subject,
   2418                                            index,
   2419                                            last_match_info);
   2420   RETURN_IF_EMPTY_HANDLE(isolate, result);
   2421   return *result;
   2422 }
   2423 
   2424 
   2425 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
   2426   SealHandleScope shs(isolate);
   2427   ASSERT(args.length() == 3);
   2428   CONVERT_SMI_ARG_CHECKED(elements_count, 0);
   2429   if (elements_count < 0 ||
   2430       elements_count > FixedArray::kMaxLength ||
   2431       !Smi::IsValid(elements_count)) {
   2432     return isolate->ThrowIllegalOperation();
   2433   }
   2434   Object* new_object;
   2435   { MaybeObject* maybe_new_object =
   2436         isolate->heap()->AllocateFixedArray(elements_count);
   2437     if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
   2438   }
   2439   FixedArray* elements = FixedArray::cast(new_object);
   2440   { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw(
   2441       JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
   2442     if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
   2443   }
   2444   {
   2445     DisallowHeapAllocation no_gc;
   2446     HandleScope scope(isolate);
   2447     reinterpret_cast<HeapObject*>(new_object)->
   2448         set_map(isolate->native_context()->regexp_result_map());
   2449   }
   2450   JSArray* array = JSArray::cast(new_object);
   2451   array->set_properties(isolate->heap()->empty_fixed_array());
   2452   array->set_elements(elements);
   2453   array->set_length(Smi::FromInt(elements_count));
   2454   // Write in-object properties after the length of the array.
   2455   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
   2456   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
   2457   return array;
   2458 }
   2459 
   2460 
   2461 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
   2462   SealHandleScope shs(isolate);
   2463   DisallowHeapAllocation no_allocation;
   2464   ASSERT(args.length() == 5);
   2465   CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
   2466   CONVERT_ARG_CHECKED(String, source, 1);
   2467   // If source is the empty string we set it to "(?:)" instead as
   2468   // suggested by ECMA-262, 5th, section 15.10.4.1.
   2469   if (source->length() == 0) source = isolate->heap()->query_colon_string();
   2470 
   2471   Object* global = args[2];
   2472   if (!global->IsTrue()) global = isolate->heap()->false_value();
   2473 
   2474   Object* ignoreCase = args[3];
   2475   if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value();
   2476 
   2477   Object* multiline = args[4];
   2478   if (!multiline->IsTrue()) multiline = isolate->heap()->false_value();
   2479 
   2480   Map* map = regexp->map();
   2481   Object* constructor = map->constructor();
   2482   if (constructor->IsJSFunction() &&
   2483       JSFunction::cast(constructor)->initial_map() == map) {
   2484     // If we still have the original map, set in-object properties directly.
   2485     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
   2486     // Both true and false are immovable immortal objects so no need for write
   2487     // barrier.
   2488     regexp->InObjectPropertyAtPut(
   2489         JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER);
   2490     regexp->InObjectPropertyAtPut(
   2491         JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
   2492     regexp->InObjectPropertyAtPut(
   2493         JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
   2494     regexp->InObjectPropertyAtPut(
   2495         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
   2496     return regexp;
   2497   }
   2498 
   2499   // Map has changed, so use generic, but slower, method.
   2500   PropertyAttributes final =
   2501       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
   2502   PropertyAttributes writable =
   2503       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
   2504   Heap* heap = isolate->heap();
   2505   MaybeObject* result;
   2506   result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_string(),
   2507                                                     source,
   2508                                                     final);
   2509   // TODO(jkummerow): Turn these back into ASSERTs when we can be certain
   2510   // that it never fires in Release mode in the wild.
   2511   CHECK(!result->IsFailure());
   2512   result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_string(),
   2513                                                     global,
   2514                                                     final);
   2515   CHECK(!result->IsFailure());
   2516   result =
   2517       regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_string(),
   2518                                                ignoreCase,
   2519                                                final);
   2520   CHECK(!result->IsFailure());
   2521   result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_string(),
   2522                                                     multiline,
   2523                                                     final);
   2524   CHECK(!result->IsFailure());
   2525   result =
   2526       regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_string(),
   2527                                                Smi::FromInt(0),
   2528                                                writable);
   2529   CHECK(!result->IsFailure());
   2530   USE(result);
   2531   return regexp;
   2532 }
   2533 
   2534 
   2535 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
   2536   HandleScope scope(isolate);
   2537   ASSERT(args.length() == 1);
   2538   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
   2539   // This is necessary to enable fast checks for absence of elements
   2540   // on Array.prototype and below.
   2541   prototype->set_elements(isolate->heap()->empty_fixed_array());
   2542   return Smi::FromInt(0);
   2543 }
   2544 
   2545 
   2546 static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
   2547                                          Handle<JSObject> holder,
   2548                                          const char* name,
   2549                                          Builtins::Name builtin_name) {
   2550   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
   2551   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
   2552   Handle<JSFunction> optimized =
   2553       isolate->factory()->NewFunction(key,
   2554                                       JS_OBJECT_TYPE,
   2555                                       JSObject::kHeaderSize,
   2556                                       code,
   2557                                       false);
   2558   optimized->shared()->DontAdaptArguments();
   2559   JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode);
   2560   return optimized;
   2561 }
   2562 
   2563 
   2564 RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
   2565   HandleScope scope(isolate);
   2566   ASSERT(args.length() == 1);
   2567   CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
   2568 
   2569   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
   2570   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
   2571   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
   2572   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
   2573   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
   2574   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
   2575   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
   2576 
   2577   return *holder;
   2578 }
   2579 
   2580 
   2581 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsClassicModeFunction) {
   2582   SealHandleScope shs(isolate);
   2583   ASSERT(args.length() == 1);
   2584   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2585   if (!callable->IsJSFunction()) {
   2586     HandleScope scope(isolate);
   2587     bool threw = false;
   2588     Handle<Object> delegate =
   2589         Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
   2590     if (threw) return Failure::Exception();
   2591     callable = JSFunction::cast(*delegate);
   2592   }
   2593   JSFunction* function = JSFunction::cast(callable);
   2594   SharedFunctionInfo* shared = function->shared();
   2595   return isolate->heap()->ToBoolean(shared->is_classic_mode());
   2596 }
   2597 
   2598 
   2599 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
   2600   SealHandleScope shs(isolate);
   2601   ASSERT(args.length() == 1);
   2602   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   2603 
   2604   if (!callable->IsJSFunction()) {
   2605     HandleScope scope(isolate);
   2606     bool threw = false;
   2607     Handle<Object> delegate =
   2608         Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
   2609     if (threw) return Failure::Exception();
   2610     callable = JSFunction::cast(*delegate);
   2611   }
   2612   JSFunction* function = JSFunction::cast(callable);
   2613 
   2614   SharedFunctionInfo* shared = function->shared();
   2615   if (shared->native() || !shared->is_classic_mode()) {
   2616     return isolate->heap()->undefined_value();
   2617   }
   2618   // Returns undefined for strict or native functions, or
   2619   // the associated global receiver for "normal" functions.
   2620 
   2621   Context* native_context =
   2622       function->context()->global_object()->native_context();
   2623   return native_context->global_object()->global_receiver();
   2624 }
   2625 
   2626 
   2627 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
   2628   HandleScope scope(isolate);
   2629   ASSERT(args.length() == 4);
   2630   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
   2631   int index = args.smi_at(1);
   2632   Handle<String> pattern = args.at<String>(2);
   2633   Handle<String> flags = args.at<String>(3);
   2634 
   2635   // Get the RegExp function from the context in the literals array.
   2636   // This is the RegExp function from the context in which the
   2637   // function was created.  We do not use the RegExp function from the
   2638   // current native context because this might be the RegExp function
   2639   // from another context which we should not have access to.
   2640   Handle<JSFunction> constructor =
   2641       Handle<JSFunction>(
   2642           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
   2643   // Compute the regular expression literal.
   2644   bool has_pending_exception;
   2645   Handle<Object> regexp =
   2646       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags,
   2647                                       &has_pending_exception);
   2648   if (has_pending_exception) {
   2649     ASSERT(isolate->has_pending_exception());
   2650     return Failure::Exception();
   2651   }
   2652   literals->set(index, *regexp);
   2653   return *regexp;
   2654 }
   2655 
   2656 
   2657 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetName) {
   2658   SealHandleScope shs(isolate);
   2659   ASSERT(args.length() == 1);
   2660 
   2661   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2662   return f->shared()->name();
   2663 }
   2664 
   2665 
   2666 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
   2667   SealHandleScope shs(isolate);
   2668   ASSERT(args.length() == 2);
   2669 
   2670   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2671   CONVERT_ARG_CHECKED(String, name, 1);
   2672   f->shared()->set_name(name);
   2673   return isolate->heap()->undefined_value();
   2674 }
   2675 
   2676 
   2677 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
   2678   SealHandleScope shs(isolate);
   2679   ASSERT(args.length() == 1);
   2680   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2681   return isolate->heap()->ToBoolean(
   2682       f->shared()->name_should_print_as_anonymous());
   2683 }
   2684 
   2685 
   2686 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
   2687   SealHandleScope shs(isolate);
   2688   ASSERT(args.length() == 1);
   2689   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2690   f->shared()->set_name_should_print_as_anonymous(true);
   2691   return isolate->heap()->undefined_value();
   2692 }
   2693 
   2694 
   2695 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsGenerator) {
   2696   SealHandleScope shs(isolate);
   2697   ASSERT(args.length() == 1);
   2698   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2699   return isolate->heap()->ToBoolean(f->shared()->is_generator());
   2700 }
   2701 
   2702 
   2703 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
   2704   SealHandleScope shs(isolate);
   2705   ASSERT(args.length() == 1);
   2706 
   2707   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2708   f->RemovePrototype();
   2709 
   2710   return isolate->heap()->undefined_value();
   2711 }
   2712 
   2713 
   2714 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScript) {
   2715   HandleScope scope(isolate);
   2716   ASSERT(args.length() == 1);
   2717 
   2718   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2719   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
   2720   if (!script->IsScript()) return isolate->heap()->undefined_value();
   2721 
   2722   return *GetScriptWrapper(Handle<Script>::cast(script));
   2723 }
   2724 
   2725 
   2726 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetSourceCode) {
   2727   HandleScope scope(isolate);
   2728   ASSERT(args.length() == 1);
   2729 
   2730   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
   2731   Handle<SharedFunctionInfo> shared(f->shared());
   2732   return *shared->GetSourceCode();
   2733 }
   2734 
   2735 
   2736 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScriptSourcePosition) {
   2737   SealHandleScope shs(isolate);
   2738   ASSERT(args.length() == 1);
   2739 
   2740   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2741   int pos = fun->shared()->start_position();
   2742   return Smi::FromInt(pos);
   2743 }
   2744 
   2745 
   2746 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
   2747   SealHandleScope shs(isolate);
   2748   ASSERT(args.length() == 2);
   2749 
   2750   CONVERT_ARG_CHECKED(Code, code, 0);
   2751   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
   2752 
   2753   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
   2754 
   2755   Address pc = code->address() + offset;
   2756   return Smi::FromInt(code->SourcePosition(pc));
   2757 }
   2758 
   2759 
   2760 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetInstanceClassName) {
   2761   SealHandleScope shs(isolate);
   2762   ASSERT(args.length() == 2);
   2763 
   2764   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2765   CONVERT_ARG_CHECKED(String, name, 1);
   2766   fun->SetInstanceClassName(name);
   2767   return isolate->heap()->undefined_value();
   2768 }
   2769 
   2770 
   2771 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
   2772   SealHandleScope shs(isolate);
   2773   ASSERT(args.length() == 2);
   2774 
   2775   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2776   CONVERT_SMI_ARG_CHECKED(length, 1);
   2777   fun->shared()->set_length(length);
   2778   return isolate->heap()->undefined_value();
   2779 }
   2780 
   2781 
   2782 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
   2783   SealHandleScope shs(isolate);
   2784   ASSERT(args.length() == 2);
   2785 
   2786   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2787   ASSERT(fun->should_have_prototype());
   2788   Object* obj;
   2789   { MaybeObject* maybe_obj =
   2790         Accessors::FunctionSetPrototype(fun, args[1], NULL);
   2791     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   2792   }
   2793   return args[0];  // return TOS
   2794 }
   2795 
   2796 
   2797 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
   2798   SealHandleScope shs(isolate);
   2799   RUNTIME_ASSERT(args.length() == 1);
   2800   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   2801 
   2802   String* name = isolate->heap()->prototype_string();
   2803 
   2804   if (function->HasFastProperties()) {
   2805     // Construct a new field descriptor with updated attributes.
   2806     DescriptorArray* instance_desc = function->map()->instance_descriptors();
   2807 
   2808     int index = instance_desc->SearchWithCache(name, function->map());
   2809     ASSERT(index != DescriptorArray::kNotFound);
   2810     PropertyDetails details = instance_desc->GetDetails(index);
   2811 
   2812     CallbacksDescriptor new_desc(name,
   2813         instance_desc->GetValue(index),
   2814         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
   2815 
   2816     // Create a new map featuring the new field descriptors array.
   2817     Map* new_map;
   2818     MaybeObject* maybe_map =
   2819         function->map()->CopyReplaceDescriptor(
   2820             instance_desc, &new_desc, index, OMIT_TRANSITION);
   2821     if (!maybe_map->To(&new_map)) return maybe_map;
   2822 
   2823     function->set_map(new_map);
   2824   } else {  // Dictionary properties.
   2825     // Directly manipulate the property details.
   2826     int entry = function->property_dictionary()->FindEntry(name);
   2827     ASSERT(entry != NameDictionary::kNotFound);
   2828     PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
   2829     PropertyDetails new_details(
   2830         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
   2831         details.type(),
   2832         details.dictionary_index());
   2833     function->property_dictionary()->DetailsAtPut(entry, new_details);
   2834   }
   2835   return function;
   2836 }
   2837 
   2838 
   2839 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
   2840   SealHandleScope shs(isolate);
   2841   ASSERT(args.length() == 1);
   2842 
   2843   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2844   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
   2845 }
   2846 
   2847 
   2848 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
   2849   SealHandleScope shs(isolate);
   2850   ASSERT(args.length() == 1);
   2851 
   2852   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2853   return isolate->heap()->ToBoolean(f->IsBuiltin());
   2854 }
   2855 
   2856 
   2857 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
   2858   HandleScope scope(isolate);
   2859   ASSERT(args.length() == 2);
   2860 
   2861   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
   2862   Handle<Object> code = args.at<Object>(1);
   2863 
   2864   if (code->IsNull()) return *target;
   2865   RUNTIME_ASSERT(code->IsJSFunction());
   2866   Handle<JSFunction> source = Handle<JSFunction>::cast(code);
   2867   Handle<SharedFunctionInfo> target_shared(target->shared());
   2868   Handle<SharedFunctionInfo> source_shared(source->shared());
   2869 
   2870   if (!JSFunction::EnsureCompiled(source, KEEP_EXCEPTION)) {
   2871     return Failure::Exception();
   2872   }
   2873 
   2874   // Mark both, the source and the target, as un-flushable because the
   2875   // shared unoptimized code makes them impossible to enqueue in a list.
   2876   ASSERT(target_shared->code()->gc_metadata() == NULL);
   2877   ASSERT(source_shared->code()->gc_metadata() == NULL);
   2878   target_shared->set_dont_flush(true);
   2879   source_shared->set_dont_flush(true);
   2880 
   2881   // Set the code, scope info, formal parameter count, and the length
   2882   // of the target shared function info.  Set the source code of the
   2883   // target function to undefined.  SetCode is only used for built-in
   2884   // constructors like String, Array, and Object, and some web code
   2885   // doesn't like seeing source code for constructors.
   2886   target_shared->ReplaceCode(source_shared->code());
   2887   target_shared->set_scope_info(source_shared->scope_info());
   2888   target_shared->set_length(source_shared->length());
   2889   target_shared->set_formal_parameter_count(
   2890       source_shared->formal_parameter_count());
   2891   target_shared->set_script(isolate->heap()->undefined_value());
   2892 
   2893   // Since we don't store the source we should never optimize this.
   2894   target_shared->code()->set_optimizable(false);
   2895 
   2896   // Set the code of the target function.
   2897   target->ReplaceCode(source_shared->code());
   2898   ASSERT(target->next_function_link()->IsUndefined());
   2899 
   2900   // Make sure we get a fresh copy of the literal vector to avoid cross
   2901   // context contamination.
   2902   Handle<Context> context(source->context());
   2903   int number_of_literals = source->NumberOfLiterals();
   2904   Handle<FixedArray> literals =
   2905       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
   2906   if (number_of_literals > 0) {
   2907     literals->set(JSFunction::kLiteralNativeContextIndex,
   2908                   context->native_context());
   2909   }
   2910   target->set_context(*context);
   2911   target->set_literals(*literals);
   2912 
   2913   if (isolate->logger()->is_logging_code_events() ||
   2914       isolate->cpu_profiler()->is_profiling()) {
   2915     isolate->logger()->LogExistingFunction(
   2916         source_shared, Handle<Code>(source_shared->code()));
   2917   }
   2918 
   2919   return *target;
   2920 }
   2921 
   2922 
   2923 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
   2924   HandleScope scope(isolate);
   2925   ASSERT(args.length() == 2);
   2926   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   2927   CONVERT_SMI_ARG_CHECKED(num, 1);
   2928   RUNTIME_ASSERT(num >= 0);
   2929   SetExpectedNofProperties(function, num);
   2930   return isolate->heap()->undefined_value();
   2931 }
   2932 
   2933 
   2934 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
   2935   SealHandleScope shs(isolate);
   2936   ASSERT(args.length() == 0);
   2937 
   2938   JavaScriptFrameIterator it(isolate);
   2939   JavaScriptFrame* frame = it.frame();
   2940   JSFunction* function = frame->function();
   2941   RUNTIME_ASSERT(function->shared()->is_generator());
   2942 
   2943   JSGeneratorObject* generator;
   2944   if (frame->IsConstructor()) {
   2945     generator = JSGeneratorObject::cast(frame->receiver());
   2946   } else {
   2947     MaybeObject* maybe_generator =
   2948         isolate->heap()->AllocateJSGeneratorObject(function);
   2949     if (!maybe_generator->To(&generator)) return maybe_generator;
   2950   }
   2951   generator->set_function(function);
   2952   generator->set_context(Context::cast(frame->context()));
   2953   generator->set_receiver(frame->receiver());
   2954   generator->set_continuation(0);
   2955   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
   2956   generator->set_stack_handler_index(-1);
   2957 
   2958   return generator;
   2959 }
   2960 
   2961 
   2962 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) {
   2963   SealHandleScope shs(isolate);
   2964   ASSERT(args.length() == 1);
   2965   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
   2966 
   2967   JavaScriptFrameIterator stack_iterator(isolate);
   2968   JavaScriptFrame* frame = stack_iterator.frame();
   2969   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
   2970   ASSERT_EQ(frame->function(), generator_object->function());
   2971 
   2972   // The caller should have saved the context and continuation already.
   2973   ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
   2974   ASSERT_LT(0, generator_object->continuation());
   2975 
   2976   // We expect there to be at least two values on the operand stack: the return
   2977   // value of the yield expression, and the argument to this runtime call.
   2978   // Neither of those should be saved.
   2979   int operands_count = frame->ComputeOperandsCount();
   2980   ASSERT_GE(operands_count, 2);
   2981   operands_count -= 2;
   2982 
   2983   if (operands_count == 0) {
   2984     // Although it's semantically harmless to call this function with an
   2985     // operands_count of zero, it is also unnecessary.
   2986     ASSERT_EQ(generator_object->operand_stack(),
   2987               isolate->heap()->empty_fixed_array());
   2988     ASSERT_EQ(generator_object->stack_handler_index(), -1);
   2989     // If there are no operands on the stack, there shouldn't be a handler
   2990     // active either.
   2991     ASSERT(!frame->HasHandler());
   2992   } else {
   2993     int stack_handler_index = -1;
   2994     MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count);
   2995     FixedArray* operand_stack;
   2996     if (!alloc->To(&operand_stack)) return alloc;
   2997     frame->SaveOperandStack(operand_stack, &stack_handler_index);
   2998     generator_object->set_operand_stack(operand_stack);
   2999     generator_object->set_stack_handler_index(stack_handler_index);
   3000   }
   3001 
   3002   return isolate->heap()->undefined_value();
   3003 }
   3004 
   3005 
   3006 // Note that this function is the slow path for resuming generators.  It is only
   3007 // called if the suspended activation had operands on the stack, stack handlers
   3008 // needing rewinding, or if the resume should throw an exception.  The fast path
   3009 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
   3010 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
   3011 // called in any case, as it needs to reconstruct the stack frame and make space
   3012 // for arguments and operands.
   3013 RUNTIME_FUNCTION(MaybeObject*, Runtime_ResumeJSGeneratorObject) {
   3014   SealHandleScope shs(isolate);
   3015   ASSERT(args.length() == 3);
   3016   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
   3017   CONVERT_ARG_CHECKED(Object, value, 1);
   3018   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
   3019   JavaScriptFrameIterator stack_iterator(isolate);
   3020   JavaScriptFrame* frame = stack_iterator.frame();
   3021 
   3022   ASSERT_EQ(frame->function(), generator_object->function());
   3023   ASSERT(frame->function()->is_compiled());
   3024 
   3025   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0);
   3026   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0);
   3027 
   3028   Address pc = generator_object->function()->code()->instruction_start();
   3029   int offset = generator_object->continuation();
   3030   ASSERT(offset > 0);
   3031   frame->set_pc(pc + offset);
   3032   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
   3033 
   3034   FixedArray* operand_stack = generator_object->operand_stack();
   3035   int operands_count = operand_stack->length();
   3036   if (operands_count != 0) {
   3037     frame->RestoreOperandStack(operand_stack,
   3038                                generator_object->stack_handler_index());
   3039     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
   3040     generator_object->set_stack_handler_index(-1);
   3041   }
   3042 
   3043   JSGeneratorObject::ResumeMode resume_mode =
   3044       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
   3045   switch (resume_mode) {
   3046     case JSGeneratorObject::NEXT:
   3047       return value;
   3048     case JSGeneratorObject::THROW:
   3049       return isolate->Throw(value);
   3050   }
   3051 
   3052   UNREACHABLE();
   3053   return isolate->ThrowIllegalOperation();
   3054 }
   3055 
   3056 
   3057 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowGeneratorStateError) {
   3058   HandleScope scope(isolate);
   3059   ASSERT(args.length() == 1);
   3060   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
   3061   int continuation = generator->continuation();
   3062   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
   3063       "generator_finished" : "generator_running";
   3064   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
   3065   Handle<Object> error = isolate->factory()->NewError(message, argv);
   3066   return isolate->Throw(*error);
   3067 }
   3068 
   3069 
   3070 RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) {
   3071   SealHandleScope shs(isolate);
   3072   ASSERT(args.length() == 1);
   3073   CONVERT_ARG_CHECKED(JSObject, object, 0);
   3074   return object->Freeze(isolate);
   3075 }
   3076 
   3077 
   3078 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
   3079                                                  Object* char_code) {
   3080   if (char_code->IsNumber()) {
   3081     return isolate->heap()->LookupSingleCharacterStringFromCode(
   3082         NumberToUint32(char_code) & 0xffff);
   3083   }
   3084   return isolate->heap()->empty_string();
   3085 }
   3086 
   3087 
   3088 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAt) {
   3089   SealHandleScope shs(isolate);
   3090   ASSERT(args.length() == 2);
   3091 
   3092   CONVERT_ARG_CHECKED(String, subject, 0);
   3093   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
   3094 
   3095   // Flatten the string.  If someone wants to get a char at an index
   3096   // in a cons string, it is likely that more indices will be
   3097   // accessed.
   3098   Object* flat;
   3099   { MaybeObject* maybe_flat = subject->TryFlatten();
   3100     if (!maybe_flat->ToObject(&flat)) return maybe_flat;
   3101   }
   3102   subject = String::cast(flat);
   3103 
   3104   if (i >= static_cast<uint32_t>(subject->length())) {
   3105     return isolate->heap()->nan_value();
   3106   }
   3107 
   3108   return Smi::FromInt(subject->Get(i));
   3109 }
   3110 
   3111 
   3112 RUNTIME_FUNCTION(MaybeObject*, Runtime_CharFromCode) {
   3113   SealHandleScope shs(isolate);
   3114   ASSERT(args.length() == 1);
   3115   return CharFromCode(isolate, args[0]);
   3116 }
   3117 
   3118 
   3119 class FixedArrayBuilder {
   3120  public:
   3121   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
   3122       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
   3123         length_(0),
   3124         has_non_smi_elements_(false) {
   3125     // Require a non-zero initial size. Ensures that doubling the size to
   3126     // extend the array will work.
   3127     ASSERT(initial_capacity > 0);
   3128   }
   3129 
   3130   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
   3131       : array_(backing_store),
   3132         length_(0),
   3133         has_non_smi_elements_(false) {
   3134     // Require a non-zero initial size. Ensures that doubling the size to
   3135     // extend the array will work.
   3136     ASSERT(backing_store->length() > 0);
   3137   }
   3138 
   3139   bool HasCapacity(int elements) {
   3140     int length = array_->length();
   3141     int required_length = length_ + elements;
   3142     return (length >= required_length);
   3143   }
   3144 
   3145   void EnsureCapacity(int elements) {
   3146     int length = array_->length();
   3147     int required_length = length_ + elements;
   3148     if (length < required_length) {
   3149       int new_length = length;
   3150       do {
   3151         new_length *= 2;
   3152       } while (new_length < required_length);
   3153       Handle<FixedArray> extended_array =
   3154           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
   3155       array_->CopyTo(0, *extended_array, 0, length_);
   3156       array_ = extended_array;
   3157     }
   3158   }
   3159 
   3160   void Add(Object* value) {
   3161     ASSERT(!value->IsSmi());
   3162     ASSERT(length_ < capacity());
   3163     array_->set(length_, value);
   3164     length_++;
   3165     has_non_smi_elements_ = true;
   3166   }
   3167 
   3168   void Add(Smi* value) {
   3169     ASSERT(value->IsSmi());
   3170     ASSERT(length_ < capacity());
   3171     array_->set(length_, value);
   3172     length_++;
   3173   }
   3174 
   3175   Handle<FixedArray> array() {
   3176     return array_;
   3177   }
   3178 
   3179   int length() {
   3180     return length_;
   3181   }
   3182 
   3183   int capacity() {
   3184     return array_->length();
   3185   }
   3186 
   3187   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
   3188     Factory* factory = target_array->GetIsolate()->factory();
   3189     factory->SetContent(target_array, array_);
   3190     target_array->set_length(Smi::FromInt(length_));
   3191     return target_array;
   3192   }
   3193 
   3194 
   3195  private:
   3196   Handle<FixedArray> array_;
   3197   int length_;
   3198   bool has_non_smi_elements_;
   3199 };
   3200 
   3201 
   3202 // Forward declarations.
   3203 const int kStringBuilderConcatHelperLengthBits = 11;
   3204 const int kStringBuilderConcatHelperPositionBits = 19;
   3205 
   3206 template <typename schar>
   3207 static inline void StringBuilderConcatHelper(String*,
   3208                                              schar*,
   3209                                              FixedArray*,
   3210                                              int);
   3211 
   3212 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
   3213     StringBuilderSubstringLength;
   3214 typedef BitField<int,
   3215                  kStringBuilderConcatHelperLengthBits,
   3216                  kStringBuilderConcatHelperPositionBits>
   3217     StringBuilderSubstringPosition;
   3218 
   3219 
   3220 class ReplacementStringBuilder {
   3221  public:
   3222   ReplacementStringBuilder(Heap* heap,
   3223                            Handle<String> subject,
   3224                            int estimated_part_count)
   3225       : heap_(heap),
   3226         array_builder_(heap->isolate(), estimated_part_count),
   3227         subject_(subject),
   3228         character_count_(0),
   3229         is_ascii_(subject->IsOneByteRepresentation()) {
   3230     // Require a non-zero initial size. Ensures that doubling the size to
   3231     // extend the array will work.
   3232     ASSERT(estimated_part_count > 0);
   3233   }
   3234 
   3235   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
   3236                                      int from,
   3237                                      int to) {
   3238     ASSERT(from >= 0);
   3239     int length = to - from;
   3240     ASSERT(length > 0);
   3241     if (StringBuilderSubstringLength::is_valid(length) &&
   3242         StringBuilderSubstringPosition::is_valid(from)) {
   3243       int encoded_slice = StringBuilderSubstringLength::encode(length) |
   3244           StringBuilderSubstringPosition::encode(from);
   3245       builder->Add(Smi::FromInt(encoded_slice));
   3246     } else {
   3247       // Otherwise encode as two smis.
   3248       builder->Add(Smi::FromInt(-length));
   3249       builder->Add(Smi::FromInt(from));
   3250     }
   3251   }
   3252 
   3253 
   3254   void EnsureCapacity(int elements) {
   3255     array_builder_.EnsureCapacity(elements);
   3256   }
   3257 
   3258 
   3259   void AddSubjectSlice(int from, int to) {
   3260     AddSubjectSlice(&array_builder_, from, to);
   3261     IncrementCharacterCount(to - from);
   3262   }
   3263 
   3264 
   3265   void AddString(Handle<String> string) {
   3266     int length = string->length();
   3267     ASSERT(length > 0);
   3268     AddElement(*string);
   3269     if (!string->IsOneByteRepresentation()) {
   3270       is_ascii_ = false;
   3271     }
   3272     IncrementCharacterCount(length);
   3273   }
   3274 
   3275 
   3276   Handle<String> ToString() {
   3277     if (array_builder_.length() == 0) {
   3278       return heap_->isolate()->factory()->empty_string();
   3279     }
   3280 
   3281     Handle<String> joined_string;
   3282     if (is_ascii_) {
   3283       Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_);
   3284       DisallowHeapAllocation no_gc;
   3285       uint8_t* char_buffer = seq->GetChars();
   3286       StringBuilderConcatHelper(*subject_,
   3287                                 char_buffer,
   3288                                 *array_builder_.array(),
   3289                                 array_builder_.length());
   3290       joined_string = Handle<String>::cast(seq);
   3291     } else {
   3292       // Non-ASCII.
   3293       Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
   3294       DisallowHeapAllocation no_gc;
   3295       uc16* char_buffer = seq->GetChars();
   3296       StringBuilderConcatHelper(*subject_,
   3297                                 char_buffer,
   3298                                 *array_builder_.array(),
   3299                                 array_builder_.length());
   3300       joined_string = Handle<String>::cast(seq);
   3301     }
   3302     return joined_string;
   3303   }
   3304 
   3305 
   3306   void IncrementCharacterCount(int by) {
   3307     if (character_count_ > String::kMaxLength - by) {
   3308       V8::FatalProcessOutOfMemory("String.replace result too large.");
   3309     }
   3310     character_count_ += by;
   3311   }
   3312 
   3313  private:
   3314   Handle<SeqOneByteString> NewRawOneByteString(int length) {
   3315     return heap_->isolate()->factory()->NewRawOneByteString(length);
   3316   }
   3317 
   3318 
   3319   Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
   3320     return heap_->isolate()->factory()->NewRawTwoByteString(length);
   3321   }
   3322 
   3323 
   3324   void AddElement(Object* element) {
   3325     ASSERT(element->IsSmi() || element->IsString());
   3326     ASSERT(array_builder_.capacity() > array_builder_.length());
   3327     array_builder_.Add(element);
   3328   }
   3329 
   3330   Heap* heap_;
   3331   FixedArrayBuilder array_builder_;
   3332   Handle<String> subject_;
   3333   int character_count_;
   3334   bool is_ascii_;
   3335 };
   3336 
   3337 
   3338 class CompiledReplacement {
   3339  public:
   3340   explicit CompiledReplacement(Zone* zone)
   3341       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
   3342 
   3343   // Return whether the replacement is simple.
   3344   bool Compile(Handle<String> replacement,
   3345                int capture_count,
   3346                int subject_length);
   3347 
   3348   // Use Apply only if Compile returned false.
   3349   void Apply(ReplacementStringBuilder* builder,
   3350              int match_from,
   3351              int match_to,
   3352              int32_t* match);
   3353 
   3354   // Number of distinct parts of the replacement pattern.
   3355   int parts() {
   3356     return parts_.length();
   3357   }
   3358 
   3359   Zone* zone() const { return zone_; }
   3360 
   3361  private:
   3362   enum PartType {
   3363     SUBJECT_PREFIX = 1,
   3364     SUBJECT_SUFFIX,
   3365     SUBJECT_CAPTURE,
   3366     REPLACEMENT_SUBSTRING,
   3367     REPLACEMENT_STRING,
   3368 
   3369     NUMBER_OF_PART_TYPES
   3370   };
   3371 
   3372   struct ReplacementPart {
   3373     static inline ReplacementPart SubjectMatch() {
   3374       return ReplacementPart(SUBJECT_CAPTURE, 0);
   3375     }
   3376     static inline ReplacementPart SubjectCapture(int capture_index) {
   3377       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
   3378     }
   3379     static inline ReplacementPart SubjectPrefix() {
   3380       return ReplacementPart(SUBJECT_PREFIX, 0);
   3381     }
   3382     static inline ReplacementPart SubjectSuffix(int subject_length) {
   3383       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
   3384     }
   3385     static inline ReplacementPart ReplacementString() {
   3386       return ReplacementPart(REPLACEMENT_STRING, 0);
   3387     }
   3388     static inline ReplacementPart ReplacementSubString(int from, int to) {
   3389       ASSERT(from >= 0);
   3390       ASSERT(to > from);
   3391       return ReplacementPart(-from, to);
   3392     }
   3393 
   3394     // If tag <= 0 then it is the negation of a start index of a substring of
   3395     // the replacement pattern, otherwise it's a value from PartType.
   3396     ReplacementPart(int tag, int data)
   3397         : tag(tag), data(data) {
   3398       // Must be non-positive or a PartType value.
   3399       ASSERT(tag < NUMBER_OF_PART_TYPES);
   3400     }
   3401     // Either a value of PartType or a non-positive number that is
   3402     // the negation of an index into the replacement string.
   3403     int tag;
   3404     // The data value's interpretation depends on the value of tag:
   3405     // tag == SUBJECT_PREFIX ||
   3406     // tag == SUBJECT_SUFFIX:  data is unused.
   3407     // tag == SUBJECT_CAPTURE: data is the number of the capture.
   3408     // tag == REPLACEMENT_SUBSTRING ||
   3409     // tag == REPLACEMENT_STRING:    data is index into array of substrings
   3410     //                               of the replacement string.
   3411     // tag <= 0: Temporary representation of the substring of the replacement
   3412     //           string ranging over -tag .. data.
   3413     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
   3414     //           substring objects.
   3415     int data;
   3416   };
   3417 
   3418   template<typename Char>
   3419   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
   3420                                Vector<Char> characters,
   3421                                int capture_count,
   3422                                int subject_length,
   3423                                Zone* zone) {
   3424     int length = characters.length();
   3425     int last = 0;
   3426     for (int i = 0; i < length; i++) {
   3427       Char c = characters[i];
   3428       if (c == '$') {
   3429         int next_index = i + 1;
   3430         if (next_index == length) {  // No next character!
   3431           break;
   3432         }
   3433         Char c2 = characters[next_index];
   3434         switch (c2) {
   3435         case '$':
   3436           if (i > last) {
   3437             // There is a substring before. Include the first "$".
   3438             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
   3439                        zone);
   3440             last = next_index + 1;  // Continue after the second "$".
   3441           } else {
   3442             // Let the next substring start with the second "$".
   3443             last = next_index;
   3444           }
   3445           i = next_index;
   3446           break;
   3447         case '`':
   3448           if (i > last) {
   3449             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3450           }
   3451           parts->Add(ReplacementPart::SubjectPrefix(), zone);
   3452           i = next_index;
   3453           last = i + 1;
   3454           break;
   3455         case '\'':
   3456           if (i > last) {
   3457             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3458           }
   3459           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
   3460           i = next_index;
   3461           last = i + 1;
   3462           break;
   3463         case '&':
   3464           if (i > last) {
   3465             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3466           }
   3467           parts->Add(ReplacementPart::SubjectMatch(), zone);
   3468           i = next_index;
   3469           last = i + 1;
   3470           break;
   3471         case '0':
   3472         case '1':
   3473         case '2':
   3474         case '3':
   3475         case '4':
   3476         case '5':
   3477         case '6':
   3478         case '7':
   3479         case '8':
   3480         case '9': {
   3481           int capture_ref = c2 - '0';
   3482           if (capture_ref > capture_count) {
   3483             i = next_index;
   3484             continue;
   3485           }
   3486           int second_digit_index = next_index + 1;
   3487           if (second_digit_index < length) {
   3488             // Peek ahead to see if we have two digits.
   3489             Char c3 = characters[second_digit_index];
   3490             if ('0' <= c3 && c3 <= '9') {  // Double digits.
   3491               int double_digit_ref = capture_ref * 10 + c3 - '0';
   3492               if (double_digit_ref <= capture_count) {
   3493                 next_index = second_digit_index;
   3494                 capture_ref = double_digit_ref;
   3495               }
   3496             }
   3497           }
   3498           if (capture_ref > 0) {
   3499             if (i > last) {
   3500               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
   3501             }
   3502             ASSERT(capture_ref <= capture_count);
   3503             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
   3504             last = next_index + 1;
   3505           }
   3506           i = next_index;
   3507           break;
   3508         }
   3509         default:
   3510           i = next_index;
   3511           break;
   3512         }
   3513       }
   3514     }
   3515     if (length > last) {
   3516       if (last == 0) {
   3517         // Replacement is simple.  Do not use Apply to do the replacement.
   3518         return true;
   3519       } else {
   3520         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
   3521       }
   3522     }
   3523     return false;
   3524   }
   3525 
   3526   ZoneList<ReplacementPart> parts_;
   3527   ZoneList<Handle<String> > replacement_substrings_;
   3528   Zone* zone_;
   3529 };
   3530 
   3531 
   3532 bool CompiledReplacement::Compile(Handle<String> replacement,
   3533                                   int capture_count,
   3534                                   int subject_length) {
   3535   {
   3536     DisallowHeapAllocation no_gc;
   3537     String::FlatContent content = replacement->GetFlatContent();
   3538     ASSERT(content.IsFlat());
   3539     bool simple = false;
   3540     if (content.IsAscii()) {
   3541       simple = ParseReplacementPattern(&parts_,
   3542                                        content.ToOneByteVector(),
   3543                                        capture_count,
   3544                                        subject_length,
   3545                                        zone());
   3546     } else {
   3547       ASSERT(content.IsTwoByte());
   3548       simple = ParseReplacementPattern(&parts_,
   3549                                        content.ToUC16Vector(),
   3550                                        capture_count,
   3551                                        subject_length,
   3552                                        zone());
   3553     }
   3554     if (simple) return true;
   3555   }
   3556 
   3557   Isolate* isolate = replacement->GetIsolate();
   3558   // Find substrings of replacement string and create them as String objects.
   3559   int substring_index = 0;
   3560   for (int i = 0, n = parts_.length(); i < n; i++) {
   3561     int tag = parts_[i].tag;
   3562     if (tag <= 0) {  // A replacement string slice.
   3563       int from = -tag;
   3564       int to = parts_[i].data;
   3565       replacement_substrings_.Add(
   3566           isolate->factory()->NewSubString(replacement, from, to), zone());
   3567       parts_[i].tag = REPLACEMENT_SUBSTRING;
   3568       parts_[i].data = substring_index;
   3569       substring_index++;
   3570     } else if (tag == REPLACEMENT_STRING) {
   3571       replacement_substrings_.Add(replacement, zone());
   3572       parts_[i].data = substring_index;
   3573       substring_index++;
   3574     }
   3575   }
   3576   return false;
   3577 }
   3578 
   3579 
   3580 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
   3581                                 int match_from,
   3582                                 int match_to,
   3583                                 int32_t* match) {
   3584   ASSERT_LT(0, parts_.length());
   3585   for (int i = 0, n = parts_.length(); i < n; i++) {
   3586     ReplacementPart part = parts_[i];
   3587     switch (part.tag) {
   3588       case SUBJECT_PREFIX:
   3589         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
   3590         break;
   3591       case SUBJECT_SUFFIX: {
   3592         int subject_length = part.data;
   3593         if (match_to < subject_length) {
   3594           builder->AddSubjectSlice(match_to, subject_length);
   3595         }
   3596         break;
   3597       }
   3598       case SUBJECT_CAPTURE: {
   3599         int capture = part.data;
   3600         int from = match[capture * 2];
   3601         int to = match[capture * 2 + 1];
   3602         if (from >= 0 && to > from) {
   3603           builder->AddSubjectSlice(from, to);
   3604         }
   3605         break;
   3606       }
   3607       case REPLACEMENT_SUBSTRING:
   3608       case REPLACEMENT_STRING:
   3609         builder->AddString(replacement_substrings_[part.data]);
   3610         break;
   3611       default:
   3612         UNREACHABLE();
   3613     }
   3614   }
   3615 }
   3616 
   3617 
   3618 void FindAsciiStringIndices(Vector<const uint8_t> subject,
   3619                             char pattern,
   3620                             ZoneList<int>* indices,
   3621                             unsigned int limit,
   3622                             Zone* zone) {
   3623   ASSERT(limit > 0);
   3624   // Collect indices of pattern in subject using memchr.
   3625   // Stop after finding at most limit values.
   3626   const uint8_t* subject_start = subject.start();
   3627   const uint8_t* subject_end = subject_start + subject.length();
   3628   const uint8_t* pos = subject_start;
   3629   while (limit > 0) {
   3630     pos = reinterpret_cast<const uint8_t*>(
   3631         memchr(pos, pattern, subject_end - pos));
   3632     if (pos == NULL) return;
   3633     indices->Add(static_cast<int>(pos - subject_start), zone);
   3634     pos++;
   3635     limit--;
   3636   }
   3637 }
   3638 
   3639 
   3640 void FindTwoByteStringIndices(const Vector<const uc16> subject,
   3641                               uc16 pattern,
   3642                               ZoneList<int>* indices,
   3643                               unsigned int limit,
   3644                               Zone* zone) {
   3645   ASSERT(limit > 0);
   3646   const uc16* subject_start = subject.start();
   3647   const uc16* subject_end = subject_start + subject.length();
   3648   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
   3649     if (*pos == pattern) {
   3650       indices->Add(static_cast<int>(pos - subject_start), zone);
   3651       limit--;
   3652     }
   3653   }
   3654 }
   3655 
   3656 
   3657 template <typename SubjectChar, typename PatternChar>
   3658 void FindStringIndices(Isolate* isolate,
   3659                        Vector<const SubjectChar> subject,
   3660                        Vector<const PatternChar> pattern,
   3661                        ZoneList<int>* indices,
   3662                        unsigned int limit,
   3663                        Zone* zone) {
   3664   ASSERT(limit > 0);
   3665   // Collect indices of pattern in subject.
   3666   // Stop after finding at most limit values.
   3667   int pattern_length = pattern.length();
   3668   int index = 0;
   3669   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   3670   while (limit > 0) {
   3671     index = search.Search(subject, index);
   3672     if (index < 0) return;
   3673     indices->Add(index, zone);
   3674     index += pattern_length;
   3675     limit--;
   3676   }
   3677 }
   3678 
   3679 
   3680 void FindStringIndicesDispatch(Isolate* isolate,
   3681                                String* subject,
   3682                                String* pattern,
   3683                                ZoneList<int>* indices,
   3684                                unsigned int limit,
   3685                                Zone* zone) {
   3686   {
   3687     DisallowHeapAllocation no_gc;
   3688     String::FlatContent subject_content = subject->GetFlatContent();
   3689     String::FlatContent pattern_content = pattern->GetFlatContent();
   3690     ASSERT(subject_content.IsFlat());
   3691     ASSERT(pattern_content.IsFlat());
   3692     if (subject_content.IsAscii()) {
   3693       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
   3694       if (pattern_content.IsAscii()) {
   3695         Vector<const uint8_t> pattern_vector =
   3696             pattern_content.ToOneByteVector();
   3697         if (pattern_vector.length() == 1) {
   3698           FindAsciiStringIndices(subject_vector,
   3699                                  pattern_vector[0],
   3700                                  indices,
   3701                                  limit,
   3702                                  zone);
   3703         } else {
   3704           FindStringIndices(isolate,
   3705                             subject_vector,
   3706                             pattern_vector,
   3707                             indices,
   3708                             limit,
   3709                             zone);
   3710         }
   3711       } else {
   3712         FindStringIndices(isolate,
   3713                           subject_vector,
   3714                           pattern_content.ToUC16Vector(),
   3715                           indices,
   3716                           limit,
   3717                           zone);
   3718       }
   3719     } else {
   3720       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
   3721       if (pattern_content.IsAscii()) {
   3722         Vector<const uint8_t> pattern_vector =
   3723             pattern_content.ToOneByteVector();
   3724         if (pattern_vector.length() == 1) {
   3725           FindTwoByteStringIndices(subject_vector,
   3726                                    pattern_vector[0],
   3727                                    indices,
   3728                                    limit,
   3729                                    zone);
   3730         } else {
   3731           FindStringIndices(isolate,
   3732                             subject_vector,
   3733                             pattern_vector,
   3734                             indices,
   3735                             limit,
   3736                             zone);
   3737         }
   3738       } else {
   3739         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
   3740         if (pattern_vector.length() == 1) {
   3741           FindTwoByteStringIndices(subject_vector,
   3742                                    pattern_vector[0],
   3743                                    indices,
   3744                                    limit,
   3745                                    zone);
   3746         } else {
   3747           FindStringIndices(isolate,
   3748                             subject_vector,
   3749                             pattern_vector,
   3750                             indices,
   3751                             limit,
   3752                             zone);
   3753         }
   3754       }
   3755     }
   3756   }
   3757 }
   3758 
   3759 
   3760 template<typename ResultSeqString>
   3761 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
   3762     Isolate* isolate,
   3763     Handle<String> subject,
   3764     Handle<JSRegExp> pattern_regexp,
   3765     Handle<String> replacement,
   3766     Handle<JSArray> last_match_info) {
   3767   ASSERT(subject->IsFlat());
   3768   ASSERT(replacement->IsFlat());
   3769 
   3770   ZoneScope zone_scope(isolate->runtime_zone());
   3771   ZoneList<int> indices(8, zone_scope.zone());
   3772   ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
   3773   String* pattern =
   3774       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
   3775   int subject_len = subject->length();
   3776   int pattern_len = pattern->length();
   3777   int replacement_len = replacement->length();
   3778 
   3779   FindStringIndicesDispatch(
   3780       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
   3781 
   3782   int matches = indices.length();
   3783   if (matches == 0) return *subject;
   3784 
   3785   // Detect integer overflow.
   3786   int64_t result_len_64 =
   3787       (static_cast<int64_t>(replacement_len) -
   3788        static_cast<int64_t>(pattern_len)) *
   3789       static_cast<int64_t>(matches) +
   3790       static_cast<int64_t>(subject_len);
   3791   if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11);
   3792   int result_len = static_cast<int>(result_len_64);
   3793 
   3794   int subject_pos = 0;
   3795   int result_pos = 0;
   3796 
   3797   Handle<ResultSeqString> result;
   3798   if (ResultSeqString::kHasAsciiEncoding) {
   3799     result = Handle<ResultSeqString>::cast(
   3800         isolate->factory()->NewRawOneByteString(result_len));
   3801   } else {
   3802     result = Handle<ResultSeqString>::cast(
   3803         isolate->factory()->NewRawTwoByteString(result_len));
   3804   }
   3805 
   3806   for (int i = 0; i < matches; i++) {
   3807     // Copy non-matched subject content.
   3808     if (subject_pos < indices.at(i)) {
   3809       String::WriteToFlat(*subject,
   3810                           result->GetChars() + result_pos,
   3811                           subject_pos,
   3812                           indices.at(i));
   3813       result_pos += indices.at(i) - subject_pos;
   3814     }
   3815 
   3816     // Replace match.
   3817     if (replacement_len > 0) {
   3818       String::WriteToFlat(*replacement,
   3819                           result->GetChars() + result_pos,
   3820                           0,
   3821                           replacement_len);
   3822       result_pos += replacement_len;
   3823     }
   3824 
   3825     subject_pos = indices.at(i) + pattern_len;
   3826   }
   3827   // Add remaining subject content at the end.
   3828   if (subject_pos < subject_len) {
   3829     String::WriteToFlat(*subject,
   3830                         result->GetChars() + result_pos,
   3831                         subject_pos,
   3832                         subject_len);
   3833   }
   3834 
   3835   int32_t match_indices[] = { indices.at(matches - 1),
   3836                               indices.at(matches - 1) + pattern_len };
   3837   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
   3838 
   3839   return *result;
   3840 }
   3841 
   3842 
   3843 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
   3844     Isolate* isolate,
   3845     Handle<String> subject,
   3846     Handle<JSRegExp> regexp,
   3847     Handle<String> replacement,
   3848     Handle<JSArray> last_match_info) {
   3849   ASSERT(subject->IsFlat());
   3850   ASSERT(replacement->IsFlat());
   3851 
   3852   int capture_count = regexp->CaptureCount();
   3853   int subject_length = subject->length();
   3854 
   3855   // CompiledReplacement uses zone allocation.
   3856   ZoneScope zone_scope(isolate->runtime_zone());
   3857   CompiledReplacement compiled_replacement(zone_scope.zone());
   3858   bool simple_replace = compiled_replacement.Compile(replacement,
   3859                                                      capture_count,
   3860                                                      subject_length);
   3861 
   3862   // Shortcut for simple non-regexp global replacements
   3863   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
   3864     if (subject->HasOnlyOneByteChars() &&
   3865         replacement->HasOnlyOneByteChars()) {
   3866       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   3867           isolate, subject, regexp, replacement, last_match_info);
   3868     } else {
   3869       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   3870           isolate, subject, regexp, replacement, last_match_info);
   3871     }
   3872   }
   3873 
   3874   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   3875   if (global_cache.HasException()) return Failure::Exception();
   3876 
   3877   int32_t* current_match = global_cache.FetchNext();
   3878   if (current_match == NULL) {
   3879     if (global_cache.HasException()) return Failure::Exception();
   3880     return *subject;
   3881   }
   3882 
   3883   // Guessing the number of parts that the final result string is built
   3884   // from. Global regexps can match any number of times, so we guess
   3885   // conservatively.
   3886   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
   3887   ReplacementStringBuilder builder(isolate->heap(),
   3888                                    subject,
   3889                                    expected_parts);
   3890 
   3891   // Number of parts added by compiled replacement plus preceeding
   3892   // string and possibly suffix after last match.  It is possible for
   3893   // all components to use two elements when encoded as two smis.
   3894   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
   3895 
   3896   int prev = 0;
   3897 
   3898   do {
   3899     builder.EnsureCapacity(parts_added_per_loop);
   3900 
   3901     int start = current_match[0];
   3902     int end = current_match[1];
   3903 
   3904     if (prev < start) {
   3905       builder.AddSubjectSlice(prev, start);
   3906     }
   3907 
   3908     if (simple_replace) {
   3909       builder.AddString(replacement);
   3910     } else {
   3911       compiled_replacement.Apply(&builder,
   3912                                  start,
   3913                                  end,
   3914                                  current_match);
   3915     }
   3916     prev = end;
   3917 
   3918     current_match = global_cache.FetchNext();
   3919   } while (current_match != NULL);
   3920 
   3921   if (global_cache.HasException()) return Failure::Exception();
   3922 
   3923   if (prev < subject_length) {
   3924     builder.EnsureCapacity(2);
   3925     builder.AddSubjectSlice(prev, subject_length);
   3926   }
   3927 
   3928   RegExpImpl::SetLastMatchInfo(last_match_info,
   3929                                subject,
   3930                                capture_count,
   3931                                global_cache.LastSuccessfulMatch());
   3932 
   3933   return *(builder.ToString());
   3934 }
   3935 
   3936 
   3937 template <typename ResultSeqString>
   3938 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
   3939     Isolate* isolate,
   3940     Handle<String> subject,
   3941     Handle<JSRegExp> regexp,
   3942     Handle<JSArray> last_match_info) {
   3943   ASSERT(subject->IsFlat());
   3944 
   3945   // Shortcut for simple non-regexp global replacements
   3946   if (regexp->TypeTag() == JSRegExp::ATOM) {
   3947     Handle<String> empty_string = isolate->factory()->empty_string();
   3948     if (subject->IsOneByteRepresentation()) {
   3949       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
   3950           isolate, subject, regexp, empty_string, last_match_info);
   3951     } else {
   3952       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
   3953           isolate, subject, regexp, empty_string, last_match_info);
   3954     }
   3955   }
   3956 
   3957   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   3958   if (global_cache.HasException()) return Failure::Exception();
   3959 
   3960   int32_t* current_match = global_cache.FetchNext();
   3961   if (current_match == NULL) {
   3962     if (global_cache.HasException()) return Failure::Exception();
   3963     return *subject;
   3964   }
   3965 
   3966   int start = current_match[0];
   3967   int end = current_match[1];
   3968   int capture_count = regexp->CaptureCount();
   3969   int subject_length = subject->length();
   3970 
   3971   int new_length = subject_length - (end - start);
   3972   if (new_length == 0) return isolate->heap()->empty_string();
   3973 
   3974   Handle<ResultSeqString> answer;
   3975   if (ResultSeqString::kHasAsciiEncoding) {
   3976     answer = Handle<ResultSeqString>::cast(
   3977         isolate->factory()->NewRawOneByteString(new_length));
   3978   } else {
   3979     answer = Handle<ResultSeqString>::cast(
   3980         isolate->factory()->NewRawTwoByteString(new_length));
   3981   }
   3982 
   3983   int prev = 0;
   3984   int position = 0;
   3985 
   3986   do {
   3987     start = current_match[0];
   3988     end = current_match[1];
   3989     if (prev < start) {
   3990       // Add substring subject[prev;start] to answer string.
   3991       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
   3992       position += start - prev;
   3993     }
   3994     prev = end;
   3995 
   3996     current_match = global_cache.FetchNext();
   3997   } while (current_match != NULL);
   3998 
   3999   if (global_cache.HasException()) return Failure::Exception();
   4000 
   4001   RegExpImpl::SetLastMatchInfo(last_match_info,
   4002                                subject,
   4003                                capture_count,
   4004                                global_cache.LastSuccessfulMatch());
   4005 
   4006   if (prev < subject_length) {
   4007     // Add substring subject[prev;length] to answer string.
   4008     String::WriteToFlat(
   4009         *subject, answer->GetChars() + position, prev, subject_length);
   4010     position += subject_length - prev;
   4011   }
   4012 
   4013   if (position == 0) return isolate->heap()->empty_string();
   4014 
   4015   // Shorten string and fill
   4016   int string_size = ResultSeqString::SizeFor(position);
   4017   int allocated_string_size = ResultSeqString::SizeFor(new_length);
   4018   int delta = allocated_string_size - string_size;
   4019 
   4020   answer->set_length(position);
   4021   if (delta == 0) return *answer;
   4022 
   4023   Address end_of_string = answer->address() + string_size;
   4024   isolate->heap()->CreateFillerObjectAt(end_of_string, delta);
   4025   if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) {
   4026     MemoryChunk::IncrementLiveBytesFromMutator(answer->address(), -delta);
   4027   }
   4028 
   4029   return *answer;
   4030 }
   4031 
   4032 
   4033 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) {
   4034   HandleScope scope(isolate);
   4035   ASSERT(args.length() == 4);
   4036 
   4037   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4038   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
   4039   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4040   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   4041 
   4042   ASSERT(regexp->GetFlags().is_global());
   4043 
   4044   if (!subject->IsFlat()) subject = FlattenGetString(subject);
   4045 
   4046   if (replacement->length() == 0) {
   4047     if (subject->HasOnlyOneByteChars()) {
   4048       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
   4049           isolate, subject, regexp, last_match_info);
   4050     } else {
   4051       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
   4052           isolate, subject, regexp, last_match_info);
   4053     }
   4054   }
   4055 
   4056   if (!replacement->IsFlat()) replacement = FlattenGetString(replacement);
   4057 
   4058   return StringReplaceGlobalRegExpWithString(
   4059       isolate, subject, regexp, replacement, last_match_info);
   4060 }
   4061 
   4062 
   4063 Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
   4064                                               Handle<String> subject,
   4065                                               Handle<String> search,
   4066                                               Handle<String> replace,
   4067                                               bool* found,
   4068                                               int recursion_limit) {
   4069   if (recursion_limit == 0) return Handle<String>::null();
   4070   if (subject->IsConsString()) {
   4071     ConsString* cons = ConsString::cast(*subject);
   4072     Handle<String> first = Handle<String>(cons->first());
   4073     Handle<String> second = Handle<String>(cons->second());
   4074     Handle<String> new_first =
   4075         StringReplaceOneCharWithString(isolate,
   4076                                        first,
   4077                                        search,
   4078                                        replace,
   4079                                        found,
   4080                                        recursion_limit - 1);
   4081     if (*found) return isolate->factory()->NewConsString(new_first, second);
   4082     if (new_first.is_null()) return new_first;
   4083 
   4084     Handle<String> new_second =
   4085         StringReplaceOneCharWithString(isolate,
   4086                                        second,
   4087                                        search,
   4088                                        replace,
   4089                                        found,
   4090                                        recursion_limit - 1);
   4091     if (*found) return isolate->factory()->NewConsString(first, new_second);
   4092     if (new_second.is_null()) return new_second;
   4093 
   4094     return subject;
   4095   } else {
   4096     int index = Runtime::StringMatch(isolate, subject, search, 0);
   4097     if (index == -1) return subject;
   4098     *found = true;
   4099     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
   4100     Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
   4101     Handle<String> second =
   4102         isolate->factory()->NewSubString(subject, index + 1, subject->length());
   4103     return isolate->factory()->NewConsString(cons1, second);
   4104   }
   4105 }
   4106 
   4107 
   4108 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
   4109   HandleScope scope(isolate);
   4110   ASSERT(args.length() == 3);
   4111   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4112   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
   4113   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
   4114 
   4115   // If the cons string tree is too deep, we simply abort the recursion and
   4116   // retry with a flattened subject string.
   4117   const int kRecursionLimit = 0x1000;
   4118   bool found = false;
   4119   Handle<String> result = StringReplaceOneCharWithString(isolate,
   4120                                                          subject,
   4121                                                          search,
   4122                                                          replace,
   4123                                                          &found,
   4124                                                          kRecursionLimit);
   4125   if (!result.is_null()) return *result;
   4126   return *StringReplaceOneCharWithString(isolate,
   4127                                          FlattenGetString(subject),
   4128                                          search,
   4129                                          replace,
   4130                                          &found,
   4131                                          kRecursionLimit);
   4132 }
   4133 
   4134 
   4135 // Perform string match of pattern on subject, starting at start index.
   4136 // Caller must ensure that 0 <= start_index <= sub->length(),
   4137 // and should check that pat->length() + start_index <= sub->length().
   4138 int Runtime::StringMatch(Isolate* isolate,
   4139                          Handle<String> sub,
   4140                          Handle<String> pat,
   4141                          int start_index) {
   4142   ASSERT(0 <= start_index);
   4143   ASSERT(start_index <= sub->length());
   4144 
   4145   int pattern_length = pat->length();
   4146   if (pattern_length == 0) return start_index;
   4147 
   4148   int subject_length = sub->length();
   4149   if (start_index + pattern_length > subject_length) return -1;
   4150 
   4151   if (!sub->IsFlat()) FlattenString(sub);
   4152   if (!pat->IsFlat()) FlattenString(pat);
   4153 
   4154   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4155   // Extract flattened substrings of cons strings before determining asciiness.
   4156   String::FlatContent seq_sub = sub->GetFlatContent();
   4157   String::FlatContent seq_pat = pat->GetFlatContent();
   4158 
   4159   // dispatch on type of strings
   4160   if (seq_pat.IsAscii()) {
   4161     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
   4162     if (seq_sub.IsAscii()) {
   4163       return SearchString(isolate,
   4164                           seq_sub.ToOneByteVector(),
   4165                           pat_vector,
   4166                           start_index);
   4167     }
   4168     return SearchString(isolate,
   4169                         seq_sub.ToUC16Vector(),
   4170                         pat_vector,
   4171                         start_index);
   4172   }
   4173   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
   4174   if (seq_sub.IsAscii()) {
   4175     return SearchString(isolate,
   4176                         seq_sub.ToOneByteVector(),
   4177                         pat_vector,
   4178                         start_index);
   4179   }
   4180   return SearchString(isolate,
   4181                       seq_sub.ToUC16Vector(),
   4182                       pat_vector,
   4183                       start_index);
   4184 }
   4185 
   4186 
   4187 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) {
   4188   HandleScope scope(isolate);
   4189   ASSERT(args.length() == 3);
   4190 
   4191   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4192   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4193 
   4194   Object* index = args[2];
   4195   uint32_t start_index;
   4196   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4197 
   4198   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
   4199   int position =
   4200       Runtime::StringMatch(isolate, sub, pat, start_index);
   4201   return Smi::FromInt(position);
   4202 }
   4203 
   4204 
   4205 template <typename schar, typename pchar>
   4206 static int StringMatchBackwards(Vector<const schar> subject,
   4207                                 Vector<const pchar> pattern,
   4208                                 int idx) {
   4209   int pattern_length = pattern.length();
   4210   ASSERT(pattern_length >= 1);
   4211   ASSERT(idx + pattern_length <= subject.length());
   4212 
   4213   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   4214     for (int i = 0; i < pattern_length; i++) {
   4215       uc16 c = pattern[i];
   4216       if (c > String::kMaxOneByteCharCode) {
   4217         return -1;
   4218       }
   4219     }
   4220   }
   4221 
   4222   pchar pattern_first_char = pattern[0];
   4223   for (int i = idx; i >= 0; i--) {
   4224     if (subject[i] != pattern_first_char) continue;
   4225     int j = 1;
   4226     while (j < pattern_length) {
   4227       if (pattern[j] != subject[i+j]) {
   4228         break;
   4229       }
   4230       j++;
   4231     }
   4232     if (j == pattern_length) {
   4233       return i;
   4234     }
   4235   }
   4236   return -1;
   4237 }
   4238 
   4239 
   4240 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
   4241   HandleScope scope(isolate);
   4242   ASSERT(args.length() == 3);
   4243 
   4244   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   4245   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   4246 
   4247   Object* index = args[2];
   4248   uint32_t start_index;
   4249   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   4250 
   4251   uint32_t pat_length = pat->length();
   4252   uint32_t sub_length = sub->length();
   4253 
   4254   if (start_index + pat_length > sub_length) {
   4255     start_index = sub_length - pat_length;
   4256   }
   4257 
   4258   if (pat_length == 0) {
   4259     return Smi::FromInt(start_index);
   4260   }
   4261 
   4262   if (!sub->IsFlat()) FlattenString(sub);
   4263   if (!pat->IsFlat()) FlattenString(pat);
   4264 
   4265   int position = -1;
   4266   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
   4267 
   4268   String::FlatContent sub_content = sub->GetFlatContent();
   4269   String::FlatContent pat_content = pat->GetFlatContent();
   4270 
   4271   if (pat_content.IsAscii()) {
   4272     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
   4273     if (sub_content.IsAscii()) {
   4274       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4275                                       pat_vector,
   4276                                       start_index);
   4277     } else {
   4278       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4279                                       pat_vector,
   4280                                       start_index);
   4281     }
   4282   } else {
   4283     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
   4284     if (sub_content.IsAscii()) {
   4285       position = StringMatchBackwards(sub_content.ToOneByteVector(),
   4286                                       pat_vector,
   4287                                       start_index);
   4288     } else {
   4289       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   4290                                       pat_vector,
   4291                                       start_index);
   4292     }
   4293   }
   4294 
   4295   return Smi::FromInt(position);
   4296 }
   4297 
   4298 
   4299 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
   4300   SealHandleScope shs(isolate);
   4301   ASSERT(args.length() == 2);
   4302 
   4303   CONVERT_ARG_CHECKED(String, str1, 0);
   4304   CONVERT_ARG_CHECKED(String, str2, 1);
   4305 
   4306   if (str1 == str2) return Smi::FromInt(0);  // Equal.
   4307   int str1_length = str1->length();
   4308   int str2_length = str2->length();
   4309 
   4310   // Decide trivial cases without flattening.
   4311   if (str1_length == 0) {
   4312     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
   4313     return Smi::FromInt(-str2_length);
   4314   } else {
   4315     if (str2_length == 0) return Smi::FromInt(str1_length);
   4316   }
   4317 
   4318   int end = str1_length < str2_length ? str1_length : str2_length;
   4319 
   4320   // No need to flatten if we are going to find the answer on the first
   4321   // character.  At this point we know there is at least one character
   4322   // in each string, due to the trivial case handling above.
   4323   int d = str1->Get(0) - str2->Get(0);
   4324   if (d != 0) return Smi::FromInt(d);
   4325 
   4326   str1->TryFlatten();
   4327   str2->TryFlatten();
   4328 
   4329   ConsStringIteratorOp* op1 =
   4330       isolate->runtime_state()->string_locale_compare_it1();
   4331   ConsStringIteratorOp* op2 =
   4332       isolate->runtime_state()->string_locale_compare_it2();
   4333   // TODO(dcarney) Can do array compares here more efficiently.
   4334   StringCharacterStream stream1(str1, op1);
   4335   StringCharacterStream stream2(str2, op2);
   4336 
   4337   for (int i = 0; i < end; i++) {
   4338     uint16_t char1 = stream1.GetNext();
   4339     uint16_t char2 = stream2.GetNext();
   4340     if (char1 != char2) return Smi::FromInt(char1 - char2);
   4341   }
   4342 
   4343   return Smi::FromInt(str1_length - str2_length);
   4344 }
   4345 
   4346 
   4347 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
   4348   SealHandleScope shs(isolate);
   4349   ASSERT(args.length() == 3);
   4350 
   4351   CONVERT_ARG_CHECKED(String, value, 0);
   4352   int start, end;
   4353   // We have a fast integer-only case here to avoid a conversion to double in
   4354   // the common case where from and to are Smis.
   4355   if (args[1]->IsSmi() && args[2]->IsSmi()) {
   4356     CONVERT_SMI_ARG_CHECKED(from_number, 1);
   4357     CONVERT_SMI_ARG_CHECKED(to_number, 2);
   4358     start = from_number;
   4359     end = to_number;
   4360   } else {
   4361     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
   4362     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
   4363     start = FastD2IChecked(from_number);
   4364     end = FastD2IChecked(to_number);
   4365   }
   4366   RUNTIME_ASSERT(end >= start);
   4367   RUNTIME_ASSERT(start >= 0);
   4368   RUNTIME_ASSERT(end <= value->length());
   4369   isolate->counters()->sub_string_runtime()->Increment();
   4370   if (end - start == 1) {
   4371      return isolate->heap()->LookupSingleCharacterStringFromCode(
   4372          value->Get(start));
   4373   }
   4374   return value->SubString(start, end);
   4375 }
   4376 
   4377 
   4378 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
   4379   HandleScope handles(isolate);
   4380   ASSERT_EQ(3, args.length());
   4381 
   4382   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   4383   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   4384   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
   4385 
   4386   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4387   if (global_cache.HasException()) return Failure::Exception();
   4388 
   4389   int capture_count = regexp->CaptureCount();
   4390 
   4391   ZoneScope zone_scope(isolate->runtime_zone());
   4392   ZoneList<int> offsets(8, zone_scope.zone());
   4393 
   4394   while (true) {
   4395     int32_t* match = global_cache.FetchNext();
   4396     if (match == NULL) break;
   4397     offsets.Add(match[0], zone_scope.zone());  // start
   4398     offsets.Add(match[1], zone_scope.zone());  // end
   4399   }
   4400 
   4401   if (global_cache.HasException()) return Failure::Exception();
   4402 
   4403   if (offsets.length() == 0) {
   4404     // Not a single match.
   4405     return isolate->heap()->null_value();
   4406   }
   4407 
   4408   RegExpImpl::SetLastMatchInfo(regexp_info,
   4409                                subject,
   4410                                capture_count,
   4411                                global_cache.LastSuccessfulMatch());
   4412 
   4413   int matches = offsets.length() / 2;
   4414   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
   4415   Handle<String> substring =
   4416       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
   4417   elements->set(0, *substring);
   4418   for (int i = 1; i < matches; i++) {
   4419     HandleScope temp_scope(isolate);
   4420     int from = offsets.at(i * 2);
   4421     int to = offsets.at(i * 2 + 1);
   4422     Handle<String> substring =
   4423         isolate->factory()->NewProperSubString(subject, from, to);
   4424     elements->set(i, *substring);
   4425   }
   4426   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
   4427   result->set_length(Smi::FromInt(matches));
   4428   return *result;
   4429 }
   4430 
   4431 
   4432 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
   4433 // separate last match info.  See comment on that function.
   4434 template<bool has_capture>
   4435 static MaybeObject* SearchRegExpMultiple(
   4436     Isolate* isolate,
   4437     Handle<String> subject,
   4438     Handle<JSRegExp> regexp,
   4439     Handle<JSArray> last_match_array,
   4440     Handle<JSArray> result_array) {
   4441   ASSERT(subject->IsFlat());
   4442   ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
   4443 
   4444   int capture_count = regexp->CaptureCount();
   4445   int subject_length = subject->length();
   4446 
   4447   static const int kMinLengthToCache = 0x1000;
   4448 
   4449   if (subject_length > kMinLengthToCache) {
   4450     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
   4451         isolate->heap(),
   4452         *subject,
   4453         regexp->data(),
   4454         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
   4455     if (*cached_answer != Smi::FromInt(0)) {
   4456       Handle<FixedArray> cached_fixed_array =
   4457           Handle<FixedArray>(FixedArray::cast(*cached_answer));
   4458       // The cache FixedArray is a COW-array and can therefore be reused.
   4459       isolate->factory()->SetContent(result_array, cached_fixed_array);
   4460       // The actual length of the result array is stored in the last element of
   4461       // the backing store (the backing FixedArray may have a larger capacity).
   4462       Object* cached_fixed_array_last_element =
   4463           cached_fixed_array->get(cached_fixed_array->length() - 1);
   4464       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
   4465       result_array->set_length(js_array_length);
   4466       RegExpImpl::SetLastMatchInfo(
   4467           last_match_array, subject, capture_count, NULL);
   4468       return *result_array;
   4469     }
   4470   }
   4471 
   4472   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
   4473   if (global_cache.HasException()) return Failure::Exception();
   4474 
   4475   Handle<FixedArray> result_elements;
   4476   if (result_array->HasFastObjectElements()) {
   4477     result_elements =
   4478         Handle<FixedArray>(FixedArray::cast(result_array->elements()));
   4479   }
   4480   if (result_elements.is_null() || result_elements->length() < 16) {
   4481     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   4482   }
   4483 
   4484   FixedArrayBuilder builder(result_elements);
   4485 
   4486   // Position to search from.
   4487   int match_start = -1;
   4488   int match_end = 0;
   4489   bool first = true;
   4490 
   4491   // Two smis before and after the match, for very long strings.
   4492   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
   4493 
   4494   while (true) {
   4495     int32_t* current_match = global_cache.FetchNext();
   4496     if (current_match == NULL) break;
   4497     match_start = current_match[0];
   4498     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   4499     if (match_end < match_start) {
   4500       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4501                                                 match_end,
   4502                                                 match_start);
   4503     }
   4504     match_end = current_match[1];
   4505     {
   4506       // Avoid accumulating new handles inside loop.
   4507       HandleScope temp_scope(isolate);
   4508       Handle<String> match;
   4509       if (!first) {
   4510         match = isolate->factory()->NewProperSubString(subject,
   4511                                                        match_start,
   4512                                                        match_end);
   4513       } else {
   4514         match = isolate->factory()->NewSubString(subject,
   4515                                                  match_start,
   4516                                                  match_end);
   4517         first = false;
   4518       }
   4519 
   4520       if (has_capture) {
   4521         // Arguments array to replace function is match, captures, index and
   4522         // subject, i.e., 3 + capture count in total.
   4523         Handle<FixedArray> elements =
   4524             isolate->factory()->NewFixedArray(3 + capture_count);
   4525 
   4526         elements->set(0, *match);
   4527         for (int i = 1; i <= capture_count; i++) {
   4528           int start = current_match[i * 2];
   4529           if (start >= 0) {
   4530             int end = current_match[i * 2 + 1];
   4531             ASSERT(start <= end);
   4532             Handle<String> substring =
   4533                 isolate->factory()->NewSubString(subject, start, end);
   4534             elements->set(i, *substring);
   4535           } else {
   4536             ASSERT(current_match[i * 2 + 1] < 0);
   4537             elements->set(i, isolate->heap()->undefined_value());
   4538           }
   4539         }
   4540         elements->set(capture_count + 1, Smi::FromInt(match_start));
   4541         elements->set(capture_count + 2, *subject);
   4542         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
   4543       } else {
   4544         builder.Add(*match);
   4545       }
   4546     }
   4547   }
   4548 
   4549   if (global_cache.HasException()) return Failure::Exception();
   4550 
   4551   if (match_start >= 0) {
   4552     // Finished matching, with at least one match.
   4553     if (match_end < subject_length) {
   4554       ReplacementStringBuilder::AddSubjectSlice(&builder,
   4555                                                 match_end,
   4556                                                 subject_length);
   4557     }
   4558 
   4559     RegExpImpl::SetLastMatchInfo(
   4560         last_match_array, subject, capture_count, NULL);
   4561 
   4562     if (subject_length > kMinLengthToCache) {
   4563       // Store the length of the result array into the last element of the
   4564       // backing FixedArray.
   4565       builder.EnsureCapacity(1);
   4566       Handle<FixedArray> fixed_array = builder.array();
   4567       fixed_array->set(fixed_array->length() - 1,
   4568                        Smi::FromInt(builder.length()));
   4569       // Cache the result and turn the FixedArray into a COW array.
   4570       RegExpResultsCache::Enter(isolate->heap(),
   4571                                 *subject,
   4572                                 regexp->data(),
   4573                                 *fixed_array,
   4574                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
   4575     }
   4576     return *builder.ToJSArray(result_array);
   4577   } else {
   4578     return isolate->heap()->null_value();  // No matches at all.
   4579   }
   4580 }
   4581 
   4582 
   4583 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
   4584 // lastMatchInfoOverride to maintain the last match info, so we don't need to
   4585 // set any other last match array info.
   4586 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
   4587   HandleScope handles(isolate);
   4588   ASSERT(args.length() == 4);
   4589 
   4590   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   4591   if (!subject->IsFlat()) FlattenString(subject);
   4592   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   4593   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
   4594   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
   4595 
   4596   ASSERT(regexp->GetFlags().is_global());
   4597 
   4598   if (regexp->CaptureCount() == 0) {
   4599     return SearchRegExpMultiple<false>(
   4600         isolate, subject, regexp, last_match_info, result_array);
   4601   } else {
   4602     return SearchRegExpMultiple<true>(
   4603         isolate, subject, regexp, last_match_info, result_array);
   4604   }
   4605 }
   4606 
   4607 
   4608 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
   4609   SealHandleScope shs(isolate);
   4610   ASSERT(args.length() == 2);
   4611   CONVERT_SMI_ARG_CHECKED(radix, 1);
   4612   RUNTIME_ASSERT(2 <= radix && radix <= 36);
   4613 
   4614   // Fast case where the result is a one character string.
   4615   if (args[0]->IsSmi()) {
   4616     int value = args.smi_at(0);
   4617     if (value >= 0 && value < radix) {
   4618       // Character array used for conversion.
   4619       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   4620       return isolate->heap()->
   4621           LookupSingleCharacterStringFromCode(kCharTable[value]);
   4622     }
   4623   }
   4624 
   4625   // Slow case.
   4626   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4627   if (std::isnan(value)) {
   4628     return *isolate->factory()->nan_string();
   4629   }
   4630   if (std::isinf(value)) {
   4631     if (value < 0) {
   4632       return *isolate->factory()->minus_infinity_string();
   4633     }
   4634     return *isolate->factory()->infinity_string();
   4635   }
   4636   char* str = DoubleToRadixCString(value, radix);
   4637   MaybeObject* result =
   4638       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4639   DeleteArray(str);
   4640   return result;
   4641 }
   4642 
   4643 
   4644 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
   4645   SealHandleScope shs(isolate);
   4646   ASSERT(args.length() == 2);
   4647 
   4648   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4649   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4650   int f = FastD2IChecked(f_number);
   4651   RUNTIME_ASSERT(f >= 0);
   4652   char* str = DoubleToFixedCString(value, f);
   4653   MaybeObject* res =
   4654       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4655   DeleteArray(str);
   4656   return res;
   4657 }
   4658 
   4659 
   4660 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
   4661   SealHandleScope shs(isolate);
   4662   ASSERT(args.length() == 2);
   4663 
   4664   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4665   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4666   int f = FastD2IChecked(f_number);
   4667   RUNTIME_ASSERT(f >= -1 && f <= 20);
   4668   char* str = DoubleToExponentialCString(value, f);
   4669   MaybeObject* res =
   4670       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4671   DeleteArray(str);
   4672   return res;
   4673 }
   4674 
   4675 
   4676 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
   4677   SealHandleScope shs(isolate);
   4678   ASSERT(args.length() == 2);
   4679 
   4680   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4681   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4682   int f = FastD2IChecked(f_number);
   4683   RUNTIME_ASSERT(f >= 1 && f <= 21);
   4684   char* str = DoubleToPrecisionCString(value, f);
   4685   MaybeObject* res =
   4686       isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
   4687   DeleteArray(str);
   4688   return res;
   4689 }
   4690 
   4691 
   4692 // Returns a single character string where first character equals
   4693 // string->Get(index).
   4694 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
   4695   if (index < static_cast<uint32_t>(string->length())) {
   4696     string->TryFlatten();
   4697     return LookupSingleCharacterStringFromCode(
   4698         string->GetIsolate(),
   4699         string->Get(index));
   4700   }
   4701   return Execution::CharAt(string, index);
   4702 }
   4703 
   4704 
   4705 MaybeObject* Runtime::GetElementOrCharAtOrFail(Isolate* isolate,
   4706                                                Handle<Object> object,
   4707                                                uint32_t index) {
   4708   CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
   4709       GetElementOrCharAt(isolate, object, index));
   4710 }
   4711 
   4712 
   4713 MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
   4714                                          Handle<Object> object,
   4715                                          uint32_t index) {
   4716   // Handle [] indexing on Strings
   4717   if (object->IsString()) {
   4718     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
   4719     if (!result->IsUndefined()) return *result;
   4720   }
   4721 
   4722   // Handle [] indexing on String objects
   4723   if (object->IsStringObjectWithCharacterAt(index)) {
   4724     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
   4725     Handle<Object> result =
   4726         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
   4727     if (!result->IsUndefined()) return *result;
   4728   }
   4729 
   4730   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
   4731     return object->GetPrototype(isolate)->GetElement(index);
   4732   }
   4733 
   4734   return object->GetElement(index);
   4735 }
   4736 
   4737 
   4738 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
   4739                                         Handle<JSReceiver> object,
   4740                                         Handle<Object> key) {
   4741   HandleScope scope(isolate);
   4742 
   4743   // Check if the given key is an array index.
   4744   uint32_t index;
   4745   if (key->ToArrayIndex(&index)) {
   4746     return isolate->heap()->ToBoolean(object->HasElement(index));
   4747   }
   4748 
   4749   // Convert the key to a name - possibly by calling back into JavaScript.
   4750   Handle<Name> name;
   4751   if (key->IsName()) {
   4752     name = Handle<Name>::cast(key);
   4753   } else {
   4754     bool has_pending_exception = false;
   4755     Handle<Object> converted =
   4756         Execution::ToString(key, &has_pending_exception);
   4757     if (has_pending_exception) return Failure::Exception();
   4758     name = Handle<Name>::cast(converted);
   4759   }
   4760 
   4761   return isolate->heap()->ToBoolean(object->HasProperty(*name));
   4762 }
   4763 
   4764 MaybeObject* Runtime::GetObjectPropertyOrFail(
   4765     Isolate* isolate,
   4766     Handle<Object> object,
   4767     Handle<Object> key) {
   4768   CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
   4769       GetObjectProperty(isolate, object, key));
   4770 }
   4771 
   4772 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
   4773                                         Handle<Object> object,
   4774                                         Handle<Object> key) {
   4775   HandleScope scope(isolate);
   4776 
   4777   if (object->IsUndefined() || object->IsNull()) {
   4778     Handle<Object> args[2] = { key, object };
   4779     Handle<Object> error =
   4780         isolate->factory()->NewTypeError("non_object_property_load",
   4781                                          HandleVector(args, 2));
   4782     return isolate->Throw(*error);
   4783   }
   4784 
   4785   // Check if the given key is an array index.
   4786   uint32_t index;
   4787   if (key->ToArrayIndex(&index)) {
   4788     return GetElementOrCharAt(isolate, object, index);
   4789   }
   4790 
   4791   // Convert the key to a name - possibly by calling back into JavaScript.
   4792   Handle<Name> name;
   4793   if (key->IsName()) {
   4794     name = Handle<Name>::cast(key);
   4795   } else {
   4796     bool has_pending_exception = false;
   4797     Handle<Object> converted =
   4798         Execution::ToString(key, &has_pending_exception);
   4799     if (has_pending_exception) return Failure::Exception();
   4800     name = Handle<Name>::cast(converted);
   4801   }
   4802 
   4803   // Check if the name is trivially convertible to an index and get
   4804   // the element if so.
   4805   if (name->AsArrayIndex(&index)) {
   4806     return GetElementOrCharAt(isolate, object, index);
   4807   } else {
   4808     return object->GetProperty(*name);
   4809   }
   4810 }
   4811 
   4812 
   4813 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
   4814   SealHandleScope shs(isolate);
   4815   ASSERT(args.length() == 2);
   4816 
   4817   Handle<Object> object = args.at<Object>(0);
   4818   Handle<Object> key = args.at<Object>(1);
   4819 
   4820   return Runtime::GetObjectProperty(isolate, object, key);
   4821 }
   4822 
   4823 
   4824 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
   4825 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
   4826   SealHandleScope shs(isolate);
   4827   ASSERT(args.length() == 2);
   4828 
   4829   // Fast cases for getting named properties of the receiver JSObject
   4830   // itself.
   4831   //
   4832   // The global proxy objects has to be excluded since LocalLookup on
   4833   // the global proxy object can return a valid result even though the
   4834   // global proxy object never has properties.  This is the case
   4835   // because the global proxy object forwards everything to its hidden
   4836   // prototype including local lookups.
   4837   //
   4838   // Additionally, we need to make sure that we do not cache results
   4839   // for objects that require access checks.
   4840   if (args[0]->IsJSObject()) {
   4841     if (!args[0]->IsJSGlobalProxy() &&
   4842         !args[0]->IsAccessCheckNeeded() &&
   4843         args[1]->IsName()) {
   4844       JSObject* receiver = JSObject::cast(args[0]);
   4845       Name* key = Name::cast(args[1]);
   4846       if (receiver->HasFastProperties()) {
   4847         // Attempt to use lookup cache.
   4848         Map* receiver_map = receiver->map();
   4849         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
   4850         int offset = keyed_lookup_cache->Lookup(receiver_map, key);
   4851         if (offset != -1) {
   4852           // Doubles are not cached, so raw read the value.
   4853           Object* value = receiver->RawFastPropertyAt(offset);
   4854           return value->IsTheHole()
   4855               ? isolate->heap()->undefined_value()
   4856               : value;
   4857         }
   4858         // Lookup cache miss.  Perform lookup and update the cache if
   4859         // appropriate.
   4860         LookupResult result(isolate);
   4861         receiver->LocalLookup(key, &result);
   4862         if (result.IsField()) {
   4863           int offset = result.GetFieldIndex().field_index();
   4864           // Do not track double fields in the keyed lookup cache. Reading
   4865           // double values requires boxing.
   4866           if (!FLAG_track_double_fields ||
   4867               !result.representation().IsDouble()) {
   4868             keyed_lookup_cache->Update(receiver_map, key, offset);
   4869           }
   4870           return receiver->FastPropertyAt(result.representation(), offset);
   4871         }
   4872       } else {
   4873         // Attempt dictionary lookup.
   4874         NameDictionary* dictionary = receiver->property_dictionary();
   4875         int entry = dictionary->FindEntry(key);
   4876         if ((entry != NameDictionary::kNotFound) &&
   4877             (dictionary->DetailsAt(entry).type() == NORMAL)) {
   4878           Object* value = dictionary->ValueAt(entry);
   4879           if (!receiver->IsGlobalObject()) return value;
   4880           value = PropertyCell::cast(value)->value();
   4881           if (!value->IsTheHole()) return value;
   4882           // If value is the hole do the general lookup.
   4883         }
   4884       }
   4885     } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
   4886       // JSObject without a name key. If the key is a Smi, check for a
   4887       // definite out-of-bounds access to elements, which is a strong indicator
   4888       // that subsequent accesses will also call the runtime. Proactively
   4889       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
   4890       // doubles for those future calls in the case that the elements would
   4891       // become FAST_DOUBLE_ELEMENTS.
   4892       Handle<JSObject> js_object(args.at<JSObject>(0));
   4893       ElementsKind elements_kind = js_object->GetElementsKind();
   4894       if (IsFastDoubleElementsKind(elements_kind)) {
   4895         FixedArrayBase* elements = js_object->elements();
   4896         if (args.at<Smi>(1)->value() >= elements->length()) {
   4897           if (IsFastHoleyElementsKind(elements_kind)) {
   4898             elements_kind = FAST_HOLEY_ELEMENTS;
   4899           } else {
   4900             elements_kind = FAST_ELEMENTS;
   4901           }
   4902           MaybeObject* maybe_object = TransitionElements(js_object,
   4903                                                          elements_kind,
   4904                                                          isolate);
   4905           if (maybe_object->IsFailure()) return maybe_object;
   4906         }
   4907       } else {
   4908         ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
   4909                !IsFastElementsKind(elements_kind));
   4910       }
   4911     }
   4912   } else if (args[0]->IsString() && args[1]->IsSmi()) {
   4913     // Fast case for string indexing using [] with a smi index.
   4914     HandleScope scope(isolate);
   4915     Handle<String> str = args.at<String>(0);
   4916     int index = args.smi_at(1);
   4917     if (index >= 0 && index < str->length()) {
   4918       Handle<Object> result = GetCharAt(str, index);
   4919       return *result;
   4920     }
   4921   }
   4922 
   4923   // Fall back to GetObjectProperty.
   4924   return Runtime::GetObjectProperty(isolate,
   4925                                     args.at<Object>(0),
   4926                                     args.at<Object>(1));
   4927 }
   4928 
   4929 
   4930 static bool IsValidAccessor(Handle<Object> obj) {
   4931   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
   4932 }
   4933 
   4934 
   4935 // Implements part of 8.12.9 DefineOwnProperty.
   4936 // There are 3 cases that lead here:
   4937 // Step 4b - define a new accessor property.
   4938 // Steps 9c & 12 - replace an existing data property with an accessor property.
   4939 // Step 12 - update an existing accessor property with an accessor or generic
   4940 //           descriptor.
   4941 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
   4942   HandleScope scope(isolate);
   4943   ASSERT(args.length() == 5);
   4944   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   4945   RUNTIME_ASSERT(!obj->IsNull());
   4946   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   4947   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   4948   RUNTIME_ASSERT(IsValidAccessor(getter));
   4949   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   4950   RUNTIME_ASSERT(IsValidAccessor(setter));
   4951   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
   4952   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   4953   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   4954 
   4955   bool fast = obj->HasFastProperties();
   4956   JSObject::DefineAccessor(obj, name, getter, setter, attr);
   4957   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   4958   if (fast) JSObject::TransformToFastProperties(obj, 0);
   4959   return isolate->heap()->undefined_value();
   4960 }
   4961 
   4962 
   4963 // Implements part of 8.12.9 DefineOwnProperty.
   4964 // There are 3 cases that lead here:
   4965 // Step 4a - define a new data property.
   4966 // Steps 9b & 12 - replace an existing accessor property with a data property.
   4967 // Step 12 - update an existing data property with a data or generic
   4968 //           descriptor.
   4969 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
   4970   HandleScope scope(isolate);
   4971   ASSERT(args.length() == 4);
   4972   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
   4973   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   4974   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
   4975   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
   4976   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   4977   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   4978 
   4979   LookupResult result(isolate);
   4980   js_object->LocalLookupRealNamedProperty(*name, &result);
   4981 
   4982   // Special case for callback properties.
   4983   if (result.IsPropertyCallbacks()) {
   4984     Object* callback = result.GetCallbackObject();
   4985     // To be compatible with Safari we do not change the value on API objects
   4986     // in Object.defineProperty(). Firefox disagrees here, and actually changes
   4987     // the value.
   4988     if (callback->IsAccessorInfo()) {
   4989       return isolate->heap()->undefined_value();
   4990     }
   4991     // Avoid redefining foreign callback as data property, just use the stored
   4992     // setter to update the value instead.
   4993     // TODO(mstarzinger): So far this only works if property attributes don't
   4994     // change, this should be fixed once we cleanup the underlying code.
   4995     if (callback->IsForeign() && result.GetAttributes() == attr) {
   4996       return js_object->SetPropertyWithCallback(callback,
   4997                                                 *name,
   4998                                                 *obj_value,
   4999                                                 result.holder(),
   5000                                                 kStrictMode);
   5001     }
   5002   }
   5003 
   5004   // Take special care when attributes are different and there is already
   5005   // a property. For simplicity we normalize the property which enables us
   5006   // to not worry about changing the instance_descriptor and creating a new
   5007   // map. The current version of SetObjectProperty does not handle attributes
   5008   // correctly in the case where a property is a field and is reset with
   5009   // new attributes.
   5010   if (result.IsFound() &&
   5011       (attr != result.GetAttributes() || result.IsPropertyCallbacks())) {
   5012     // New attributes - normalize to avoid writing to instance descriptor
   5013     if (js_object->IsJSGlobalProxy()) {
   5014       // Since the result is a property, the prototype will exist so
   5015       // we don't have to check for null.
   5016       js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
   5017     }
   5018     JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
   5019     // Use IgnoreAttributes version since a readonly property may be
   5020     // overridden and SetProperty does not allow this.
   5021     return js_object->SetLocalPropertyIgnoreAttributes(*name,
   5022                                                        *obj_value,
   5023                                                        attr);
   5024   }
   5025 
   5026   return Runtime::ForceSetObjectProperty(isolate,
   5027                                          js_object,
   5028                                          name,
   5029                                          obj_value,
   5030                                          attr);
   5031 }
   5032 
   5033 
   5034 // Return property without being observable by accessors or interceptors.
   5035 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
   5036   SealHandleScope shs(isolate);
   5037   ASSERT(args.length() == 2);
   5038   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5039   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5040   LookupResult lookup(isolate);
   5041   object->LookupRealNamedProperty(*key, &lookup);
   5042   if (!lookup.IsFound()) return isolate->heap()->undefined_value();
   5043   switch (lookup.type()) {
   5044     case NORMAL:
   5045       return lookup.holder()->GetNormalizedProperty(&lookup);
   5046     case FIELD:
   5047       return lookup.holder()->FastPropertyAt(
   5048           lookup.representation(),
   5049           lookup.GetFieldIndex().field_index());
   5050     case CONSTANT:
   5051       return lookup.GetConstant();
   5052     case CALLBACKS:
   5053     case HANDLER:
   5054     case INTERCEPTOR:
   5055     case TRANSITION:
   5056       return isolate->heap()->undefined_value();
   5057     case NONEXISTENT:
   5058       UNREACHABLE();
   5059   }
   5060   return isolate->heap()->undefined_value();
   5061 }
   5062 
   5063 
   5064 MaybeObject* Runtime::SetObjectPropertyOrFail(
   5065     Isolate* isolate,
   5066     Handle<Object> object,
   5067     Handle<Object> key,
   5068     Handle<Object> value,
   5069     PropertyAttributes attr,
   5070     StrictModeFlag strict_mode) {
   5071   CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
   5072       SetObjectProperty(isolate, object, key, value, attr, strict_mode));
   5073 }
   5074 
   5075 
   5076 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
   5077                                         Handle<Object> object,
   5078                                         Handle<Object> key,
   5079                                         Handle<Object> value,
   5080                                         PropertyAttributes attr,
   5081                                         StrictModeFlag strict_mode) {
   5082   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
   5083   HandleScope scope(isolate);
   5084 
   5085   if (object->IsUndefined() || object->IsNull()) {
   5086     Handle<Object> args[2] = { key, object };
   5087     Handle<Object> error =
   5088         isolate->factory()->NewTypeError("non_object_property_store",
   5089                                          HandleVector(args, 2));
   5090     return isolate->Throw(*error);
   5091   }
   5092 
   5093   if (object->IsJSProxy()) {
   5094     bool has_pending_exception = false;
   5095     Handle<Object> name = key->IsSymbol()
   5096         ? key : Execution::ToString(key, &has_pending_exception);
   5097     if (has_pending_exception) return Failure::Exception();
   5098     return JSProxy::cast(*object)->SetProperty(
   5099         Name::cast(*name), *value, attr, strict_mode);
   5100   }
   5101 
   5102   // If the object isn't a JavaScript object, we ignore the store.
   5103   if (!object->IsJSObject()) return *value;
   5104 
   5105   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   5106 
   5107   // Check if the given key is an array index.
   5108   uint32_t index;
   5109   if (key->ToArrayIndex(&index)) {
   5110     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5111     // of a string using [] notation.  We need to support this too in
   5112     // JavaScript.
   5113     // In the case of a String object we just need to redirect the assignment to
   5114     // the underlying string if the index is in range.  Since the underlying
   5115     // string does nothing with the assignment then we can ignore such
   5116     // assignments.
   5117     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5118       return *value;
   5119     }
   5120 
   5121     js_object->ValidateElements();
   5122     if (js_object->HasExternalArrayElements()) {
   5123       if (!value->IsNumber() && !value->IsUndefined()) {
   5124         bool has_exception;
   5125         Handle<Object> number = Execution::ToNumber(value, &has_exception);
   5126         if (has_exception) return Failure::Exception();
   5127         value = number;
   5128       }
   5129     }
   5130     MaybeObject* result = js_object->SetElement(
   5131         index, *value, attr, strict_mode, true, set_mode);
   5132     js_object->ValidateElements();
   5133     if (result->IsFailure()) return result;
   5134     return *value;
   5135   }
   5136 
   5137   if (key->IsName()) {
   5138     MaybeObject* result;
   5139     Handle<Name> name = Handle<Name>::cast(key);
   5140     if (name->AsArrayIndex(&index)) {
   5141       if (js_object->HasExternalArrayElements()) {
   5142         if (!value->IsNumber() && !value->IsUndefined()) {
   5143           bool has_exception;
   5144           Handle<Object> number = Execution::ToNumber(value, &has_exception);
   5145           if (has_exception) return Failure::Exception();
   5146           value = number;
   5147         }
   5148       }
   5149       result = js_object->SetElement(
   5150           index, *value, attr, strict_mode, true, set_mode);
   5151     } else {
   5152       if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
   5153       result = js_object->SetProperty(*name, *value, attr, strict_mode);
   5154     }
   5155     if (result->IsFailure()) return result;
   5156     return *value;
   5157   }
   5158 
   5159   // Call-back into JavaScript to convert the key to a string.
   5160   bool has_pending_exception = false;
   5161   Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
   5162   if (has_pending_exception) return Failure::Exception();
   5163   Handle<String> name = Handle<String>::cast(converted);
   5164 
   5165   if (name->AsArrayIndex(&index)) {
   5166     return js_object->SetElement(
   5167         index, *value, attr, strict_mode, true, set_mode);
   5168   } else {
   5169     return js_object->SetProperty(*name, *value, attr, strict_mode);
   5170   }
   5171 }
   5172 
   5173 
   5174 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
   5175                                              Handle<JSObject> js_object,
   5176                                              Handle<Object> key,
   5177                                              Handle<Object> value,
   5178                                              PropertyAttributes attr) {
   5179   HandleScope scope(isolate);
   5180 
   5181   // Check if the given key is an array index.
   5182   uint32_t index;
   5183   if (key->ToArrayIndex(&index)) {
   5184     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   5185     // of a string using [] notation.  We need to support this too in
   5186     // JavaScript.
   5187     // In the case of a String object we just need to redirect the assignment to
   5188     // the underlying string if the index is in range.  Since the underlying
   5189     // string does nothing with the assignment then we can ignore such
   5190     // assignments.
   5191     if (js_object->IsStringObjectWithCharacterAt(index)) {
   5192       return *value;
   5193     }
   5194 
   5195     return js_object->SetElement(
   5196         index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   5197   }
   5198 
   5199   if (key->IsName()) {
   5200     Handle<Name> name = Handle<Name>::cast(key);
   5201     if (name->AsArrayIndex(&index)) {
   5202       return js_object->SetElement(
   5203           index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   5204     } else {
   5205       if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
   5206       return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
   5207     }
   5208   }
   5209 
   5210   // Call-back into JavaScript to convert the key to a string.
   5211   bool has_pending_exception = false;
   5212   Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
   5213   if (has_pending_exception) return Failure::Exception();
   5214   Handle<String> name = Handle<String>::cast(converted);
   5215 
   5216   if (name->AsArrayIndex(&index)) {
   5217     return js_object->SetElement(
   5218         index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   5219   } else {
   5220     return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
   5221   }
   5222 }
   5223 
   5224 
   5225 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
   5226                                            Handle<JSReceiver> receiver,
   5227                                            Handle<Object> key,
   5228                                            JSReceiver::DeleteMode mode) {
   5229   HandleScope scope(isolate);
   5230 
   5231   // Check if the given key is an array index.
   5232   uint32_t index;
   5233   if (key->ToArrayIndex(&index)) {
   5234     // In Firefox/SpiderMonkey, Safari and Opera you can access the
   5235     // characters of a string using [] notation.  In the case of a
   5236     // String object we just need to redirect the deletion to the
   5237     // underlying string if the index is in range.  Since the
   5238     // underlying string does nothing with the deletion, we can ignore
   5239     // such deletions.
   5240     if (receiver->IsStringObjectWithCharacterAt(index)) {
   5241       return isolate->heap()->true_value();
   5242     }
   5243 
   5244     Handle<Object> result = JSReceiver::DeleteElement(receiver, index, mode);
   5245     RETURN_IF_EMPTY_HANDLE(isolate, result);
   5246     return *result;
   5247   }
   5248 
   5249   Handle<Name> name;
   5250   if (key->IsName()) {
   5251     name = Handle<Name>::cast(key);
   5252   } else {
   5253     // Call-back into JavaScript to convert the key to a string.
   5254     bool has_pending_exception = false;
   5255     Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
   5256     if (has_pending_exception) return Failure::Exception();
   5257     name = Handle<String>::cast(converted);
   5258   }
   5259 
   5260   if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
   5261   Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode);
   5262   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5263   return *result;
   5264 }
   5265 
   5266 
   5267 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
   5268   SealHandleScope shs(isolate);
   5269   RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
   5270 
   5271   Handle<Object> object = args.at<Object>(0);
   5272   Handle<Object> key = args.at<Object>(1);
   5273   Handle<Object> value = args.at<Object>(2);
   5274   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   5275   RUNTIME_ASSERT(
   5276       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5277   // Compute attributes.
   5278   PropertyAttributes attributes =
   5279       static_cast<PropertyAttributes>(unchecked_attributes);
   5280 
   5281   StrictModeFlag strict_mode = kNonStrictMode;
   5282   if (args.length() == 5) {
   5283     CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
   5284     strict_mode = strict_mode_flag;
   5285   }
   5286 
   5287   return Runtime::SetObjectProperty(isolate,
   5288                                     object,
   5289                                     key,
   5290                                     value,
   5291                                     attributes,
   5292                                     strict_mode);
   5293 }
   5294 
   5295 
   5296 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) {
   5297   HandleScope scope(isolate);
   5298   RUNTIME_ASSERT(args.length() == 2);
   5299   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
   5300   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
   5301   JSObject::TransitionElementsKind(array, map->elements_kind());
   5302   return *array;
   5303 }
   5304 
   5305 
   5306 // Set the native flag on the function.
   5307 // This is used to decide if we should transform null and undefined
   5308 // into the global object when doing call and apply.
   5309 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
   5310   SealHandleScope shs(isolate);
   5311   RUNTIME_ASSERT(args.length() == 1);
   5312 
   5313   Handle<Object> object = args.at<Object>(0);
   5314 
   5315   if (object->IsJSFunction()) {
   5316     JSFunction* func = JSFunction::cast(*object);
   5317     func->shared()->set_native(true);
   5318   }
   5319   return isolate->heap()->undefined_value();
   5320 }
   5321 
   5322 
   5323 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
   5324   HandleScope scope(isolate);
   5325   RUNTIME_ASSERT(args.length() == 5);
   5326   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   5327   CONVERT_SMI_ARG_CHECKED(store_index, 1);
   5328   Handle<Object> value = args.at<Object>(2);
   5329   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
   5330   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
   5331 
   5332   Object* raw_literal_cell = literals->get(literal_index);
   5333   JSArray* boilerplate = NULL;
   5334   if (raw_literal_cell->IsAllocationSite()) {
   5335     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
   5336     boilerplate = JSArray::cast(site->transition_info());
   5337   } else {
   5338     boilerplate = JSArray::cast(raw_literal_cell);
   5339   }
   5340   Handle<JSArray> boilerplate_object(boilerplate);
   5341   ElementsKind elements_kind = object->GetElementsKind();
   5342   ASSERT(IsFastElementsKind(elements_kind));
   5343   // Smis should never trigger transitions.
   5344   ASSERT(!value->IsSmi());
   5345 
   5346   if (value->IsNumber()) {
   5347     ASSERT(IsFastSmiElementsKind(elements_kind));
   5348     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5349         ? FAST_HOLEY_DOUBLE_ELEMENTS
   5350         : FAST_DOUBLE_ELEMENTS;
   5351     if (IsMoreGeneralElementsKindTransition(
   5352             boilerplate_object->GetElementsKind(),
   5353             transitioned_kind)) {
   5354       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5355     }
   5356     JSObject::TransitionElementsKind(object, transitioned_kind);
   5357     ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
   5358     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
   5359     HeapNumber* number = HeapNumber::cast(*value);
   5360     double_array->set(store_index, number->Number());
   5361   } else {
   5362     ASSERT(IsFastSmiElementsKind(elements_kind) ||
   5363            IsFastDoubleElementsKind(elements_kind));
   5364     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
   5365         ? FAST_HOLEY_ELEMENTS
   5366         : FAST_ELEMENTS;
   5367     JSObject::TransitionElementsKind(object, transitioned_kind);
   5368     if (IsMoreGeneralElementsKindTransition(
   5369             boilerplate_object->GetElementsKind(),
   5370             transitioned_kind)) {
   5371       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
   5372     }
   5373     FixedArray* object_array = FixedArray::cast(object->elements());
   5374     object_array->set(store_index, *value);
   5375   }
   5376   return *object;
   5377 }
   5378 
   5379 
   5380 // Check whether debugger and is about to step into the callback that is passed
   5381 // to a built-in function such as Array.forEach.
   5382 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) {
   5383   SealHandleScope shs(isolate);
   5384 #ifdef ENABLE_DEBUGGER_SUPPORT
   5385   if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
   5386     return isolate->heap()->false_value();
   5387   }
   5388   CONVERT_ARG_CHECKED(Object, callback, 0);
   5389   // We do not step into the callback if it's a builtin or not even a function.
   5390   if (!callback->IsJSFunction() || JSFunction::cast(callback)->IsBuiltin()) {
   5391     return isolate->heap()->false_value();
   5392   }
   5393   return isolate->heap()->true_value();
   5394 #else
   5395   return isolate->heap()->false_value();
   5396 #endif  // ENABLE_DEBUGGER_SUPPORT
   5397 }
   5398 
   5399 
   5400 // Set one shot breakpoints for the callback function that is passed to a
   5401 // built-in function such as Array.forEach to enable stepping into the callback.
   5402 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
   5403   SealHandleScope shs(isolate);
   5404 #ifdef ENABLE_DEBUGGER_SUPPORT
   5405   Debug* debug = isolate->debug();
   5406   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
   5407   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
   5408   HandleScope scope(isolate);
   5409   // When leaving the callback, step out has been activated, but not performed
   5410   // if we do not leave the builtin.  To be able to step into the callback
   5411   // again, we need to clear the step out at this point.
   5412   debug->ClearStepOut();
   5413   debug->FloodWithOneShot(callback);
   5414 #endif  // ENABLE_DEBUGGER_SUPPORT
   5415   return isolate->heap()->undefined_value();
   5416 }
   5417 
   5418 
   5419 // Set a local property, even if it is READ_ONLY.  If the property does not
   5420 // exist, it will be added with attributes NONE.
   5421 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
   5422   SealHandleScope shs(isolate);
   5423   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
   5424   CONVERT_ARG_CHECKED(JSObject, object, 0);
   5425   CONVERT_ARG_CHECKED(Name, name, 1);
   5426   // Compute attributes.
   5427   PropertyAttributes attributes = NONE;
   5428   if (args.length() == 4) {
   5429     CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
   5430     // Only attribute bits should be set.
   5431     RUNTIME_ASSERT(
   5432         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   5433     attributes = static_cast<PropertyAttributes>(unchecked_value);
   5434   }
   5435 
   5436   return object->
   5437       SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
   5438 }
   5439 
   5440 
   5441 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
   5442   HandleScope scope(isolate);
   5443   ASSERT(args.length() == 3);
   5444   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5445   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   5446   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
   5447   JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode)
   5448       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
   5449   Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode);
   5450   RETURN_IF_EMPTY_HANDLE(isolate, result);
   5451   return *result;
   5452 }
   5453 
   5454 
   5455 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
   5456                                                    Handle<JSObject> object,
   5457                                                    Handle<Name> key) {
   5458   if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
   5459   // Handle hidden prototypes.  If there's a hidden prototype above this thing
   5460   // then we have to check it for properties, because they are supposed to
   5461   // look like they are on this object.
   5462   Handle<Object> proto(object->GetPrototype(), isolate);
   5463   if (proto->IsJSObject() &&
   5464       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
   5465     return HasLocalPropertyImplementation(isolate,
   5466                                           Handle<JSObject>::cast(proto),
   5467                                           key);
   5468   }
   5469   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5470   return isolate->heap()->false_value();
   5471 }
   5472 
   5473 
   5474 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
   5475   SealHandleScope shs(isolate);
   5476   ASSERT(args.length() == 2);
   5477   CONVERT_ARG_CHECKED(Name, key, 1);
   5478 
   5479   uint32_t index;
   5480   const bool key_is_array_index = key->AsArrayIndex(&index);
   5481 
   5482   Object* obj = args[0];
   5483   // Only JS objects can have properties.
   5484   if (obj->IsJSObject()) {
   5485     JSObject* object = JSObject::cast(obj);
   5486     // Fast case: either the key is a real named property or it is not
   5487     // an array index and there are no interceptors or hidden
   5488     // prototypes.
   5489     if (object->HasRealNamedProperty(isolate, key)) {
   5490       ASSERT(!isolate->has_scheduled_exception());
   5491       return isolate->heap()->true_value();
   5492     } else {
   5493       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5494     }
   5495     Map* map = object->map();
   5496     if (!key_is_array_index &&
   5497         !map->has_named_interceptor() &&
   5498         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
   5499       return isolate->heap()->false_value();
   5500     }
   5501     // Slow case.
   5502     HandleScope scope(isolate);
   5503     return HasLocalPropertyImplementation(isolate,
   5504                                           Handle<JSObject>(object),
   5505                                           Handle<Name>(key));
   5506   } else if (obj->IsString() && key_is_array_index) {
   5507     // Well, there is one exception:  Handle [] on strings.
   5508     String* string = String::cast(obj);
   5509     if (index < static_cast<uint32_t>(string->length())) {
   5510       return isolate->heap()->true_value();
   5511     }
   5512   }
   5513   return isolate->heap()->false_value();
   5514 }
   5515 
   5516 
   5517 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
   5518   SealHandleScope shs(isolate);
   5519   ASSERT(args.length() == 2);
   5520   CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
   5521   CONVERT_ARG_CHECKED(Name, key, 1);
   5522 
   5523   bool result = receiver->HasProperty(key);
   5524   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5525   if (isolate->has_pending_exception()) return Failure::Exception();
   5526   return isolate->heap()->ToBoolean(result);
   5527 }
   5528 
   5529 
   5530 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
   5531   SealHandleScope shs(isolate);
   5532   ASSERT(args.length() == 2);
   5533   CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
   5534   CONVERT_SMI_ARG_CHECKED(index, 1);
   5535 
   5536   bool result = receiver->HasElement(index);
   5537   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5538   if (isolate->has_pending_exception()) return Failure::Exception();
   5539   return isolate->heap()->ToBoolean(result);
   5540 }
   5541 
   5542 
   5543 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
   5544   SealHandleScope shs(isolate);
   5545   ASSERT(args.length() == 2);
   5546 
   5547   CONVERT_ARG_CHECKED(JSObject, object, 0);
   5548   CONVERT_ARG_CHECKED(Name, key, 1);
   5549 
   5550   PropertyAttributes att = object->GetLocalPropertyAttribute(key);
   5551   if (att == ABSENT || (att & DONT_ENUM) != 0) {
   5552     RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5553     return isolate->heap()->false_value();
   5554   }
   5555   ASSERT(!isolate->has_scheduled_exception());
   5556   return isolate->heap()->true_value();
   5557 }
   5558 
   5559 
   5560 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
   5561   HandleScope scope(isolate);
   5562   ASSERT(args.length() == 1);
   5563   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   5564   bool threw = false;
   5565   Handle<JSArray> result = GetKeysFor(object, &threw);
   5566   if (threw) return Failure::Exception();
   5567   return *result;
   5568 }
   5569 
   5570 
   5571 // Returns either a FixedArray as Runtime_GetPropertyNames,
   5572 // or, if the given object has an enum cache that contains
   5573 // all enumerable properties of the object and its prototypes
   5574 // have none, the map of the object. This is used to speed up
   5575 // the check for deletions during a for-in.
   5576 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
   5577   SealHandleScope shs(isolate);
   5578   ASSERT(args.length() == 1);
   5579 
   5580   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
   5581 
   5582   if (raw_object->IsSimpleEnum()) return raw_object->map();
   5583 
   5584   HandleScope scope(isolate);
   5585   Handle<JSReceiver> object(raw_object);
   5586   bool threw = false;
   5587   Handle<FixedArray> content =
   5588       GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw);
   5589   if (threw) return Failure::Exception();
   5590 
   5591   // Test again, since cache may have been built by preceding call.
   5592   if (object->IsSimpleEnum()) return object->map();
   5593 
   5594   return *content;
   5595 }
   5596 
   5597 
   5598 // Find the length of the prototype chain that is to to handled as one. If a
   5599 // prototype object is hidden it is to be viewed as part of the the object it
   5600 // is prototype for.
   5601 static int LocalPrototypeChainLength(JSObject* obj) {
   5602   int count = 1;
   5603   Object* proto = obj->GetPrototype();
   5604   while (proto->IsJSObject() &&
   5605          JSObject::cast(proto)->map()->is_hidden_prototype()) {
   5606     count++;
   5607     proto = JSObject::cast(proto)->GetPrototype();
   5608   }
   5609   return count;
   5610 }
   5611 
   5612 
   5613 // Return the names of the local named properties.
   5614 // args[0]: object
   5615 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
   5616   HandleScope scope(isolate);
   5617   ASSERT(args.length() == 2);
   5618   if (!args[0]->IsJSObject()) {
   5619     return isolate->heap()->undefined_value();
   5620   }
   5621   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5622   CONVERT_BOOLEAN_ARG_CHECKED(include_symbols, 1);
   5623   PropertyAttributes filter = include_symbols ? NONE : SYMBOLIC;
   5624 
   5625   // Skip the global proxy as it has no properties and always delegates to the
   5626   // real global object.
   5627   if (obj->IsJSGlobalProxy()) {
   5628     // Only collect names if access is permitted.
   5629     if (obj->IsAccessCheckNeeded() &&
   5630         !isolate->MayNamedAccess(*obj,
   5631                                  isolate->heap()->undefined_value(),
   5632                                  v8::ACCESS_KEYS)) {
   5633       isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS);
   5634       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5635       return *isolate->factory()->NewJSArray(0);
   5636     }
   5637     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   5638   }
   5639 
   5640   // Find the number of objects making up this.
   5641   int length = LocalPrototypeChainLength(*obj);
   5642 
   5643   // Find the number of local properties for each of the objects.
   5644   ScopedVector<int> local_property_count(length);
   5645   int total_property_count = 0;
   5646   Handle<JSObject> jsproto = obj;
   5647   for (int i = 0; i < length; i++) {
   5648     // Only collect names if access is permitted.
   5649     if (jsproto->IsAccessCheckNeeded() &&
   5650         !isolate->MayNamedAccess(*jsproto,
   5651                                  isolate->heap()->undefined_value(),
   5652                                  v8::ACCESS_KEYS)) {
   5653       isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS);
   5654       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5655       return *isolate->factory()->NewJSArray(0);
   5656     }
   5657     int n;
   5658     n = jsproto->NumberOfLocalProperties(filter);
   5659     local_property_count[i] = n;
   5660     total_property_count += n;
   5661     if (i < length - 1) {
   5662       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   5663     }
   5664   }
   5665 
   5666   // Allocate an array with storage for all the property names.
   5667   Handle<FixedArray> names =
   5668       isolate->factory()->NewFixedArray(total_property_count);
   5669 
   5670   // Get the property names.
   5671   jsproto = obj;
   5672   int proto_with_hidden_properties = 0;
   5673   int next_copy_index = 0;
   5674   for (int i = 0; i < length; i++) {
   5675     jsproto->GetLocalPropertyNames(*names, next_copy_index, filter);
   5676     next_copy_index += local_property_count[i];
   5677     if (jsproto->HasHiddenProperties()) {
   5678       proto_with_hidden_properties++;
   5679     }
   5680     if (i < length - 1) {
   5681       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   5682     }
   5683   }
   5684 
   5685   // Filter out name of hidden properties object.
   5686   if (proto_with_hidden_properties > 0) {
   5687     Handle<FixedArray> old_names = names;
   5688     names = isolate->factory()->NewFixedArray(
   5689         names->length() - proto_with_hidden_properties);
   5690     int dest_pos = 0;
   5691     for (int i = 0; i < total_property_count; i++) {
   5692       Object* name = old_names->get(i);
   5693       if (name == isolate->heap()->hidden_string()) {
   5694         continue;
   5695       }
   5696       names->set(dest_pos++, name);
   5697     }
   5698   }
   5699 
   5700   return *isolate->factory()->NewJSArrayWithElements(names);
   5701 }
   5702 
   5703 
   5704 // Return the names of the local indexed properties.
   5705 // args[0]: object
   5706 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalElementNames) {
   5707   HandleScope scope(isolate);
   5708   ASSERT(args.length() == 1);
   5709   if (!args[0]->IsJSObject()) {
   5710     return isolate->heap()->undefined_value();
   5711   }
   5712   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5713 
   5714   int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
   5715   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
   5716   obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
   5717   return *isolate->factory()->NewJSArrayWithElements(names);
   5718 }
   5719 
   5720 
   5721 // Return information on whether an object has a named or indexed interceptor.
   5722 // args[0]: object
   5723 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetInterceptorInfo) {
   5724   HandleScope scope(isolate);
   5725   ASSERT(args.length() == 1);
   5726   if (!args[0]->IsJSObject()) {
   5727     return Smi::FromInt(0);
   5728   }
   5729   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5730 
   5731   int result = 0;
   5732   if (obj->HasNamedInterceptor()) result |= 2;
   5733   if (obj->HasIndexedInterceptor()) result |= 1;
   5734 
   5735   return Smi::FromInt(result);
   5736 }
   5737 
   5738 
   5739 // Return property names from named interceptor.
   5740 // args[0]: object
   5741 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
   5742   HandleScope scope(isolate);
   5743   ASSERT(args.length() == 1);
   5744   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5745 
   5746   if (obj->HasNamedInterceptor()) {
   5747     v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
   5748     if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
   5749   }
   5750   return isolate->heap()->undefined_value();
   5751 }
   5752 
   5753 
   5754 // Return element names from indexed interceptor.
   5755 // args[0]: object
   5756 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetIndexedInterceptorElementNames) {
   5757   HandleScope scope(isolate);
   5758   ASSERT(args.length() == 1);
   5759   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5760 
   5761   if (obj->HasIndexedInterceptor()) {
   5762     v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
   5763     if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
   5764   }
   5765   return isolate->heap()->undefined_value();
   5766 }
   5767 
   5768 
   5769 RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
   5770   HandleScope scope(isolate);
   5771   ASSERT_EQ(args.length(), 1);
   5772   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
   5773   Handle<JSObject> object(raw_object);
   5774 
   5775   if (object->IsJSGlobalProxy()) {
   5776     // Do access checks before going to the global object.
   5777     if (object->IsAccessCheckNeeded() &&
   5778         !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
   5779                              v8::ACCESS_KEYS)) {
   5780       isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
   5781       RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   5782       return *isolate->factory()->NewJSArray(0);
   5783     }
   5784 
   5785     Handle<Object> proto(object->GetPrototype(), isolate);
   5786     // If proxy is detached we simply return an empty array.
   5787     if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
   5788     object = Handle<JSObject>::cast(proto);
   5789   }
   5790 
   5791   bool threw = false;
   5792   Handle<FixedArray> contents =
   5793       GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
   5794   if (threw) return Failure::Exception();
   5795 
   5796   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
   5797   // property array and since the result is mutable we have to create
   5798   // a fresh clone on each invocation.
   5799   int length = contents->length();
   5800   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
   5801   for (int i = 0; i < length; i++) {
   5802     Object* entry = contents->get(i);
   5803     if (entry->IsString()) {
   5804       copy->set(i, entry);
   5805     } else {
   5806       ASSERT(entry->IsNumber());
   5807       HandleScope scope(isolate);
   5808       Handle<Object> entry_handle(entry, isolate);
   5809       Handle<Object> entry_str =
   5810           isolate->factory()->NumberToString(entry_handle);
   5811       copy->set(i, *entry_str);
   5812     }
   5813   }
   5814   return *isolate->factory()->NewJSArrayWithElements(copy);
   5815 }
   5816 
   5817 
   5818 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
   5819   SealHandleScope shs(isolate);
   5820   ASSERT(args.length() == 1);
   5821 
   5822   // Compute the frame holding the arguments.
   5823   JavaScriptFrameIterator it(isolate);
   5824   it.AdvanceToArgumentsFrame();
   5825   JavaScriptFrame* frame = it.frame();
   5826 
   5827   // Get the actual number of provided arguments.
   5828   const uint32_t n = frame->ComputeParametersCount();
   5829 
   5830   // Try to convert the key to an index. If successful and within
   5831   // index return the the argument from the frame.
   5832   uint32_t index;
   5833   if (args[0]->ToArrayIndex(&index) && index < n) {
   5834     return frame->GetParameter(index);
   5835   }
   5836 
   5837   if (args[0]->IsSymbol()) {
   5838     // Lookup in the initial Object.prototype object.
   5839     return isolate->initial_object_prototype()->GetProperty(
   5840         Symbol::cast(args[0]));
   5841   }
   5842 
   5843   // Convert the key to a string.
   5844   HandleScope scope(isolate);
   5845   bool exception = false;
   5846   Handle<Object> converted =
   5847       Execution::ToString(args.at<Object>(0), &exception);
   5848   if (exception) return Failure::Exception();
   5849   Handle<String> key = Handle<String>::cast(converted);
   5850 
   5851   // Try to convert the string key into an array index.
   5852   if (key->AsArrayIndex(&index)) {
   5853     if (index < n) {
   5854       return frame->GetParameter(index);
   5855     } else {
   5856       return isolate->initial_object_prototype()->GetElement(index);
   5857     }
   5858   }
   5859 
   5860   // Handle special arguments properties.
   5861   if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n);
   5862   if (key->Equals(isolate->heap()->callee_string())) {
   5863     JSFunction* function = frame->function();
   5864     if (!function->shared()->is_classic_mode()) {
   5865       return isolate->Throw(*isolate->factory()->NewTypeError(
   5866           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
   5867     }
   5868     return function;
   5869   }
   5870 
   5871   // Lookup in the initial Object.prototype object.
   5872   return isolate->initial_object_prototype()->GetProperty(*key);
   5873 }
   5874 
   5875 
   5876 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
   5877   SealHandleScope shs(isolate);
   5878   ASSERT(args.length() == 1);
   5879   Object* object = args[0];
   5880   return (object->IsJSObject() && !object->IsGlobalObject())
   5881       ? JSObject::cast(object)->TransformToFastProperties(0)
   5882       : object;
   5883 }
   5884 
   5885 
   5886 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
   5887   SealHandleScope shs(isolate);
   5888   ASSERT(args.length() == 1);
   5889 
   5890   return isolate->heap()->ToBoolean(args[0]->BooleanValue());
   5891 }
   5892 
   5893 
   5894 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
   5895 // Possible optimizations: put the type string into the oddballs.
   5896 RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
   5897   SealHandleScope shs(isolate);
   5898 
   5899   Object* obj = args[0];
   5900   if (obj->IsNumber()) return isolate->heap()->number_string();
   5901   HeapObject* heap_obj = HeapObject::cast(obj);
   5902 
   5903   // typeof an undetectable object is 'undefined'
   5904   if (heap_obj->map()->is_undetectable()) {
   5905     return isolate->heap()->undefined_string();
   5906   }
   5907 
   5908   InstanceType instance_type = heap_obj->map()->instance_type();
   5909   if (instance_type < FIRST_NONSTRING_TYPE) {
   5910     return isolate->heap()->string_string();
   5911   }
   5912 
   5913   switch (instance_type) {
   5914     case ODDBALL_TYPE:
   5915       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
   5916         return isolate->heap()->boolean_string();
   5917       }
   5918       if (heap_obj->IsNull()) {
   5919         return FLAG_harmony_typeof
   5920             ? isolate->heap()->null_string()
   5921             : isolate->heap()->object_string();
   5922       }
   5923       ASSERT(heap_obj->IsUndefined());
   5924       return isolate->heap()->undefined_string();
   5925     case SYMBOL_TYPE:
   5926       return isolate->heap()->symbol_string();
   5927     case JS_FUNCTION_TYPE:
   5928     case JS_FUNCTION_PROXY_TYPE:
   5929       return isolate->heap()->function_string();
   5930     default:
   5931       // For any kind of object not handled above, the spec rule for
   5932       // host objects gives that it is okay to return "object"
   5933       return isolate->heap()->object_string();
   5934   }
   5935 }
   5936 
   5937 
   5938 static bool AreDigits(const uint8_t*s, int from, int to) {
   5939   for (int i = from; i < to; i++) {
   5940     if (s[i] < '0' || s[i] > '9') return false;
   5941   }
   5942 
   5943   return true;
   5944 }
   5945 
   5946 
   5947 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
   5948   ASSERT(to - from < 10);  // Overflow is not possible.
   5949   ASSERT(from < to);
   5950   int d = s[from] - '0';
   5951 
   5952   for (int i = from + 1; i < to; i++) {
   5953     d = 10 * d + (s[i] - '0');
   5954   }
   5955 
   5956   return d;
   5957 }
   5958 
   5959 
   5960 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
   5961   SealHandleScope shs(isolate);
   5962   ASSERT(args.length() == 1);
   5963   CONVERT_ARG_CHECKED(String, subject, 0);
   5964   subject->TryFlatten();
   5965 
   5966   // Fast case: short integer or some sorts of junk values.
   5967   int len = subject->length();
   5968   if (subject->IsSeqOneByteString()) {
   5969     if (len == 0) return Smi::FromInt(0);
   5970 
   5971     uint8_t const* data = SeqOneByteString::cast(subject)->GetChars();
   5972     bool minus = (data[0] == '-');
   5973     int start_pos = (minus ? 1 : 0);
   5974 
   5975     if (start_pos == len) {
   5976       return isolate->heap()->nan_value();
   5977     } else if (data[start_pos] > '9') {
   5978       // Fast check for a junk value. A valid string may start from a
   5979       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
   5980       // the 'I' character ('Infinity'). All of that have codes not greater than
   5981       // '9' except 'I' and &nbsp;.
   5982       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
   5983         return isolate->heap()->nan_value();
   5984       }
   5985     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   5986       // The maximal/minimal smi has 10 digits. If the string has less digits we
   5987       // know it will fit into the smi-data type.
   5988       int d = ParseDecimalInteger(data, start_pos, len);
   5989       if (minus) {
   5990         if (d == 0) return isolate->heap()->minus_zero_value();
   5991         d = -d;
   5992       } else if (!subject->HasHashCode() &&
   5993                  len <= String::kMaxArrayIndexSize &&
   5994                  (len == 1 || data[0] != '0')) {
   5995         // String hash is not calculated yet but all the data are present.
   5996         // Update the hash field to speed up sequential convertions.
   5997         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   5998 #ifdef DEBUG
   5999         subject->Hash();  // Force hash calculation.
   6000         ASSERT_EQ(static_cast<int>(subject->hash_field()),
   6001                   static_cast<int>(hash));
   6002 #endif
   6003         subject->set_hash_field(hash);
   6004       }
   6005       return Smi::FromInt(d);
   6006     }
   6007   }
   6008 
   6009   // Slower case.
   6010   int flags = ALLOW_HEX;
   6011   if (FLAG_harmony_numeric_literals) {
   6012     // The current spec draft has not updated "ToNumber Applied to the String
   6013     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
   6014     flags |= ALLOW_OCTAL | ALLOW_BINARY;
   6015   }
   6016   return isolate->heap()->NumberFromDouble(
   6017       StringToDouble(isolate->unicode_cache(), subject, flags));
   6018 }
   6019 
   6020 
   6021 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) {
   6022   SealHandleScope shs(isolate);
   6023   CONVERT_SMI_ARG_CHECKED(length, 0);
   6024   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
   6025   if (length == 0) return isolate->heap()->empty_string();
   6026   if (is_one_byte) {
   6027     return isolate->heap()->AllocateRawOneByteString(length);
   6028   } else {
   6029     return isolate->heap()->AllocateRawTwoByteString(length);
   6030   }
   6031 }
   6032 
   6033 
   6034 RUNTIME_FUNCTION(MaybeObject*, Runtime_TruncateString) {
   6035   HandleScope scope(isolate);
   6036   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
   6037   CONVERT_SMI_ARG_CHECKED(new_length, 1);
   6038   return *SeqString::Truncate(string, new_length);
   6039 }
   6040 
   6041 
   6042 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
   6043   HandleScope scope(isolate);
   6044   ASSERT(args.length() == 1);
   6045   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6046   Handle<String> string = FlattenGetString(source);
   6047   ASSERT(string->IsFlat());
   6048   Handle<String> result = string->IsOneByteRepresentationUnderneath()
   6049       ? URIEscape::Escape<uint8_t>(isolate, source)
   6050       : URIEscape::Escape<uc16>(isolate, source);
   6051   if (result.is_null()) return Failure::OutOfMemoryException(0x12);
   6052   return *result;
   6053 }
   6054 
   6055 
   6056 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
   6057   HandleScope scope(isolate);
   6058   ASSERT(args.length() == 1);
   6059   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   6060   Handle<String> string = FlattenGetString(source);
   6061   ASSERT(string->IsFlat());
   6062   return string->IsOneByteRepresentationUnderneath()
   6063       ? *URIUnescape::Unescape<uint8_t>(isolate, source)
   6064       : *URIUnescape::Unescape<uc16>(isolate, source);
   6065 }
   6066 
   6067 
   6068 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
   6069   HandleScope scope(isolate);
   6070   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   6071   ASSERT(args.length() == 1);
   6072   return BasicJsonStringifier::StringifyString(isolate, string);
   6073 }
   6074 
   6075 
   6076 RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
   6077   HandleScope scope(isolate);
   6078   ASSERT(args.length() == 1);
   6079   BasicJsonStringifier stringifier(isolate);
   6080   return stringifier.Stringify(Handle<Object>(args[0], isolate));
   6081 }
   6082 
   6083 
   6084 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
   6085   SealHandleScope shs(isolate);
   6086 
   6087   CONVERT_ARG_CHECKED(String, s, 0);
   6088   CONVERT_SMI_ARG_CHECKED(radix, 1);
   6089 
   6090   s->TryFlatten();
   6091 
   6092   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
   6093   double value = StringToInt(isolate->unicode_cache(), s, radix);
   6094   return isolate->heap()->NumberFromDouble(value);
   6095 }
   6096 
   6097 
   6098 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
   6099   SealHandleScope shs(isolate);
   6100   CONVERT_ARG_CHECKED(String, str, 0);
   6101 
   6102   // ECMA-262 section 15.1.2.3, empty string is NaN
   6103   double value = StringToDouble(isolate->unicode_cache(),
   6104                                 str, ALLOW_TRAILING_JUNK, OS::nan_value());
   6105 
   6106   // Create a number object from the value.
   6107   return isolate->heap()->NumberFromDouble(value);
   6108 }
   6109 
   6110 
   6111 template <class Converter>
   6112 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
   6113     Isolate* isolate,
   6114     String* s,
   6115     int length,
   6116     int input_string_length,
   6117     unibrow::Mapping<Converter, 128>* mapping) {
   6118   // We try this twice, once with the assumption that the result is no longer
   6119   // than the input and, if that assumption breaks, again with the exact
   6120   // length.  This may not be pretty, but it is nicer than what was here before
   6121   // and I hereby claim my vaffel-is.
   6122   //
   6123   // Allocate the resulting string.
   6124   //
   6125   // NOTE: This assumes that the upper/lower case of an ASCII
   6126   // character is also ASCII.  This is currently the case, but it
   6127   // might break in the future if we implement more context and locale
   6128   // dependent upper/lower conversions.
   6129   Object* o;
   6130   { MaybeObject* maybe_o = s->IsOneByteRepresentation()
   6131         ? isolate->heap()->AllocateRawOneByteString(length)
   6132         : isolate->heap()->AllocateRawTwoByteString(length);
   6133     if (!maybe_o->ToObject(&o)) return maybe_o;
   6134   }
   6135   String* result = String::cast(o);
   6136   bool has_changed_character = false;
   6137 
   6138   // Convert all characters to upper case, assuming that they will fit
   6139   // in the buffer
   6140   Access<ConsStringIteratorOp> op(
   6141       isolate->runtime_state()->string_iterator());
   6142   StringCharacterStream stream(s, op.value());
   6143   unibrow::uchar chars[Converter::kMaxWidth];
   6144   // We can assume that the string is not empty
   6145   uc32 current = stream.GetNext();
   6146   for (int i = 0; i < length;) {
   6147     bool has_next = stream.HasMore();
   6148     uc32 next = has_next ? stream.GetNext() : 0;
   6149     int char_length = mapping->get(current, next, chars);
   6150     if (char_length == 0) {
   6151       // The case conversion of this character is the character itself.
   6152       result->Set(i, current);
   6153       i++;
   6154     } else if (char_length == 1) {
   6155       // Common case: converting the letter resulted in one character.
   6156       ASSERT(static_cast<uc32>(chars[0]) != current);
   6157       result->Set(i, chars[0]);
   6158       has_changed_character = true;
   6159       i++;
   6160     } else if (length == input_string_length) {
   6161       // We've assumed that the result would be as long as the
   6162       // input but here is a character that converts to several
   6163       // characters.  No matter, we calculate the exact length
   6164       // of the result and try the whole thing again.
   6165       //
   6166       // Note that this leaves room for optimization.  We could just
   6167       // memcpy what we already have to the result string.  Also,
   6168       // the result string is the last object allocated we could
   6169       // "realloc" it and probably, in the vast majority of cases,
   6170       // extend the existing string to be able to hold the full
   6171       // result.
   6172       int next_length = 0;
   6173       if (has_next) {
   6174         next_length = mapping->get(next, 0, chars);
   6175         if (next_length == 0) next_length = 1;
   6176       }
   6177       int current_length = i + char_length + next_length;
   6178       while (stream.HasMore()) {
   6179         current = stream.GetNext();
   6180         // NOTE: we use 0 as the next character here because, while
   6181         // the next character may affect what a character converts to,
   6182         // it does not in any case affect the length of what it convert
   6183         // to.
   6184         int char_length = mapping->get(current, 0, chars);
   6185         if (char_length == 0) char_length = 1;
   6186         current_length += char_length;
   6187         if (current_length > Smi::kMaxValue) {
   6188           isolate->context()->mark_out_of_memory();
   6189           return Failure::OutOfMemoryException(0x13);
   6190         }
   6191       }
   6192       // Try again with the real length.
   6193       return Smi::FromInt(current_length);
   6194     } else {
   6195       for (int j = 0; j < char_length; j++) {
   6196         result->Set(i, chars[j]);
   6197         i++;
   6198       }
   6199       has_changed_character = true;
   6200     }
   6201     current = next;
   6202   }
   6203   if (has_changed_character) {
   6204     return result;
   6205   } else {
   6206     // If we didn't actually change anything in doing the conversion
   6207     // we simple return the result and let the converted string
   6208     // become garbage; there is no reason to keep two identical strings
   6209     // alive.
   6210     return s;
   6211   }
   6212 }
   6213 
   6214 
   6215 namespace {
   6216 
   6217 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
   6218 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
   6219 
   6220 // Given a word and two range boundaries returns a word with high bit
   6221 // set in every byte iff the corresponding input byte was strictly in
   6222 // the range (m, n). All the other bits in the result are cleared.
   6223 // This function is only useful when it can be inlined and the
   6224 // boundaries are statically known.
   6225 // Requires: all bytes in the input word and the boundaries must be
   6226 // ASCII (less than 0x7F).
   6227 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
   6228   // Use strict inequalities since in edge cases the function could be
   6229   // further simplified.
   6230   ASSERT(0 < m && m < n);
   6231   // Has high bit set in every w byte less than n.
   6232   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   6233   // Has high bit set in every w byte greater than m.
   6234   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
   6235   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
   6236 }
   6237 
   6238 
   6239 enum AsciiCaseConversion {
   6240   ASCII_TO_LOWER,
   6241   ASCII_TO_UPPER
   6242 };
   6243 
   6244 
   6245 template <AsciiCaseConversion dir>
   6246 struct FastAsciiConverter {
   6247   static bool Convert(char* dst, char* src, int length, bool* changed_out) {
   6248 #ifdef DEBUG
   6249     char* saved_dst = dst;
   6250     char* saved_src = src;
   6251 #endif
   6252     // We rely on the distance between upper and lower case letters
   6253     // being a known power of 2.
   6254     ASSERT('a' - 'A' == (1 << 5));
   6255     // Boundaries for the range of input characters than require conversion.
   6256     const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1;
   6257     const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1;
   6258     bool changed = false;
   6259     uintptr_t or_acc = 0;
   6260     char* const limit = src + length;
   6261 #ifdef V8_HOST_CAN_READ_UNALIGNED
   6262     // Process the prefix of the input that requires no conversion one
   6263     // (machine) word at a time.
   6264     while (src <= limit - sizeof(uintptr_t)) {
   6265       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
   6266       or_acc |= w;
   6267       if (AsciiRangeMask(w, lo, hi) != 0) {
   6268         changed = true;
   6269         break;
   6270       }
   6271       *reinterpret_cast<uintptr_t*>(dst) = w;
   6272       src += sizeof(uintptr_t);
   6273       dst += sizeof(uintptr_t);
   6274     }
   6275     // Process the remainder of the input performing conversion when
   6276     // required one word at a time.
   6277     while (src <= limit - sizeof(uintptr_t)) {
   6278       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
   6279       or_acc |= w;
   6280       uintptr_t m = AsciiRangeMask(w, lo, hi);
   6281       // The mask has high (7th) bit set in every byte that needs
   6282       // conversion and we know that the distance between cases is
   6283       // 1 << 5.
   6284       *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
   6285       src += sizeof(uintptr_t);
   6286       dst += sizeof(uintptr_t);
   6287     }
   6288 #endif
   6289     // Process the last few bytes of the input (or the whole input if
   6290     // unaligned access is not supported).
   6291     while (src < limit) {
   6292       char c = *src;
   6293       or_acc |= c;
   6294       if (lo < c && c < hi) {
   6295         c ^= (1 << 5);
   6296         changed = true;
   6297       }
   6298       *dst = c;
   6299       ++src;
   6300       ++dst;
   6301     }
   6302     if ((or_acc & kAsciiMask) != 0) {
   6303       return false;
   6304     }
   6305 #ifdef DEBUG
   6306     CheckConvert(saved_dst, saved_src, length, changed);
   6307 #endif
   6308     *changed_out = changed;
   6309     return true;
   6310   }
   6311 
   6312 #ifdef DEBUG
   6313   static void CheckConvert(char* dst, char* src, int length, bool changed) {
   6314     bool expected_changed = false;
   6315     for (int i = 0; i < length; i++) {
   6316       if (dst[i] == src[i]) continue;
   6317       expected_changed = true;
   6318       if (dir == ASCII_TO_LOWER) {
   6319         ASSERT('A' <= src[i] && src[i] <= 'Z');
   6320         ASSERT(dst[i] == src[i] + ('a' - 'A'));
   6321       } else {
   6322         ASSERT(dir == ASCII_TO_UPPER);
   6323         ASSERT('a' <= src[i] && src[i] <= 'z');
   6324         ASSERT(dst[i] == src[i] - ('a' - 'A'));
   6325       }
   6326     }
   6327     ASSERT(expected_changed == changed);
   6328   }
   6329 #endif
   6330 };
   6331 
   6332 
   6333 struct ToLowerTraits {
   6334   typedef unibrow::ToLowercase UnibrowConverter;
   6335 
   6336   typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter;
   6337 };
   6338 
   6339 
   6340 struct ToUpperTraits {
   6341   typedef unibrow::ToUppercase UnibrowConverter;
   6342 
   6343   typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter;
   6344 };
   6345 
   6346 }  // namespace
   6347 
   6348 
   6349 template <typename ConvertTraits>
   6350 MUST_USE_RESULT static MaybeObject* ConvertCase(
   6351     Arguments args,
   6352     Isolate* isolate,
   6353     unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
   6354   SealHandleScope shs(isolate);
   6355   CONVERT_ARG_CHECKED(String, s, 0);
   6356   s = s->TryFlattenGetString();
   6357 
   6358   const int length = s->length();
   6359   // Assume that the string is not empty; we need this assumption later
   6360   if (length == 0) return s;
   6361 
   6362   // Simpler handling of ASCII strings.
   6363   //
   6364   // NOTE: This assumes that the upper/lower case of an ASCII
   6365   // character is also ASCII.  This is currently the case, but it
   6366   // might break in the future if we implement more context and locale
   6367   // dependent upper/lower conversions.
   6368   if (s->IsSeqOneByteString()) {
   6369     Object* o;
   6370     { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length);
   6371       if (!maybe_o->ToObject(&o)) return maybe_o;
   6372     }
   6373     SeqOneByteString* result = SeqOneByteString::cast(o);
   6374     bool has_changed_character;
   6375     bool is_ascii = ConvertTraits::AsciiConverter::Convert(
   6376         reinterpret_cast<char*>(result->GetChars()),
   6377         reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
   6378         length,
   6379         &has_changed_character);
   6380     // If not ASCII, we discard the result and take the 2 byte path.
   6381     if (is_ascii) {
   6382       return has_changed_character ? result : s;
   6383     }
   6384   }
   6385 
   6386   Object* answer;
   6387   { MaybeObject* maybe_answer =
   6388         ConvertCaseHelper(isolate, s, length, length, mapping);
   6389     if (!maybe_answer->ToObject(&answer)) return maybe_answer;
   6390   }
   6391   if (answer->IsSmi()) {
   6392     // Retry with correct length.
   6393     { MaybeObject* maybe_answer =
   6394           ConvertCaseHelper(isolate,
   6395                             s, Smi::cast(answer)->value(), length, mapping);
   6396       if (!maybe_answer->ToObject(&answer)) return maybe_answer;
   6397     }
   6398   }
   6399   return answer;
   6400 }
   6401 
   6402 
   6403 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
   6404   return ConvertCase<ToLowerTraits>(
   6405       args, isolate, isolate->runtime_state()->to_lower_mapping());
   6406 }
   6407 
   6408 
   6409 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
   6410   return ConvertCase<ToUpperTraits>(
   6411       args, isolate, isolate->runtime_state()->to_upper_mapping());
   6412 }
   6413 
   6414 
   6415 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
   6416   return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
   6417 }
   6418 
   6419 
   6420 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
   6421   SealHandleScope shs(isolate);
   6422   ASSERT(args.length() == 3);
   6423 
   6424   CONVERT_ARG_CHECKED(String, s, 0);
   6425   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
   6426   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
   6427 
   6428   s->TryFlatten();
   6429   int length = s->length();
   6430 
   6431   int left = 0;
   6432   if (trimLeft) {
   6433     while (left < length && IsTrimWhiteSpace(s->Get(left))) {
   6434       left++;
   6435     }
   6436   }
   6437 
   6438   int right = length;
   6439   if (trimRight) {
   6440     while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) {
   6441       right--;
   6442     }
   6443   }
   6444   return s->SubString(left, right);
   6445 }
   6446 
   6447 
   6448 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
   6449   HandleScope handle_scope(isolate);
   6450   ASSERT(args.length() == 3);
   6451   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6452   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   6453   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
   6454 
   6455   int subject_length = subject->length();
   6456   int pattern_length = pattern->length();
   6457   RUNTIME_ASSERT(pattern_length > 0);
   6458 
   6459   if (limit == 0xffffffffu) {
   6460     Handle<Object> cached_answer(
   6461         RegExpResultsCache::Lookup(isolate->heap(),
   6462                                    *subject,
   6463                                    *pattern,
   6464                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
   6465         isolate);
   6466     if (*cached_answer != Smi::FromInt(0)) {
   6467       // The cache FixedArray is a COW-array and can therefore be reused.
   6468       Handle<JSArray> result =
   6469           isolate->factory()->NewJSArrayWithElements(
   6470               Handle<FixedArray>::cast(cached_answer));
   6471       return *result;
   6472     }
   6473   }
   6474 
   6475   // The limit can be very large (0xffffffffu), but since the pattern
   6476   // isn't empty, we can never create more parts than ~half the length
   6477   // of the subject.
   6478 
   6479   if (!subject->IsFlat()) FlattenString(subject);
   6480 
   6481   static const int kMaxInitialListCapacity = 16;
   6482 
   6483   ZoneScope zone_scope(isolate->runtime_zone());
   6484 
   6485   // Find (up to limit) indices of separator and end-of-string in subject
   6486   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
   6487   ZoneList<int> indices(initial_capacity, zone_scope.zone());
   6488   if (!pattern->IsFlat()) FlattenString(pattern);
   6489 
   6490   FindStringIndicesDispatch(isolate, *subject, *pattern,
   6491                             &indices, limit, zone_scope.zone());
   6492 
   6493   if (static_cast<uint32_t>(indices.length()) < limit) {
   6494     indices.Add(subject_length, zone_scope.zone());
   6495   }
   6496 
   6497   // The list indices now contains the end of each part to create.
   6498 
   6499   // Create JSArray of substrings separated by separator.
   6500   int part_count = indices.length();
   6501 
   6502   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
   6503   MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements();
   6504   if (maybe_result->IsFailure()) return maybe_result;
   6505   result->set_length(Smi::FromInt(part_count));
   6506 
   6507   ASSERT(result->HasFastObjectElements());
   6508 
   6509   if (part_count == 1 && indices.at(0) == subject_length) {
   6510     FixedArray::cast(result->elements())->set(0, *subject);
   6511     return *result;
   6512   }
   6513 
   6514   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
   6515   int part_start = 0;
   6516   for (int i = 0; i < part_count; i++) {
   6517     HandleScope local_loop_handle(isolate);
   6518     int part_end = indices.at(i);
   6519     Handle<String> substring =
   6520         isolate->factory()->NewProperSubString(subject, part_start, part_end);
   6521     elements->set(i, *substring);
   6522     part_start = part_end + pattern_length;
   6523   }
   6524 
   6525   if (limit == 0xffffffffu) {
   6526     if (result->HasFastObjectElements()) {
   6527       RegExpResultsCache::Enter(isolate->heap(),
   6528                                 *subject,
   6529                                 *pattern,
   6530                                 *elements,
   6531                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
   6532     }
   6533   }
   6534 
   6535   return *result;
   6536 }
   6537 
   6538 
   6539 // Copies ASCII characters to the given fixed array looking up
   6540 // one-char strings in the cache. Gives up on the first char that is
   6541 // not in the cache and fills the remainder with smi zeros. Returns
   6542 // the length of the successfully copied prefix.
   6543 static int CopyCachedAsciiCharsToArray(Heap* heap,
   6544                                        const uint8_t* chars,
   6545                                        FixedArray* elements,
   6546                                        int length) {
   6547   DisallowHeapAllocation no_gc;
   6548   FixedArray* ascii_cache = heap->single_character_string_cache();
   6549   Object* undefined = heap->undefined_value();
   6550   int i;
   6551   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   6552   for (i = 0; i < length; ++i) {
   6553     Object* value = ascii_cache->get(chars[i]);
   6554     if (value == undefined) break;
   6555     elements->set(i, value, mode);
   6556   }
   6557   if (i < length) {
   6558     ASSERT(Smi::FromInt(0) == 0);
   6559     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
   6560   }
   6561 #ifdef DEBUG
   6562   for (int j = 0; j < length; ++j) {
   6563     Object* element = elements->get(j);
   6564     ASSERT(element == Smi::FromInt(0) ||
   6565            (element->IsString() && String::cast(element)->LooksValid()));
   6566   }
   6567 #endif
   6568   return i;
   6569 }
   6570 
   6571 
   6572 // Converts a String to JSArray.
   6573 // For example, "foo" => ["f", "o", "o"].
   6574 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
   6575   HandleScope scope(isolate);
   6576   ASSERT(args.length() == 2);
   6577   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6578   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   6579 
   6580   s = FlattenGetString(s);
   6581   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
   6582 
   6583   Handle<FixedArray> elements;
   6584   int position = 0;
   6585   if (s->IsFlat() && s->IsOneByteRepresentation()) {
   6586     // Try using cached chars where possible.
   6587     Object* obj;
   6588     { MaybeObject* maybe_obj =
   6589           isolate->heap()->AllocateUninitializedFixedArray(length);
   6590       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   6591     }
   6592     elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
   6593     DisallowHeapAllocation no_gc;
   6594     String::FlatContent content = s->GetFlatContent();
   6595     if (content.IsAscii()) {
   6596       Vector<const uint8_t> chars = content.ToOneByteVector();
   6597       // Note, this will initialize all elements (not only the prefix)
   6598       // to prevent GC from seeing partially initialized array.
   6599       position = CopyCachedAsciiCharsToArray(isolate->heap(),
   6600                                              chars.start(),
   6601                                              *elements,
   6602                                              length);
   6603     } else {
   6604       MemsetPointer(elements->data_start(),
   6605                     isolate->heap()->undefined_value(),
   6606                     length);
   6607     }
   6608   } else {
   6609     elements = isolate->factory()->NewFixedArray(length);
   6610   }
   6611   for (int i = position; i < length; ++i) {
   6612     Handle<Object> str =
   6613         LookupSingleCharacterStringFromCode(isolate, s->Get(i));
   6614     elements->set(i, *str);
   6615   }
   6616 
   6617 #ifdef DEBUG
   6618   for (int i = 0; i < length; ++i) {
   6619     ASSERT(String::cast(elements->get(i))->length() == 1);
   6620   }
   6621 #endif
   6622 
   6623   return *isolate->factory()->NewJSArrayWithElements(elements);
   6624 }
   6625 
   6626 
   6627 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
   6628   SealHandleScope shs(isolate);
   6629   ASSERT(args.length() == 1);
   6630   CONVERT_ARG_CHECKED(String, value, 0);
   6631   return value->ToObject();
   6632 }
   6633 
   6634 
   6635 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
   6636   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
   6637   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
   6638   return char_length == 0;
   6639 }
   6640 
   6641 
   6642 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToString) {
   6643   SealHandleScope shs(isolate);
   6644   ASSERT(args.length() == 1);
   6645 
   6646   Object* number = args[0];
   6647   RUNTIME_ASSERT(number->IsNumber());
   6648 
   6649   return isolate->heap()->NumberToString(number);
   6650 }
   6651 
   6652 
   6653 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToStringSkipCache) {
   6654   SealHandleScope shs(isolate);
   6655   ASSERT(args.length() == 1);
   6656 
   6657   Object* number = args[0];
   6658   RUNTIME_ASSERT(number->IsNumber());
   6659 
   6660   return isolate->heap()->NumberToString(
   6661       number, false, isolate->heap()->GetPretenureMode());
   6662 }
   6663 
   6664 
   6665 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
   6666   SealHandleScope shs(isolate);
   6667   ASSERT(args.length() == 1);
   6668 
   6669   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6670 
   6671   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6672   if (number > 0 && number <= Smi::kMaxValue) {
   6673     return Smi::FromInt(static_cast<int>(number));
   6674   }
   6675   return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
   6676 }
   6677 
   6678 
   6679 // ES6 draft 9.1.11
   6680 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPositiveInteger) {
   6681   SealHandleScope shs(isolate);
   6682   ASSERT(args.length() == 1);
   6683 
   6684   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6685 
   6686   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6687   if (number > 0 && number <= Smi::kMaxValue) {
   6688     return Smi::FromInt(static_cast<int>(number));
   6689   }
   6690   if (number <= 0) {
   6691     return Smi::FromInt(0);
   6692   }
   6693   return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
   6694 }
   6695 
   6696 
   6697 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
   6698   SealHandleScope shs(isolate);
   6699   ASSERT(args.length() == 1);
   6700 
   6701   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6702 
   6703   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6704   if (number > 0 && number <= Smi::kMaxValue) {
   6705     return Smi::FromInt(static_cast<int>(number));
   6706   }
   6707 
   6708   double double_value = DoubleToInteger(number);
   6709   // Map both -0 and +0 to +0.
   6710   if (double_value == 0) double_value = 0;
   6711 
   6712   return isolate->heap()->NumberFromDouble(double_value);
   6713 }
   6714 
   6715 
   6716 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) {
   6717   SealHandleScope shs(isolate);
   6718   ASSERT(args.length() == 1);
   6719 
   6720   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
   6721   return isolate->heap()->NumberFromUint32(number);
   6722 }
   6723 
   6724 
   6725 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
   6726   SealHandleScope shs(isolate);
   6727   ASSERT(args.length() == 1);
   6728 
   6729   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6730 
   6731   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6732   if (number > 0 && number <= Smi::kMaxValue) {
   6733     return Smi::FromInt(static_cast<int>(number));
   6734   }
   6735   return isolate->heap()->NumberFromInt32(DoubleToInt32(number));
   6736 }
   6737 
   6738 
   6739 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
   6740 // a small integer.
   6741 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToSmi) {
   6742   SealHandleScope shs(isolate);
   6743   ASSERT(args.length() == 1);
   6744 
   6745   Object* obj = args[0];
   6746   if (obj->IsSmi()) {
   6747     return obj;
   6748   }
   6749   if (obj->IsHeapNumber()) {
   6750     double value = HeapNumber::cast(obj)->value();
   6751     int int_value = FastD2I(value);
   6752     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
   6753       return Smi::FromInt(int_value);
   6754     }
   6755   }
   6756   return isolate->heap()->nan_value();
   6757 }
   6758 
   6759 
   6760 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateHeapNumber) {
   6761   SealHandleScope shs(isolate);
   6762   ASSERT(args.length() == 0);
   6763   return isolate->heap()->AllocateHeapNumber(0);
   6764 }
   6765 
   6766 
   6767 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
   6768   SealHandleScope shs(isolate);
   6769   ASSERT(args.length() == 2);
   6770 
   6771   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6772   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6773   return isolate->heap()->NumberFromDouble(x + y);
   6774 }
   6775 
   6776 
   6777 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
   6778   SealHandleScope shs(isolate);
   6779   ASSERT(args.length() == 2);
   6780 
   6781   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6782   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6783   return isolate->heap()->NumberFromDouble(x - y);
   6784 }
   6785 
   6786 
   6787 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
   6788   SealHandleScope shs(isolate);
   6789   ASSERT(args.length() == 2);
   6790 
   6791   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6792   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6793   return isolate->heap()->NumberFromDouble(x * y);
   6794 }
   6795 
   6796 
   6797 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
   6798   SealHandleScope shs(isolate);
   6799   ASSERT(args.length() == 1);
   6800 
   6801   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6802   return isolate->heap()->NumberFromDouble(-x);
   6803 }
   6804 
   6805 
   6806 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) {
   6807   SealHandleScope shs(isolate);
   6808   ASSERT(args.length() == 0);
   6809 
   6810   return isolate->heap()->NumberFromDouble(9876543210.0);
   6811 }
   6812 
   6813 
   6814 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
   6815   SealHandleScope shs(isolate);
   6816   ASSERT(args.length() == 2);
   6817 
   6818   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6819   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6820   return isolate->heap()->NumberFromDouble(x / y);
   6821 }
   6822 
   6823 
   6824 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
   6825   SealHandleScope shs(isolate);
   6826   ASSERT(args.length() == 2);
   6827 
   6828   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6829   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6830 
   6831   x = modulo(x, y);
   6832   // NumberFromDouble may return a Smi instead of a Number object
   6833   return isolate->heap()->NumberFromDouble(x);
   6834 }
   6835 
   6836 
   6837 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberImul) {
   6838   SealHandleScope shs(isolate);
   6839   ASSERT(args.length() == 2);
   6840 
   6841   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   6842   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   6843   return isolate->heap()->NumberFromInt32(x * y);
   6844 }
   6845 
   6846 
   6847 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) {
   6848   SealHandleScope shs(isolate);
   6849   ASSERT(args.length() == 2);
   6850   CONVERT_ARG_CHECKED(String, str1, 0);
   6851   CONVERT_ARG_CHECKED(String, str2, 1);
   6852   isolate->counters()->string_add_runtime()->Increment();
   6853   return isolate->heap()->AllocateConsString(str1, str2);
   6854 }
   6855 
   6856 
   6857 template <typename sinkchar>
   6858 static inline void StringBuilderConcatHelper(String* special,
   6859                                              sinkchar* sink,
   6860                                              FixedArray* fixed_array,
   6861                                              int array_length) {
   6862   int position = 0;
   6863   for (int i = 0; i < array_length; i++) {
   6864     Object* element = fixed_array->get(i);
   6865     if (element->IsSmi()) {
   6866       // Smi encoding of position and length.
   6867       int encoded_slice = Smi::cast(element)->value();
   6868       int pos;
   6869       int len;
   6870       if (encoded_slice > 0) {
   6871         // Position and length encoded in one smi.
   6872         pos = StringBuilderSubstringPosition::decode(encoded_slice);
   6873         len = StringBuilderSubstringLength::decode(encoded_slice);
   6874       } else {
   6875         // Position and length encoded in two smis.
   6876         Object* obj = fixed_array->get(++i);
   6877         ASSERT(obj->IsSmi());
   6878         pos = Smi::cast(obj)->value();
   6879         len = -encoded_slice;
   6880       }
   6881       String::WriteToFlat(special,
   6882                           sink + position,
   6883                           pos,
   6884                           pos + len);
   6885       position += len;
   6886     } else {
   6887       String* string = String::cast(element);
   6888       int element_length = string->length();
   6889       String::WriteToFlat(string, sink + position, 0, element_length);
   6890       position += element_length;
   6891     }
   6892   }
   6893 }
   6894 
   6895 
   6896 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
   6897   SealHandleScope shs(isolate);
   6898   ASSERT(args.length() == 3);
   6899   CONVERT_ARG_CHECKED(JSArray, array, 0);
   6900   if (!args[1]->IsSmi()) {
   6901     isolate->context()->mark_out_of_memory();
   6902     return Failure::OutOfMemoryException(0x14);
   6903   }
   6904   int array_length = args.smi_at(1);
   6905   CONVERT_ARG_CHECKED(String, special, 2);
   6906 
   6907   // This assumption is used by the slice encoding in one or two smis.
   6908   ASSERT(Smi::kMaxValue >= String::kMaxLength);
   6909 
   6910   MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements();
   6911   if (maybe_result->IsFailure()) return maybe_result;
   6912 
   6913   int special_length = special->length();
   6914   if (!array->HasFastObjectElements()) {
   6915     return isolate->Throw(isolate->heap()->illegal_argument_string());
   6916   }
   6917   FixedArray* fixed_array = FixedArray::cast(array->elements());
   6918   if (fixed_array->length() < array_length) {
   6919     array_length = fixed_array->length();
   6920   }
   6921 
   6922   if (array_length == 0) {
   6923     return isolate->heap()->empty_string();
   6924   } else if (array_length == 1) {
   6925     Object* first = fixed_array->get(0);
   6926     if (first->IsString()) return first;
   6927   }
   6928 
   6929   bool one_byte = special->HasOnlyOneByteChars();
   6930   int position = 0;
   6931   for (int i = 0; i < array_length; i++) {
   6932     int increment = 0;
   6933     Object* elt = fixed_array->get(i);
   6934     if (elt->IsSmi()) {
   6935       // Smi encoding of position and length.
   6936       int smi_value = Smi::cast(elt)->value();
   6937       int pos;
   6938       int len;
   6939       if (smi_value > 0) {
   6940         // Position and length encoded in one smi.
   6941         pos = StringBuilderSubstringPosition::decode(smi_value);
   6942         len = StringBuilderSubstringLength::decode(smi_value);
   6943       } else {
   6944         // Position and length encoded in two smis.
   6945         len = -smi_value;
   6946         // Get the position and check that it is a positive smi.
   6947         i++;
   6948         if (i >= array_length) {
   6949           return isolate->Throw(isolate->heap()->illegal_argument_string());
   6950         }
   6951         Object* next_smi = fixed_array->get(i);
   6952         if (!next_smi->IsSmi()) {
   6953           return isolate->Throw(isolate->heap()->illegal_argument_string());
   6954         }
   6955         pos = Smi::cast(next_smi)->value();
   6956         if (pos < 0) {
   6957           return isolate->Throw(isolate->heap()->illegal_argument_string());
   6958         }
   6959       }
   6960       ASSERT(pos >= 0);
   6961       ASSERT(len >= 0);
   6962       if (pos > special_length || len > special_length - pos) {
   6963         return isolate->Throw(isolate->heap()->illegal_argument_string());
   6964       }
   6965       increment = len;
   6966     } else if (elt->IsString()) {
   6967       String* element = String::cast(elt);
   6968       int element_length = element->length();
   6969       increment = element_length;
   6970       if (one_byte && !element->HasOnlyOneByteChars()) {
   6971         one_byte = false;
   6972       }
   6973     } else {
   6974       ASSERT(!elt->IsTheHole());
   6975       return isolate->Throw(isolate->heap()->illegal_argument_string());
   6976     }
   6977     if (increment > String::kMaxLength - position) {
   6978       isolate->context()->mark_out_of_memory();
   6979       return Failure::OutOfMemoryException(0x15);
   6980     }
   6981     position += increment;
   6982   }
   6983 
   6984   int length = position;
   6985   Object* object;
   6986 
   6987   if (one_byte) {
   6988     { MaybeObject* maybe_object =
   6989           isolate->heap()->AllocateRawOneByteString(length);
   6990       if (!maybe_object->ToObject(&object)) return maybe_object;
   6991     }
   6992     SeqOneByteString* answer = SeqOneByteString::cast(object);
   6993     StringBuilderConcatHelper(special,
   6994                               answer->GetChars(),
   6995                               fixed_array,
   6996                               array_length);
   6997     return answer;
   6998   } else {
   6999     { MaybeObject* maybe_object =
   7000           isolate->heap()->AllocateRawTwoByteString(length);
   7001       if (!maybe_object->ToObject(&object)) return maybe_object;
   7002     }
   7003     SeqTwoByteString* answer = SeqTwoByteString::cast(object);
   7004     StringBuilderConcatHelper(special,
   7005                               answer->GetChars(),
   7006                               fixed_array,
   7007                               array_length);
   7008     return answer;
   7009   }
   7010 }
   7011 
   7012 
   7013 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
   7014   SealHandleScope shs(isolate);
   7015   ASSERT(args.length() == 3);
   7016   CONVERT_ARG_CHECKED(JSArray, array, 0);
   7017   if (!args[1]->IsSmi()) {
   7018     isolate->context()->mark_out_of_memory();
   7019     return Failure::OutOfMemoryException(0x16);
   7020   }
   7021   int array_length = args.smi_at(1);
   7022   CONVERT_ARG_CHECKED(String, separator, 2);
   7023 
   7024   if (!array->HasFastObjectElements()) {
   7025     return isolate->Throw(isolate->heap()->illegal_argument_string());
   7026   }
   7027   FixedArray* fixed_array = FixedArray::cast(array->elements());
   7028   if (fixed_array->length() < array_length) {
   7029     array_length = fixed_array->length();
   7030   }
   7031 
   7032   if (array_length == 0) {
   7033     return isolate->heap()->empty_string();
   7034   } else if (array_length == 1) {
   7035     Object* first = fixed_array->get(0);
   7036     if (first->IsString()) return first;
   7037   }
   7038 
   7039   int separator_length = separator->length();
   7040   int max_nof_separators =
   7041       (String::kMaxLength + separator_length - 1) / separator_length;
   7042   if (max_nof_separators < (array_length - 1)) {
   7043       isolate->context()->mark_out_of_memory();
   7044       return Failure::OutOfMemoryException(0x17);
   7045   }
   7046   int length = (array_length - 1) * separator_length;
   7047   for (int i = 0; i < array_length; i++) {
   7048     Object* element_obj = fixed_array->get(i);
   7049     if (!element_obj->IsString()) {
   7050       // TODO(1161): handle this case.
   7051       return isolate->Throw(isolate->heap()->illegal_argument_string());
   7052     }
   7053     String* element = String::cast(element_obj);
   7054     int increment = element->length();
   7055     if (increment > String::kMaxLength - length) {
   7056       isolate->context()->mark_out_of_memory();
   7057       return Failure::OutOfMemoryException(0x18);
   7058     }
   7059     length += increment;
   7060   }
   7061 
   7062   Object* object;
   7063   { MaybeObject* maybe_object =
   7064         isolate->heap()->AllocateRawTwoByteString(length);
   7065     if (!maybe_object->ToObject(&object)) return maybe_object;
   7066   }
   7067   SeqTwoByteString* answer = SeqTwoByteString::cast(object);
   7068 
   7069   uc16* sink = answer->GetChars();
   7070 #ifdef DEBUG
   7071   uc16* end = sink + length;
   7072 #endif
   7073 
   7074   String* first = String::cast(fixed_array->get(0));
   7075   int first_length = first->length();
   7076   String::WriteToFlat(first, sink, 0, first_length);
   7077   sink += first_length;
   7078 
   7079   for (int i = 1; i < array_length; i++) {
   7080     ASSERT(sink + separator_length <= end);
   7081     String::WriteToFlat(separator, sink, 0, separator_length);
   7082     sink += separator_length;
   7083 
   7084     String* element = String::cast(fixed_array->get(i));
   7085     int element_length = element->length();
   7086     ASSERT(sink + element_length <= end);
   7087     String::WriteToFlat(element, sink, 0, element_length);
   7088     sink += element_length;
   7089   }
   7090   ASSERT(sink == end);
   7091 
   7092   // Use %_FastAsciiArrayJoin instead.
   7093   ASSERT(!answer->IsOneByteRepresentation());
   7094   return answer;
   7095 }
   7096 
   7097 template <typename Char>
   7098 static void JoinSparseArrayWithSeparator(FixedArray* elements,
   7099                                          int elements_length,
   7100                                          uint32_t array_length,
   7101                                          String* separator,
   7102                                          Vector<Char> buffer) {
   7103   int previous_separator_position = 0;
   7104   int separator_length = separator->length();
   7105   int cursor = 0;
   7106   for (int i = 0; i < elements_length; i += 2) {
   7107     int position = NumberToInt32(elements->get(i));
   7108     String* string = String::cast(elements->get(i + 1));
   7109     int string_length = string->length();
   7110     if (string->length() > 0) {
   7111       while (previous_separator_position < position) {
   7112         String::WriteToFlat<Char>(separator, &buffer[cursor],
   7113                                   0, separator_length);
   7114         cursor += separator_length;
   7115         previous_separator_position++;
   7116       }
   7117       String::WriteToFlat<Char>(string, &buffer[cursor],
   7118                                 0, string_length);
   7119       cursor += string->length();
   7120     }
   7121   }
   7122   if (separator_length > 0) {
   7123     // Array length must be representable as a signed 32-bit number,
   7124     // otherwise the total string length would have been too large.
   7125     ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
   7126     int last_array_index = static_cast<int>(array_length - 1);
   7127     while (previous_separator_position < last_array_index) {
   7128       String::WriteToFlat<Char>(separator, &buffer[cursor],
   7129                                 0, separator_length);
   7130       cursor += separator_length;
   7131       previous_separator_position++;
   7132     }
   7133   }
   7134   ASSERT(cursor <= buffer.length());
   7135 }
   7136 
   7137 
   7138 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
   7139   SealHandleScope shs(isolate);
   7140   ASSERT(args.length() == 3);
   7141   CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
   7142   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
   7143   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
   7144   CONVERT_ARG_CHECKED(String, separator, 2);
   7145   // elements_array is fast-mode JSarray of alternating positions
   7146   // (increasing order) and strings.
   7147   // array_length is length of original array (used to add separators);
   7148   // separator is string to put between elements. Assumed to be non-empty.
   7149 
   7150   // Find total length of join result.
   7151   int string_length = 0;
   7152   bool is_ascii = separator->IsOneByteRepresentation();
   7153   int max_string_length;
   7154   if (is_ascii) {
   7155     max_string_length = SeqOneByteString::kMaxLength;
   7156   } else {
   7157     max_string_length = SeqTwoByteString::kMaxLength;
   7158   }
   7159   bool overflow = false;
   7160   CONVERT_NUMBER_CHECKED(int, elements_length,
   7161                          Int32, elements_array->length());
   7162   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
   7163   FixedArray* elements = FixedArray::cast(elements_array->elements());
   7164   for (int i = 0; i < elements_length; i += 2) {
   7165     RUNTIME_ASSERT(elements->get(i)->IsNumber());
   7166     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
   7167     String* string = String::cast(elements->get(i + 1));
   7168     int length = string->length();
   7169     if (is_ascii && !string->IsOneByteRepresentation()) {
   7170       is_ascii = false;
   7171       max_string_length = SeqTwoByteString::kMaxLength;
   7172     }
   7173     if (length > max_string_length ||
   7174         max_string_length - length < string_length) {
   7175       overflow = true;
   7176       break;
   7177     }
   7178     string_length += length;
   7179   }
   7180   int separator_length = separator->length();
   7181   if (!overflow && separator_length > 0) {
   7182     if (array_length <= 0x7fffffffu) {
   7183       int separator_count = static_cast<int>(array_length) - 1;
   7184       int remaining_length = max_string_length - string_length;
   7185       if ((remaining_length / separator_length) >= separator_count) {
   7186         string_length += separator_length * (array_length - 1);
   7187       } else {
   7188         // Not room for the separators within the maximal string length.
   7189         overflow = true;
   7190       }
   7191     } else {
   7192       // Nonempty separator and at least 2^31-1 separators necessary
   7193       // means that the string is too large to create.
   7194       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
   7195       overflow = true;
   7196     }
   7197   }
   7198   if (overflow) {
   7199     // Throw OutOfMemory exception for creating too large a string.
   7200     V8::FatalProcessOutOfMemory("Array join result too large.");
   7201   }
   7202 
   7203   if (is_ascii) {
   7204     MaybeObject* result_allocation =
   7205         isolate->heap()->AllocateRawOneByteString(string_length);
   7206     if (result_allocation->IsFailure()) return result_allocation;
   7207     SeqOneByteString* result_string =
   7208         SeqOneByteString::cast(result_allocation->ToObjectUnchecked());
   7209     JoinSparseArrayWithSeparator<uint8_t>(elements,
   7210                                           elements_length,
   7211                                           array_length,
   7212                                           separator,
   7213                                           Vector<uint8_t>(
   7214                                               result_string->GetChars(),
   7215                                               string_length));
   7216     return result_string;
   7217   } else {
   7218     MaybeObject* result_allocation =
   7219         isolate->heap()->AllocateRawTwoByteString(string_length);
   7220     if (result_allocation->IsFailure()) return result_allocation;
   7221     SeqTwoByteString* result_string =
   7222         SeqTwoByteString::cast(result_allocation->ToObjectUnchecked());
   7223     JoinSparseArrayWithSeparator<uc16>(elements,
   7224                                        elements_length,
   7225                                        array_length,
   7226                                        separator,
   7227                                        Vector<uc16>(result_string->GetChars(),
   7228                                                     string_length));
   7229     return result_string;
   7230   }
   7231 }
   7232 
   7233 
   7234 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberOr) {
   7235   SealHandleScope shs(isolate);
   7236   ASSERT(args.length() == 2);
   7237 
   7238   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7239   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7240   return isolate->heap()->NumberFromInt32(x | y);
   7241 }
   7242 
   7243 
   7244 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAnd) {
   7245   SealHandleScope shs(isolate);
   7246   ASSERT(args.length() == 2);
   7247 
   7248   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7249   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7250   return isolate->heap()->NumberFromInt32(x & y);
   7251 }
   7252 
   7253 
   7254 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) {
   7255   SealHandleScope shs(isolate);
   7256   ASSERT(args.length() == 2);
   7257 
   7258   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7259   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7260   return isolate->heap()->NumberFromInt32(x ^ y);
   7261 }
   7262 
   7263 
   7264 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) {
   7265   SealHandleScope shs(isolate);
   7266   ASSERT(args.length() == 2);
   7267 
   7268   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7269   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7270   return isolate->heap()->NumberFromInt32(x << (y & 0x1f));
   7271 }
   7272 
   7273 
   7274 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShr) {
   7275   SealHandleScope shs(isolate);
   7276   ASSERT(args.length() == 2);
   7277 
   7278   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
   7279   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7280   return isolate->heap()->NumberFromUint32(x >> (y & 0x1f));
   7281 }
   7282 
   7283 
   7284 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSar) {
   7285   SealHandleScope shs(isolate);
   7286   ASSERT(args.length() == 2);
   7287 
   7288   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7289   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7290   return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
   7291 }
   7292 
   7293 
   7294 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
   7295   SealHandleScope shs(isolate);
   7296   ASSERT(args.length() == 2);
   7297 
   7298   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7299   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7300   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
   7301   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
   7302   if (x == y) return Smi::FromInt(EQUAL);
   7303   Object* result;
   7304   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
   7305     result = Smi::FromInt(EQUAL);
   7306   } else {
   7307     result = Smi::FromInt(NOT_EQUAL);
   7308   }
   7309   return result;
   7310 }
   7311 
   7312 
   7313 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
   7314   SealHandleScope shs(isolate);
   7315   ASSERT(args.length() == 2);
   7316 
   7317   CONVERT_ARG_CHECKED(String, x, 0);
   7318   CONVERT_ARG_CHECKED(String, y, 1);
   7319 
   7320   bool not_equal = !x->Equals(y);
   7321   // This is slightly convoluted because the value that signifies
   7322   // equality is 0 and inequality is 1 so we have to negate the result
   7323   // from String::Equals.
   7324   ASSERT(not_equal == 0 || not_equal == 1);
   7325   STATIC_CHECK(EQUAL == 0);
   7326   STATIC_CHECK(NOT_EQUAL == 1);
   7327   return Smi::FromInt(not_equal);
   7328 }
   7329 
   7330 
   7331 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
   7332   SealHandleScope shs(isolate);
   7333   ASSERT(args.length() == 3);
   7334 
   7335   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7336   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7337   if (std::isnan(x) || std::isnan(y)) return args[2];
   7338   if (x == y) return Smi::FromInt(EQUAL);
   7339   if (isless(x, y)) return Smi::FromInt(LESS);
   7340   return Smi::FromInt(GREATER);
   7341 }
   7342 
   7343 
   7344 // Compare two Smis as if they were converted to strings and then
   7345 // compared lexicographically.
   7346 RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
   7347   SealHandleScope shs(isolate);
   7348   ASSERT(args.length() == 2);
   7349   CONVERT_SMI_ARG_CHECKED(x_value, 0);
   7350   CONVERT_SMI_ARG_CHECKED(y_value, 1);
   7351 
   7352   // If the integers are equal so are the string representations.
   7353   if (x_value == y_value) return Smi::FromInt(EQUAL);
   7354 
   7355   // If one of the integers is zero the normal integer order is the
   7356   // same as the lexicographic order of the string representations.
   7357   if (x_value == 0 || y_value == 0)
   7358     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
   7359 
   7360   // If only one of the integers is negative the negative number is
   7361   // smallest because the char code of '-' is less than the char code
   7362   // of any digit.  Otherwise, we make both values positive.
   7363 
   7364   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
   7365   // architectures using 32-bit Smis.
   7366   uint32_t x_scaled = x_value;
   7367   uint32_t y_scaled = y_value;
   7368   if (x_value < 0 || y_value < 0) {
   7369     if (y_value >= 0) return Smi::FromInt(LESS);
   7370     if (x_value >= 0) return Smi::FromInt(GREATER);
   7371     x_scaled = -x_value;
   7372     y_scaled = -y_value;
   7373   }
   7374 
   7375   static const uint32_t kPowersOf10[] = {
   7376     1, 10, 100, 1000, 10*1000, 100*1000,
   7377     1000*1000, 10*1000*1000, 100*1000*1000,
   7378     1000*1000*1000
   7379   };
   7380 
   7381   // If the integers have the same number of decimal digits they can be
   7382   // compared directly as the numeric order is the same as the
   7383   // lexicographic order.  If one integer has fewer digits, it is scaled
   7384   // by some power of 10 to have the same number of digits as the longer
   7385   // integer.  If the scaled integers are equal it means the shorter
   7386   // integer comes first in the lexicographic order.
   7387 
   7388   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
   7389   int x_log2 = IntegerLog2(x_scaled);
   7390   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
   7391   x_log10 -= x_scaled < kPowersOf10[x_log10];
   7392 
   7393   int y_log2 = IntegerLog2(y_scaled);
   7394   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
   7395   y_log10 -= y_scaled < kPowersOf10[y_log10];
   7396 
   7397   int tie = EQUAL;
   7398 
   7399   if (x_log10 < y_log10) {
   7400     // X has fewer digits.  We would like to simply scale up X but that
   7401     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
   7402     // be scaled up to 9_000_000_000. So we scale up by the next
   7403     // smallest power and scale down Y to drop one digit. It is OK to
   7404     // drop one digit from the longer integer since the final digit is
   7405     // past the length of the shorter integer.
   7406     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
   7407     y_scaled /= 10;
   7408     tie = LESS;
   7409   } else if (y_log10 < x_log10) {
   7410     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
   7411     x_scaled /= 10;
   7412     tie = GREATER;
   7413   }
   7414 
   7415   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
   7416   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
   7417   return Smi::FromInt(tie);
   7418 }
   7419 
   7420 
   7421 static Object* StringCharacterStreamCompare(RuntimeState* state,
   7422                                         String* x,
   7423                                         String* y) {
   7424   StringCharacterStream stream_x(x, state->string_iterator_compare_x());
   7425   StringCharacterStream stream_y(y, state->string_iterator_compare_y());
   7426   while (stream_x.HasMore() && stream_y.HasMore()) {
   7427     int d = stream_x.GetNext() - stream_y.GetNext();
   7428     if (d < 0) return Smi::FromInt(LESS);
   7429     else if (d > 0) return Smi::FromInt(GREATER);
   7430   }
   7431 
   7432   // x is (non-trivial) prefix of y:
   7433   if (stream_y.HasMore()) return Smi::FromInt(LESS);
   7434   // y is prefix of x:
   7435   return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL);
   7436 }
   7437 
   7438 
   7439 static Object* FlatStringCompare(String* x, String* y) {
   7440   ASSERT(x->IsFlat());
   7441   ASSERT(y->IsFlat());
   7442   Object* equal_prefix_result = Smi::FromInt(EQUAL);
   7443   int prefix_length = x->length();
   7444   if (y->length() < prefix_length) {
   7445     prefix_length = y->length();
   7446     equal_prefix_result = Smi::FromInt(GREATER);
   7447   } else if (y->length() > prefix_length) {
   7448     equal_prefix_result = Smi::FromInt(LESS);
   7449   }
   7450   int r;
   7451   DisallowHeapAllocation no_gc;
   7452   String::FlatContent x_content = x->GetFlatContent();
   7453   String::FlatContent y_content = y->GetFlatContent();
   7454   if (x_content.IsAscii()) {
   7455     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
   7456     if (y_content.IsAscii()) {
   7457       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7458       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7459     } else {
   7460       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7461       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7462     }
   7463   } else {
   7464     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   7465     if (y_content.IsAscii()) {
   7466       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
   7467       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7468     } else {
   7469       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7470       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7471     }
   7472   }
   7473   Object* result;
   7474   if (r == 0) {
   7475     result = equal_prefix_result;
   7476   } else {
   7477     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
   7478   }
   7479   ASSERT(result ==
   7480       StringCharacterStreamCompare(Isolate::Current()->runtime_state(), x, y));
   7481   return result;
   7482 }
   7483 
   7484 
   7485 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) {
   7486   SealHandleScope shs(isolate);
   7487   ASSERT(args.length() == 2);
   7488 
   7489   CONVERT_ARG_CHECKED(String, x, 0);
   7490   CONVERT_ARG_CHECKED(String, y, 1);
   7491 
   7492   isolate->counters()->string_compare_runtime()->Increment();
   7493 
   7494   // A few fast case tests before we flatten.
   7495   if (x == y) return Smi::FromInt(EQUAL);
   7496   if (y->length() == 0) {
   7497     if (x->length() == 0) return Smi::FromInt(EQUAL);
   7498     return Smi::FromInt(GREATER);
   7499   } else if (x->length() == 0) {
   7500     return Smi::FromInt(LESS);
   7501   }
   7502 
   7503   int d = x->Get(0) - y->Get(0);
   7504   if (d < 0) return Smi::FromInt(LESS);
   7505   else if (d > 0) return Smi::FromInt(GREATER);
   7506 
   7507   Object* obj;
   7508   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
   7509     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7510   }
   7511   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
   7512     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7513   }
   7514 
   7515   return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
   7516       : StringCharacterStreamCompare(isolate->runtime_state(), x, y);
   7517 }
   7518 
   7519 
   7520 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
   7521   SealHandleScope shs(isolate);
   7522   ASSERT(args.length() == 1);
   7523   isolate->counters()->math_acos()->Increment();
   7524 
   7525   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7526   return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
   7527 }
   7528 
   7529 
   7530 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
   7531   SealHandleScope shs(isolate);
   7532   ASSERT(args.length() == 1);
   7533   isolate->counters()->math_asin()->Increment();
   7534 
   7535   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7536   return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
   7537 }
   7538 
   7539 
   7540 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
   7541   SealHandleScope shs(isolate);
   7542   ASSERT(args.length() == 1);
   7543   isolate->counters()->math_atan()->Increment();
   7544 
   7545   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7546   return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
   7547 }
   7548 
   7549 
   7550 static const double kPiDividedBy4 = 0.78539816339744830962;
   7551 
   7552 
   7553 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
   7554   SealHandleScope shs(isolate);
   7555   ASSERT(args.length() == 2);
   7556   isolate->counters()->math_atan2()->Increment();
   7557 
   7558   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7559   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7560   double result;
   7561   if (std::isinf(x) && std::isinf(y)) {
   7562     // Make sure that the result in case of two infinite arguments
   7563     // is a multiple of Pi / 4. The sign of the result is determined
   7564     // by the first argument (x) and the sign of the second argument
   7565     // determines the multiplier: one or three.
   7566     int multiplier = (x < 0) ? -1 : 1;
   7567     if (y < 0) multiplier *= 3;
   7568     result = multiplier * kPiDividedBy4;
   7569   } else {
   7570     result = atan2(x, y);
   7571   }
   7572   return isolate->heap()->AllocateHeapNumber(result);
   7573 }
   7574 
   7575 
   7576 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
   7577   SealHandleScope shs(isolate);
   7578   ASSERT(args.length() == 1);
   7579   isolate->counters()->math_ceil()->Increment();
   7580 
   7581   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7582   return isolate->heap()->NumberFromDouble(ceiling(x));
   7583 }
   7584 
   7585 
   7586 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
   7587   SealHandleScope shs(isolate);
   7588   ASSERT(args.length() == 1);
   7589   isolate->counters()->math_cos()->Increment();
   7590 
   7591   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7592   return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
   7593 }
   7594 
   7595 
   7596 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
   7597   SealHandleScope shs(isolate);
   7598   ASSERT(args.length() == 1);
   7599   isolate->counters()->math_exp()->Increment();
   7600 
   7601   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7602   lazily_initialize_fast_exp();
   7603   return isolate->heap()->NumberFromDouble(fast_exp(x));
   7604 }
   7605 
   7606 
   7607 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
   7608   SealHandleScope shs(isolate);
   7609   ASSERT(args.length() == 1);
   7610   isolate->counters()->math_floor()->Increment();
   7611 
   7612   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7613   return isolate->heap()->NumberFromDouble(floor(x));
   7614 }
   7615 
   7616 
   7617 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
   7618   SealHandleScope shs(isolate);
   7619   ASSERT(args.length() == 1);
   7620   isolate->counters()->math_log()->Increment();
   7621 
   7622   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7623   return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
   7624 }
   7625 
   7626 
   7627 // Slow version of Math.pow.  We check for fast paths for special cases.
   7628 // Used if SSE2/VFP3 is not available.
   7629 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
   7630   SealHandleScope shs(isolate);
   7631   ASSERT(args.length() == 2);
   7632   isolate->counters()->math_pow()->Increment();
   7633 
   7634   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7635 
   7636   // If the second argument is a smi, it is much faster to call the
   7637   // custom powi() function than the generic pow().
   7638   if (args[1]->IsSmi()) {
   7639     int y = args.smi_at(1);
   7640     return isolate->heap()->NumberFromDouble(power_double_int(x, y));
   7641   }
   7642 
   7643   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7644   double result = power_helper(x, y);
   7645   if (std::isnan(result)) return isolate->heap()->nan_value();
   7646   return isolate->heap()->AllocateHeapNumber(result);
   7647 }
   7648 
   7649 
   7650 // Fast version of Math.pow if we know that y is not an integer and y is not
   7651 // -0.5 or 0.5.  Used as slow case from full codegen.
   7652 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
   7653   SealHandleScope shs(isolate);
   7654   ASSERT(args.length() == 2);
   7655   isolate->counters()->math_pow()->Increment();
   7656 
   7657   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7658   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7659   if (y == 0) {
   7660     return Smi::FromInt(1);
   7661   } else {
   7662     double result = power_double_double(x, y);
   7663     if (std::isnan(result)) return isolate->heap()->nan_value();
   7664     return isolate->heap()->AllocateHeapNumber(result);
   7665   }
   7666 }
   7667 
   7668 
   7669 RUNTIME_FUNCTION(MaybeObject*, Runtime_RoundNumber) {
   7670   SealHandleScope shs(isolate);
   7671   ASSERT(args.length() == 1);
   7672   isolate->counters()->math_round()->Increment();
   7673 
   7674   if (!args[0]->IsHeapNumber()) {
   7675     // Must be smi. Return the argument unchanged for all the other types
   7676     // to make fuzz-natives test happy.
   7677     return args[0];
   7678   }
   7679 
   7680   HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
   7681 
   7682   double value = number->value();
   7683   int exponent = number->get_exponent();
   7684   int sign = number->get_sign();
   7685 
   7686   if (exponent < -1) {
   7687     // Number in range ]-0.5..0.5[. These always round to +/-zero.
   7688     if (sign) return isolate->heap()->minus_zero_value();
   7689     return Smi::FromInt(0);
   7690   }
   7691 
   7692   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
   7693   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
   7694   // argument holds for 32-bit smis).
   7695   if (!sign && exponent < kSmiValueSize - 2) {
   7696     return Smi::FromInt(static_cast<int>(value + 0.5));
   7697   }
   7698 
   7699   // If the magnitude is big enough, there's no place for fraction part. If we
   7700   // try to add 0.5 to this number, 1.0 will be added instead.
   7701   if (exponent >= 52) {
   7702     return number;
   7703   }
   7704 
   7705   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
   7706 
   7707   // Do not call NumberFromDouble() to avoid extra checks.
   7708   return isolate->heap()->AllocateHeapNumber(floor(value + 0.5));
   7709 }
   7710 
   7711 
   7712 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
   7713   SealHandleScope shs(isolate);
   7714   ASSERT(args.length() == 1);
   7715   isolate->counters()->math_sin()->Increment();
   7716 
   7717   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7718   return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
   7719 }
   7720 
   7721 
   7722 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
   7723   SealHandleScope shs(isolate);
   7724   ASSERT(args.length() == 1);
   7725   isolate->counters()->math_sqrt()->Increment();
   7726 
   7727   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7728   return isolate->heap()->AllocateHeapNumber(fast_sqrt(x));
   7729 }
   7730 
   7731 
   7732 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
   7733   SealHandleScope shs(isolate);
   7734   ASSERT(args.length() == 1);
   7735   isolate->counters()->math_tan()->Increment();
   7736 
   7737   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7738   return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
   7739 }
   7740 
   7741 
   7742 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
   7743   SealHandleScope shs(isolate);
   7744   ASSERT(args.length() == 2);
   7745 
   7746   CONVERT_SMI_ARG_CHECKED(year, 0);
   7747   CONVERT_SMI_ARG_CHECKED(month, 1);
   7748 
   7749   return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
   7750 }
   7751 
   7752 
   7753 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
   7754   HandleScope scope(isolate);
   7755   ASSERT(args.length() == 3);
   7756 
   7757   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
   7758   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
   7759   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
   7760 
   7761   DateCache* date_cache = isolate->date_cache();
   7762 
   7763   Object* value = NULL;
   7764   bool is_value_nan = false;
   7765   if (std::isnan(time)) {
   7766     value = isolate->heap()->nan_value();
   7767     is_value_nan = true;
   7768   } else if (!is_utc &&
   7769              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
   7770               time > DateCache::kMaxTimeBeforeUTCInMs)) {
   7771     value = isolate->heap()->nan_value();
   7772     is_value_nan = true;
   7773   } else {
   7774     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
   7775     if (time < -DateCache::kMaxTimeInMs ||
   7776         time > DateCache::kMaxTimeInMs) {
   7777       value = isolate->heap()->nan_value();
   7778       is_value_nan = true;
   7779     } else  {
   7780       MaybeObject* maybe_result =
   7781           isolate->heap()->AllocateHeapNumber(DoubleToInteger(time));
   7782       if (!maybe_result->ToObject(&value)) return maybe_result;
   7783     }
   7784   }
   7785   date->SetValue(value, is_value_nan);
   7786   return value;
   7787 }
   7788 
   7789 
   7790 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
   7791   HandleScope scope(isolate);
   7792   ASSERT(args.length() == 3);
   7793 
   7794   Handle<JSFunction> callee = args.at<JSFunction>(0);
   7795   Object** parameters = reinterpret_cast<Object**>(args[1]);
   7796   const int argument_count = Smi::cast(args[2])->value();
   7797 
   7798   Handle<JSObject> result =
   7799       isolate->factory()->NewArgumentsObject(callee, argument_count);
   7800   // Allocate the elements if needed.
   7801   int parameter_count = callee->shared()->formal_parameter_count();
   7802   if (argument_count > 0) {
   7803     if (parameter_count > 0) {
   7804       int mapped_count = Min(argument_count, parameter_count);
   7805       Handle<FixedArray> parameter_map =
   7806           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
   7807       parameter_map->set_map(
   7808           isolate->heap()->non_strict_arguments_elements_map());
   7809 
   7810       Handle<Map> old_map(result->map());
   7811       Handle<Map> new_map = isolate->factory()->CopyMap(old_map);
   7812       new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
   7813 
   7814       result->set_map(*new_map);
   7815       result->set_elements(*parameter_map);
   7816 
   7817       // Store the context and the arguments array at the beginning of the
   7818       // parameter map.
   7819       Handle<Context> context(isolate->context());
   7820       Handle<FixedArray> arguments =
   7821           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   7822       parameter_map->set(0, *context);
   7823       parameter_map->set(1, *arguments);
   7824 
   7825       // Loop over the actual parameters backwards.
   7826       int index = argument_count - 1;
   7827       while (index >= mapped_count) {
   7828         // These go directly in the arguments array and have no
   7829         // corresponding slot in the parameter map.
   7830         arguments->set(index, *(parameters - index - 1));
   7831         --index;
   7832       }
   7833 
   7834       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
   7835       while (index >= 0) {
   7836         // Detect duplicate names to the right in the parameter list.
   7837         Handle<String> name(scope_info->ParameterName(index));
   7838         int context_local_count = scope_info->ContextLocalCount();
   7839         bool duplicate = false;
   7840         for (int j = index + 1; j < parameter_count; ++j) {
   7841           if (scope_info->ParameterName(j) == *name) {
   7842             duplicate = true;
   7843             break;
   7844           }
   7845         }
   7846 
   7847         if (duplicate) {
   7848           // This goes directly in the arguments array with a hole in the
   7849           // parameter map.
   7850           arguments->set(index, *(parameters - index - 1));
   7851           parameter_map->set_the_hole(index + 2);
   7852         } else {
   7853           // The context index goes in the parameter map with a hole in the
   7854           // arguments array.
   7855           int context_index = -1;
   7856           for (int j = 0; j < context_local_count; ++j) {
   7857             if (scope_info->ContextLocalName(j) == *name) {
   7858               context_index = j;
   7859               break;
   7860             }
   7861           }
   7862           ASSERT(context_index >= 0);
   7863           arguments->set_the_hole(index);
   7864           parameter_map->set(index + 2, Smi::FromInt(
   7865               Context::MIN_CONTEXT_SLOTS + context_index));
   7866         }
   7867 
   7868         --index;
   7869       }
   7870     } else {
   7871       // If there is no aliasing, the arguments object elements are not
   7872       // special in any way.
   7873       Handle<FixedArray> elements =
   7874           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   7875       result->set_elements(*elements);
   7876       for (int i = 0; i < argument_count; ++i) {
   7877         elements->set(i, *(parameters - i - 1));
   7878       }
   7879     }
   7880   }
   7881   return *result;
   7882 }
   7883 
   7884 
   7885 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
   7886   SealHandleScope shs(isolate);
   7887   ASSERT(args.length() == 3);
   7888 
   7889   JSFunction* callee = JSFunction::cast(args[0]);
   7890   Object** parameters = reinterpret_cast<Object**>(args[1]);
   7891   const int length = args.smi_at(2);
   7892 
   7893   Object* result;
   7894   { MaybeObject* maybe_result =
   7895         isolate->heap()->AllocateArgumentsObject(callee, length);
   7896     if (!maybe_result->ToObject(&result)) return maybe_result;
   7897   }
   7898   // Allocate the elements if needed.
   7899   if (length > 0) {
   7900     // Allocate the fixed array.
   7901     Object* obj;
   7902     { MaybeObject* maybe_obj = isolate->heap()->AllocateRawFixedArray(length);
   7903       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7904     }
   7905 
   7906     DisallowHeapAllocation no_gc;
   7907     FixedArray* array = reinterpret_cast<FixedArray*>(obj);
   7908     array->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
   7909     array->set_length(length);
   7910 
   7911     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   7912     for (int i = 0; i < length; i++) {
   7913       array->set(i, *--parameters, mode);
   7914     }
   7915     JSObject::cast(result)->set_elements(FixedArray::cast(obj));
   7916   }
   7917   return result;
   7918 }
   7919 
   7920 
   7921 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
   7922   HandleScope scope(isolate);
   7923   ASSERT(args.length() == 3);
   7924   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   7925   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
   7926   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
   7927 
   7928   // The caller ensures that we pretenure closures that are assigned
   7929   // directly to properties.
   7930   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   7931   Handle<JSFunction> result =
   7932       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   7933                                                             context,
   7934                                                             pretenure_flag);
   7935   return *result;
   7936 }
   7937 
   7938 
   7939 // Find the arguments of the JavaScript function invocation that called
   7940 // into C++ code. Collect these in a newly allocated array of handles (possibly
   7941 // prefixed by a number of empty handles).
   7942 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
   7943     Isolate* isolate,
   7944     int prefix_argc,
   7945     int* total_argc) {
   7946   // Find frame containing arguments passed to the caller.
   7947   JavaScriptFrameIterator it(isolate);
   7948   JavaScriptFrame* frame = it.frame();
   7949   List<JSFunction*> functions(2);
   7950   frame->GetFunctions(&functions);
   7951   if (functions.length() > 1) {
   7952     int inlined_jsframe_index = functions.length() - 1;
   7953     JSFunction* inlined_function = functions[inlined_jsframe_index];
   7954     Vector<SlotRef> args_slots =
   7955         SlotRef::ComputeSlotMappingForArguments(
   7956             frame,
   7957             inlined_jsframe_index,
   7958             inlined_function->shared()->formal_parameter_count());
   7959 
   7960     int args_count = args_slots.length();
   7961 
   7962     *total_argc = prefix_argc + args_count;
   7963     SmartArrayPointer<Handle<Object> > param_data(
   7964         NewArray<Handle<Object> >(*total_argc));
   7965     for (int i = 0; i < args_count; i++) {
   7966       Handle<Object> val = args_slots[i].GetValue(isolate);
   7967       param_data[prefix_argc + i] = val;
   7968     }
   7969 
   7970     args_slots.Dispose();
   7971 
   7972     return param_data;
   7973   } else {
   7974     it.AdvanceToArgumentsFrame();
   7975     frame = it.frame();
   7976     int args_count = frame->ComputeParametersCount();
   7977 
   7978     *total_argc = prefix_argc + args_count;
   7979     SmartArrayPointer<Handle<Object> > param_data(
   7980         NewArray<Handle<Object> >(*total_argc));
   7981     for (int i = 0; i < args_count; i++) {
   7982       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
   7983       param_data[prefix_argc + i] = val;
   7984     }
   7985     return param_data;
   7986   }
   7987 }
   7988 
   7989 
   7990 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
   7991   HandleScope scope(isolate);
   7992   ASSERT(args.length() == 4);
   7993   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
   7994   RUNTIME_ASSERT(args[3]->IsNumber());
   7995   Handle<Object> bindee = args.at<Object>(1);
   7996 
   7997   // TODO(lrn): Create bound function in C++ code from premade shared info.
   7998   bound_function->shared()->set_bound(true);
   7999   // Get all arguments of calling function (Function.prototype.bind).
   8000   int argc = 0;
   8001   SmartArrayPointer<Handle<Object> > arguments =
   8002       GetCallerArguments(isolate, 0, &argc);
   8003   // Don't count the this-arg.
   8004   if (argc > 0) {
   8005     ASSERT(*arguments[0] == args[2]);
   8006     argc--;
   8007   } else {
   8008     ASSERT(args[2]->IsUndefined());
   8009   }
   8010   // Initialize array of bindings (function, this, and any existing arguments
   8011   // if the function was already bound).
   8012   Handle<FixedArray> new_bindings;
   8013   int i;
   8014   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
   8015     Handle<FixedArray> old_bindings(
   8016         JSFunction::cast(*bindee)->function_bindings());
   8017     new_bindings =
   8018         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
   8019     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
   8020                             isolate);
   8021     i = 0;
   8022     for (int n = old_bindings->length(); i < n; i++) {
   8023       new_bindings->set(i, old_bindings->get(i));
   8024     }
   8025   } else {
   8026     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
   8027     new_bindings = isolate->factory()->NewFixedArray(array_size);
   8028     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
   8029     new_bindings->set(JSFunction::kBoundThisIndex, args[2]);
   8030     i = 2;
   8031   }
   8032   // Copy arguments, skipping the first which is "this_arg".
   8033   for (int j = 0; j < argc; j++, i++) {
   8034     new_bindings->set(i, *arguments[j + 1]);
   8035   }
   8036   new_bindings->set_map_no_write_barrier(
   8037       isolate->heap()->fixed_cow_array_map());
   8038   bound_function->set_function_bindings(*new_bindings);
   8039 
   8040   // Update length.
   8041   Handle<String> length_string = isolate->factory()->length_string();
   8042   Handle<Object> new_length(args.at<Object>(3));
   8043   PropertyAttributes attr =
   8044       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
   8045   ForceSetProperty(bound_function, length_string, new_length, attr);
   8046   return *bound_function;
   8047 }
   8048 
   8049 
   8050 RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
   8051   HandleScope handles(isolate);
   8052   ASSERT(args.length() == 1);
   8053   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
   8054   if (callable->IsJSFunction()) {
   8055     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
   8056     if (function->shared()->bound()) {
   8057       Handle<FixedArray> bindings(function->function_bindings());
   8058       ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
   8059       return *isolate->factory()->NewJSArrayWithElements(bindings);
   8060     }
   8061   }
   8062   return isolate->heap()->undefined_value();
   8063 }
   8064 
   8065 
   8066 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
   8067   HandleScope scope(isolate);
   8068   ASSERT(args.length() == 1);
   8069   // First argument is a function to use as a constructor.
   8070   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8071   RUNTIME_ASSERT(function->shared()->bound());
   8072 
   8073   // The argument is a bound function. Extract its bound arguments
   8074   // and callable.
   8075   Handle<FixedArray> bound_args =
   8076       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
   8077   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
   8078   Handle<Object> bound_function(
   8079       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
   8080       isolate);
   8081   ASSERT(!bound_function->IsJSFunction() ||
   8082          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
   8083 
   8084   int total_argc = 0;
   8085   SmartArrayPointer<Handle<Object> > param_data =
   8086       GetCallerArguments(isolate, bound_argc, &total_argc);
   8087   for (int i = 0; i < bound_argc; i++) {
   8088     param_data[i] = Handle<Object>(bound_args->get(
   8089         JSFunction::kBoundArgumentsStartIndex + i), isolate);
   8090   }
   8091 
   8092   if (!bound_function->IsJSFunction()) {
   8093     bool exception_thrown;
   8094     bound_function = Execution::TryGetConstructorDelegate(bound_function,
   8095                                                           &exception_thrown);
   8096     if (exception_thrown) return Failure::Exception();
   8097   }
   8098   ASSERT(bound_function->IsJSFunction());
   8099 
   8100   bool exception = false;
   8101   Handle<Object> result =
   8102       Execution::New(Handle<JSFunction>::cast(bound_function),
   8103                      total_argc, *param_data, &exception);
   8104   if (exception) {
   8105     return Failure::Exception();
   8106   }
   8107   ASSERT(!result.is_null());
   8108   return *result;
   8109 }
   8110 
   8111 
   8112 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
   8113   HandleScope scope(isolate);
   8114   ASSERT(args.length() == 1);
   8115 
   8116   Handle<Object> constructor = args.at<Object>(0);
   8117 
   8118   // If the constructor isn't a proper function we throw a type error.
   8119   if (!constructor->IsJSFunction()) {
   8120     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8121     Handle<Object> type_error =
   8122         isolate->factory()->NewTypeError("not_constructor", arguments);
   8123     return isolate->Throw(*type_error);
   8124   }
   8125 
   8126   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
   8127 
   8128   // If function should not have prototype, construction is not allowed. In this
   8129   // case generated code bailouts here, since function has no initial_map.
   8130   if (!function->should_have_prototype() && !function->shared()->bound()) {
   8131     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   8132     Handle<Object> type_error =
   8133         isolate->factory()->NewTypeError("not_constructor", arguments);
   8134     return isolate->Throw(*type_error);
   8135   }
   8136 
   8137 #ifdef ENABLE_DEBUGGER_SUPPORT
   8138   Debug* debug = isolate->debug();
   8139   // Handle stepping into constructors if step into is active.
   8140   if (debug->StepInActive()) {
   8141     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
   8142   }
   8143 #endif
   8144 
   8145   if (function->has_initial_map()) {
   8146     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
   8147       // The 'Function' function ignores the receiver object when
   8148       // called using 'new' and creates a new JSFunction object that
   8149       // is returned.  The receiver object is only used for error
   8150       // reporting if an error occurs when constructing the new
   8151       // JSFunction. Factory::NewJSObject() should not be used to
   8152       // allocate JSFunctions since it does not properly initialize
   8153       // the shared part of the function. Since the receiver is
   8154       // ignored anyway, we use the global object as the receiver
   8155       // instead of a new JSFunction object. This way, errors are
   8156       // reported the same way whether or not 'Function' is called
   8157       // using 'new'.
   8158       return isolate->context()->global_object();
   8159     }
   8160   }
   8161 
   8162   // The function should be compiled for the optimization hints to be
   8163   // available.
   8164   JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION);
   8165 
   8166   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
   8167   if (!function->has_initial_map() &&
   8168       shared->IsInobjectSlackTrackingInProgress()) {
   8169     // The tracking is already in progress for another function. We can only
   8170     // track one initial_map at a time, so we force the completion before the
   8171     // function is called as a constructor for the first time.
   8172     shared->CompleteInobjectSlackTracking();
   8173   }
   8174 
   8175   Handle<JSObject> result = isolate->factory()->NewJSObject(function);
   8176   RETURN_IF_EMPTY_HANDLE(isolate, result);
   8177 
   8178   isolate->counters()->constructed_objects()->Increment();
   8179   isolate->counters()->constructed_objects_runtime()->Increment();
   8180 
   8181   return *result;
   8182 }
   8183 
   8184 
   8185 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) {
   8186   HandleScope scope(isolate);
   8187   ASSERT(args.length() == 1);
   8188 
   8189   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8190   function->shared()->CompleteInobjectSlackTracking();
   8191 
   8192   return isolate->heap()->undefined_value();
   8193 }
   8194 
   8195 
   8196 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
   8197   HandleScope scope(isolate);
   8198   ASSERT(args.length() == 1);
   8199 
   8200   Handle<JSFunction> function = args.at<JSFunction>(0);
   8201 #ifdef DEBUG
   8202   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
   8203     PrintF("[lazy: ");
   8204     function->PrintName();
   8205     PrintF("]\n");
   8206   }
   8207 #endif
   8208 
   8209   // Compile the target function.
   8210   ASSERT(!function->is_compiled());
   8211   if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) {
   8212     return Failure::Exception();
   8213   }
   8214 
   8215   // All done. Return the compiled code.
   8216   ASSERT(function->is_compiled());
   8217   return function->code();
   8218 }
   8219 
   8220 
   8221 bool AllowOptimization(Isolate* isolate, Handle<JSFunction> function) {
   8222   // If the function is not compiled ignore the lazy
   8223   // recompilation. This can happen if the debugger is activated and
   8224   // the function is returned to the not compiled state.
   8225   if (!function->shared()->is_compiled()) return false;
   8226 
   8227   // If the function is not optimizable or debugger is active continue using the
   8228   // code from the full compiler.
   8229   if (!FLAG_crankshaft ||
   8230       function->shared()->optimization_disabled() ||
   8231       isolate->DebuggerHasBreakPoints()) {
   8232     if (FLAG_trace_opt) {
   8233       PrintF("[failed to optimize ");
   8234       function->PrintName();
   8235       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
   8236           function->shared()->optimization_disabled() ? "F" : "T",
   8237           isolate->DebuggerHasBreakPoints() ? "T" : "F");
   8238     }
   8239     return false;
   8240   }
   8241   return true;
   8242 }
   8243 
   8244 
   8245 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
   8246   HandleScope scope(isolate);
   8247   ASSERT(args.length() == 1);
   8248   Handle<JSFunction> function = args.at<JSFunction>(0);
   8249 
   8250   if (!AllowOptimization(isolate, function)) {
   8251     function->ReplaceCode(function->shared()->code());
   8252     return function->code();
   8253   }
   8254   function->shared()->code()->set_profiler_ticks(0);
   8255   if (JSFunction::CompileOptimized(function,
   8256                                    BailoutId::None(),
   8257                                    CLEAR_EXCEPTION)) {
   8258     return function->code();
   8259   }
   8260   if (FLAG_trace_opt) {
   8261     PrintF("[failed to optimize ");
   8262     function->PrintName();
   8263     PrintF(": optimized compilation failed]\n");
   8264   }
   8265   function->ReplaceCode(function->shared()->code());
   8266   return function->code();
   8267 }
   8268 
   8269 
   8270 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParallelRecompile) {
   8271   HandleScope handle_scope(isolate);
   8272   ASSERT(args.length() == 1);
   8273   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8274   if (!AllowOptimization(isolate, function)) {
   8275     function->ReplaceCode(function->shared()->code());
   8276     return isolate->heap()->undefined_value();
   8277   }
   8278   function->shared()->code()->set_profiler_ticks(0);
   8279   ASSERT(FLAG_parallel_recompilation);
   8280   Compiler::RecompileParallel(function);
   8281   return isolate->heap()->undefined_value();
   8282 }
   8283 
   8284 
   8285 RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) {
   8286   HandleScope handle_scope(isolate);
   8287   ASSERT(args.length() == 1);
   8288   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8289   ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation);
   8290   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   8291   return function->code();
   8292 }
   8293 
   8294 
   8295 class ActivationsFinder : public ThreadVisitor {
   8296  public:
   8297   Code* code_;
   8298   bool has_code_activations_;
   8299 
   8300   explicit ActivationsFinder(Code* code)
   8301     : code_(code),
   8302       has_code_activations_(false) { }
   8303 
   8304   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
   8305     JavaScriptFrameIterator it(isolate, top);
   8306     VisitFrames(&it);
   8307   }
   8308 
   8309   void VisitFrames(JavaScriptFrameIterator* it) {
   8310     for (; !it->done(); it->Advance()) {
   8311       JavaScriptFrame* frame = it->frame();
   8312       if (code_->contains(frame->pc())) has_code_activations_ = true;
   8313     }
   8314   }
   8315 };
   8316 
   8317 
   8318 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) {
   8319   HandleScope scope(isolate);
   8320   ASSERT(args.length() == 0);
   8321   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8322   ASSERT(AllowHeapAllocation::IsAllowed());
   8323   delete deoptimizer;
   8324   return isolate->heap()->undefined_value();
   8325 }
   8326 
   8327 
   8328 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
   8329   HandleScope scope(isolate);
   8330   ASSERT(args.length() == 1);
   8331   RUNTIME_ASSERT(args[0]->IsSmi());
   8332   Deoptimizer::BailoutType type =
   8333       static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
   8334   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8335   ASSERT(AllowHeapAllocation::IsAllowed());
   8336 
   8337   Handle<JSFunction> function = deoptimizer->function();
   8338   Handle<Code> optimized_code = deoptimizer->compiled_code();
   8339 
   8340   ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
   8341   ASSERT(type == deoptimizer->bailout_type());
   8342 
   8343   // Make sure to materialize objects before causing any allocation.
   8344   JavaScriptFrameIterator it(isolate);
   8345   deoptimizer->MaterializeHeapObjects(&it);
   8346   delete deoptimizer;
   8347 
   8348   JavaScriptFrame* frame = it.frame();
   8349   RUNTIME_ASSERT(frame->function()->IsJSFunction());
   8350 
   8351   // Avoid doing too much work when running with --always-opt and keep
   8352   // the optimized code around.
   8353   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
   8354     return isolate->heap()->undefined_value();
   8355   }
   8356 
   8357   // Search for other activations of the same function and code.
   8358   ActivationsFinder activations_finder(*optimized_code);
   8359   activations_finder.VisitFrames(&it);
   8360   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
   8361 
   8362   if (!activations_finder.has_code_activations_) {
   8363     if (function->code() == *optimized_code) {
   8364       if (FLAG_trace_deopt) {
   8365         PrintF("[removing optimized code for: ");
   8366         function->PrintName();
   8367         PrintF("]\n");
   8368       }
   8369       function->ReplaceCode(function->shared()->code());
   8370     }
   8371   } else {
   8372     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
   8373     // unconditionally if the code is not already marked for deoptimization.
   8374     // If there is an index by shared function info, all the better.
   8375     Deoptimizer::DeoptimizeFunction(*function);
   8376   }
   8377   // Evict optimized code for this function from the cache so that it doesn't
   8378   // get used for new closures.
   8379   function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
   8380                                                 "notify deoptimized");
   8381 
   8382   return isolate->heap()->undefined_value();
   8383 }
   8384 
   8385 
   8386 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyOSR) {
   8387   SealHandleScope shs(isolate);
   8388   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8389   delete deoptimizer;
   8390   return isolate->heap()->undefined_value();
   8391 }
   8392 
   8393 
   8394 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
   8395   HandleScope scope(isolate);
   8396   ASSERT(args.length() == 1);
   8397   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8398   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
   8399 
   8400   Deoptimizer::DeoptimizeFunction(*function);
   8401 
   8402   return isolate->heap()->undefined_value();
   8403 }
   8404 
   8405 
   8406 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearFunctionTypeFeedback) {
   8407   HandleScope scope(isolate);
   8408   ASSERT(args.length() == 1);
   8409   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8410   Code* unoptimized = function->shared()->code();
   8411   if (unoptimized->kind() == Code::FUNCTION) {
   8412     unoptimized->ClearInlineCaches();
   8413     unoptimized->ClearTypeFeedbackCells(isolate->heap());
   8414   }
   8415   return isolate->heap()->undefined_value();
   8416 }
   8417 
   8418 
   8419 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
   8420   SealHandleScope shs(isolate);
   8421 #if defined(USE_SIMULATOR)
   8422   return isolate->heap()->true_value();
   8423 #else
   8424   return isolate->heap()->false_value();
   8425 #endif
   8426 }
   8427 
   8428 
   8429 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsParallelRecompilationSupported) {
   8430   HandleScope scope(isolate);
   8431   return FLAG_parallel_recompilation
   8432       ? isolate->heap()->true_value() : isolate->heap()->false_value();
   8433 }
   8434 
   8435 
   8436 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
   8437   HandleScope scope(isolate);
   8438   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8439   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8440 
   8441   if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
   8442   function->MarkForLazyRecompilation();
   8443 
   8444   Code* unoptimized = function->shared()->code();
   8445   if (args.length() == 2 &&
   8446       unoptimized->kind() == Code::FUNCTION) {
   8447     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   8448     if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
   8449       for (int i = 0; i <= Code::kMaxLoopNestingMarker; i++) {
   8450         unoptimized->set_allow_osr_at_loop_nesting_level(i);
   8451         isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
   8452       }
   8453     } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) {
   8454       function->MarkForParallelRecompilation();
   8455     }
   8456   }
   8457 
   8458   return isolate->heap()->undefined_value();
   8459 }
   8460 
   8461 
   8462 RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimizeFunction) {
   8463   HandleScope scope(isolate);
   8464   ASSERT(args.length() == 1);
   8465   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8466   ASSERT(!function->IsOptimized());
   8467   function->shared()->set_optimization_disabled(true);
   8468   return isolate->heap()->undefined_value();
   8469 }
   8470 
   8471 
   8472 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
   8473   HandleScope scope(isolate);
   8474   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8475   if (!V8::UseCrankshaft()) {
   8476     return Smi::FromInt(4);  // 4 == "never".
   8477   }
   8478   bool sync_with_compiler_thread = true;
   8479   if (args.length() == 2) {
   8480     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
   8481     if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
   8482       sync_with_compiler_thread = false;
   8483     }
   8484   }
   8485   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8486   if (FLAG_parallel_recompilation && sync_with_compiler_thread) {
   8487     while (function->IsInRecompileQueue() ||
   8488            function->IsMarkedForInstallingRecompiledCode()) {
   8489       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   8490       OS::Sleep(50);
   8491     }
   8492   }
   8493   if (FLAG_always_opt) {
   8494     // We may have always opt, but that is more best-effort than a real
   8495     // promise, so we still say "no" if it is not optimized.
   8496     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
   8497                                    : Smi::FromInt(2);  // 2 == "no".
   8498   }
   8499   if (FLAG_deopt_every_n_times) {
   8500     return Smi::FromInt(6);  // 6 == "maybe deopted".
   8501   }
   8502   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
   8503                                  : Smi::FromInt(2);  // 2 == "no".
   8504 }
   8505 
   8506 
   8507 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
   8508   HandleScope scope(isolate);
   8509   ASSERT(args.length() == 1);
   8510   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8511   return Smi::FromInt(function->shared()->opt_count());
   8512 }
   8513 
   8514 
   8515 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
   8516   HandleScope scope(isolate);
   8517   ASSERT(args.length() == 1);
   8518   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8519 
   8520   // We're not prepared to handle a function with arguments object.
   8521   ASSERT(!function->shared()->uses_arguments());
   8522 
   8523   // We have hit a back edge in an unoptimized frame for a function that was
   8524   // selected for on-stack replacement.  Find the unoptimized code object.
   8525   Handle<Code> unoptimized(function->shared()->code(), isolate);
   8526   // Keep track of whether we've succeeded in optimizing.
   8527   bool succeeded = unoptimized->optimizable();
   8528   if (succeeded) {
   8529     // If we are trying to do OSR when there are already optimized
   8530     // activations of the function, it means (a) the function is directly or
   8531     // indirectly recursive and (b) an optimized invocation has been
   8532     // deoptimized so that we are currently in an unoptimized activation.
   8533     // Check for optimized activations of this function.
   8534     JavaScriptFrameIterator it(isolate);
   8535     while (succeeded && !it.done()) {
   8536       JavaScriptFrame* frame = it.frame();
   8537       succeeded = !frame->is_optimized() || frame->function() != *function;
   8538       it.Advance();
   8539     }
   8540   }
   8541 
   8542   BailoutId ast_id = BailoutId::None();
   8543   if (succeeded) {
   8544     // The top JS function is this one, the PC is somewhere in the
   8545     // unoptimized code.
   8546     JavaScriptFrameIterator it(isolate);
   8547     JavaScriptFrame* frame = it.frame();
   8548     ASSERT(frame->function() == *function);
   8549     ASSERT(frame->LookupCode() == *unoptimized);
   8550     ASSERT(unoptimized->contains(frame->pc()));
   8551 
   8552     // Use linear search of the unoptimized code's back edge table to find
   8553     // the AST id matching the PC.
   8554     uint32_t target_pc_offset =
   8555       static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
   8556     uint32_t loop_depth = 0;
   8557 
   8558     for (FullCodeGenerator::BackEdgeTableIterator back_edges(*unoptimized);
   8559          !back_edges.Done();
   8560          back_edges.Next()) {
   8561       if (back_edges.pc_offset() == target_pc_offset) {
   8562         ast_id = back_edges.ast_id();
   8563         loop_depth = back_edges.loop_depth();
   8564         break;
   8565       }
   8566     }
   8567     ASSERT(!ast_id.IsNone());
   8568 
   8569     if (FLAG_trace_osr) {
   8570       PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
   8571               ast_id.ToInt(), loop_depth);
   8572       function->PrintName();
   8573       PrintF("]\n");
   8574     }
   8575 
   8576     // Try to compile the optimized code.  A true return value from
   8577     // CompileOptimized means that compilation succeeded, not necessarily
   8578     // that optimization succeeded.
   8579     if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
   8580         function->IsOptimized()) {
   8581       DeoptimizationInputData* data = DeoptimizationInputData::cast(
   8582           function->code()->deoptimization_data());
   8583       if (data->OsrPcOffset()->value() >= 0) {
   8584         if (FLAG_trace_osr) {
   8585           PrintF("[on-stack replacement offset %d in optimized code]\n",
   8586                data->OsrPcOffset()->value());
   8587         }
   8588         ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
   8589       } else {
   8590         // We may never generate the desired OSR entry if we emit an
   8591         // early deoptimize.
   8592         succeeded = false;
   8593       }
   8594     } else {
   8595       succeeded = false;
   8596     }
   8597   }
   8598 
   8599   // Revert to the original interrupt calls in the original unoptimized code.
   8600   if (FLAG_trace_osr) {
   8601     PrintF("[restoring original interrupt calls in ");
   8602     function->PrintName();
   8603     PrintF("]\n");
   8604   }
   8605   InterruptStub interrupt_stub;
   8606   Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate);
   8607   Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
   8608   Deoptimizer::RevertInterruptCode(*unoptimized,
   8609                                    *interrupt_code,
   8610                                    *replacement_code);
   8611 
   8612   // If the optimization attempt succeeded, return the AST id tagged as a
   8613   // smi. This tells the builtin that we need to translate the unoptimized
   8614   // frame to an optimized one.
   8615   if (succeeded) {
   8616     ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
   8617     return Smi::FromInt(ast_id.ToInt());
   8618   } else {
   8619     if (function->IsMarkedForLazyRecompilation()) {
   8620       function->ReplaceCode(function->shared()->code());
   8621     }
   8622     return Smi::FromInt(-1);
   8623   }
   8624 }
   8625 
   8626 
   8627 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
   8628   SealHandleScope shs(isolate);
   8629   ASSERT(args.length() == 2);
   8630 #ifdef DEBUG
   8631   CONVERT_SMI_ARG_CHECKED(interval, 0);
   8632   CONVERT_SMI_ARG_CHECKED(timeout, 1);
   8633   isolate->heap()->set_allocation_timeout(timeout);
   8634   FLAG_gc_interval = interval;
   8635 #endif
   8636   return isolate->heap()->undefined_value();
   8637 }
   8638 
   8639 
   8640 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
   8641   SealHandleScope shs(isolate);
   8642   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8643   return isolate->heap()->undefined_value();
   8644 }
   8645 
   8646 
   8647 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
   8648   SealHandleScope shs(isolate);
   8649   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8650   return isolate->heap()->nan_value();
   8651 }
   8652 
   8653 
   8654 RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
   8655   HandleScope scope(isolate);
   8656   ASSERT(args.length() >= 2);
   8657   int argc = args.length() - 2;
   8658   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
   8659   Object* receiver = args[0];
   8660 
   8661   // If there are too many arguments, allocate argv via malloc.
   8662   const int argv_small_size = 10;
   8663   Handle<Object> argv_small_buffer[argv_small_size];
   8664   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8665   Handle<Object>* argv = argv_small_buffer;
   8666   if (argc > argv_small_size) {
   8667     argv = new Handle<Object>[argc];
   8668     if (argv == NULL) return isolate->StackOverflow();
   8669     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8670   }
   8671 
   8672   for (int i = 0; i < argc; ++i) {
   8673      MaybeObject* maybe = args[1 + i];
   8674      Object* object;
   8675      if (!maybe->To<Object>(&object)) return maybe;
   8676      argv[i] = Handle<Object>(object, isolate);
   8677   }
   8678 
   8679   bool threw;
   8680   Handle<JSReceiver> hfun(fun);
   8681   Handle<Object> hreceiver(receiver, isolate);
   8682   Handle<Object> result =
   8683       Execution::Call(hfun, hreceiver, argc, argv, &threw, true);
   8684 
   8685   if (threw) return Failure::Exception();
   8686   return *result;
   8687 }
   8688 
   8689 
   8690 RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
   8691   HandleScope scope(isolate);
   8692   ASSERT(args.length() == 5);
   8693   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
   8694   Handle<Object> receiver = args.at<Object>(1);
   8695   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
   8696   CONVERT_SMI_ARG_CHECKED(offset, 3);
   8697   CONVERT_SMI_ARG_CHECKED(argc, 4);
   8698   RUNTIME_ASSERT(offset >= 0);
   8699   RUNTIME_ASSERT(argc >= 0);
   8700 
   8701   // If there are too many arguments, allocate argv via malloc.
   8702   const int argv_small_size = 10;
   8703   Handle<Object> argv_small_buffer[argv_small_size];
   8704   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8705   Handle<Object>* argv = argv_small_buffer;
   8706   if (argc > argv_small_size) {
   8707     argv = new Handle<Object>[argc];
   8708     if (argv == NULL) return isolate->StackOverflow();
   8709     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8710   }
   8711 
   8712   for (int i = 0; i < argc; ++i) {
   8713     argv[i] = Object::GetElement(arguments, offset + i);
   8714   }
   8715 
   8716   bool threw;
   8717   Handle<Object> result =
   8718       Execution::Call(fun, receiver, argc, argv, &threw, true);
   8719 
   8720   if (threw) return Failure::Exception();
   8721   return *result;
   8722 }
   8723 
   8724 
   8725 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
   8726   HandleScope scope(isolate);
   8727   ASSERT(args.length() == 1);
   8728   RUNTIME_ASSERT(!args[0]->IsJSFunction());
   8729   return *Execution::GetFunctionDelegate(args.at<Object>(0));
   8730 }
   8731 
   8732 
   8733 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
   8734   HandleScope scope(isolate);
   8735   ASSERT(args.length() == 1);
   8736   RUNTIME_ASSERT(!args[0]->IsJSFunction());
   8737   return *Execution::GetConstructorDelegate(args.at<Object>(0));
   8738 }
   8739 
   8740 
   8741 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewGlobalContext) {
   8742   SealHandleScope shs(isolate);
   8743   ASSERT(args.length() == 2);
   8744 
   8745   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8746   CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 1);
   8747   Context* result;
   8748   MaybeObject* maybe_result =
   8749       isolate->heap()->AllocateGlobalContext(function, scope_info);
   8750   if (!maybe_result->To(&result)) return maybe_result;
   8751 
   8752   ASSERT(function->context() == isolate->context());
   8753   ASSERT(function->context()->global_object() == result->global_object());
   8754   isolate->set_context(result);
   8755   result->global_object()->set_global_context(result);
   8756 
   8757   return result;  // non-failure
   8758 }
   8759 
   8760 
   8761 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
   8762   SealHandleScope shs(isolate);
   8763   ASSERT(args.length() == 1);
   8764 
   8765   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8766   int length = function->shared()->scope_info()->ContextLength();
   8767   Context* result;
   8768   MaybeObject* maybe_result =
   8769       isolate->heap()->AllocateFunctionContext(length, function);
   8770   if (!maybe_result->To(&result)) return maybe_result;
   8771 
   8772   isolate->set_context(result);
   8773 
   8774   return result;  // non-failure
   8775 }
   8776 
   8777 
   8778 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
   8779   SealHandleScope shs(isolate);
   8780   ASSERT(args.length() == 2);
   8781   JSReceiver* extension_object;
   8782   if (args[0]->IsJSReceiver()) {
   8783     extension_object = JSReceiver::cast(args[0]);
   8784   } else {
   8785     // Convert the object to a proper JavaScript object.
   8786     MaybeObject* maybe_js_object = args[0]->ToObject();
   8787     if (!maybe_js_object->To(&extension_object)) {
   8788       if (Failure::cast(maybe_js_object)->IsInternalError()) {
   8789         HandleScope scope(isolate);
   8790         Handle<Object> handle = args.at<Object>(0);
   8791         Handle<Object> result =
   8792             isolate->factory()->NewTypeError("with_expression",
   8793                                              HandleVector(&handle, 1));
   8794         return isolate->Throw(*result);
   8795       } else {
   8796         return maybe_js_object;
   8797       }
   8798     }
   8799   }
   8800 
   8801   JSFunction* function;
   8802   if (args[1]->IsSmi()) {
   8803     // A smi sentinel indicates a context nested inside global code rather
   8804     // than some function.  There is a canonical empty function that can be
   8805     // gotten from the native context.
   8806     function = isolate->context()->native_context()->closure();
   8807   } else {
   8808     function = JSFunction::cast(args[1]);
   8809   }
   8810 
   8811   Context* context;
   8812   MaybeObject* maybe_context =
   8813       isolate->heap()->AllocateWithContext(function,
   8814                                            isolate->context(),
   8815                                            extension_object);
   8816   if (!maybe_context->To(&context)) return maybe_context;
   8817   isolate->set_context(context);
   8818   return context;
   8819 }
   8820 
   8821 
   8822 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
   8823   SealHandleScope shs(isolate);
   8824   ASSERT(args.length() == 3);
   8825   String* name = String::cast(args[0]);
   8826   Object* thrown_object = args[1];
   8827   JSFunction* function;
   8828   if (args[2]->IsSmi()) {
   8829     // A smi sentinel indicates a context nested inside global code rather
   8830     // than some function.  There is a canonical empty function that can be
   8831     // gotten from the native context.
   8832     function = isolate->context()->native_context()->closure();
   8833   } else {
   8834     function = JSFunction::cast(args[2]);
   8835   }
   8836   Context* context;
   8837   MaybeObject* maybe_context =
   8838       isolate->heap()->AllocateCatchContext(function,
   8839                                             isolate->context(),
   8840                                             name,
   8841                                             thrown_object);
   8842   if (!maybe_context->To(&context)) return maybe_context;
   8843   isolate->set_context(context);
   8844   return context;
   8845 }
   8846 
   8847 
   8848 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
   8849   SealHandleScope shs(isolate);
   8850   ASSERT(args.length() == 2);
   8851   ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
   8852   JSFunction* function;
   8853   if (args[1]->IsSmi()) {
   8854     // A smi sentinel indicates a context nested inside global code rather
   8855     // than some function.  There is a canonical empty function that can be
   8856     // gotten from the native context.
   8857     function = isolate->context()->native_context()->closure();
   8858   } else {
   8859     function = JSFunction::cast(args[1]);
   8860   }
   8861   Context* context;
   8862   MaybeObject* maybe_context =
   8863       isolate->heap()->AllocateBlockContext(function,
   8864                                             isolate->context(),
   8865                                             scope_info);
   8866   if (!maybe_context->To(&context)) return maybe_context;
   8867   isolate->set_context(context);
   8868   return context;
   8869 }
   8870 
   8871 
   8872 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSModule) {
   8873   SealHandleScope shs(isolate);
   8874   ASSERT(args.length() == 1);
   8875   Object* obj = args[0];
   8876   return isolate->heap()->ToBoolean(obj->IsJSModule());
   8877 }
   8878 
   8879 
   8880 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushModuleContext) {
   8881   SealHandleScope shs(isolate);
   8882   ASSERT(args.length() == 2);
   8883   CONVERT_SMI_ARG_CHECKED(index, 0);
   8884 
   8885   if (!args[1]->IsScopeInfo()) {
   8886     // Module already initialized. Find hosting context and retrieve context.
   8887     Context* host = Context::cast(isolate->context())->global_context();
   8888     Context* context = Context::cast(host->get(index));
   8889     ASSERT(context->previous() == isolate->context());
   8890     isolate->set_context(context);
   8891     return context;
   8892   }
   8893 
   8894   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
   8895 
   8896   // Allocate module context.
   8897   HandleScope scope(isolate);
   8898   Factory* factory = isolate->factory();
   8899   Handle<Context> context = factory->NewModuleContext(scope_info);
   8900   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
   8901   context->set_module(*module);
   8902   Context* previous = isolate->context();
   8903   context->set_previous(previous);
   8904   context->set_closure(previous->closure());
   8905   context->set_global_object(previous->global_object());
   8906   isolate->set_context(*context);
   8907 
   8908   // Find hosting scope and initialize internal variable holding module there.
   8909   previous->global_context()->set(index, *context);
   8910 
   8911   return *context;
   8912 }
   8913 
   8914 
   8915 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareModules) {
   8916   HandleScope scope(isolate);
   8917   ASSERT(args.length() == 1);
   8918   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
   8919   Context* host_context = isolate->context();
   8920 
   8921   for (int i = 0; i < descriptions->length(); ++i) {
   8922     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
   8923     int host_index = description->host_index();
   8924     Handle<Context> context(Context::cast(host_context->get(host_index)));
   8925     Handle<JSModule> module(context->module());
   8926 
   8927     for (int j = 0; j < description->length(); ++j) {
   8928       Handle<String> name(description->name(j));
   8929       VariableMode mode = description->mode(j);
   8930       int index = description->index(j);
   8931       switch (mode) {
   8932         case VAR:
   8933         case LET:
   8934         case CONST:
   8935         case CONST_HARMONY: {
   8936           PropertyAttributes attr =
   8937               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
   8938           Handle<AccessorInfo> info =
   8939               Accessors::MakeModuleExport(name, index, attr);
   8940           Handle<Object> result = SetAccessor(module, info);
   8941           ASSERT(!(result.is_null() || result->IsUndefined()));
   8942           USE(result);
   8943           break;
   8944         }
   8945         case MODULE: {
   8946           Object* referenced_context = Context::cast(host_context)->get(index);
   8947           Handle<JSModule> value(Context::cast(referenced_context)->module());
   8948           JSReceiver::SetProperty(module, name, value, FROZEN, kStrictMode);
   8949           break;
   8950         }
   8951         case INTERNAL:
   8952         case TEMPORARY:
   8953         case DYNAMIC:
   8954         case DYNAMIC_GLOBAL:
   8955         case DYNAMIC_LOCAL:
   8956           UNREACHABLE();
   8957       }
   8958     }
   8959 
   8960     JSObject::PreventExtensions(module);
   8961   }
   8962 
   8963   ASSERT(!isolate->has_pending_exception());
   8964   return isolate->heap()->undefined_value();
   8965 }
   8966 
   8967 
   8968 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
   8969   HandleScope scope(isolate);
   8970   ASSERT(args.length() == 2);
   8971 
   8972   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   8973   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   8974 
   8975   int index;
   8976   PropertyAttributes attributes;
   8977   ContextLookupFlags flags = FOLLOW_CHAINS;
   8978   BindingFlags binding_flags;
   8979   Handle<Object> holder = context->Lookup(name,
   8980                                           flags,
   8981                                           &index,
   8982                                           &attributes,
   8983                                           &binding_flags);
   8984 
   8985   // If the slot was not found the result is true.
   8986   if (holder.is_null()) {
   8987     return isolate->heap()->true_value();
   8988   }
   8989 
   8990   // If the slot was found in a context, it should be DONT_DELETE.
   8991   if (holder->IsContext()) {
   8992     return isolate->heap()->false_value();
   8993   }
   8994 
   8995   // The slot was found in a JSObject, either a context extension object,
   8996   // the global object, or the subject of a with.  Try to delete it
   8997   // (respecting DONT_DELETE).
   8998   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   8999   Handle<Object> result = JSReceiver::DeleteProperty(object, name);
   9000   RETURN_IF_EMPTY_HANDLE(isolate, result);
   9001   return *result;
   9002 }
   9003 
   9004 
   9005 // A mechanism to return a pair of Object pointers in registers (if possible).
   9006 // How this is achieved is calling convention-dependent.
   9007 // All currently supported x86 compiles uses calling conventions that are cdecl
   9008 // variants where a 64-bit value is returned in two 32-bit registers
   9009 // (edx:eax on ia32, r1:r0 on ARM).
   9010 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
   9011 // In Win64 calling convention, a struct of two pointers is returned in memory,
   9012 // allocated by the caller, and passed as a pointer in a hidden first parameter.
   9013 #ifdef V8_HOST_ARCH_64_BIT
   9014 struct ObjectPair {
   9015   MaybeObject* x;
   9016   MaybeObject* y;
   9017 };
   9018 
   9019 
   9020 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
   9021   ObjectPair result = {x, y};
   9022   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
   9023   // In Win64 they are assigned to a hidden first argument.
   9024   return result;
   9025 }
   9026 #else
   9027 typedef uint64_t ObjectPair;
   9028 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
   9029   return reinterpret_cast<uint32_t>(x) |
   9030       (reinterpret_cast<ObjectPair>(y) << 32);
   9031 }
   9032 #endif
   9033 
   9034 
   9035 static inline MaybeObject* Unhole(Heap* heap,
   9036                                   MaybeObject* x,
   9037                                   PropertyAttributes attributes) {
   9038   ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
   9039   USE(attributes);
   9040   return x->IsTheHole() ? heap->undefined_value() : x;
   9041 }
   9042 
   9043 
   9044 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
   9045                                            JSObject* holder) {
   9046   ASSERT(!holder->IsGlobalObject());
   9047   Context* top = isolate->context();
   9048   // Get the context extension function.
   9049   JSFunction* context_extension_function =
   9050       top->native_context()->context_extension_function();
   9051   // If the holder isn't a context extension object, we just return it
   9052   // as the receiver. This allows arguments objects to be used as
   9053   // receivers, but only if they are put in the context scope chain
   9054   // explicitly via a with-statement.
   9055   Object* constructor = holder->map()->constructor();
   9056   if (constructor != context_extension_function) return holder;
   9057   // Fall back to using the global object as the implicit receiver if
   9058   // the property turns out to be a local variable allocated in a
   9059   // context extension object - introduced via eval. Implicit global
   9060   // receivers are indicated with the hole value.
   9061   return isolate->heap()->the_hole_value();
   9062 }
   9063 
   9064 
   9065 static ObjectPair LoadContextSlotHelper(Arguments args,
   9066                                         Isolate* isolate,
   9067                                         bool throw_error) {
   9068   HandleScope scope(isolate);
   9069   ASSERT_EQ(2, args.length());
   9070 
   9071   if (!args[0]->IsContext() || !args[1]->IsString()) {
   9072     return MakePair(isolate->ThrowIllegalOperation(), NULL);
   9073   }
   9074   Handle<Context> context = args.at<Context>(0);
   9075   Handle<String> name = args.at<String>(1);
   9076 
   9077   int index;
   9078   PropertyAttributes attributes;
   9079   ContextLookupFlags flags = FOLLOW_CHAINS;
   9080   BindingFlags binding_flags;
   9081   Handle<Object> holder = context->Lookup(name,
   9082                                           flags,
   9083                                           &index,
   9084                                           &attributes,
   9085                                           &binding_flags);
   9086   if (isolate->has_pending_exception()) {
   9087     return MakePair(Failure::Exception(), NULL);
   9088   }
   9089 
   9090   // If the index is non-negative, the slot has been found in a context.
   9091   if (index >= 0) {
   9092     ASSERT(holder->IsContext());
   9093     // If the "property" we were looking for is a local variable, the
   9094     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
   9095     //
   9096     // Use the hole as the receiver to signal that the receiver is implicit
   9097     // and that the global receiver should be used (as distinguished from an
   9098     // explicit receiver that happens to be a global object).
   9099     Handle<Object> receiver = isolate->factory()->the_hole_value();
   9100     Object* value = Context::cast(*holder)->get(index);
   9101     // Check for uninitialized bindings.
   9102     switch (binding_flags) {
   9103       case MUTABLE_CHECK_INITIALIZED:
   9104       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
   9105         if (value->IsTheHole()) {
   9106           Handle<Object> reference_error =
   9107               isolate->factory()->NewReferenceError("not_defined",
   9108                                                     HandleVector(&name, 1));
   9109           return MakePair(isolate->Throw(*reference_error), NULL);
   9110         }
   9111         // FALLTHROUGH
   9112       case MUTABLE_IS_INITIALIZED:
   9113       case IMMUTABLE_IS_INITIALIZED:
   9114       case IMMUTABLE_IS_INITIALIZED_HARMONY:
   9115         ASSERT(!value->IsTheHole());
   9116         return MakePair(value, *receiver);
   9117       case IMMUTABLE_CHECK_INITIALIZED:
   9118         return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
   9119       case MISSING_BINDING:
   9120         UNREACHABLE();
   9121         return MakePair(NULL, NULL);
   9122     }
   9123   }
   9124 
   9125   // Otherwise, if the slot was found the holder is a context extension
   9126   // object, subject of a with, or a global object.  We read the named
   9127   // property from it.
   9128   if (!holder.is_null()) {
   9129     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
   9130     ASSERT(object->IsJSProxy() || object->HasProperty(*name));
   9131     // GetProperty below can cause GC.
   9132     Handle<Object> receiver_handle(
   9133         object->IsGlobalObject()
   9134             ? GlobalObject::cast(*object)->global_receiver()
   9135             : object->IsJSProxy() ? static_cast<Object*>(*object)
   9136                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
   9137         isolate);
   9138 
   9139     // No need to unhole the value here.  This is taken care of by the
   9140     // GetProperty function.
   9141     MaybeObject* value = object->GetProperty(*name);
   9142     return MakePair(value, *receiver_handle);
   9143   }
   9144 
   9145   if (throw_error) {
   9146     // The property doesn't exist - throw exception.
   9147     Handle<Object> reference_error =
   9148         isolate->factory()->NewReferenceError("not_defined",
   9149                                               HandleVector(&name, 1));
   9150     return MakePair(isolate->Throw(*reference_error), NULL);
   9151   } else {
   9152     // The property doesn't exist - return undefined.
   9153     return MakePair(isolate->heap()->undefined_value(),
   9154                     isolate->heap()->undefined_value());
   9155   }
   9156 }
   9157 
   9158 
   9159 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) {
   9160   return LoadContextSlotHelper(args, isolate, true);
   9161 }
   9162 
   9163 
   9164 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlotNoReferenceError) {
   9165   return LoadContextSlotHelper(args, isolate, false);
   9166 }
   9167 
   9168 
   9169 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
   9170   HandleScope scope(isolate);
   9171   ASSERT(args.length() == 4);
   9172 
   9173   Handle<Object> value(args[0], isolate);
   9174   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   9175   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   9176   CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
   9177   StrictModeFlag strict_mode = (language_mode == CLASSIC_MODE)
   9178       ? kNonStrictMode : kStrictMode;
   9179 
   9180   int index;
   9181   PropertyAttributes attributes;
   9182   ContextLookupFlags flags = FOLLOW_CHAINS;
   9183   BindingFlags binding_flags;
   9184   Handle<Object> holder = context->Lookup(name,
   9185                                           flags,
   9186                                           &index,
   9187                                           &attributes,
   9188                                           &binding_flags);
   9189   if (isolate->has_pending_exception()) return Failure::Exception();
   9190 
   9191   if (index >= 0) {
   9192     // The property was found in a context slot.
   9193     Handle<Context> context = Handle<Context>::cast(holder);
   9194     if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
   9195         context->get(index)->IsTheHole()) {
   9196       Handle<Object> error =
   9197           isolate->factory()->NewReferenceError("not_defined",
   9198                                                 HandleVector(&name, 1));
   9199       return isolate->Throw(*error);
   9200     }
   9201     // Ignore if read_only variable.
   9202     if ((attributes & READ_ONLY) == 0) {
   9203       // Context is a fixed array and set cannot fail.
   9204       context->set(index, *value);
   9205     } else if (strict_mode == kStrictMode) {
   9206       // Setting read only property in strict mode.
   9207       Handle<Object> error =
   9208           isolate->factory()->NewTypeError("strict_cannot_assign",
   9209                                            HandleVector(&name, 1));
   9210       return isolate->Throw(*error);
   9211     }
   9212     return *value;
   9213   }
   9214 
   9215   // Slow case: The property is not in a context slot.  It is either in a
   9216   // context extension object, a property of the subject of a with, or a
   9217   // property of the global object.
   9218   Handle<JSReceiver> object;
   9219 
   9220   if (!holder.is_null()) {
   9221     // The property exists on the holder.
   9222     object = Handle<JSReceiver>::cast(holder);
   9223   } else {
   9224     // The property was not found.
   9225     ASSERT(attributes == ABSENT);
   9226 
   9227     if (strict_mode == kStrictMode) {
   9228       // Throw in strict mode (assignment to undefined variable).
   9229       Handle<Object> error =
   9230           isolate->factory()->NewReferenceError(
   9231               "not_defined", HandleVector(&name, 1));
   9232       return isolate->Throw(*error);
   9233     }
   9234     // In non-strict mode, the property is added to the global object.
   9235     attributes = NONE;
   9236     object = Handle<JSReceiver>(isolate->context()->global_object());
   9237   }
   9238 
   9239   // Set the property if it's not read only or doesn't yet exist.
   9240   if ((attributes & READ_ONLY) == 0 ||
   9241       (object->GetLocalPropertyAttribute(*name) == ABSENT)) {
   9242     RETURN_IF_EMPTY_HANDLE(
   9243         isolate,
   9244         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
   9245   } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
   9246     // Setting read only property in strict mode.
   9247     Handle<Object> error =
   9248       isolate->factory()->NewTypeError(
   9249           "strict_cannot_assign", HandleVector(&name, 1));
   9250     return isolate->Throw(*error);
   9251   }
   9252   return *value;
   9253 }
   9254 
   9255 
   9256 RUNTIME_FUNCTION(MaybeObject*, Runtime_Throw) {
   9257   HandleScope scope(isolate);
   9258   ASSERT(args.length() == 1);
   9259 
   9260   return isolate->Throw(args[0]);
   9261 }
   9262 
   9263 
   9264 RUNTIME_FUNCTION(MaybeObject*, Runtime_ReThrow) {
   9265   HandleScope scope(isolate);
   9266   ASSERT(args.length() == 1);
   9267 
   9268   return isolate->ReThrow(args[0]);
   9269 }
   9270 
   9271 
   9272 RUNTIME_FUNCTION(MaybeObject*, Runtime_PromoteScheduledException) {
   9273   SealHandleScope shs(isolate);
   9274   ASSERT_EQ(0, args.length());
   9275   return isolate->PromoteScheduledException();
   9276 }
   9277 
   9278 
   9279 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowReferenceError) {
   9280   HandleScope scope(isolate);
   9281   ASSERT(args.length() == 1);
   9282 
   9283   Handle<Object> name(args[0], isolate);
   9284   Handle<Object> reference_error =
   9285     isolate->factory()->NewReferenceError("not_defined",
   9286                                           HandleVector(&name, 1));
   9287   return isolate->Throw(*reference_error);
   9288 }
   9289 
   9290 
   9291 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowNotDateError) {
   9292   HandleScope scope(isolate);
   9293   ASSERT(args.length() == 0);
   9294   return isolate->Throw(*isolate->factory()->NewTypeError(
   9295       "not_date_object", HandleVector<Object>(NULL, 0)));
   9296 }
   9297 
   9298 
   9299 
   9300 RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
   9301   SealHandleScope shs(isolate);
   9302   ASSERT(args.length() == 0);
   9303 
   9304   // First check if this is a real stack overflow.
   9305   if (isolate->stack_guard()->IsStackOverflow()) {
   9306     SealHandleScope shs(isolate);
   9307     return isolate->StackOverflow();
   9308   }
   9309 
   9310   return Execution::HandleStackGuardInterrupt(isolate);
   9311 }
   9312 
   9313 
   9314 RUNTIME_FUNCTION(MaybeObject*, Runtime_Interrupt) {
   9315   SealHandleScope shs(isolate);
   9316   ASSERT(args.length() == 0);
   9317   return Execution::HandleStackGuardInterrupt(isolate);
   9318 }
   9319 
   9320 
   9321 static int StackSize(Isolate* isolate) {
   9322   int n = 0;
   9323   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
   9324   return n;
   9325 }
   9326 
   9327 
   9328 static void PrintTransition(Isolate* isolate, Object* result) {
   9329   // indentation
   9330   { const int nmax = 80;
   9331     int n = StackSize(isolate);
   9332     if (n <= nmax)
   9333       PrintF("%4d:%*s", n, n, "");
   9334     else
   9335       PrintF("%4d:%*s", n, nmax, "...");
   9336   }
   9337 
   9338   if (result == NULL) {
   9339     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
   9340     PrintF(" {\n");
   9341   } else {
   9342     // function result
   9343     PrintF("} -> ");
   9344     result->ShortPrint();
   9345     PrintF("\n");
   9346   }
   9347 }
   9348 
   9349 
   9350 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
   9351   SealHandleScope shs(isolate);
   9352   ASSERT(args.length() == 0);
   9353   PrintTransition(isolate, NULL);
   9354   return isolate->heap()->undefined_value();
   9355 }
   9356 
   9357 
   9358 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) {
   9359   SealHandleScope shs(isolate);
   9360   PrintTransition(isolate, args[0]);
   9361   return args[0];  // return TOS
   9362 }
   9363 
   9364 
   9365 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrint) {
   9366   SealHandleScope shs(isolate);
   9367   ASSERT(args.length() == 1);
   9368 
   9369 #ifdef DEBUG
   9370   if (args[0]->IsString()) {
   9371     // If we have a string, assume it's a code "marker"
   9372     // and print some interesting cpu debugging info.
   9373     JavaScriptFrameIterator it(isolate);
   9374     JavaScriptFrame* frame = it.frame();
   9375     PrintF("fp = %p, sp = %p, caller_sp = %p: ",
   9376            frame->fp(), frame->sp(), frame->caller_sp());
   9377   } else {
   9378     PrintF("DebugPrint: ");
   9379   }
   9380   args[0]->Print();
   9381   if (args[0]->IsHeapObject()) {
   9382     PrintF("\n");
   9383     HeapObject::cast(args[0])->map()->Print();
   9384   }
   9385 #else
   9386   // ShortPrint is available in release mode. Print is not.
   9387   args[0]->ShortPrint();
   9388 #endif
   9389   PrintF("\n");
   9390   Flush();
   9391 
   9392   return args[0];  // return TOS
   9393 }
   9394 
   9395 
   9396 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugTrace) {
   9397   SealHandleScope shs(isolate);
   9398   ASSERT(args.length() == 0);
   9399   isolate->PrintStack(stdout);
   9400   return isolate->heap()->undefined_value();
   9401 }
   9402 
   9403 
   9404 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
   9405   SealHandleScope shs(isolate);
   9406   ASSERT(args.length() == 0);
   9407 
   9408   // According to ECMA-262, section 15.9.1, page 117, the precision of
   9409   // the number in a Date object representing a particular instant in
   9410   // time is milliseconds. Therefore, we floor the result of getting
   9411   // the OS time.
   9412   double millis = floor(OS::TimeCurrentMillis());
   9413   return isolate->heap()->NumberFromDouble(millis);
   9414 }
   9415 
   9416 
   9417 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
   9418   HandleScope scope(isolate);
   9419   ASSERT(args.length() == 2);
   9420 
   9421   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   9422   FlattenString(str);
   9423 
   9424   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
   9425 
   9426   MaybeObject* maybe_result_array =
   9427       output->EnsureCanContainHeapObjectElements();
   9428   if (maybe_result_array->IsFailure()) return maybe_result_array;
   9429   RUNTIME_ASSERT(output->HasFastObjectElements());
   9430 
   9431   DisallowHeapAllocation no_gc;
   9432 
   9433   FixedArray* output_array = FixedArray::cast(output->elements());
   9434   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
   9435   bool result;
   9436   String::FlatContent str_content = str->GetFlatContent();
   9437   if (str_content.IsAscii()) {
   9438     result = DateParser::Parse(str_content.ToOneByteVector(),
   9439                                output_array,
   9440                                isolate->unicode_cache());
   9441   } else {
   9442     ASSERT(str_content.IsTwoByte());
   9443     result = DateParser::Parse(str_content.ToUC16Vector(),
   9444                                output_array,
   9445                                isolate->unicode_cache());
   9446   }
   9447 
   9448   if (result) {
   9449     return *output;
   9450   } else {
   9451     return isolate->heap()->null_value();
   9452   }
   9453 }
   9454 
   9455 
   9456 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
   9457   SealHandleScope shs(isolate);
   9458   ASSERT(args.length() == 1);
   9459 
   9460   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9461   int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x));
   9462   const char* zone = OS::LocalTimezone(static_cast<double>(time));
   9463   return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
   9464 }
   9465 
   9466 
   9467 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateToUTC) {
   9468   SealHandleScope shs(isolate);
   9469   ASSERT(args.length() == 1);
   9470 
   9471   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9472   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
   9473 
   9474   return isolate->heap()->NumberFromDouble(static_cast<double>(time));
   9475 }
   9476 
   9477 
   9478 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
   9479   SealHandleScope shs(isolate);
   9480   ASSERT(args.length() == 1);
   9481   Object* global = args[0];
   9482   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
   9483   return JSGlobalObject::cast(global)->global_receiver();
   9484 }
   9485 
   9486 
   9487 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
   9488   HandleScope scope(isolate);
   9489   ASSERT_EQ(1, args.length());
   9490   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9491 
   9492   source = Handle<String>(FlattenGetString(source));
   9493   // Optimized fast case where we only have ASCII characters.
   9494   Handle<Object> result;
   9495   if (source->IsSeqOneByteString()) {
   9496     result = JsonParser<true>::Parse(source);
   9497   } else {
   9498     result = JsonParser<false>::Parse(source);
   9499   }
   9500   if (result.is_null()) {
   9501     // Syntax error or stack overflow in scanner.
   9502     ASSERT(isolate->has_pending_exception());
   9503     return Failure::Exception();
   9504   }
   9505   return *result;
   9506 }
   9507 
   9508 
   9509 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   9510                                       Handle<Context> context) {
   9511   ASSERT(context->allow_code_gen_from_strings()->IsFalse());
   9512   // Check with callback if set.
   9513   AllowCodeGenerationFromStringsCallback callback =
   9514       isolate->allow_code_gen_callback();
   9515   if (callback == NULL) {
   9516     // No callback set and code generation disallowed.
   9517     return false;
   9518   } else {
   9519     // Callback set. Let it decide if code generation is allowed.
   9520     VMState<EXTERNAL> state(isolate);
   9521     return callback(v8::Utils::ToLocal(context));
   9522   }
   9523 }
   9524 
   9525 
   9526 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
   9527   HandleScope scope(isolate);
   9528   ASSERT_EQ(2, args.length());
   9529   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9530   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
   9531 
   9532   // Extract native context.
   9533   Handle<Context> context(isolate->context()->native_context());
   9534 
   9535   // Check if native context allows code generation from
   9536   // strings. Throw an exception if it doesn't.
   9537   if (context->allow_code_gen_from_strings()->IsFalse() &&
   9538       !CodeGenerationFromStringsAllowed(isolate, context)) {
   9539     Handle<Object> error_message =
   9540         context->ErrorMessageForCodeGenerationFromStrings();
   9541     return isolate->Throw(*isolate->factory()->NewEvalError(
   9542         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
   9543   }
   9544 
   9545   // Compile source string in the native context.
   9546   ParseRestriction restriction = function_literal_only
   9547       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
   9548   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   9549       source, context, true, CLASSIC_MODE, restriction, RelocInfo::kNoPosition);
   9550   RETURN_IF_EMPTY_HANDLE(isolate, shared);
   9551   Handle<JSFunction> fun =
   9552       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   9553                                                             context,
   9554                                                             NOT_TENURED);
   9555   return *fun;
   9556 }
   9557 
   9558 
   9559 static ObjectPair CompileGlobalEval(Isolate* isolate,
   9560                                     Handle<String> source,
   9561                                     Handle<Object> receiver,
   9562                                     LanguageMode language_mode,
   9563                                     int scope_position) {
   9564   Handle<Context> context = Handle<Context>(isolate->context());
   9565   Handle<Context> native_context = Handle<Context>(context->native_context());
   9566 
   9567   // Check if native context allows code generation from
   9568   // strings. Throw an exception if it doesn't.
   9569   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
   9570       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
   9571     Handle<Object> error_message =
   9572         native_context->ErrorMessageForCodeGenerationFromStrings();
   9573     isolate->Throw(*isolate->factory()->NewEvalError(
   9574         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
   9575     return MakePair(Failure::Exception(), NULL);
   9576   }
   9577 
   9578   // Deal with a normal eval call with a string argument. Compile it
   9579   // and return the compiled function bound in the local context.
   9580   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   9581       source,
   9582       context,
   9583       context->IsNativeContext(),
   9584       language_mode,
   9585       NO_PARSE_RESTRICTION,
   9586       scope_position);
   9587   RETURN_IF_EMPTY_HANDLE_VALUE(isolate, shared,
   9588                                MakePair(Failure::Exception(), NULL));
   9589   Handle<JSFunction> compiled =
   9590       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   9591           shared, context, NOT_TENURED);
   9592   return MakePair(*compiled, *receiver);
   9593 }
   9594 
   9595 
   9596 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
   9597   HandleScope scope(isolate);
   9598   ASSERT(args.length() == 5);
   9599 
   9600   Handle<Object> callee = args.at<Object>(0);
   9601 
   9602   // If "eval" didn't refer to the original GlobalEval, it's not a
   9603   // direct call to eval.
   9604   // (And even if it is, but the first argument isn't a string, just let
   9605   // execution default to an indirect call to eval, which will also return
   9606   // the first argument without doing anything).
   9607   if (*callee != isolate->native_context()->global_eval_fun() ||
   9608       !args[1]->IsString()) {
   9609     return MakePair(*callee, isolate->heap()->the_hole_value());
   9610   }
   9611 
   9612   CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
   9613   ASSERT(args[4]->IsSmi());
   9614   return CompileGlobalEval(isolate,
   9615                            args.at<String>(1),
   9616                            args.at<Object>(2),
   9617                            language_mode,
   9618                            args.smi_at(4));
   9619 }
   9620 
   9621 
   9622 static MaybeObject* Allocate(Isolate* isolate,
   9623                              int size,
   9624                              AllocationSpace space) {
   9625   // Allocate a block of memory in the given space (filled with a filler).
   9626   // Use as fallback for allocation in generated code when the space
   9627   // is full.
   9628   SealHandleScope shs(isolate);
   9629   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9630   RUNTIME_ASSERT(size > 0);
   9631   Heap* heap = isolate->heap();
   9632   RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize());
   9633   Object* allocation;
   9634   { MaybeObject* maybe_allocation;
   9635     if (space == NEW_SPACE) {
   9636       maybe_allocation = heap->new_space()->AllocateRaw(size);
   9637     } else {
   9638       ASSERT(space == OLD_POINTER_SPACE || space == OLD_DATA_SPACE);
   9639       maybe_allocation = heap->paged_space(space)->AllocateRaw(size);
   9640     }
   9641     if (maybe_allocation->ToObject(&allocation)) {
   9642       heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size);
   9643     }
   9644     return maybe_allocation;
   9645   }
   9646 }
   9647 
   9648 
   9649 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) {
   9650   SealHandleScope shs(isolate);
   9651   ASSERT(args.length() == 1);
   9652   CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
   9653   return Allocate(isolate, size_smi->value(), NEW_SPACE);
   9654 }
   9655 
   9656 
   9657 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldPointerSpace) {
   9658   SealHandleScope shs(isolate);
   9659   ASSERT(args.length() == 1);
   9660   CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
   9661   return Allocate(isolate, size_smi->value(), OLD_POINTER_SPACE);
   9662 }
   9663 
   9664 
   9665 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldDataSpace) {
   9666   SealHandleScope shs(isolate);
   9667   ASSERT(args.length() == 1);
   9668   CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
   9669   return Allocate(isolate, size_smi->value(), OLD_DATA_SPACE);
   9670 }
   9671 
   9672 
   9673 // Push an object unto an array of objects if it is not already in the
   9674 // array.  Returns true if the element was pushed on the stack and
   9675 // false otherwise.
   9676 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
   9677   SealHandleScope shs(isolate);
   9678   ASSERT(args.length() == 2);
   9679   CONVERT_ARG_CHECKED(JSArray, array, 0);
   9680   CONVERT_ARG_CHECKED(JSReceiver, element, 1);
   9681   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
   9682   int length = Smi::cast(array->length())->value();
   9683   FixedArray* elements = FixedArray::cast(array->elements());
   9684   for (int i = 0; i < length; i++) {
   9685     if (elements->get(i) == element) return isolate->heap()->false_value();
   9686   }
   9687   Object* obj;
   9688   // Strict not needed. Used for cycle detection in Array join implementation.
   9689   { MaybeObject* maybe_obj =
   9690         array->SetFastElement(length, element, kNonStrictMode, true);
   9691     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   9692   }
   9693   return isolate->heap()->true_value();
   9694 }
   9695 
   9696 
   9697 /**
   9698  * A simple visitor visits every element of Array's.
   9699  * The backend storage can be a fixed array for fast elements case,
   9700  * or a dictionary for sparse array. Since Dictionary is a subtype
   9701  * of FixedArray, the class can be used by both fast and slow cases.
   9702  * The second parameter of the constructor, fast_elements, specifies
   9703  * whether the storage is a FixedArray or Dictionary.
   9704  *
   9705  * An index limit is used to deal with the situation that a result array
   9706  * length overflows 32-bit non-negative integer.
   9707  */
   9708 class ArrayConcatVisitor {
   9709  public:
   9710   ArrayConcatVisitor(Isolate* isolate,
   9711                      Handle<FixedArray> storage,
   9712                      bool fast_elements) :
   9713       isolate_(isolate),
   9714       storage_(Handle<FixedArray>::cast(
   9715           isolate->global_handles()->Create(*storage))),
   9716       index_offset_(0u),
   9717       fast_elements_(fast_elements),
   9718       exceeds_array_limit_(false) { }
   9719 
   9720   ~ArrayConcatVisitor() {
   9721     clear_storage();
   9722   }
   9723 
   9724   void visit(uint32_t i, Handle<Object> elm) {
   9725     if (i > JSObject::kMaxElementCount - index_offset_) {
   9726       exceeds_array_limit_ = true;
   9727       return;
   9728     }
   9729     uint32_t index = index_offset_ + i;
   9730 
   9731     if (fast_elements_) {
   9732       if (index < static_cast<uint32_t>(storage_->length())) {
   9733         storage_->set(index, *elm);
   9734         return;
   9735       }
   9736       // Our initial estimate of length was foiled, possibly by
   9737       // getters on the arrays increasing the length of later arrays
   9738       // during iteration.
   9739       // This shouldn't happen in anything but pathological cases.
   9740       SetDictionaryMode(index);
   9741       // Fall-through to dictionary mode.
   9742     }
   9743     ASSERT(!fast_elements_);
   9744     Handle<SeededNumberDictionary> dict(
   9745         SeededNumberDictionary::cast(*storage_));
   9746     Handle<SeededNumberDictionary> result =
   9747         isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
   9748     if (!result.is_identical_to(dict)) {
   9749       // Dictionary needed to grow.
   9750       clear_storage();
   9751       set_storage(*result);
   9752     }
   9753   }
   9754 
   9755   void increase_index_offset(uint32_t delta) {
   9756     if (JSObject::kMaxElementCount - index_offset_ < delta) {
   9757       index_offset_ = JSObject::kMaxElementCount;
   9758     } else {
   9759       index_offset_ += delta;
   9760     }
   9761   }
   9762 
   9763   bool exceeds_array_limit() {
   9764     return exceeds_array_limit_;
   9765   }
   9766 
   9767   Handle<JSArray> ToArray() {
   9768     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
   9769     Handle<Object> length =
   9770         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
   9771     Handle<Map> map;
   9772     if (fast_elements_) {
   9773       map = isolate_->factory()->GetElementsTransitionMap(array,
   9774                                                           FAST_HOLEY_ELEMENTS);
   9775     } else {
   9776       map = isolate_->factory()->GetElementsTransitionMap(array,
   9777                                                           DICTIONARY_ELEMENTS);
   9778     }
   9779     array->set_map(*map);
   9780     array->set_length(*length);
   9781     array->set_elements(*storage_);
   9782     return array;
   9783   }
   9784 
   9785  private:
   9786   // Convert storage to dictionary mode.
   9787   void SetDictionaryMode(uint32_t index) {
   9788     ASSERT(fast_elements_);
   9789     Handle<FixedArray> current_storage(*storage_);
   9790     Handle<SeededNumberDictionary> slow_storage(
   9791         isolate_->factory()->NewSeededNumberDictionary(
   9792             current_storage->length()));
   9793     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
   9794     for (uint32_t i = 0; i < current_length; i++) {
   9795       HandleScope loop_scope(isolate_);
   9796       Handle<Object> element(current_storage->get(i), isolate_);
   9797       if (!element->IsTheHole()) {
   9798         Handle<SeededNumberDictionary> new_storage =
   9799           isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
   9800         if (!new_storage.is_identical_to(slow_storage)) {
   9801           slow_storage = loop_scope.CloseAndEscape(new_storage);
   9802         }
   9803       }
   9804     }
   9805     clear_storage();
   9806     set_storage(*slow_storage);
   9807     fast_elements_ = false;
   9808   }
   9809 
   9810   inline void clear_storage() {
   9811     isolate_->global_handles()->Destroy(
   9812         Handle<Object>::cast(storage_).location());
   9813   }
   9814 
   9815   inline void set_storage(FixedArray* storage) {
   9816     storage_ = Handle<FixedArray>::cast(
   9817         isolate_->global_handles()->Create(storage));
   9818   }
   9819 
   9820   Isolate* isolate_;
   9821   Handle<FixedArray> storage_;  // Always a global handle.
   9822   // Index after last seen index. Always less than or equal to
   9823   // JSObject::kMaxElementCount.
   9824   uint32_t index_offset_;
   9825   bool fast_elements_ : 1;
   9826   bool exceeds_array_limit_ : 1;
   9827 };
   9828 
   9829 
   9830 static uint32_t EstimateElementCount(Handle<JSArray> array) {
   9831   uint32_t length = static_cast<uint32_t>(array->length()->Number());
   9832   int element_count = 0;
   9833   switch (array->GetElementsKind()) {
   9834     case FAST_SMI_ELEMENTS:
   9835     case FAST_HOLEY_SMI_ELEMENTS:
   9836     case FAST_ELEMENTS:
   9837     case FAST_HOLEY_ELEMENTS: {
   9838       // Fast elements can't have lengths that are not representable by
   9839       // a 32-bit signed integer.
   9840       ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
   9841       int fast_length = static_cast<int>(length);
   9842       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
   9843       for (int i = 0; i < fast_length; i++) {
   9844         if (!elements->get(i)->IsTheHole()) element_count++;
   9845       }
   9846       break;
   9847     }
   9848     case FAST_DOUBLE_ELEMENTS:
   9849     case FAST_HOLEY_DOUBLE_ELEMENTS: {
   9850       // Fast elements can't have lengths that are not representable by
   9851       // a 32-bit signed integer.
   9852       ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
   9853       int fast_length = static_cast<int>(length);
   9854       if (array->elements()->IsFixedArray()) {
   9855         ASSERT(FixedArray::cast(array->elements())->length() == 0);
   9856         break;
   9857       }
   9858       Handle<FixedDoubleArray> elements(
   9859           FixedDoubleArray::cast(array->elements()));
   9860       for (int i = 0; i < fast_length; i++) {
   9861         if (!elements->is_the_hole(i)) element_count++;
   9862       }
   9863       break;
   9864     }
   9865     case DICTIONARY_ELEMENTS: {
   9866       Handle<SeededNumberDictionary> dictionary(
   9867           SeededNumberDictionary::cast(array->elements()));
   9868       int capacity = dictionary->Capacity();
   9869       for (int i = 0; i < capacity; i++) {
   9870         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
   9871         if (dictionary->IsKey(*key)) {
   9872           element_count++;
   9873         }
   9874       }
   9875       break;
   9876     }
   9877     case NON_STRICT_ARGUMENTS_ELEMENTS:
   9878     case EXTERNAL_BYTE_ELEMENTS:
   9879     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
   9880     case EXTERNAL_SHORT_ELEMENTS:
   9881     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
   9882     case EXTERNAL_INT_ELEMENTS:
   9883     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
   9884     case EXTERNAL_FLOAT_ELEMENTS:
   9885     case EXTERNAL_DOUBLE_ELEMENTS:
   9886     case EXTERNAL_PIXEL_ELEMENTS:
   9887       // External arrays are always dense.
   9888       return length;
   9889   }
   9890   // As an estimate, we assume that the prototype doesn't contain any
   9891   // inherited elements.
   9892   return element_count;
   9893 }
   9894 
   9895 
   9896 
   9897 template<class ExternalArrayClass, class ElementType>
   9898 static void IterateExternalArrayElements(Isolate* isolate,
   9899                                          Handle<JSObject> receiver,
   9900                                          bool elements_are_ints,
   9901                                          bool elements_are_guaranteed_smis,
   9902                                          ArrayConcatVisitor* visitor) {
   9903   Handle<ExternalArrayClass> array(
   9904       ExternalArrayClass::cast(receiver->elements()));
   9905   uint32_t len = static_cast<uint32_t>(array->length());
   9906 
   9907   ASSERT(visitor != NULL);
   9908   if (elements_are_ints) {
   9909     if (elements_are_guaranteed_smis) {
   9910       for (uint32_t j = 0; j < len; j++) {
   9911         HandleScope loop_scope(isolate);
   9912         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
   9913                       isolate);
   9914         visitor->visit(j, e);
   9915       }
   9916     } else {
   9917       for (uint32_t j = 0; j < len; j++) {
   9918         HandleScope loop_scope(isolate);
   9919         int64_t val = static_cast<int64_t>(array->get_scalar(j));
   9920         if (Smi::IsValid(static_cast<intptr_t>(val))) {
   9921           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
   9922           visitor->visit(j, e);
   9923         } else {
   9924           Handle<Object> e =
   9925               isolate->factory()->NewNumber(static_cast<ElementType>(val));
   9926           visitor->visit(j, e);
   9927         }
   9928       }
   9929     }
   9930   } else {
   9931     for (uint32_t j = 0; j < len; j++) {
   9932       HandleScope loop_scope(isolate);
   9933       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
   9934       visitor->visit(j, e);
   9935     }
   9936   }
   9937 }
   9938 
   9939 
   9940 // Used for sorting indices in a List<uint32_t>.
   9941 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
   9942   uint32_t a = *ap;
   9943   uint32_t b = *bp;
   9944   return (a == b) ? 0 : (a < b) ? -1 : 1;
   9945 }
   9946 
   9947 
   9948 static void CollectElementIndices(Handle<JSObject> object,
   9949                                   uint32_t range,
   9950                                   List<uint32_t>* indices) {
   9951   Isolate* isolate = object->GetIsolate();
   9952   ElementsKind kind = object->GetElementsKind();
   9953   switch (kind) {
   9954     case FAST_SMI_ELEMENTS:
   9955     case FAST_ELEMENTS:
   9956     case FAST_HOLEY_SMI_ELEMENTS:
   9957     case FAST_HOLEY_ELEMENTS: {
   9958       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
   9959       uint32_t length = static_cast<uint32_t>(elements->length());
   9960       if (range < length) length = range;
   9961       for (uint32_t i = 0; i < length; i++) {
   9962         if (!elements->get(i)->IsTheHole()) {
   9963           indices->Add(i);
   9964         }
   9965       }
   9966       break;
   9967     }
   9968     case FAST_HOLEY_DOUBLE_ELEMENTS:
   9969     case FAST_DOUBLE_ELEMENTS: {
   9970       // TODO(1810): Decide if it's worthwhile to implement this.
   9971       UNREACHABLE();
   9972       break;
   9973     }
   9974     case DICTIONARY_ELEMENTS: {
   9975       Handle<SeededNumberDictionary> dict(
   9976           SeededNumberDictionary::cast(object->elements()));
   9977       uint32_t capacity = dict->Capacity();
   9978       for (uint32_t j = 0; j < capacity; j++) {
   9979         HandleScope loop_scope(isolate);
   9980         Handle<Object> k(dict->KeyAt(j), isolate);
   9981         if (dict->IsKey(*k)) {
   9982           ASSERT(k->IsNumber());
   9983           uint32_t index = static_cast<uint32_t>(k->Number());
   9984           if (index < range) {
   9985             indices->Add(index);
   9986           }
   9987         }
   9988       }
   9989       break;
   9990     }
   9991     default: {
   9992       int dense_elements_length;
   9993       switch (kind) {
   9994         case EXTERNAL_PIXEL_ELEMENTS: {
   9995           dense_elements_length =
   9996               ExternalPixelArray::cast(object->elements())->length();
   9997           break;
   9998         }
   9999         case EXTERNAL_BYTE_ELEMENTS: {
   10000           dense_elements_length =
   10001               ExternalByteArray::cast(object->elements())->length();
   10002           break;
   10003         }
   10004         case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
   10005           dense_elements_length =
   10006               ExternalUnsignedByteArray::cast(object->elements())->length();
   10007           break;
   10008         }
   10009         case EXTERNAL_SHORT_ELEMENTS: {
   10010           dense_elements_length =
   10011               ExternalShortArray::cast(object->elements())->length();
   10012           break;
   10013         }
   10014         case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
   10015           dense_elements_length =
   10016               ExternalUnsignedShortArray::cast(object->elements())->length();
   10017           break;
   10018         }
   10019         case EXTERNAL_INT_ELEMENTS: {
   10020           dense_elements_length =
   10021               ExternalIntArray::cast(object->elements())->length();
   10022           break;
   10023         }
   10024         case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
   10025           dense_elements_length =
   10026               ExternalUnsignedIntArray::cast(object->elements())->length();
   10027           break;
   10028         }
   10029         case EXTERNAL_FLOAT_ELEMENTS: {
   10030           dense_elements_length =
   10031               ExternalFloatArray::cast(object->elements())->length();
   10032           break;
   10033         }
   10034         case EXTERNAL_DOUBLE_ELEMENTS: {
   10035           dense_elements_length =
   10036               ExternalDoubleArray::cast(object->elements())->length();
   10037           break;
   10038         }
   10039         default:
   10040           UNREACHABLE();
   10041           dense_elements_length = 0;
   10042           break;
   10043       }
   10044       uint32_t length = static_cast<uint32_t>(dense_elements_length);
   10045       if (range <= length) {
   10046         length = range;
   10047         // We will add all indices, so we might as well clear it first
   10048         // and avoid duplicates.
   10049         indices->Clear();
   10050       }
   10051       for (uint32_t i = 0; i < length; i++) {
   10052         indices->Add(i);
   10053       }
   10054       if (length == range) return;  // All indices accounted for already.
   10055       break;
   10056     }
   10057   }
   10058 
   10059   Handle<Object> prototype(object->GetPrototype(), isolate);
   10060   if (prototype->IsJSObject()) {
   10061     // The prototype will usually have no inherited element indices,
   10062     // but we have to check.
   10063     CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
   10064   }
   10065 }
   10066 
   10067 
   10068 /**
   10069  * A helper function that visits elements of a JSArray in numerical
   10070  * order.
   10071  *
   10072  * The visitor argument called for each existing element in the array
   10073  * with the element index and the element's value.
   10074  * Afterwards it increments the base-index of the visitor by the array
   10075  * length.
   10076  * Returns false if any access threw an exception, otherwise true.
   10077  */
   10078 static bool IterateElements(Isolate* isolate,
   10079                             Handle<JSArray> receiver,
   10080                             ArrayConcatVisitor* visitor) {
   10081   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
   10082   switch (receiver->GetElementsKind()) {
   10083     case FAST_SMI_ELEMENTS:
   10084     case FAST_ELEMENTS:
   10085     case FAST_HOLEY_SMI_ELEMENTS:
   10086     case FAST_HOLEY_ELEMENTS: {
   10087       // Run through the elements FixedArray and use HasElement and GetElement
   10088       // to check the prototype for missing elements.
   10089       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
   10090       int fast_length = static_cast<int>(length);
   10091       ASSERT(fast_length <= elements->length());
   10092       for (int j = 0; j < fast_length; j++) {
   10093         HandleScope loop_scope(isolate);
   10094         Handle<Object> element_value(elements->get(j), isolate);
   10095         if (!element_value->IsTheHole()) {
   10096           visitor->visit(j, element_value);
   10097         } else if (receiver->HasElement(j)) {
   10098           // Call GetElement on receiver, not its prototype, or getters won't
   10099           // have the correct receiver.
   10100           element_value = Object::GetElement(receiver, j);
   10101           RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
   10102           visitor->visit(j, element_value);
   10103         }
   10104       }
   10105       break;
   10106     }
   10107     case FAST_HOLEY_DOUBLE_ELEMENTS:
   10108     case FAST_DOUBLE_ELEMENTS: {
   10109       // Run through the elements FixedArray and use HasElement and GetElement
   10110       // to check the prototype for missing elements.
   10111       Handle<FixedDoubleArray> elements(
   10112           FixedDoubleArray::cast(receiver->elements()));
   10113       int fast_length = static_cast<int>(length);
   10114       ASSERT(fast_length <= elements->length());
   10115       for (int j = 0; j < fast_length; j++) {
   10116         HandleScope loop_scope(isolate);
   10117         if (!elements->is_the_hole(j)) {
   10118           double double_value = elements->get_scalar(j);
   10119           Handle<Object> element_value =
   10120               isolate->factory()->NewNumber(double_value);
   10121           visitor->visit(j, element_value);
   10122         } else if (receiver->HasElement(j)) {
   10123           // Call GetElement on receiver, not its prototype, or getters won't
   10124           // have the correct receiver.
   10125           Handle<Object> element_value = Object::GetElement(receiver, j);
   10126           RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
   10127           visitor->visit(j, element_value);
   10128         }
   10129       }
   10130       break;
   10131     }
   10132     case DICTIONARY_ELEMENTS: {
   10133       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
   10134       List<uint32_t> indices(dict->Capacity() / 2);
   10135       // Collect all indices in the object and the prototypes less
   10136       // than length. This might introduce duplicates in the indices list.
   10137       CollectElementIndices(receiver, length, &indices);
   10138       indices.Sort(&compareUInt32);
   10139       int j = 0;
   10140       int n = indices.length();
   10141       while (j < n) {
   10142         HandleScope loop_scope(isolate);
   10143         uint32_t index = indices[j];
   10144         Handle<Object> element = Object::GetElement(receiver, index);
   10145         RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
   10146         visitor->visit(index, element);
   10147         // Skip to next different index (i.e., omit duplicates).
   10148         do {
   10149           j++;
   10150         } while (j < n && indices[j] == index);
   10151       }
   10152       break;
   10153     }
   10154     case EXTERNAL_PIXEL_ELEMENTS: {
   10155       Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
   10156           receiver->elements()));
   10157       for (uint32_t j = 0; j < length; j++) {
   10158         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
   10159         visitor->visit(j, e);
   10160       }
   10161       break;
   10162     }
   10163     case EXTERNAL_BYTE_ELEMENTS: {
   10164       IterateExternalArrayElements<ExternalByteArray, int8_t>(
   10165           isolate, receiver, true, true, visitor);
   10166       break;
   10167     }
   10168     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
   10169       IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>(
   10170           isolate, receiver, true, true, visitor);
   10171       break;
   10172     }
   10173     case EXTERNAL_SHORT_ELEMENTS: {
   10174       IterateExternalArrayElements<ExternalShortArray, int16_t>(
   10175           isolate, receiver, true, true, visitor);
   10176       break;
   10177     }
   10178     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
   10179       IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>(
   10180           isolate, receiver, true, true, visitor);
   10181       break;
   10182     }
   10183     case EXTERNAL_INT_ELEMENTS: {
   10184       IterateExternalArrayElements<ExternalIntArray, int32_t>(
   10185           isolate, receiver, true, false, visitor);
   10186       break;
   10187     }
   10188     case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
   10189       IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>(
   10190           isolate, receiver, true, false, visitor);
   10191       break;
   10192     }
   10193     case EXTERNAL_FLOAT_ELEMENTS: {
   10194       IterateExternalArrayElements<ExternalFloatArray, float>(
   10195           isolate, receiver, false, false, visitor);
   10196       break;
   10197     }
   10198     case EXTERNAL_DOUBLE_ELEMENTS: {
   10199       IterateExternalArrayElements<ExternalDoubleArray, double>(
   10200           isolate, receiver, false, false, visitor);
   10201       break;
   10202     }
   10203     default:
   10204       UNREACHABLE();
   10205       break;
   10206   }
   10207   visitor->increase_index_offset(length);
   10208   return true;
   10209 }
   10210 
   10211 
   10212 /**
   10213  * Array::concat implementation.
   10214  * See ECMAScript 262, 15.4.4.4.
   10215  * TODO(581): Fix non-compliance for very large concatenations and update to
   10216  * following the ECMAScript 5 specification.
   10217  */
   10218 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
   10219   HandleScope handle_scope(isolate);
   10220   ASSERT(args.length() == 1);
   10221 
   10222   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
   10223   int argument_count = static_cast<int>(arguments->length()->Number());
   10224   RUNTIME_ASSERT(arguments->HasFastObjectElements());
   10225   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
   10226 
   10227   // Pass 1: estimate the length and number of elements of the result.
   10228   // The actual length can be larger if any of the arguments have getters
   10229   // that mutate other arguments (but will otherwise be precise).
   10230   // The number of elements is precise if there are no inherited elements.
   10231 
   10232   ElementsKind kind = FAST_SMI_ELEMENTS;
   10233 
   10234   uint32_t estimate_result_length = 0;
   10235   uint32_t estimate_nof_elements = 0;
   10236   for (int i = 0; i < argument_count; i++) {
   10237     HandleScope loop_scope(isolate);
   10238     Handle<Object> obj(elements->get(i), isolate);
   10239     uint32_t length_estimate;
   10240     uint32_t element_estimate;
   10241     if (obj->IsJSArray()) {
   10242       Handle<JSArray> array(Handle<JSArray>::cast(obj));
   10243       length_estimate = static_cast<uint32_t>(array->length()->Number());
   10244       if (length_estimate != 0) {
   10245         ElementsKind array_kind =
   10246             GetPackedElementsKind(array->map()->elements_kind());
   10247         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
   10248           kind = array_kind;
   10249         }
   10250       }
   10251       element_estimate = EstimateElementCount(array);
   10252     } else {
   10253       if (obj->IsHeapObject()) {
   10254         if (obj->IsNumber()) {
   10255           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
   10256             kind = FAST_DOUBLE_ELEMENTS;
   10257           }
   10258         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
   10259           kind = FAST_ELEMENTS;
   10260         }
   10261       }
   10262       length_estimate = 1;
   10263       element_estimate = 1;
   10264     }
   10265     // Avoid overflows by capping at kMaxElementCount.
   10266     if (JSObject::kMaxElementCount - estimate_result_length <
   10267         length_estimate) {
   10268       estimate_result_length = JSObject::kMaxElementCount;
   10269     } else {
   10270       estimate_result_length += length_estimate;
   10271     }
   10272     if (JSObject::kMaxElementCount - estimate_nof_elements <
   10273         element_estimate) {
   10274       estimate_nof_elements = JSObject::kMaxElementCount;
   10275     } else {
   10276       estimate_nof_elements += element_estimate;
   10277     }
   10278   }
   10279 
   10280   // If estimated number of elements is more than half of length, a
   10281   // fixed array (fast case) is more time and space-efficient than a
   10282   // dictionary.
   10283   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
   10284 
   10285   Handle<FixedArray> storage;
   10286   if (fast_case) {
   10287     if (kind == FAST_DOUBLE_ELEMENTS) {
   10288       Handle<FixedDoubleArray> double_storage =
   10289           isolate->factory()->NewFixedDoubleArray(estimate_result_length);
   10290       int j = 0;
   10291       bool failure = false;
   10292       for (int i = 0; i < argument_count; i++) {
   10293         Handle<Object> obj(elements->get(i), isolate);
   10294         if (obj->IsSmi()) {
   10295           double_storage->set(j, Smi::cast(*obj)->value());
   10296           j++;
   10297         } else if (obj->IsNumber()) {
   10298           double_storage->set(j, obj->Number());
   10299           j++;
   10300         } else {
   10301           JSArray* array = JSArray::cast(*obj);
   10302           uint32_t length = static_cast<uint32_t>(array->length()->Number());
   10303           switch (array->map()->elements_kind()) {
   10304             case FAST_HOLEY_DOUBLE_ELEMENTS:
   10305             case FAST_DOUBLE_ELEMENTS: {
   10306               // Empty fixed array indicates that there are no elements.
   10307               if (array->elements()->IsFixedArray()) break;
   10308               FixedDoubleArray* elements =
   10309                   FixedDoubleArray::cast(array->elements());
   10310               for (uint32_t i = 0; i < length; i++) {
   10311                 if (elements->is_the_hole(i)) {
   10312                   failure = true;
   10313                   break;
   10314                 }
   10315                 double double_value = elements->get_scalar(i);
   10316                 double_storage->set(j, double_value);
   10317                 j++;
   10318               }
   10319               break;
   10320             }
   10321             case FAST_HOLEY_SMI_ELEMENTS:
   10322             case FAST_SMI_ELEMENTS: {
   10323               FixedArray* elements(
   10324                   FixedArray::cast(array->elements()));
   10325               for (uint32_t i = 0; i < length; i++) {
   10326                 Object* element = elements->get(i);
   10327                 if (element->IsTheHole()) {
   10328                   failure = true;
   10329                   break;
   10330                 }
   10331                 int32_t int_value = Smi::cast(element)->value();
   10332                 double_storage->set(j, int_value);
   10333                 j++;
   10334               }
   10335               break;
   10336             }
   10337             case FAST_HOLEY_ELEMENTS:
   10338               ASSERT_EQ(0, length);
   10339               break;
   10340             default:
   10341               UNREACHABLE();
   10342           }
   10343         }
   10344         if (failure) break;
   10345       }
   10346       Handle<JSArray> array = isolate->factory()->NewJSArray(0);
   10347       Smi* length = Smi::FromInt(j);
   10348       Handle<Map> map;
   10349       map = isolate->factory()->GetElementsTransitionMap(array, kind);
   10350       array->set_map(*map);
   10351       array->set_length(length);
   10352       array->set_elements(*double_storage);
   10353       return *array;
   10354     }
   10355     // The backing storage array must have non-existing elements to preserve
   10356     // holes across concat operations.
   10357     storage = isolate->factory()->NewFixedArrayWithHoles(
   10358         estimate_result_length);
   10359   } else {
   10360     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
   10361     uint32_t at_least_space_for = estimate_nof_elements +
   10362                                   (estimate_nof_elements >> 2);
   10363     storage = Handle<FixedArray>::cast(
   10364         isolate->factory()->NewSeededNumberDictionary(at_least_space_for));
   10365   }
   10366 
   10367   ArrayConcatVisitor visitor(isolate, storage, fast_case);
   10368 
   10369   for (int i = 0; i < argument_count; i++) {
   10370     Handle<Object> obj(elements->get(i), isolate);
   10371     if (obj->IsJSArray()) {
   10372       Handle<JSArray> array = Handle<JSArray>::cast(obj);
   10373       if (!IterateElements(isolate, array, &visitor)) {
   10374         return Failure::Exception();
   10375       }
   10376     } else {
   10377       visitor.visit(0, obj);
   10378       visitor.increase_index_offset(1);
   10379     }
   10380   }
   10381 
   10382   if (visitor.exceeds_array_limit()) {
   10383     return isolate->Throw(
   10384         *isolate->factory()->NewRangeError("invalid_array_length",
   10385                                            HandleVector<Object>(NULL, 0)));
   10386   }
   10387   return *visitor.ToArray();
   10388 }
   10389 
   10390 
   10391 // This will not allocate (flatten the string), but it may run
   10392 // very slowly for very deeply nested ConsStrings.  For debugging use only.
   10393 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
   10394   SealHandleScope shs(isolate);
   10395   ASSERT(args.length() == 1);
   10396 
   10397   CONVERT_ARG_CHECKED(String, string, 0);
   10398   ConsStringIteratorOp op;
   10399   StringCharacterStream stream(string, &op);
   10400   while (stream.HasMore()) {
   10401     uint16_t character = stream.GetNext();
   10402     PrintF("%c", character);
   10403   }
   10404   return string;
   10405 }
   10406 
   10407 
   10408 // Moves all own elements of an object, that are below a limit, to positions
   10409 // starting at zero. All undefined values are placed after non-undefined values,
   10410 // and are followed by non-existing element. Does not change the length
   10411 // property.
   10412 // Returns the number of non-undefined elements collected.
   10413 RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
   10414   SealHandleScope shs(isolate);
   10415   ASSERT(args.length() == 2);
   10416   CONVERT_ARG_CHECKED(JSObject, object, 0);
   10417   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   10418   return object->PrepareElementsForSort(limit);
   10419 }
   10420 
   10421 
   10422 // Move contents of argument 0 (an array) to argument 1 (an array)
   10423 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
   10424   SealHandleScope shs(isolate);
   10425   ASSERT(args.length() == 2);
   10426   CONVERT_ARG_CHECKED(JSArray, from, 0);
   10427   CONVERT_ARG_CHECKED(JSArray, to, 1);
   10428   from->ValidateElements();
   10429   to->ValidateElements();
   10430   FixedArrayBase* new_elements = from->elements();
   10431   ElementsKind from_kind = from->GetElementsKind();
   10432   MaybeObject* maybe_new_map;
   10433   maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind);
   10434   Object* new_map;
   10435   if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
   10436   to->set_map_and_elements(Map::cast(new_map), new_elements);
   10437   to->set_length(from->length());
   10438   Object* obj;
   10439   { MaybeObject* maybe_obj = from->ResetElements();
   10440     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   10441   }
   10442   from->set_length(Smi::FromInt(0));
   10443   to->ValidateElements();
   10444   return to;
   10445 }
   10446 
   10447 
   10448 // How many elements does this object/array have?
   10449 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
   10450   SealHandleScope shs(isolate);
   10451   ASSERT(args.length() == 1);
   10452   CONVERT_ARG_CHECKED(JSObject, object, 0);
   10453   HeapObject* elements = object->elements();
   10454   if (elements->IsDictionary()) {
   10455     int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
   10456     return Smi::FromInt(result);
   10457   } else if (object->IsJSArray()) {
   10458     return JSArray::cast(object)->length();
   10459   } else {
   10460     return Smi::FromInt(FixedArray::cast(elements)->length());
   10461   }
   10462 }
   10463 
   10464 
   10465 // Returns an array that tells you where in the [0, length) interval an array
   10466 // might have elements.  Can either return an array of keys (positive integers
   10467 // or undefined) or a number representing the positive length of an interval
   10468 // starting at index 0.
   10469 // Intervals can span over some keys that are not in the object.
   10470 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
   10471   HandleScope scope(isolate);
   10472   ASSERT(args.length() == 2);
   10473   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   10474   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
   10475   if (array->elements()->IsDictionary()) {
   10476     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
   10477     for (Handle<Object> p = array;
   10478          !p->IsNull();
   10479          p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
   10480       if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
   10481         // Bail out if we find a proxy or interceptor, likely not worth
   10482         // collecting keys in that case.
   10483         return *isolate->factory()->NewNumberFromUint(length);
   10484       }
   10485       Handle<JSObject> current = Handle<JSObject>::cast(p);
   10486       Handle<FixedArray> current_keys =
   10487           isolate->factory()->NewFixedArray(
   10488               current->NumberOfLocalElements(NONE));
   10489       current->GetLocalElementKeys(*current_keys, NONE);
   10490       keys = UnionOfKeys(keys, current_keys);
   10491     }
   10492     // Erase any keys >= length.
   10493     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
   10494     // is changed to let this happen on the JS side.
   10495     for (int i = 0; i < keys->length(); i++) {
   10496       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
   10497     }
   10498     return *isolate->factory()->NewJSArrayWithElements(keys);
   10499   } else {
   10500     ASSERT(array->HasFastSmiOrObjectElements() ||
   10501            array->HasFastDoubleElements());
   10502     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
   10503     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
   10504   }
   10505 }
   10506 
   10507 
   10508 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
   10509   SealHandleScope shs(isolate);
   10510   ASSERT(args.length() == 3);
   10511   CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
   10512   CONVERT_ARG_CHECKED(Name, name, 1);
   10513   CONVERT_SMI_ARG_CHECKED(flag, 2);
   10514   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
   10515   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
   10516   return JSObject::cast(receiver)->LookupAccessor(name, component);
   10517 }
   10518 
   10519 
   10520 #ifdef ENABLE_DEBUGGER_SUPPORT
   10521 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
   10522   SealHandleScope shs(isolate);
   10523   ASSERT(args.length() == 0);
   10524   return Execution::DebugBreakHelper();
   10525 }
   10526 
   10527 
   10528 // Helper functions for wrapping and unwrapping stack frame ids.
   10529 static Smi* WrapFrameId(StackFrame::Id id) {
   10530   ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
   10531   return Smi::FromInt(id >> 2);
   10532 }
   10533 
   10534 
   10535 static StackFrame::Id UnwrapFrameId(int wrapped) {
   10536   return static_cast<StackFrame::Id>(wrapped << 2);
   10537 }
   10538 
   10539 
   10540 // Adds a JavaScript function as a debug event listener.
   10541 // args[0]: debug event listener function to set or null or undefined for
   10542 //          clearing the event listener function
   10543 // args[1]: object supplied during callback
   10544 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDebugEventListener) {
   10545   SealHandleScope shs(isolate);
   10546   ASSERT(args.length() == 2);
   10547   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
   10548                  args[0]->IsUndefined() ||
   10549                  args[0]->IsNull());
   10550   Handle<Object> callback = args.at<Object>(0);
   10551   Handle<Object> data = args.at<Object>(1);
   10552   isolate->debugger()->SetEventListener(callback, data);
   10553 
   10554   return isolate->heap()->undefined_value();
   10555 }
   10556 
   10557 
   10558 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
   10559   SealHandleScope shs(isolate);
   10560   ASSERT(args.length() == 0);
   10561   isolate->stack_guard()->DebugBreak();
   10562   return isolate->heap()->undefined_value();
   10563 }
   10564 
   10565 
   10566 static MaybeObject* DebugLookupResultValue(Heap* heap,
   10567                                            Object* receiver,
   10568                                            Name* name,
   10569                                            LookupResult* result,
   10570                                            bool* caught_exception) {
   10571   Object* value;
   10572   switch (result->type()) {
   10573     case NORMAL:
   10574       value = result->holder()->GetNormalizedProperty(result);
   10575       if (value->IsTheHole()) {
   10576         return heap->undefined_value();
   10577       }
   10578       return value;
   10579     case FIELD: {
   10580       Object* value;
   10581       MaybeObject* maybe_value =
   10582           JSObject::cast(result->holder())->FastPropertyAt(
   10583               result->representation(),
   10584               result->GetFieldIndex().field_index());
   10585       if (!maybe_value->To(&value)) return maybe_value;
   10586       if (value->IsTheHole()) {
   10587         return heap->undefined_value();
   10588       }
   10589       return value;
   10590     }
   10591     case CONSTANT:
   10592       return result->GetConstant();
   10593     case CALLBACKS: {
   10594       Object* structure = result->GetCallbackObject();
   10595       if (structure->IsForeign() || structure->IsAccessorInfo()) {
   10596         MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
   10597             receiver, structure, name);
   10598         if (!maybe_value->ToObject(&value)) {
   10599           if (maybe_value->IsRetryAfterGC()) return maybe_value;
   10600           ASSERT(maybe_value->IsException());
   10601           maybe_value = heap->isolate()->pending_exception();
   10602           heap->isolate()->clear_pending_exception();
   10603           if (caught_exception != NULL) {
   10604             *caught_exception = true;
   10605           }
   10606           return maybe_value;
   10607         }
   10608         return value;
   10609       } else {
   10610         return heap->undefined_value();
   10611       }
   10612     }
   10613     case INTERCEPTOR:
   10614     case TRANSITION:
   10615       return heap->undefined_value();
   10616     case HANDLER:
   10617     case NONEXISTENT:
   10618       UNREACHABLE();
   10619       return heap->undefined_value();
   10620   }
   10621   UNREACHABLE();  // keep the compiler happy
   10622   return heap->undefined_value();
   10623 }
   10624 
   10625 
   10626 // Get debugger related details for an object property.
   10627 // args[0]: object holding property
   10628 // args[1]: name of the property
   10629 //
   10630 // The array returned contains the following information:
   10631 // 0: Property value
   10632 // 1: Property details
   10633 // 2: Property value is exception
   10634 // 3: Getter function if defined
   10635 // 4: Setter function if defined
   10636 // Items 2-4 are only filled if the property has either a getter or a setter
   10637 // defined through __defineGetter__ and/or __defineSetter__.
   10638 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
   10639   HandleScope scope(isolate);
   10640 
   10641   ASSERT(args.length() == 2);
   10642 
   10643   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10644   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10645 
   10646   // Make sure to set the current context to the context before the debugger was
   10647   // entered (if the debugger is entered). The reason for switching context here
   10648   // is that for some property lookups (accessors and interceptors) callbacks
   10649   // into the embedding application can occour, and the embedding application
   10650   // could have the assumption that its own native context is the current
   10651   // context and not some internal debugger context.
   10652   SaveContext save(isolate);
   10653   if (isolate->debug()->InDebugger()) {
   10654     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
   10655   }
   10656 
   10657   // Skip the global proxy as it has no properties and always delegates to the
   10658   // real global object.
   10659   if (obj->IsJSGlobalProxy()) {
   10660     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   10661   }
   10662 
   10663 
   10664   // Check if the name is trivially convertible to an index and get the element
   10665   // if so.
   10666   uint32_t index;
   10667   if (name->AsArrayIndex(&index)) {
   10668     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
   10669     Object* element_or_char;
   10670     { MaybeObject* maybe_element_or_char =
   10671           Runtime::GetElementOrCharAt(isolate, obj, index);
   10672       if (!maybe_element_or_char->ToObject(&element_or_char)) {
   10673         return maybe_element_or_char;
   10674       }
   10675     }
   10676     details->set(0, element_or_char);
   10677     details->set(
   10678         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
   10679     return *isolate->factory()->NewJSArrayWithElements(details);
   10680   }
   10681 
   10682   // Find the number of objects making up this.
   10683   int length = LocalPrototypeChainLength(*obj);
   10684 
   10685   // Try local lookup on each of the objects.
   10686   Handle<JSObject> jsproto = obj;
   10687   for (int i = 0; i < length; i++) {
   10688     LookupResult result(isolate);
   10689     jsproto->LocalLookup(*name, &result);
   10690     if (result.IsFound()) {
   10691       // LookupResult is not GC safe as it holds raw object pointers.
   10692       // GC can happen later in this code so put the required fields into
   10693       // local variables using handles when required for later use.
   10694       Handle<Object> result_callback_obj;
   10695       if (result.IsPropertyCallbacks()) {
   10696         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
   10697                                              isolate);
   10698       }
   10699       Smi* property_details = result.GetPropertyDetails().AsSmi();
   10700       // DebugLookupResultValue can cause GC so details from LookupResult needs
   10701       // to be copied to handles before this.
   10702       bool caught_exception = false;
   10703       Object* raw_value;
   10704       { MaybeObject* maybe_raw_value =
   10705             DebugLookupResultValue(isolate->heap(), *obj, *name,
   10706                                    &result, &caught_exception);
   10707         if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value;
   10708       }
   10709       Handle<Object> value(raw_value, isolate);
   10710 
   10711       // If the callback object is a fixed array then it contains JavaScript
   10712       // getter and/or setter.
   10713       bool hasJavaScriptAccessors = result.IsPropertyCallbacks() &&
   10714                                     result_callback_obj->IsAccessorPair();
   10715       Handle<FixedArray> details =
   10716           isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
   10717       details->set(0, *value);
   10718       details->set(1, property_details);
   10719       if (hasJavaScriptAccessors) {
   10720         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
   10721         details->set(2, isolate->heap()->ToBoolean(caught_exception));
   10722         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
   10723         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
   10724       }
   10725 
   10726       return *isolate->factory()->NewJSArrayWithElements(details);
   10727     }
   10728     if (i < length - 1) {
   10729       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   10730     }
   10731   }
   10732 
   10733   return isolate->heap()->undefined_value();
   10734 }
   10735 
   10736 
   10737 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
   10738   HandleScope scope(isolate);
   10739 
   10740   ASSERT(args.length() == 2);
   10741 
   10742   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10743   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10744 
   10745   LookupResult result(isolate);
   10746   obj->Lookup(*name, &result);
   10747   if (result.IsFound()) {
   10748     return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
   10749   }
   10750   return isolate->heap()->undefined_value();
   10751 }
   10752 
   10753 
   10754 // Return the property type calculated from the property details.
   10755 // args[0]: smi with property details.
   10756 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
   10757   SealHandleScope shs(isolate);
   10758   ASSERT(args.length() == 1);
   10759   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10760   return Smi::FromInt(static_cast<int>(details.type()));
   10761 }
   10762 
   10763 
   10764 // Return the property attribute calculated from the property details.
   10765 // args[0]: smi with property details.
   10766 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
   10767   SealHandleScope shs(isolate);
   10768   ASSERT(args.length() == 1);
   10769   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10770   return Smi::FromInt(static_cast<int>(details.attributes()));
   10771 }
   10772 
   10773 
   10774 // Return the property insertion index calculated from the property details.
   10775 // args[0]: smi with property details.
   10776 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
   10777   SealHandleScope shs(isolate);
   10778   ASSERT(args.length() == 1);
   10779   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10780   // TODO(verwaest): Depends on the type of details.
   10781   return Smi::FromInt(details.dictionary_index());
   10782 }
   10783 
   10784 
   10785 // Return property value from named interceptor.
   10786 // args[0]: object
   10787 // args[1]: property name
   10788 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
   10789   HandleScope scope(isolate);
   10790   ASSERT(args.length() == 2);
   10791   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10792   RUNTIME_ASSERT(obj->HasNamedInterceptor());
   10793   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   10794 
   10795   PropertyAttributes attributes;
   10796   return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
   10797 }
   10798 
   10799 
   10800 // Return element value from indexed interceptor.
   10801 // args[0]: object
   10802 // args[1]: index
   10803 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
   10804   HandleScope scope(isolate);
   10805   ASSERT(args.length() == 2);
   10806   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10807   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
   10808   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
   10809 
   10810   return obj->GetElementWithInterceptor(*obj, index);
   10811 }
   10812 
   10813 
   10814 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckExecutionState) {
   10815   SealHandleScope shs(isolate);
   10816   ASSERT(args.length() >= 1);
   10817   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   10818   // Check that the break id is valid.
   10819   if (isolate->debug()->break_id() == 0 ||
   10820       break_id != isolate->debug()->break_id()) {
   10821     return isolate->Throw(
   10822         isolate->heap()->illegal_execution_state_string());
   10823   }
   10824 
   10825   return isolate->heap()->true_value();
   10826 }
   10827 
   10828 
   10829 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
   10830   HandleScope scope(isolate);
   10831   ASSERT(args.length() == 1);
   10832 
   10833   // Check arguments.
   10834   Object* result;
   10835   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   10836       RUNTIME_ARGUMENTS(isolate, args));
   10837     if (!maybe_result->ToObject(&result)) return maybe_result;
   10838   }
   10839 
   10840   // Count all frames which are relevant to debugging stack trace.
   10841   int n = 0;
   10842   StackFrame::Id id = isolate->debug()->break_frame_id();
   10843   if (id == StackFrame::NO_ID) {
   10844     // If there is no JavaScript stack frame count is 0.
   10845     return Smi::FromInt(0);
   10846   }
   10847 
   10848   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
   10849     n += it.frame()->GetInlineCount();
   10850   }
   10851   return Smi::FromInt(n);
   10852 }
   10853 
   10854 
   10855 class FrameInspector {
   10856  public:
   10857   FrameInspector(JavaScriptFrame* frame,
   10858                  int inlined_jsframe_index,
   10859                  Isolate* isolate)
   10860       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
   10861     // Calculate the deoptimized frame.
   10862     if (frame->is_optimized()) {
   10863       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
   10864           frame, inlined_jsframe_index, isolate);
   10865     }
   10866     has_adapted_arguments_ = frame_->has_adapted_arguments();
   10867     is_bottommost_ = inlined_jsframe_index == 0;
   10868     is_optimized_ = frame_->is_optimized();
   10869   }
   10870 
   10871   ~FrameInspector() {
   10872     // Get rid of the calculated deoptimized frame if any.
   10873     if (deoptimized_frame_ != NULL) {
   10874       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
   10875                                                   isolate_);
   10876     }
   10877   }
   10878 
   10879   int GetParametersCount() {
   10880     return is_optimized_
   10881         ? deoptimized_frame_->parameters_count()
   10882         : frame_->ComputeParametersCount();
   10883   }
   10884   int expression_count() { return deoptimized_frame_->expression_count(); }
   10885   Object* GetFunction() {
   10886     return is_optimized_
   10887         ? deoptimized_frame_->GetFunction()
   10888         : frame_->function();
   10889   }
   10890   Object* GetParameter(int index) {
   10891     return is_optimized_
   10892         ? deoptimized_frame_->GetParameter(index)
   10893         : frame_->GetParameter(index);
   10894   }
   10895   Object* GetExpression(int index) {
   10896     return is_optimized_
   10897         ? deoptimized_frame_->GetExpression(index)
   10898         : frame_->GetExpression(index);
   10899   }
   10900   int GetSourcePosition() {
   10901     return is_optimized_
   10902         ? deoptimized_frame_->GetSourcePosition()
   10903         : frame_->LookupCode()->SourcePosition(frame_->pc());
   10904   }
   10905   bool IsConstructor() {
   10906     return is_optimized_ && !is_bottommost_
   10907         ? deoptimized_frame_->HasConstructStub()
   10908         : frame_->IsConstructor();
   10909   }
   10910 
   10911   // To inspect all the provided arguments the frame might need to be
   10912   // replaced with the arguments frame.
   10913   void SetArgumentsFrame(JavaScriptFrame* frame) {
   10914     ASSERT(has_adapted_arguments_);
   10915     frame_ = frame;
   10916     is_optimized_ = frame_->is_optimized();
   10917     ASSERT(!is_optimized_);
   10918   }
   10919 
   10920  private:
   10921   JavaScriptFrame* frame_;
   10922   DeoptimizedFrameInfo* deoptimized_frame_;
   10923   Isolate* isolate_;
   10924   bool is_optimized_;
   10925   bool is_bottommost_;
   10926   bool has_adapted_arguments_;
   10927 
   10928   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
   10929 };
   10930 
   10931 
   10932 static const int kFrameDetailsFrameIdIndex = 0;
   10933 static const int kFrameDetailsReceiverIndex = 1;
   10934 static const int kFrameDetailsFunctionIndex = 2;
   10935 static const int kFrameDetailsArgumentCountIndex = 3;
   10936 static const int kFrameDetailsLocalCountIndex = 4;
   10937 static const int kFrameDetailsSourcePositionIndex = 5;
   10938 static const int kFrameDetailsConstructCallIndex = 6;
   10939 static const int kFrameDetailsAtReturnIndex = 7;
   10940 static const int kFrameDetailsFlagsIndex = 8;
   10941 static const int kFrameDetailsFirstDynamicIndex = 9;
   10942 
   10943 
   10944 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
   10945                                              JavaScriptFrame* frame) {
   10946   SaveContext* save = isolate->save_context();
   10947   while (save != NULL && !save->IsBelowFrame(frame)) {
   10948     save = save->prev();
   10949   }
   10950   ASSERT(save != NULL);
   10951   return save;
   10952 }
   10953 
   10954 
   10955 // Return an array with frame details
   10956 // args[0]: number: break id
   10957 // args[1]: number: frame index
   10958 //
   10959 // The array returned contains the following information:
   10960 // 0: Frame id
   10961 // 1: Receiver
   10962 // 2: Function
   10963 // 3: Argument count
   10964 // 4: Local count
   10965 // 5: Source position
   10966 // 6: Constructor call
   10967 // 7: Is at return
   10968 // 8: Flags
   10969 // Arguments name, value
   10970 // Locals name, value
   10971 // Return value if any
   10972 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   10973   HandleScope scope(isolate);
   10974   ASSERT(args.length() == 2);
   10975 
   10976   // Check arguments.
   10977   Object* check;
   10978   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   10979       RUNTIME_ARGUMENTS(isolate, args));
   10980     if (!maybe_check->ToObject(&check)) return maybe_check;
   10981   }
   10982   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   10983   Heap* heap = isolate->heap();
   10984 
   10985   // Find the relevant frame with the requested index.
   10986   StackFrame::Id id = isolate->debug()->break_frame_id();
   10987   if (id == StackFrame::NO_ID) {
   10988     // If there are no JavaScript stack frames return undefined.
   10989     return heap->undefined_value();
   10990   }
   10991 
   10992   int count = 0;
   10993   JavaScriptFrameIterator it(isolate, id);
   10994   for (; !it.done(); it.Advance()) {
   10995     if (index < count + it.frame()->GetInlineCount()) break;
   10996     count += it.frame()->GetInlineCount();
   10997   }
   10998   if (it.done()) return heap->undefined_value();
   10999 
   11000   bool is_optimized = it.frame()->is_optimized();
   11001 
   11002   int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
   11003   if (is_optimized) {
   11004     inlined_jsframe_index =
   11005         it.frame()->GetInlineCount() - (index - count) - 1;
   11006   }
   11007   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
   11008 
   11009   // Traverse the saved contexts chain to find the active context for the
   11010   // selected frame.
   11011   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
   11012 
   11013   // Get the frame id.
   11014   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
   11015 
   11016   // Find source position in unoptimized code.
   11017   int position = frame_inspector.GetSourcePosition();
   11018 
   11019   // Check for constructor frame.
   11020   bool constructor = frame_inspector.IsConstructor();
   11021 
   11022   // Get scope info and read from it for local variable information.
   11023   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11024   Handle<SharedFunctionInfo> shared(function->shared());
   11025   Handle<ScopeInfo> scope_info(shared->scope_info());
   11026   ASSERT(*scope_info != ScopeInfo::Empty(isolate));
   11027 
   11028   // Get the locals names and values into a temporary array.
   11029   //
   11030   // TODO(1240907): Hide compiler-introduced stack variables
   11031   // (e.g. .result)?  For users of the debugger, they will probably be
   11032   // confusing.
   11033   Handle<FixedArray> locals =
   11034       isolate->factory()->NewFixedArray(scope_info->LocalCount() * 2);
   11035 
   11036   // Fill in the values of the locals.
   11037   int i = 0;
   11038   for (; i < scope_info->StackLocalCount(); ++i) {
   11039     // Use the value from the stack.
   11040     locals->set(i * 2, scope_info->LocalName(i));
   11041     locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
   11042   }
   11043   if (i < scope_info->LocalCount()) {
   11044     // Get the context containing declarations.
   11045     Handle<Context> context(
   11046         Context::cast(it.frame()->context())->declaration_context());
   11047     for (; i < scope_info->LocalCount(); ++i) {
   11048       Handle<String> name(scope_info->LocalName(i));
   11049       VariableMode mode;
   11050       InitializationFlag init_flag;
   11051       locals->set(i * 2, *name);
   11052       locals->set(i * 2 + 1, context->get(
   11053           scope_info->ContextSlotIndex(*name, &mode, &init_flag)));
   11054     }
   11055   }
   11056 
   11057   // Check whether this frame is positioned at return. If not top
   11058   // frame or if the frame is optimized it cannot be at a return.
   11059   bool at_return = false;
   11060   if (!is_optimized && index == 0) {
   11061     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
   11062   }
   11063 
   11064   // If positioned just before return find the value to be returned and add it
   11065   // to the frame information.
   11066   Handle<Object> return_value = isolate->factory()->undefined_value();
   11067   if (at_return) {
   11068     StackFrameIterator it2(isolate);
   11069     Address internal_frame_sp = NULL;
   11070     while (!it2.done()) {
   11071       if (it2.frame()->is_internal()) {
   11072         internal_frame_sp = it2.frame()->sp();
   11073       } else {
   11074         if (it2.frame()->is_java_script()) {
   11075           if (it2.frame()->id() == it.frame()->id()) {
   11076             // The internal frame just before the JavaScript frame contains the
   11077             // value to return on top. A debug break at return will create an
   11078             // internal frame to store the return value (eax/rax/r0) before
   11079             // entering the debug break exit frame.
   11080             if (internal_frame_sp != NULL) {
   11081               return_value =
   11082                   Handle<Object>(Memory::Object_at(internal_frame_sp),
   11083                                  isolate);
   11084               break;
   11085             }
   11086           }
   11087         }
   11088 
   11089         // Indicate that the previous frame was not an internal frame.
   11090         internal_frame_sp = NULL;
   11091       }
   11092       it2.Advance();
   11093     }
   11094   }
   11095 
   11096   // Now advance to the arguments adapter frame (if any). It contains all
   11097   // the provided parameters whereas the function frame always have the number
   11098   // of arguments matching the functions parameters. The rest of the
   11099   // information (except for what is collected above) is the same.
   11100   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
   11101     it.AdvanceToArgumentsFrame();
   11102     frame_inspector.SetArgumentsFrame(it.frame());
   11103   }
   11104 
   11105   // Find the number of arguments to fill. At least fill the number of
   11106   // parameters for the function and fill more if more parameters are provided.
   11107   int argument_count = scope_info->ParameterCount();
   11108   if (argument_count < frame_inspector.GetParametersCount()) {
   11109     argument_count = frame_inspector.GetParametersCount();
   11110   }
   11111 
   11112   // Calculate the size of the result.
   11113   int details_size = kFrameDetailsFirstDynamicIndex +
   11114                      2 * (argument_count + scope_info->LocalCount()) +
   11115                      (at_return ? 1 : 0);
   11116   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   11117 
   11118   // Add the frame id.
   11119   details->set(kFrameDetailsFrameIdIndex, *frame_id);
   11120 
   11121   // Add the function (same as in function frame).
   11122   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
   11123 
   11124   // Add the arguments count.
   11125   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
   11126 
   11127   // Add the locals count
   11128   details->set(kFrameDetailsLocalCountIndex,
   11129                Smi::FromInt(scope_info->LocalCount()));
   11130 
   11131   // Add the source position.
   11132   if (position != RelocInfo::kNoPosition) {
   11133     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
   11134   } else {
   11135     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
   11136   }
   11137 
   11138   // Add the constructor information.
   11139   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
   11140 
   11141   // Add the at return information.
   11142   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
   11143 
   11144   // Add flags to indicate information on whether this frame is
   11145   //   bit 0: invoked in the debugger context.
   11146   //   bit 1: optimized frame.
   11147   //   bit 2: inlined in optimized frame
   11148   int flags = 0;
   11149   if (*save->context() == *isolate->debug()->debug_context()) {
   11150     flags |= 1 << 0;
   11151   }
   11152   if (is_optimized) {
   11153     flags |= 1 << 1;
   11154     flags |= inlined_jsframe_index << 2;
   11155   }
   11156   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
   11157 
   11158   // Fill the dynamic part.
   11159   int details_index = kFrameDetailsFirstDynamicIndex;
   11160 
   11161   // Add arguments name and value.
   11162   for (int i = 0; i < argument_count; i++) {
   11163     // Name of the argument.
   11164     if (i < scope_info->ParameterCount()) {
   11165       details->set(details_index++, scope_info->ParameterName(i));
   11166     } else {
   11167       details->set(details_index++, heap->undefined_value());
   11168     }
   11169 
   11170     // Parameter value.
   11171     if (i < frame_inspector.GetParametersCount()) {
   11172       // Get the value from the stack.
   11173       details->set(details_index++, frame_inspector.GetParameter(i));
   11174     } else {
   11175       details->set(details_index++, heap->undefined_value());
   11176     }
   11177   }
   11178 
   11179   // Add locals name and value from the temporary copy from the function frame.
   11180   for (int i = 0; i < scope_info->LocalCount() * 2; i++) {
   11181     details->set(details_index++, locals->get(i));
   11182   }
   11183 
   11184   // Add the value being returned.
   11185   if (at_return) {
   11186     details->set(details_index++, *return_value);
   11187   }
   11188 
   11189   // Add the receiver (same as in function frame).
   11190   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
   11191   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
   11192   Handle<Object> receiver(it.frame()->receiver(), isolate);
   11193   if (!receiver->IsJSObject() &&
   11194       shared->is_classic_mode() &&
   11195       !function->IsBuiltin()) {
   11196     // If the receiver is not a JSObject and the function is not a
   11197     // builtin or strict-mode we have hit an optimization where a
   11198     // value object is not converted into a wrapped JS objects. To
   11199     // hide this optimization from the debugger, we wrap the receiver
   11200     // by creating correct wrapper object based on the calling frame's
   11201     // native context.
   11202     it.Advance();
   11203     Handle<Context> calling_frames_native_context(
   11204         Context::cast(Context::cast(it.frame()->context())->native_context()));
   11205     ASSERT(!receiver->IsUndefined() && !receiver->IsNull());
   11206     receiver =
   11207         isolate->factory()->ToObject(receiver, calling_frames_native_context);
   11208   }
   11209   details->set(kFrameDetailsReceiverIndex, *receiver);
   11210 
   11211   ASSERT_EQ(details_size, details_index);
   11212   return *isolate->factory()->NewJSArrayWithElements(details);
   11213 }
   11214 
   11215 
   11216 // Create a plain JSObject which materializes the local scope for the specified
   11217 // frame.
   11218 static Handle<JSObject> MaterializeStackLocalsWithFrameInspector(
   11219     Isolate* isolate,
   11220     Handle<JSObject> target,
   11221     Handle<JSFunction> function,
   11222     FrameInspector* frame_inspector) {
   11223   Handle<SharedFunctionInfo> shared(function->shared());
   11224   Handle<ScopeInfo> scope_info(shared->scope_info());
   11225 
   11226   // First fill all parameters.
   11227   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11228     Handle<Object> value(i < frame_inspector->GetParametersCount()
   11229                              ? frame_inspector->GetParameter(i)
   11230                              : isolate->heap()->undefined_value(),
   11231                          isolate);
   11232     ASSERT(!value->IsTheHole());
   11233 
   11234     RETURN_IF_EMPTY_HANDLE_VALUE(
   11235         isolate,
   11236         SetProperty(isolate,
   11237                     target,
   11238                     Handle<String>(scope_info->ParameterName(i)),
   11239                     value,
   11240                     NONE,
   11241                     kNonStrictMode),
   11242         Handle<JSObject>());
   11243   }
   11244 
   11245   // Second fill all stack locals.
   11246   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11247     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
   11248     if (value->IsTheHole()) continue;
   11249 
   11250     RETURN_IF_EMPTY_HANDLE_VALUE(
   11251         isolate,
   11252         SetProperty(isolate,
   11253                     target,
   11254                     Handle<String>(scope_info->StackLocalName(i)),
   11255                     value,
   11256                     NONE,
   11257                     kNonStrictMode),
   11258         Handle<JSObject>());
   11259   }
   11260 
   11261   return target;
   11262 }
   11263 
   11264 
   11265 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
   11266                                                     Handle<JSObject> target,
   11267                                                     Handle<JSFunction> function,
   11268                                                     JavaScriptFrame* frame,
   11269                                                     int inlined_jsframe_index) {
   11270   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11271     // Optimized frames are not supported.
   11272     // TODO(yangguo): make sure all code deoptimized when debugger is active
   11273     //                and assert that this cannot happen.
   11274     return;
   11275   }
   11276 
   11277   Handle<SharedFunctionInfo> shared(function->shared());
   11278   Handle<ScopeInfo> scope_info(shared->scope_info());
   11279 
   11280   // Parameters.
   11281   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11282     ASSERT(!frame->GetParameter(i)->IsTheHole());
   11283     HandleScope scope(isolate);
   11284     Handle<Object> value = GetProperty(
   11285         isolate, target, Handle<String>(scope_info->ParameterName(i)));
   11286     frame->SetParameterValue(i, *value);
   11287   }
   11288 
   11289   // Stack locals.
   11290   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11291     if (frame->GetExpression(i)->IsTheHole()) continue;
   11292     HandleScope scope(isolate);
   11293     Handle<Object> value = GetProperty(
   11294         isolate, target, Handle<String>(scope_info->StackLocalName(i)));
   11295     frame->SetExpression(i, *value);
   11296   }
   11297 }
   11298 
   11299 
   11300 static Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
   11301                                                 Handle<JSObject> target,
   11302                                                 Handle<JSFunction> function,
   11303                                                 JavaScriptFrame* frame) {
   11304   HandleScope scope(isolate);
   11305   Handle<SharedFunctionInfo> shared(function->shared());
   11306   Handle<ScopeInfo> scope_info(shared->scope_info());
   11307 
   11308   if (!scope_info->HasContext()) return target;
   11309 
   11310   // Third fill all context locals.
   11311   Handle<Context> frame_context(Context::cast(frame->context()));
   11312   Handle<Context> function_context(frame_context->declaration_context());
   11313   if (!scope_info->CopyContextLocalsToScopeObject(
   11314           isolate, function_context, target)) {
   11315     return Handle<JSObject>();
   11316   }
   11317 
   11318   // Finally copy any properties from the function context extension.
   11319   // These will be variables introduced by eval.
   11320   if (function_context->closure() == *function) {
   11321     if (function_context->has_extension() &&
   11322         !function_context->IsNativeContext()) {
   11323       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11324       bool threw = false;
   11325       Handle<FixedArray> keys =
   11326           GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
   11327       if (threw) return Handle<JSObject>();
   11328 
   11329       for (int i = 0; i < keys->length(); i++) {
   11330         // Names of variables introduced by eval are strings.
   11331         ASSERT(keys->get(i)->IsString());
   11332         Handle<String> key(String::cast(keys->get(i)));
   11333         RETURN_IF_EMPTY_HANDLE_VALUE(
   11334             isolate,
   11335             SetProperty(isolate,
   11336                         target,
   11337                         key,
   11338                         GetProperty(isolate, ext, key),
   11339                         NONE,
   11340                         kNonStrictMode),
   11341             Handle<JSObject>());
   11342       }
   11343     }
   11344   }
   11345 
   11346   return target;
   11347 }
   11348 
   11349 
   11350 static Handle<JSObject> MaterializeLocalScope(
   11351     Isolate* isolate,
   11352     JavaScriptFrame* frame,
   11353     int inlined_jsframe_index) {
   11354   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   11355   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11356 
   11357   Handle<JSObject> local_scope =
   11358       isolate->factory()->NewJSObject(isolate->object_function());
   11359   local_scope = MaterializeStackLocalsWithFrameInspector(
   11360                     isolate, local_scope, function, &frame_inspector);
   11361   RETURN_IF_EMPTY_HANDLE_VALUE(isolate, local_scope, Handle<JSObject>());
   11362 
   11363   return MaterializeLocalContext(isolate, local_scope, function, frame);
   11364 }
   11365 
   11366 
   11367 // Set the context local variable value.
   11368 static bool SetContextLocalValue(Isolate* isolate,
   11369                                  Handle<ScopeInfo> scope_info,
   11370                                  Handle<Context> context,
   11371                                  Handle<String> variable_name,
   11372                                  Handle<Object> new_value) {
   11373   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
   11374     Handle<String> next_name(scope_info->ContextLocalName(i));
   11375     if (variable_name->Equals(*next_name)) {
   11376       VariableMode mode;
   11377       InitializationFlag init_flag;
   11378       int context_index =
   11379           scope_info->ContextSlotIndex(*next_name, &mode, &init_flag);
   11380       context->set(context_index, *new_value);
   11381       return true;
   11382     }
   11383   }
   11384 
   11385   return false;
   11386 }
   11387 
   11388 
   11389 static bool SetLocalVariableValue(Isolate* isolate,
   11390                                   JavaScriptFrame* frame,
   11391                                   int inlined_jsframe_index,
   11392                                   Handle<String> variable_name,
   11393                                   Handle<Object> new_value) {
   11394   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
   11395     // Optimized frames are not supported.
   11396     return false;
   11397   }
   11398 
   11399   Handle<JSFunction> function(frame->function());
   11400   Handle<SharedFunctionInfo> shared(function->shared());
   11401   Handle<ScopeInfo> scope_info(shared->scope_info());
   11402 
   11403   bool default_result = false;
   11404 
   11405   // Parameters.
   11406   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   11407     if (scope_info->ParameterName(i)->Equals(*variable_name)) {
   11408       frame->SetParameterValue(i, *new_value);
   11409       // Argument might be shadowed in heap context, don't stop here.
   11410       default_result = true;
   11411     }
   11412   }
   11413 
   11414   // Stack locals.
   11415   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   11416     if (scope_info->StackLocalName(i)->Equals(*variable_name)) {
   11417       frame->SetExpression(i, *new_value);
   11418       return true;
   11419     }
   11420   }
   11421 
   11422   if (scope_info->HasContext()) {
   11423     // Context locals.
   11424     Handle<Context> frame_context(Context::cast(frame->context()));
   11425     Handle<Context> function_context(frame_context->declaration_context());
   11426     if (SetContextLocalValue(
   11427         isolate, scope_info, function_context, variable_name, new_value)) {
   11428       return true;
   11429     }
   11430 
   11431     // Function context extension. These are variables introduced by eval.
   11432     if (function_context->closure() == *function) {
   11433       if (function_context->has_extension() &&
   11434           !function_context->IsNativeContext()) {
   11435         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   11436 
   11437         if (ext->HasProperty(*variable_name)) {
   11438           // We don't expect this to do anything except replacing
   11439           // property value.
   11440           SetProperty(isolate,
   11441                       ext,
   11442                       variable_name,
   11443                       new_value,
   11444                       NONE,
   11445                       kNonStrictMode);
   11446           return true;
   11447         }
   11448       }
   11449     }
   11450   }
   11451 
   11452   return default_result;
   11453 }
   11454 
   11455 
   11456 // Create a plain JSObject which materializes the closure content for the
   11457 // context.
   11458 static Handle<JSObject> MaterializeClosure(Isolate* isolate,
   11459                                            Handle<Context> context) {
   11460   ASSERT(context->IsFunctionContext());
   11461 
   11462   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11463   Handle<ScopeInfo> scope_info(shared->scope_info());
   11464 
   11465   // Allocate and initialize a JSObject with all the content of this function
   11466   // closure.
   11467   Handle<JSObject> closure_scope =
   11468       isolate->factory()->NewJSObject(isolate->object_function());
   11469 
   11470   // Fill all context locals to the context extension.
   11471   if (!scope_info->CopyContextLocalsToScopeObject(
   11472           isolate, context, closure_scope)) {
   11473     return Handle<JSObject>();
   11474   }
   11475 
   11476   // Finally copy any properties from the function context extension. This will
   11477   // be variables introduced by eval.
   11478   if (context->has_extension()) {
   11479     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11480     bool threw = false;
   11481     Handle<FixedArray> keys =
   11482         GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
   11483     if (threw) return Handle<JSObject>();
   11484 
   11485     for (int i = 0; i < keys->length(); i++) {
   11486       // Names of variables introduced by eval are strings.
   11487       ASSERT(keys->get(i)->IsString());
   11488       Handle<String> key(String::cast(keys->get(i)));
   11489        RETURN_IF_EMPTY_HANDLE_VALUE(
   11490           isolate,
   11491           SetProperty(isolate,
   11492                       closure_scope,
   11493                       key,
   11494                       GetProperty(isolate, ext, key),
   11495                       NONE,
   11496                       kNonStrictMode),
   11497           Handle<JSObject>());
   11498     }
   11499   }
   11500 
   11501   return closure_scope;
   11502 }
   11503 
   11504 
   11505 // This method copies structure of MaterializeClosure method above.
   11506 static bool SetClosureVariableValue(Isolate* isolate,
   11507                                     Handle<Context> context,
   11508                                     Handle<String> variable_name,
   11509                                     Handle<Object> new_value) {
   11510   ASSERT(context->IsFunctionContext());
   11511 
   11512   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   11513   Handle<ScopeInfo> scope_info(shared->scope_info());
   11514 
   11515   // Context locals to the context extension.
   11516   if (SetContextLocalValue(
   11517           isolate, scope_info, context, variable_name, new_value)) {
   11518     return true;
   11519   }
   11520 
   11521   // Properties from the function context extension. This will
   11522   // be variables introduced by eval.
   11523   if (context->has_extension()) {
   11524     Handle<JSObject> ext(JSObject::cast(context->extension()));
   11525     if (ext->HasProperty(*variable_name)) {
   11526       // We don't expect this to do anything except replacing property value.
   11527       SetProperty(isolate,
   11528                   ext,
   11529                   variable_name,
   11530                   new_value,
   11531                   NONE,
   11532                   kNonStrictMode);
   11533       return true;
   11534     }
   11535   }
   11536 
   11537   return false;
   11538 }
   11539 
   11540 
   11541 // Create a plain JSObject which materializes the scope for the specified
   11542 // catch context.
   11543 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
   11544                                               Handle<Context> context) {
   11545   ASSERT(context->IsCatchContext());
   11546   Handle<String> name(String::cast(context->extension()));
   11547   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
   11548                                isolate);
   11549   Handle<JSObject> catch_scope =
   11550       isolate->factory()->NewJSObject(isolate->object_function());
   11551   RETURN_IF_EMPTY_HANDLE_VALUE(
   11552       isolate,
   11553       SetProperty(isolate,
   11554                   catch_scope,
   11555                   name,
   11556                   thrown_object,
   11557                   NONE,
   11558                   kNonStrictMode),
   11559       Handle<JSObject>());
   11560   return catch_scope;
   11561 }
   11562 
   11563 
   11564 static bool SetCatchVariableValue(Isolate* isolate,
   11565                                   Handle<Context> context,
   11566                                   Handle<String> variable_name,
   11567                                   Handle<Object> new_value) {
   11568   ASSERT(context->IsCatchContext());
   11569   Handle<String> name(String::cast(context->extension()));
   11570   if (!name->Equals(*variable_name)) {
   11571     return false;
   11572   }
   11573   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
   11574   return true;
   11575 }
   11576 
   11577 
   11578 // Create a plain JSObject which materializes the block scope for the specified
   11579 // block context.
   11580 static Handle<JSObject> MaterializeBlockScope(
   11581     Isolate* isolate,
   11582     Handle<Context> context) {
   11583   ASSERT(context->IsBlockContext());
   11584   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11585 
   11586   // Allocate and initialize a JSObject with all the arguments, stack locals
   11587   // heap locals and extension properties of the debugged function.
   11588   Handle<JSObject> block_scope =
   11589       isolate->factory()->NewJSObject(isolate->object_function());
   11590 
   11591   // Fill all context locals.
   11592   if (!scope_info->CopyContextLocalsToScopeObject(
   11593           isolate, context, block_scope)) {
   11594     return Handle<JSObject>();
   11595   }
   11596 
   11597   return block_scope;
   11598 }
   11599 
   11600 
   11601 // Create a plain JSObject which materializes the module scope for the specified
   11602 // module context.
   11603 static Handle<JSObject> MaterializeModuleScope(
   11604     Isolate* isolate,
   11605     Handle<Context> context) {
   11606   ASSERT(context->IsModuleContext());
   11607   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   11608 
   11609   // Allocate and initialize a JSObject with all the members of the debugged
   11610   // module.
   11611   Handle<JSObject> module_scope =
   11612       isolate->factory()->NewJSObject(isolate->object_function());
   11613 
   11614   // Fill all context locals.
   11615   if (!scope_info->CopyContextLocalsToScopeObject(
   11616           isolate, context, module_scope)) {
   11617     return Handle<JSObject>();
   11618   }
   11619 
   11620   return module_scope;
   11621 }
   11622 
   11623 
   11624 // Iterate over the actual scopes visible from a stack frame or from a closure.
   11625 // The iteration proceeds from the innermost visible nested scope outwards.
   11626 // All scopes are backed by an actual context except the local scope,
   11627 // which is inserted "artificially" in the context chain.
   11628 class ScopeIterator {
   11629  public:
   11630   enum ScopeType {
   11631     ScopeTypeGlobal = 0,
   11632     ScopeTypeLocal,
   11633     ScopeTypeWith,
   11634     ScopeTypeClosure,
   11635     ScopeTypeCatch,
   11636     ScopeTypeBlock,
   11637     ScopeTypeModule
   11638   };
   11639 
   11640   ScopeIterator(Isolate* isolate,
   11641                 JavaScriptFrame* frame,
   11642                 int inlined_jsframe_index)
   11643     : isolate_(isolate),
   11644       frame_(frame),
   11645       inlined_jsframe_index_(inlined_jsframe_index),
   11646       function_(frame->function()),
   11647       context_(Context::cast(frame->context())),
   11648       nested_scope_chain_(4),
   11649       failed_(false) {
   11650 
   11651     // Catch the case when the debugger stops in an internal function.
   11652     Handle<SharedFunctionInfo> shared_info(function_->shared());
   11653     Handle<ScopeInfo> scope_info(shared_info->scope_info());
   11654     if (shared_info->script() == isolate->heap()->undefined_value()) {
   11655       while (context_->closure() == *function_) {
   11656         context_ = Handle<Context>(context_->previous(), isolate_);
   11657       }
   11658       return;
   11659     }
   11660 
   11661     // Get the debug info (create it if it does not exist).
   11662     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
   11663       // Return if ensuring debug info failed.
   11664       return;
   11665     }
   11666     Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
   11667 
   11668     // Find the break point where execution has stopped.
   11669     BreakLocationIterator break_location_iterator(debug_info,
   11670                                                   ALL_BREAK_LOCATIONS);
   11671     // pc points to the instruction after the current one, possibly a break
   11672     // location as well. So the "- 1" to exclude it from the search.
   11673     break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
   11674     if (break_location_iterator.IsExit()) {
   11675       // We are within the return sequence. At the momemt it is not possible to
   11676       // get a source position which is consistent with the current scope chain.
   11677       // Thus all nested with, catch and block contexts are skipped and we only
   11678       // provide the function scope.
   11679       if (scope_info->HasContext()) {
   11680         context_ = Handle<Context>(context_->declaration_context(), isolate_);
   11681       } else {
   11682         while (context_->closure() == *function_) {
   11683           context_ = Handle<Context>(context_->previous(), isolate_);
   11684         }
   11685       }
   11686       if (scope_info->scope_type() != EVAL_SCOPE) {
   11687         nested_scope_chain_.Add(scope_info);
   11688       }
   11689     } else {
   11690       // Reparse the code and analyze the scopes.
   11691       Handle<Script> script(Script::cast(shared_info->script()));
   11692       Scope* scope = NULL;
   11693 
   11694       // Check whether we are in global, eval or function code.
   11695       Handle<ScopeInfo> scope_info(shared_info->scope_info());
   11696       if (scope_info->scope_type() != FUNCTION_SCOPE) {
   11697         // Global or eval code.
   11698         CompilationInfoWithZone info(script);
   11699         if (scope_info->scope_type() == GLOBAL_SCOPE) {
   11700           info.MarkAsGlobal();
   11701         } else {
   11702           ASSERT(scope_info->scope_type() == EVAL_SCOPE);
   11703           info.MarkAsEval();
   11704           info.SetContext(Handle<Context>(function_->context()));
   11705         }
   11706         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   11707           scope = info.function()->scope();
   11708         }
   11709         RetrieveScopeChain(scope, shared_info);
   11710       } else {
   11711         // Function code
   11712         CompilationInfoWithZone info(shared_info);
   11713         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
   11714           scope = info.function()->scope();
   11715         }
   11716         RetrieveScopeChain(scope, shared_info);
   11717       }
   11718     }
   11719   }
   11720 
   11721   ScopeIterator(Isolate* isolate,
   11722                 Handle<JSFunction> function)
   11723     : isolate_(isolate),
   11724       frame_(NULL),
   11725       inlined_jsframe_index_(0),
   11726       function_(function),
   11727       context_(function->context()),
   11728       failed_(false) {
   11729     if (function->IsBuiltin()) {
   11730       context_ = Handle<Context>();
   11731     }
   11732   }
   11733 
   11734   // More scopes?
   11735   bool Done() {
   11736     ASSERT(!failed_);
   11737     return context_.is_null();
   11738   }
   11739 
   11740   bool Failed() { return failed_; }
   11741 
   11742   // Move to the next scope.
   11743   void Next() {
   11744     ASSERT(!failed_);
   11745     ScopeType scope_type = Type();
   11746     if (scope_type == ScopeTypeGlobal) {
   11747       // The global scope is always the last in the chain.
   11748       ASSERT(context_->IsNativeContext());
   11749       context_ = Handle<Context>();
   11750       return;
   11751     }
   11752     if (nested_scope_chain_.is_empty()) {
   11753       context_ = Handle<Context>(context_->previous(), isolate_);
   11754     } else {
   11755       if (nested_scope_chain_.last()->HasContext()) {
   11756         ASSERT(context_->previous() != NULL);
   11757         context_ = Handle<Context>(context_->previous(), isolate_);
   11758       }
   11759       nested_scope_chain_.RemoveLast();
   11760     }
   11761   }
   11762 
   11763   // Return the type of the current scope.
   11764   ScopeType Type() {
   11765     ASSERT(!failed_);
   11766     if (!nested_scope_chain_.is_empty()) {
   11767       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
   11768       switch (scope_info->scope_type()) {
   11769         case FUNCTION_SCOPE:
   11770           ASSERT(context_->IsFunctionContext() ||
   11771                  !scope_info->HasContext());
   11772           return ScopeTypeLocal;
   11773         case MODULE_SCOPE:
   11774           ASSERT(context_->IsModuleContext());
   11775           return ScopeTypeModule;
   11776         case GLOBAL_SCOPE:
   11777           ASSERT(context_->IsNativeContext());
   11778           return ScopeTypeGlobal;
   11779         case WITH_SCOPE:
   11780           ASSERT(context_->IsWithContext());
   11781           return ScopeTypeWith;
   11782         case CATCH_SCOPE:
   11783           ASSERT(context_->IsCatchContext());
   11784           return ScopeTypeCatch;
   11785         case BLOCK_SCOPE:
   11786           ASSERT(!scope_info->HasContext() ||
   11787                  context_->IsBlockContext());
   11788           return ScopeTypeBlock;
   11789         case EVAL_SCOPE:
   11790           UNREACHABLE();
   11791       }
   11792     }
   11793     if (context_->IsNativeContext()) {
   11794       ASSERT(context_->global_object()->IsGlobalObject());
   11795       return ScopeTypeGlobal;
   11796     }
   11797     if (context_->IsFunctionContext()) {
   11798       return ScopeTypeClosure;
   11799     }
   11800     if (context_->IsCatchContext()) {
   11801       return ScopeTypeCatch;
   11802     }
   11803     if (context_->IsBlockContext()) {
   11804       return ScopeTypeBlock;
   11805     }
   11806     if (context_->IsModuleContext()) {
   11807       return ScopeTypeModule;
   11808     }
   11809     ASSERT(context_->IsWithContext());
   11810     return ScopeTypeWith;
   11811   }
   11812 
   11813   // Return the JavaScript object with the content of the current scope.
   11814   Handle<JSObject> ScopeObject() {
   11815     ASSERT(!failed_);
   11816     switch (Type()) {
   11817       case ScopeIterator::ScopeTypeGlobal:
   11818         return Handle<JSObject>(CurrentContext()->global_object());
   11819       case ScopeIterator::ScopeTypeLocal:
   11820         // Materialize the content of the local scope into a JSObject.
   11821         ASSERT(nested_scope_chain_.length() == 1);
   11822         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
   11823       case ScopeIterator::ScopeTypeWith:
   11824         // Return the with object.
   11825         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
   11826       case ScopeIterator::ScopeTypeCatch:
   11827         return MaterializeCatchScope(isolate_, CurrentContext());
   11828       case ScopeIterator::ScopeTypeClosure:
   11829         // Materialize the content of the closure scope into a JSObject.
   11830         return MaterializeClosure(isolate_, CurrentContext());
   11831       case ScopeIterator::ScopeTypeBlock:
   11832         return MaterializeBlockScope(isolate_, CurrentContext());
   11833       case ScopeIterator::ScopeTypeModule:
   11834         return MaterializeModuleScope(isolate_, CurrentContext());
   11835     }
   11836     UNREACHABLE();
   11837     return Handle<JSObject>();
   11838   }
   11839 
   11840   bool SetVariableValue(Handle<String> variable_name,
   11841                         Handle<Object> new_value) {
   11842     ASSERT(!failed_);
   11843     switch (Type()) {
   11844       case ScopeIterator::ScopeTypeGlobal:
   11845         break;
   11846       case ScopeIterator::ScopeTypeLocal:
   11847         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
   11848             variable_name, new_value);
   11849       case ScopeIterator::ScopeTypeWith:
   11850         break;
   11851       case ScopeIterator::ScopeTypeCatch:
   11852         return SetCatchVariableValue(isolate_, CurrentContext(),
   11853             variable_name, new_value);
   11854       case ScopeIterator::ScopeTypeClosure:
   11855         return SetClosureVariableValue(isolate_, CurrentContext(),
   11856             variable_name, new_value);
   11857       case ScopeIterator::ScopeTypeBlock:
   11858         // TODO(2399): should we implement it?
   11859         break;
   11860       case ScopeIterator::ScopeTypeModule:
   11861         // TODO(2399): should we implement it?
   11862         break;
   11863     }
   11864     return false;
   11865   }
   11866 
   11867   Handle<ScopeInfo> CurrentScopeInfo() {
   11868     ASSERT(!failed_);
   11869     if (!nested_scope_chain_.is_empty()) {
   11870       return nested_scope_chain_.last();
   11871     } else if (context_->IsBlockContext()) {
   11872       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
   11873     } else if (context_->IsFunctionContext()) {
   11874       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
   11875     }
   11876     return Handle<ScopeInfo>::null();
   11877   }
   11878 
   11879   // Return the context for this scope. For the local context there might not
   11880   // be an actual context.
   11881   Handle<Context> CurrentContext() {
   11882     ASSERT(!failed_);
   11883     if (Type() == ScopeTypeGlobal ||
   11884         nested_scope_chain_.is_empty()) {
   11885       return context_;
   11886     } else if (nested_scope_chain_.last()->HasContext()) {
   11887       return context_;
   11888     } else {
   11889       return Handle<Context>();
   11890     }
   11891   }
   11892 
   11893 #ifdef DEBUG
   11894   // Debug print of the content of the current scope.
   11895   void DebugPrint() {
   11896     ASSERT(!failed_);
   11897     switch (Type()) {
   11898       case ScopeIterator::ScopeTypeGlobal:
   11899         PrintF("Global:\n");
   11900         CurrentContext()->Print();
   11901         break;
   11902 
   11903       case ScopeIterator::ScopeTypeLocal: {
   11904         PrintF("Local:\n");
   11905         function_->shared()->scope_info()->Print();
   11906         if (!CurrentContext().is_null()) {
   11907           CurrentContext()->Print();
   11908           if (CurrentContext()->has_extension()) {
   11909             Handle<Object> extension(CurrentContext()->extension(), isolate_);
   11910             if (extension->IsJSContextExtensionObject()) {
   11911               extension->Print();
   11912             }
   11913           }
   11914         }
   11915         break;
   11916       }
   11917 
   11918       case ScopeIterator::ScopeTypeWith:
   11919         PrintF("With:\n");
   11920         CurrentContext()->extension()->Print();
   11921         break;
   11922 
   11923       case ScopeIterator::ScopeTypeCatch:
   11924         PrintF("Catch:\n");
   11925         CurrentContext()->extension()->Print();
   11926         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
   11927         break;
   11928 
   11929       case ScopeIterator::ScopeTypeClosure:
   11930         PrintF("Closure:\n");
   11931         CurrentContext()->Print();
   11932         if (CurrentContext()->has_extension()) {
   11933           Handle<Object> extension(CurrentContext()->extension(), isolate_);
   11934           if (extension->IsJSContextExtensionObject()) {
   11935             extension->Print();
   11936           }
   11937         }
   11938         break;
   11939 
   11940       default:
   11941         UNREACHABLE();
   11942     }
   11943     PrintF("\n");
   11944   }
   11945 #endif
   11946 
   11947  private:
   11948   Isolate* isolate_;
   11949   JavaScriptFrame* frame_;
   11950   int inlined_jsframe_index_;
   11951   Handle<JSFunction> function_;
   11952   Handle<Context> context_;
   11953   List<Handle<ScopeInfo> > nested_scope_chain_;
   11954   bool failed_;
   11955 
   11956   void RetrieveScopeChain(Scope* scope,
   11957                           Handle<SharedFunctionInfo> shared_info) {
   11958     if (scope != NULL) {
   11959       int source_position = shared_info->code()->SourcePosition(frame_->pc());
   11960       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
   11961     } else {
   11962       // A failed reparse indicates that the preparser has diverged from the
   11963       // parser or that the preparse data given to the initial parse has been
   11964       // faulty. We fail in debug mode but in release mode we only provide the
   11965       // information we get from the context chain but nothing about
   11966       // completely stack allocated scopes or stack allocated locals.
   11967       // Or it could be due to stack overflow.
   11968       ASSERT(isolate_->has_pending_exception());
   11969       failed_ = true;
   11970     }
   11971   }
   11972 
   11973   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
   11974 };
   11975 
   11976 
   11977 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
   11978   HandleScope scope(isolate);
   11979   ASSERT(args.length() == 2);
   11980 
   11981   // Check arguments.
   11982   Object* check;
   11983   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   11984       RUNTIME_ARGUMENTS(isolate, args));
   11985     if (!maybe_check->ToObject(&check)) return maybe_check;
   11986   }
   11987   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   11988 
   11989   // Get the frame where the debugging is performed.
   11990   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   11991   JavaScriptFrameIterator it(isolate, id);
   11992   JavaScriptFrame* frame = it.frame();
   11993 
   11994   // Count the visible scopes.
   11995   int n = 0;
   11996   for (ScopeIterator it(isolate, frame, 0);
   11997        !it.Done();
   11998        it.Next()) {
   11999     n++;
   12000   }
   12001 
   12002   return Smi::FromInt(n);
   12003 }
   12004 
   12005 
   12006 // Returns the list of step-in positions (text offset) in a function of the
   12007 // stack frame in a range from the current debug break position to the end
   12008 // of the corresponding statement.
   12009 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
   12010   HandleScope scope(isolate);
   12011   ASSERT(args.length() == 2);
   12012 
   12013   // Check arguments.
   12014   Object* check;
   12015   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12016       RUNTIME_ARGUMENTS(isolate, args));
   12017     if (!maybe_check->ToObject(&check)) return maybe_check;
   12018   }
   12019   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12020 
   12021   // Get the frame where the debugging is performed.
   12022   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12023   JavaScriptFrameIterator frame_it(isolate, id);
   12024   JavaScriptFrame* frame = frame_it.frame();
   12025 
   12026   Handle<JSFunction> fun =
   12027       Handle<JSFunction>(frame->function());
   12028   Handle<SharedFunctionInfo> shared =
   12029       Handle<SharedFunctionInfo>(fun->shared());
   12030 
   12031   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
   12032     return isolate->heap()->undefined_value();
   12033   }
   12034 
   12035   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
   12036 
   12037   int len = 0;
   12038   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
   12039   // Find the break point where execution has stopped.
   12040   BreakLocationIterator break_location_iterator(debug_info,
   12041                                                 ALL_BREAK_LOCATIONS);
   12042 
   12043   break_location_iterator.FindBreakLocationFromAddress(frame->pc());
   12044   int current_statement_pos = break_location_iterator.statement_position();
   12045 
   12046   while (!break_location_iterator.Done()) {
   12047     if (break_location_iterator.pc() > frame->pc()) {
   12048       if (break_location_iterator.IsStepInLocation(isolate)) {
   12049         Smi* position_value = Smi::FromInt(break_location_iterator.position());
   12050         JSObject::SetElement(array, len,
   12051             Handle<Object>(position_value, isolate),
   12052             NONE, kNonStrictMode);
   12053         len++;
   12054       }
   12055     }
   12056     // Advance iterator.
   12057     break_location_iterator.Next();
   12058     if (current_statement_pos !=
   12059         break_location_iterator.statement_position()) {
   12060       break;
   12061     }
   12062   }
   12063   return *array;
   12064 }
   12065 
   12066 
   12067 static const int kScopeDetailsTypeIndex = 0;
   12068 static const int kScopeDetailsObjectIndex = 1;
   12069 static const int kScopeDetailsSize = 2;
   12070 
   12071 
   12072 static MaybeObject* MaterializeScopeDetails(Isolate* isolate,
   12073     ScopeIterator* it) {
   12074   // Calculate the size of the result.
   12075   int details_size = kScopeDetailsSize;
   12076   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   12077 
   12078   // Fill in scope details.
   12079   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
   12080   Handle<JSObject> scope_object = it->ScopeObject();
   12081   RETURN_IF_EMPTY_HANDLE(isolate, scope_object);
   12082   details->set(kScopeDetailsObjectIndex, *scope_object);
   12083 
   12084   return *isolate->factory()->NewJSArrayWithElements(details);
   12085 }
   12086 
   12087 
   12088 // Return an array with scope details
   12089 // args[0]: number: break id
   12090 // args[1]: number: frame index
   12091 // args[2]: number: inlined frame index
   12092 // args[3]: number: scope index
   12093 //
   12094 // The array returned contains the following information:
   12095 // 0: Scope type
   12096 // 1: Scope object
   12097 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
   12098   HandleScope scope(isolate);
   12099   ASSERT(args.length() == 4);
   12100 
   12101   // Check arguments.
   12102   Object* check;
   12103   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12104       RUNTIME_ARGUMENTS(isolate, args));
   12105     if (!maybe_check->ToObject(&check)) return maybe_check;
   12106   }
   12107   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12108   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12109   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12110 
   12111   // Get the frame where the debugging is performed.
   12112   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12113   JavaScriptFrameIterator frame_it(isolate, id);
   12114   JavaScriptFrame* frame = frame_it.frame();
   12115 
   12116   // Find the requested scope.
   12117   int n = 0;
   12118   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12119   for (; !it.Done() && n < index; it.Next()) {
   12120     n++;
   12121   }
   12122   if (it.Done()) {
   12123     return isolate->heap()->undefined_value();
   12124   }
   12125   return MaterializeScopeDetails(isolate, &it);
   12126 }
   12127 
   12128 
   12129 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
   12130   HandleScope scope(isolate);
   12131   ASSERT(args.length() == 1);
   12132 
   12133   // Check arguments.
   12134   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12135 
   12136   // Count the visible scopes.
   12137   int n = 0;
   12138   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
   12139     n++;
   12140   }
   12141 
   12142   return Smi::FromInt(n);
   12143 }
   12144 
   12145 
   12146 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) {
   12147   HandleScope scope(isolate);
   12148   ASSERT(args.length() == 2);
   12149 
   12150   // Check arguments.
   12151   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12152   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12153 
   12154   // Find the requested scope.
   12155   int n = 0;
   12156   ScopeIterator it(isolate, fun);
   12157   for (; !it.Done() && n < index; it.Next()) {
   12158     n++;
   12159   }
   12160   if (it.Done()) {
   12161     return isolate->heap()->undefined_value();
   12162   }
   12163 
   12164   return MaterializeScopeDetails(isolate, &it);
   12165 }
   12166 
   12167 
   12168 static bool SetScopeVariableValue(ScopeIterator* it, int index,
   12169                                   Handle<String> variable_name,
   12170                                   Handle<Object> new_value) {
   12171   for (int n = 0; !it->Done() && n < index; it->Next()) {
   12172     n++;
   12173   }
   12174   if (it->Done()) {
   12175     return false;
   12176   }
   12177   return it->SetVariableValue(variable_name, new_value);
   12178 }
   12179 
   12180 
   12181 // Change variable value in closure or local scope
   12182 // args[0]: number or JsFunction: break id or function
   12183 // args[1]: number: frame index (when arg[0] is break id)
   12184 // args[2]: number: inlined frame index (when arg[0] is break id)
   12185 // args[3]: number: scope index
   12186 // args[4]: string: variable name
   12187 // args[5]: object: new value
   12188 //
   12189 // Return true if success and false otherwise
   12190 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) {
   12191   HandleScope scope(isolate);
   12192   ASSERT(args.length() == 6);
   12193 
   12194   // Check arguments.
   12195   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   12196   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
   12197   Handle<Object> new_value = args.at<Object>(5);
   12198 
   12199   bool res;
   12200   if (args[0]->IsNumber()) {
   12201     Object* check;
   12202     { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12203         RUNTIME_ARGUMENTS(isolate, args));
   12204       if (!maybe_check->ToObject(&check)) return maybe_check;
   12205     }
   12206     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12207     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12208 
   12209     // Get the frame where the debugging is performed.
   12210     StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12211     JavaScriptFrameIterator frame_it(isolate, id);
   12212     JavaScriptFrame* frame = frame_it.frame();
   12213 
   12214     ScopeIterator it(isolate, frame, inlined_jsframe_index);
   12215     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12216   } else {
   12217     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12218     ScopeIterator it(isolate, fun);
   12219     res = SetScopeVariableValue(&it, index, variable_name, new_value);
   12220   }
   12221 
   12222   return isolate->heap()->ToBoolean(res);
   12223 }
   12224 
   12225 
   12226 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
   12227   HandleScope scope(isolate);
   12228   ASSERT(args.length() == 0);
   12229 
   12230 #ifdef DEBUG
   12231   // Print the scopes for the top frame.
   12232   StackFrameLocator locator(isolate);
   12233   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
   12234   for (ScopeIterator it(isolate, frame, 0);
   12235        !it.Done();
   12236        it.Next()) {
   12237     it.DebugPrint();
   12238   }
   12239 #endif
   12240   return isolate->heap()->undefined_value();
   12241 }
   12242 
   12243 
   12244 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
   12245   HandleScope scope(isolate);
   12246   ASSERT(args.length() == 1);
   12247 
   12248   // Check arguments.
   12249   Object* result;
   12250   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   12251       RUNTIME_ARGUMENTS(isolate, args));
   12252     if (!maybe_result->ToObject(&result)) return maybe_result;
   12253   }
   12254 
   12255   // Count all archived V8 threads.
   12256   int n = 0;
   12257   for (ThreadState* thread =
   12258           isolate->thread_manager()->FirstThreadStateInUse();
   12259        thread != NULL;
   12260        thread = thread->Next()) {
   12261     n++;
   12262   }
   12263 
   12264   // Total number of threads is current thread and archived threads.
   12265   return Smi::FromInt(n + 1);
   12266 }
   12267 
   12268 
   12269 static const int kThreadDetailsCurrentThreadIndex = 0;
   12270 static const int kThreadDetailsThreadIdIndex = 1;
   12271 static const int kThreadDetailsSize = 2;
   12272 
   12273 // Return an array with thread details
   12274 // args[0]: number: break id
   12275 // args[1]: number: thread index
   12276 //
   12277 // The array returned contains the following information:
   12278 // 0: Is current thread?
   12279 // 1: Thread id
   12280 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
   12281   HandleScope scope(isolate);
   12282   ASSERT(args.length() == 2);
   12283 
   12284   // Check arguments.
   12285   Object* check;
   12286   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12287       RUNTIME_ARGUMENTS(isolate, args));
   12288     if (!maybe_check->ToObject(&check)) return maybe_check;
   12289   }
   12290   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   12291 
   12292   // Allocate array for result.
   12293   Handle<FixedArray> details =
   12294       isolate->factory()->NewFixedArray(kThreadDetailsSize);
   12295 
   12296   // Thread index 0 is current thread.
   12297   if (index == 0) {
   12298     // Fill the details.
   12299     details->set(kThreadDetailsCurrentThreadIndex,
   12300                  isolate->heap()->true_value());
   12301     details->set(kThreadDetailsThreadIdIndex,
   12302                  Smi::FromInt(ThreadId::Current().ToInteger()));
   12303   } else {
   12304     // Find the thread with the requested index.
   12305     int n = 1;
   12306     ThreadState* thread =
   12307         isolate->thread_manager()->FirstThreadStateInUse();
   12308     while (index != n && thread != NULL) {
   12309       thread = thread->Next();
   12310       n++;
   12311     }
   12312     if (thread == NULL) {
   12313       return isolate->heap()->undefined_value();
   12314     }
   12315 
   12316     // Fill the details.
   12317     details->set(kThreadDetailsCurrentThreadIndex,
   12318                  isolate->heap()->false_value());
   12319     details->set(kThreadDetailsThreadIdIndex,
   12320                  Smi::FromInt(thread->id().ToInteger()));
   12321   }
   12322 
   12323   // Convert to JS array and return.
   12324   return *isolate->factory()->NewJSArrayWithElements(details);
   12325 }
   12326 
   12327 
   12328 // Sets the disable break state
   12329 // args[0]: disable break state
   12330 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDisableBreak) {
   12331   HandleScope scope(isolate);
   12332   ASSERT(args.length() == 1);
   12333   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
   12334   isolate->debug()->set_disable_break(disable_break);
   12335   return  isolate->heap()->undefined_value();
   12336 }
   12337 
   12338 
   12339 static bool IsPositionAlignmentCodeCorrect(int alignment) {
   12340   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
   12341 }
   12342 
   12343 
   12344 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
   12345   HandleScope scope(isolate);
   12346   ASSERT(args.length() == 2);
   12347 
   12348   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   12349   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
   12350 
   12351   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12352     return isolate->ThrowIllegalOperation();
   12353   }
   12354   BreakPositionAlignment alignment =
   12355       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12356 
   12357   Handle<SharedFunctionInfo> shared(fun->shared());
   12358   // Find the number of break points
   12359   Handle<Object> break_locations =
   12360       Debug::GetSourceBreakLocations(shared, alignment);
   12361   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   12362   // Return array as JS array
   12363   return *isolate->factory()->NewJSArrayWithElements(
   12364       Handle<FixedArray>::cast(break_locations));
   12365 }
   12366 
   12367 
   12368 // Set a break point in a function.
   12369 // args[0]: function
   12370 // args[1]: number: break source position (within the function source)
   12371 // args[2]: number: break point object
   12372 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
   12373   HandleScope scope(isolate);
   12374   ASSERT(args.length() == 3);
   12375   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   12376   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12377   RUNTIME_ASSERT(source_position >= 0);
   12378   Handle<Object> break_point_object_arg = args.at<Object>(2);
   12379 
   12380   // Set break point.
   12381   isolate->debug()->SetBreakPoint(function, break_point_object_arg,
   12382                                   &source_position);
   12383 
   12384   return Smi::FromInt(source_position);
   12385 }
   12386 
   12387 
   12388 // Changes the state of a break point in a script and returns source position
   12389 // where break point was set. NOTE: Regarding performance see the NOTE for
   12390 // GetScriptFromScriptData.
   12391 // args[0]: script to set break point in
   12392 // args[1]: number: break source position (within the script source)
   12393 // args[2]: number, breakpoint position alignment
   12394 // args[3]: number: break point object
   12395 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
   12396   HandleScope scope(isolate);
   12397   ASSERT(args.length() == 4);
   12398   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   12399   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12400   RUNTIME_ASSERT(source_position >= 0);
   12401   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
   12402   Handle<Object> break_point_object_arg = args.at<Object>(3);
   12403 
   12404   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   12405     return isolate->ThrowIllegalOperation();
   12406   }
   12407   BreakPositionAlignment alignment =
   12408       static_cast<BreakPositionAlignment>(statement_aligned_code);
   12409 
   12410   // Get the script from the script wrapper.
   12411   RUNTIME_ASSERT(wrapper->value()->IsScript());
   12412   Handle<Script> script(Script::cast(wrapper->value()));
   12413 
   12414   // Set break point.
   12415   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
   12416                                                 &source_position,
   12417                                                 alignment)) {
   12418     return  isolate->heap()->undefined_value();
   12419   }
   12420 
   12421   return Smi::FromInt(source_position);
   12422 }
   12423 
   12424 
   12425 // Clear a break point
   12426 // args[0]: number: break point object
   12427 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
   12428   HandleScope scope(isolate);
   12429   ASSERT(args.length() == 1);
   12430   Handle<Object> break_point_object_arg = args.at<Object>(0);
   12431 
   12432   // Clear break point.
   12433   isolate->debug()->ClearBreakPoint(break_point_object_arg);
   12434 
   12435   return isolate->heap()->undefined_value();
   12436 }
   12437 
   12438 
   12439 // Change the state of break on exceptions.
   12440 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
   12441 // args[1]: Boolean indicating on/off.
   12442 RUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
   12443   HandleScope scope(isolate);
   12444   ASSERT(args.length() == 2);
   12445   RUNTIME_ASSERT(args[0]->IsNumber());
   12446   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
   12447 
   12448   // If the number doesn't match an enum value, the ChangeBreakOnException
   12449   // function will default to affecting caught exceptions.
   12450   ExceptionBreakType type =
   12451       static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
   12452   // Update break point state.
   12453   isolate->debug()->ChangeBreakOnException(type, enable);
   12454   return isolate->heap()->undefined_value();
   12455 }
   12456 
   12457 
   12458 // Returns the state of break on exceptions
   12459 // args[0]: boolean indicating uncaught exceptions
   12460 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
   12461   HandleScope scope(isolate);
   12462   ASSERT(args.length() == 1);
   12463   RUNTIME_ASSERT(args[0]->IsNumber());
   12464 
   12465   ExceptionBreakType type =
   12466       static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
   12467   bool result = isolate->debug()->IsBreakOnException(type);
   12468   return Smi::FromInt(result);
   12469 }
   12470 
   12471 
   12472 // Prepare for stepping
   12473 // args[0]: break id for checking execution state
   12474 // args[1]: step action from the enumeration StepAction
   12475 // args[2]: number of times to perform the step, for step out it is the number
   12476 //          of frames to step down.
   12477 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
   12478   HandleScope scope(isolate);
   12479   ASSERT(args.length() == 3);
   12480   // Check arguments.
   12481   Object* check;
   12482   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   12483       RUNTIME_ARGUMENTS(isolate, args));
   12484     if (!maybe_check->ToObject(&check)) return maybe_check;
   12485   }
   12486   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
   12487     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12488   }
   12489 
   12490   // Get the step action and check validity.
   12491   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   12492   if (step_action != StepIn &&
   12493       step_action != StepNext &&
   12494       step_action != StepOut &&
   12495       step_action != StepInMin &&
   12496       step_action != StepMin) {
   12497     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12498   }
   12499 
   12500   // Get the number of steps.
   12501   int step_count = NumberToInt32(args[2]);
   12502   if (step_count < 1) {
   12503     return isolate->Throw(isolate->heap()->illegal_argument_string());
   12504   }
   12505 
   12506   // Clear all current stepping setup.
   12507   isolate->debug()->ClearStepping();
   12508 
   12509   // Prepare step.
   12510   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
   12511                                 step_count);
   12512   return isolate->heap()->undefined_value();
   12513 }
   12514 
   12515 
   12516 // Clear all stepping set by PrepareStep.
   12517 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
   12518   HandleScope scope(isolate);
   12519   ASSERT(args.length() == 0);
   12520   isolate->debug()->ClearStepping();
   12521   return isolate->heap()->undefined_value();
   12522 }
   12523 
   12524 
   12525 // Helper function to find or create the arguments object for
   12526 // Runtime_DebugEvaluate.
   12527 static Handle<JSObject> MaterializeArgumentsObject(
   12528     Isolate* isolate,
   12529     Handle<JSObject> target,
   12530     Handle<JSFunction> function) {
   12531   // Do not materialize the arguments object for eval or top-level code.
   12532   // Skip if "arguments" is already taken.
   12533   if (!function->shared()->is_function() ||
   12534       target->HasLocalProperty(isolate->heap()->arguments_string())) {
   12535     return target;
   12536   }
   12537 
   12538   // FunctionGetArguments can't throw an exception.
   12539   Handle<JSObject> arguments = Handle<JSObject>::cast(
   12540       Accessors::FunctionGetArguments(function));
   12541   SetProperty(isolate,
   12542               target,
   12543               isolate->factory()->arguments_string(),
   12544               arguments,
   12545               ::NONE,
   12546               kNonStrictMode);
   12547   return target;
   12548 }
   12549 
   12550 
   12551 // Compile and evaluate source for the given context.
   12552 static MaybeObject* DebugEvaluate(Isolate* isolate,
   12553                                   Handle<Context> context,
   12554                                   Handle<Object> context_extension,
   12555                                   Handle<Object> receiver,
   12556                                   Handle<String> source) {
   12557   if (context_extension->IsJSObject()) {
   12558     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
   12559     Handle<JSFunction> closure(context->closure(), isolate);
   12560     context = isolate->factory()->NewWithContext(closure, context, extension);
   12561   }
   12562 
   12563   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   12564       source,
   12565       context,
   12566       context->IsNativeContext(),
   12567       CLASSIC_MODE,
   12568       NO_PARSE_RESTRICTION,
   12569       RelocInfo::kNoPosition);
   12570   RETURN_IF_EMPTY_HANDLE(isolate, shared);
   12571 
   12572   Handle<JSFunction> eval_fun =
   12573       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   12574           shared, context, NOT_TENURED);
   12575   bool pending_exception;
   12576   Handle<Object> result = Execution::Call(
   12577       eval_fun, receiver, 0, NULL, &pending_exception);
   12578 
   12579   if (pending_exception) return Failure::Exception();
   12580 
   12581   // Skip the global proxy as it has no properties and always delegates to the
   12582   // real global object.
   12583   if (result->IsJSGlobalProxy()) {
   12584     result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
   12585   }
   12586 
   12587   // Clear the oneshot breakpoints so that the debugger does not step further.
   12588   isolate->debug()->ClearStepping();
   12589   return *result;
   12590 }
   12591 
   12592 
   12593 // Evaluate a piece of JavaScript in the context of a stack frame for
   12594 // debugging.  Things that need special attention are:
   12595 // - Parameters and stack-allocated locals need to be materialized.  Altered
   12596 //   values need to be written back to the stack afterwards.
   12597 // - The arguments object needs to materialized.
   12598 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   12599   HandleScope scope(isolate);
   12600 
   12601   // Check the execution state and decode arguments frame and source to be
   12602   // evaluated.
   12603   ASSERT(args.length() == 6);
   12604   Object* check_result;
   12605   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   12606       RUNTIME_ARGUMENTS(isolate, args));
   12607     if (!maybe_result->ToObject(&check_result)) return maybe_result;
   12608   }
   12609   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   12610   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   12611   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
   12612   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
   12613   Handle<Object> context_extension(args[5], isolate);
   12614 
   12615   // Handle the processing of break.
   12616   DisableBreak disable_break_save(disable_break);
   12617 
   12618   // Get the frame where the debugging is performed.
   12619   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   12620   JavaScriptFrameIterator it(isolate, id);
   12621   JavaScriptFrame* frame = it.frame();
   12622   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   12623   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   12624 
   12625   // Traverse the saved contexts chain to find the active context for the
   12626   // selected frame.
   12627   SaveContext* save = FindSavedContextForFrame(isolate, frame);
   12628 
   12629   SaveContext savex(isolate);
   12630   isolate->set_context(*(save->context()));
   12631 
   12632   // Evaluate on the context of the frame.
   12633   Handle<Context> context(Context::cast(frame->context()));
   12634   ASSERT(!context.is_null());
   12635 
   12636   // Materialize stack locals and the arguments object.
   12637   Handle<JSObject> materialized =
   12638       isolate->factory()->NewJSObject(isolate->object_function());
   12639 
   12640   materialized = MaterializeStackLocalsWithFrameInspector(
   12641       isolate, materialized, function, &frame_inspector);
   12642   RETURN_IF_EMPTY_HANDLE(isolate, materialized);
   12643 
   12644   materialized = MaterializeArgumentsObject(isolate, materialized, function);
   12645   RETURN_IF_EMPTY_HANDLE(isolate, materialized);
   12646 
   12647   // Add the materialized object in a with-scope to shadow the stack locals.
   12648   context = isolate->factory()->NewWithContext(function, context, materialized);
   12649 
   12650   Handle<Object> receiver(frame->receiver(), isolate);
   12651   Object* evaluate_result_object;
   12652   { MaybeObject* maybe_result =
   12653     DebugEvaluate(isolate, context, context_extension, receiver, source);
   12654     if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result;
   12655   }
   12656 
   12657   Handle<Object> result(evaluate_result_object, isolate);
   12658 
   12659   // Write back potential changes to materialized stack locals to the stack.
   12660   UpdateStackLocalsFromMaterializedObject(
   12661       isolate, materialized, function, frame, inlined_jsframe_index);
   12662 
   12663   return *result;
   12664 }
   12665 
   12666 
   12667 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
   12668   HandleScope scope(isolate);
   12669 
   12670   // Check the execution state and decode arguments frame and source to be
   12671   // evaluated.
   12672   ASSERT(args.length() == 4);
   12673   Object* check_result;
   12674   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   12675       RUNTIME_ARGUMENTS(isolate, args));
   12676     if (!maybe_result->ToObject(&check_result)) return maybe_result;
   12677   }
   12678   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   12679   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
   12680   Handle<Object> context_extension(args[3], isolate);
   12681 
   12682   // Handle the processing of break.
   12683   DisableBreak disable_break_save(disable_break);
   12684 
   12685   // Enter the top context from before the debugger was invoked.
   12686   SaveContext save(isolate);
   12687   SaveContext* top = &save;
   12688   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
   12689     top = top->prev();
   12690   }
   12691   if (top != NULL) {
   12692     isolate->set_context(*top->context());
   12693   }
   12694 
   12695   // Get the native context now set to the top context from before the
   12696   // debugger was invoked.
   12697   Handle<Context> context = isolate->native_context();
   12698   Handle<Object> receiver = isolate->global_object();
   12699   return DebugEvaluate(isolate, context, context_extension, receiver, source);
   12700 }
   12701 
   12702 
   12703 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
   12704   HandleScope scope(isolate);
   12705   ASSERT(args.length() == 0);
   12706 
   12707   // Fill the script objects.
   12708   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
   12709 
   12710   // Convert the script objects to proper JS objects.
   12711   for (int i = 0; i < instances->length(); i++) {
   12712     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
   12713     // Get the script wrapper in a local handle before calling GetScriptWrapper,
   12714     // because using
   12715     //   instances->set(i, *GetScriptWrapper(script))
   12716     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
   12717     // already have dereferenced the instances handle.
   12718     Handle<JSValue> wrapper = GetScriptWrapper(script);
   12719     instances->set(i, *wrapper);
   12720   }
   12721 
   12722   // Return result as a JS array.
   12723   Handle<JSObject> result =
   12724       isolate->factory()->NewJSObject(isolate->array_function());
   12725   isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
   12726   return *result;
   12727 }
   12728 
   12729 
   12730 // Helper function used by Runtime_DebugReferencedBy below.
   12731 static int DebugReferencedBy(HeapIterator* iterator,
   12732                              JSObject* target,
   12733                              Object* instance_filter, int max_references,
   12734                              FixedArray* instances, int instances_size,
   12735                              JSFunction* arguments_function) {
   12736   Isolate* isolate = target->GetIsolate();
   12737   SealHandleScope shs(isolate);
   12738   DisallowHeapAllocation no_allocation;
   12739 
   12740   // Iterate the heap.
   12741   int count = 0;
   12742   JSObject* last = NULL;
   12743   HeapObject* heap_obj = NULL;
   12744   while (((heap_obj = iterator->next()) != NULL) &&
   12745          (max_references == 0 || count < max_references)) {
   12746     // Only look at all JSObjects.
   12747     if (heap_obj->IsJSObject()) {
   12748       // Skip context extension objects and argument arrays as these are
   12749       // checked in the context of functions using them.
   12750       JSObject* obj = JSObject::cast(heap_obj);
   12751       if (obj->IsJSContextExtensionObject() ||
   12752           obj->map()->constructor() == arguments_function) {
   12753         continue;
   12754       }
   12755 
   12756       // Check if the JS object has a reference to the object looked for.
   12757       if (obj->ReferencesObject(target)) {
   12758         // Check instance filter if supplied. This is normally used to avoid
   12759         // references from mirror objects (see Runtime_IsInPrototypeChain).
   12760         if (!instance_filter->IsUndefined()) {
   12761           Object* V = obj;
   12762           while (true) {
   12763             Object* prototype = V->GetPrototype(isolate);
   12764             if (prototype->IsNull()) {
   12765               break;
   12766             }
   12767             if (instance_filter == prototype) {
   12768               obj = NULL;  // Don't add this object.
   12769               break;
   12770             }
   12771             V = prototype;
   12772           }
   12773         }
   12774 
   12775         if (obj != NULL) {
   12776           // Valid reference found add to instance array if supplied an update
   12777           // count.
   12778           if (instances != NULL && count < instances_size) {
   12779             instances->set(count, obj);
   12780           }
   12781           last = obj;
   12782           count++;
   12783         }
   12784       }
   12785     }
   12786   }
   12787 
   12788   // Check for circular reference only. This can happen when the object is only
   12789   // referenced from mirrors and has a circular reference in which case the
   12790   // object is not really alive and would have been garbage collected if not
   12791   // referenced from the mirror.
   12792   if (count == 1 && last == target) {
   12793     count = 0;
   12794   }
   12795 
   12796   // Return the number of referencing objects found.
   12797   return count;
   12798 }
   12799 
   12800 
   12801 // Scan the heap for objects with direct references to an object
   12802 // args[0]: the object to find references to
   12803 // args[1]: constructor function for instances to exclude (Mirror)
   12804 // args[2]: the the maximum number of objects to return
   12805 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
   12806   SealHandleScope shs(isolate);
   12807   ASSERT(args.length() == 3);
   12808 
   12809   // First perform a full GC in order to avoid references from dead objects.
   12810   isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
   12811                                      "%DebugReferencedBy");
   12812   // The heap iterator reserves the right to do a GC to make the heap iterable.
   12813   // Due to the GC above we know it won't need to do that, but it seems cleaner
   12814   // to get the heap iterator constructed before we start having unprotected
   12815   // Object* locals that are not protected by handles.
   12816 
   12817   // Check parameters.
   12818   CONVERT_ARG_CHECKED(JSObject, target, 0);
   12819   Object* instance_filter = args[1];
   12820   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
   12821                  instance_filter->IsJSObject());
   12822   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
   12823   RUNTIME_ASSERT(max_references >= 0);
   12824 
   12825 
   12826   // Get the constructor function for context extension and arguments array.
   12827   JSObject* arguments_boilerplate =
   12828       isolate->context()->native_context()->arguments_boilerplate();
   12829   JSFunction* arguments_function =
   12830       JSFunction::cast(arguments_boilerplate->map()->constructor());
   12831 
   12832   // Get the number of referencing objects.
   12833   int count;
   12834   Heap* heap = isolate->heap();
   12835   HeapIterator heap_iterator(heap);
   12836   count = DebugReferencedBy(&heap_iterator,
   12837                             target, instance_filter, max_references,
   12838                             NULL, 0, arguments_function);
   12839 
   12840   // Allocate an array to hold the result.
   12841   Object* object;
   12842   { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
   12843     if (!maybe_object->ToObject(&object)) return maybe_object;
   12844   }
   12845   FixedArray* instances = FixedArray::cast(object);
   12846 
   12847   // Fill the referencing objects.
   12848   // AllocateFixedArray above does not make the heap non-iterable.
   12849   ASSERT(heap->IsHeapIterable());
   12850   HeapIterator heap_iterator2(heap);
   12851   count = DebugReferencedBy(&heap_iterator2,
   12852                             target, instance_filter, max_references,
   12853                             instances, count, arguments_function);
   12854 
   12855   // Return result as JS array.
   12856   Object* result;
   12857   MaybeObject* maybe_result = heap->AllocateJSObject(
   12858       isolate->context()->native_context()->array_function());
   12859   if (!maybe_result->ToObject(&result)) return maybe_result;
   12860   return JSArray::cast(result)->SetContent(instances);
   12861 }
   12862 
   12863 
   12864 // Helper function used by Runtime_DebugConstructedBy below.
   12865 static int DebugConstructedBy(HeapIterator* iterator,
   12866                               JSFunction* constructor,
   12867                               int max_references,
   12868                               FixedArray* instances,
   12869                               int instances_size) {
   12870   DisallowHeapAllocation no_allocation;
   12871 
   12872   // Iterate the heap.
   12873   int count = 0;
   12874   HeapObject* heap_obj = NULL;
   12875   while (((heap_obj = iterator->next()) != NULL) &&
   12876          (max_references == 0 || count < max_references)) {
   12877     // Only look at all JSObjects.
   12878     if (heap_obj->IsJSObject()) {
   12879       JSObject* obj = JSObject::cast(heap_obj);
   12880       if (obj->map()->constructor() == constructor) {
   12881         // Valid reference found add to instance array if supplied an update
   12882         // count.
   12883         if (instances != NULL && count < instances_size) {
   12884           instances->set(count, obj);
   12885         }
   12886         count++;
   12887       }
   12888     }
   12889   }
   12890 
   12891   // Return the number of referencing objects found.
   12892   return count;
   12893 }
   12894 
   12895 
   12896 // Scan the heap for objects constructed by a specific function.
   12897 // args[0]: the constructor to find instances of
   12898 // args[1]: the the maximum number of objects to return
   12899 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
   12900   SealHandleScope shs(isolate);
   12901   ASSERT(args.length() == 2);
   12902 
   12903   // First perform a full GC in order to avoid dead objects.
   12904   Heap* heap = isolate->heap();
   12905   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
   12906 
   12907   // Check parameters.
   12908   CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
   12909   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   12910   RUNTIME_ASSERT(max_references >= 0);
   12911 
   12912   // Get the number of referencing objects.
   12913   int count;
   12914   HeapIterator heap_iterator(heap);
   12915   count = DebugConstructedBy(&heap_iterator,
   12916                              constructor,
   12917                              max_references,
   12918                              NULL,
   12919                              0);
   12920 
   12921   // Allocate an array to hold the result.
   12922   Object* object;
   12923   { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
   12924     if (!maybe_object->ToObject(&object)) return maybe_object;
   12925   }
   12926   FixedArray* instances = FixedArray::cast(object);
   12927 
   12928   ASSERT(HEAP->IsHeapIterable());
   12929   // Fill the referencing objects.
   12930   HeapIterator heap_iterator2(heap);
   12931   count = DebugConstructedBy(&heap_iterator2,
   12932                              constructor,
   12933                              max_references,
   12934                              instances,
   12935                              count);
   12936 
   12937   // Return result as JS array.
   12938   Object* result;
   12939   { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
   12940       isolate->context()->native_context()->array_function());
   12941     if (!maybe_result->ToObject(&result)) return maybe_result;
   12942   }
   12943   return JSArray::cast(result)->SetContent(instances);
   12944 }
   12945 
   12946 
   12947 // Find the effective prototype object as returned by __proto__.
   12948 // args[0]: the object to find the prototype for.
   12949 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
   12950   SealHandleScope shs(isolate);
   12951   ASSERT(args.length() == 1);
   12952   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   12953   return GetPrototypeSkipHiddenPrototypes(isolate, obj);
   12954 }
   12955 
   12956 
   12957 // Patches script source (should be called upon BeforeCompile event).
   12958 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
   12959   HandleScope scope(isolate);
   12960   ASSERT(args.length() == 2);
   12961 
   12962   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
   12963   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   12964 
   12965   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
   12966   Handle<Script> script(Script::cast(script_wrapper->value()));
   12967 
   12968   int compilation_state = script->compilation_state();
   12969   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
   12970   script->set_source(*source);
   12971 
   12972   return isolate->heap()->undefined_value();
   12973 }
   12974 
   12975 
   12976 RUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
   12977   SealHandleScope shs(isolate);
   12978   ASSERT(args.length() == 0);
   12979   CPU::DebugBreak();
   12980   return isolate->heap()->undefined_value();
   12981 }
   12982 
   12983 
   12984 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
   12985   HandleScope scope(isolate);
   12986 #ifdef DEBUG
   12987   ASSERT(args.length() == 1);
   12988   // Get the function and make sure it is compiled.
   12989   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   12990   if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
   12991     return Failure::Exception();
   12992   }
   12993   func->code()->PrintLn();
   12994 #endif  // DEBUG
   12995   return isolate->heap()->undefined_value();
   12996 }
   12997 
   12998 
   12999 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
   13000   HandleScope scope(isolate);
   13001 #ifdef DEBUG
   13002   ASSERT(args.length() == 1);
   13003   // Get the function and make sure it is compiled.
   13004   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   13005   if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
   13006     return Failure::Exception();
   13007   }
   13008   func->shared()->construct_stub()->PrintLn();
   13009 #endif  // DEBUG
   13010   return isolate->heap()->undefined_value();
   13011 }
   13012 
   13013 
   13014 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
   13015   SealHandleScope shs(isolate);
   13016   ASSERT(args.length() == 1);
   13017 
   13018   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   13019   return f->shared()->inferred_name();
   13020 }
   13021 
   13022 
   13023 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
   13024                                             Script* script,
   13025                                             FixedArray* buffer) {
   13026   DisallowHeapAllocation no_allocation;
   13027   int counter = 0;
   13028   int buffer_size = buffer->length();
   13029   for (HeapObject* obj = iterator->next();
   13030        obj != NULL;
   13031        obj = iterator->next()) {
   13032     ASSERT(obj != NULL);
   13033     if (!obj->IsSharedFunctionInfo()) {
   13034       continue;
   13035     }
   13036     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
   13037     if (shared->script() != script) {
   13038       continue;
   13039     }
   13040     if (counter < buffer_size) {
   13041       buffer->set(counter, shared);
   13042     }
   13043     counter++;
   13044   }
   13045   return counter;
   13046 }
   13047 
   13048 
   13049 // For a script finds all SharedFunctionInfo's in the heap that points
   13050 // to this script. Returns JSArray of SharedFunctionInfo wrapped
   13051 // in OpaqueReferences.
   13052 RUNTIME_FUNCTION(MaybeObject*,
   13053                  Runtime_LiveEditFindSharedFunctionInfosForScript) {
   13054   HandleScope scope(isolate);
   13055   CHECK(isolate->debugger()->live_edit_enabled());
   13056   ASSERT(args.length() == 1);
   13057   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
   13058 
   13059   RUNTIME_ASSERT(script_value->value()->IsScript());
   13060   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
   13061 
   13062   const int kBufferSize = 32;
   13063 
   13064   Handle<FixedArray> array;
   13065   array = isolate->factory()->NewFixedArray(kBufferSize);
   13066   int number;
   13067   Heap* heap = isolate->heap();
   13068   {
   13069     heap->EnsureHeapIsIterable();
   13070     DisallowHeapAllocation no_allocation;
   13071     HeapIterator heap_iterator(heap);
   13072     Script* scr = *script;
   13073     FixedArray* arr = *array;
   13074     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13075   }
   13076   if (number > kBufferSize) {
   13077     array = isolate->factory()->NewFixedArray(number);
   13078     heap->EnsureHeapIsIterable();
   13079     DisallowHeapAllocation no_allocation;
   13080     HeapIterator heap_iterator(heap);
   13081     Script* scr = *script;
   13082     FixedArray* arr = *array;
   13083     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   13084   }
   13085 
   13086   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
   13087   result->set_length(Smi::FromInt(number));
   13088 
   13089   LiveEdit::WrapSharedFunctionInfos(result);
   13090 
   13091   return *result;
   13092 }
   13093 
   13094 
   13095 // For a script calculates compilation information about all its functions.
   13096 // The script source is explicitly specified by the second argument.
   13097 // The source of the actual script is not used, however it is important that
   13098 // all generated code keeps references to this particular instance of script.
   13099 // Returns a JSArray of compilation infos. The array is ordered so that
   13100 // each function with all its descendant is always stored in a continues range
   13101 // with the function itself going first. The root function is a script function.
   13102 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
   13103   HandleScope scope(isolate);
   13104   CHECK(isolate->debugger()->live_edit_enabled());
   13105   ASSERT(args.length() == 2);
   13106   CONVERT_ARG_CHECKED(JSValue, script, 0);
   13107   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   13108 
   13109   RUNTIME_ASSERT(script->value()->IsScript());
   13110   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
   13111 
   13112   JSArray* result =  LiveEdit::GatherCompileInfo(script_handle, source);
   13113 
   13114   if (isolate->has_pending_exception()) {
   13115     return Failure::Exception();
   13116   }
   13117 
   13118   return result;
   13119 }
   13120 
   13121 
   13122 // Changes the source of the script to a new_source.
   13123 // If old_script_name is provided (i.e. is a String), also creates a copy of
   13124 // the script with its original source and sends notification to debugger.
   13125 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
   13126   HandleScope scope(isolate);
   13127   CHECK(isolate->debugger()->live_edit_enabled());
   13128   ASSERT(args.length() == 3);
   13129   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
   13130   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
   13131   Handle<Object> old_script_name(args[2], isolate);
   13132 
   13133   RUNTIME_ASSERT(original_script_value->value()->IsScript());
   13134   Handle<Script> original_script(Script::cast(original_script_value->value()));
   13135 
   13136   Object* old_script = LiveEdit::ChangeScriptSource(original_script,
   13137                                                     new_source,
   13138                                                     old_script_name);
   13139 
   13140   if (old_script->IsScript()) {
   13141     Handle<Script> script_handle(Script::cast(old_script));
   13142     return *(GetScriptWrapper(script_handle));
   13143   } else {
   13144     return isolate->heap()->null_value();
   13145   }
   13146 }
   13147 
   13148 
   13149 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
   13150   HandleScope scope(isolate);
   13151   CHECK(isolate->debugger()->live_edit_enabled());
   13152   ASSERT(args.length() == 1);
   13153   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
   13154   return LiveEdit::FunctionSourceUpdated(shared_info);
   13155 }
   13156 
   13157 
   13158 // Replaces code of SharedFunctionInfo with a new one.
   13159 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
   13160   HandleScope scope(isolate);
   13161   CHECK(isolate->debugger()->live_edit_enabled());
   13162   ASSERT(args.length() == 2);
   13163   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
   13164   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
   13165 
   13166   return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
   13167 }
   13168 
   13169 
   13170 // Connects SharedFunctionInfo to another script.
   13171 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
   13172   HandleScope scope(isolate);
   13173   CHECK(isolate->debugger()->live_edit_enabled());
   13174   ASSERT(args.length() == 2);
   13175   Handle<Object> function_object(args[0], isolate);
   13176   Handle<Object> script_object(args[1], isolate);
   13177 
   13178   if (function_object->IsJSValue()) {
   13179     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
   13180     if (script_object->IsJSValue()) {
   13181       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
   13182       Script* script = Script::cast(JSValue::cast(*script_object)->value());
   13183       script_object = Handle<Object>(script, isolate);
   13184     }
   13185 
   13186     LiveEdit::SetFunctionScript(function_wrapper, script_object);
   13187   } else {
   13188     // Just ignore this. We may not have a SharedFunctionInfo for some functions
   13189     // and we check it in this function.
   13190   }
   13191 
   13192   return isolate->heap()->undefined_value();
   13193 }
   13194 
   13195 
   13196 // In a code of a parent function replaces original function as embedded object
   13197 // with a substitution one.
   13198 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
   13199   HandleScope scope(isolate);
   13200   CHECK(isolate->debugger()->live_edit_enabled());
   13201   ASSERT(args.length() == 3);
   13202 
   13203   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
   13204   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
   13205   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
   13206 
   13207   LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
   13208                                        subst_wrapper);
   13209 
   13210   return isolate->heap()->undefined_value();
   13211 }
   13212 
   13213 
   13214 // Updates positions of a shared function info (first parameter) according
   13215 // to script source change. Text change is described in second parameter as
   13216 // array of groups of 3 numbers:
   13217 // (change_begin, change_end, change_end_new_position).
   13218 // Each group describes a change in text; groups are sorted by change_begin.
   13219 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
   13220   HandleScope scope(isolate);
   13221   CHECK(isolate->debugger()->live_edit_enabled());
   13222   ASSERT(args.length() == 2);
   13223   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13224   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
   13225 
   13226   return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
   13227 }
   13228 
   13229 
   13230 // For array of SharedFunctionInfo's (each wrapped in JSValue)
   13231 // checks that none of them have activations on stacks (of any thread).
   13232 // Returns array of the same length with corresponding results of
   13233 // LiveEdit::FunctionPatchabilityStatus type.
   13234 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
   13235   HandleScope scope(isolate);
   13236   CHECK(isolate->debugger()->live_edit_enabled());
   13237   ASSERT(args.length() == 2);
   13238   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   13239   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
   13240 
   13241   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
   13242 }
   13243 
   13244 
   13245 // Compares 2 strings line-by-line, then token-wise and returns diff in form
   13246 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
   13247 // of diff chunks.
   13248 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
   13249   HandleScope scope(isolate);
   13250   CHECK(isolate->debugger()->live_edit_enabled());
   13251   ASSERT(args.length() == 2);
   13252   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
   13253   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
   13254 
   13255   return *LiveEdit::CompareStrings(s1, s2);
   13256 }
   13257 
   13258 
   13259 // Restarts a call frame and completely drops all frames above.
   13260 // Returns true if successful. Otherwise returns undefined or an error message.
   13261 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditRestartFrame) {
   13262   HandleScope scope(isolate);
   13263   CHECK(isolate->debugger()->live_edit_enabled());
   13264   ASSERT(args.length() == 2);
   13265 
   13266   // Check arguments.
   13267   Object* check;
   13268   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   13269       RUNTIME_ARGUMENTS(isolate, args));
   13270     if (!maybe_check->ToObject(&check)) return maybe_check;
   13271   }
   13272   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   13273   Heap* heap = isolate->heap();
   13274 
   13275   // Find the relevant frame with the requested index.
   13276   StackFrame::Id id = isolate->debug()->break_frame_id();
   13277   if (id == StackFrame::NO_ID) {
   13278     // If there are no JavaScript stack frames return undefined.
   13279     return heap->undefined_value();
   13280   }
   13281 
   13282   int count = 0;
   13283   JavaScriptFrameIterator it(isolate, id);
   13284   for (; !it.done(); it.Advance()) {
   13285     if (index < count + it.frame()->GetInlineCount()) break;
   13286     count += it.frame()->GetInlineCount();
   13287   }
   13288   if (it.done()) return heap->undefined_value();
   13289 
   13290   const char* error_message = LiveEdit::RestartFrame(it.frame());
   13291   if (error_message) {
   13292     return *(isolate->factory()->InternalizeUtf8String(error_message));
   13293   }
   13294   return heap->true_value();
   13295 }
   13296 
   13297 
   13298 // A testing entry. Returns statement position which is the closest to
   13299 // source_position.
   13300 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
   13301   HandleScope scope(isolate);
   13302   CHECK(isolate->debugger()->live_edit_enabled());
   13303   ASSERT(args.length() == 2);
   13304   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13305   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   13306 
   13307   Handle<Code> code(function->code(), isolate);
   13308 
   13309   if (code->kind() != Code::FUNCTION &&
   13310       code->kind() != Code::OPTIMIZED_FUNCTION) {
   13311     return isolate->heap()->undefined_value();
   13312   }
   13313 
   13314   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
   13315   int closest_pc = 0;
   13316   int distance = kMaxInt;
   13317   while (!it.done()) {
   13318     int statement_position = static_cast<int>(it.rinfo()->data());
   13319     // Check if this break point is closer that what was previously found.
   13320     if (source_position <= statement_position &&
   13321         statement_position - source_position < distance) {
   13322       closest_pc =
   13323           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
   13324       distance = statement_position - source_position;
   13325       // Check whether we can't get any closer.
   13326       if (distance == 0) break;
   13327     }
   13328     it.next();
   13329   }
   13330 
   13331   return Smi::FromInt(closest_pc);
   13332 }
   13333 
   13334 
   13335 // Calls specified function with or without entering the debugger.
   13336 // This is used in unit tests to run code as if debugger is entered or simply
   13337 // to have a stack with C++ frame in the middle.
   13338 RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
   13339   HandleScope scope(isolate);
   13340   ASSERT(args.length() == 2);
   13341   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   13342   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
   13343 
   13344   Handle<Object> result;
   13345   bool pending_exception;
   13346   {
   13347     if (without_debugger) {
   13348       result = Execution::Call(function, isolate->global_object(), 0, NULL,
   13349                                &pending_exception);
   13350     } else {
   13351       EnterDebugger enter_debugger;
   13352       result = Execution::Call(function, isolate->global_object(), 0, NULL,
   13353                                &pending_exception);
   13354     }
   13355   }
   13356   if (!pending_exception) {
   13357     return *result;
   13358   } else {
   13359     return Failure::Exception();
   13360   }
   13361 }
   13362 
   13363 
   13364 // Sets a v8 flag.
   13365 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
   13366   SealHandleScope shs(isolate);
   13367   CONVERT_ARG_CHECKED(String, arg, 0);
   13368   SmartArrayPointer<char> flags =
   13369       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   13370   FlagList::SetFlagsFromString(*flags, StrLength(*flags));
   13371   return isolate->heap()->undefined_value();
   13372 }
   13373 
   13374 
   13375 // Performs a GC.
   13376 // Presently, it only does a full GC.
   13377 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectGarbage) {
   13378   SealHandleScope shs(isolate);
   13379   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
   13380   return isolate->heap()->undefined_value();
   13381 }
   13382 
   13383 
   13384 // Gets the current heap usage.
   13385 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
   13386   SealHandleScope shs(isolate);
   13387   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
   13388   if (!Smi::IsValid(usage)) {
   13389     return *isolate->factory()->NewNumberFromInt(usage);
   13390   }
   13391   return Smi::FromInt(usage);
   13392 }
   13393 
   13394 #endif  // ENABLE_DEBUGGER_SUPPORT
   13395 
   13396 
   13397 #ifdef V8_I18N_SUPPORT
   13398 RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
   13399   HandleScope scope(isolate);
   13400 
   13401   ASSERT(args.length() == 1);
   13402   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
   13403 
   13404   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
   13405 
   13406   // Return value which denotes invalid language tag.
   13407   const char* const kInvalidTag = "invalid-tag";
   13408 
   13409   UErrorCode error = U_ZERO_ERROR;
   13410   char icu_result[ULOC_FULLNAME_CAPACITY];
   13411   int icu_length = 0;
   13412 
   13413   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
   13414                       &icu_length, &error);
   13415   if (U_FAILURE(error) || icu_length == 0) {
   13416     return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
   13417   }
   13418 
   13419   char result[ULOC_FULLNAME_CAPACITY];
   13420 
   13421   // Force strict BCP47 rules.
   13422   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
   13423 
   13424   if (U_FAILURE(error)) {
   13425     return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
   13426   }
   13427 
   13428   return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
   13429 }
   13430 
   13431 
   13432 RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
   13433   HandleScope scope(isolate);
   13434 
   13435   ASSERT(args.length() == 1);
   13436   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
   13437 
   13438   const icu::Locale* available_locales = NULL;
   13439   int32_t count = 0;
   13440 
   13441   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
   13442     available_locales = icu::Collator::getAvailableLocales(count);
   13443   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
   13444     available_locales = icu::NumberFormat::getAvailableLocales(count);
   13445   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
   13446     available_locales = icu::DateFormat::getAvailableLocales(count);
   13447   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
   13448     available_locales = icu::BreakIterator::getAvailableLocales(count);
   13449   }
   13450 
   13451   UErrorCode error = U_ZERO_ERROR;
   13452   char result[ULOC_FULLNAME_CAPACITY];
   13453   Handle<JSObject> locales =
   13454       isolate->factory()->NewJSObject(isolate->object_function());
   13455 
   13456   for (int32_t i = 0; i < count; ++i) {
   13457     const char* icu_name = available_locales[i].getName();
   13458 
   13459     error = U_ZERO_ERROR;
   13460     // No need to force strict BCP47 rules.
   13461     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13462     if (U_FAILURE(error)) {
   13463       // This shouldn't happen, but lets not break the user.
   13464       continue;
   13465     }
   13466 
   13467     RETURN_IF_EMPTY_HANDLE(isolate,
   13468         JSObject::SetLocalPropertyIgnoreAttributes(
   13469             locales,
   13470             isolate->factory()->NewStringFromAscii(CStrVector(result)),
   13471             isolate->factory()->NewNumber(i),
   13472             NONE));
   13473   }
   13474 
   13475   return *locales;
   13476 }
   13477 
   13478 
   13479 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) {
   13480   SealHandleScope shs(isolate);
   13481 
   13482   ASSERT(args.length() == 0);
   13483 
   13484   icu::Locale default_locale;
   13485 
   13486   // Set the locale
   13487   char result[ULOC_FULLNAME_CAPACITY];
   13488   UErrorCode status = U_ZERO_ERROR;
   13489   uloc_toLanguageTag(
   13490       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
   13491   if (U_SUCCESS(status)) {
   13492     return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
   13493   }
   13494 
   13495   return isolate->heap()->AllocateStringFromOneByte(CStrVector("und"));
   13496 }
   13497 
   13498 
   13499 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
   13500   HandleScope scope(isolate);
   13501 
   13502   ASSERT(args.length() == 1);
   13503 
   13504   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
   13505 
   13506   uint32_t length = static_cast<uint32_t>(input->length()->Number());
   13507   Handle<FixedArray> output = isolate->factory()->NewFixedArray(length);
   13508   Handle<Name> maximized =
   13509       isolate->factory()->NewStringFromAscii(CStrVector("maximized"));
   13510   Handle<Name> base =
   13511       isolate->factory()->NewStringFromAscii(CStrVector("base"));
   13512   for (unsigned int i = 0; i < length; ++i) {
   13513     MaybeObject* maybe_string = input->GetElement(i);
   13514     Object* locale_id;
   13515     if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) {
   13516       return isolate->Throw(isolate->heap()->illegal_argument_string());
   13517     }
   13518 
   13519     v8::String::Utf8Value utf8_locale_id(
   13520         v8::Utils::ToLocal(Handle<String>(String::cast(locale_id))));
   13521 
   13522     UErrorCode error = U_ZERO_ERROR;
   13523 
   13524     // Convert from BCP47 to ICU format.
   13525     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
   13526     char icu_locale[ULOC_FULLNAME_CAPACITY];
   13527     int icu_locale_length = 0;
   13528     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
   13529                         &icu_locale_length, &error);
   13530     if (U_FAILURE(error) || icu_locale_length == 0) {
   13531       return isolate->Throw(isolate->heap()->illegal_argument_string());
   13532     }
   13533 
   13534     // Maximize the locale.
   13535     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
   13536     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
   13537     uloc_addLikelySubtags(
   13538         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13539 
   13540     // Remove extensions from maximized locale.
   13541     // de_Latn_DE@collation=phonebook -> de_Latn_DE
   13542     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
   13543     uloc_getBaseName(
   13544         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
   13545 
   13546     // Get original name without extensions.
   13547     // de_DE@collation=phonebook -> de_DE
   13548     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
   13549     uloc_getBaseName(
   13550         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
   13551 
   13552     // Convert from ICU locale format to BCP47 format.
   13553     // de_Latn_DE -> de-Latn-DE
   13554     char base_max_locale[ULOC_FULLNAME_CAPACITY];
   13555     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
   13556                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13557 
   13558     // de_DE -> de-DE
   13559     char base_locale[ULOC_FULLNAME_CAPACITY];
   13560     uloc_toLanguageTag(
   13561         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
   13562 
   13563     if (U_FAILURE(error)) {
   13564       return isolate->Throw(isolate->heap()->illegal_argument_string());
   13565     }
   13566 
   13567     Handle<JSObject> result =
   13568         isolate->factory()->NewJSObject(isolate->object_function());
   13569     RETURN_IF_EMPTY_HANDLE(isolate,
   13570         JSObject::SetLocalPropertyIgnoreAttributes(
   13571             result,
   13572             maximized,
   13573             isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)),
   13574             NONE));
   13575     RETURN_IF_EMPTY_HANDLE(isolate,
   13576         JSObject::SetLocalPropertyIgnoreAttributes(
   13577             result,
   13578             base,
   13579             isolate->factory()->NewStringFromAscii(CStrVector(base_locale)),
   13580             NONE));
   13581     output->set(i, *result);
   13582   }
   13583 
   13584   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output);
   13585   result->set_length(Smi::FromInt(length));
   13586   return *result;
   13587 }
   13588 
   13589 
   13590 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
   13591   HandleScope scope(isolate);
   13592 
   13593   ASSERT(args.length() == 3);
   13594 
   13595   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   13596   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   13597   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   13598 
   13599   Handle<ObjectTemplateInfo> date_format_template =
   13600       I18N::GetTemplate(isolate);
   13601 
   13602   // Create an empty object wrapper.
   13603   bool has_pending_exception = false;
   13604   Handle<JSObject> local_object = Execution::InstantiateObject(
   13605       date_format_template, &has_pending_exception);
   13606   if (has_pending_exception) {
   13607     ASSERT(isolate->has_pending_exception());
   13608     return Failure::Exception();
   13609   }
   13610 
   13611   // Set date time formatter as internal field of the resulting JS object.
   13612   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
   13613       isolate, locale, options, resolved);
   13614 
   13615   if (!date_format) return isolate->ThrowIllegalOperation();
   13616 
   13617   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
   13618 
   13619   RETURN_IF_EMPTY_HANDLE(isolate,
   13620       JSObject::SetLocalPropertyIgnoreAttributes(
   13621           local_object,
   13622           isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")),
   13623           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   13624           NONE));
   13625 
   13626   Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
   13627                                  v8::Utils::ToLocal(local_object));
   13628   // Make object handle weak so we can delete the data format once GC kicks in.
   13629   wrapper.MakeWeak<void>(NULL, &DateFormat::DeleteDateFormat);
   13630   wrapper.ClearAndLeak();
   13631   return *local_object;
   13632 }
   13633 
   13634 
   13635 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
   13636   HandleScope scope(isolate);
   13637 
   13638   ASSERT(args.length() == 2);
   13639 
   13640   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   13641   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
   13642 
   13643   bool has_pending_exception = false;
   13644   Handle<Object> value = Execution::ToNumber(date, &has_pending_exception);
   13645   if (has_pending_exception) {
   13646     ASSERT(isolate->has_pending_exception());
   13647     return Failure::Exception();
   13648   }
   13649 
   13650   icu::SimpleDateFormat* date_format =
   13651       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   13652   if (!date_format) return isolate->ThrowIllegalOperation();
   13653 
   13654   icu::UnicodeString result;
   13655   date_format->format(value->Number(), result);
   13656 
   13657   return *isolate->factory()->NewStringFromTwoByte(
   13658       Vector<const uint16_t>(
   13659           reinterpret_cast<const uint16_t*>(result.getBuffer()),
   13660           result.length()));
   13661 }
   13662 
   13663 
   13664 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) {
   13665   HandleScope scope(isolate);
   13666 
   13667   ASSERT(args.length() == 2);
   13668 
   13669   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
   13670   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
   13671 
   13672   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
   13673   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
   13674   icu::SimpleDateFormat* date_format =
   13675       DateFormat::UnpackDateFormat(isolate, date_format_holder);
   13676   if (!date_format) return isolate->ThrowIllegalOperation();
   13677 
   13678   UErrorCode status = U_ZERO_ERROR;
   13679   UDate date = date_format->parse(u_date, status);
   13680   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   13681 
   13682   bool has_pending_exception = false;
   13683   Handle<JSDate> result = Handle<JSDate>::cast(
   13684       Execution::NewDate(static_cast<double>(date), &has_pending_exception));
   13685   if (has_pending_exception) {
   13686     ASSERT(isolate->has_pending_exception());
   13687     return Failure::Exception();
   13688   }
   13689   return *result;
   13690 }
   13691 
   13692 
   13693 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
   13694   HandleScope scope(isolate);
   13695 
   13696   ASSERT(args.length() == 3);
   13697 
   13698   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   13699   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   13700   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   13701 
   13702   Handle<ObjectTemplateInfo> number_format_template =
   13703       I18N::GetTemplate(isolate);
   13704 
   13705   // Create an empty object wrapper.
   13706   bool has_pending_exception = false;
   13707   Handle<JSObject> local_object = Execution::InstantiateObject(
   13708       number_format_template, &has_pending_exception);
   13709   if (has_pending_exception) {
   13710     ASSERT(isolate->has_pending_exception());
   13711     return Failure::Exception();
   13712   }
   13713 
   13714   // Set number formatter as internal field of the resulting JS object.
   13715   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
   13716       isolate, locale, options, resolved);
   13717 
   13718   if (!number_format) return isolate->ThrowIllegalOperation();
   13719 
   13720   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
   13721 
   13722   RETURN_IF_EMPTY_HANDLE(isolate,
   13723       JSObject::SetLocalPropertyIgnoreAttributes(
   13724           local_object,
   13725           isolate->factory()->NewStringFromAscii(CStrVector("numberFormat")),
   13726           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   13727           NONE));
   13728 
   13729   Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
   13730                                  v8::Utils::ToLocal(local_object));
   13731   // Make object handle weak so we can delete the number format once GC kicks
   13732   // in.
   13733   wrapper.MakeWeak<void>(NULL, &NumberFormat::DeleteNumberFormat);
   13734   wrapper.ClearAndLeak();
   13735   return *local_object;
   13736 }
   13737 
   13738 
   13739 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
   13740   HandleScope scope(isolate);
   13741 
   13742   ASSERT(args.length() == 2);
   13743 
   13744   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   13745   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
   13746 
   13747   bool has_pending_exception = false;
   13748   Handle<Object> value = Execution::ToNumber(number, &has_pending_exception);
   13749   if (has_pending_exception) {
   13750     ASSERT(isolate->has_pending_exception());
   13751     return Failure::Exception();
   13752   }
   13753 
   13754   icu::DecimalFormat* number_format =
   13755       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   13756   if (!number_format) return isolate->ThrowIllegalOperation();
   13757 
   13758   icu::UnicodeString result;
   13759   number_format->format(value->Number(), result);
   13760 
   13761   return *isolate->factory()->NewStringFromTwoByte(
   13762       Vector<const uint16_t>(
   13763           reinterpret_cast<const uint16_t*>(result.getBuffer()),
   13764           result.length()));
   13765 }
   13766 
   13767 
   13768 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) {
   13769   HandleScope scope(isolate);
   13770 
   13771   ASSERT(args.length() == 2);
   13772 
   13773   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
   13774   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
   13775 
   13776   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
   13777   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
   13778   icu::DecimalFormat* number_format =
   13779       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
   13780   if (!number_format) return isolate->ThrowIllegalOperation();
   13781 
   13782   UErrorCode status = U_ZERO_ERROR;
   13783   icu::Formattable result;
   13784   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
   13785   // to be part of Chrome.
   13786   // TODO(cira): Include currency parsing code using parseCurrency call.
   13787   // We need to check if the formatter parses all currencies or only the
   13788   // one it was constructed with (it will impact the API - how to return ISO
   13789   // code and the value).
   13790   number_format->parse(u_number, result, status);
   13791   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
   13792 
   13793   switch (result.getType()) {
   13794   case icu::Formattable::kDouble:
   13795     return *isolate->factory()->NewNumber(result.getDouble());
   13796   case icu::Formattable::kLong:
   13797     return *isolate->factory()->NewNumberFromInt(result.getLong());
   13798   case icu::Formattable::kInt64:
   13799     return *isolate->factory()->NewNumber(
   13800         static_cast<double>(result.getInt64()));
   13801   default:
   13802     return isolate->heap()->undefined_value();
   13803   }
   13804 }
   13805 
   13806 
   13807 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
   13808   HandleScope scope(isolate);
   13809 
   13810   ASSERT(args.length() == 3);
   13811 
   13812   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
   13813   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
   13814   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
   13815 
   13816   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
   13817 
   13818   // Create an empty object wrapper.
   13819   bool has_pending_exception = false;
   13820   Handle<JSObject> local_object = Execution::InstantiateObject(
   13821       collator_template, &has_pending_exception);
   13822   if (has_pending_exception) {
   13823     ASSERT(isolate->has_pending_exception());
   13824     return Failure::Exception();
   13825   }
   13826 
   13827   // Set collator as internal field of the resulting JS object.
   13828   icu::Collator* collator = Collator::InitializeCollator(
   13829       isolate, locale, options, resolved);
   13830 
   13831   if (!collator) return isolate->ThrowIllegalOperation();
   13832 
   13833   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
   13834 
   13835   RETURN_IF_EMPTY_HANDLE(isolate,
   13836       JSObject::SetLocalPropertyIgnoreAttributes(
   13837           local_object,
   13838           isolate->factory()->NewStringFromAscii(CStrVector("collator")),
   13839           isolate->factory()->NewStringFromAscii(CStrVector("valid")),
   13840           NONE));
   13841 
   13842   Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
   13843                                  v8::Utils::ToLocal(local_object));
   13844   // Make object handle weak so we can delete the collator once GC kicks in.
   13845   wrapper.MakeWeak<void>(NULL, &Collator::DeleteCollator);
   13846   wrapper.ClearAndLeak();
   13847   return *local_object;
   13848 }
   13849 
   13850 
   13851 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalCompare) {
   13852   HandleScope scope(isolate);
   13853 
   13854   ASSERT(args.length() == 3);
   13855 
   13856   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
   13857   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
   13858   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
   13859 
   13860   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
   13861   if (!collator) return isolate->ThrowIllegalOperation();
   13862 
   13863   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
   13864   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
   13865   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
   13866   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
   13867   UErrorCode status = U_ZERO_ERROR;
   13868   UCollationResult result = collator->compare(u_string1,
   13869                                               string_value1.length(),
   13870                                               u_string2,
   13871                                               string_value2.length(),
   13872                                               status);
   13873   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
   13874 
   13875   return *isolate->factory()->NewNumberFromInt(result);
   13876 }
   13877 #endif  // V8_I18N_SUPPORT
   13878 
   13879 
   13880 // Finds the script object from the script data. NOTE: This operation uses
   13881 // heap traversal to find the function generated for the source position
   13882 // for the requested break point. For lazily compiled functions several heap
   13883 // traversals might be required rendering this operation as a rather slow
   13884 // operation. However for setting break points which is normally done through
   13885 // some kind of user interaction the performance is not crucial.
   13886 static Handle<Object> Runtime_GetScriptFromScriptName(
   13887     Handle<String> script_name) {
   13888   // Scan the heap for Script objects to find the script with the requested
   13889   // script data.
   13890   Handle<Script> script;
   13891   Factory* factory = script_name->GetIsolate()->factory();
   13892   Heap* heap = script_name->GetHeap();
   13893   heap->EnsureHeapIsIterable();
   13894   DisallowHeapAllocation no_allocation_during_heap_iteration;
   13895   HeapIterator iterator(heap);
   13896   HeapObject* obj = NULL;
   13897   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
   13898     // If a script is found check if it has the script data requested.
   13899     if (obj->IsScript()) {
   13900       if (Script::cast(obj)->name()->IsString()) {
   13901         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
   13902           script = Handle<Script>(Script::cast(obj));
   13903         }
   13904       }
   13905     }
   13906   }
   13907 
   13908   // If no script with the requested script data is found return undefined.
   13909   if (script.is_null()) return factory->undefined_value();
   13910 
   13911   // Return the script found.
   13912   return GetScriptWrapper(script);
   13913 }
   13914 
   13915 
   13916 // Get the script object from script data. NOTE: Regarding performance
   13917 // see the NOTE for GetScriptFromScriptData.
   13918 // args[0]: script data for the script to find the source for
   13919 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
   13920   HandleScope scope(isolate);
   13921 
   13922   ASSERT(args.length() == 1);
   13923 
   13924   CONVERT_ARG_CHECKED(String, script_name, 0);
   13925 
   13926   // Find the requested script.
   13927   Handle<Object> result =
   13928       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
   13929   return *result;
   13930 }
   13931 
   13932 
   13933 // Collect the raw data for a stack trace.  Returns an array of 4
   13934 // element segments each containing a receiver, function, code and
   13935 // native code offset.
   13936 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
   13937   HandleScope scope(isolate);
   13938   ASSERT_EQ(args.length(), 3);
   13939   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   13940   Handle<Object> caller = args.at<Object>(1);
   13941   CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
   13942 
   13943   // Optionally capture a more detailed stack trace for the message.
   13944   isolate->CaptureAndSetDetailedStackTrace(error_object);
   13945   // Capture a simple stack trace for the stack property.
   13946   return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
   13947 }
   13948 
   13949 
   13950 // Retrieve the stack trace.  This is the raw stack trace that yet has to
   13951 // be formatted.  Since we only need this once, clear it afterwards.
   13952 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
   13953   HandleScope scope(isolate);
   13954   ASSERT_EQ(args.length(), 1);
   13955   CONVERT_ARG_CHECKED(JSObject, error_object, 0);
   13956   String* key = isolate->heap()->hidden_stack_trace_string();
   13957   Object* result = error_object->GetHiddenProperty(key);
   13958   if (result->IsTheHole()) return isolate->heap()->undefined_value();
   13959   RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
   13960   error_object->DeleteHiddenProperty(key);
   13961   return result;
   13962 }
   13963 
   13964 
   13965 // Returns V8 version as a string.
   13966 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
   13967   SealHandleScope shs(isolate);
   13968   ASSERT_EQ(args.length(), 0);
   13969 
   13970   const char* version_string = v8::V8::GetVersion();
   13971 
   13972   return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string),
   13973                                                   NOT_TENURED);
   13974 }
   13975 
   13976 
   13977 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
   13978   SealHandleScope shs(isolate);
   13979   ASSERT(args.length() == 2);
   13980   OS::PrintError("abort: %s\n",
   13981                  reinterpret_cast<char*>(args[0]) + args.smi_at(1));
   13982   isolate->PrintStack(stderr);
   13983   OS::Abort();
   13984   UNREACHABLE();
   13985   return NULL;
   13986 }
   13987 
   13988 
   13989 RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) {
   13990   HandleScope scope(isolate);
   13991   ASSERT(args.length() == 1);
   13992   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   13993   FlattenString(str);
   13994   return isolate->heap()->undefined_value();
   13995 }
   13996 
   13997 
   13998 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
   13999   HandleScope scope(isolate);
   14000   ASSERT(args.length() == 0);
   14001   isolate->heap()->NotifyContextDisposed();
   14002   return isolate->heap()->undefined_value();
   14003 }
   14004 
   14005 
   14006 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) {
   14007   HandleScope scope(isolate);
   14008   ASSERT(args.length() == 1);
   14009   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   14010   if (!object->IsJSObject()) return Smi::FromInt(0);
   14011   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   14012   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
   14013   JSObject::MigrateInstance(js_object);
   14014   return *object;
   14015 }
   14016 
   14017 
   14018 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
   14019   SealHandleScope shs(isolate);
   14020   // This is only called from codegen, so checks might be more lax.
   14021   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
   14022   Object* key = args[1];
   14023 
   14024   int finger_index = cache->finger_index();
   14025   Object* o = cache->get(finger_index);
   14026   if (o == key) {
   14027     // The fastest case: hit the same place again.
   14028     return cache->get(finger_index + 1);
   14029   }
   14030 
   14031   for (int i = finger_index - 2;
   14032        i >= JSFunctionResultCache::kEntriesIndex;
   14033        i -= 2) {
   14034     o = cache->get(i);
   14035     if (o == key) {
   14036       cache->set_finger_index(i);
   14037       return cache->get(i + 1);
   14038     }
   14039   }
   14040 
   14041   int size = cache->size();
   14042   ASSERT(size <= cache->length());
   14043 
   14044   for (int i = size - 2; i > finger_index; i -= 2) {
   14045     o = cache->get(i);
   14046     if (o == key) {
   14047       cache->set_finger_index(i);
   14048       return cache->get(i + 1);
   14049     }
   14050   }
   14051 
   14052   // There is no value in the cache.  Invoke the function and cache result.
   14053   HandleScope scope(isolate);
   14054 
   14055   Handle<JSFunctionResultCache> cache_handle(cache);
   14056   Handle<Object> key_handle(key, isolate);
   14057   Handle<Object> value;
   14058   {
   14059     Handle<JSFunction> factory(JSFunction::cast(
   14060           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
   14061     // TODO(antonm): consider passing a receiver when constructing a cache.
   14062     Handle<Object> receiver(isolate->native_context()->global_object(),
   14063                             isolate);
   14064     // This handle is nor shared, nor used later, so it's safe.
   14065     Handle<Object> argv[] = { key_handle };
   14066     bool pending_exception;
   14067     value = Execution::Call(factory,
   14068                             receiver,
   14069                             ARRAY_SIZE(argv),
   14070                             argv,
   14071                             &pending_exception);
   14072     if (pending_exception) return Failure::Exception();
   14073   }
   14074 
   14075 #ifdef VERIFY_HEAP
   14076   if (FLAG_verify_heap) {
   14077     cache_handle->JSFunctionResultCacheVerify();
   14078   }
   14079 #endif
   14080 
   14081   // Function invocation may have cleared the cache.  Reread all the data.
   14082   finger_index = cache_handle->finger_index();
   14083   size = cache_handle->size();
   14084 
   14085   // If we have spare room, put new data into it, otherwise evict post finger
   14086   // entry which is likely to be the least recently used.
   14087   int index = -1;
   14088   if (size < cache_handle->length()) {
   14089     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
   14090     index = size;
   14091   } else {
   14092     index = finger_index + JSFunctionResultCache::kEntrySize;
   14093     if (index == cache_handle->length()) {
   14094       index = JSFunctionResultCache::kEntriesIndex;
   14095     }
   14096   }
   14097 
   14098   ASSERT(index % 2 == 0);
   14099   ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
   14100   ASSERT(index < cache_handle->length());
   14101 
   14102   cache_handle->set(index, *key_handle);
   14103   cache_handle->set(index + 1, *value);
   14104   cache_handle->set_finger_index(index);
   14105 
   14106 #ifdef VERIFY_HEAP
   14107   if (FLAG_verify_heap) {
   14108     cache_handle->JSFunctionResultCacheVerify();
   14109   }
   14110 #endif
   14111 
   14112   return *value;
   14113 }
   14114 
   14115 
   14116 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
   14117   SealHandleScope shs(isolate);
   14118   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14119   return Smi::FromInt(message->start_position());
   14120 }
   14121 
   14122 
   14123 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
   14124   SealHandleScope shs(isolate);
   14125   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   14126   return message->script();
   14127 }
   14128 
   14129 
   14130 #ifdef DEBUG
   14131 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
   14132 // Exclude the code in release mode.
   14133 RUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
   14134   HandleScope scope(isolate);
   14135   ASSERT(args.length() == 0);
   14136 #define COUNT_ENTRY(Name, argc, ressize) + 1
   14137   int entry_count = 0
   14138       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
   14139       INLINE_FUNCTION_LIST(COUNT_ENTRY)
   14140       INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY);
   14141 #undef COUNT_ENTRY
   14142   Factory* factory = isolate->factory();
   14143   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
   14144   int index = 0;
   14145   bool inline_runtime_functions = false;
   14146 #define ADD_ENTRY(Name, argc, ressize)                                       \
   14147   {                                                                          \
   14148     HandleScope inner(isolate);                                              \
   14149     Handle<String> name;                                                     \
   14150     /* Inline runtime functions have an underscore in front of the name. */  \
   14151     if (inline_runtime_functions) {                                          \
   14152       name = factory->NewStringFromAscii(                                    \
   14153           Vector<const char>("_" #Name, StrLength("_" #Name)));              \
   14154     } else {                                                                 \
   14155       name = factory->NewStringFromAscii(                                    \
   14156           Vector<const char>(#Name, StrLength(#Name)));                      \
   14157     }                                                                        \
   14158     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
   14159     pair_elements->set(0, *name);                                            \
   14160     pair_elements->set(1, Smi::FromInt(argc));                               \
   14161     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
   14162     elements->set(index++, *pair);                                           \
   14163   }
   14164   inline_runtime_functions = false;
   14165   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   14166   inline_runtime_functions = true;
   14167   INLINE_FUNCTION_LIST(ADD_ENTRY)
   14168   INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   14169 #undef ADD_ENTRY
   14170   ASSERT_EQ(index, entry_count);
   14171   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
   14172   return *result;
   14173 }
   14174 #endif
   14175 
   14176 
   14177 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
   14178   SealHandleScope shs(isolate);
   14179   ASSERT(args.length() == 2);
   14180   CONVERT_ARG_CHECKED(String, format, 0);
   14181   CONVERT_ARG_CHECKED(JSArray, elms, 1);
   14182   DisallowHeapAllocation no_gc;
   14183   String::FlatContent format_content = format->GetFlatContent();
   14184   RUNTIME_ASSERT(format_content.IsAscii());
   14185   Vector<const uint8_t> chars = format_content.ToOneByteVector();
   14186   isolate->logger()->LogRuntime(Vector<const char>::cast(chars), elms);
   14187   return isolate->heap()->undefined_value();
   14188 }
   14189 
   14190 
   14191 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
   14192   UNREACHABLE();  // implemented as macro in the parser
   14193   return NULL;
   14194 }
   14195 
   14196 
   14197 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
   14198   RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) {     \
   14199     CONVERT_ARG_CHECKED(JSObject, obj, 0);              \
   14200     return isolate->heap()->ToBoolean(obj->Has##Name());  \
   14201   }
   14202 
   14203 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
   14204 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
   14205 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
   14206 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
   14207 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
   14208 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
   14209 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(NonStrictArgumentsElements)
   14210 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
   14211 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
   14212 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
   14213 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
   14214 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
   14215 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
   14216 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
   14217 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
   14218 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
   14219 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
   14220 // Properties test sitting with elements tests - not fooling anyone.
   14221 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
   14222 
   14223 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
   14224 
   14225 
   14226 RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
   14227   SealHandleScope shs(isolate);
   14228   ASSERT(args.length() == 2);
   14229   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
   14230   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
   14231   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
   14232 }
   14233 
   14234 
   14235 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
   14236   SealHandleScope shs(isolate);
   14237   ASSERT(args.length() == 1);
   14238 
   14239   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
   14240   JSReceiver* obj = JSReceiver::cast(args[0]);
   14241   if (obj->IsJSGlobalProxy()) {
   14242     Object* proto = obj->GetPrototype();
   14243     if (proto->IsNull()) return isolate->heap()->false_value();
   14244     ASSERT(proto->IsJSGlobalObject());
   14245     obj = JSReceiver::cast(proto);
   14246   }
   14247   return isolate->heap()->ToBoolean(obj->map()->is_observed());
   14248 }
   14249 
   14250 
   14251 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) {
   14252   SealHandleScope shs(isolate);
   14253   ASSERT(args.length() == 1);
   14254   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
   14255   if (obj->IsJSGlobalProxy()) {
   14256     Object* proto = obj->GetPrototype();
   14257     if (proto->IsNull()) return isolate->heap()->undefined_value();
   14258     ASSERT(proto->IsJSGlobalObject());
   14259     obj = JSReceiver::cast(proto);
   14260   }
   14261   if (obj->IsJSProxy())
   14262     return isolate->heap()->undefined_value();
   14263 
   14264   ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() &&
   14265            JSObject::cast(obj)->HasFastElements()));
   14266   ASSERT(obj->IsJSObject());
   14267   return JSObject::cast(obj)->SetObserved(isolate);
   14268 }
   14269 
   14270 
   14271 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetObserverDeliveryPending) {
   14272   SealHandleScope shs(isolate);
   14273   ASSERT(args.length() == 0);
   14274   isolate->set_observer_delivery_pending(true);
   14275   return isolate->heap()->undefined_value();
   14276 }
   14277 
   14278 
   14279 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetObservationState) {
   14280   SealHandleScope shs(isolate);
   14281   ASSERT(args.length() == 0);
   14282   return isolate->heap()->observation_state();
   14283 }
   14284 
   14285 
   14286 RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapCreate) {
   14287   HandleScope scope(isolate);
   14288   ASSERT(args.length() == 0);
   14289   // TODO(adamk): Currently this runtime function is only called three times per
   14290   // isolate. If it's called more often, the map should be moved into the
   14291   // strong root list.
   14292   Handle<Map> map =
   14293       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
   14294   Handle<JSWeakMap> weakmap =
   14295       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
   14296   return WeakCollectionInitialize(isolate, weakmap);
   14297 }
   14298 
   14299 
   14300 RUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) {
   14301   SealHandleScope shs(isolate);
   14302   ASSERT(args.length() == 1);
   14303   Object* object = args[0];
   14304   if (object->IsJSGlobalProxy()) {
   14305     object = object->GetPrototype(isolate);
   14306     if (object->IsNull()) return isolate->heap()->undefined_value();
   14307   }
   14308   return object;
   14309 }
   14310 
   14311 
   14312 static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
   14313                                            Handle<JSFunction> constructor,
   14314                                            Handle<Object> type_info,
   14315                                            Arguments* caller_args) {
   14316   bool holey = false;
   14317   bool can_use_type_feedback = true;
   14318   if (caller_args->length() == 1) {
   14319     Object* argument_one = (*caller_args)[0];
   14320     if (argument_one->IsSmi()) {
   14321       int value = Smi::cast(argument_one)->value();
   14322       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
   14323         // the array is a dictionary in this case.
   14324         can_use_type_feedback = false;
   14325       } else if (value != 0) {
   14326         holey = true;
   14327       }
   14328     } else {
   14329       // Non-smi length argument produces a dictionary
   14330       can_use_type_feedback = false;
   14331     }
   14332   }
   14333 
   14334   JSArray* array;
   14335   MaybeObject* maybe_array;
   14336   if (!type_info.is_null() &&
   14337       *type_info != isolate->heap()->undefined_value() &&
   14338       Cell::cast(*type_info)->value()->IsAllocationSite() &&
   14339       can_use_type_feedback) {
   14340     Handle<Cell> cell = Handle<Cell>::cast(type_info);
   14341     Handle<AllocationSite> site = Handle<AllocationSite>(
   14342         AllocationSite::cast(cell->value()), isolate);
   14343     ASSERT(!site->IsLiteralSite());
   14344     ElementsKind to_kind = site->GetElementsKind();
   14345     if (holey && !IsFastHoleyElementsKind(to_kind)) {
   14346       to_kind = GetHoleyElementsKind(to_kind);
   14347       // Update the allocation site info to reflect the advice alteration.
   14348       site->SetElementsKind(to_kind);
   14349     }
   14350 
   14351     maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
   14352         *constructor, site);
   14353     if (!maybe_array->To(&array)) return maybe_array;
   14354   } else {
   14355     maybe_array = isolate->heap()->AllocateJSObject(*constructor);
   14356     if (!maybe_array->To(&array)) return maybe_array;
   14357     // We might need to transition to holey
   14358     ElementsKind kind = constructor->initial_map()->elements_kind();
   14359     if (holey && !IsFastHoleyElementsKind(kind)) {
   14360       kind = GetHoleyElementsKind(kind);
   14361       maybe_array = array->TransitionElementsKind(kind);
   14362       if (maybe_array->IsFailure()) return maybe_array;
   14363     }
   14364   }
   14365 
   14366   maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0,
   14367       DONT_INITIALIZE_ARRAY_ELEMENTS);
   14368   if (maybe_array->IsFailure()) return maybe_array;
   14369   maybe_array = ArrayConstructInitializeElements(array, caller_args);
   14370   if (maybe_array->IsFailure()) return maybe_array;
   14371   return array;
   14372 }
   14373 
   14374 
   14375 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
   14376   HandleScope scope(isolate);
   14377   // If we get 2 arguments then they are the stub parameters (constructor, type
   14378   // info).  If we get 3, then the first one is a pointer to the arguments
   14379   // passed by the caller.
   14380   Arguments empty_args(0, NULL);
   14381   bool no_caller_args = args.length() == 2;
   14382   ASSERT(no_caller_args || args.length() == 3);
   14383   int parameters_start = no_caller_args ? 0 : 1;
   14384   Arguments* caller_args = no_caller_args
   14385       ? &empty_args
   14386       : reinterpret_cast<Arguments*>(args[0]);
   14387   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   14388   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
   14389 
   14390   return ArrayConstructorCommon(isolate,
   14391                                 constructor,
   14392                                 type_info,
   14393                                 caller_args);
   14394 }
   14395 
   14396 
   14397 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) {
   14398   HandleScope scope(isolate);
   14399   Arguments empty_args(0, NULL);
   14400   bool no_caller_args = args.length() == 1;
   14401   ASSERT(no_caller_args || args.length() == 2);
   14402   int parameters_start = no_caller_args ? 0 : 1;
   14403   Arguments* caller_args = no_caller_args
   14404       ? &empty_args
   14405       : reinterpret_cast<Arguments*>(args[0]);
   14406   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
   14407 
   14408   return ArrayConstructorCommon(isolate,
   14409                                 constructor,
   14410                                 Handle<Object>::null(),
   14411                                 caller_args);
   14412 }
   14413 
   14414 
   14415 // ----------------------------------------------------------------------------
   14416 // Implementation of Runtime
   14417 
   14418 #define F(name, number_of_args, result_size)                             \
   14419   { Runtime::k##name, Runtime::RUNTIME, #name,   \
   14420     FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
   14421 
   14422 
   14423 #define I(name, number_of_args, result_size)                             \
   14424   { Runtime::kInline##name, Runtime::INLINE,     \
   14425     "_" #name, NULL, number_of_args, result_size },
   14426 
   14427 static const Runtime::Function kIntrinsicFunctions[] = {
   14428   RUNTIME_FUNCTION_LIST(F)
   14429   INLINE_FUNCTION_LIST(I)
   14430   INLINE_RUNTIME_FUNCTION_LIST(I)
   14431 };
   14432 
   14433 
   14434 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
   14435                                                        Object* dictionary) {
   14436   ASSERT(Isolate::Current()->heap() == heap);
   14437   ASSERT(dictionary != NULL);
   14438   ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0);
   14439   for (int i = 0; i < kNumFunctions; ++i) {
   14440     Object* name_string;
   14441     { MaybeObject* maybe_name_string =
   14442           heap->InternalizeUtf8String(kIntrinsicFunctions[i].name);
   14443       if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
   14444     }
   14445     NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
   14446     { MaybeObject* maybe_dictionary = name_dictionary->Add(
   14447           String::cast(name_string),
   14448           Smi::FromInt(i),
   14449           PropertyDetails(NONE, NORMAL, Representation::None()));
   14450       if (!maybe_dictionary->ToObject(&dictionary)) {
   14451         // Non-recoverable failure.  Calling code must restart heap
   14452         // initialization.
   14453         return maybe_dictionary;
   14454       }
   14455     }
   14456   }
   14457   return dictionary;
   14458 }
   14459 
   14460 
   14461 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
   14462   Heap* heap = name->GetHeap();
   14463   int entry = heap->intrinsic_function_names()->FindEntry(*name);
   14464   if (entry != kNotFound) {
   14465     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
   14466     int function_index = Smi::cast(smi_index)->value();
   14467     return &(kIntrinsicFunctions[function_index]);
   14468   }
   14469   return NULL;
   14470 }
   14471 
   14472 
   14473 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
   14474   return &(kIntrinsicFunctions[static_cast<int>(id)]);
   14475 }
   14476 
   14477 
   14478 void Runtime::PerformGC(Object* result) {
   14479   Isolate* isolate = Isolate::Current();
   14480   Failure* failure = Failure::cast(result);
   14481   if (failure->IsRetryAfterGC()) {
   14482     if (isolate->heap()->new_space()->AddFreshPage()) {
   14483       return;
   14484     }
   14485 
   14486     // Try to do a garbage collection; ignore it if it fails. The C
   14487     // entry stub will throw an out-of-memory exception in that case.
   14488     isolate->heap()->CollectGarbage(failure->allocation_space(),
   14489                                     "Runtime::PerformGC");
   14490   } else {
   14491     // Handle last resort GC and make sure to allow future allocations
   14492     // to grow the heap without causing GCs (if possible).
   14493     isolate->counters()->gc_last_resort_from_js()->Increment();
   14494     isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
   14495                                        "Runtime::PerformGC");
   14496   }
   14497 }
   14498 
   14499 
   14500 } }  // namespace v8::internal
   14501