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 
     30 #include "v8.h"
     31 
     32 #include "accessors.h"
     33 #include "api.h"
     34 #include "arguments.h"
     35 #include "bootstrapper.h"
     36 #include "codegen.h"
     37 #include "compilation-cache.h"
     38 #include "compiler.h"
     39 #include "cpu.h"
     40 #include "dateparser-inl.h"
     41 #include "debug.h"
     42 #include "deoptimizer.h"
     43 #include "date.h"
     44 #include "execution.h"
     45 #include "global-handles.h"
     46 #include "isolate-inl.h"
     47 #include "jsregexp.h"
     48 #include "json-parser.h"
     49 #include "liveedit.h"
     50 #include "liveobjectlist-inl.h"
     51 #include "misc-intrinsics.h"
     52 #include "parser.h"
     53 #include "platform.h"
     54 #include "runtime-profiler.h"
     55 #include "runtime.h"
     56 #include "scopeinfo.h"
     57 #include "smart-array-pointer.h"
     58 #include "string-search.h"
     59 #include "stub-cache.h"
     60 #include "v8threads.h"
     61 #include "vm-state-inl.h"
     62 
     63 namespace v8 {
     64 namespace internal {
     65 
     66 
     67 #define RUNTIME_ASSERT(value) \
     68   if (!(value)) return isolate->ThrowIllegalOperation();
     69 
     70 // Cast the given object to a value of the specified type and store
     71 // it in a variable with the given name.  If the object is not of the
     72 // expected type call IllegalOperation and return.
     73 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
     74   RUNTIME_ASSERT(args[index]->Is##Type());                           \
     75   Type* name = Type::cast(args[index]);
     76 
     77 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
     78   RUNTIME_ASSERT(args[index]->Is##Type());                           \
     79   Handle<Type> name = args.at<Type>(index);
     80 
     81 // Cast the given object to a boolean and store it in a variable with
     82 // the given name.  If the object is not a boolean call IllegalOperation
     83 // and return.
     84 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
     85   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
     86   bool name = args[index]->IsTrue();
     87 
     88 // Cast the given argument to a Smi and store its value in an int variable
     89 // with the given name.  If the argument is not a Smi call IllegalOperation
     90 // and return.
     91 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
     92   RUNTIME_ASSERT(args[index]->IsSmi());                              \
     93   int name = args.smi_at(index);
     94 
     95 // Cast the given argument to a double and store it in a variable with
     96 // the given name.  If the argument is not a number (as opposed to
     97 // the number not-a-number) call IllegalOperation and return.
     98 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
     99   RUNTIME_ASSERT(args[index]->IsNumber());                           \
    100   double name = args.number_at(index);
    101 
    102 // Call the specified converter on the object *comand store the result in
    103 // a variable of the specified type with the given name.  If the
    104 // object is not a Number call IllegalOperation and return.
    105 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
    106   RUNTIME_ASSERT(obj->IsNumber());                                   \
    107   type name = NumberTo##Type(obj);
    108 
    109 
    110 // Cast the given argument to PropertyDetails and store its value in a
    111 // variable with the given name.  If the argument is not a Smi call
    112 // IllegalOperation and return.
    113 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
    114   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    115   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
    116 
    117 
    118 // Assert that the given argument has a valid value for a StrictModeFlag
    119 // and store it in a StrictModeFlag variable with the given name.
    120 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
    121   RUNTIME_ASSERT(args[index]->IsSmi());                              \
    122   RUNTIME_ASSERT(args.smi_at(index) == kStrictMode ||                \
    123                  args.smi_at(index) == kNonStrictMode);              \
    124   StrictModeFlag name =                                              \
    125       static_cast<StrictModeFlag>(args.smi_at(index));
    126 
    127 
    128 // Assert that the given argument has a valid value for a LanguageMode
    129 // and store it in a LanguageMode variable with the given name.
    130 #define CONVERT_LANGUAGE_MODE_ARG(name, index)                       \
    131   ASSERT(args[index]->IsSmi());                                      \
    132   ASSERT(args.smi_at(index) == CLASSIC_MODE ||                       \
    133          args.smi_at(index) == STRICT_MODE ||                        \
    134          args.smi_at(index) == EXTENDED_MODE);                       \
    135   LanguageMode name =                                                \
    136       static_cast<LanguageMode>(args.smi_at(index));
    137 
    138 
    139 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
    140                                                    JSObject* boilerplate) {
    141   StackLimitCheck check(isolate);
    142   if (check.HasOverflowed()) return isolate->StackOverflow();
    143 
    144   Heap* heap = isolate->heap();
    145   Object* result;
    146   { MaybeObject* maybe_result = heap->CopyJSObject(boilerplate);
    147     if (!maybe_result->ToObject(&result)) return maybe_result;
    148   }
    149   JSObject* copy = JSObject::cast(result);
    150 
    151   // Deep copy local properties.
    152   if (copy->HasFastProperties()) {
    153     FixedArray* properties = copy->properties();
    154     for (int i = 0; i < properties->length(); i++) {
    155       Object* value = properties->get(i);
    156       if (value->IsJSObject()) {
    157         JSObject* js_object = JSObject::cast(value);
    158         { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
    159           if (!maybe_result->ToObject(&result)) return maybe_result;
    160         }
    161         properties->set(i, result);
    162       }
    163     }
    164     int nof = copy->map()->inobject_properties();
    165     for (int i = 0; i < nof; i++) {
    166       Object* value = copy->InObjectPropertyAt(i);
    167       if (value->IsJSObject()) {
    168         JSObject* js_object = JSObject::cast(value);
    169         { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
    170           if (!maybe_result->ToObject(&result)) return maybe_result;
    171         }
    172         copy->InObjectPropertyAtPut(i, result);
    173       }
    174     }
    175   } else {
    176     { MaybeObject* maybe_result =
    177           heap->AllocateFixedArray(copy->NumberOfLocalProperties());
    178       if (!maybe_result->ToObject(&result)) return maybe_result;
    179     }
    180     FixedArray* names = FixedArray::cast(result);
    181     copy->GetLocalPropertyNames(names, 0);
    182     for (int i = 0; i < names->length(); i++) {
    183       ASSERT(names->get(i)->IsString());
    184       String* key_string = String::cast(names->get(i));
    185       PropertyAttributes attributes =
    186           copy->GetLocalPropertyAttribute(key_string);
    187       // Only deep copy fields from the object literal expression.
    188       // In particular, don't try to copy the length attribute of
    189       // an array.
    190       if (attributes != NONE) continue;
    191       Object* value =
    192           copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
    193       if (value->IsJSObject()) {
    194         JSObject* js_object = JSObject::cast(value);
    195         { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
    196           if (!maybe_result->ToObject(&result)) return maybe_result;
    197         }
    198         { MaybeObject* maybe_result =
    199               // Creating object copy for literals. No strict mode needed.
    200               copy->SetProperty(key_string, result, NONE, kNonStrictMode);
    201           if (!maybe_result->ToObject(&result)) return maybe_result;
    202         }
    203       }
    204     }
    205   }
    206 
    207   // Deep copy local elements.
    208   // Pixel elements cannot be created using an object literal.
    209   ASSERT(!copy->HasExternalArrayElements());
    210   switch (copy->GetElementsKind()) {
    211     case FAST_SMI_ONLY_ELEMENTS:
    212     case FAST_ELEMENTS: {
    213       FixedArray* elements = FixedArray::cast(copy->elements());
    214       if (elements->map() == heap->fixed_cow_array_map()) {
    215         isolate->counters()->cow_arrays_created_runtime()->Increment();
    216 #ifdef DEBUG
    217         for (int i = 0; i < elements->length(); i++) {
    218           ASSERT(!elements->get(i)->IsJSObject());
    219         }
    220 #endif
    221       } else {
    222         for (int i = 0; i < elements->length(); i++) {
    223           Object* value = elements->get(i);
    224           ASSERT(value->IsSmi() ||
    225                  value->IsTheHole() ||
    226                  (copy->GetElementsKind() == FAST_ELEMENTS));
    227           if (value->IsJSObject()) {
    228             JSObject* js_object = JSObject::cast(value);
    229             { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
    230                                                               js_object);
    231               if (!maybe_result->ToObject(&result)) return maybe_result;
    232             }
    233             elements->set(i, result);
    234           }
    235         }
    236       }
    237       break;
    238     }
    239     case DICTIONARY_ELEMENTS: {
    240       SeededNumberDictionary* element_dictionary = copy->element_dictionary();
    241       int capacity = element_dictionary->Capacity();
    242       for (int i = 0; i < capacity; i++) {
    243         Object* k = element_dictionary->KeyAt(i);
    244         if (element_dictionary->IsKey(k)) {
    245           Object* value = element_dictionary->ValueAt(i);
    246           if (value->IsJSObject()) {
    247             JSObject* js_object = JSObject::cast(value);
    248             { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
    249                                                               js_object);
    250               if (!maybe_result->ToObject(&result)) return maybe_result;
    251             }
    252             element_dictionary->ValueAtPut(i, result);
    253           }
    254         }
    255       }
    256       break;
    257     }
    258     case NON_STRICT_ARGUMENTS_ELEMENTS:
    259       UNIMPLEMENTED();
    260       break;
    261     case EXTERNAL_PIXEL_ELEMENTS:
    262     case EXTERNAL_BYTE_ELEMENTS:
    263     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
    264     case EXTERNAL_SHORT_ELEMENTS:
    265     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
    266     case EXTERNAL_INT_ELEMENTS:
    267     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
    268     case EXTERNAL_FLOAT_ELEMENTS:
    269     case EXTERNAL_DOUBLE_ELEMENTS:
    270     case FAST_DOUBLE_ELEMENTS:
    271       // No contained objects, nothing to do.
    272       break;
    273   }
    274   return copy;
    275 }
    276 
    277 
    278 static Handle<Map> ComputeObjectLiteralMap(
    279     Handle<Context> context,
    280     Handle<FixedArray> constant_properties,
    281     bool* is_result_from_cache) {
    282   Isolate* isolate = context->GetIsolate();
    283   int properties_length = constant_properties->length();
    284   int number_of_properties = properties_length / 2;
    285   // Check that there are only symbols and array indices among keys.
    286   int number_of_symbol_keys = 0;
    287   for (int p = 0; p != properties_length; p += 2) {
    288     Object* key = constant_properties->get(p);
    289     uint32_t element_index = 0;
    290     if (key->IsSymbol()) {
    291       number_of_symbol_keys++;
    292     } else if (key->ToArrayIndex(&element_index)) {
    293       // An index key does not require space in the property backing store.
    294       number_of_properties--;
    295     } else {
    296       // Bail out as a non-symbol non-index key makes caching impossible.
    297       // ASSERT to make sure that the if condition after the loop is false.
    298       ASSERT(number_of_symbol_keys != number_of_properties);
    299       break;
    300     }
    301   }
    302   // If we only have symbols and array indices among keys then we can
    303   // use the map cache in the global context.
    304   const int kMaxKeys = 10;
    305   if ((number_of_symbol_keys == number_of_properties) &&
    306       (number_of_symbol_keys < kMaxKeys)) {
    307     // Create the fixed array with the key.
    308     Handle<FixedArray> keys =
    309         isolate->factory()->NewFixedArray(number_of_symbol_keys);
    310     if (number_of_symbol_keys > 0) {
    311       int index = 0;
    312       for (int p = 0; p < properties_length; p += 2) {
    313         Object* key = constant_properties->get(p);
    314         if (key->IsSymbol()) {
    315           keys->set(index++, key);
    316         }
    317       }
    318       ASSERT(index == number_of_symbol_keys);
    319     }
    320     *is_result_from_cache = true;
    321     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
    322   }
    323   *is_result_from_cache = false;
    324   return isolate->factory()->CopyMap(
    325       Handle<Map>(context->object_function()->initial_map()),
    326       number_of_properties);
    327 }
    328 
    329 
    330 static Handle<Object> CreateLiteralBoilerplate(
    331     Isolate* isolate,
    332     Handle<FixedArray> literals,
    333     Handle<FixedArray> constant_properties);
    334 
    335 
    336 static Handle<Object> CreateObjectLiteralBoilerplate(
    337     Isolate* isolate,
    338     Handle<FixedArray> literals,
    339     Handle<FixedArray> constant_properties,
    340     bool should_have_fast_elements,
    341     bool has_function_literal) {
    342   // Get the global context from the literals array.  This is the
    343   // context in which the function was created and we use the object
    344   // function from this context to create the object literal.  We do
    345   // not use the object function from the current global context
    346   // because this might be the object function from another context
    347   // which we should not have access to.
    348   Handle<Context> context =
    349       Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals));
    350 
    351   // In case we have function literals, we want the object to be in
    352   // slow properties mode for now. We don't go in the map cache because
    353   // maps with constant functions can't be shared if the functions are
    354   // not the same (which is the common case).
    355   bool is_result_from_cache = false;
    356   Handle<Map> map = has_function_literal
    357       ? Handle<Map>(context->object_function()->initial_map())
    358       : ComputeObjectLiteralMap(context,
    359                                 constant_properties,
    360                                 &is_result_from_cache);
    361 
    362   Handle<JSObject> boilerplate = isolate->factory()->NewJSObjectFromMap(map);
    363 
    364   // Normalize the elements of the boilerplate to save space if needed.
    365   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
    366 
    367   // Add the constant properties to the boilerplate.
    368   int length = constant_properties->length();
    369   bool should_transform =
    370       !is_result_from_cache && boilerplate->HasFastProperties();
    371   if (should_transform || has_function_literal) {
    372     // Normalize the properties of object to avoid n^2 behavior
    373     // when extending the object multiple properties. Indicate the number of
    374     // properties to be added.
    375     JSObject::NormalizeProperties(
    376         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
    377   }
    378 
    379   for (int index = 0; index < length; index +=2) {
    380     Handle<Object> key(constant_properties->get(index+0), isolate);
    381     Handle<Object> value(constant_properties->get(index+1), isolate);
    382     if (value->IsFixedArray()) {
    383       // The value contains the constant_properties of a
    384       // simple object or array literal.
    385       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
    386       value = CreateLiteralBoilerplate(isolate, literals, array);
    387       if (value.is_null()) return value;
    388     }
    389     Handle<Object> result;
    390     uint32_t element_index = 0;
    391     if (key->IsSymbol()) {
    392       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
    393         // Array index as string (uint32).
    394         result = JSObject::SetOwnElement(
    395             boilerplate, element_index, value, kNonStrictMode);
    396       } else {
    397         Handle<String> name(String::cast(*key));
    398         ASSERT(!name->AsArrayIndex(&element_index));
    399         result = JSObject::SetLocalPropertyIgnoreAttributes(
    400             boilerplate, name, value, NONE);
    401       }
    402     } else if (key->ToArrayIndex(&element_index)) {
    403       // Array index (uint32).
    404       result = JSObject::SetOwnElement(
    405           boilerplate, element_index, value, kNonStrictMode);
    406     } else {
    407       // Non-uint32 number.
    408       ASSERT(key->IsNumber());
    409       double num = key->Number();
    410       char arr[100];
    411       Vector<char> buffer(arr, ARRAY_SIZE(arr));
    412       const char* str = DoubleToCString(num, buffer);
    413       Handle<String> name =
    414           isolate->factory()->NewStringFromAscii(CStrVector(str));
    415       result = JSObject::SetLocalPropertyIgnoreAttributes(
    416           boilerplate, name, value, NONE);
    417     }
    418     // If setting the property on the boilerplate throws an
    419     // exception, the exception is converted to an empty handle in
    420     // the handle based operations.  In that case, we need to
    421     // convert back to an exception.
    422     if (result.is_null()) return result;
    423   }
    424 
    425   // Transform to fast properties if necessary. For object literals with
    426   // containing function literals we defer this operation until after all
    427   // computed properties have been assigned so that we can generate
    428   // constant function properties.
    429   if (should_transform && !has_function_literal) {
    430     JSObject::TransformToFastProperties(
    431         boilerplate, boilerplate->map()->unused_property_fields());
    432   }
    433 
    434   return boilerplate;
    435 }
    436 
    437 
    438 MaybeObject* TransitionElements(Handle<Object> object,
    439                                 ElementsKind to_kind,
    440                                 Isolate* isolate) {
    441   HandleScope scope(isolate);
    442   if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
    443   ElementsKind from_kind =
    444       Handle<JSObject>::cast(object)->map()->elements_kind();
    445   if (Map::IsValidElementsTransition(from_kind, to_kind)) {
    446     Handle<Object> result = JSObject::TransitionElementsKind(
    447         Handle<JSObject>::cast(object), to_kind);
    448     if (result.is_null()) return isolate->ThrowIllegalOperation();
    449     return *result;
    450   }
    451   return isolate->ThrowIllegalOperation();
    452 }
    453 
    454 
    455 static const int kSmiOnlyLiteralMinimumLength = 1024;
    456 
    457 
    458 Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
    459     Isolate* isolate,
    460     Handle<FixedArray> literals,
    461     Handle<FixedArray> elements) {
    462   // Create the JSArray.
    463   Handle<JSFunction> constructor(
    464       JSFunction::GlobalContextFromLiterals(*literals)->array_function());
    465   Handle<JSArray> object =
    466       Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor));
    467 
    468   ElementsKind constant_elements_kind =
    469       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
    470   Handle<FixedArrayBase> constant_elements_values(
    471       FixedArrayBase::cast(elements->get(1)));
    472 
    473   Context* global_context = isolate->context()->global_context();
    474   if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) {
    475     object->set_map(Map::cast(global_context->smi_js_array_map()));
    476   } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
    477     object->set_map(Map::cast(global_context->double_js_array_map()));
    478   } else {
    479     object->set_map(Map::cast(global_context->object_js_array_map()));
    480   }
    481 
    482   Handle<FixedArrayBase> copied_elements_values;
    483   if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
    484     ASSERT(FLAG_smi_only_arrays);
    485     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
    486         Handle<FixedDoubleArray>::cast(constant_elements_values));
    487   } else {
    488     ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS ||
    489            constant_elements_kind == FAST_ELEMENTS);
    490     const bool is_cow =
    491         (constant_elements_values->map() ==
    492          isolate->heap()->fixed_cow_array_map());
    493     if (is_cow) {
    494       copied_elements_values = constant_elements_values;
    495 #if DEBUG
    496       Handle<FixedArray> fixed_array_values =
    497           Handle<FixedArray>::cast(copied_elements_values);
    498       for (int i = 0; i < fixed_array_values->length(); i++) {
    499         ASSERT(!fixed_array_values->get(i)->IsFixedArray());
    500       }
    501 #endif
    502     } else {
    503       Handle<FixedArray> fixed_array_values =
    504           Handle<FixedArray>::cast(constant_elements_values);
    505       Handle<FixedArray> fixed_array_values_copy =
    506           isolate->factory()->CopyFixedArray(fixed_array_values);
    507       copied_elements_values = fixed_array_values_copy;
    508       for (int i = 0; i < fixed_array_values->length(); i++) {
    509         Object* current = fixed_array_values->get(i);
    510         if (current->IsFixedArray()) {
    511           // The value contains the constant_properties of a
    512           // simple object or array literal.
    513           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
    514           Handle<Object> result =
    515               CreateLiteralBoilerplate(isolate, literals, fa);
    516           if (result.is_null()) return result;
    517           fixed_array_values_copy->set(i, *result);
    518         }
    519       }
    520     }
    521   }
    522   object->set_elements(*copied_elements_values);
    523   object->set_length(Smi::FromInt(copied_elements_values->length()));
    524 
    525   //  Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is
    526   //  on or the object is larger than the threshold.
    527   if (!FLAG_smi_only_arrays &&
    528       constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) {
    529     if (object->GetElementsKind() != FAST_ELEMENTS) {
    530       CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
    531     }
    532   }
    533 
    534   return object;
    535 }
    536 
    537 
    538 static Handle<Object> CreateLiteralBoilerplate(
    539     Isolate* isolate,
    540     Handle<FixedArray> literals,
    541     Handle<FixedArray> array) {
    542   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
    543   const bool kHasNoFunctionLiteral = false;
    544   switch (CompileTimeValue::GetType(array)) {
    545     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
    546       return CreateObjectLiteralBoilerplate(isolate,
    547                                             literals,
    548                                             elements,
    549                                             true,
    550                                             kHasNoFunctionLiteral);
    551     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
    552       return CreateObjectLiteralBoilerplate(isolate,
    553                                             literals,
    554                                             elements,
    555                                             false,
    556                                             kHasNoFunctionLiteral);
    557     case CompileTimeValue::ARRAY_LITERAL:
    558       return Runtime::CreateArrayLiteralBoilerplate(
    559           isolate, literals, elements);
    560     default:
    561       UNREACHABLE();
    562       return Handle<Object>::null();
    563   }
    564 }
    565 
    566 
    567 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
    568   HandleScope scope(isolate);
    569   ASSERT(args.length() == 4);
    570   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    571   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    572   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    573   CONVERT_SMI_ARG_CHECKED(flags, 3);
    574   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    575   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    576 
    577   // Check if boilerplate exists. If not, create it first.
    578   Handle<Object> boilerplate(literals->get(literals_index), isolate);
    579   if (*boilerplate == isolate->heap()->undefined_value()) {
    580     boilerplate = CreateObjectLiteralBoilerplate(isolate,
    581                                                  literals,
    582                                                  constant_properties,
    583                                                  should_have_fast_elements,
    584                                                  has_function_literal);
    585     if (boilerplate.is_null()) return Failure::Exception();
    586     // Update the functions literal and return the boilerplate.
    587     literals->set(literals_index, *boilerplate);
    588   }
    589   return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate));
    590 }
    591 
    592 
    593 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
    594   HandleScope scope(isolate);
    595   ASSERT(args.length() == 4);
    596   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    597   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    598   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
    599   CONVERT_SMI_ARG_CHECKED(flags, 3);
    600   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
    601   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
    602 
    603   // Check if boilerplate exists. If not, create it first.
    604   Handle<Object> boilerplate(literals->get(literals_index), isolate);
    605   if (*boilerplate == isolate->heap()->undefined_value()) {
    606     boilerplate = CreateObjectLiteralBoilerplate(isolate,
    607                                                  literals,
    608                                                  constant_properties,
    609                                                  should_have_fast_elements,
    610                                                  has_function_literal);
    611     if (boilerplate.is_null()) return Failure::Exception();
    612     // Update the functions literal and return the boilerplate.
    613     literals->set(literals_index, *boilerplate);
    614   }
    615   return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
    616 }
    617 
    618 
    619 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
    620   HandleScope scope(isolate);
    621   ASSERT(args.length() == 3);
    622   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    623   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    624   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    625 
    626   // Check if boilerplate exists. If not, create it first.
    627   Handle<Object> boilerplate(literals->get(literals_index), isolate);
    628   if (*boilerplate == isolate->heap()->undefined_value()) {
    629     boilerplate =
    630         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
    631     if (boilerplate.is_null()) return Failure::Exception();
    632     // Update the functions literal and return the boilerplate.
    633     literals->set(literals_index, *boilerplate);
    634   }
    635   return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate));
    636 }
    637 
    638 
    639 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
    640   HandleScope scope(isolate);
    641   ASSERT(args.length() == 3);
    642   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
    643   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
    644   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
    645 
    646   // Check if boilerplate exists. If not, create it first.
    647   Handle<Object> boilerplate(literals->get(literals_index), isolate);
    648   if (*boilerplate == isolate->heap()->undefined_value()) {
    649     ASSERT(*elements != isolate->heap()->empty_fixed_array());
    650     boilerplate =
    651         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
    652     if (boilerplate.is_null()) return Failure::Exception();
    653     // Update the functions literal and return the boilerplate.
    654     literals->set(literals_index, *boilerplate);
    655   }
    656   if (JSObject::cast(*boilerplate)->elements()->map() ==
    657       isolate->heap()->fixed_cow_array_map()) {
    658     isolate->counters()->cow_arrays_created_runtime()->Increment();
    659   }
    660   return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
    661 }
    662 
    663 
    664 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
    665   ASSERT(args.length() == 2);
    666   Object* handler = args[0];
    667   Object* prototype = args[1];
    668   Object* used_prototype =
    669       prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
    670   return isolate->heap()->AllocateJSProxy(handler, used_prototype);
    671 }
    672 
    673 
    674 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) {
    675   ASSERT(args.length() == 4);
    676   Object* handler = args[0];
    677   Object* call_trap = args[1];
    678   Object* construct_trap = args[2];
    679   Object* prototype = args[3];
    680   Object* used_prototype =
    681       prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
    682   return isolate->heap()->AllocateJSFunctionProxy(
    683       handler, call_trap, construct_trap, used_prototype);
    684 }
    685 
    686 
    687 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
    688   ASSERT(args.length() == 1);
    689   Object* obj = args[0];
    690   return isolate->heap()->ToBoolean(obj->IsJSProxy());
    691 }
    692 
    693 
    694 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) {
    695   ASSERT(args.length() == 1);
    696   Object* obj = args[0];
    697   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
    698 }
    699 
    700 
    701 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
    702   ASSERT(args.length() == 1);
    703   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    704   return proxy->handler();
    705 }
    706 
    707 
    708 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
    709   ASSERT(args.length() == 1);
    710   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    711   return proxy->call_trap();
    712 }
    713 
    714 
    715 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
    716   ASSERT(args.length() == 1);
    717   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
    718   return proxy->construct_trap();
    719 }
    720 
    721 
    722 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
    723   ASSERT(args.length() == 1);
    724   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
    725   proxy->Fix();
    726   return isolate->heap()->undefined_value();
    727 }
    728 
    729 
    730 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
    731   HandleScope scope(isolate);
    732   ASSERT(args.length() == 1);
    733   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
    734   Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
    735   holder->set_table(*table);
    736   return *holder;
    737 }
    738 
    739 
    740 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
    741   HandleScope scope(isolate);
    742   ASSERT(args.length() == 2);
    743   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
    744   Handle<Object> key(args[1]);
    745   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
    746   table = ObjectHashSetAdd(table, key);
    747   holder->set_table(*table);
    748   return isolate->heap()->undefined_symbol();
    749 }
    750 
    751 
    752 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
    753   HandleScope scope(isolate);
    754   ASSERT(args.length() == 2);
    755   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
    756   Handle<Object> key(args[1]);
    757   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
    758   return isolate->heap()->ToBoolean(table->Contains(*key));
    759 }
    760 
    761 
    762 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
    763   HandleScope scope(isolate);
    764   ASSERT(args.length() == 2);
    765   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
    766   Handle<Object> key(args[1]);
    767   Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
    768   table = ObjectHashSetRemove(table, key);
    769   holder->set_table(*table);
    770   return isolate->heap()->undefined_symbol();
    771 }
    772 
    773 
    774 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
    775   HandleScope scope(isolate);
    776   ASSERT(args.length() == 1);
    777   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
    778   Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
    779   holder->set_table(*table);
    780   return *holder;
    781 }
    782 
    783 
    784 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
    785   HandleScope scope(isolate);
    786   ASSERT(args.length() == 2);
    787   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
    788   Handle<Object> key(args[1]);
    789   return ObjectHashTable::cast(holder->table())->Lookup(*key);
    790 }
    791 
    792 
    793 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
    794   HandleScope scope(isolate);
    795   ASSERT(args.length() == 3);
    796   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
    797   Handle<Object> key(args[1]);
    798   Handle<Object> value(args[2]);
    799   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
    800   Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
    801   holder->set_table(*new_table);
    802   return *value;
    803 }
    804 
    805 
    806 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
    807   HandleScope scope(isolate);
    808   ASSERT(args.length() == 1);
    809   CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
    810   ASSERT(weakmap->map()->inobject_properties() == 0);
    811   Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
    812   weakmap->set_table(*table);
    813   weakmap->set_next(Smi::FromInt(0));
    814   return *weakmap;
    815 }
    816 
    817 
    818 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
    819   NoHandleAllocation ha;
    820   ASSERT(args.length() == 2);
    821   CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
    822   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
    823   return ObjectHashTable::cast(weakmap->table())->Lookup(*key);
    824 }
    825 
    826 
    827 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
    828   HandleScope scope(isolate);
    829   ASSERT(args.length() == 3);
    830   CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
    831   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
    832   Handle<Object> value(args[2]);
    833   Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
    834   Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
    835   weakmap->set_table(*new_table);
    836   return *value;
    837 }
    838 
    839 
    840 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
    841   NoHandleAllocation ha;
    842   ASSERT(args.length() == 1);
    843   Object* obj = args[0];
    844   if (!obj->IsJSObject()) return isolate->heap()->null_value();
    845   return JSObject::cast(obj)->class_name();
    846 }
    847 
    848 
    849 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
    850   NoHandleAllocation ha;
    851   ASSERT(args.length() == 1);
    852   CONVERT_ARG_CHECKED(JSReceiver, input_obj, 0);
    853   Object* obj = input_obj;
    854   // We don't expect access checks to be needed on JSProxy objects.
    855   ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
    856   do {
    857     if (obj->IsAccessCheckNeeded() &&
    858         !isolate->MayNamedAccess(JSObject::cast(obj),
    859                                  isolate->heap()->Proto_symbol(),
    860                                  v8::ACCESS_GET)) {
    861       isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
    862       return isolate->heap()->undefined_value();
    863     }
    864     obj = obj->GetPrototype();
    865   } while (obj->IsJSObject() &&
    866            JSObject::cast(obj)->map()->is_hidden_prototype());
    867   return obj;
    868 }
    869 
    870 
    871 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
    872   NoHandleAllocation ha;
    873   ASSERT(args.length() == 2);
    874   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
    875   Object* O = args[0];
    876   Object* V = args[1];
    877   while (true) {
    878     Object* prototype = V->GetPrototype();
    879     if (prototype->IsNull()) return isolate->heap()->false_value();
    880     if (O == prototype) return isolate->heap()->true_value();
    881     V = prototype;
    882   }
    883 }
    884 
    885 
    886 // Recursively traverses hidden prototypes if property is not found
    887 static void GetOwnPropertyImplementation(JSObject* obj,
    888                                          String* name,
    889                                          LookupResult* result) {
    890   obj->LocalLookupRealNamedProperty(name, result);
    891 
    892   if (!result->IsProperty()) {
    893     Object* proto = obj->GetPrototype();
    894     if (proto->IsJSObject() &&
    895       JSObject::cast(proto)->map()->is_hidden_prototype())
    896       GetOwnPropertyImplementation(JSObject::cast(proto),
    897                                    name, result);
    898   }
    899 }
    900 
    901 
    902 static bool CheckAccessException(LookupResult* result,
    903                                  v8::AccessType access_type) {
    904   if (result->type() == CALLBACKS) {
    905     Object* callback = result->GetCallbackObject();
    906     if (callback->IsAccessorInfo()) {
    907       AccessorInfo* info = AccessorInfo::cast(callback);
    908       bool can_access =
    909           (access_type == v8::ACCESS_HAS &&
    910               (info->all_can_read() || info->all_can_write())) ||
    911           (access_type == v8::ACCESS_GET && info->all_can_read()) ||
    912           (access_type == v8::ACCESS_SET && info->all_can_write());
    913       return can_access;
    914     }
    915   }
    916 
    917   return false;
    918 }
    919 
    920 
    921 static bool CheckAccess(JSObject* obj,
    922                         String* name,
    923                         LookupResult* result,
    924                         v8::AccessType access_type) {
    925   ASSERT(result->IsProperty());
    926 
    927   JSObject* holder = result->holder();
    928   JSObject* current = obj;
    929   Isolate* isolate = obj->GetIsolate();
    930   while (true) {
    931     if (current->IsAccessCheckNeeded() &&
    932         !isolate->MayNamedAccess(current, name, access_type)) {
    933       // Access check callback denied the access, but some properties
    934       // can have a special permissions which override callbacks descision
    935       // (currently see v8::AccessControl).
    936       break;
    937     }
    938 
    939     if (current == holder) {
    940       return true;
    941     }
    942 
    943     current = JSObject::cast(current->GetPrototype());
    944   }
    945 
    946   // API callbacks can have per callback access exceptions.
    947   switch (result->type()) {
    948     case CALLBACKS: {
    949       if (CheckAccessException(result, access_type)) {
    950         return true;
    951       }
    952       break;
    953     }
    954     case INTERCEPTOR: {
    955       // If the object has an interceptor, try real named properties.
    956       // Overwrite the result to fetch the correct property later.
    957       holder->LookupRealNamedProperty(name, result);
    958       if (result->IsProperty()) {
    959         if (CheckAccessException(result, access_type)) {
    960           return true;
    961         }
    962       }
    963       break;
    964     }
    965     default:
    966       break;
    967   }
    968 
    969   isolate->ReportFailedAccessCheck(current, access_type);
    970   return false;
    971 }
    972 
    973 
    974 // TODO(1095): we should traverse hidden prototype hierachy as well.
    975 static bool CheckElementAccess(JSObject* obj,
    976                                uint32_t index,
    977                                v8::AccessType access_type) {
    978   if (obj->IsAccessCheckNeeded() &&
    979       !obj->GetIsolate()->MayIndexedAccess(obj, index, access_type)) {
    980     return false;
    981   }
    982 
    983   return true;
    984 }
    985 
    986 
    987 // Enumerator used as indices into the array returned from GetOwnProperty
    988 enum PropertyDescriptorIndices {
    989   IS_ACCESSOR_INDEX,
    990   VALUE_INDEX,
    991   GETTER_INDEX,
    992   SETTER_INDEX,
    993   WRITABLE_INDEX,
    994   ENUMERABLE_INDEX,
    995   CONFIGURABLE_INDEX,
    996   DESCRIPTOR_SIZE
    997 };
    998 
    999 
   1000 static MaybeObject* GetOwnProperty(Isolate* isolate,
   1001                                    Handle<JSObject> obj,
   1002                                    Handle<String> name) {
   1003   Heap* heap = isolate->heap();
   1004   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   1005   Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms);
   1006   LookupResult result(isolate);
   1007   // This could be an element.
   1008   uint32_t index;
   1009   if (name->AsArrayIndex(&index)) {
   1010     switch (obj->HasLocalElement(index)) {
   1011       case JSObject::UNDEFINED_ELEMENT:
   1012         return heap->undefined_value();
   1013 
   1014       case JSObject::STRING_CHARACTER_ELEMENT: {
   1015         // Special handling of string objects according to ECMAScript 5
   1016         // 15.5.5.2. Note that this might be a string object with elements
   1017         // other than the actual string value. This is covered by the
   1018         // subsequent cases.
   1019         Handle<JSValue> js_value = Handle<JSValue>::cast(obj);
   1020         Handle<String> str(String::cast(js_value->value()));
   1021         Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED);
   1022 
   1023         elms->set(IS_ACCESSOR_INDEX, heap->false_value());
   1024         elms->set(VALUE_INDEX, *substr);
   1025         elms->set(WRITABLE_INDEX, heap->false_value());
   1026         elms->set(ENUMERABLE_INDEX,  heap->true_value());
   1027         elms->set(CONFIGURABLE_INDEX, heap->false_value());
   1028         return *desc;
   1029       }
   1030 
   1031       case JSObject::INTERCEPTED_ELEMENT:
   1032       case JSObject::FAST_ELEMENT: {
   1033         elms->set(IS_ACCESSOR_INDEX, heap->false_value());
   1034         Handle<Object> value = Object::GetElement(obj, index);
   1035         RETURN_IF_EMPTY_HANDLE(isolate, value);
   1036         elms->set(VALUE_INDEX, *value);
   1037         elms->set(WRITABLE_INDEX, heap->true_value());
   1038         elms->set(ENUMERABLE_INDEX,  heap->true_value());
   1039         elms->set(CONFIGURABLE_INDEX, heap->true_value());
   1040         return *desc;
   1041       }
   1042 
   1043       case JSObject::DICTIONARY_ELEMENT: {
   1044         Handle<JSObject> holder = obj;
   1045         if (obj->IsJSGlobalProxy()) {
   1046           Object* proto = obj->GetPrototype();
   1047           if (proto->IsNull()) return heap->undefined_value();
   1048           ASSERT(proto->IsJSGlobalObject());
   1049           holder = Handle<JSObject>(JSObject::cast(proto));
   1050         }
   1051         FixedArray* elements = FixedArray::cast(holder->elements());
   1052         SeededNumberDictionary* dictionary = NULL;
   1053         if (elements->map() == heap->non_strict_arguments_elements_map()) {
   1054           dictionary = SeededNumberDictionary::cast(elements->get(1));
   1055         } else {
   1056           dictionary = SeededNumberDictionary::cast(elements);
   1057         }
   1058         int entry = dictionary->FindEntry(index);
   1059         ASSERT(entry != SeededNumberDictionary::kNotFound);
   1060         PropertyDetails details = dictionary->DetailsAt(entry);
   1061         switch (details.type()) {
   1062           case CALLBACKS: {
   1063             // This is an accessor property with getter and/or setter.
   1064             AccessorPair* accessors =
   1065                 AccessorPair::cast(dictionary->ValueAt(entry));
   1066             elms->set(IS_ACCESSOR_INDEX, heap->true_value());
   1067             if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
   1068               elms->set(GETTER_INDEX, accessors->GetComponent(ACCESSOR_GETTER));
   1069             }
   1070             if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
   1071               elms->set(SETTER_INDEX, accessors->GetComponent(ACCESSOR_SETTER));
   1072             }
   1073             break;
   1074           }
   1075           case NORMAL: {
   1076             // This is a data property.
   1077             elms->set(IS_ACCESSOR_INDEX, heap->false_value());
   1078             Handle<Object> value = Object::GetElement(obj, index);
   1079             ASSERT(!value.is_null());
   1080             elms->set(VALUE_INDEX, *value);
   1081             elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly()));
   1082             break;
   1083           }
   1084           default:
   1085             UNREACHABLE();
   1086             break;
   1087         }
   1088         elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum()));
   1089         elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete()));
   1090         return *desc;
   1091       }
   1092     }
   1093   }
   1094 
   1095   // Use recursive implementation to also traverse hidden prototypes
   1096   GetOwnPropertyImplementation(*obj, *name, &result);
   1097 
   1098   if (!result.IsProperty()) {
   1099     return heap->undefined_value();
   1100   }
   1101 
   1102   if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
   1103     return heap->false_value();
   1104   }
   1105 
   1106   elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum()));
   1107   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete()));
   1108 
   1109   bool is_js_accessor = (result.type() == CALLBACKS) &&
   1110                         (result.GetCallbackObject()->IsAccessorPair());
   1111 
   1112   if (is_js_accessor) {
   1113     // __defineGetter__/__defineSetter__ callback.
   1114     elms->set(IS_ACCESSOR_INDEX, heap->true_value());
   1115 
   1116     AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject());
   1117     if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
   1118       elms->set(GETTER_INDEX, accessors->GetComponent(ACCESSOR_GETTER));
   1119     }
   1120     if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
   1121       elms->set(SETTER_INDEX, accessors->GetComponent(ACCESSOR_SETTER));
   1122     }
   1123   } else {
   1124     elms->set(IS_ACCESSOR_INDEX, heap->false_value());
   1125     elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly()));
   1126 
   1127     PropertyAttributes attrs;
   1128     Object* value;
   1129     // GetProperty will check access and report any violations.
   1130     { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
   1131       if (!maybe_value->ToObject(&value)) return maybe_value;
   1132     }
   1133     elms->set(VALUE_INDEX, value);
   1134   }
   1135 
   1136   return *desc;
   1137 }
   1138 
   1139 
   1140 // Returns an array with the property description:
   1141 //  if args[1] is not a property on args[0]
   1142 //          returns undefined
   1143 //  if args[1] is a data property on args[0]
   1144 //         [false, value, Writeable, Enumerable, Configurable]
   1145 //  if args[1] is an accessor on args[0]
   1146 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
   1147 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
   1148   ASSERT(args.length() == 2);
   1149   HandleScope scope(isolate);
   1150   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1151   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   1152   return GetOwnProperty(isolate, obj, name);
   1153 }
   1154 
   1155 
   1156 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
   1157   ASSERT(args.length() == 1);
   1158   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   1159   return obj->PreventExtensions();
   1160 }
   1161 
   1162 
   1163 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
   1164   ASSERT(args.length() == 1);
   1165   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   1166   if (obj->IsJSGlobalProxy()) {
   1167     Object* proto = obj->GetPrototype();
   1168     if (proto->IsNull()) return isolate->heap()->false_value();
   1169     ASSERT(proto->IsJSGlobalObject());
   1170     obj = JSObject::cast(proto);
   1171   }
   1172   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
   1173 }
   1174 
   1175 
   1176 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
   1177   HandleScope scope(isolate);
   1178   ASSERT(args.length() == 3);
   1179   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
   1180   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   1181   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
   1182   Handle<Object> result = RegExpImpl::Compile(re, pattern, flags);
   1183   if (result.is_null()) return Failure::Exception();
   1184   return *result;
   1185 }
   1186 
   1187 
   1188 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) {
   1189   HandleScope scope(isolate);
   1190   ASSERT(args.length() == 1);
   1191   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
   1192   return *isolate->factory()->CreateApiFunction(data);
   1193 }
   1194 
   1195 
   1196 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsTemplate) {
   1197   ASSERT(args.length() == 1);
   1198   Object* arg = args[0];
   1199   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
   1200   return isolate->heap()->ToBoolean(result);
   1201 }
   1202 
   1203 
   1204 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
   1205   ASSERT(args.length() == 2);
   1206   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
   1207   CONVERT_SMI_ARG_CHECKED(index, 1)
   1208   int offset = index * kPointerSize + HeapObject::kHeaderSize;
   1209   InstanceType type = templ->map()->instance_type();
   1210   RUNTIME_ASSERT(type ==  FUNCTION_TEMPLATE_INFO_TYPE ||
   1211                  type ==  OBJECT_TEMPLATE_INFO_TYPE);
   1212   RUNTIME_ASSERT(offset > 0);
   1213   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
   1214     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
   1215   } else {
   1216     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
   1217   }
   1218   return *HeapObject::RawField(templ, offset);
   1219 }
   1220 
   1221 
   1222 RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
   1223   ASSERT(args.length() == 1);
   1224   CONVERT_ARG_CHECKED(HeapObject, object, 0);
   1225   Map* old_map = object->map();
   1226   bool needs_access_checks = old_map->is_access_check_needed();
   1227   if (needs_access_checks) {
   1228     // Copy map so it won't interfere constructor's initial map.
   1229     Object* new_map;
   1230     { MaybeObject* maybe_new_map = old_map->CopyDropTransitions();
   1231       if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
   1232     }
   1233 
   1234     Map::cast(new_map)->set_is_access_check_needed(false);
   1235     object->set_map(Map::cast(new_map));
   1236   }
   1237   return isolate->heap()->ToBoolean(needs_access_checks);
   1238 }
   1239 
   1240 
   1241 RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
   1242   ASSERT(args.length() == 1);
   1243   CONVERT_ARG_CHECKED(HeapObject, object, 0);
   1244   Map* old_map = object->map();
   1245   if (!old_map->is_access_check_needed()) {
   1246     // Copy map so it won't interfere constructor's initial map.
   1247     Object* new_map;
   1248     { MaybeObject* maybe_new_map = old_map->CopyDropTransitions();
   1249       if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
   1250     }
   1251 
   1252     Map::cast(new_map)->set_is_access_check_needed(true);
   1253     object->set_map(Map::cast(new_map));
   1254   }
   1255   return isolate->heap()->undefined_value();
   1256 }
   1257 
   1258 
   1259 static Failure* ThrowRedeclarationError(Isolate* isolate,
   1260                                         const char* type,
   1261                                         Handle<String> name) {
   1262   HandleScope scope(isolate);
   1263   Handle<Object> type_handle =
   1264       isolate->factory()->NewStringFromAscii(CStrVector(type));
   1265   Handle<Object> args[2] = { type_handle, name };
   1266   Handle<Object> error =
   1267       isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2));
   1268   return isolate->Throw(*error);
   1269 }
   1270 
   1271 
   1272 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
   1273   ASSERT(args.length() == 3);
   1274   HandleScope scope(isolate);
   1275   Handle<GlobalObject> global = Handle<GlobalObject>(
   1276       isolate->context()->global());
   1277 
   1278   Handle<Context> context = args.at<Context>(0);
   1279   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
   1280   CONVERT_SMI_ARG_CHECKED(flags, 2);
   1281 
   1282   // Traverse the name/value pairs and set the properties.
   1283   int length = pairs->length();
   1284   for (int i = 0; i < length; i += 2) {
   1285     HandleScope scope(isolate);
   1286     Handle<String> name(String::cast(pairs->get(i)));
   1287     Handle<Object> value(pairs->get(i + 1), isolate);
   1288 
   1289     // We have to declare a global const property. To capture we only
   1290     // assign to it when evaluating the assignment for "const x =
   1291     // <expr>" the initial value is the hole.
   1292     bool is_const_property = value->IsTheHole();
   1293     bool is_function_declaration = false;
   1294     if (value->IsUndefined() || is_const_property) {
   1295       // Lookup the property in the global object, and don't set the
   1296       // value of the variable if the property is already there.
   1297       LookupResult lookup(isolate);
   1298       global->Lookup(*name, &lookup);
   1299       if (lookup.IsProperty()) {
   1300         // We found an existing property. Unless it was an interceptor
   1301         // that claims the property is absent, skip this declaration.
   1302         if (lookup.type() != INTERCEPTOR) {
   1303           continue;
   1304         }
   1305         PropertyAttributes attributes = global->GetPropertyAttribute(*name);
   1306         if (attributes != ABSENT) {
   1307           continue;
   1308         }
   1309         // Fall-through and introduce the absent property by using
   1310         // SetProperty.
   1311       }
   1312     } else {
   1313       is_function_declaration = true;
   1314       // Copy the function and update its context. Use it as value.
   1315       Handle<SharedFunctionInfo> shared =
   1316           Handle<SharedFunctionInfo>::cast(value);
   1317       Handle<JSFunction> function =
   1318           isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   1319                                                                 context,
   1320                                                                 TENURED);
   1321       value = function;
   1322     }
   1323 
   1324     LookupResult lookup(isolate);
   1325     global->LocalLookup(*name, &lookup);
   1326 
   1327     // Compute the property attributes. According to ECMA-262, section
   1328     // 13, page 71, the property must be read-only and
   1329     // non-deletable. However, neither SpiderMonkey nor KJS creates the
   1330     // property as read-only, so we don't either.
   1331     int attr = NONE;
   1332     if (!DeclareGlobalsEvalFlag::decode(flags)) {
   1333       attr |= DONT_DELETE;
   1334     }
   1335     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
   1336     if (is_const_property || (is_native && is_function_declaration)) {
   1337       attr |= READ_ONLY;
   1338     }
   1339 
   1340     LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
   1341 
   1342     // Safari does not allow the invocation of callback setters for
   1343     // function declarations. To mimic this behavior, we do not allow
   1344     // the invocation of setters for function values. This makes a
   1345     // difference for global functions with the same names as event
   1346     // handlers such as "function onload() {}". Firefox does call the
   1347     // onload setter in those case and Safari does not. We follow
   1348     // Safari for compatibility.
   1349     if (is_function_declaration) {
   1350       if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) {
   1351         // Do not overwrite READ_ONLY properties.
   1352         if (lookup.GetAttributes() & READ_ONLY) {
   1353           if (language_mode != CLASSIC_MODE) {
   1354             Handle<Object> args[] = { name };
   1355             return isolate->Throw(*isolate->factory()->NewTypeError(
   1356                 "strict_cannot_assign", HandleVector(args, ARRAY_SIZE(args))));
   1357           }
   1358           continue;
   1359         }
   1360         // Do not change DONT_DELETE to false from true.
   1361         attr |= lookup.GetAttributes() & DONT_DELETE;
   1362       }
   1363       PropertyAttributes attributes = static_cast<PropertyAttributes>(attr);
   1364 
   1365       RETURN_IF_EMPTY_HANDLE(
   1366           isolate,
   1367           JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
   1368                                                      attributes));
   1369     } else {
   1370       RETURN_IF_EMPTY_HANDLE(
   1371           isolate,
   1372           JSReceiver::SetProperty(global, name, value,
   1373                                   static_cast<PropertyAttributes>(attr),
   1374                                   language_mode == CLASSIC_MODE
   1375                                       ? kNonStrictMode : kStrictMode));
   1376     }
   1377   }
   1378 
   1379   ASSERT(!isolate->has_pending_exception());
   1380   return isolate->heap()->undefined_value();
   1381 }
   1382 
   1383 
   1384 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
   1385   HandleScope scope(isolate);
   1386   ASSERT(args.length() == 4);
   1387 
   1388   // Declarations are always made in a function or global context.  In the
   1389   // case of eval code, the context passed is the context of the caller,
   1390   // which may be some nested context and not the declaration context.
   1391   RUNTIME_ASSERT(args[0]->IsContext());
   1392   Handle<Context> context(Context::cast(args[0])->declaration_context());
   1393 
   1394   Handle<String> name(String::cast(args[1]));
   1395   PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
   1396   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
   1397   Handle<Object> initial_value(args[3], isolate);
   1398 
   1399   int index;
   1400   PropertyAttributes attributes;
   1401   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   1402   BindingFlags binding_flags;
   1403   Handle<Object> holder =
   1404       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   1405 
   1406   if (attributes != ABSENT) {
   1407     // The name was declared before; check for conflicting re-declarations.
   1408     if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
   1409       // Functions are not read-only.
   1410       ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
   1411       const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
   1412       return ThrowRedeclarationError(isolate, type, name);
   1413     }
   1414 
   1415     // Initialize it if necessary.
   1416     if (*initial_value != NULL) {
   1417       if (index >= 0) {
   1418         ASSERT(holder.is_identical_to(context));
   1419         if (((attributes & READ_ONLY) == 0) ||
   1420             context->get(index)->IsTheHole()) {
   1421           context->set(index, *initial_value);
   1422         }
   1423       } else {
   1424         // Slow case: The property is in the context extension object of a
   1425         // function context or the global object of a global context.
   1426         Handle<JSObject> object = Handle<JSObject>::cast(holder);
   1427         RETURN_IF_EMPTY_HANDLE(
   1428             isolate,
   1429             JSReceiver::SetProperty(object, name, initial_value, mode,
   1430                                     kNonStrictMode));
   1431       }
   1432     }
   1433 
   1434   } else {
   1435     // The property is not in the function context. It needs to be
   1436     // "declared" in the function context's extension context or as a
   1437     // property of the the global object.
   1438     Handle<JSObject> object;
   1439     if (context->has_extension()) {
   1440       object = Handle<JSObject>(JSObject::cast(context->extension()));
   1441     } else {
   1442       // Context extension objects are allocated lazily.
   1443       ASSERT(context->IsFunctionContext());
   1444       object = isolate->factory()->NewJSObject(
   1445           isolate->context_extension_function());
   1446       context->set_extension(*object);
   1447     }
   1448     ASSERT(*object != NULL);
   1449 
   1450     // Declare the property by setting it to the initial value if provided,
   1451     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
   1452     // constant declarations).
   1453     ASSERT(!object->HasLocalProperty(*name));
   1454     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
   1455     if (*initial_value != NULL) value = initial_value;
   1456     // Declaring a const context slot is a conflicting declaration if
   1457     // there is a callback with that name in a prototype. It is
   1458     // allowed to introduce const variables in
   1459     // JSContextExtensionObjects. They are treated specially in
   1460     // SetProperty and no setters are invoked for those since they are
   1461     // not real JSObjects.
   1462     if (initial_value->IsTheHole() &&
   1463         !object->IsJSContextExtensionObject()) {
   1464       LookupResult lookup(isolate);
   1465       object->Lookup(*name, &lookup);
   1466       if (lookup.IsFound() && (lookup.type() == CALLBACKS)) {
   1467         return ThrowRedeclarationError(isolate, "const", name);
   1468       }
   1469     }
   1470     RETURN_IF_EMPTY_HANDLE(
   1471         isolate,
   1472         JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
   1473   }
   1474 
   1475   return isolate->heap()->undefined_value();
   1476 }
   1477 
   1478 
   1479 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
   1480   NoHandleAllocation nha;
   1481   // args[0] == name
   1482   // args[1] == language_mode
   1483   // args[2] == value (optional)
   1484 
   1485   // Determine if we need to assign to the variable if it already
   1486   // exists (based on the number of arguments).
   1487   RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
   1488   bool assign = args.length() == 3;
   1489 
   1490   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   1491   GlobalObject* global = isolate->context()->global();
   1492   RUNTIME_ASSERT(args[1]->IsSmi());
   1493   CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
   1494   StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
   1495       ? kNonStrictMode : kStrictMode;
   1496 
   1497   // According to ECMA-262, section 12.2, page 62, the property must
   1498   // not be deletable.
   1499   PropertyAttributes attributes = DONT_DELETE;
   1500 
   1501   // Lookup the property locally in the global object. If it isn't
   1502   // there, there is a property with this name in the prototype chain.
   1503   // We follow Safari and Firefox behavior and only set the property
   1504   // locally if there is an explicit initialization value that we have
   1505   // to assign to the property.
   1506   // Note that objects can have hidden prototypes, so we need to traverse
   1507   // the whole chain of hidden prototypes to do a 'local' lookup.
   1508   Object* object = global;
   1509   LookupResult lookup(isolate);
   1510   while (object->IsJSObject() &&
   1511          JSObject::cast(object)->map()->is_hidden_prototype()) {
   1512     JSObject* raw_holder = JSObject::cast(object);
   1513     raw_holder->LocalLookup(*name, &lookup);
   1514     if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
   1515       HandleScope handle_scope(isolate);
   1516       Handle<JSObject> holder(raw_holder);
   1517       PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
   1518       // Update the raw pointer in case it's changed due to GC.
   1519       raw_holder = *holder;
   1520       if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
   1521         // Found an interceptor that's not read only.
   1522         if (assign) {
   1523           return raw_holder->SetProperty(
   1524               &lookup, *name, args[2], attributes, strict_mode_flag);
   1525         } else {
   1526           return isolate->heap()->undefined_value();
   1527         }
   1528       }
   1529     }
   1530     object = raw_holder->GetPrototype();
   1531   }
   1532 
   1533   // Reload global in case the loop above performed a GC.
   1534   global = isolate->context()->global();
   1535   if (assign) {
   1536     return global->SetProperty(*name, args[2], attributes, strict_mode_flag);
   1537   }
   1538   return isolate->heap()->undefined_value();
   1539 }
   1540 
   1541 
   1542 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
   1543   // All constants are declared with an initial value. The name
   1544   // of the constant is the first argument and the initial value
   1545   // is the second.
   1546   RUNTIME_ASSERT(args.length() == 2);
   1547   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   1548   Handle<Object> value = args.at<Object>(1);
   1549 
   1550   // Get the current global object from top.
   1551   GlobalObject* global = isolate->context()->global();
   1552 
   1553   // According to ECMA-262, section 12.2, page 62, the property must
   1554   // not be deletable. Since it's a const, it must be READ_ONLY too.
   1555   PropertyAttributes attributes =
   1556       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
   1557 
   1558   // Lookup the property locally in the global object. If it isn't
   1559   // there, we add the property and take special precautions to always
   1560   // add it as a local property even in case of callbacks in the
   1561   // prototype chain (this rules out using SetProperty).
   1562   // We use SetLocalPropertyIgnoreAttributes instead
   1563   LookupResult lookup(isolate);
   1564   global->LocalLookup(*name, &lookup);
   1565   if (!lookup.IsProperty()) {
   1566     return global->SetLocalPropertyIgnoreAttributes(*name,
   1567                                                     *value,
   1568                                                     attributes);
   1569   }
   1570 
   1571   if (!lookup.IsReadOnly()) {
   1572     // Restore global object from context (in case of GC) and continue
   1573     // with setting the value.
   1574     HandleScope handle_scope(isolate);
   1575     Handle<GlobalObject> global(isolate->context()->global());
   1576 
   1577     // BUG 1213575: Handle the case where we have to set a read-only
   1578     // property through an interceptor and only do it if it's
   1579     // uninitialized, e.g. the hole. Nirk...
   1580     // Passing non-strict mode because the property is writable.
   1581     RETURN_IF_EMPTY_HANDLE(
   1582         isolate,
   1583         JSReceiver::SetProperty(global, name, value, attributes,
   1584                                 kNonStrictMode));
   1585     return *value;
   1586   }
   1587 
   1588   // Set the value, but only if we're assigning the initial value to a
   1589   // constant. For now, we determine this by checking if the
   1590   // current value is the hole.
   1591   // Strict mode handling not needed (const is disallowed in strict mode).
   1592   PropertyType type = lookup.type();
   1593   if (type == FIELD) {
   1594     FixedArray* properties = global->properties();
   1595     int index = lookup.GetFieldIndex();
   1596     if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
   1597       properties->set(index, *value);
   1598     }
   1599   } else if (type == NORMAL) {
   1600     if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
   1601         !lookup.IsReadOnly()) {
   1602       global->SetNormalizedProperty(&lookup, *value);
   1603     }
   1604   } else {
   1605     // Ignore re-initialization of constants that have already been
   1606     // assigned a function value.
   1607     ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION);
   1608   }
   1609 
   1610   // Use the set value as the result of the operation.
   1611   return *value;
   1612 }
   1613 
   1614 
   1615 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
   1616   HandleScope scope(isolate);
   1617   ASSERT(args.length() == 3);
   1618 
   1619   Handle<Object> value(args[0], isolate);
   1620   ASSERT(!value->IsTheHole());
   1621 
   1622   // Initializations are always done in a function or global context.
   1623   RUNTIME_ASSERT(args[1]->IsContext());
   1624   Handle<Context> context(Context::cast(args[1])->declaration_context());
   1625 
   1626   Handle<String> name(String::cast(args[2]));
   1627 
   1628   int index;
   1629   PropertyAttributes attributes;
   1630   ContextLookupFlags flags = FOLLOW_CHAINS;
   1631   BindingFlags binding_flags;
   1632   Handle<Object> holder =
   1633       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   1634 
   1635   if (index >= 0) {
   1636     ASSERT(holder->IsContext());
   1637     // Property was found in a context.  Perform the assignment if we
   1638     // found some non-constant or an uninitialized constant.
   1639     Handle<Context> context = Handle<Context>::cast(holder);
   1640     if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
   1641       context->set(index, *value);
   1642     }
   1643     return *value;
   1644   }
   1645 
   1646   // The property could not be found, we introduce it as a property of the
   1647   // global object.
   1648   if (attributes == ABSENT) {
   1649     Handle<JSObject> global = Handle<JSObject>(
   1650         isolate->context()->global());
   1651     // Strict mode not needed (const disallowed in strict mode).
   1652     RETURN_IF_EMPTY_HANDLE(
   1653         isolate,
   1654         JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode));
   1655     return *value;
   1656   }
   1657 
   1658   // The property was present in some function's context extension object,
   1659   // as a property on the subject of a with, or as a property of the global
   1660   // object.
   1661   //
   1662   // In most situations, eval-introduced consts should still be present in
   1663   // the context extension object.  However, because declaration and
   1664   // initialization are separate, the property might have been deleted
   1665   // before we reach the initialization point.
   1666   //
   1667   // Example:
   1668   //
   1669   //    function f() { eval("delete x; const x;"); }
   1670   //
   1671   // In that case, the initialization behaves like a normal assignment.
   1672   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   1673 
   1674   if (*object == context->extension()) {
   1675     // This is the property that was introduced by the const declaration.
   1676     // Set it if it hasn't been set before.  NOTE: We cannot use
   1677     // GetProperty() to get the current value as it 'unholes' the value.
   1678     LookupResult lookup(isolate);
   1679     object->LocalLookupRealNamedProperty(*name, &lookup);
   1680     ASSERT(lookup.IsFound());  // the property was declared
   1681     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
   1682 
   1683     PropertyType type = lookup.type();
   1684     if (type == FIELD) {
   1685       FixedArray* properties = object->properties();
   1686       int index = lookup.GetFieldIndex();
   1687       if (properties->get(index)->IsTheHole()) {
   1688         properties->set(index, *value);
   1689       }
   1690     } else if (type == NORMAL) {
   1691       if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
   1692         object->SetNormalizedProperty(&lookup, *value);
   1693       }
   1694     } else {
   1695       // We should not reach here. Any real, named property should be
   1696       // either a field or a dictionary slot.
   1697       UNREACHABLE();
   1698     }
   1699   } else {
   1700     // The property was found on some other object.  Set it if it is not a
   1701     // read-only property.
   1702     if ((attributes & READ_ONLY) == 0) {
   1703       // Strict mode not needed (const disallowed in strict mode).
   1704       RETURN_IF_EMPTY_HANDLE(
   1705           isolate,
   1706           JSReceiver::SetProperty(object, name, value, attributes,
   1707                                   kNonStrictMode));
   1708     }
   1709   }
   1710 
   1711   return *value;
   1712 }
   1713 
   1714 
   1715 RUNTIME_FUNCTION(MaybeObject*,
   1716                  Runtime_OptimizeObjectForAddingMultipleProperties) {
   1717   HandleScope scope(isolate);
   1718   ASSERT(args.length() == 2);
   1719   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   1720   CONVERT_SMI_ARG_CHECKED(properties, 1);
   1721   if (object->HasFastProperties()) {
   1722     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
   1723   }
   1724   return *object;
   1725 }
   1726 
   1727 
   1728 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
   1729   HandleScope scope(isolate);
   1730   ASSERT(args.length() == 4);
   1731   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   1732   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   1733   // Due to the way the JS calls are constructed this must be less than the
   1734   // length of a string, i.e. it is always a Smi.  We check anyway for security.
   1735   CONVERT_SMI_ARG_CHECKED(index, 2);
   1736   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
   1737   RUNTIME_ASSERT(last_match_info->HasFastElements());
   1738   RUNTIME_ASSERT(index >= 0);
   1739   RUNTIME_ASSERT(index <= subject->length());
   1740   isolate->counters()->regexp_entry_runtime()->Increment();
   1741   Handle<Object> result = RegExpImpl::Exec(regexp,
   1742                                            subject,
   1743                                            index,
   1744                                            last_match_info);
   1745   if (result.is_null()) return Failure::Exception();
   1746   return *result;
   1747 }
   1748 
   1749 
   1750 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
   1751   ASSERT(args.length() == 3);
   1752   CONVERT_SMI_ARG_CHECKED(elements_count, 0);
   1753   if (elements_count < 0 ||
   1754       elements_count > FixedArray::kMaxLength ||
   1755       !Smi::IsValid(elements_count)) {
   1756     return isolate->ThrowIllegalOperation();
   1757   }
   1758   Object* new_object;
   1759   { MaybeObject* maybe_new_object =
   1760         isolate->heap()->AllocateFixedArrayWithHoles(elements_count);
   1761     if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
   1762   }
   1763   FixedArray* elements = FixedArray::cast(new_object);
   1764   { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw(
   1765       JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
   1766     if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
   1767   }
   1768   {
   1769     AssertNoAllocation no_gc;
   1770     HandleScope scope(isolate);
   1771     reinterpret_cast<HeapObject*>(new_object)->
   1772         set_map(isolate->global_context()->regexp_result_map());
   1773   }
   1774   JSArray* array = JSArray::cast(new_object);
   1775   array->set_properties(isolate->heap()->empty_fixed_array());
   1776   array->set_elements(elements);
   1777   array->set_length(Smi::FromInt(elements_count));
   1778   // Write in-object properties after the length of the array.
   1779   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
   1780   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
   1781   return array;
   1782 }
   1783 
   1784 
   1785 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
   1786   AssertNoAllocation no_alloc;
   1787   ASSERT(args.length() == 5);
   1788   CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
   1789   CONVERT_ARG_CHECKED(String, source, 1);
   1790 
   1791   Object* global = args[2];
   1792   if (!global->IsTrue()) global = isolate->heap()->false_value();
   1793 
   1794   Object* ignoreCase = args[3];
   1795   if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value();
   1796 
   1797   Object* multiline = args[4];
   1798   if (!multiline->IsTrue()) multiline = isolate->heap()->false_value();
   1799 
   1800   Map* map = regexp->map();
   1801   Object* constructor = map->constructor();
   1802   if (constructor->IsJSFunction() &&
   1803       JSFunction::cast(constructor)->initial_map() == map) {
   1804     // If we still have the original map, set in-object properties directly.
   1805     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
   1806     // Both true and false are immovable immortal objects so no need for write
   1807     // barrier.
   1808     regexp->InObjectPropertyAtPut(
   1809         JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER);
   1810     regexp->InObjectPropertyAtPut(
   1811         JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
   1812     regexp->InObjectPropertyAtPut(
   1813         JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
   1814     regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
   1815                                   Smi::FromInt(0),
   1816                                   SKIP_WRITE_BARRIER);  // It's a Smi.
   1817     return regexp;
   1818   }
   1819 
   1820   // Map has changed, so use generic, but slower, method.
   1821   PropertyAttributes final =
   1822       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
   1823   PropertyAttributes writable =
   1824       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
   1825   Heap* heap = isolate->heap();
   1826   MaybeObject* result;
   1827   result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_symbol(),
   1828                                                     source,
   1829                                                     final);
   1830   ASSERT(!result->IsFailure());
   1831   result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_symbol(),
   1832                                                     global,
   1833                                                     final);
   1834   ASSERT(!result->IsFailure());
   1835   result =
   1836       regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_symbol(),
   1837                                                ignoreCase,
   1838                                                final);
   1839   ASSERT(!result->IsFailure());
   1840   result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_symbol(),
   1841                                                     multiline,
   1842                                                     final);
   1843   ASSERT(!result->IsFailure());
   1844   result =
   1845       regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_symbol(),
   1846                                                Smi::FromInt(0),
   1847                                                writable);
   1848   ASSERT(!result->IsFailure());
   1849   USE(result);
   1850   return regexp;
   1851 }
   1852 
   1853 
   1854 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
   1855   HandleScope scope(isolate);
   1856   ASSERT(args.length() == 1);
   1857   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
   1858   // This is necessary to enable fast checks for absence of elements
   1859   // on Array.prototype and below.
   1860   prototype->set_elements(isolate->heap()->empty_fixed_array());
   1861   return Smi::FromInt(0);
   1862 }
   1863 
   1864 
   1865 static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
   1866                                          Handle<JSObject> holder,
   1867                                          const char* name,
   1868                                          Builtins::Name builtin_name) {
   1869   Handle<String> key = isolate->factory()->LookupAsciiSymbol(name);
   1870   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
   1871   Handle<JSFunction> optimized =
   1872       isolate->factory()->NewFunction(key,
   1873                                       JS_OBJECT_TYPE,
   1874                                       JSObject::kHeaderSize,
   1875                                       code,
   1876                                       false);
   1877   optimized->shared()->DontAdaptArguments();
   1878   JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode);
   1879   return optimized;
   1880 }
   1881 
   1882 
   1883 RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
   1884   HandleScope scope(isolate);
   1885   ASSERT(args.length() == 1);
   1886   CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
   1887 
   1888   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
   1889   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
   1890   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
   1891   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
   1892   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
   1893   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
   1894   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
   1895 
   1896   return *holder;
   1897 }
   1898 
   1899 
   1900 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
   1901   ASSERT(args.length() == 1);
   1902   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
   1903 
   1904   if (!callable->IsJSFunction()) {
   1905     HandleScope scope(isolate);
   1906     bool threw = false;
   1907     Handle<Object> delegate =
   1908         Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
   1909     if (threw) return Failure::Exception();
   1910     callable = JSFunction::cast(*delegate);
   1911   }
   1912   JSFunction* function = JSFunction::cast(callable);
   1913 
   1914   SharedFunctionInfo* shared = function->shared();
   1915   if (shared->native() || !shared->is_classic_mode()) {
   1916     return isolate->heap()->undefined_value();
   1917   }
   1918   // Returns undefined for strict or native functions, or
   1919   // the associated global receiver for "normal" functions.
   1920 
   1921   Context* global_context =
   1922       function->context()->global()->global_context();
   1923   return global_context->global()->global_receiver();
   1924 }
   1925 
   1926 
   1927 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
   1928   HandleScope scope(isolate);
   1929   ASSERT(args.length() == 4);
   1930   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
   1931   int index = args.smi_at(1);
   1932   Handle<String> pattern = args.at<String>(2);
   1933   Handle<String> flags = args.at<String>(3);
   1934 
   1935   // Get the RegExp function from the context in the literals array.
   1936   // This is the RegExp function from the context in which the
   1937   // function was created.  We do not use the RegExp function from the
   1938   // current global context because this might be the RegExp function
   1939   // from another context which we should not have access to.
   1940   Handle<JSFunction> constructor =
   1941       Handle<JSFunction>(
   1942           JSFunction::GlobalContextFromLiterals(*literals)->regexp_function());
   1943   // Compute the regular expression literal.
   1944   bool has_pending_exception;
   1945   Handle<Object> regexp =
   1946       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags,
   1947                                       &has_pending_exception);
   1948   if (has_pending_exception) {
   1949     ASSERT(isolate->has_pending_exception());
   1950     return Failure::Exception();
   1951   }
   1952   literals->set(index, *regexp);
   1953   return *regexp;
   1954 }
   1955 
   1956 
   1957 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetName) {
   1958   NoHandleAllocation ha;
   1959   ASSERT(args.length() == 1);
   1960 
   1961   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   1962   return f->shared()->name();
   1963 }
   1964 
   1965 
   1966 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
   1967   NoHandleAllocation ha;
   1968   ASSERT(args.length() == 2);
   1969 
   1970   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   1971   CONVERT_ARG_CHECKED(String, name, 1);
   1972   f->shared()->set_name(name);
   1973   return isolate->heap()->undefined_value();
   1974 }
   1975 
   1976 
   1977 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
   1978   NoHandleAllocation ha;
   1979   ASSERT(args.length() == 1);
   1980   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   1981   return isolate->heap()->ToBoolean(
   1982       f->shared()->name_should_print_as_anonymous());
   1983 }
   1984 
   1985 
   1986 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
   1987   NoHandleAllocation ha;
   1988   ASSERT(args.length() == 1);
   1989   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   1990   f->shared()->set_name_should_print_as_anonymous(true);
   1991   return isolate->heap()->undefined_value();
   1992 }
   1993 
   1994 
   1995 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
   1996   NoHandleAllocation ha;
   1997   ASSERT(args.length() == 1);
   1998 
   1999   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2000   Object* obj = f->RemovePrototype();
   2001   if (obj->IsFailure()) return obj;
   2002 
   2003   return isolate->heap()->undefined_value();
   2004 }
   2005 
   2006 
   2007 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScript) {
   2008   HandleScope scope(isolate);
   2009   ASSERT(args.length() == 1);
   2010 
   2011   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2012   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
   2013   if (!script->IsScript()) return isolate->heap()->undefined_value();
   2014 
   2015   return *GetScriptWrapper(Handle<Script>::cast(script));
   2016 }
   2017 
   2018 
   2019 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetSourceCode) {
   2020   HandleScope scope(isolate);
   2021   ASSERT(args.length() == 1);
   2022 
   2023   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
   2024   Handle<SharedFunctionInfo> shared(f->shared());
   2025   return *shared->GetSourceCode();
   2026 }
   2027 
   2028 
   2029 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScriptSourcePosition) {
   2030   NoHandleAllocation ha;
   2031   ASSERT(args.length() == 1);
   2032 
   2033   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2034   int pos = fun->shared()->start_position();
   2035   return Smi::FromInt(pos);
   2036 }
   2037 
   2038 
   2039 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
   2040   ASSERT(args.length() == 2);
   2041 
   2042   CONVERT_ARG_CHECKED(Code, code, 0);
   2043   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
   2044 
   2045   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
   2046 
   2047   Address pc = code->address() + offset;
   2048   return Smi::FromInt(code->SourcePosition(pc));
   2049 }
   2050 
   2051 
   2052 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetInstanceClassName) {
   2053   NoHandleAllocation ha;
   2054   ASSERT(args.length() == 2);
   2055 
   2056   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2057   CONVERT_ARG_CHECKED(String, name, 1);
   2058   fun->SetInstanceClassName(name);
   2059   return isolate->heap()->undefined_value();
   2060 }
   2061 
   2062 
   2063 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
   2064   NoHandleAllocation ha;
   2065   ASSERT(args.length() == 2);
   2066 
   2067   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2068   CONVERT_SMI_ARG_CHECKED(length, 1);
   2069   fun->shared()->set_length(length);
   2070   return isolate->heap()->undefined_value();
   2071 }
   2072 
   2073 
   2074 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
   2075   NoHandleAllocation ha;
   2076   ASSERT(args.length() == 2);
   2077 
   2078   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
   2079   ASSERT(fun->should_have_prototype());
   2080   Object* obj;
   2081   { MaybeObject* maybe_obj =
   2082         Accessors::FunctionSetPrototype(fun, args[1], NULL);
   2083     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   2084   }
   2085   return args[0];  // return TOS
   2086 }
   2087 
   2088 
   2089 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
   2090   NoHandleAllocation ha;
   2091   RUNTIME_ASSERT(args.length() == 1);
   2092   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   2093 
   2094   MaybeObject* maybe_name =
   2095       isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
   2096   String* name;
   2097   if (!maybe_name->To(&name)) return maybe_name;
   2098 
   2099   if (function->HasFastProperties()) {
   2100     // Construct a new field descriptor with updated attributes.
   2101     DescriptorArray* instance_desc = function->map()->instance_descriptors();
   2102     int index = instance_desc->Search(name);
   2103     ASSERT(index != DescriptorArray::kNotFound);
   2104     PropertyDetails details(instance_desc->GetDetails(index));
   2105     CallbacksDescriptor new_desc(name,
   2106         instance_desc->GetValue(index),
   2107         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
   2108         details.index());
   2109     // Construct a new field descriptors array containing the new descriptor.
   2110     Object* descriptors_unchecked;
   2111     { MaybeObject* maybe_descriptors_unchecked =
   2112         instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS);
   2113       if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
   2114         return maybe_descriptors_unchecked;
   2115       }
   2116     }
   2117     DescriptorArray* new_descriptors =
   2118         DescriptorArray::cast(descriptors_unchecked);
   2119     // Create a new map featuring the new field descriptors array.
   2120     Object* map_unchecked;
   2121     { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors();
   2122       if (!maybe_map_unchecked->ToObject(&map_unchecked)) {
   2123         return maybe_map_unchecked;
   2124       }
   2125     }
   2126     Map* new_map = Map::cast(map_unchecked);
   2127     new_map->set_instance_descriptors(new_descriptors);
   2128     function->set_map(new_map);
   2129   } else {  // Dictionary properties.
   2130     // Directly manipulate the property details.
   2131     int entry = function->property_dictionary()->FindEntry(name);
   2132     ASSERT(entry != StringDictionary::kNotFound);
   2133     PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
   2134     PropertyDetails new_details(
   2135         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
   2136         details.type(),
   2137         details.index());
   2138     function->property_dictionary()->DetailsAtPut(entry, new_details);
   2139   }
   2140   return function;
   2141 }
   2142 
   2143 
   2144 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
   2145   NoHandleAllocation ha;
   2146   ASSERT(args.length() == 1);
   2147 
   2148   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2149   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
   2150 }
   2151 
   2152 
   2153 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
   2154   NoHandleAllocation ha;
   2155   ASSERT(args.length() == 1);
   2156 
   2157   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   2158   return isolate->heap()->ToBoolean(f->IsBuiltin());
   2159 }
   2160 
   2161 
   2162 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
   2163   HandleScope scope(isolate);
   2164   ASSERT(args.length() == 2);
   2165 
   2166   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
   2167   Handle<Object> code = args.at<Object>(1);
   2168 
   2169   Handle<Context> context(target->context());
   2170 
   2171   if (!code->IsNull()) {
   2172     RUNTIME_ASSERT(code->IsJSFunction());
   2173     Handle<JSFunction> fun = Handle<JSFunction>::cast(code);
   2174     Handle<SharedFunctionInfo> shared(fun->shared());
   2175 
   2176     if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
   2177       return Failure::Exception();
   2178     }
   2179     // Since we don't store the source for this we should never
   2180     // optimize this.
   2181     shared->code()->set_optimizable(false);
   2182     // Set the code, scope info, formal parameter count,
   2183     // and the length of the target function.
   2184     target->shared()->set_code(shared->code());
   2185     target->ReplaceCode(shared->code());
   2186     target->shared()->set_scope_info(shared->scope_info());
   2187     target->shared()->set_length(shared->length());
   2188     target->shared()->set_formal_parameter_count(
   2189         shared->formal_parameter_count());
   2190     // Set the source code of the target function to undefined.
   2191     // SetCode is only used for built-in constructors like String,
   2192     // Array, and Object, and some web code
   2193     // doesn't like seeing source code for constructors.
   2194     target->shared()->set_script(isolate->heap()->undefined_value());
   2195     target->shared()->code()->set_optimizable(false);
   2196     // Clear the optimization hints related to the compiled code as these are no
   2197     // longer valid when the code is overwritten.
   2198     target->shared()->ClearThisPropertyAssignmentsInfo();
   2199     context = Handle<Context>(fun->context());
   2200 
   2201     // Make sure we get a fresh copy of the literal vector to avoid
   2202     // cross context contamination.
   2203     int number_of_literals = fun->NumberOfLiterals();
   2204     Handle<FixedArray> literals =
   2205         isolate->factory()->NewFixedArray(number_of_literals, TENURED);
   2206     if (number_of_literals > 0) {
   2207       // Insert the object, regexp and array functions in the literals
   2208       // array prefix.  These are the functions that will be used when
   2209       // creating object, regexp and array literals.
   2210       literals->set(JSFunction::kLiteralGlobalContextIndex,
   2211                     context->global_context());
   2212     }
   2213     target->set_literals(*literals);
   2214     target->set_next_function_link(isolate->heap()->undefined_value());
   2215 
   2216     if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) {
   2217       isolate->logger()->LogExistingFunction(
   2218           shared, Handle<Code>(shared->code()));
   2219     }
   2220   }
   2221 
   2222   target->set_context(*context);
   2223   return *target;
   2224 }
   2225 
   2226 
   2227 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
   2228   HandleScope scope(isolate);
   2229   ASSERT(args.length() == 2);
   2230   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   2231   CONVERT_SMI_ARG_CHECKED(num, 1);
   2232   RUNTIME_ASSERT(num >= 0);
   2233   SetExpectedNofProperties(function, num);
   2234   return isolate->heap()->undefined_value();
   2235 }
   2236 
   2237 
   2238 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
   2239                                                  Object* char_code) {
   2240   uint32_t code;
   2241   if (char_code->ToArrayIndex(&code)) {
   2242     if (code <= 0xffff) {
   2243       return isolate->heap()->LookupSingleCharacterStringFromCode(code);
   2244     }
   2245   }
   2246   return isolate->heap()->empty_string();
   2247 }
   2248 
   2249 
   2250 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAt) {
   2251   NoHandleAllocation ha;
   2252   ASSERT(args.length() == 2);
   2253 
   2254   CONVERT_ARG_CHECKED(String, subject, 0);
   2255   Object* index = args[1];
   2256   RUNTIME_ASSERT(index->IsNumber());
   2257 
   2258   uint32_t i = 0;
   2259   if (index->IsSmi()) {
   2260     int value = Smi::cast(index)->value();
   2261     if (value < 0) return isolate->heap()->nan_value();
   2262     i = value;
   2263   } else {
   2264     ASSERT(index->IsHeapNumber());
   2265     double value = HeapNumber::cast(index)->value();
   2266     i = static_cast<uint32_t>(DoubleToInteger(value));
   2267   }
   2268 
   2269   // Flatten the string.  If someone wants to get a char at an index
   2270   // in a cons string, it is likely that more indices will be
   2271   // accessed.
   2272   Object* flat;
   2273   { MaybeObject* maybe_flat = subject->TryFlatten();
   2274     if (!maybe_flat->ToObject(&flat)) return maybe_flat;
   2275   }
   2276   subject = String::cast(flat);
   2277 
   2278   if (i >= static_cast<uint32_t>(subject->length())) {
   2279     return isolate->heap()->nan_value();
   2280   }
   2281 
   2282   return Smi::FromInt(subject->Get(i));
   2283 }
   2284 
   2285 
   2286 RUNTIME_FUNCTION(MaybeObject*, Runtime_CharFromCode) {
   2287   NoHandleAllocation ha;
   2288   ASSERT(args.length() == 1);
   2289   return CharFromCode(isolate, args[0]);
   2290 }
   2291 
   2292 
   2293 class FixedArrayBuilder {
   2294  public:
   2295   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
   2296       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
   2297         length_(0),
   2298         has_non_smi_elements_(false) {
   2299     // Require a non-zero initial size. Ensures that doubling the size to
   2300     // extend the array will work.
   2301     ASSERT(initial_capacity > 0);
   2302   }
   2303 
   2304   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
   2305       : array_(backing_store),
   2306         length_(0),
   2307         has_non_smi_elements_(false) {
   2308     // Require a non-zero initial size. Ensures that doubling the size to
   2309     // extend the array will work.
   2310     ASSERT(backing_store->length() > 0);
   2311   }
   2312 
   2313   bool HasCapacity(int elements) {
   2314     int length = array_->length();
   2315     int required_length = length_ + elements;
   2316     return (length >= required_length);
   2317   }
   2318 
   2319   void EnsureCapacity(int elements) {
   2320     int length = array_->length();
   2321     int required_length = length_ + elements;
   2322     if (length < required_length) {
   2323       int new_length = length;
   2324       do {
   2325         new_length *= 2;
   2326       } while (new_length < required_length);
   2327       Handle<FixedArray> extended_array =
   2328           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
   2329       array_->CopyTo(0, *extended_array, 0, length_);
   2330       array_ = extended_array;
   2331     }
   2332   }
   2333 
   2334   void Add(Object* value) {
   2335     ASSERT(!value->IsSmi());
   2336     ASSERT(length_ < capacity());
   2337     array_->set(length_, value);
   2338     length_++;
   2339     has_non_smi_elements_ = true;
   2340   }
   2341 
   2342   void Add(Smi* value) {
   2343     ASSERT(value->IsSmi());
   2344     ASSERT(length_ < capacity());
   2345     array_->set(length_, value);
   2346     length_++;
   2347   }
   2348 
   2349   Handle<FixedArray> array() {
   2350     return array_;
   2351   }
   2352 
   2353   int length() {
   2354     return length_;
   2355   }
   2356 
   2357   int capacity() {
   2358     return array_->length();
   2359   }
   2360 
   2361   Handle<JSArray> ToJSArray() {
   2362     Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_);
   2363     result_array->set_length(Smi::FromInt(length_));
   2364     return result_array;
   2365   }
   2366 
   2367   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
   2368     FACTORY->SetContent(target_array, array_);
   2369     target_array->set_length(Smi::FromInt(length_));
   2370     return target_array;
   2371   }
   2372 
   2373  private:
   2374   Handle<FixedArray> array_;
   2375   int length_;
   2376   bool has_non_smi_elements_;
   2377 };
   2378 
   2379 
   2380 // Forward declarations.
   2381 const int kStringBuilderConcatHelperLengthBits = 11;
   2382 const int kStringBuilderConcatHelperPositionBits = 19;
   2383 
   2384 template <typename schar>
   2385 static inline void StringBuilderConcatHelper(String*,
   2386                                              schar*,
   2387                                              FixedArray*,
   2388                                              int);
   2389 
   2390 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
   2391     StringBuilderSubstringLength;
   2392 typedef BitField<int,
   2393                  kStringBuilderConcatHelperLengthBits,
   2394                  kStringBuilderConcatHelperPositionBits>
   2395     StringBuilderSubstringPosition;
   2396 
   2397 
   2398 class ReplacementStringBuilder {
   2399  public:
   2400   ReplacementStringBuilder(Heap* heap,
   2401                            Handle<String> subject,
   2402                            int estimated_part_count)
   2403       : heap_(heap),
   2404         array_builder_(heap->isolate(), estimated_part_count),
   2405         subject_(subject),
   2406         character_count_(0),
   2407         is_ascii_(subject->IsAsciiRepresentation()) {
   2408     // Require a non-zero initial size. Ensures that doubling the size to
   2409     // extend the array will work.
   2410     ASSERT(estimated_part_count > 0);
   2411   }
   2412 
   2413   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
   2414                                      int from,
   2415                                      int to) {
   2416     ASSERT(from >= 0);
   2417     int length = to - from;
   2418     ASSERT(length > 0);
   2419     if (StringBuilderSubstringLength::is_valid(length) &&
   2420         StringBuilderSubstringPosition::is_valid(from)) {
   2421       int encoded_slice = StringBuilderSubstringLength::encode(length) |
   2422           StringBuilderSubstringPosition::encode(from);
   2423       builder->Add(Smi::FromInt(encoded_slice));
   2424     } else {
   2425       // Otherwise encode as two smis.
   2426       builder->Add(Smi::FromInt(-length));
   2427       builder->Add(Smi::FromInt(from));
   2428     }
   2429   }
   2430 
   2431 
   2432   void EnsureCapacity(int elements) {
   2433     array_builder_.EnsureCapacity(elements);
   2434   }
   2435 
   2436 
   2437   void AddSubjectSlice(int from, int to) {
   2438     AddSubjectSlice(&array_builder_, from, to);
   2439     IncrementCharacterCount(to - from);
   2440   }
   2441 
   2442 
   2443   void AddString(Handle<String> string) {
   2444     int length = string->length();
   2445     ASSERT(length > 0);
   2446     AddElement(*string);
   2447     if (!string->IsAsciiRepresentation()) {
   2448       is_ascii_ = false;
   2449     }
   2450     IncrementCharacterCount(length);
   2451   }
   2452 
   2453 
   2454   Handle<String> ToString() {
   2455     if (array_builder_.length() == 0) {
   2456       return heap_->isolate()->factory()->empty_string();
   2457     }
   2458 
   2459     Handle<String> joined_string;
   2460     if (is_ascii_) {
   2461       Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_);
   2462       AssertNoAllocation no_alloc;
   2463       char* char_buffer = seq->GetChars();
   2464       StringBuilderConcatHelper(*subject_,
   2465                                 char_buffer,
   2466                                 *array_builder_.array(),
   2467                                 array_builder_.length());
   2468       joined_string = Handle<String>::cast(seq);
   2469     } else {
   2470       // Non-ASCII.
   2471       Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
   2472       AssertNoAllocation no_alloc;
   2473       uc16* char_buffer = seq->GetChars();
   2474       StringBuilderConcatHelper(*subject_,
   2475                                 char_buffer,
   2476                                 *array_builder_.array(),
   2477                                 array_builder_.length());
   2478       joined_string = Handle<String>::cast(seq);
   2479     }
   2480     return joined_string;
   2481   }
   2482 
   2483 
   2484   void IncrementCharacterCount(int by) {
   2485     if (character_count_ > String::kMaxLength - by) {
   2486       V8::FatalProcessOutOfMemory("String.replace result too large.");
   2487     }
   2488     character_count_ += by;
   2489   }
   2490 
   2491   Handle<JSArray> GetParts() {
   2492     return array_builder_.ToJSArray();
   2493   }
   2494 
   2495  private:
   2496   Handle<SeqAsciiString> NewRawAsciiString(int length) {
   2497     return heap_->isolate()->factory()->NewRawAsciiString(length);
   2498   }
   2499 
   2500 
   2501   Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
   2502     return heap_->isolate()->factory()->NewRawTwoByteString(length);
   2503   }
   2504 
   2505 
   2506   void AddElement(Object* element) {
   2507     ASSERT(element->IsSmi() || element->IsString());
   2508     ASSERT(array_builder_.capacity() > array_builder_.length());
   2509     array_builder_.Add(element);
   2510   }
   2511 
   2512   Heap* heap_;
   2513   FixedArrayBuilder array_builder_;
   2514   Handle<String> subject_;
   2515   int character_count_;
   2516   bool is_ascii_;
   2517 };
   2518 
   2519 
   2520 class CompiledReplacement {
   2521  public:
   2522   CompiledReplacement()
   2523       : parts_(1), replacement_substrings_(0), simple_hint_(false) {}
   2524 
   2525   void Compile(Handle<String> replacement,
   2526                int capture_count,
   2527                int subject_length);
   2528 
   2529   void Apply(ReplacementStringBuilder* builder,
   2530              int match_from,
   2531              int match_to,
   2532              Handle<JSArray> last_match_info);
   2533 
   2534   // Number of distinct parts of the replacement pattern.
   2535   int parts() {
   2536     return parts_.length();
   2537   }
   2538 
   2539   bool simple_hint() {
   2540     return simple_hint_;
   2541   }
   2542 
   2543  private:
   2544   enum PartType {
   2545     SUBJECT_PREFIX = 1,
   2546     SUBJECT_SUFFIX,
   2547     SUBJECT_CAPTURE,
   2548     REPLACEMENT_SUBSTRING,
   2549     REPLACEMENT_STRING,
   2550 
   2551     NUMBER_OF_PART_TYPES
   2552   };
   2553 
   2554   struct ReplacementPart {
   2555     static inline ReplacementPart SubjectMatch() {
   2556       return ReplacementPart(SUBJECT_CAPTURE, 0);
   2557     }
   2558     static inline ReplacementPart SubjectCapture(int capture_index) {
   2559       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
   2560     }
   2561     static inline ReplacementPart SubjectPrefix() {
   2562       return ReplacementPart(SUBJECT_PREFIX, 0);
   2563     }
   2564     static inline ReplacementPart SubjectSuffix(int subject_length) {
   2565       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
   2566     }
   2567     static inline ReplacementPart ReplacementString() {
   2568       return ReplacementPart(REPLACEMENT_STRING, 0);
   2569     }
   2570     static inline ReplacementPart ReplacementSubString(int from, int to) {
   2571       ASSERT(from >= 0);
   2572       ASSERT(to > from);
   2573       return ReplacementPart(-from, to);
   2574     }
   2575 
   2576     // If tag <= 0 then it is the negation of a start index of a substring of
   2577     // the replacement pattern, otherwise it's a value from PartType.
   2578     ReplacementPart(int tag, int data)
   2579         : tag(tag), data(data) {
   2580       // Must be non-positive or a PartType value.
   2581       ASSERT(tag < NUMBER_OF_PART_TYPES);
   2582     }
   2583     // Either a value of PartType or a non-positive number that is
   2584     // the negation of an index into the replacement string.
   2585     int tag;
   2586     // The data value's interpretation depends on the value of tag:
   2587     // tag == SUBJECT_PREFIX ||
   2588     // tag == SUBJECT_SUFFIX:  data is unused.
   2589     // tag == SUBJECT_CAPTURE: data is the number of the capture.
   2590     // tag == REPLACEMENT_SUBSTRING ||
   2591     // tag == REPLACEMENT_STRING:    data is index into array of substrings
   2592     //                               of the replacement string.
   2593     // tag <= 0: Temporary representation of the substring of the replacement
   2594     //           string ranging over -tag .. data.
   2595     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
   2596     //           substring objects.
   2597     int data;
   2598   };
   2599 
   2600   template<typename Char>
   2601   static bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
   2602                                       Vector<Char> characters,
   2603                                       int capture_count,
   2604                                       int subject_length) {
   2605     int length = characters.length();
   2606     int last = 0;
   2607     for (int i = 0; i < length; i++) {
   2608       Char c = characters[i];
   2609       if (c == '$') {
   2610         int next_index = i + 1;
   2611         if (next_index == length) {  // No next character!
   2612           break;
   2613         }
   2614         Char c2 = characters[next_index];
   2615         switch (c2) {
   2616         case '$':
   2617           if (i > last) {
   2618             // There is a substring before. Include the first "$".
   2619             parts->Add(ReplacementPart::ReplacementSubString(last, next_index));
   2620             last = next_index + 1;  // Continue after the second "$".
   2621           } else {
   2622             // Let the next substring start with the second "$".
   2623             last = next_index;
   2624           }
   2625           i = next_index;
   2626           break;
   2627         case '`':
   2628           if (i > last) {
   2629             parts->Add(ReplacementPart::ReplacementSubString(last, i));
   2630           }
   2631           parts->Add(ReplacementPart::SubjectPrefix());
   2632           i = next_index;
   2633           last = i + 1;
   2634           break;
   2635         case '\'':
   2636           if (i > last) {
   2637             parts->Add(ReplacementPart::ReplacementSubString(last, i));
   2638           }
   2639           parts->Add(ReplacementPart::SubjectSuffix(subject_length));
   2640           i = next_index;
   2641           last = i + 1;
   2642           break;
   2643         case '&':
   2644           if (i > last) {
   2645             parts->Add(ReplacementPart::ReplacementSubString(last, i));
   2646           }
   2647           parts->Add(ReplacementPart::SubjectMatch());
   2648           i = next_index;
   2649           last = i + 1;
   2650           break;
   2651         case '0':
   2652         case '1':
   2653         case '2':
   2654         case '3':
   2655         case '4':
   2656         case '5':
   2657         case '6':
   2658         case '7':
   2659         case '8':
   2660         case '9': {
   2661           int capture_ref = c2 - '0';
   2662           if (capture_ref > capture_count) {
   2663             i = next_index;
   2664             continue;
   2665           }
   2666           int second_digit_index = next_index + 1;
   2667           if (second_digit_index < length) {
   2668             // Peek ahead to see if we have two digits.
   2669             Char c3 = characters[second_digit_index];
   2670             if ('0' <= c3 && c3 <= '9') {  // Double digits.
   2671               int double_digit_ref = capture_ref * 10 + c3 - '0';
   2672               if (double_digit_ref <= capture_count) {
   2673                 next_index = second_digit_index;
   2674                 capture_ref = double_digit_ref;
   2675               }
   2676             }
   2677           }
   2678           if (capture_ref > 0) {
   2679             if (i > last) {
   2680               parts->Add(ReplacementPart::ReplacementSubString(last, i));
   2681             }
   2682             ASSERT(capture_ref <= capture_count);
   2683             parts->Add(ReplacementPart::SubjectCapture(capture_ref));
   2684             last = next_index + 1;
   2685           }
   2686           i = next_index;
   2687           break;
   2688         }
   2689         default:
   2690           i = next_index;
   2691           break;
   2692         }
   2693       }
   2694     }
   2695     if (length > last) {
   2696       if (last == 0) {
   2697         parts->Add(ReplacementPart::ReplacementString());
   2698         return true;
   2699       } else {
   2700         parts->Add(ReplacementPart::ReplacementSubString(last, length));
   2701       }
   2702     }
   2703     return false;
   2704   }
   2705 
   2706   ZoneList<ReplacementPart> parts_;
   2707   ZoneList<Handle<String> > replacement_substrings_;
   2708   bool simple_hint_;
   2709 };
   2710 
   2711 
   2712 void CompiledReplacement::Compile(Handle<String> replacement,
   2713                                   int capture_count,
   2714                                   int subject_length) {
   2715   {
   2716     AssertNoAllocation no_alloc;
   2717     String::FlatContent content = replacement->GetFlatContent();
   2718     ASSERT(content.IsFlat());
   2719     if (content.IsAscii()) {
   2720       simple_hint_ = ParseReplacementPattern(&parts_,
   2721                                              content.ToAsciiVector(),
   2722                                              capture_count,
   2723                                              subject_length);
   2724     } else {
   2725       ASSERT(content.IsTwoByte());
   2726       simple_hint_ = ParseReplacementPattern(&parts_,
   2727                                              content.ToUC16Vector(),
   2728                                              capture_count,
   2729                                              subject_length);
   2730     }
   2731   }
   2732   Isolate* isolate = replacement->GetIsolate();
   2733   // Find substrings of replacement string and create them as String objects.
   2734   int substring_index = 0;
   2735   for (int i = 0, n = parts_.length(); i < n; i++) {
   2736     int tag = parts_[i].tag;
   2737     if (tag <= 0) {  // A replacement string slice.
   2738       int from = -tag;
   2739       int to = parts_[i].data;
   2740       replacement_substrings_.Add(
   2741           isolate->factory()->NewSubString(replacement, from, to));
   2742       parts_[i].tag = REPLACEMENT_SUBSTRING;
   2743       parts_[i].data = substring_index;
   2744       substring_index++;
   2745     } else if (tag == REPLACEMENT_STRING) {
   2746       replacement_substrings_.Add(replacement);
   2747       parts_[i].data = substring_index;
   2748       substring_index++;
   2749     }
   2750   }
   2751 }
   2752 
   2753 
   2754 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
   2755                                 int match_from,
   2756                                 int match_to,
   2757                                 Handle<JSArray> last_match_info) {
   2758   for (int i = 0, n = parts_.length(); i < n; i++) {
   2759     ReplacementPart part = parts_[i];
   2760     switch (part.tag) {
   2761       case SUBJECT_PREFIX:
   2762         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
   2763         break;
   2764       case SUBJECT_SUFFIX: {
   2765         int subject_length = part.data;
   2766         if (match_to < subject_length) {
   2767           builder->AddSubjectSlice(match_to, subject_length);
   2768         }
   2769         break;
   2770       }
   2771       case SUBJECT_CAPTURE: {
   2772         int capture = part.data;
   2773         FixedArray* match_info = FixedArray::cast(last_match_info->elements());
   2774         int from = RegExpImpl::GetCapture(match_info, capture * 2);
   2775         int to = RegExpImpl::GetCapture(match_info, capture * 2 + 1);
   2776         if (from >= 0 && to > from) {
   2777           builder->AddSubjectSlice(from, to);
   2778         }
   2779         break;
   2780       }
   2781       case REPLACEMENT_SUBSTRING:
   2782       case REPLACEMENT_STRING:
   2783         builder->AddString(replacement_substrings_[part.data]);
   2784         break;
   2785       default:
   2786         UNREACHABLE();
   2787     }
   2788   }
   2789 }
   2790 
   2791 
   2792 void FindAsciiStringIndices(Vector<const char> subject,
   2793                             char pattern,
   2794                             ZoneList<int>* indices,
   2795                             unsigned int limit) {
   2796   ASSERT(limit > 0);
   2797   // Collect indices of pattern in subject using memchr.
   2798   // Stop after finding at most limit values.
   2799   const char* subject_start = reinterpret_cast<const char*>(subject.start());
   2800   const char* subject_end = subject_start + subject.length();
   2801   const char* pos = subject_start;
   2802   while (limit > 0) {
   2803     pos = reinterpret_cast<const char*>(
   2804         memchr(pos, pattern, subject_end - pos));
   2805     if (pos == NULL) return;
   2806     indices->Add(static_cast<int>(pos - subject_start));
   2807     pos++;
   2808     limit--;
   2809   }
   2810 }
   2811 
   2812 
   2813 template <typename SubjectChar, typename PatternChar>
   2814 void FindStringIndices(Isolate* isolate,
   2815                        Vector<const SubjectChar> subject,
   2816                        Vector<const PatternChar> pattern,
   2817                        ZoneList<int>* indices,
   2818                        unsigned int limit) {
   2819   ASSERT(limit > 0);
   2820   // Collect indices of pattern in subject.
   2821   // Stop after finding at most limit values.
   2822   int pattern_length = pattern.length();
   2823   int index = 0;
   2824   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   2825   while (limit > 0) {
   2826     index = search.Search(subject, index);
   2827     if (index < 0) return;
   2828     indices->Add(index);
   2829     index += pattern_length;
   2830     limit--;
   2831   }
   2832 }
   2833 
   2834 
   2835 void FindStringIndicesDispatch(Isolate* isolate,
   2836                                String* subject,
   2837                                String* pattern,
   2838                                ZoneList<int>* indices,
   2839                                unsigned int limit) {
   2840   {
   2841     AssertNoAllocation no_gc;
   2842     String::FlatContent subject_content = subject->GetFlatContent();
   2843     String::FlatContent pattern_content = pattern->GetFlatContent();
   2844     ASSERT(subject_content.IsFlat());
   2845     ASSERT(pattern_content.IsFlat());
   2846     if (subject_content.IsAscii()) {
   2847       Vector<const char> subject_vector = subject_content.ToAsciiVector();
   2848       if (pattern_content.IsAscii()) {
   2849         Vector<const char> pattern_vector = pattern_content.ToAsciiVector();
   2850         if (pattern_vector.length() == 1) {
   2851           FindAsciiStringIndices(subject_vector,
   2852                                  pattern_vector[0],
   2853                                  indices,
   2854                                  limit);
   2855         } else {
   2856           FindStringIndices(isolate,
   2857                             subject_vector,
   2858                             pattern_vector,
   2859                             indices,
   2860                             limit);
   2861         }
   2862       } else {
   2863         FindStringIndices(isolate,
   2864                           subject_vector,
   2865                           pattern_content.ToUC16Vector(),
   2866                           indices,
   2867                           limit);
   2868       }
   2869     } else {
   2870       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
   2871       if (pattern_content.IsAscii()) {
   2872         FindStringIndices(isolate,
   2873                           subject_vector,
   2874                           pattern_content.ToAsciiVector(),
   2875                           indices,
   2876                           limit);
   2877       } else {
   2878         FindStringIndices(isolate,
   2879                           subject_vector,
   2880                           pattern_content.ToUC16Vector(),
   2881                           indices,
   2882                           limit);
   2883       }
   2884     }
   2885   }
   2886 }
   2887 
   2888 
   2889 template<typename ResultSeqString>
   2890 MUST_USE_RESULT static MaybeObject* StringReplaceStringWithString(
   2891     Isolate* isolate,
   2892     Handle<String> subject,
   2893     Handle<JSRegExp> pattern_regexp,
   2894     Handle<String> replacement) {
   2895   ASSERT(subject->IsFlat());
   2896   ASSERT(replacement->IsFlat());
   2897 
   2898   ZoneScope zone_space(isolate, DELETE_ON_EXIT);
   2899   ZoneList<int> indices(8);
   2900   ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
   2901   String* pattern =
   2902       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
   2903   int subject_len = subject->length();
   2904   int pattern_len = pattern->length();
   2905   int replacement_len = replacement->length();
   2906 
   2907   FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff);
   2908 
   2909   int matches = indices.length();
   2910   if (matches == 0) return *subject;
   2911 
   2912   int result_len = (replacement_len - pattern_len) * matches + subject_len;
   2913   int subject_pos = 0;
   2914   int result_pos = 0;
   2915 
   2916   Handle<ResultSeqString> result;
   2917   if (ResultSeqString::kHasAsciiEncoding) {
   2918     result = Handle<ResultSeqString>::cast(
   2919         isolate->factory()->NewRawAsciiString(result_len));
   2920   } else {
   2921     result = Handle<ResultSeqString>::cast(
   2922         isolate->factory()->NewRawTwoByteString(result_len));
   2923   }
   2924 
   2925   for (int i = 0; i < matches; i++) {
   2926     // Copy non-matched subject content.
   2927     if (subject_pos < indices.at(i)) {
   2928       String::WriteToFlat(*subject,
   2929                           result->GetChars() + result_pos,
   2930                           subject_pos,
   2931                           indices.at(i));
   2932       result_pos += indices.at(i) - subject_pos;
   2933     }
   2934 
   2935     // Replace match.
   2936     if (replacement_len > 0) {
   2937       String::WriteToFlat(*replacement,
   2938                           result->GetChars() + result_pos,
   2939                           0,
   2940                           replacement_len);
   2941       result_pos += replacement_len;
   2942     }
   2943 
   2944     subject_pos = indices.at(i) + pattern_len;
   2945   }
   2946   // Add remaining subject content at the end.
   2947   if (subject_pos < subject_len) {
   2948     String::WriteToFlat(*subject,
   2949                         result->GetChars() + result_pos,
   2950                         subject_pos,
   2951                         subject_len);
   2952   }
   2953   return *result;
   2954 }
   2955 
   2956 
   2957 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
   2958     Isolate* isolate,
   2959     String* subject,
   2960     JSRegExp* regexp,
   2961     String* replacement,
   2962     JSArray* last_match_info) {
   2963   ASSERT(subject->IsFlat());
   2964   ASSERT(replacement->IsFlat());
   2965 
   2966   HandleScope handles(isolate);
   2967 
   2968   int length = subject->length();
   2969   Handle<String> subject_handle(subject);
   2970   Handle<JSRegExp> regexp_handle(regexp);
   2971   Handle<String> replacement_handle(replacement);
   2972   Handle<JSArray> last_match_info_handle(last_match_info);
   2973   Handle<Object> match = RegExpImpl::Exec(regexp_handle,
   2974                                           subject_handle,
   2975                                           0,
   2976                                           last_match_info_handle);
   2977   if (match.is_null()) {
   2978     return Failure::Exception();
   2979   }
   2980   if (match->IsNull()) {
   2981     return *subject_handle;
   2982   }
   2983 
   2984   int capture_count = regexp_handle->CaptureCount();
   2985 
   2986   // CompiledReplacement uses zone allocation.
   2987   ZoneScope zone(isolate, DELETE_ON_EXIT);
   2988   CompiledReplacement compiled_replacement;
   2989   compiled_replacement.Compile(replacement_handle,
   2990                                capture_count,
   2991                                length);
   2992 
   2993   bool is_global = regexp_handle->GetFlags().is_global();
   2994 
   2995   // Shortcut for simple non-regexp global replacements
   2996   if (is_global &&
   2997       regexp_handle->TypeTag() == JSRegExp::ATOM &&
   2998       compiled_replacement.simple_hint()) {
   2999     if (subject_handle->HasOnlyAsciiChars() &&
   3000         replacement_handle->HasOnlyAsciiChars()) {
   3001       return StringReplaceStringWithString<SeqAsciiString>(
   3002           isolate, subject_handle, regexp_handle, replacement_handle);
   3003     } else {
   3004       return StringReplaceStringWithString<SeqTwoByteString>(
   3005           isolate, subject_handle, regexp_handle, replacement_handle);
   3006     }
   3007   }
   3008 
   3009   // Guessing the number of parts that the final result string is built
   3010   // from. Global regexps can match any number of times, so we guess
   3011   // conservatively.
   3012   int expected_parts =
   3013       (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1;
   3014   ReplacementStringBuilder builder(isolate->heap(),
   3015                                    subject_handle,
   3016                                    expected_parts);
   3017 
   3018   // Index of end of last match.
   3019   int prev = 0;
   3020 
   3021   // Number of parts added by compiled replacement plus preceeding
   3022   // string and possibly suffix after last match.  It is possible for
   3023   // all components to use two elements when encoded as two smis.
   3024   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
   3025   bool matched = true;
   3026   do {
   3027     ASSERT(last_match_info_handle->HasFastElements());
   3028     // Increase the capacity of the builder before entering local handle-scope,
   3029     // so its internal buffer can safely allocate a new handle if it grows.
   3030     builder.EnsureCapacity(parts_added_per_loop);
   3031 
   3032     HandleScope loop_scope(isolate);
   3033     int start, end;
   3034     {
   3035       AssertNoAllocation match_info_array_is_not_in_a_handle;
   3036       FixedArray* match_info_array =
   3037           FixedArray::cast(last_match_info_handle->elements());
   3038 
   3039       ASSERT_EQ(capture_count * 2 + 2,
   3040                 RegExpImpl::GetLastCaptureCount(match_info_array));
   3041       start = RegExpImpl::GetCapture(match_info_array, 0);
   3042       end = RegExpImpl::GetCapture(match_info_array, 1);
   3043     }
   3044 
   3045     if (prev < start) {
   3046       builder.AddSubjectSlice(prev, start);
   3047     }
   3048     compiled_replacement.Apply(&builder,
   3049                                start,
   3050                                end,
   3051                                last_match_info_handle);
   3052     prev = end;
   3053 
   3054     // Only continue checking for global regexps.
   3055     if (!is_global) break;
   3056 
   3057     // Continue from where the match ended, unless it was an empty match.
   3058     int next = end;
   3059     if (start == end) {
   3060       next = end + 1;
   3061       if (next > length) break;
   3062     }
   3063 
   3064     match = RegExpImpl::Exec(regexp_handle,
   3065                              subject_handle,
   3066                              next,
   3067                              last_match_info_handle);
   3068     if (match.is_null()) {
   3069       return Failure::Exception();
   3070     }
   3071     matched = !match->IsNull();
   3072   } while (matched);
   3073 
   3074   if (prev < length) {
   3075     builder.AddSubjectSlice(prev, length);
   3076   }
   3077 
   3078   return *(builder.ToString());
   3079 }
   3080 
   3081 
   3082 template <typename ResultSeqString>
   3083 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
   3084     Isolate* isolate,
   3085     String* subject,
   3086     JSRegExp* regexp,
   3087     JSArray* last_match_info) {
   3088   ASSERT(subject->IsFlat());
   3089 
   3090   HandleScope handles(isolate);
   3091 
   3092   Handle<String> subject_handle(subject);
   3093   Handle<JSRegExp> regexp_handle(regexp);
   3094 
   3095   // Shortcut for simple non-regexp global replacements
   3096   if (regexp_handle->GetFlags().is_global() &&
   3097       regexp_handle->TypeTag() == JSRegExp::ATOM) {
   3098     Handle<String> empty_string_handle(HEAP->empty_string());
   3099     if (subject_handle->HasOnlyAsciiChars()) {
   3100       return StringReplaceStringWithString<SeqAsciiString>(
   3101           isolate, subject_handle, regexp_handle, empty_string_handle);
   3102     } else {
   3103       return StringReplaceStringWithString<SeqTwoByteString>(
   3104           isolate, subject_handle, regexp_handle, empty_string_handle);
   3105     }
   3106   }
   3107 
   3108   Handle<JSArray> last_match_info_handle(last_match_info);
   3109   Handle<Object> match = RegExpImpl::Exec(regexp_handle,
   3110                                           subject_handle,
   3111                                           0,
   3112                                           last_match_info_handle);
   3113   if (match.is_null()) return Failure::Exception();
   3114   if (match->IsNull()) return *subject_handle;
   3115 
   3116   ASSERT(last_match_info_handle->HasFastElements());
   3117 
   3118   int start, end;
   3119   {
   3120     AssertNoAllocation match_info_array_is_not_in_a_handle;
   3121     FixedArray* match_info_array =
   3122         FixedArray::cast(last_match_info_handle->elements());
   3123 
   3124     start = RegExpImpl::GetCapture(match_info_array, 0);
   3125     end = RegExpImpl::GetCapture(match_info_array, 1);
   3126   }
   3127 
   3128   int length = subject_handle->length();
   3129   int new_length = length - (end - start);
   3130   if (new_length == 0) {
   3131     return isolate->heap()->empty_string();
   3132   }
   3133   Handle<ResultSeqString> answer;
   3134   if (ResultSeqString::kHasAsciiEncoding) {
   3135     answer = Handle<ResultSeqString>::cast(
   3136         isolate->factory()->NewRawAsciiString(new_length));
   3137   } else {
   3138     answer = Handle<ResultSeqString>::cast(
   3139         isolate->factory()->NewRawTwoByteString(new_length));
   3140   }
   3141 
   3142   // If the regexp isn't global, only match once.
   3143   if (!regexp_handle->GetFlags().is_global()) {
   3144     if (start > 0) {
   3145       String::WriteToFlat(*subject_handle,
   3146                           answer->GetChars(),
   3147                           0,
   3148                           start);
   3149     }
   3150     if (end < length) {
   3151       String::WriteToFlat(*subject_handle,
   3152                           answer->GetChars() + start,
   3153                           end,
   3154                           length);
   3155     }
   3156     return *answer;
   3157   }
   3158 
   3159   int prev = 0;  // Index of end of last match.
   3160   int next = 0;  // Start of next search (prev unless last match was empty).
   3161   int position = 0;
   3162 
   3163   do {
   3164     if (prev < start) {
   3165       // Add substring subject[prev;start] to answer string.
   3166       String::WriteToFlat(*subject_handle,
   3167                           answer->GetChars() + position,
   3168                           prev,
   3169                           start);
   3170       position += start - prev;
   3171     }
   3172     prev = end;
   3173     next = end;
   3174     // Continue from where the match ended, unless it was an empty match.
   3175     if (start == end) {
   3176       next++;
   3177       if (next > length) break;
   3178     }
   3179     match = RegExpImpl::Exec(regexp_handle,
   3180                              subject_handle,
   3181                              next,
   3182                              last_match_info_handle);
   3183     if (match.is_null()) return Failure::Exception();
   3184     if (match->IsNull()) break;
   3185 
   3186     ASSERT(last_match_info_handle->HasFastElements());
   3187     HandleScope loop_scope(isolate);
   3188     {
   3189       AssertNoAllocation match_info_array_is_not_in_a_handle;
   3190       FixedArray* match_info_array =
   3191           FixedArray::cast(last_match_info_handle->elements());
   3192       start = RegExpImpl::GetCapture(match_info_array, 0);
   3193       end = RegExpImpl::GetCapture(match_info_array, 1);
   3194     }
   3195   } while (true);
   3196 
   3197   if (prev < length) {
   3198     // Add substring subject[prev;length] to answer string.
   3199     String::WriteToFlat(*subject_handle,
   3200                         answer->GetChars() + position,
   3201                         prev,
   3202                         length);
   3203     position += length - prev;
   3204   }
   3205 
   3206   if (position == 0) {
   3207     return isolate->heap()->empty_string();
   3208   }
   3209 
   3210   // Shorten string and fill
   3211   int string_size = ResultSeqString::SizeFor(position);
   3212   int allocated_string_size = ResultSeqString::SizeFor(new_length);
   3213   int delta = allocated_string_size - string_size;
   3214 
   3215   answer->set_length(position);
   3216   if (delta == 0) return *answer;
   3217 
   3218   Address end_of_string = answer->address() + string_size;
   3219   isolate->heap()->CreateFillerObjectAt(end_of_string, delta);
   3220   if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) {
   3221     MemoryChunk::IncrementLiveBytesFromMutator(answer->address(), -delta);
   3222   }
   3223 
   3224   return *answer;
   3225 }
   3226 
   3227 
   3228 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) {
   3229   ASSERT(args.length() == 4);
   3230 
   3231   CONVERT_ARG_CHECKED(String, subject, 0);
   3232   if (!subject->IsFlat()) {
   3233     Object* flat_subject;
   3234     { MaybeObject* maybe_flat_subject = subject->TryFlatten();
   3235       if (!maybe_flat_subject->ToObject(&flat_subject)) {
   3236         return maybe_flat_subject;
   3237       }
   3238     }
   3239     subject = String::cast(flat_subject);
   3240   }
   3241 
   3242   CONVERT_ARG_CHECKED(String, replacement, 2);
   3243   if (!replacement->IsFlat()) {
   3244     Object* flat_replacement;
   3245     { MaybeObject* maybe_flat_replacement = replacement->TryFlatten();
   3246       if (!maybe_flat_replacement->ToObject(&flat_replacement)) {
   3247         return maybe_flat_replacement;
   3248       }
   3249     }
   3250     replacement = String::cast(flat_replacement);
   3251   }
   3252 
   3253   CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
   3254   CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
   3255 
   3256   ASSERT(last_match_info->HasFastElements());
   3257 
   3258   if (replacement->length() == 0) {
   3259     if (subject->HasOnlyAsciiChars()) {
   3260       return StringReplaceRegExpWithEmptyString<SeqAsciiString>(
   3261           isolate, subject, regexp, last_match_info);
   3262     } else {
   3263       return StringReplaceRegExpWithEmptyString<SeqTwoByteString>(
   3264           isolate, subject, regexp, last_match_info);
   3265     }
   3266   }
   3267 
   3268   return StringReplaceRegExpWithString(isolate,
   3269                                        subject,
   3270                                        regexp,
   3271                                        replacement,
   3272                                        last_match_info);
   3273 }
   3274 
   3275 
   3276 Handle<String> Runtime::StringReplaceOneCharWithString(Isolate* isolate,
   3277                                                        Handle<String> subject,
   3278                                                        Handle<String> search,
   3279                                                        Handle<String> replace,
   3280                                                        bool* found,
   3281                                                        int recursion_limit) {
   3282   if (recursion_limit == 0) return Handle<String>::null();
   3283   if (subject->IsConsString()) {
   3284     ConsString* cons = ConsString::cast(*subject);
   3285     Handle<String> first = Handle<String>(cons->first());
   3286     Handle<String> second = Handle<String>(cons->second());
   3287     Handle<String> new_first =
   3288         StringReplaceOneCharWithString(isolate,
   3289                                        first,
   3290                                        search,
   3291                                        replace,
   3292                                        found,
   3293                                        recursion_limit - 1);
   3294     if (*found) return isolate->factory()->NewConsString(new_first, second);
   3295     if (new_first.is_null()) return new_first;
   3296 
   3297     Handle<String> new_second =
   3298         StringReplaceOneCharWithString(isolate,
   3299                                        second,
   3300                                        search,
   3301                                        replace,
   3302                                        found,
   3303                                        recursion_limit - 1);
   3304     if (*found) return isolate->factory()->NewConsString(first, new_second);
   3305     if (new_second.is_null()) return new_second;
   3306 
   3307     return subject;
   3308   } else {
   3309     int index = StringMatch(isolate, subject, search, 0);
   3310     if (index == -1) return subject;
   3311     *found = true;
   3312     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
   3313     Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
   3314     Handle<String> second =
   3315         isolate->factory()->NewSubString(subject, index + 1, subject->length());
   3316     return isolate->factory()->NewConsString(cons1, second);
   3317   }
   3318 }
   3319 
   3320 
   3321 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
   3322   ASSERT(args.length() == 3);
   3323   HandleScope scope(isolate);
   3324   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   3325   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
   3326   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
   3327 
   3328   // If the cons string tree is too deep, we simply abort the recursion and
   3329   // retry with a flattened subject string.
   3330   const int kRecursionLimit = 0x1000;
   3331   bool found = false;
   3332   Handle<String> result =
   3333       Runtime::StringReplaceOneCharWithString(isolate,
   3334                                               subject,
   3335                                               search,
   3336                                               replace,
   3337                                               &found,
   3338                                               kRecursionLimit);
   3339   if (!result.is_null()) return *result;
   3340   return *Runtime::StringReplaceOneCharWithString(isolate,
   3341                                                   FlattenGetString(subject),
   3342                                                   search,
   3343                                                   replace,
   3344                                                   &found,
   3345                                                   kRecursionLimit);
   3346 }
   3347 
   3348 
   3349 // Perform string match of pattern on subject, starting at start index.
   3350 // Caller must ensure that 0 <= start_index <= sub->length(),
   3351 // and should check that pat->length() + start_index <= sub->length().
   3352 int Runtime::StringMatch(Isolate* isolate,
   3353                          Handle<String> sub,
   3354                          Handle<String> pat,
   3355                          int start_index) {
   3356   ASSERT(0 <= start_index);
   3357   ASSERT(start_index <= sub->length());
   3358 
   3359   int pattern_length = pat->length();
   3360   if (pattern_length == 0) return start_index;
   3361 
   3362   int subject_length = sub->length();
   3363   if (start_index + pattern_length > subject_length) return -1;
   3364 
   3365   if (!sub->IsFlat()) FlattenString(sub);
   3366   if (!pat->IsFlat()) FlattenString(pat);
   3367 
   3368   AssertNoAllocation no_heap_allocation;  // ensure vectors stay valid
   3369   // Extract flattened substrings of cons strings before determining asciiness.
   3370   String::FlatContent seq_sub = sub->GetFlatContent();
   3371   String::FlatContent seq_pat = pat->GetFlatContent();
   3372 
   3373   // dispatch on type of strings
   3374   if (seq_pat.IsAscii()) {
   3375     Vector<const char> pat_vector = seq_pat.ToAsciiVector();
   3376     if (seq_sub.IsAscii()) {
   3377       return SearchString(isolate,
   3378                           seq_sub.ToAsciiVector(),
   3379                           pat_vector,
   3380                           start_index);
   3381     }
   3382     return SearchString(isolate,
   3383                         seq_sub.ToUC16Vector(),
   3384                         pat_vector,
   3385                         start_index);
   3386   }
   3387   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
   3388   if (seq_sub.IsAscii()) {
   3389     return SearchString(isolate,
   3390                         seq_sub.ToAsciiVector(),
   3391                         pat_vector,
   3392                         start_index);
   3393   }
   3394   return SearchString(isolate,
   3395                       seq_sub.ToUC16Vector(),
   3396                       pat_vector,
   3397                       start_index);
   3398 }
   3399 
   3400 
   3401 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) {
   3402   HandleScope scope(isolate);  // create a new handle scope
   3403   ASSERT(args.length() == 3);
   3404 
   3405   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   3406   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   3407 
   3408   Object* index = args[2];
   3409   uint32_t start_index;
   3410   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   3411 
   3412   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
   3413   int position =
   3414       Runtime::StringMatch(isolate, sub, pat, start_index);
   3415   return Smi::FromInt(position);
   3416 }
   3417 
   3418 
   3419 template <typename schar, typename pchar>
   3420 static int StringMatchBackwards(Vector<const schar> subject,
   3421                                 Vector<const pchar> pattern,
   3422                                 int idx) {
   3423   int pattern_length = pattern.length();
   3424   ASSERT(pattern_length >= 1);
   3425   ASSERT(idx + pattern_length <= subject.length());
   3426 
   3427   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
   3428     for (int i = 0; i < pattern_length; i++) {
   3429       uc16 c = pattern[i];
   3430       if (c > String::kMaxAsciiCharCode) {
   3431         return -1;
   3432       }
   3433     }
   3434   }
   3435 
   3436   pchar pattern_first_char = pattern[0];
   3437   for (int i = idx; i >= 0; i--) {
   3438     if (subject[i] != pattern_first_char) continue;
   3439     int j = 1;
   3440     while (j < pattern_length) {
   3441       if (pattern[j] != subject[i+j]) {
   3442         break;
   3443       }
   3444       j++;
   3445     }
   3446     if (j == pattern_length) {
   3447       return i;
   3448     }
   3449   }
   3450   return -1;
   3451 }
   3452 
   3453 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
   3454   HandleScope scope(isolate);  // create a new handle scope
   3455   ASSERT(args.length() == 3);
   3456 
   3457   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
   3458   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
   3459 
   3460   Object* index = args[2];
   3461   uint32_t start_index;
   3462   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
   3463 
   3464   uint32_t pat_length = pat->length();
   3465   uint32_t sub_length = sub->length();
   3466 
   3467   if (start_index + pat_length > sub_length) {
   3468     start_index = sub_length - pat_length;
   3469   }
   3470 
   3471   if (pat_length == 0) {
   3472     return Smi::FromInt(start_index);
   3473   }
   3474 
   3475   if (!sub->IsFlat()) FlattenString(sub);
   3476   if (!pat->IsFlat()) FlattenString(pat);
   3477 
   3478   int position = -1;
   3479   AssertNoAllocation no_heap_allocation;  // ensure vectors stay valid
   3480 
   3481   String::FlatContent sub_content = sub->GetFlatContent();
   3482   String::FlatContent pat_content = pat->GetFlatContent();
   3483 
   3484   if (pat_content.IsAscii()) {
   3485     Vector<const char> pat_vector = pat_content.ToAsciiVector();
   3486     if (sub_content.IsAscii()) {
   3487       position = StringMatchBackwards(sub_content.ToAsciiVector(),
   3488                                       pat_vector,
   3489                                       start_index);
   3490     } else {
   3491       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   3492                                       pat_vector,
   3493                                       start_index);
   3494     }
   3495   } else {
   3496     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
   3497     if (sub_content.IsAscii()) {
   3498       position = StringMatchBackwards(sub_content.ToAsciiVector(),
   3499                                       pat_vector,
   3500                                       start_index);
   3501     } else {
   3502       position = StringMatchBackwards(sub_content.ToUC16Vector(),
   3503                                       pat_vector,
   3504                                       start_index);
   3505     }
   3506   }
   3507 
   3508   return Smi::FromInt(position);
   3509 }
   3510 
   3511 
   3512 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
   3513   NoHandleAllocation ha;
   3514   ASSERT(args.length() == 2);
   3515 
   3516   CONVERT_ARG_CHECKED(String, str1, 0);
   3517   CONVERT_ARG_CHECKED(String, str2, 1);
   3518 
   3519   if (str1 == str2) return Smi::FromInt(0);  // Equal.
   3520   int str1_length = str1->length();
   3521   int str2_length = str2->length();
   3522 
   3523   // Decide trivial cases without flattening.
   3524   if (str1_length == 0) {
   3525     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
   3526     return Smi::FromInt(-str2_length);
   3527   } else {
   3528     if (str2_length == 0) return Smi::FromInt(str1_length);
   3529   }
   3530 
   3531   int end = str1_length < str2_length ? str1_length : str2_length;
   3532 
   3533   // No need to flatten if we are going to find the answer on the first
   3534   // character.  At this point we know there is at least one character
   3535   // in each string, due to the trivial case handling above.
   3536   int d = str1->Get(0) - str2->Get(0);
   3537   if (d != 0) return Smi::FromInt(d);
   3538 
   3539   str1->TryFlatten();
   3540   str2->TryFlatten();
   3541 
   3542   StringInputBuffer& buf1 =
   3543       *isolate->runtime_state()->string_locale_compare_buf1();
   3544   StringInputBuffer& buf2 =
   3545       *isolate->runtime_state()->string_locale_compare_buf2();
   3546 
   3547   buf1.Reset(str1);
   3548   buf2.Reset(str2);
   3549 
   3550   for (int i = 0; i < end; i++) {
   3551     uint16_t char1 = buf1.GetNext();
   3552     uint16_t char2 = buf2.GetNext();
   3553     if (char1 != char2) return Smi::FromInt(char1 - char2);
   3554   }
   3555 
   3556   return Smi::FromInt(str1_length - str2_length);
   3557 }
   3558 
   3559 
   3560 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
   3561   NoHandleAllocation ha;
   3562   ASSERT(args.length() == 3);
   3563 
   3564   CONVERT_ARG_CHECKED(String, value, 0);
   3565   int start, end;
   3566   // We have a fast integer-only case here to avoid a conversion to double in
   3567   // the common case where from and to are Smis.
   3568   if (args[1]->IsSmi() && args[2]->IsSmi()) {
   3569     CONVERT_SMI_ARG_CHECKED(from_number, 1);
   3570     CONVERT_SMI_ARG_CHECKED(to_number, 2);
   3571     start = from_number;
   3572     end = to_number;
   3573   } else {
   3574     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
   3575     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
   3576     start = FastD2I(from_number);
   3577     end = FastD2I(to_number);
   3578   }
   3579   RUNTIME_ASSERT(end >= start);
   3580   RUNTIME_ASSERT(start >= 0);
   3581   RUNTIME_ASSERT(end <= value->length());
   3582   isolate->counters()->sub_string_runtime()->Increment();
   3583   return value->SubString(start, end);
   3584 }
   3585 
   3586 
   3587 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
   3588   ASSERT_EQ(3, args.length());
   3589 
   3590   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   3591   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
   3592   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
   3593   HandleScope handles;
   3594 
   3595   Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info);
   3596 
   3597   if (match.is_null()) {
   3598     return Failure::Exception();
   3599   }
   3600   if (match->IsNull()) {
   3601     return isolate->heap()->null_value();
   3602   }
   3603   int length = subject->length();
   3604 
   3605   ZoneScope zone_space(isolate, DELETE_ON_EXIT);
   3606   ZoneList<int> offsets(8);
   3607   int start;
   3608   int end;
   3609   do {
   3610     {
   3611       AssertNoAllocation no_alloc;
   3612       FixedArray* elements = FixedArray::cast(regexp_info->elements());
   3613       start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value();
   3614       end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value();
   3615     }
   3616     offsets.Add(start);
   3617     offsets.Add(end);
   3618     if (start == end) if (++end > length) break;
   3619     match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
   3620     if (match.is_null()) {
   3621       return Failure::Exception();
   3622     }
   3623   } while (!match->IsNull());
   3624   int matches = offsets.length() / 2;
   3625   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
   3626   Handle<String> substring = isolate->factory()->
   3627     NewSubString(subject, offsets.at(0), offsets.at(1));
   3628   elements->set(0, *substring);
   3629   for (int i = 1; i < matches ; i++) {
   3630     int from = offsets.at(i * 2);
   3631     int to = offsets.at(i * 2 + 1);
   3632     Handle<String> substring = isolate->factory()->
   3633         NewProperSubString(subject, from, to);
   3634     elements->set(i, *substring);
   3635   }
   3636   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
   3637   result->set_length(Smi::FromInt(matches));
   3638   return *result;
   3639 }
   3640 
   3641 
   3642 // Two smis before and after the match, for very long strings.
   3643 const int kMaxBuilderEntriesPerRegExpMatch = 5;
   3644 
   3645 
   3646 static void SetLastMatchInfoNoCaptures(Handle<String> subject,
   3647                                        Handle<JSArray> last_match_info,
   3648                                        int match_start,
   3649                                        int match_end) {
   3650   // Fill last_match_info with a single capture.
   3651   last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead);
   3652   AssertNoAllocation no_gc;
   3653   FixedArray* elements = FixedArray::cast(last_match_info->elements());
   3654   RegExpImpl::SetLastCaptureCount(elements, 2);
   3655   RegExpImpl::SetLastInput(elements, *subject);
   3656   RegExpImpl::SetLastSubject(elements, *subject);
   3657   RegExpImpl::SetCapture(elements, 0, match_start);
   3658   RegExpImpl::SetCapture(elements, 1, match_end);
   3659 }
   3660 
   3661 
   3662 template <typename SubjectChar, typename PatternChar>
   3663 static bool SearchStringMultiple(Isolate* isolate,
   3664                                  Vector<const SubjectChar> subject,
   3665                                  Vector<const PatternChar> pattern,
   3666                                  String* pattern_string,
   3667                                  FixedArrayBuilder* builder,
   3668                                  int* match_pos) {
   3669   int pos = *match_pos;
   3670   int subject_length = subject.length();
   3671   int pattern_length = pattern.length();
   3672   int max_search_start = subject_length - pattern_length;
   3673   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   3674   while (pos <= max_search_start) {
   3675     if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
   3676       *match_pos = pos;
   3677       return false;
   3678     }
   3679     // Position of end of previous match.
   3680     int match_end = pos + pattern_length;
   3681     int new_pos = search.Search(subject, match_end);
   3682     if (new_pos >= 0) {
   3683       // A match.
   3684       if (new_pos > match_end) {
   3685         ReplacementStringBuilder::AddSubjectSlice(builder,
   3686             match_end,
   3687             new_pos);
   3688       }
   3689       pos = new_pos;
   3690       builder->Add(pattern_string);
   3691     } else {
   3692       break;
   3693     }
   3694   }
   3695 
   3696   if (pos < max_search_start) {
   3697     ReplacementStringBuilder::AddSubjectSlice(builder,
   3698                                               pos + pattern_length,
   3699                                               subject_length);
   3700   }
   3701   *match_pos = pos;
   3702   return true;
   3703 }
   3704 
   3705 
   3706 static bool SearchStringMultiple(Isolate* isolate,
   3707                                  Handle<String> subject,
   3708                                  Handle<String> pattern,
   3709                                  Handle<JSArray> last_match_info,
   3710                                  FixedArrayBuilder* builder) {
   3711   ASSERT(subject->IsFlat());
   3712   ASSERT(pattern->IsFlat());
   3713 
   3714   // Treating as if a previous match was before first character.
   3715   int match_pos = -pattern->length();
   3716 
   3717   for (;;) {  // Break when search complete.
   3718     builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   3719     AssertNoAllocation no_gc;
   3720     String::FlatContent subject_content = subject->GetFlatContent();
   3721     String::FlatContent pattern_content = pattern->GetFlatContent();
   3722     if (subject_content.IsAscii()) {
   3723       Vector<const char> subject_vector = subject_content.ToAsciiVector();
   3724       if (pattern_content.IsAscii()) {
   3725         if (SearchStringMultiple(isolate,
   3726                                  subject_vector,
   3727                                  pattern_content.ToAsciiVector(),
   3728                                  *pattern,
   3729                                  builder,
   3730                                  &match_pos)) break;
   3731       } else {
   3732         if (SearchStringMultiple(isolate,
   3733                                  subject_vector,
   3734                                  pattern_content.ToUC16Vector(),
   3735                                  *pattern,
   3736                                  builder,
   3737                                  &match_pos)) break;
   3738       }
   3739     } else {
   3740       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
   3741       if (pattern_content.IsAscii()) {
   3742         if (SearchStringMultiple(isolate,
   3743                                  subject_vector,
   3744                                  pattern_content.ToAsciiVector(),
   3745                                  *pattern,
   3746                                  builder,
   3747                                  &match_pos)) break;
   3748       } else {
   3749         if (SearchStringMultiple(isolate,
   3750                                  subject_vector,
   3751                                  pattern_content.ToUC16Vector(),
   3752                                  *pattern,
   3753                                  builder,
   3754                                  &match_pos)) break;
   3755       }
   3756     }
   3757   }
   3758 
   3759   if (match_pos >= 0) {
   3760     SetLastMatchInfoNoCaptures(subject,
   3761                                last_match_info,
   3762                                match_pos,
   3763                                match_pos + pattern->length());
   3764     return true;
   3765   }
   3766   return false;  // No matches at all.
   3767 }
   3768 
   3769 
   3770 static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
   3771     Isolate* isolate,
   3772     Handle<String> subject,
   3773     Handle<JSRegExp> regexp,
   3774     Handle<JSArray> last_match_array,
   3775     FixedArrayBuilder* builder) {
   3776   ASSERT(subject->IsFlat());
   3777   int match_start = -1;
   3778   int match_end = 0;
   3779   int pos = 0;
   3780   int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
   3781   if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
   3782 
   3783   OffsetsVector registers(required_registers, isolate);
   3784   Vector<int32_t> register_vector(registers.vector(), registers.length());
   3785   int subject_length = subject->length();
   3786   bool first = true;
   3787 
   3788   for (;;) {  // Break on failure, return on exception.
   3789     RegExpImpl::IrregexpResult result =
   3790         RegExpImpl::IrregexpExecOnce(regexp,
   3791                                      subject,
   3792                                      pos,
   3793                                      register_vector);
   3794     if (result == RegExpImpl::RE_SUCCESS) {
   3795       match_start = register_vector[0];
   3796       builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   3797       if (match_end < match_start) {
   3798         ReplacementStringBuilder::AddSubjectSlice(builder,
   3799                                                   match_end,
   3800                                                   match_start);
   3801       }
   3802       match_end = register_vector[1];
   3803       HandleScope loop_scope(isolate);
   3804       if (!first) {
   3805         builder->Add(*isolate->factory()->NewProperSubString(subject,
   3806                                                              match_start,
   3807                                                              match_end));
   3808       } else {
   3809         builder->Add(*isolate->factory()->NewSubString(subject,
   3810                                                        match_start,
   3811                                                        match_end));
   3812       }
   3813       if (match_start != match_end) {
   3814         pos = match_end;
   3815       } else {
   3816         pos = match_end + 1;
   3817         if (pos > subject_length) break;
   3818       }
   3819     } else if (result == RegExpImpl::RE_FAILURE) {
   3820       break;
   3821     } else {
   3822       ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
   3823       return result;
   3824     }
   3825     first = false;
   3826   }
   3827 
   3828   if (match_start >= 0) {
   3829     if (match_end < subject_length) {
   3830       ReplacementStringBuilder::AddSubjectSlice(builder,
   3831                                                 match_end,
   3832                                                 subject_length);
   3833     }
   3834     SetLastMatchInfoNoCaptures(subject,
   3835                                last_match_array,
   3836                                match_start,
   3837                                match_end);
   3838     return RegExpImpl::RE_SUCCESS;
   3839   } else {
   3840     return RegExpImpl::RE_FAILURE;  // No matches at all.
   3841   }
   3842 }
   3843 
   3844 
   3845 static RegExpImpl::IrregexpResult SearchRegExpMultiple(
   3846     Isolate* isolate,
   3847     Handle<String> subject,
   3848     Handle<JSRegExp> regexp,
   3849     Handle<JSArray> last_match_array,
   3850     FixedArrayBuilder* builder) {
   3851 
   3852   ASSERT(subject->IsFlat());
   3853   int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
   3854   if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
   3855 
   3856   OffsetsVector registers(required_registers, isolate);
   3857   Vector<int32_t> register_vector(registers.vector(), registers.length());
   3858 
   3859   RegExpImpl::IrregexpResult result =
   3860       RegExpImpl::IrregexpExecOnce(regexp,
   3861                                    subject,
   3862                                    0,
   3863                                    register_vector);
   3864 
   3865   int capture_count = regexp->CaptureCount();
   3866   int subject_length = subject->length();
   3867 
   3868   // Position to search from.
   3869   int pos = 0;
   3870   // End of previous match. Differs from pos if match was empty.
   3871   int match_end = 0;
   3872   if (result == RegExpImpl::RE_SUCCESS) {
   3873     // Need to keep a copy of the previous match for creating last_match_info
   3874     // at the end, so we have two vectors that we swap between.
   3875     OffsetsVector registers2(required_registers, isolate);
   3876     Vector<int> prev_register_vector(registers2.vector(), registers2.length());
   3877     bool first = true;
   3878     do {
   3879       int match_start = register_vector[0];
   3880       builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
   3881       if (match_end < match_start) {
   3882         ReplacementStringBuilder::AddSubjectSlice(builder,
   3883                                                   match_end,
   3884                                                   match_start);
   3885       }
   3886       match_end = register_vector[1];
   3887 
   3888       {
   3889         // Avoid accumulating new handles inside loop.
   3890         HandleScope temp_scope(isolate);
   3891         // Arguments array to replace function is match, captures, index and
   3892         // subject, i.e., 3 + capture count in total.
   3893         Handle<FixedArray> elements =
   3894             isolate->factory()->NewFixedArray(3 + capture_count);
   3895         Handle<String> match;
   3896         if (!first) {
   3897           match = isolate->factory()->NewProperSubString(subject,
   3898                                                          match_start,
   3899                                                          match_end);
   3900         } else {
   3901           match = isolate->factory()->NewSubString(subject,
   3902                                                    match_start,
   3903                                                    match_end);
   3904         }
   3905         elements->set(0, *match);
   3906         for (int i = 1; i <= capture_count; i++) {
   3907           int start = register_vector[i * 2];
   3908           if (start >= 0) {
   3909             int end = register_vector[i * 2 + 1];
   3910             ASSERT(start <= end);
   3911             Handle<String> substring;
   3912             if (!first) {
   3913               substring = isolate->factory()->NewProperSubString(subject,
   3914                                                                  start,
   3915                                                                  end);
   3916             } else {
   3917               substring = isolate->factory()->NewSubString(subject, start, end);
   3918             }
   3919             elements->set(i, *substring);
   3920           } else {
   3921             ASSERT(register_vector[i * 2 + 1] < 0);
   3922             elements->set(i, isolate->heap()->undefined_value());
   3923           }
   3924         }
   3925         elements->set(capture_count + 1, Smi::FromInt(match_start));
   3926         elements->set(capture_count + 2, *subject);
   3927         builder->Add(*isolate->factory()->NewJSArrayWithElements(elements));
   3928       }
   3929       // Swap register vectors, so the last successful match is in
   3930       // prev_register_vector.
   3931       Vector<int32_t> tmp = prev_register_vector;
   3932       prev_register_vector = register_vector;
   3933       register_vector = tmp;
   3934 
   3935       if (match_end > match_start) {
   3936         pos = match_end;
   3937       } else {
   3938         pos = match_end + 1;
   3939         if (pos > subject_length) {
   3940           break;
   3941         }
   3942       }
   3943 
   3944       result = RegExpImpl::IrregexpExecOnce(regexp,
   3945                                             subject,
   3946                                             pos,
   3947                                             register_vector);
   3948       first = false;
   3949     } while (result == RegExpImpl::RE_SUCCESS);
   3950 
   3951     if (result != RegExpImpl::RE_EXCEPTION) {
   3952       // Finished matching, with at least one match.
   3953       if (match_end < subject_length) {
   3954         ReplacementStringBuilder::AddSubjectSlice(builder,
   3955                                                   match_end,
   3956                                                   subject_length);
   3957       }
   3958 
   3959       int last_match_capture_count = (capture_count + 1) * 2;
   3960       int last_match_array_size =
   3961           last_match_capture_count + RegExpImpl::kLastMatchOverhead;
   3962       last_match_array->EnsureSize(last_match_array_size);
   3963       AssertNoAllocation no_gc;
   3964       FixedArray* elements = FixedArray::cast(last_match_array->elements());
   3965       RegExpImpl::SetLastCaptureCount(elements, last_match_capture_count);
   3966       RegExpImpl::SetLastSubject(elements, *subject);
   3967       RegExpImpl::SetLastInput(elements, *subject);
   3968       for (int i = 0; i < last_match_capture_count; i++) {
   3969         RegExpImpl::SetCapture(elements, i, prev_register_vector[i]);
   3970       }
   3971       return RegExpImpl::RE_SUCCESS;
   3972     }
   3973   }
   3974   // No matches at all, return failure or exception result directly.
   3975   return result;
   3976 }
   3977 
   3978 
   3979 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
   3980   ASSERT(args.length() == 4);
   3981   HandleScope handles(isolate);
   3982 
   3983   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
   3984   if (!subject->IsFlat()) FlattenString(subject);
   3985   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
   3986   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
   3987   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
   3988 
   3989   ASSERT(last_match_info->HasFastElements());
   3990   ASSERT(regexp->GetFlags().is_global());
   3991   Handle<FixedArray> result_elements;
   3992   if (result_array->HasFastElements()) {
   3993     result_elements =
   3994         Handle<FixedArray>(FixedArray::cast(result_array->elements()));
   3995   }
   3996   if (result_elements.is_null() || result_elements->length() < 16) {
   3997     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   3998   }
   3999   FixedArrayBuilder builder(result_elements);
   4000 
   4001   if (regexp->TypeTag() == JSRegExp::ATOM) {
   4002     Handle<String> pattern(
   4003         String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
   4004     ASSERT(pattern->IsFlat());
   4005     if (SearchStringMultiple(isolate, subject, pattern,
   4006                              last_match_info, &builder)) {
   4007       return *builder.ToJSArray(result_array);
   4008     }
   4009     return isolate->heap()->null_value();
   4010   }
   4011 
   4012   ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
   4013 
   4014   RegExpImpl::IrregexpResult result;
   4015   if (regexp->CaptureCount() == 0) {
   4016     result = SearchRegExpNoCaptureMultiple(isolate,
   4017                                            subject,
   4018                                            regexp,
   4019                                            last_match_info,
   4020                                            &builder);
   4021   } else {
   4022     result = SearchRegExpMultiple(isolate,
   4023                                   subject,
   4024                                   regexp,
   4025                                   last_match_info,
   4026                                   &builder);
   4027   }
   4028   if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
   4029   if (result == RegExpImpl::RE_FAILURE) return isolate->heap()->null_value();
   4030   ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
   4031   return Failure::Exception();
   4032 }
   4033 
   4034 
   4035 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
   4036   NoHandleAllocation ha;
   4037   ASSERT(args.length() == 2);
   4038   CONVERT_SMI_ARG_CHECKED(radix, 1);
   4039   RUNTIME_ASSERT(2 <= radix && radix <= 36);
   4040 
   4041   // Fast case where the result is a one character string.
   4042   if (args[0]->IsSmi()) {
   4043     int value = args.smi_at(0);
   4044     if (value >= 0 && value < radix) {
   4045       // Character array used for conversion.
   4046       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   4047       return isolate->heap()->
   4048           LookupSingleCharacterStringFromCode(kCharTable[value]);
   4049     }
   4050   }
   4051 
   4052   // Slow case.
   4053   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4054   if (isnan(value)) {
   4055     return *isolate->factory()->nan_symbol();
   4056   }
   4057   if (isinf(value)) {
   4058     if (value < 0) {
   4059       return *isolate->factory()->minus_infinity_symbol();
   4060     }
   4061     return *isolate->factory()->infinity_symbol();
   4062   }
   4063   char* str = DoubleToRadixCString(value, radix);
   4064   MaybeObject* result =
   4065       isolate->heap()->AllocateStringFromAscii(CStrVector(str));
   4066   DeleteArray(str);
   4067   return result;
   4068 }
   4069 
   4070 
   4071 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
   4072   NoHandleAllocation ha;
   4073   ASSERT(args.length() == 2);
   4074 
   4075   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4076   if (isnan(value)) {
   4077     return *isolate->factory()->nan_symbol();
   4078   }
   4079   if (isinf(value)) {
   4080     if (value < 0) {
   4081       return *isolate->factory()->minus_infinity_symbol();
   4082     }
   4083     return *isolate->factory()->infinity_symbol();
   4084   }
   4085   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4086   int f = FastD2I(f_number);
   4087   RUNTIME_ASSERT(f >= 0);
   4088   char* str = DoubleToFixedCString(value, f);
   4089   MaybeObject* res =
   4090       isolate->heap()->AllocateStringFromAscii(CStrVector(str));
   4091   DeleteArray(str);
   4092   return res;
   4093 }
   4094 
   4095 
   4096 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
   4097   NoHandleAllocation ha;
   4098   ASSERT(args.length() == 2);
   4099 
   4100   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4101   if (isnan(value)) {
   4102     return *isolate->factory()->nan_symbol();
   4103   }
   4104   if (isinf(value)) {
   4105     if (value < 0) {
   4106       return *isolate->factory()->minus_infinity_symbol();
   4107     }
   4108     return *isolate->factory()->infinity_symbol();
   4109   }
   4110   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4111   int f = FastD2I(f_number);
   4112   RUNTIME_ASSERT(f >= -1 && f <= 20);
   4113   char* str = DoubleToExponentialCString(value, f);
   4114   MaybeObject* res =
   4115       isolate->heap()->AllocateStringFromAscii(CStrVector(str));
   4116   DeleteArray(str);
   4117   return res;
   4118 }
   4119 
   4120 
   4121 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
   4122   NoHandleAllocation ha;
   4123   ASSERT(args.length() == 2);
   4124 
   4125   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   4126   if (isnan(value)) {
   4127     return *isolate->factory()->nan_symbol();
   4128   }
   4129   if (isinf(value)) {
   4130     if (value < 0) {
   4131       return *isolate->factory()->minus_infinity_symbol();
   4132     }
   4133     return *isolate->factory()->infinity_symbol();
   4134   }
   4135   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   4136   int f = FastD2I(f_number);
   4137   RUNTIME_ASSERT(f >= 1 && f <= 21);
   4138   char* str = DoubleToPrecisionCString(value, f);
   4139   MaybeObject* res =
   4140       isolate->heap()->AllocateStringFromAscii(CStrVector(str));
   4141   DeleteArray(str);
   4142   return res;
   4143 }
   4144 
   4145 
   4146 // Returns a single character string where first character equals
   4147 // string->Get(index).
   4148 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
   4149   if (index < static_cast<uint32_t>(string->length())) {
   4150     string->TryFlatten();
   4151     return LookupSingleCharacterStringFromCode(
   4152         string->Get(index));
   4153   }
   4154   return Execution::CharAt(string, index);
   4155 }
   4156 
   4157 
   4158 MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
   4159                                          Handle<Object> object,
   4160                                          uint32_t index) {
   4161   // Handle [] indexing on Strings
   4162   if (object->IsString()) {
   4163     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
   4164     if (!result->IsUndefined()) return *result;
   4165   }
   4166 
   4167   // Handle [] indexing on String objects
   4168   if (object->IsStringObjectWithCharacterAt(index)) {
   4169     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
   4170     Handle<Object> result =
   4171         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
   4172     if (!result->IsUndefined()) return *result;
   4173   }
   4174 
   4175   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
   4176     return object->GetPrototype()->GetElement(index);
   4177   }
   4178 
   4179   return object->GetElement(index);
   4180 }
   4181 
   4182 
   4183 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
   4184                                         Handle<Object> object,
   4185                                         Handle<Object> key) {
   4186   HandleScope scope(isolate);
   4187 
   4188   if (object->IsUndefined() || object->IsNull()) {
   4189     Handle<Object> args[2] = { key, object };
   4190     Handle<Object> error =
   4191         isolate->factory()->NewTypeError("non_object_property_load",
   4192                                          HandleVector(args, 2));
   4193     return isolate->Throw(*error);
   4194   }
   4195 
   4196   // Check if the given key is an array index.
   4197   uint32_t index;
   4198   if (key->ToArrayIndex(&index)) {
   4199     return GetElementOrCharAt(isolate, object, index);
   4200   }
   4201 
   4202   // Convert the key to a string - possibly by calling back into JavaScript.
   4203   Handle<String> name;
   4204   if (key->IsString()) {
   4205     name = Handle<String>::cast(key);
   4206   } else {
   4207     bool has_pending_exception = false;
   4208     Handle<Object> converted =
   4209         Execution::ToString(key, &has_pending_exception);
   4210     if (has_pending_exception) return Failure::Exception();
   4211     name = Handle<String>::cast(converted);
   4212   }
   4213 
   4214   // Check if the name is trivially convertible to an index and get
   4215   // the element if so.
   4216   if (name->AsArrayIndex(&index)) {
   4217     return GetElementOrCharAt(isolate, object, index);
   4218   } else {
   4219     return object->GetProperty(*name);
   4220   }
   4221 }
   4222 
   4223 
   4224 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
   4225   NoHandleAllocation ha;
   4226   ASSERT(args.length() == 2);
   4227 
   4228   Handle<Object> object = args.at<Object>(0);
   4229   Handle<Object> key = args.at<Object>(1);
   4230 
   4231   return Runtime::GetObjectProperty(isolate, object, key);
   4232 }
   4233 
   4234 
   4235 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric.
   4236 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
   4237   NoHandleAllocation ha;
   4238   ASSERT(args.length() == 2);
   4239 
   4240   // Fast cases for getting named properties of the receiver JSObject
   4241   // itself.
   4242   //
   4243   // The global proxy objects has to be excluded since LocalLookup on
   4244   // the global proxy object can return a valid result even though the
   4245   // global proxy object never has properties.  This is the case
   4246   // because the global proxy object forwards everything to its hidden
   4247   // prototype including local lookups.
   4248   //
   4249   // Additionally, we need to make sure that we do not cache results
   4250   // for objects that require access checks.
   4251   if (args[0]->IsJSObject()) {
   4252     if (!args[0]->IsJSGlobalProxy() &&
   4253         !args[0]->IsAccessCheckNeeded() &&
   4254         args[1]->IsString()) {
   4255       JSObject* receiver = JSObject::cast(args[0]);
   4256       String* key = String::cast(args[1]);
   4257       if (receiver->HasFastProperties()) {
   4258         // Attempt to use lookup cache.
   4259         Map* receiver_map = receiver->map();
   4260         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
   4261         int offset = keyed_lookup_cache->Lookup(receiver_map, key);
   4262         if (offset != -1) {
   4263           Object* value = receiver->FastPropertyAt(offset);
   4264           return value->IsTheHole()
   4265               ? isolate->heap()->undefined_value()
   4266               : value;
   4267         }
   4268         // Lookup cache miss.  Perform lookup and update the cache if
   4269         // appropriate.
   4270         LookupResult result(isolate);
   4271         receiver->LocalLookup(key, &result);
   4272         if (result.IsFound() && result.type() == FIELD) {
   4273           int offset = result.GetFieldIndex();
   4274           keyed_lookup_cache->Update(receiver_map, key, offset);
   4275           return receiver->FastPropertyAt(offset);
   4276         }
   4277       } else {
   4278         // Attempt dictionary lookup.
   4279         StringDictionary* dictionary = receiver->property_dictionary();
   4280         int entry = dictionary->FindEntry(key);
   4281         if ((entry != StringDictionary::kNotFound) &&
   4282             (dictionary->DetailsAt(entry).type() == NORMAL)) {
   4283           Object* value = dictionary->ValueAt(entry);
   4284           if (!receiver->IsGlobalObject()) return value;
   4285           value = JSGlobalPropertyCell::cast(value)->value();
   4286           if (!value->IsTheHole()) return value;
   4287           // If value is the hole do the general lookup.
   4288         }
   4289       }
   4290     } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
   4291       // JSObject without a string key. If the key is a Smi, check for a
   4292       // definite out-of-bounds access to elements, which is a strong indicator
   4293       // that subsequent accesses will also call the runtime. Proactively
   4294       // transition elements to FAST_ELEMENTS to avoid excessive boxing of
   4295       // doubles for those future calls in the case that the elements would
   4296       // become FAST_DOUBLE_ELEMENTS.
   4297       Handle<JSObject> js_object(args.at<JSObject>(0));
   4298       ElementsKind elements_kind = js_object->GetElementsKind();
   4299       if (elements_kind == FAST_SMI_ONLY_ELEMENTS ||
   4300           elements_kind == FAST_DOUBLE_ELEMENTS) {
   4301         FixedArrayBase* elements = js_object->elements();
   4302         if (args.at<Smi>(1)->value() >= elements->length()) {
   4303           MaybeObject* maybe_object = TransitionElements(js_object,
   4304                                                          FAST_ELEMENTS,
   4305                                                          isolate);
   4306           if (maybe_object->IsFailure()) return maybe_object;
   4307         }
   4308       }
   4309     }
   4310   } else if (args[0]->IsString() && args[1]->IsSmi()) {
   4311     // Fast case for string indexing using [] with a smi index.
   4312     HandleScope scope(isolate);
   4313     Handle<String> str = args.at<String>(0);
   4314     int index = args.smi_at(1);
   4315     if (index >= 0 && index < str->length()) {
   4316       Handle<Object> result = GetCharAt(str, index);
   4317       return *result;
   4318     }
   4319   }
   4320 
   4321   // Fall back to GetObjectProperty.
   4322   return Runtime::GetObjectProperty(isolate,
   4323                                     args.at<Object>(0),
   4324                                     args.at<Object>(1));
   4325 }
   4326 
   4327 
   4328 static bool IsValidAccessor(Handle<Object> obj) {
   4329   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
   4330 }
   4331 
   4332 
   4333 // Implements part of 8.12.9 DefineOwnProperty.
   4334 // There are 3 cases that lead here:
   4335 // Step 4b - define a new accessor property.
   4336 // Steps 9c & 12 - replace an existing data property with an accessor property.
   4337 // Step 12 - update an existing accessor property with an accessor or generic
   4338 //           descriptor.
   4339 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
   4340   ASSERT(args.length() == 5);
   4341   HandleScope scope(isolate);
   4342   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   4343   RUNTIME_ASSERT(!obj->IsNull());
   4344   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   4345   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
   4346   RUNTIME_ASSERT(IsValidAccessor(getter));
   4347   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
   4348   RUNTIME_ASSERT(IsValidAccessor(setter));
   4349   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
   4350   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   4351   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   4352 
   4353   bool fast = obj->HasFastProperties();
   4354   JSObject::DefineAccessor(obj, name, getter, setter, attr);
   4355   if (fast) JSObject::TransformToFastProperties(obj, 0);
   4356   return isolate->heap()->undefined_value();
   4357 }
   4358 
   4359 // Implements part of 8.12.9 DefineOwnProperty.
   4360 // There are 3 cases that lead here:
   4361 // Step 4a - define a new data property.
   4362 // Steps 9b & 12 - replace an existing accessor property with a data property.
   4363 // Step 12 - update an existing data property with a data or generic
   4364 //           descriptor.
   4365 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
   4366   ASSERT(args.length() == 4);
   4367   HandleScope scope(isolate);
   4368   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
   4369   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   4370   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
   4371   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
   4372   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   4373   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
   4374 
   4375   LookupResult result(isolate);
   4376   js_object->LocalLookupRealNamedProperty(*name, &result);
   4377 
   4378   // Special case for callback properties.
   4379   if (result.IsFound() && result.type() == CALLBACKS) {
   4380     Object* callback = result.GetCallbackObject();
   4381     // To be compatible with Safari we do not change the value on API objects
   4382     // in Object.defineProperty(). Firefox disagrees here, and actually changes
   4383     // the value.
   4384     if (callback->IsAccessorInfo()) {
   4385       return isolate->heap()->undefined_value();
   4386     }
   4387     // Avoid redefining foreign callback as data property, just use the stored
   4388     // setter to update the value instead.
   4389     // TODO(mstarzinger): So far this only works if property attributes don't
   4390     // change, this should be fixed once we cleanup the underlying code.
   4391     if (callback->IsForeign() && result.GetAttributes() == attr) {
   4392       return js_object->SetPropertyWithCallback(callback,
   4393                                                 *name,
   4394                                                 *obj_value,
   4395                                                 result.holder(),
   4396                                                 kStrictMode);
   4397     }
   4398   }
   4399 
   4400   // Take special care when attributes are different and there is already
   4401   // a property. For simplicity we normalize the property which enables us
   4402   // to not worry about changing the instance_descriptor and creating a new
   4403   // map. The current version of SetObjectProperty does not handle attributes
   4404   // correctly in the case where a property is a field and is reset with
   4405   // new attributes.
   4406   if (result.IsProperty() &&
   4407       (attr != result.GetAttributes() || result.type() == CALLBACKS)) {
   4408     // New attributes - normalize to avoid writing to instance descriptor
   4409     if (js_object->IsJSGlobalProxy()) {
   4410       // Since the result is a property, the prototype will exist so
   4411       // we don't have to check for null.
   4412       js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
   4413     }
   4414     JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
   4415     // Use IgnoreAttributes version since a readonly property may be
   4416     // overridden and SetProperty does not allow this.
   4417     return js_object->SetLocalPropertyIgnoreAttributes(*name,
   4418                                                        *obj_value,
   4419                                                        attr);
   4420   }
   4421 
   4422   return Runtime::ForceSetObjectProperty(isolate,
   4423                                          js_object,
   4424                                          name,
   4425                                          obj_value,
   4426                                          attr);
   4427 }
   4428 
   4429 
   4430 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
   4431                                         Handle<Object> object,
   4432                                         Handle<Object> key,
   4433                                         Handle<Object> value,
   4434                                         PropertyAttributes attr,
   4435                                         StrictModeFlag strict_mode) {
   4436   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
   4437   HandleScope scope(isolate);
   4438 
   4439   if (object->IsUndefined() || object->IsNull()) {
   4440     Handle<Object> args[2] = { key, object };
   4441     Handle<Object> error =
   4442         isolate->factory()->NewTypeError("non_object_property_store",
   4443                                          HandleVector(args, 2));
   4444     return isolate->Throw(*error);
   4445   }
   4446 
   4447   if (object->IsJSProxy()) {
   4448     bool has_pending_exception = false;
   4449     Handle<Object> name = Execution::ToString(key, &has_pending_exception);
   4450     if (has_pending_exception) return Failure::Exception();
   4451     return JSProxy::cast(*object)->SetProperty(
   4452         String::cast(*name), *value, attr, strict_mode);
   4453   }
   4454 
   4455   // If the object isn't a JavaScript object, we ignore the store.
   4456   if (!object->IsJSObject()) return *value;
   4457 
   4458   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
   4459 
   4460   // Check if the given key is an array index.
   4461   uint32_t index;
   4462   if (key->ToArrayIndex(&index)) {
   4463     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   4464     // of a string using [] notation.  We need to support this too in
   4465     // JavaScript.
   4466     // In the case of a String object we just need to redirect the assignment to
   4467     // the underlying string if the index is in range.  Since the underlying
   4468     // string does nothing with the assignment then we can ignore such
   4469     // assignments.
   4470     if (js_object->IsStringObjectWithCharacterAt(index)) {
   4471       return *value;
   4472     }
   4473 
   4474     Handle<Object> result = JSObject::SetElement(
   4475         js_object, index, value, attr, strict_mode, set_mode);
   4476     if (result.is_null()) return Failure::Exception();
   4477     return *value;
   4478   }
   4479 
   4480   if (key->IsString()) {
   4481     Handle<Object> result;
   4482     if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
   4483       result = JSObject::SetElement(
   4484           js_object, index, value, attr, strict_mode, set_mode);
   4485     } else {
   4486       Handle<String> key_string = Handle<String>::cast(key);
   4487       key_string->TryFlatten();
   4488       result = JSReceiver::SetProperty(
   4489           js_object, key_string, value, attr, strict_mode);
   4490     }
   4491     if (result.is_null()) return Failure::Exception();
   4492     return *value;
   4493   }
   4494 
   4495   // Call-back into JavaScript to convert the key to a string.
   4496   bool has_pending_exception = false;
   4497   Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
   4498   if (has_pending_exception) return Failure::Exception();
   4499   Handle<String> name = Handle<String>::cast(converted);
   4500 
   4501   if (name->AsArrayIndex(&index)) {
   4502     return js_object->SetElement(
   4503         index, *value, attr, strict_mode, true, set_mode);
   4504   } else {
   4505     return js_object->SetProperty(*name, *value, attr, strict_mode);
   4506   }
   4507 }
   4508 
   4509 
   4510 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
   4511                                              Handle<JSObject> js_object,
   4512                                              Handle<Object> key,
   4513                                              Handle<Object> value,
   4514                                              PropertyAttributes attr) {
   4515   HandleScope scope(isolate);
   4516 
   4517   // Check if the given key is an array index.
   4518   uint32_t index;
   4519   if (key->ToArrayIndex(&index)) {
   4520     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
   4521     // of a string using [] notation.  We need to support this too in
   4522     // JavaScript.
   4523     // In the case of a String object we just need to redirect the assignment to
   4524     // the underlying string if the index is in range.  Since the underlying
   4525     // string does nothing with the assignment then we can ignore such
   4526     // assignments.
   4527     if (js_object->IsStringObjectWithCharacterAt(index)) {
   4528       return *value;
   4529     }
   4530 
   4531     return js_object->SetElement(
   4532         index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   4533   }
   4534 
   4535   if (key->IsString()) {
   4536     if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
   4537       return js_object->SetElement(
   4538           index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   4539     } else {
   4540       Handle<String> key_string = Handle<String>::cast(key);
   4541       key_string->TryFlatten();
   4542       return js_object->SetLocalPropertyIgnoreAttributes(*key_string,
   4543                                                          *value,
   4544                                                          attr);
   4545     }
   4546   }
   4547 
   4548   // Call-back into JavaScript to convert the key to a string.
   4549   bool has_pending_exception = false;
   4550   Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
   4551   if (has_pending_exception) return Failure::Exception();
   4552   Handle<String> name = Handle<String>::cast(converted);
   4553 
   4554   if (name->AsArrayIndex(&index)) {
   4555     return js_object->SetElement(
   4556         index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   4557   } else {
   4558     return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
   4559   }
   4560 }
   4561 
   4562 
   4563 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
   4564                                                 Handle<JSReceiver> receiver,
   4565                                                 Handle<Object> key) {
   4566   HandleScope scope(isolate);
   4567 
   4568   // Check if the given key is an array index.
   4569   uint32_t index;
   4570   if (key->ToArrayIndex(&index)) {
   4571     // In Firefox/SpiderMonkey, Safari and Opera you can access the
   4572     // characters of a string using [] notation.  In the case of a
   4573     // String object we just need to redirect the deletion to the
   4574     // underlying string if the index is in range.  Since the
   4575     // underlying string does nothing with the deletion, we can ignore
   4576     // such deletions.
   4577     if (receiver->IsStringObjectWithCharacterAt(index)) {
   4578       return isolate->heap()->true_value();
   4579     }
   4580 
   4581     return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION);
   4582   }
   4583 
   4584   Handle<String> key_string;
   4585   if (key->IsString()) {
   4586     key_string = Handle<String>::cast(key);
   4587   } else {
   4588     // Call-back into JavaScript to convert the key to a string.
   4589     bool has_pending_exception = false;
   4590     Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
   4591     if (has_pending_exception) return Failure::Exception();
   4592     key_string = Handle<String>::cast(converted);
   4593   }
   4594 
   4595   key_string->TryFlatten();
   4596   return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION);
   4597 }
   4598 
   4599 
   4600 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
   4601   NoHandleAllocation ha;
   4602   RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
   4603 
   4604   Handle<Object> object = args.at<Object>(0);
   4605   Handle<Object> key = args.at<Object>(1);
   4606   Handle<Object> value = args.at<Object>(2);
   4607   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   4608   RUNTIME_ASSERT(
   4609       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   4610   // Compute attributes.
   4611   PropertyAttributes attributes =
   4612       static_cast<PropertyAttributes>(unchecked_attributes);
   4613 
   4614   StrictModeFlag strict_mode = kNonStrictMode;
   4615   if (args.length() == 5) {
   4616     CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
   4617     strict_mode = strict_mode_flag;
   4618   }
   4619 
   4620   return Runtime::SetObjectProperty(isolate,
   4621                                     object,
   4622                                     key,
   4623                                     value,
   4624                                     attributes,
   4625                                     strict_mode);
   4626 }
   4627 
   4628 
   4629 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) {
   4630   NoHandleAllocation ha;
   4631   RUNTIME_ASSERT(args.length() == 1);
   4632   Handle<Object> object = args.at<Object>(0);
   4633   return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate);
   4634 }
   4635 
   4636 
   4637 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) {
   4638   NoHandleAllocation ha;
   4639   RUNTIME_ASSERT(args.length() == 1);
   4640   Handle<Object> object = args.at<Object>(0);
   4641   return TransitionElements(object, FAST_ELEMENTS, isolate);
   4642 }
   4643 
   4644 
   4645 // Set the native flag on the function.
   4646 // This is used to decide if we should transform null and undefined
   4647 // into the global object when doing call and apply.
   4648 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
   4649   NoHandleAllocation ha;
   4650   RUNTIME_ASSERT(args.length() == 1);
   4651 
   4652   Handle<Object> object = args.at<Object>(0);
   4653 
   4654   if (object->IsJSFunction()) {
   4655     JSFunction* func = JSFunction::cast(*object);
   4656     func->shared()->set_native(true);
   4657   }
   4658   return isolate->heap()->undefined_value();
   4659 }
   4660 
   4661 
   4662 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
   4663   RUNTIME_ASSERT(args.length() == 5);
   4664   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   4665   CONVERT_SMI_ARG_CHECKED(store_index, 1);
   4666   Handle<Object> value = args.at<Object>(2);
   4667   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
   4668   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
   4669   HandleScope scope;
   4670 
   4671   Object* raw_boilerplate_object = literals->get(literal_index);
   4672   Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object));
   4673 #if DEBUG
   4674   ElementsKind elements_kind = object->GetElementsKind();
   4675 #endif
   4676   ASSERT(elements_kind <= FAST_DOUBLE_ELEMENTS);
   4677   // Smis should never trigger transitions.
   4678   ASSERT(!value->IsSmi());
   4679 
   4680   if (value->IsNumber()) {
   4681     ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS);
   4682     JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
   4683     JSObject::TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS);
   4684     ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS);
   4685     FixedDoubleArray* double_array =
   4686         FixedDoubleArray::cast(object->elements());
   4687     HeapNumber* number = HeapNumber::cast(*value);
   4688     double_array->set(store_index, number->Number());
   4689   } else {
   4690     ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS ||
   4691            elements_kind == FAST_DOUBLE_ELEMENTS);
   4692     JSObject::TransitionElementsKind(object, FAST_ELEMENTS);
   4693     JSObject::TransitionElementsKind(boilerplate_object, FAST_ELEMENTS);
   4694     FixedArray* object_array =
   4695         FixedArray::cast(object->elements());
   4696     object_array->set(store_index, *value);
   4697   }
   4698   return *object;
   4699 }
   4700 
   4701 
   4702 // Set a local property, even if it is READ_ONLY.  If the property does not
   4703 // exist, it will be added with attributes NONE.
   4704 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
   4705   NoHandleAllocation ha;
   4706   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
   4707   CONVERT_ARG_CHECKED(JSObject, object, 0);
   4708   CONVERT_ARG_CHECKED(String, name, 1);
   4709   // Compute attributes.
   4710   PropertyAttributes attributes = NONE;
   4711   if (args.length() == 4) {
   4712     CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
   4713     // Only attribute bits should be set.
   4714     RUNTIME_ASSERT(
   4715         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   4716     attributes = static_cast<PropertyAttributes>(unchecked_value);
   4717   }
   4718 
   4719   return object->
   4720       SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
   4721 }
   4722 
   4723 
   4724 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
   4725   NoHandleAllocation ha;
   4726   ASSERT(args.length() == 3);
   4727 
   4728   CONVERT_ARG_CHECKED(JSReceiver, object, 0);
   4729   CONVERT_ARG_CHECKED(String, key, 1);
   4730   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
   4731   return object->DeleteProperty(key, (strict_mode == kStrictMode)
   4732                                       ? JSReceiver::STRICT_DELETION
   4733                                       : JSReceiver::NORMAL_DELETION);
   4734 }
   4735 
   4736 
   4737 static Object* HasLocalPropertyImplementation(Isolate* isolate,
   4738                                               Handle<JSObject> object,
   4739                                               Handle<String> key) {
   4740   if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
   4741   // Handle hidden prototypes.  If there's a hidden prototype above this thing
   4742   // then we have to check it for properties, because they are supposed to
   4743   // look like they are on this object.
   4744   Handle<Object> proto(object->GetPrototype());
   4745   if (proto->IsJSObject() &&
   4746       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
   4747     return HasLocalPropertyImplementation(isolate,
   4748                                           Handle<JSObject>::cast(proto),
   4749                                           key);
   4750   }
   4751   return isolate->heap()->false_value();
   4752 }
   4753 
   4754 
   4755 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
   4756   NoHandleAllocation ha;
   4757   ASSERT(args.length() == 2);
   4758   CONVERT_ARG_CHECKED(String, key, 1);
   4759 
   4760   uint32_t index;
   4761   const bool key_is_array_index = key->AsArrayIndex(&index);
   4762 
   4763   Object* obj = args[0];
   4764   // Only JS objects can have properties.
   4765   if (obj->IsJSObject()) {
   4766     JSObject* object = JSObject::cast(obj);
   4767     // Fast case: either the key is a real named property or it is not
   4768     // an array index and there are no interceptors or hidden
   4769     // prototypes.
   4770     if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value();
   4771     Map* map = object->map();
   4772     if (!key_is_array_index &&
   4773         !map->has_named_interceptor() &&
   4774         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
   4775       return isolate->heap()->false_value();
   4776     }
   4777     // Slow case.
   4778     HandleScope scope(isolate);
   4779     return HasLocalPropertyImplementation(isolate,
   4780                                           Handle<JSObject>(object),
   4781                                           Handle<String>(key));
   4782   } else if (obj->IsString() && key_is_array_index) {
   4783     // Well, there is one exception:  Handle [] on strings.
   4784     String* string = String::cast(obj);
   4785     if (index < static_cast<uint32_t>(string->length())) {
   4786       return isolate->heap()->true_value();
   4787     }
   4788   }
   4789   return isolate->heap()->false_value();
   4790 }
   4791 
   4792 
   4793 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
   4794   NoHandleAllocation na;
   4795   ASSERT(args.length() == 2);
   4796   CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
   4797   CONVERT_ARG_CHECKED(String, key, 1);
   4798 
   4799   bool result = receiver->HasProperty(key);
   4800   if (isolate->has_pending_exception()) return Failure::Exception();
   4801   return isolate->heap()->ToBoolean(result);
   4802 }
   4803 
   4804 
   4805 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
   4806   NoHandleAllocation na;
   4807   ASSERT(args.length() == 2);
   4808   CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
   4809   CONVERT_SMI_ARG_CHECKED(index, 1);
   4810 
   4811   bool result = receiver->HasElement(index);
   4812   if (isolate->has_pending_exception()) return Failure::Exception();
   4813   return isolate->heap()->ToBoolean(result);
   4814 }
   4815 
   4816 
   4817 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
   4818   NoHandleAllocation ha;
   4819   ASSERT(args.length() == 2);
   4820 
   4821   CONVERT_ARG_CHECKED(JSObject, object, 0);
   4822   CONVERT_ARG_CHECKED(String, key, 1);
   4823 
   4824   uint32_t index;
   4825   if (key->AsArrayIndex(&index)) {
   4826     JSObject::LocalElementType type = object->HasLocalElement(index);
   4827     switch (type) {
   4828       case JSObject::UNDEFINED_ELEMENT:
   4829       case JSObject::STRING_CHARACTER_ELEMENT:
   4830         return isolate->heap()->false_value();
   4831       case JSObject::INTERCEPTED_ELEMENT:
   4832       case JSObject::FAST_ELEMENT:
   4833         return isolate->heap()->true_value();
   4834       case JSObject::DICTIONARY_ELEMENT: {
   4835         if (object->IsJSGlobalProxy()) {
   4836           Object* proto = object->GetPrototype();
   4837           if (proto->IsNull()) {
   4838             return isolate->heap()->false_value();
   4839           }
   4840           ASSERT(proto->IsJSGlobalObject());
   4841           object = JSObject::cast(proto);
   4842         }
   4843         FixedArray* elements = FixedArray::cast(object->elements());
   4844         SeededNumberDictionary* dictionary = NULL;
   4845         if (elements->map() ==
   4846             isolate->heap()->non_strict_arguments_elements_map()) {
   4847           dictionary = SeededNumberDictionary::cast(elements->get(1));
   4848         } else {
   4849           dictionary = SeededNumberDictionary::cast(elements);
   4850         }
   4851         int entry = dictionary->FindEntry(index);
   4852         ASSERT(entry != SeededNumberDictionary::kNotFound);
   4853         PropertyDetails details = dictionary->DetailsAt(entry);
   4854         return isolate->heap()->ToBoolean(!details.IsDontEnum());
   4855       }
   4856     }
   4857   }
   4858 
   4859   PropertyAttributes att = object->GetLocalPropertyAttribute(key);
   4860   return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0);
   4861 }
   4862 
   4863 
   4864 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
   4865   HandleScope scope(isolate);
   4866   ASSERT(args.length() == 1);
   4867   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   4868   bool threw = false;
   4869   Handle<JSArray> result = GetKeysFor(object, &threw);
   4870   if (threw) return Failure::Exception();
   4871   return *result;
   4872 }
   4873 
   4874 
   4875 // Returns either a FixedArray as Runtime_GetPropertyNames,
   4876 // or, if the given object has an enum cache that contains
   4877 // all enumerable properties of the object and its prototypes
   4878 // have none, the map of the object. This is used to speed up
   4879 // the check for deletions during a for-in.
   4880 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
   4881   ASSERT(args.length() == 1);
   4882 
   4883   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
   4884 
   4885   if (raw_object->IsSimpleEnum()) return raw_object->map();
   4886 
   4887   HandleScope scope(isolate);
   4888   Handle<JSReceiver> object(raw_object);
   4889   bool threw = false;
   4890   Handle<FixedArray> content =
   4891       GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw);
   4892   if (threw) return Failure::Exception();
   4893 
   4894   // Test again, since cache may have been built by preceding call.
   4895   if (object->IsSimpleEnum()) return object->map();
   4896 
   4897   return *content;
   4898 }
   4899 
   4900 
   4901 // Find the length of the prototype chain that is to to handled as one. If a
   4902 // prototype object is hidden it is to be viewed as part of the the object it
   4903 // is prototype for.
   4904 static int LocalPrototypeChainLength(JSObject* obj) {
   4905   int count = 1;
   4906   Object* proto = obj->GetPrototype();
   4907   while (proto->IsJSObject() &&
   4908          JSObject::cast(proto)->map()->is_hidden_prototype()) {
   4909     count++;
   4910     proto = JSObject::cast(proto)->GetPrototype();
   4911   }
   4912   return count;
   4913 }
   4914 
   4915 
   4916 // Return the names of the local named properties.
   4917 // args[0]: object
   4918 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
   4919   HandleScope scope(isolate);
   4920   ASSERT(args.length() == 1);
   4921   if (!args[0]->IsJSObject()) {
   4922     return isolate->heap()->undefined_value();
   4923   }
   4924   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   4925 
   4926   // Skip the global proxy as it has no properties and always delegates to the
   4927   // real global object.
   4928   if (obj->IsJSGlobalProxy()) {
   4929     // Only collect names if access is permitted.
   4930     if (obj->IsAccessCheckNeeded() &&
   4931         !isolate->MayNamedAccess(*obj,
   4932                                  isolate->heap()->undefined_value(),
   4933                                  v8::ACCESS_KEYS)) {
   4934       isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS);
   4935       return *isolate->factory()->NewJSArray(0);
   4936     }
   4937     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   4938   }
   4939 
   4940   // Find the number of objects making up this.
   4941   int length = LocalPrototypeChainLength(*obj);
   4942 
   4943   // Find the number of local properties for each of the objects.
   4944   ScopedVector<int> local_property_count(length);
   4945   int total_property_count = 0;
   4946   Handle<JSObject> jsproto = obj;
   4947   for (int i = 0; i < length; i++) {
   4948     // Only collect names if access is permitted.
   4949     if (jsproto->IsAccessCheckNeeded() &&
   4950         !isolate->MayNamedAccess(*jsproto,
   4951                                  isolate->heap()->undefined_value(),
   4952                                  v8::ACCESS_KEYS)) {
   4953       isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS);
   4954       return *isolate->factory()->NewJSArray(0);
   4955     }
   4956     int n;
   4957     n = jsproto->NumberOfLocalProperties();
   4958     local_property_count[i] = n;
   4959     total_property_count += n;
   4960     if (i < length - 1) {
   4961       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   4962     }
   4963   }
   4964 
   4965   // Allocate an array with storage for all the property names.
   4966   Handle<FixedArray> names =
   4967       isolate->factory()->NewFixedArray(total_property_count);
   4968 
   4969   // Get the property names.
   4970   jsproto = obj;
   4971   int proto_with_hidden_properties = 0;
   4972   int next_copy_index = 0;
   4973   for (int i = 0; i < length; i++) {
   4974     jsproto->GetLocalPropertyNames(*names, next_copy_index);
   4975     next_copy_index += local_property_count[i];
   4976     if (jsproto->HasHiddenProperties()) {
   4977       proto_with_hidden_properties++;
   4978     }
   4979     if (i < length - 1) {
   4980       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   4981     }
   4982   }
   4983 
   4984   // Filter out name of hidden propeties object.
   4985   if (proto_with_hidden_properties > 0) {
   4986     Handle<FixedArray> old_names = names;
   4987     names = isolate->factory()->NewFixedArray(
   4988         names->length() - proto_with_hidden_properties);
   4989     int dest_pos = 0;
   4990     for (int i = 0; i < total_property_count; i++) {
   4991       Object* name = old_names->get(i);
   4992       if (name == isolate->heap()->hidden_symbol()) {
   4993         continue;
   4994       }
   4995       names->set(dest_pos++, name);
   4996     }
   4997   }
   4998 
   4999   return *isolate->factory()->NewJSArrayWithElements(names);
   5000 }
   5001 
   5002 
   5003 // Return the names of the local indexed properties.
   5004 // args[0]: object
   5005 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalElementNames) {
   5006   HandleScope scope(isolate);
   5007   ASSERT(args.length() == 1);
   5008   if (!args[0]->IsJSObject()) {
   5009     return isolate->heap()->undefined_value();
   5010   }
   5011   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5012 
   5013   int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
   5014   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
   5015   obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
   5016   return *isolate->factory()->NewJSArrayWithElements(names);
   5017 }
   5018 
   5019 
   5020 // Return information on whether an object has a named or indexed interceptor.
   5021 // args[0]: object
   5022 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetInterceptorInfo) {
   5023   HandleScope scope(isolate);
   5024   ASSERT(args.length() == 1);
   5025   if (!args[0]->IsJSObject()) {
   5026     return Smi::FromInt(0);
   5027   }
   5028   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5029 
   5030   int result = 0;
   5031   if (obj->HasNamedInterceptor()) result |= 2;
   5032   if (obj->HasIndexedInterceptor()) result |= 1;
   5033 
   5034   return Smi::FromInt(result);
   5035 }
   5036 
   5037 
   5038 // Return property names from named interceptor.
   5039 // args[0]: object
   5040 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
   5041   HandleScope scope(isolate);
   5042   ASSERT(args.length() == 1);
   5043   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5044 
   5045   if (obj->HasNamedInterceptor()) {
   5046     v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
   5047     if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
   5048   }
   5049   return isolate->heap()->undefined_value();
   5050 }
   5051 
   5052 
   5053 // Return element names from indexed interceptor.
   5054 // args[0]: object
   5055 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetIndexedInterceptorElementNames) {
   5056   HandleScope scope(isolate);
   5057   ASSERT(args.length() == 1);
   5058   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   5059 
   5060   if (obj->HasIndexedInterceptor()) {
   5061     v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
   5062     if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
   5063   }
   5064   return isolate->heap()->undefined_value();
   5065 }
   5066 
   5067 
   5068 RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
   5069   ASSERT_EQ(args.length(), 1);
   5070   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
   5071   HandleScope scope(isolate);
   5072   Handle<JSObject> object(raw_object);
   5073 
   5074   if (object->IsJSGlobalProxy()) {
   5075     // Do access checks before going to the global object.
   5076     if (object->IsAccessCheckNeeded() &&
   5077         !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
   5078                              v8::ACCESS_KEYS)) {
   5079       isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
   5080       return *isolate->factory()->NewJSArray(0);
   5081     }
   5082 
   5083     Handle<Object> proto(object->GetPrototype());
   5084     // If proxy is detached we simply return an empty array.
   5085     if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
   5086     object = Handle<JSObject>::cast(proto);
   5087   }
   5088 
   5089   bool threw = false;
   5090   Handle<FixedArray> contents =
   5091       GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
   5092   if (threw) return Failure::Exception();
   5093 
   5094   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
   5095   // property array and since the result is mutable we have to create
   5096   // a fresh clone on each invocation.
   5097   int length = contents->length();
   5098   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
   5099   for (int i = 0; i < length; i++) {
   5100     Object* entry = contents->get(i);
   5101     if (entry->IsString()) {
   5102       copy->set(i, entry);
   5103     } else {
   5104       ASSERT(entry->IsNumber());
   5105       HandleScope scope(isolate);
   5106       Handle<Object> entry_handle(entry, isolate);
   5107       Handle<Object> entry_str =
   5108           isolate->factory()->NumberToString(entry_handle);
   5109       copy->set(i, *entry_str);
   5110     }
   5111   }
   5112   return *isolate->factory()->NewJSArrayWithElements(copy);
   5113 }
   5114 
   5115 
   5116 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
   5117   NoHandleAllocation ha;
   5118   ASSERT(args.length() == 1);
   5119 
   5120   // Compute the frame holding the arguments.
   5121   JavaScriptFrameIterator it(isolate);
   5122   it.AdvanceToArgumentsFrame();
   5123   JavaScriptFrame* frame = it.frame();
   5124 
   5125   // Get the actual number of provided arguments.
   5126   const uint32_t n = frame->ComputeParametersCount();
   5127 
   5128   // Try to convert the key to an index. If successful and within
   5129   // index return the the argument from the frame.
   5130   uint32_t index;
   5131   if (args[0]->ToArrayIndex(&index) && index < n) {
   5132     return frame->GetParameter(index);
   5133   }
   5134 
   5135   // Convert the key to a string.
   5136   HandleScope scope(isolate);
   5137   bool exception = false;
   5138   Handle<Object> converted =
   5139       Execution::ToString(args.at<Object>(0), &exception);
   5140   if (exception) return Failure::Exception();
   5141   Handle<String> key = Handle<String>::cast(converted);
   5142 
   5143   // Try to convert the string key into an array index.
   5144   if (key->AsArrayIndex(&index)) {
   5145     if (index < n) {
   5146       return frame->GetParameter(index);
   5147     } else {
   5148       return isolate->initial_object_prototype()->GetElement(index);
   5149     }
   5150   }
   5151 
   5152   // Handle special arguments properties.
   5153   if (key->Equals(isolate->heap()->length_symbol())) return Smi::FromInt(n);
   5154   if (key->Equals(isolate->heap()->callee_symbol())) {
   5155     Object* function = frame->function();
   5156     if (function->IsJSFunction() &&
   5157         !JSFunction::cast(function)->shared()->is_classic_mode()) {
   5158       return isolate->Throw(*isolate->factory()->NewTypeError(
   5159           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
   5160     }
   5161     return function;
   5162   }
   5163 
   5164   // Lookup in the initial Object.prototype object.
   5165   return isolate->initial_object_prototype()->GetProperty(*key);
   5166 }
   5167 
   5168 
   5169 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
   5170   ASSERT(args.length() == 1);
   5171   Object* object = args[0];
   5172   return (object->IsJSObject() && !object->IsGlobalObject())
   5173       ? JSObject::cast(object)->TransformToFastProperties(0)
   5174       : object;
   5175 }
   5176 
   5177 
   5178 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) {
   5179   ASSERT(args.length() == 1);
   5180   Object* obj = args[0];
   5181   return (obj->IsJSObject() && !obj->IsJSGlobalProxy())
   5182       ? JSObject::cast(obj)->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0)
   5183       : obj;
   5184 }
   5185 
   5186 
   5187 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
   5188   NoHandleAllocation ha;
   5189   ASSERT(args.length() == 1);
   5190 
   5191   return args[0]->ToBoolean();
   5192 }
   5193 
   5194 
   5195 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
   5196 // Possible optimizations: put the type string into the oddballs.
   5197 RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
   5198   NoHandleAllocation ha;
   5199 
   5200   Object* obj = args[0];
   5201   if (obj->IsNumber()) return isolate->heap()->number_symbol();
   5202   HeapObject* heap_obj = HeapObject::cast(obj);
   5203 
   5204   // typeof an undetectable object is 'undefined'
   5205   if (heap_obj->map()->is_undetectable()) {
   5206     return isolate->heap()->undefined_symbol();
   5207   }
   5208 
   5209   InstanceType instance_type = heap_obj->map()->instance_type();
   5210   if (instance_type < FIRST_NONSTRING_TYPE) {
   5211     return isolate->heap()->string_symbol();
   5212   }
   5213 
   5214   switch (instance_type) {
   5215     case ODDBALL_TYPE:
   5216       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
   5217         return isolate->heap()->boolean_symbol();
   5218       }
   5219       if (heap_obj->IsNull()) {
   5220         return FLAG_harmony_typeof
   5221             ? isolate->heap()->null_symbol()
   5222             : isolate->heap()->object_symbol();
   5223       }
   5224       ASSERT(heap_obj->IsUndefined());
   5225       return isolate->heap()->undefined_symbol();
   5226     case JS_FUNCTION_TYPE:
   5227     case JS_FUNCTION_PROXY_TYPE:
   5228       return isolate->heap()->function_symbol();
   5229     default:
   5230       // For any kind of object not handled above, the spec rule for
   5231       // host objects gives that it is okay to return "object"
   5232       return isolate->heap()->object_symbol();
   5233   }
   5234 }
   5235 
   5236 
   5237 static bool AreDigits(const char*s, int from, int to) {
   5238   for (int i = from; i < to; i++) {
   5239     if (s[i] < '0' || s[i] > '9') return false;
   5240   }
   5241 
   5242   return true;
   5243 }
   5244 
   5245 
   5246 static int ParseDecimalInteger(const char*s, int from, int to) {
   5247   ASSERT(to - from < 10);  // Overflow is not possible.
   5248   ASSERT(from < to);
   5249   int d = s[from] - '0';
   5250 
   5251   for (int i = from + 1; i < to; i++) {
   5252     d = 10 * d + (s[i] - '0');
   5253   }
   5254 
   5255   return d;
   5256 }
   5257 
   5258 
   5259 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
   5260   NoHandleAllocation ha;
   5261   ASSERT(args.length() == 1);
   5262   CONVERT_ARG_CHECKED(String, subject, 0);
   5263   subject->TryFlatten();
   5264 
   5265   // Fast case: short integer or some sorts of junk values.
   5266   int len = subject->length();
   5267   if (subject->IsSeqAsciiString()) {
   5268     if (len == 0) return Smi::FromInt(0);
   5269 
   5270     char const* data = SeqAsciiString::cast(subject)->GetChars();
   5271     bool minus = (data[0] == '-');
   5272     int start_pos = (minus ? 1 : 0);
   5273 
   5274     if (start_pos == len) {
   5275       return isolate->heap()->nan_value();
   5276     } else if (data[start_pos] > '9') {
   5277       // Fast check for a junk value. A valid string may start from a
   5278       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
   5279       // the 'I' character ('Infinity'). All of that have codes not greater than
   5280       // '9' except 'I'.
   5281       if (data[start_pos] != 'I') {
   5282         return isolate->heap()->nan_value();
   5283       }
   5284     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
   5285       // The maximal/minimal smi has 10 digits. If the string has less digits we
   5286       // know it will fit into the smi-data type.
   5287       int d = ParseDecimalInteger(data, start_pos, len);
   5288       if (minus) {
   5289         if (d == 0) return isolate->heap()->minus_zero_value();
   5290         d = -d;
   5291       } else if (!subject->HasHashCode() &&
   5292                  len <= String::kMaxArrayIndexSize &&
   5293                  (len == 1 || data[0] != '0')) {
   5294         // String hash is not calculated yet but all the data are present.
   5295         // Update the hash field to speed up sequential convertions.
   5296         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
   5297 #ifdef DEBUG
   5298         subject->Hash();  // Force hash calculation.
   5299         ASSERT_EQ(static_cast<int>(subject->hash_field()),
   5300                   static_cast<int>(hash));
   5301 #endif
   5302         subject->set_hash_field(hash);
   5303       }
   5304       return Smi::FromInt(d);
   5305     }
   5306   }
   5307 
   5308   // Slower case.
   5309   return isolate->heap()->NumberFromDouble(
   5310       StringToDouble(isolate->unicode_cache(), subject, ALLOW_HEX));
   5311 }
   5312 
   5313 
   5314 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringFromCharCodeArray) {
   5315   NoHandleAllocation ha;
   5316   ASSERT(args.length() == 1);
   5317 
   5318   CONVERT_ARG_CHECKED(JSArray, codes, 0);
   5319   int length = Smi::cast(codes->length())->value();
   5320 
   5321   // Check if the string can be ASCII.
   5322   int i;
   5323   for (i = 0; i < length; i++) {
   5324     Object* element;
   5325     { MaybeObject* maybe_element = codes->GetElement(i);
   5326       // We probably can't get an exception here, but just in order to enforce
   5327       // the checking of inputs in the runtime calls we check here.
   5328       if (!maybe_element->ToObject(&element)) return maybe_element;
   5329     }
   5330     CONVERT_NUMBER_CHECKED(int, chr, Int32, element);
   5331     if ((chr & 0xffff) > String::kMaxAsciiCharCode)
   5332       break;
   5333   }
   5334 
   5335   MaybeObject* maybe_object = NULL;
   5336   if (i == length) {  // The string is ASCII.
   5337     maybe_object = isolate->heap()->AllocateRawAsciiString(length);
   5338   } else {  // The string is not ASCII.
   5339     maybe_object = isolate->heap()->AllocateRawTwoByteString(length);
   5340   }
   5341 
   5342   Object* object = NULL;
   5343   if (!maybe_object->ToObject(&object)) return maybe_object;
   5344   String* result = String::cast(object);
   5345   for (int i = 0; i < length; i++) {
   5346     Object* element;
   5347     { MaybeObject* maybe_element = codes->GetElement(i);
   5348       if (!maybe_element->ToObject(&element)) return maybe_element;
   5349     }
   5350     CONVERT_NUMBER_CHECKED(int, chr, Int32, element);
   5351     result->Set(i, chr & 0xffff);
   5352   }
   5353   return result;
   5354 }
   5355 
   5356 
   5357 // kNotEscaped is generated by the following:
   5358 //
   5359 // #!/bin/perl
   5360 // for (my $i = 0; $i < 256; $i++) {
   5361 //   print "\n" if $i % 16 == 0;
   5362 //   my $c = chr($i);
   5363 //   my $escaped = 1;
   5364 //   $escaped = 0 if $c =~ m#[A-Za-z0-9@*_+./-]#;
   5365 //   print $escaped ? "0, " : "1, ";
   5366 // }
   5367 
   5368 
   5369 static bool IsNotEscaped(uint16_t character) {
   5370   // Only for 8 bit characters, the rest are always escaped (in a different way)
   5371   ASSERT(character < 256);
   5372   static const char kNotEscaped[256] = {
   5373     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5374     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5375     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1,
   5376     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
   5377     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   5378     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
   5379     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   5380     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
   5381     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5382     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5383     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5384     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5385     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5386     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5387     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5388     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5389   };
   5390   return kNotEscaped[character] != 0;
   5391 }
   5392 
   5393 
   5394 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
   5395   const char hex_chars[] = "0123456789ABCDEF";
   5396   NoHandleAllocation ha;
   5397   ASSERT(args.length() == 1);
   5398   CONVERT_ARG_CHECKED(String, source, 0);
   5399 
   5400   source->TryFlatten();
   5401 
   5402   int escaped_length = 0;
   5403   int length = source->length();
   5404   {
   5405     Access<StringInputBuffer> buffer(
   5406         isolate->runtime_state()->string_input_buffer());
   5407     buffer->Reset(source);
   5408     while (buffer->has_more()) {
   5409       uint16_t character = buffer->GetNext();
   5410       if (character >= 256) {
   5411         escaped_length += 6;
   5412       } else if (IsNotEscaped(character)) {
   5413         escaped_length++;
   5414       } else {
   5415         escaped_length += 3;
   5416       }
   5417       // We don't allow strings that are longer than a maximal length.
   5418       ASSERT(String::kMaxLength < 0x7fffffff - 6);  // Cannot overflow.
   5419       if (escaped_length > String::kMaxLength) {
   5420         isolate->context()->mark_out_of_memory();
   5421         return Failure::OutOfMemoryException();
   5422       }
   5423     }
   5424   }
   5425   // No length change implies no change.  Return original string if no change.
   5426   if (escaped_length == length) {
   5427     return source;
   5428   }
   5429   Object* o;
   5430   { MaybeObject* maybe_o =
   5431         isolate->heap()->AllocateRawAsciiString(escaped_length);
   5432     if (!maybe_o->ToObject(&o)) return maybe_o;
   5433   }
   5434   String* destination = String::cast(o);
   5435   int dest_position = 0;
   5436 
   5437   Access<StringInputBuffer> buffer(
   5438       isolate->runtime_state()->string_input_buffer());
   5439   buffer->Rewind();
   5440   while (buffer->has_more()) {
   5441     uint16_t chr = buffer->GetNext();
   5442     if (chr >= 256) {
   5443       destination->Set(dest_position, '%');
   5444       destination->Set(dest_position+1, 'u');
   5445       destination->Set(dest_position+2, hex_chars[chr >> 12]);
   5446       destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]);
   5447       destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]);
   5448       destination->Set(dest_position+5, hex_chars[chr & 0xf]);
   5449       dest_position += 6;
   5450     } else if (IsNotEscaped(chr)) {
   5451       destination->Set(dest_position, chr);
   5452       dest_position++;
   5453     } else {
   5454       destination->Set(dest_position, '%');
   5455       destination->Set(dest_position+1, hex_chars[chr >> 4]);
   5456       destination->Set(dest_position+2, hex_chars[chr & 0xf]);
   5457       dest_position += 3;
   5458     }
   5459   }
   5460   return destination;
   5461 }
   5462 
   5463 
   5464 static inline int TwoDigitHex(uint16_t character1, uint16_t character2) {
   5465   static const signed char kHexValue['g'] = {
   5466     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   5467     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   5468     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   5469     0,  1,  2,   3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
   5470     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   5471     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   5472     -1, 10, 11, 12, 13, 14, 15 };
   5473 
   5474   if (character1 > 'f') return -1;
   5475   int hi = kHexValue[character1];
   5476   if (hi == -1) return -1;
   5477   if (character2 > 'f') return -1;
   5478   int lo = kHexValue[character2];
   5479   if (lo == -1) return -1;
   5480   return (hi << 4) + lo;
   5481 }
   5482 
   5483 
   5484 static inline int Unescape(String* source,
   5485                            int i,
   5486                            int length,
   5487                            int* step) {
   5488   uint16_t character = source->Get(i);
   5489   int32_t hi = 0;
   5490   int32_t lo = 0;
   5491   if (character == '%' &&
   5492       i <= length - 6 &&
   5493       source->Get(i + 1) == 'u' &&
   5494       (hi = TwoDigitHex(source->Get(i + 2),
   5495                         source->Get(i + 3))) != -1 &&
   5496       (lo = TwoDigitHex(source->Get(i + 4),
   5497                         source->Get(i + 5))) != -1) {
   5498     *step = 6;
   5499     return (hi << 8) + lo;
   5500   } else if (character == '%' &&
   5501       i <= length - 3 &&
   5502       (lo = TwoDigitHex(source->Get(i + 1),
   5503                         source->Get(i + 2))) != -1) {
   5504     *step = 3;
   5505     return lo;
   5506   } else {
   5507     *step = 1;
   5508     return character;
   5509   }
   5510 }
   5511 
   5512 
   5513 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
   5514   NoHandleAllocation ha;
   5515   ASSERT(args.length() == 1);
   5516   CONVERT_ARG_CHECKED(String, source, 0);
   5517 
   5518   source->TryFlatten();
   5519 
   5520   bool ascii = true;
   5521   int length = source->length();
   5522 
   5523   int unescaped_length = 0;
   5524   for (int i = 0; i < length; unescaped_length++) {
   5525     int step;
   5526     if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) {
   5527       ascii = false;
   5528     }
   5529     i += step;
   5530   }
   5531 
   5532   // No length change implies no change.  Return original string if no change.
   5533   if (unescaped_length == length)
   5534     return source;
   5535 
   5536   Object* o;
   5537   { MaybeObject* maybe_o =
   5538         ascii ?
   5539         isolate->heap()->AllocateRawAsciiString(unescaped_length) :
   5540         isolate->heap()->AllocateRawTwoByteString(unescaped_length);
   5541     if (!maybe_o->ToObject(&o)) return maybe_o;
   5542   }
   5543   String* destination = String::cast(o);
   5544 
   5545   int dest_position = 0;
   5546   for (int i = 0; i < length; dest_position++) {
   5547     int step;
   5548     destination->Set(dest_position, Unescape(source, i, length, &step));
   5549     i += step;
   5550   }
   5551   return destination;
   5552 }
   5553 
   5554 
   5555 static const unsigned int kQuoteTableLength = 128u;
   5556 
   5557 static const int kJsonQuotesCharactersPerEntry = 8;
   5558 static const char* const JsonQuotes =
   5559     "\\u0000  \\u0001  \\u0002  \\u0003  "
   5560     "\\u0004  \\u0005  \\u0006  \\u0007  "
   5561     "\\b      \\t      \\n      \\u000b  "
   5562     "\\f      \\r      \\u000e  \\u000f  "
   5563     "\\u0010  \\u0011  \\u0012  \\u0013  "
   5564     "\\u0014  \\u0015  \\u0016  \\u0017  "
   5565     "\\u0018  \\u0019  \\u001a  \\u001b  "
   5566     "\\u001c  \\u001d  \\u001e  \\u001f  "
   5567     "        !       \\\"      #       "
   5568     "$       %       &       '       "
   5569     "(       )       *       +       "
   5570     ",       -       .       /       "
   5571     "0       1       2       3       "
   5572     "4       5       6       7       "
   5573     "8       9       :       ;       "
   5574     "<       =       >       ?       "
   5575     "@       A       B       C       "
   5576     "D       E       F       G       "
   5577     "H       I       J       K       "
   5578     "L       M       N       O       "
   5579     "P       Q       R       S       "
   5580     "T       U       V       W       "
   5581     "X       Y       Z       [       "
   5582     "\\\\      ]       ^       _       "
   5583     "`       a       b       c       "
   5584     "d       e       f       g       "
   5585     "h       i       j       k       "
   5586     "l       m       n       o       "
   5587     "p       q       r       s       "
   5588     "t       u       v       w       "
   5589     "x       y       z       {       "
   5590     "|       }       ~       \177       ";
   5591 
   5592 
   5593 // For a string that is less than 32k characters it should always be
   5594 // possible to allocate it in new space.
   5595 static const int kMaxGuaranteedNewSpaceString = 32 * 1024;
   5596 
   5597 
   5598 // Doing JSON quoting cannot make the string more than this many times larger.
   5599 static const int kJsonQuoteWorstCaseBlowup = 6;
   5600 
   5601 static const int kSpaceForQuotesAndComma = 3;
   5602 static const int kSpaceForBrackets = 2;
   5603 
   5604 // Covers the entire ASCII range (all other characters are unchanged by JSON
   5605 // quoting).
   5606 static const byte JsonQuoteLengths[kQuoteTableLength] = {
   5607     6, 6, 6, 6, 6, 6, 6, 6,
   5608     2, 2, 2, 6, 2, 2, 6, 6,
   5609     6, 6, 6, 6, 6, 6, 6, 6,
   5610     6, 6, 6, 6, 6, 6, 6, 6,
   5611     1, 1, 2, 1, 1, 1, 1, 1,
   5612     1, 1, 1, 1, 1, 1, 1, 1,
   5613     1, 1, 1, 1, 1, 1, 1, 1,
   5614     1, 1, 1, 1, 1, 1, 1, 1,
   5615     1, 1, 1, 1, 1, 1, 1, 1,
   5616     1, 1, 1, 1, 1, 1, 1, 1,
   5617     1, 1, 1, 1, 1, 1, 1, 1,
   5618     1, 1, 1, 1, 2, 1, 1, 1,
   5619     1, 1, 1, 1, 1, 1, 1, 1,
   5620     1, 1, 1, 1, 1, 1, 1, 1,
   5621     1, 1, 1, 1, 1, 1, 1, 1,
   5622     1, 1, 1, 1, 1, 1, 1, 1,
   5623 };
   5624 
   5625 
   5626 template <typename StringType>
   5627 MaybeObject* AllocateRawString(Isolate* isolate, int length);
   5628 
   5629 
   5630 template <>
   5631 MaybeObject* AllocateRawString<SeqTwoByteString>(Isolate* isolate, int length) {
   5632   return isolate->heap()->AllocateRawTwoByteString(length);
   5633 }
   5634 
   5635 
   5636 template <>
   5637 MaybeObject* AllocateRawString<SeqAsciiString>(Isolate* isolate, int length) {
   5638   return isolate->heap()->AllocateRawAsciiString(length);
   5639 }
   5640 
   5641 
   5642 template <typename Char, typename StringType, bool comma>
   5643 static MaybeObject* SlowQuoteJsonString(Isolate* isolate,
   5644                                         Vector<const Char> characters) {
   5645   int length = characters.length();
   5646   const Char* read_cursor = characters.start();
   5647   const Char* end = read_cursor + length;
   5648   const int kSpaceForQuotes = 2 + (comma ? 1 :0);
   5649   int quoted_length = kSpaceForQuotes;
   5650   while (read_cursor < end) {
   5651     Char c = *(read_cursor++);
   5652     if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
   5653       quoted_length++;
   5654     } else {
   5655       quoted_length += JsonQuoteLengths[static_cast<unsigned>(c)];
   5656     }
   5657   }
   5658   MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
   5659                                                          quoted_length);
   5660   Object* new_object;
   5661   if (!new_alloc->ToObject(&new_object)) {
   5662     return new_alloc;
   5663   }
   5664   StringType* new_string = StringType::cast(new_object);
   5665 
   5666   Char* write_cursor = reinterpret_cast<Char*>(
   5667       new_string->address() + SeqString::kHeaderSize);
   5668   if (comma) *(write_cursor++) = ',';
   5669   *(write_cursor++) = '"';
   5670 
   5671   read_cursor = characters.start();
   5672   while (read_cursor < end) {
   5673     Char c = *(read_cursor++);
   5674     if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
   5675       *(write_cursor++) = c;
   5676     } else {
   5677       int len = JsonQuoteLengths[static_cast<unsigned>(c)];
   5678       const char* replacement = JsonQuotes +
   5679           static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
   5680       for (int i = 0; i < len; i++) {
   5681         *write_cursor++ = *replacement++;
   5682       }
   5683     }
   5684   }
   5685   *(write_cursor++) = '"';
   5686   return new_string;
   5687 }
   5688 
   5689 
   5690 template <typename SinkChar, typename SourceChar>
   5691 static inline SinkChar* WriteQuoteJsonString(
   5692     Isolate* isolate,
   5693     SinkChar* write_cursor,
   5694     Vector<const SourceChar> characters) {
   5695   // SinkChar is only char if SourceChar is guaranteed to be char.
   5696   ASSERT(sizeof(SinkChar) >= sizeof(SourceChar));
   5697   const SourceChar* read_cursor = characters.start();
   5698   const SourceChar* end = read_cursor + characters.length();
   5699   *(write_cursor++) = '"';
   5700   while (read_cursor < end) {
   5701     SourceChar c = *(read_cursor++);
   5702     if (sizeof(SourceChar) > 1u &&
   5703         static_cast<unsigned>(c) >= kQuoteTableLength) {
   5704       *(write_cursor++) = static_cast<SinkChar>(c);
   5705     } else {
   5706       int len = JsonQuoteLengths[static_cast<unsigned>(c)];
   5707       const char* replacement = JsonQuotes +
   5708           static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
   5709       write_cursor[0] = replacement[0];
   5710       if (len > 1) {
   5711         write_cursor[1] = replacement[1];
   5712         if (len > 2) {
   5713           ASSERT(len == 6);
   5714           write_cursor[2] = replacement[2];
   5715           write_cursor[3] = replacement[3];
   5716           write_cursor[4] = replacement[4];
   5717           write_cursor[5] = replacement[5];
   5718         }
   5719       }
   5720       write_cursor += len;
   5721     }
   5722   }
   5723   *(write_cursor++) = '"';
   5724   return write_cursor;
   5725 }
   5726 
   5727 
   5728 template <typename Char, typename StringType, bool comma>
   5729 static MaybeObject* QuoteJsonString(Isolate* isolate,
   5730                                     Vector<const Char> characters) {
   5731   int length = characters.length();
   5732   isolate->counters()->quote_json_char_count()->Increment(length);
   5733   int worst_case_length =
   5734         length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotesAndComma;
   5735   if (worst_case_length > kMaxGuaranteedNewSpaceString) {
   5736     return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
   5737   }
   5738 
   5739   MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
   5740                                                          worst_case_length);
   5741   Object* new_object;
   5742   if (!new_alloc->ToObject(&new_object)) {
   5743     return new_alloc;
   5744   }
   5745   if (!isolate->heap()->new_space()->Contains(new_object)) {
   5746     // Even if our string is small enough to fit in new space we still have to
   5747     // handle it being allocated in old space as may happen in the third
   5748     // attempt.  See CALL_AND_RETRY in heap-inl.h and similar code in
   5749     // CEntryStub::GenerateCore.
   5750     return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
   5751   }
   5752   StringType* new_string = StringType::cast(new_object);
   5753   ASSERT(isolate->heap()->new_space()->Contains(new_string));
   5754 
   5755   Char* write_cursor = reinterpret_cast<Char*>(
   5756       new_string->address() + SeqString::kHeaderSize);
   5757   if (comma) *(write_cursor++) = ',';
   5758   write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
   5759                                                   write_cursor,
   5760                                                   characters);
   5761   int final_length = static_cast<int>(
   5762       write_cursor - reinterpret_cast<Char*>(
   5763           new_string->address() + SeqString::kHeaderSize));
   5764   isolate->heap()->new_space()->
   5765       template ShrinkStringAtAllocationBoundary<StringType>(
   5766           new_string, final_length);
   5767   return new_string;
   5768 }
   5769 
   5770 
   5771 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
   5772   NoHandleAllocation ha;
   5773   CONVERT_ARG_CHECKED(String, str, 0);
   5774   if (!str->IsFlat()) {
   5775     MaybeObject* try_flatten = str->TryFlatten();
   5776     Object* flat;
   5777     if (!try_flatten->ToObject(&flat)) {
   5778       return try_flatten;
   5779     }
   5780     str = String::cast(flat);
   5781     ASSERT(str->IsFlat());
   5782   }
   5783   String::FlatContent flat = str->GetFlatContent();
   5784   ASSERT(flat.IsFlat());
   5785   if (flat.IsTwoByte()) {
   5786     return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
   5787                                                           flat.ToUC16Vector());
   5788   } else {
   5789     return QuoteJsonString<char, SeqAsciiString, false>(isolate,
   5790                                                         flat.ToAsciiVector());
   5791   }
   5792 }
   5793 
   5794 
   5795 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) {
   5796   NoHandleAllocation ha;
   5797   CONVERT_ARG_CHECKED(String, str, 0);
   5798   if (!str->IsFlat()) {
   5799     MaybeObject* try_flatten = str->TryFlatten();
   5800     Object* flat;
   5801     if (!try_flatten->ToObject(&flat)) {
   5802       return try_flatten;
   5803     }
   5804     str = String::cast(flat);
   5805     ASSERT(str->IsFlat());
   5806   }
   5807   String::FlatContent flat = str->GetFlatContent();
   5808   if (flat.IsTwoByte()) {
   5809     return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
   5810                                                          flat.ToUC16Vector());
   5811   } else {
   5812     return QuoteJsonString<char, SeqAsciiString, true>(isolate,
   5813                                                        flat.ToAsciiVector());
   5814   }
   5815 }
   5816 
   5817 
   5818 template <typename Char, typename StringType>
   5819 static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
   5820                                          FixedArray* array,
   5821                                          int worst_case_length) {
   5822   int length = array->length();
   5823 
   5824   MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
   5825                                                          worst_case_length);
   5826   Object* new_object;
   5827   if (!new_alloc->ToObject(&new_object)) {
   5828     return new_alloc;
   5829   }
   5830   if (!isolate->heap()->new_space()->Contains(new_object)) {
   5831     // Even if our string is small enough to fit in new space we still have to
   5832     // handle it being allocated in old space as may happen in the third
   5833     // attempt.  See CALL_AND_RETRY in heap-inl.h and similar code in
   5834     // CEntryStub::GenerateCore.
   5835     return isolate->heap()->undefined_value();
   5836   }
   5837   AssertNoAllocation no_gc;
   5838   StringType* new_string = StringType::cast(new_object);
   5839   ASSERT(isolate->heap()->new_space()->Contains(new_string));
   5840 
   5841   Char* write_cursor = reinterpret_cast<Char*>(
   5842       new_string->address() + SeqString::kHeaderSize);
   5843   *(write_cursor++) = '[';
   5844   for (int i = 0; i < length; i++) {
   5845     if (i != 0) *(write_cursor++) = ',';
   5846     String* str = String::cast(array->get(i));
   5847     String::FlatContent content = str->GetFlatContent();
   5848     ASSERT(content.IsFlat());
   5849     if (content.IsTwoByte()) {
   5850       write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
   5851                                                       write_cursor,
   5852                                                       content.ToUC16Vector());
   5853     } else {
   5854       write_cursor = WriteQuoteJsonString<Char, char>(isolate,
   5855                                                       write_cursor,
   5856                                                       content.ToAsciiVector());
   5857     }
   5858   }
   5859   *(write_cursor++) = ']';
   5860 
   5861   int final_length = static_cast<int>(
   5862       write_cursor - reinterpret_cast<Char*>(
   5863           new_string->address() + SeqString::kHeaderSize));
   5864   isolate->heap()->new_space()->
   5865       template ShrinkStringAtAllocationBoundary<StringType>(
   5866           new_string, final_length);
   5867   return new_string;
   5868 }
   5869 
   5870 
   5871 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
   5872   NoHandleAllocation ha;
   5873   ASSERT(args.length() == 1);
   5874   CONVERT_ARG_CHECKED(JSArray, array, 0);
   5875 
   5876   if (!array->HasFastElements()) return isolate->heap()->undefined_value();
   5877   FixedArray* elements = FixedArray::cast(array->elements());
   5878   int n = elements->length();
   5879   bool ascii = true;
   5880   int total_length = 0;
   5881 
   5882   for (int i = 0; i < n; i++) {
   5883     Object* elt = elements->get(i);
   5884     if (!elt->IsString()) return isolate->heap()->undefined_value();
   5885     String* element = String::cast(elt);
   5886     if (!element->IsFlat()) return isolate->heap()->undefined_value();
   5887     total_length += element->length();
   5888     if (ascii && element->IsTwoByteRepresentation()) {
   5889       ascii = false;
   5890     }
   5891   }
   5892 
   5893   int worst_case_length =
   5894       kSpaceForBrackets + n * kSpaceForQuotesAndComma
   5895       + total_length * kJsonQuoteWorstCaseBlowup;
   5896 
   5897   if (worst_case_length > kMaxGuaranteedNewSpaceString) {
   5898     return isolate->heap()->undefined_value();
   5899   }
   5900 
   5901   if (ascii) {
   5902     return QuoteJsonStringArray<char, SeqAsciiString>(isolate,
   5903                                                       elements,
   5904                                                       worst_case_length);
   5905   } else {
   5906     return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate,
   5907                                                         elements,
   5908                                                         worst_case_length);
   5909   }
   5910 }
   5911 
   5912 
   5913 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
   5914   NoHandleAllocation ha;
   5915 
   5916   CONVERT_ARG_CHECKED(String, s, 0);
   5917   CONVERT_SMI_ARG_CHECKED(radix, 1);
   5918 
   5919   s->TryFlatten();
   5920 
   5921   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
   5922   double value = StringToInt(isolate->unicode_cache(), s, radix);
   5923   return isolate->heap()->NumberFromDouble(value);
   5924 }
   5925 
   5926 
   5927 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
   5928   NoHandleAllocation ha;
   5929   CONVERT_ARG_CHECKED(String, str, 0);
   5930 
   5931   // ECMA-262 section 15.1.2.3, empty string is NaN
   5932   double value = StringToDouble(isolate->unicode_cache(),
   5933                                 str, ALLOW_TRAILING_JUNK, OS::nan_value());
   5934 
   5935   // Create a number object from the value.
   5936   return isolate->heap()->NumberFromDouble(value);
   5937 }
   5938 
   5939 
   5940 template <class Converter>
   5941 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
   5942     Isolate* isolate,
   5943     String* s,
   5944     int length,
   5945     int input_string_length,
   5946     unibrow::Mapping<Converter, 128>* mapping) {
   5947   // We try this twice, once with the assumption that the result is no longer
   5948   // than the input and, if that assumption breaks, again with the exact
   5949   // length.  This may not be pretty, but it is nicer than what was here before
   5950   // and I hereby claim my vaffel-is.
   5951   //
   5952   // Allocate the resulting string.
   5953   //
   5954   // NOTE: This assumes that the upper/lower case of an ASCII
   5955   // character is also ASCII.  This is currently the case, but it
   5956   // might break in the future if we implement more context and locale
   5957   // dependent upper/lower conversions.
   5958   Object* o;
   5959   { MaybeObject* maybe_o = s->IsAsciiRepresentation()
   5960         ? isolate->heap()->AllocateRawAsciiString(length)
   5961         : isolate->heap()->AllocateRawTwoByteString(length);
   5962     if (!maybe_o->ToObject(&o)) return maybe_o;
   5963   }
   5964   String* result = String::cast(o);
   5965   bool has_changed_character = false;
   5966 
   5967   // Convert all characters to upper case, assuming that they will fit
   5968   // in the buffer
   5969   Access<StringInputBuffer> buffer(
   5970       isolate->runtime_state()->string_input_buffer());
   5971   buffer->Reset(s);
   5972   unibrow::uchar chars[Converter::kMaxWidth];
   5973   // We can assume that the string is not empty
   5974   uc32 current = buffer->GetNext();
   5975   for (int i = 0; i < length;) {
   5976     bool has_next = buffer->has_more();
   5977     uc32 next = has_next ? buffer->GetNext() : 0;
   5978     int char_length = mapping->get(current, next, chars);
   5979     if (char_length == 0) {
   5980       // The case conversion of this character is the character itself.
   5981       result->Set(i, current);
   5982       i++;
   5983     } else if (char_length == 1) {
   5984       // Common case: converting the letter resulted in one character.
   5985       ASSERT(static_cast<uc32>(chars[0]) != current);
   5986       result->Set(i, chars[0]);
   5987       has_changed_character = true;
   5988       i++;
   5989     } else if (length == input_string_length) {
   5990       // We've assumed that the result would be as long as the
   5991       // input but here is a character that converts to several
   5992       // characters.  No matter, we calculate the exact length
   5993       // of the result and try the whole thing again.
   5994       //
   5995       // Note that this leaves room for optimization.  We could just
   5996       // memcpy what we already have to the result string.  Also,
   5997       // the result string is the last object allocated we could
   5998       // "realloc" it and probably, in the vast majority of cases,
   5999       // extend the existing string to be able to hold the full
   6000       // result.
   6001       int next_length = 0;
   6002       if (has_next) {
   6003         next_length = mapping->get(next, 0, chars);
   6004         if (next_length == 0) next_length = 1;
   6005       }
   6006       int current_length = i + char_length + next_length;
   6007       while (buffer->has_more()) {
   6008         current = buffer->GetNext();
   6009         // NOTE: we use 0 as the next character here because, while
   6010         // the next character may affect what a character converts to,
   6011         // it does not in any case affect the length of what it convert
   6012         // to.
   6013         int char_length = mapping->get(current, 0, chars);
   6014         if (char_length == 0) char_length = 1;
   6015         current_length += char_length;
   6016         if (current_length > Smi::kMaxValue) {
   6017           isolate->context()->mark_out_of_memory();
   6018           return Failure::OutOfMemoryException();
   6019         }
   6020       }
   6021       // Try again with the real length.
   6022       return Smi::FromInt(current_length);
   6023     } else {
   6024       for (int j = 0; j < char_length; j++) {
   6025         result->Set(i, chars[j]);
   6026         i++;
   6027       }
   6028       has_changed_character = true;
   6029     }
   6030     current = next;
   6031   }
   6032   if (has_changed_character) {
   6033     return result;
   6034   } else {
   6035     // If we didn't actually change anything in doing the conversion
   6036     // we simple return the result and let the converted string
   6037     // become garbage; there is no reason to keep two identical strings
   6038     // alive.
   6039     return s;
   6040   }
   6041 }
   6042 
   6043 
   6044 namespace {
   6045 
   6046 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
   6047 
   6048 
   6049 // Given a word and two range boundaries returns a word with high bit
   6050 // set in every byte iff the corresponding input byte was strictly in
   6051 // the range (m, n). All the other bits in the result are cleared.
   6052 // This function is only useful when it can be inlined and the
   6053 // boundaries are statically known.
   6054 // Requires: all bytes in the input word and the boundaries must be
   6055 // ASCII (less than 0x7F).
   6056 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
   6057   // Every byte in an ASCII string is less than or equal to 0x7F.
   6058   ASSERT((w & (kOneInEveryByte * 0x7F)) == w);
   6059   // Use strict inequalities since in edge cases the function could be
   6060   // further simplified.
   6061   ASSERT(0 < m && m < n && n < 0x7F);
   6062   // Has high bit set in every w byte less than n.
   6063   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   6064   // Has high bit set in every w byte greater than m.
   6065   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
   6066   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
   6067 }
   6068 
   6069 
   6070 enum AsciiCaseConversion {
   6071   ASCII_TO_LOWER,
   6072   ASCII_TO_UPPER
   6073 };
   6074 
   6075 
   6076 template <AsciiCaseConversion dir>
   6077 struct FastAsciiConverter {
   6078   static bool Convert(char* dst, char* src, int length) {
   6079 #ifdef DEBUG
   6080     char* saved_dst = dst;
   6081     char* saved_src = src;
   6082 #endif
   6083     // We rely on the distance between upper and lower case letters
   6084     // being a known power of 2.
   6085     ASSERT('a' - 'A' == (1 << 5));
   6086     // Boundaries for the range of input characters than require conversion.
   6087     const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1;
   6088     const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1;
   6089     bool changed = false;
   6090     char* const limit = src + length;
   6091 #ifdef V8_HOST_CAN_READ_UNALIGNED
   6092     // Process the prefix of the input that requires no conversion one
   6093     // (machine) word at a time.
   6094     while (src <= limit - sizeof(uintptr_t)) {
   6095       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
   6096       if (AsciiRangeMask(w, lo, hi) != 0) {
   6097         changed = true;
   6098         break;
   6099       }
   6100       *reinterpret_cast<uintptr_t*>(dst) = w;
   6101       src += sizeof(uintptr_t);
   6102       dst += sizeof(uintptr_t);
   6103     }
   6104     // Process the remainder of the input performing conversion when
   6105     // required one word at a time.
   6106     while (src <= limit - sizeof(uintptr_t)) {
   6107       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
   6108       uintptr_t m = AsciiRangeMask(w, lo, hi);
   6109       // The mask has high (7th) bit set in every byte that needs
   6110       // conversion and we know that the distance between cases is
   6111       // 1 << 5.
   6112       *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
   6113       src += sizeof(uintptr_t);
   6114       dst += sizeof(uintptr_t);
   6115     }
   6116 #endif
   6117     // Process the last few bytes of the input (or the whole input if
   6118     // unaligned access is not supported).
   6119     while (src < limit) {
   6120       char c = *src;
   6121       if (lo < c && c < hi) {
   6122         c ^= (1 << 5);
   6123         changed = true;
   6124       }
   6125       *dst = c;
   6126       ++src;
   6127       ++dst;
   6128     }
   6129 #ifdef DEBUG
   6130     CheckConvert(saved_dst, saved_src, length, changed);
   6131 #endif
   6132     return changed;
   6133   }
   6134 
   6135 #ifdef DEBUG
   6136   static void CheckConvert(char* dst, char* src, int length, bool changed) {
   6137     bool expected_changed = false;
   6138     for (int i = 0; i < length; i++) {
   6139       if (dst[i] == src[i]) continue;
   6140       expected_changed = true;
   6141       if (dir == ASCII_TO_LOWER) {
   6142         ASSERT('A' <= src[i] && src[i] <= 'Z');
   6143         ASSERT(dst[i] == src[i] + ('a' - 'A'));
   6144       } else {
   6145         ASSERT(dir == ASCII_TO_UPPER);
   6146         ASSERT('a' <= src[i] && src[i] <= 'z');
   6147         ASSERT(dst[i] == src[i] - ('a' - 'A'));
   6148       }
   6149     }
   6150     ASSERT(expected_changed == changed);
   6151   }
   6152 #endif
   6153 };
   6154 
   6155 
   6156 struct ToLowerTraits {
   6157   typedef unibrow::ToLowercase UnibrowConverter;
   6158 
   6159   typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter;
   6160 };
   6161 
   6162 
   6163 struct ToUpperTraits {
   6164   typedef unibrow::ToUppercase UnibrowConverter;
   6165 
   6166   typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter;
   6167 };
   6168 
   6169 }  // namespace
   6170 
   6171 
   6172 template <typename ConvertTraits>
   6173 MUST_USE_RESULT static MaybeObject* ConvertCase(
   6174     Arguments args,
   6175     Isolate* isolate,
   6176     unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
   6177   NoHandleAllocation ha;
   6178   CONVERT_ARG_CHECKED(String, s, 0);
   6179   s = s->TryFlattenGetString();
   6180 
   6181   const int length = s->length();
   6182   // Assume that the string is not empty; we need this assumption later
   6183   if (length == 0) return s;
   6184 
   6185   // Simpler handling of ASCII strings.
   6186   //
   6187   // NOTE: This assumes that the upper/lower case of an ASCII
   6188   // character is also ASCII.  This is currently the case, but it
   6189   // might break in the future if we implement more context and locale
   6190   // dependent upper/lower conversions.
   6191   if (s->IsSeqAsciiString()) {
   6192     Object* o;
   6193     { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length);
   6194       if (!maybe_o->ToObject(&o)) return maybe_o;
   6195     }
   6196     SeqAsciiString* result = SeqAsciiString::cast(o);
   6197     bool has_changed_character = ConvertTraits::AsciiConverter::Convert(
   6198         result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length);
   6199     return has_changed_character ? result : s;
   6200   }
   6201 
   6202   Object* answer;
   6203   { MaybeObject* maybe_answer =
   6204         ConvertCaseHelper(isolate, s, length, length, mapping);
   6205     if (!maybe_answer->ToObject(&answer)) return maybe_answer;
   6206   }
   6207   if (answer->IsSmi()) {
   6208     // Retry with correct length.
   6209     { MaybeObject* maybe_answer =
   6210           ConvertCaseHelper(isolate,
   6211                             s, Smi::cast(answer)->value(), length, mapping);
   6212       if (!maybe_answer->ToObject(&answer)) return maybe_answer;
   6213     }
   6214   }
   6215   return answer;
   6216 }
   6217 
   6218 
   6219 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
   6220   return ConvertCase<ToLowerTraits>(
   6221       args, isolate, isolate->runtime_state()->to_lower_mapping());
   6222 }
   6223 
   6224 
   6225 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
   6226   return ConvertCase<ToUpperTraits>(
   6227       args, isolate, isolate->runtime_state()->to_upper_mapping());
   6228 }
   6229 
   6230 
   6231 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
   6232   return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
   6233 }
   6234 
   6235 
   6236 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
   6237   NoHandleAllocation ha;
   6238   ASSERT(args.length() == 3);
   6239 
   6240   CONVERT_ARG_CHECKED(String, s, 0);
   6241   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
   6242   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
   6243 
   6244   s->TryFlatten();
   6245   int length = s->length();
   6246 
   6247   int left = 0;
   6248   if (trimLeft) {
   6249     while (left < length && IsTrimWhiteSpace(s->Get(left))) {
   6250       left++;
   6251     }
   6252   }
   6253 
   6254   int right = length;
   6255   if (trimRight) {
   6256     while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) {
   6257       right--;
   6258     }
   6259   }
   6260   return s->SubString(left, right);
   6261 }
   6262 
   6263 
   6264 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
   6265   ASSERT(args.length() == 3);
   6266   HandleScope handle_scope(isolate);
   6267   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
   6268   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
   6269   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
   6270 
   6271   int subject_length = subject->length();
   6272   int pattern_length = pattern->length();
   6273   RUNTIME_ASSERT(pattern_length > 0);
   6274 
   6275   if (limit == 0xffffffffu) {
   6276     Handle<Object> cached_answer(StringSplitCache::Lookup(
   6277         isolate->heap()->string_split_cache(),
   6278         *subject,
   6279         *pattern));
   6280     if (*cached_answer != Smi::FromInt(0)) {
   6281       Handle<JSArray> result =
   6282           isolate->factory()->NewJSArrayWithElements(
   6283               Handle<FixedArray>::cast(cached_answer));
   6284       return *result;
   6285     }
   6286   }
   6287 
   6288   // The limit can be very large (0xffffffffu), but since the pattern
   6289   // isn't empty, we can never create more parts than ~half the length
   6290   // of the subject.
   6291 
   6292   if (!subject->IsFlat()) FlattenString(subject);
   6293 
   6294   static const int kMaxInitialListCapacity = 16;
   6295 
   6296   ZoneScope scope(isolate, DELETE_ON_EXIT);
   6297 
   6298   // Find (up to limit) indices of separator and end-of-string in subject
   6299   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
   6300   ZoneList<int> indices(initial_capacity);
   6301   if (!pattern->IsFlat()) FlattenString(pattern);
   6302 
   6303   FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit);
   6304 
   6305   if (static_cast<uint32_t>(indices.length()) < limit) {
   6306     indices.Add(subject_length);
   6307   }
   6308 
   6309   // The list indices now contains the end of each part to create.
   6310 
   6311   // Create JSArray of substrings separated by separator.
   6312   int part_count = indices.length();
   6313 
   6314   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
   6315   MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements();
   6316   if (maybe_result->IsFailure()) return maybe_result;
   6317   result->set_length(Smi::FromInt(part_count));
   6318 
   6319   ASSERT(result->HasFastElements());
   6320 
   6321   if (part_count == 1 && indices.at(0) == subject_length) {
   6322     FixedArray::cast(result->elements())->set(0, *subject);
   6323     return *result;
   6324   }
   6325 
   6326   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
   6327   int part_start = 0;
   6328   for (int i = 0; i < part_count; i++) {
   6329     HandleScope local_loop_handle;
   6330     int part_end = indices.at(i);
   6331     Handle<String> substring =
   6332         isolate->factory()->NewProperSubString(subject, part_start, part_end);
   6333     elements->set(i, *substring);
   6334     part_start = part_end + pattern_length;
   6335   }
   6336 
   6337   if (limit == 0xffffffffu) {
   6338     if (result->HasFastElements()) {
   6339       StringSplitCache::Enter(isolate->heap(),
   6340                               isolate->heap()->string_split_cache(),
   6341                               *subject,
   6342                               *pattern,
   6343                               *elements);
   6344     }
   6345   }
   6346 
   6347   return *result;
   6348 }
   6349 
   6350 
   6351 // Copies ASCII characters to the given fixed array looking up
   6352 // one-char strings in the cache. Gives up on the first char that is
   6353 // not in the cache and fills the remainder with smi zeros. Returns
   6354 // the length of the successfully copied prefix.
   6355 static int CopyCachedAsciiCharsToArray(Heap* heap,
   6356                                        const char* chars,
   6357                                        FixedArray* elements,
   6358                                        int length) {
   6359   AssertNoAllocation no_gc;
   6360   FixedArray* ascii_cache = heap->single_character_string_cache();
   6361   Object* undefined = heap->undefined_value();
   6362   int i;
   6363   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
   6364   for (i = 0; i < length; ++i) {
   6365     Object* value = ascii_cache->get(chars[i]);
   6366     if (value == undefined) break;
   6367     elements->set(i, value, mode);
   6368   }
   6369   if (i < length) {
   6370     ASSERT(Smi::FromInt(0) == 0);
   6371     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
   6372   }
   6373 #ifdef DEBUG
   6374   for (int j = 0; j < length; ++j) {
   6375     Object* element = elements->get(j);
   6376     ASSERT(element == Smi::FromInt(0) ||
   6377            (element->IsString() && String::cast(element)->LooksValid()));
   6378   }
   6379 #endif
   6380   return i;
   6381 }
   6382 
   6383 
   6384 // Converts a String to JSArray.
   6385 // For example, "foo" => ["f", "o", "o"].
   6386 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
   6387   HandleScope scope(isolate);
   6388   ASSERT(args.length() == 2);
   6389   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
   6390   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   6391 
   6392   s = FlattenGetString(s);
   6393   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
   6394 
   6395   Handle<FixedArray> elements;
   6396   int position = 0;
   6397   if (s->IsFlat() && s->IsAsciiRepresentation()) {
   6398     // Try using cached chars where possible.
   6399     Object* obj;
   6400     { MaybeObject* maybe_obj =
   6401           isolate->heap()->AllocateUninitializedFixedArray(length);
   6402       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   6403     }
   6404     elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
   6405     String::FlatContent content = s->GetFlatContent();
   6406     if (content.IsAscii()) {
   6407       Vector<const char> chars = content.ToAsciiVector();
   6408       // Note, this will initialize all elements (not only the prefix)
   6409       // to prevent GC from seeing partially initialized array.
   6410       position = CopyCachedAsciiCharsToArray(isolate->heap(),
   6411                                              chars.start(),
   6412                                              *elements,
   6413                                              length);
   6414     } else {
   6415       MemsetPointer(elements->data_start(),
   6416                     isolate->heap()->undefined_value(),
   6417                     length);
   6418     }
   6419   } else {
   6420     elements = isolate->factory()->NewFixedArray(length);
   6421   }
   6422   for (int i = position; i < length; ++i) {
   6423     Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
   6424     elements->set(i, *str);
   6425   }
   6426 
   6427 #ifdef DEBUG
   6428   for (int i = 0; i < length; ++i) {
   6429     ASSERT(String::cast(elements->get(i))->length() == 1);
   6430   }
   6431 #endif
   6432 
   6433   return *isolate->factory()->NewJSArrayWithElements(elements);
   6434 }
   6435 
   6436 
   6437 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
   6438   NoHandleAllocation ha;
   6439   ASSERT(args.length() == 1);
   6440   CONVERT_ARG_CHECKED(String, value, 0);
   6441   return value->ToObject();
   6442 }
   6443 
   6444 
   6445 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
   6446   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
   6447   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
   6448   return char_length == 0;
   6449 }
   6450 
   6451 
   6452 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToString) {
   6453   NoHandleAllocation ha;
   6454   ASSERT(args.length() == 1);
   6455 
   6456   Object* number = args[0];
   6457   RUNTIME_ASSERT(number->IsNumber());
   6458 
   6459   return isolate->heap()->NumberToString(number);
   6460 }
   6461 
   6462 
   6463 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToStringSkipCache) {
   6464   NoHandleAllocation ha;
   6465   ASSERT(args.length() == 1);
   6466 
   6467   Object* number = args[0];
   6468   RUNTIME_ASSERT(number->IsNumber());
   6469 
   6470   return isolate->heap()->NumberToString(number, false);
   6471 }
   6472 
   6473 
   6474 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
   6475   NoHandleAllocation ha;
   6476   ASSERT(args.length() == 1);
   6477 
   6478   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6479 
   6480   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6481   if (number > 0 && number <= Smi::kMaxValue) {
   6482     return Smi::FromInt(static_cast<int>(number));
   6483   }
   6484   return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
   6485 }
   6486 
   6487 
   6488 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
   6489   NoHandleAllocation ha;
   6490   ASSERT(args.length() == 1);
   6491 
   6492   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6493 
   6494   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6495   if (number > 0 && number <= Smi::kMaxValue) {
   6496     return Smi::FromInt(static_cast<int>(number));
   6497   }
   6498 
   6499   double double_value = DoubleToInteger(number);
   6500   // Map both -0 and +0 to +0.
   6501   if (double_value == 0) double_value = 0;
   6502 
   6503   return isolate->heap()->NumberFromDouble(double_value);
   6504 }
   6505 
   6506 
   6507 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) {
   6508   NoHandleAllocation ha;
   6509   ASSERT(args.length() == 1);
   6510 
   6511   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
   6512   return isolate->heap()->NumberFromUint32(number);
   6513 }
   6514 
   6515 
   6516 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
   6517   NoHandleAllocation ha;
   6518   ASSERT(args.length() == 1);
   6519 
   6520   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
   6521 
   6522   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   6523   if (number > 0 && number <= Smi::kMaxValue) {
   6524     return Smi::FromInt(static_cast<int>(number));
   6525   }
   6526   return isolate->heap()->NumberFromInt32(DoubleToInt32(number));
   6527 }
   6528 
   6529 
   6530 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
   6531 // a small integer.
   6532 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToSmi) {
   6533   NoHandleAllocation ha;
   6534   ASSERT(args.length() == 1);
   6535 
   6536   Object* obj = args[0];
   6537   if (obj->IsSmi()) {
   6538     return obj;
   6539   }
   6540   if (obj->IsHeapNumber()) {
   6541     double value = HeapNumber::cast(obj)->value();
   6542     int int_value = FastD2I(value);
   6543     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
   6544       return Smi::FromInt(int_value);
   6545     }
   6546   }
   6547   return isolate->heap()->nan_value();
   6548 }
   6549 
   6550 
   6551 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateHeapNumber) {
   6552   NoHandleAllocation ha;
   6553   ASSERT(args.length() == 0);
   6554   return isolate->heap()->AllocateHeapNumber(0);
   6555 }
   6556 
   6557 
   6558 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
   6559   NoHandleAllocation ha;
   6560   ASSERT(args.length() == 2);
   6561 
   6562   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6563   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6564   return isolate->heap()->NumberFromDouble(x + y);
   6565 }
   6566 
   6567 
   6568 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
   6569   NoHandleAllocation ha;
   6570   ASSERT(args.length() == 2);
   6571 
   6572   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6573   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6574   return isolate->heap()->NumberFromDouble(x - y);
   6575 }
   6576 
   6577 
   6578 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
   6579   NoHandleAllocation ha;
   6580   ASSERT(args.length() == 2);
   6581 
   6582   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6583   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6584   return isolate->heap()->NumberFromDouble(x * y);
   6585 }
   6586 
   6587 
   6588 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
   6589   NoHandleAllocation ha;
   6590   ASSERT(args.length() == 1);
   6591 
   6592   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6593   return isolate->heap()->NumberFromDouble(-x);
   6594 }
   6595 
   6596 
   6597 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) {
   6598   NoHandleAllocation ha;
   6599   ASSERT(args.length() == 0);
   6600 
   6601   return isolate->heap()->NumberFromDouble(9876543210.0);
   6602 }
   6603 
   6604 
   6605 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
   6606   NoHandleAllocation ha;
   6607   ASSERT(args.length() == 2);
   6608 
   6609   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6610   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6611   return isolate->heap()->NumberFromDouble(x / y);
   6612 }
   6613 
   6614 
   6615 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
   6616   NoHandleAllocation ha;
   6617   ASSERT(args.length() == 2);
   6618 
   6619   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   6620   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   6621 
   6622   x = modulo(x, y);
   6623   // NumberFromDouble may return a Smi instead of a Number object
   6624   return isolate->heap()->NumberFromDouble(x);
   6625 }
   6626 
   6627 
   6628 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) {
   6629   NoHandleAllocation ha;
   6630   ASSERT(args.length() == 2);
   6631   CONVERT_ARG_CHECKED(String, str1, 0);
   6632   CONVERT_ARG_CHECKED(String, str2, 1);
   6633   isolate->counters()->string_add_runtime()->Increment();
   6634   return isolate->heap()->AllocateConsString(str1, str2);
   6635 }
   6636 
   6637 
   6638 template <typename sinkchar>
   6639 static inline void StringBuilderConcatHelper(String* special,
   6640                                              sinkchar* sink,
   6641                                              FixedArray* fixed_array,
   6642                                              int array_length) {
   6643   int position = 0;
   6644   for (int i = 0; i < array_length; i++) {
   6645     Object* element = fixed_array->get(i);
   6646     if (element->IsSmi()) {
   6647       // Smi encoding of position and length.
   6648       int encoded_slice = Smi::cast(element)->value();
   6649       int pos;
   6650       int len;
   6651       if (encoded_slice > 0) {
   6652         // Position and length encoded in one smi.
   6653         pos = StringBuilderSubstringPosition::decode(encoded_slice);
   6654         len = StringBuilderSubstringLength::decode(encoded_slice);
   6655       } else {
   6656         // Position and length encoded in two smis.
   6657         Object* obj = fixed_array->get(++i);
   6658         ASSERT(obj->IsSmi());
   6659         pos = Smi::cast(obj)->value();
   6660         len = -encoded_slice;
   6661       }
   6662       String::WriteToFlat(special,
   6663                           sink + position,
   6664                           pos,
   6665                           pos + len);
   6666       position += len;
   6667     } else {
   6668       String* string = String::cast(element);
   6669       int element_length = string->length();
   6670       String::WriteToFlat(string, sink + position, 0, element_length);
   6671       position += element_length;
   6672     }
   6673   }
   6674 }
   6675 
   6676 
   6677 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
   6678   NoHandleAllocation ha;
   6679   ASSERT(args.length() == 3);
   6680   CONVERT_ARG_CHECKED(JSArray, array, 0);
   6681   if (!args[1]->IsSmi()) {
   6682     isolate->context()->mark_out_of_memory();
   6683     return Failure::OutOfMemoryException();
   6684   }
   6685   int array_length = args.smi_at(1);
   6686   CONVERT_ARG_CHECKED(String, special, 2);
   6687 
   6688   // This assumption is used by the slice encoding in one or two smis.
   6689   ASSERT(Smi::kMaxValue >= String::kMaxLength);
   6690 
   6691   MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements();
   6692   if (maybe_result->IsFailure()) return maybe_result;
   6693 
   6694   int special_length = special->length();
   6695   if (!array->HasFastElements()) {
   6696     return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6697   }
   6698   FixedArray* fixed_array = FixedArray::cast(array->elements());
   6699   if (fixed_array->length() < array_length) {
   6700     array_length = fixed_array->length();
   6701   }
   6702 
   6703   if (array_length == 0) {
   6704     return isolate->heap()->empty_string();
   6705   } else if (array_length == 1) {
   6706     Object* first = fixed_array->get(0);
   6707     if (first->IsString()) return first;
   6708   }
   6709 
   6710   bool ascii = special->HasOnlyAsciiChars();
   6711   int position = 0;
   6712   for (int i = 0; i < array_length; i++) {
   6713     int increment = 0;
   6714     Object* elt = fixed_array->get(i);
   6715     if (elt->IsSmi()) {
   6716       // Smi encoding of position and length.
   6717       int smi_value = Smi::cast(elt)->value();
   6718       int pos;
   6719       int len;
   6720       if (smi_value > 0) {
   6721         // Position and length encoded in one smi.
   6722         pos = StringBuilderSubstringPosition::decode(smi_value);
   6723         len = StringBuilderSubstringLength::decode(smi_value);
   6724       } else {
   6725         // Position and length encoded in two smis.
   6726         len = -smi_value;
   6727         // Get the position and check that it is a positive smi.
   6728         i++;
   6729         if (i >= array_length) {
   6730           return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6731         }
   6732         Object* next_smi = fixed_array->get(i);
   6733         if (!next_smi->IsSmi()) {
   6734           return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6735         }
   6736         pos = Smi::cast(next_smi)->value();
   6737         if (pos < 0) {
   6738           return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6739         }
   6740       }
   6741       ASSERT(pos >= 0);
   6742       ASSERT(len >= 0);
   6743       if (pos > special_length || len > special_length - pos) {
   6744         return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6745       }
   6746       increment = len;
   6747     } else if (elt->IsString()) {
   6748       String* element = String::cast(elt);
   6749       int element_length = element->length();
   6750       increment = element_length;
   6751       if (ascii && !element->HasOnlyAsciiChars()) {
   6752         ascii = false;
   6753       }
   6754     } else {
   6755       ASSERT(!elt->IsTheHole());
   6756       return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6757     }
   6758     if (increment > String::kMaxLength - position) {
   6759       isolate->context()->mark_out_of_memory();
   6760       return Failure::OutOfMemoryException();
   6761     }
   6762     position += increment;
   6763   }
   6764 
   6765   int length = position;
   6766   Object* object;
   6767 
   6768   if (ascii) {
   6769     { MaybeObject* maybe_object =
   6770           isolate->heap()->AllocateRawAsciiString(length);
   6771       if (!maybe_object->ToObject(&object)) return maybe_object;
   6772     }
   6773     SeqAsciiString* answer = SeqAsciiString::cast(object);
   6774     StringBuilderConcatHelper(special,
   6775                               answer->GetChars(),
   6776                               fixed_array,
   6777                               array_length);
   6778     return answer;
   6779   } else {
   6780     { MaybeObject* maybe_object =
   6781           isolate->heap()->AllocateRawTwoByteString(length);
   6782       if (!maybe_object->ToObject(&object)) return maybe_object;
   6783     }
   6784     SeqTwoByteString* answer = SeqTwoByteString::cast(object);
   6785     StringBuilderConcatHelper(special,
   6786                               answer->GetChars(),
   6787                               fixed_array,
   6788                               array_length);
   6789     return answer;
   6790   }
   6791 }
   6792 
   6793 
   6794 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
   6795   NoHandleAllocation ha;
   6796   ASSERT(args.length() == 3);
   6797   CONVERT_ARG_CHECKED(JSArray, array, 0);
   6798   if (!args[1]->IsSmi()) {
   6799     isolate->context()->mark_out_of_memory();
   6800     return Failure::OutOfMemoryException();
   6801   }
   6802   int array_length = args.smi_at(1);
   6803   CONVERT_ARG_CHECKED(String, separator, 2);
   6804 
   6805   if (!array->HasFastElements()) {
   6806     return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6807   }
   6808   FixedArray* fixed_array = FixedArray::cast(array->elements());
   6809   if (fixed_array->length() < array_length) {
   6810     array_length = fixed_array->length();
   6811   }
   6812 
   6813   if (array_length == 0) {
   6814     return isolate->heap()->empty_string();
   6815   } else if (array_length == 1) {
   6816     Object* first = fixed_array->get(0);
   6817     if (first->IsString()) return first;
   6818   }
   6819 
   6820   int separator_length = separator->length();
   6821   int max_nof_separators =
   6822       (String::kMaxLength + separator_length - 1) / separator_length;
   6823   if (max_nof_separators < (array_length - 1)) {
   6824       isolate->context()->mark_out_of_memory();
   6825       return Failure::OutOfMemoryException();
   6826   }
   6827   int length = (array_length - 1) * separator_length;
   6828   for (int i = 0; i < array_length; i++) {
   6829     Object* element_obj = fixed_array->get(i);
   6830     if (!element_obj->IsString()) {
   6831       // TODO(1161): handle this case.
   6832       return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   6833     }
   6834     String* element = String::cast(element_obj);
   6835     int increment = element->length();
   6836     if (increment > String::kMaxLength - length) {
   6837       isolate->context()->mark_out_of_memory();
   6838       return Failure::OutOfMemoryException();
   6839     }
   6840     length += increment;
   6841   }
   6842 
   6843   Object* object;
   6844   { MaybeObject* maybe_object =
   6845         isolate->heap()->AllocateRawTwoByteString(length);
   6846     if (!maybe_object->ToObject(&object)) return maybe_object;
   6847   }
   6848   SeqTwoByteString* answer = SeqTwoByteString::cast(object);
   6849 
   6850   uc16* sink = answer->GetChars();
   6851 #ifdef DEBUG
   6852   uc16* end = sink + length;
   6853 #endif
   6854 
   6855   String* first = String::cast(fixed_array->get(0));
   6856   int first_length = first->length();
   6857   String::WriteToFlat(first, sink, 0, first_length);
   6858   sink += first_length;
   6859 
   6860   for (int i = 1; i < array_length; i++) {
   6861     ASSERT(sink + separator_length <= end);
   6862     String::WriteToFlat(separator, sink, 0, separator_length);
   6863     sink += separator_length;
   6864 
   6865     String* element = String::cast(fixed_array->get(i));
   6866     int element_length = element->length();
   6867     ASSERT(sink + element_length <= end);
   6868     String::WriteToFlat(element, sink, 0, element_length);
   6869     sink += element_length;
   6870   }
   6871   ASSERT(sink == end);
   6872 
   6873   ASSERT(!answer->HasOnlyAsciiChars());  // Use %_FastAsciiArrayJoin instead.
   6874   return answer;
   6875 }
   6876 
   6877 template <typename Char>
   6878 static void JoinSparseArrayWithSeparator(FixedArray* elements,
   6879                                          int elements_length,
   6880                                          uint32_t array_length,
   6881                                          String* separator,
   6882                                          Vector<Char> buffer) {
   6883   int previous_separator_position = 0;
   6884   int separator_length = separator->length();
   6885   int cursor = 0;
   6886   for (int i = 0; i < elements_length; i += 2) {
   6887     int position = NumberToInt32(elements->get(i));
   6888     String* string = String::cast(elements->get(i + 1));
   6889     int string_length = string->length();
   6890     if (string->length() > 0) {
   6891       while (previous_separator_position < position) {
   6892         String::WriteToFlat<Char>(separator, &buffer[cursor],
   6893                                   0, separator_length);
   6894         cursor += separator_length;
   6895         previous_separator_position++;
   6896       }
   6897       String::WriteToFlat<Char>(string, &buffer[cursor],
   6898                                 0, string_length);
   6899       cursor += string->length();
   6900     }
   6901   }
   6902   if (separator_length > 0) {
   6903     // Array length must be representable as a signed 32-bit number,
   6904     // otherwise the total string length would have been too large.
   6905     ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
   6906     int last_array_index = static_cast<int>(array_length - 1);
   6907     while (previous_separator_position < last_array_index) {
   6908       String::WriteToFlat<Char>(separator, &buffer[cursor],
   6909                                 0, separator_length);
   6910       cursor += separator_length;
   6911       previous_separator_position++;
   6912     }
   6913   }
   6914   ASSERT(cursor <= buffer.length());
   6915 }
   6916 
   6917 
   6918 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
   6919   NoHandleAllocation ha;
   6920   ASSERT(args.length() == 3);
   6921   CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
   6922   RUNTIME_ASSERT(elements_array->HasFastElements() ||
   6923                  elements_array->HasFastSmiOnlyElements());
   6924   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
   6925   CONVERT_ARG_CHECKED(String, separator, 2);
   6926   // elements_array is fast-mode JSarray of alternating positions
   6927   // (increasing order) and strings.
   6928   // array_length is length of original array (used to add separators);
   6929   // separator is string to put between elements. Assumed to be non-empty.
   6930 
   6931   // Find total length of join result.
   6932   int string_length = 0;
   6933   bool is_ascii = separator->IsAsciiRepresentation();
   6934   int max_string_length;
   6935   if (is_ascii) {
   6936     max_string_length = SeqAsciiString::kMaxLength;
   6937   } else {
   6938     max_string_length = SeqTwoByteString::kMaxLength;
   6939   }
   6940   bool overflow = false;
   6941   CONVERT_NUMBER_CHECKED(int, elements_length,
   6942                          Int32, elements_array->length());
   6943   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
   6944   FixedArray* elements = FixedArray::cast(elements_array->elements());
   6945   for (int i = 0; i < elements_length; i += 2) {
   6946     RUNTIME_ASSERT(elements->get(i)->IsNumber());
   6947     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
   6948     String* string = String::cast(elements->get(i + 1));
   6949     int length = string->length();
   6950     if (is_ascii && !string->IsAsciiRepresentation()) {
   6951       is_ascii = false;
   6952       max_string_length = SeqTwoByteString::kMaxLength;
   6953     }
   6954     if (length > max_string_length ||
   6955         max_string_length - length < string_length) {
   6956       overflow = true;
   6957       break;
   6958     }
   6959     string_length += length;
   6960   }
   6961   int separator_length = separator->length();
   6962   if (!overflow && separator_length > 0) {
   6963     if (array_length <= 0x7fffffffu) {
   6964       int separator_count = static_cast<int>(array_length) - 1;
   6965       int remaining_length = max_string_length - string_length;
   6966       if ((remaining_length / separator_length) >= separator_count) {
   6967         string_length += separator_length * (array_length - 1);
   6968       } else {
   6969         // Not room for the separators within the maximal string length.
   6970         overflow = true;
   6971       }
   6972     } else {
   6973       // Nonempty separator and at least 2^31-1 separators necessary
   6974       // means that the string is too large to create.
   6975       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
   6976       overflow = true;
   6977     }
   6978   }
   6979   if (overflow) {
   6980     // Throw OutOfMemory exception for creating too large a string.
   6981     V8::FatalProcessOutOfMemory("Array join result too large.");
   6982   }
   6983 
   6984   if (is_ascii) {
   6985     MaybeObject* result_allocation =
   6986         isolate->heap()->AllocateRawAsciiString(string_length);
   6987     if (result_allocation->IsFailure()) return result_allocation;
   6988     SeqAsciiString* result_string =
   6989         SeqAsciiString::cast(result_allocation->ToObjectUnchecked());
   6990     JoinSparseArrayWithSeparator<char>(elements,
   6991                                        elements_length,
   6992                                        array_length,
   6993                                        separator,
   6994                                        Vector<char>(result_string->GetChars(),
   6995                                                     string_length));
   6996     return result_string;
   6997   } else {
   6998     MaybeObject* result_allocation =
   6999         isolate->heap()->AllocateRawTwoByteString(string_length);
   7000     if (result_allocation->IsFailure()) return result_allocation;
   7001     SeqTwoByteString* result_string =
   7002         SeqTwoByteString::cast(result_allocation->ToObjectUnchecked());
   7003     JoinSparseArrayWithSeparator<uc16>(elements,
   7004                                        elements_length,
   7005                                        array_length,
   7006                                        separator,
   7007                                        Vector<uc16>(result_string->GetChars(),
   7008                                                     string_length));
   7009     return result_string;
   7010   }
   7011 }
   7012 
   7013 
   7014 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberOr) {
   7015   NoHandleAllocation ha;
   7016   ASSERT(args.length() == 2);
   7017 
   7018   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7019   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7020   return isolate->heap()->NumberFromInt32(x | y);
   7021 }
   7022 
   7023 
   7024 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAnd) {
   7025   NoHandleAllocation ha;
   7026   ASSERT(args.length() == 2);
   7027 
   7028   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7029   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7030   return isolate->heap()->NumberFromInt32(x & y);
   7031 }
   7032 
   7033 
   7034 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) {
   7035   NoHandleAllocation ha;
   7036   ASSERT(args.length() == 2);
   7037 
   7038   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7039   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7040   return isolate->heap()->NumberFromInt32(x ^ y);
   7041 }
   7042 
   7043 
   7044 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberNot) {
   7045   NoHandleAllocation ha;
   7046   ASSERT(args.length() == 1);
   7047 
   7048   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7049   return isolate->heap()->NumberFromInt32(~x);
   7050 }
   7051 
   7052 
   7053 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) {
   7054   NoHandleAllocation ha;
   7055   ASSERT(args.length() == 2);
   7056 
   7057   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7058   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7059   return isolate->heap()->NumberFromInt32(x << (y & 0x1f));
   7060 }
   7061 
   7062 
   7063 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShr) {
   7064   NoHandleAllocation ha;
   7065   ASSERT(args.length() == 2);
   7066 
   7067   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
   7068   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7069   return isolate->heap()->NumberFromUint32(x >> (y & 0x1f));
   7070 }
   7071 
   7072 
   7073 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSar) {
   7074   NoHandleAllocation ha;
   7075   ASSERT(args.length() == 2);
   7076 
   7077   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
   7078   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
   7079   return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
   7080 }
   7081 
   7082 
   7083 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
   7084   NoHandleAllocation ha;
   7085   ASSERT(args.length() == 2);
   7086 
   7087   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7088   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7089   if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
   7090   if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
   7091   if (x == y) return Smi::FromInt(EQUAL);
   7092   Object* result;
   7093   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
   7094     result = Smi::FromInt(EQUAL);
   7095   } else {
   7096     result = Smi::FromInt(NOT_EQUAL);
   7097   }
   7098   return result;
   7099 }
   7100 
   7101 
   7102 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
   7103   NoHandleAllocation ha;
   7104   ASSERT(args.length() == 2);
   7105 
   7106   CONVERT_ARG_CHECKED(String, x, 0);
   7107   CONVERT_ARG_CHECKED(String, y, 1);
   7108 
   7109   bool not_equal = !x->Equals(y);
   7110   // This is slightly convoluted because the value that signifies
   7111   // equality is 0 and inequality is 1 so we have to negate the result
   7112   // from String::Equals.
   7113   ASSERT(not_equal == 0 || not_equal == 1);
   7114   STATIC_CHECK(EQUAL == 0);
   7115   STATIC_CHECK(NOT_EQUAL == 1);
   7116   return Smi::FromInt(not_equal);
   7117 }
   7118 
   7119 
   7120 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
   7121   NoHandleAllocation ha;
   7122   ASSERT(args.length() == 3);
   7123 
   7124   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7125   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7126   if (isnan(x) || isnan(y)) return args[2];
   7127   if (x == y) return Smi::FromInt(EQUAL);
   7128   if (isless(x, y)) return Smi::FromInt(LESS);
   7129   return Smi::FromInt(GREATER);
   7130 }
   7131 
   7132 
   7133 // Compare two Smis as if they were converted to strings and then
   7134 // compared lexicographically.
   7135 RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
   7136   NoHandleAllocation ha;
   7137   ASSERT(args.length() == 2);
   7138   CONVERT_SMI_ARG_CHECKED(x_value, 0);
   7139   CONVERT_SMI_ARG_CHECKED(y_value, 1);
   7140 
   7141   // If the integers are equal so are the string representations.
   7142   if (x_value == y_value) return Smi::FromInt(EQUAL);
   7143 
   7144   // If one of the integers is zero the normal integer order is the
   7145   // same as the lexicographic order of the string representations.
   7146   if (x_value == 0 || y_value == 0)
   7147     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
   7148 
   7149   // If only one of the integers is negative the negative number is
   7150   // smallest because the char code of '-' is less than the char code
   7151   // of any digit.  Otherwise, we make both values positive.
   7152 
   7153   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
   7154   // architectures using 32-bit Smis.
   7155   uint32_t x_scaled = x_value;
   7156   uint32_t y_scaled = y_value;
   7157   if (x_value < 0 || y_value < 0) {
   7158     if (y_value >= 0) return Smi::FromInt(LESS);
   7159     if (x_value >= 0) return Smi::FromInt(GREATER);
   7160     x_scaled = -x_value;
   7161     y_scaled = -y_value;
   7162   }
   7163 
   7164   static const uint32_t kPowersOf10[] = {
   7165     1, 10, 100, 1000, 10*1000, 100*1000,
   7166     1000*1000, 10*1000*1000, 100*1000*1000,
   7167     1000*1000*1000
   7168   };
   7169 
   7170   // If the integers have the same number of decimal digits they can be
   7171   // compared directly as the numeric order is the same as the
   7172   // lexicographic order.  If one integer has fewer digits, it is scaled
   7173   // by some power of 10 to have the same number of digits as the longer
   7174   // integer.  If the scaled integers are equal it means the shorter
   7175   // integer comes first in the lexicographic order.
   7176 
   7177   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
   7178   int x_log2 = IntegerLog2(x_scaled);
   7179   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
   7180   x_log10 -= x_scaled < kPowersOf10[x_log10];
   7181 
   7182   int y_log2 = IntegerLog2(y_scaled);
   7183   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
   7184   y_log10 -= y_scaled < kPowersOf10[y_log10];
   7185 
   7186   int tie = EQUAL;
   7187 
   7188   if (x_log10 < y_log10) {
   7189     // X has fewer digits.  We would like to simply scale up X but that
   7190     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
   7191     // be scaled up to 9_000_000_000. So we scale up by the next
   7192     // smallest power and scale down Y to drop one digit. It is OK to
   7193     // drop one digit from the longer integer since the final digit is
   7194     // past the length of the shorter integer.
   7195     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
   7196     y_scaled /= 10;
   7197     tie = LESS;
   7198   } else if (y_log10 < x_log10) {
   7199     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
   7200     x_scaled /= 10;
   7201     tie = GREATER;
   7202   }
   7203 
   7204   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
   7205   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
   7206   return Smi::FromInt(tie);
   7207 }
   7208 
   7209 
   7210 static Object* StringInputBufferCompare(RuntimeState* state,
   7211                                         String* x,
   7212                                         String* y) {
   7213   StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx();
   7214   StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy();
   7215   bufx.Reset(x);
   7216   bufy.Reset(y);
   7217   while (bufx.has_more() && bufy.has_more()) {
   7218     int d = bufx.GetNext() - bufy.GetNext();
   7219     if (d < 0) return Smi::FromInt(LESS);
   7220     else if (d > 0) return Smi::FromInt(GREATER);
   7221   }
   7222 
   7223   // x is (non-trivial) prefix of y:
   7224   if (bufy.has_more()) return Smi::FromInt(LESS);
   7225   // y is prefix of x:
   7226   return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
   7227 }
   7228 
   7229 
   7230 static Object* FlatStringCompare(String* x, String* y) {
   7231   ASSERT(x->IsFlat());
   7232   ASSERT(y->IsFlat());
   7233   Object* equal_prefix_result = Smi::FromInt(EQUAL);
   7234   int prefix_length = x->length();
   7235   if (y->length() < prefix_length) {
   7236     prefix_length = y->length();
   7237     equal_prefix_result = Smi::FromInt(GREATER);
   7238   } else if (y->length() > prefix_length) {
   7239     equal_prefix_result = Smi::FromInt(LESS);
   7240   }
   7241   int r;
   7242   String::FlatContent x_content = x->GetFlatContent();
   7243   String::FlatContent y_content = y->GetFlatContent();
   7244   if (x_content.IsAscii()) {
   7245     Vector<const char> x_chars = x_content.ToAsciiVector();
   7246     if (y_content.IsAscii()) {
   7247       Vector<const char> y_chars = y_content.ToAsciiVector();
   7248       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7249     } else {
   7250       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7251       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7252     }
   7253   } else {
   7254     Vector<const uc16> x_chars = x_content.ToUC16Vector();
   7255     if (y_content.IsAscii()) {
   7256       Vector<const char> y_chars = y_content.ToAsciiVector();
   7257       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7258     } else {
   7259       Vector<const uc16> y_chars = y_content.ToUC16Vector();
   7260       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
   7261     }
   7262   }
   7263   Object* result;
   7264   if (r == 0) {
   7265     result = equal_prefix_result;
   7266   } else {
   7267     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
   7268   }
   7269   ASSERT(result ==
   7270       StringInputBufferCompare(Isolate::Current()->runtime_state(), x, y));
   7271   return result;
   7272 }
   7273 
   7274 
   7275 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) {
   7276   NoHandleAllocation ha;
   7277   ASSERT(args.length() == 2);
   7278 
   7279   CONVERT_ARG_CHECKED(String, x, 0);
   7280   CONVERT_ARG_CHECKED(String, y, 1);
   7281 
   7282   isolate->counters()->string_compare_runtime()->Increment();
   7283 
   7284   // A few fast case tests before we flatten.
   7285   if (x == y) return Smi::FromInt(EQUAL);
   7286   if (y->length() == 0) {
   7287     if (x->length() == 0) return Smi::FromInt(EQUAL);
   7288     return Smi::FromInt(GREATER);
   7289   } else if (x->length() == 0) {
   7290     return Smi::FromInt(LESS);
   7291   }
   7292 
   7293   int d = x->Get(0) - y->Get(0);
   7294   if (d < 0) return Smi::FromInt(LESS);
   7295   else if (d > 0) return Smi::FromInt(GREATER);
   7296 
   7297   Object* obj;
   7298   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
   7299     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7300   }
   7301   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
   7302     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7303   }
   7304 
   7305   return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
   7306       : StringInputBufferCompare(isolate->runtime_state(), x, y);
   7307 }
   7308 
   7309 
   7310 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
   7311   NoHandleAllocation ha;
   7312   ASSERT(args.length() == 1);
   7313   isolate->counters()->math_acos()->Increment();
   7314 
   7315   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7316   return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
   7317 }
   7318 
   7319 
   7320 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
   7321   NoHandleAllocation ha;
   7322   ASSERT(args.length() == 1);
   7323   isolate->counters()->math_asin()->Increment();
   7324 
   7325   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7326   return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
   7327 }
   7328 
   7329 
   7330 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
   7331   NoHandleAllocation ha;
   7332   ASSERT(args.length() == 1);
   7333   isolate->counters()->math_atan()->Increment();
   7334 
   7335   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7336   return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
   7337 }
   7338 
   7339 
   7340 static const double kPiDividedBy4 = 0.78539816339744830962;
   7341 
   7342 
   7343 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
   7344   NoHandleAllocation ha;
   7345   ASSERT(args.length() == 2);
   7346   isolate->counters()->math_atan2()->Increment();
   7347 
   7348   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7349   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7350   double result;
   7351   if (isinf(x) && isinf(y)) {
   7352     // Make sure that the result in case of two infinite arguments
   7353     // is a multiple of Pi / 4. The sign of the result is determined
   7354     // by the first argument (x) and the sign of the second argument
   7355     // determines the multiplier: one or three.
   7356     int multiplier = (x < 0) ? -1 : 1;
   7357     if (y < 0) multiplier *= 3;
   7358     result = multiplier * kPiDividedBy4;
   7359   } else {
   7360     result = atan2(x, y);
   7361   }
   7362   return isolate->heap()->AllocateHeapNumber(result);
   7363 }
   7364 
   7365 
   7366 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
   7367   NoHandleAllocation ha;
   7368   ASSERT(args.length() == 1);
   7369   isolate->counters()->math_ceil()->Increment();
   7370 
   7371   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7372   return isolate->heap()->NumberFromDouble(ceiling(x));
   7373 }
   7374 
   7375 
   7376 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
   7377   NoHandleAllocation ha;
   7378   ASSERT(args.length() == 1);
   7379   isolate->counters()->math_cos()->Increment();
   7380 
   7381   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7382   return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
   7383 }
   7384 
   7385 
   7386 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
   7387   NoHandleAllocation ha;
   7388   ASSERT(args.length() == 1);
   7389   isolate->counters()->math_exp()->Increment();
   7390 
   7391   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7392   return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x);
   7393 }
   7394 
   7395 
   7396 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
   7397   NoHandleAllocation ha;
   7398   ASSERT(args.length() == 1);
   7399   isolate->counters()->math_floor()->Increment();
   7400 
   7401   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7402   return isolate->heap()->NumberFromDouble(floor(x));
   7403 }
   7404 
   7405 
   7406 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
   7407   NoHandleAllocation ha;
   7408   ASSERT(args.length() == 1);
   7409   isolate->counters()->math_log()->Increment();
   7410 
   7411   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7412   return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
   7413 }
   7414 
   7415 // Slow version of Math.pow.  We check for fast paths for special cases.
   7416 // Used if SSE2/VFP3 is not available.
   7417 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
   7418   NoHandleAllocation ha;
   7419   ASSERT(args.length() == 2);
   7420   isolate->counters()->math_pow()->Increment();
   7421 
   7422   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7423 
   7424   // If the second argument is a smi, it is much faster to call the
   7425   // custom powi() function than the generic pow().
   7426   if (args[1]->IsSmi()) {
   7427     int y = args.smi_at(1);
   7428     return isolate->heap()->NumberFromDouble(power_double_int(x, y));
   7429   }
   7430 
   7431   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7432   int y_int = static_cast<int>(y);
   7433   double result;
   7434   if (y == y_int) {
   7435     result = power_double_int(x, y_int);  // Returns 1 if exponent is 0.
   7436   } else  if (y == 0.5) {
   7437     result = (isinf(x)) ? V8_INFINITY
   7438                         : fast_sqrt(x + 0.0);  // Convert -0 to +0.
   7439   } else if (y == -0.5) {
   7440     result = (isinf(x)) ? 0
   7441                         : 1.0 / fast_sqrt(x + 0.0);  // Convert -0 to +0.
   7442   } else {
   7443     result = power_double_double(x, y);
   7444   }
   7445   if (isnan(result)) return isolate->heap()->nan_value();
   7446   return isolate->heap()->AllocateHeapNumber(result);
   7447 }
   7448 
   7449 // Fast version of Math.pow if we know that y is not an integer and y is not
   7450 // -0.5 or 0.5.  Used as slow case from full codegen.
   7451 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
   7452   NoHandleAllocation ha;
   7453   ASSERT(args.length() == 2);
   7454   isolate->counters()->math_pow()->Increment();
   7455 
   7456   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7457   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   7458   if (y == 0) {
   7459     return Smi::FromInt(1);
   7460   } else {
   7461     double result = power_double_double(x, y);
   7462     if (isnan(result)) return isolate->heap()->nan_value();
   7463     return isolate->heap()->AllocateHeapNumber(result);
   7464   }
   7465 }
   7466 
   7467 
   7468 RUNTIME_FUNCTION(MaybeObject*, Runtime_RoundNumber) {
   7469   NoHandleAllocation ha;
   7470   ASSERT(args.length() == 1);
   7471   isolate->counters()->math_round()->Increment();
   7472 
   7473   if (!args[0]->IsHeapNumber()) {
   7474     // Must be smi. Return the argument unchanged for all the other types
   7475     // to make fuzz-natives test happy.
   7476     return args[0];
   7477   }
   7478 
   7479   HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
   7480 
   7481   double value = number->value();
   7482   int exponent = number->get_exponent();
   7483   int sign = number->get_sign();
   7484 
   7485   if (exponent < -1) {
   7486     // Number in range ]-0.5..0.5[. These always round to +/-zero.
   7487     if (sign) return isolate->heap()->minus_zero_value();
   7488     return Smi::FromInt(0);
   7489   }
   7490 
   7491   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
   7492   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
   7493   // argument holds for 32-bit smis).
   7494   if (!sign && exponent < kSmiValueSize - 2) {
   7495     return Smi::FromInt(static_cast<int>(value + 0.5));
   7496   }
   7497 
   7498   // If the magnitude is big enough, there's no place for fraction part. If we
   7499   // try to add 0.5 to this number, 1.0 will be added instead.
   7500   if (exponent >= 52) {
   7501     return number;
   7502   }
   7503 
   7504   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
   7505 
   7506   // Do not call NumberFromDouble() to avoid extra checks.
   7507   return isolate->heap()->AllocateHeapNumber(floor(value + 0.5));
   7508 }
   7509 
   7510 
   7511 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
   7512   NoHandleAllocation ha;
   7513   ASSERT(args.length() == 1);
   7514   isolate->counters()->math_sin()->Increment();
   7515 
   7516   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7517   return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
   7518 }
   7519 
   7520 
   7521 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
   7522   NoHandleAllocation ha;
   7523   ASSERT(args.length() == 1);
   7524   isolate->counters()->math_sqrt()->Increment();
   7525 
   7526   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7527   return isolate->heap()->AllocateHeapNumber(fast_sqrt(x));
   7528 }
   7529 
   7530 
   7531 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
   7532   NoHandleAllocation ha;
   7533   ASSERT(args.length() == 1);
   7534   isolate->counters()->math_tan()->Increment();
   7535 
   7536   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   7537   return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
   7538 }
   7539 
   7540 
   7541 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
   7542   NoHandleAllocation ha;
   7543   ASSERT(args.length() == 2);
   7544 
   7545   CONVERT_SMI_ARG_CHECKED(year, 0);
   7546   CONVERT_SMI_ARG_CHECKED(month, 1);
   7547 
   7548   return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
   7549 }
   7550 
   7551 
   7552 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
   7553   HandleScope scope(isolate);
   7554   ASSERT(args.length() == 3);
   7555 
   7556   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
   7557   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
   7558   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
   7559 
   7560   DateCache* date_cache = isolate->date_cache();
   7561 
   7562   Object* value = NULL;
   7563   bool is_value_nan = false;
   7564   if (isnan(time)) {
   7565     value = isolate->heap()->nan_value();
   7566     is_value_nan = true;
   7567   } else if (!is_utc &&
   7568              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
   7569               time > DateCache::kMaxTimeBeforeUTCInMs)) {
   7570     value = isolate->heap()->nan_value();
   7571     is_value_nan = true;
   7572   } else {
   7573     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
   7574     if (time < -DateCache::kMaxTimeInMs ||
   7575         time > DateCache::kMaxTimeInMs) {
   7576       value = isolate->heap()->nan_value();
   7577       is_value_nan = true;
   7578     } else  {
   7579       MaybeObject* maybe_result =
   7580           isolate->heap()->AllocateHeapNumber(DoubleToInteger(time));
   7581       if (!maybe_result->ToObject(&value)) return maybe_result;
   7582     }
   7583   }
   7584   date->SetValue(value, is_value_nan);
   7585   return value;
   7586 }
   7587 
   7588 
   7589 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
   7590   HandleScope scope(isolate);
   7591   ASSERT(args.length() == 3);
   7592 
   7593   Handle<JSFunction> callee = args.at<JSFunction>(0);
   7594   Object** parameters = reinterpret_cast<Object**>(args[1]);
   7595   const int argument_count = Smi::cast(args[2])->value();
   7596 
   7597   Handle<JSObject> result =
   7598       isolate->factory()->NewArgumentsObject(callee, argument_count);
   7599   // Allocate the elements if needed.
   7600   int parameter_count = callee->shared()->formal_parameter_count();
   7601   if (argument_count > 0) {
   7602     if (parameter_count > 0) {
   7603       int mapped_count = Min(argument_count, parameter_count);
   7604       Handle<FixedArray> parameter_map =
   7605           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
   7606       parameter_map->set_map(
   7607           isolate->heap()->non_strict_arguments_elements_map());
   7608 
   7609       Handle<Map> old_map(result->map());
   7610       Handle<Map> new_map =
   7611           isolate->factory()->CopyMapDropTransitions(old_map);
   7612       new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
   7613 
   7614       result->set_map(*new_map);
   7615       result->set_elements(*parameter_map);
   7616 
   7617       // Store the context and the arguments array at the beginning of the
   7618       // parameter map.
   7619       Handle<Context> context(isolate->context());
   7620       Handle<FixedArray> arguments =
   7621           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   7622       parameter_map->set(0, *context);
   7623       parameter_map->set(1, *arguments);
   7624 
   7625       // Loop over the actual parameters backwards.
   7626       int index = argument_count - 1;
   7627       while (index >= mapped_count) {
   7628         // These go directly in the arguments array and have no
   7629         // corresponding slot in the parameter map.
   7630         arguments->set(index, *(parameters - index - 1));
   7631         --index;
   7632       }
   7633 
   7634       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
   7635       while (index >= 0) {
   7636         // Detect duplicate names to the right in the parameter list.
   7637         Handle<String> name(scope_info->ParameterName(index));
   7638         int context_local_count = scope_info->ContextLocalCount();
   7639         bool duplicate = false;
   7640         for (int j = index + 1; j < parameter_count; ++j) {
   7641           if (scope_info->ParameterName(j) == *name) {
   7642             duplicate = true;
   7643             break;
   7644           }
   7645         }
   7646 
   7647         if (duplicate) {
   7648           // This goes directly in the arguments array with a hole in the
   7649           // parameter map.
   7650           arguments->set(index, *(parameters - index - 1));
   7651           parameter_map->set_the_hole(index + 2);
   7652         } else {
   7653           // The context index goes in the parameter map with a hole in the
   7654           // arguments array.
   7655           int context_index = -1;
   7656           for (int j = 0; j < context_local_count; ++j) {
   7657             if (scope_info->ContextLocalName(j) == *name) {
   7658               context_index = j;
   7659               break;
   7660             }
   7661           }
   7662           ASSERT(context_index >= 0);
   7663           arguments->set_the_hole(index);
   7664           parameter_map->set(index + 2, Smi::FromInt(
   7665               Context::MIN_CONTEXT_SLOTS + context_index));
   7666         }
   7667 
   7668         --index;
   7669       }
   7670     } else {
   7671       // If there is no aliasing, the arguments object elements are not
   7672       // special in any way.
   7673       Handle<FixedArray> elements =
   7674           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
   7675       result->set_elements(*elements);
   7676       for (int i = 0; i < argument_count; ++i) {
   7677         elements->set(i, *(parameters - i - 1));
   7678       }
   7679     }
   7680   }
   7681   return *result;
   7682 }
   7683 
   7684 
   7685 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
   7686   NoHandleAllocation ha;
   7687   ASSERT(args.length() == 3);
   7688 
   7689   JSFunction* callee = JSFunction::cast(args[0]);
   7690   Object** parameters = reinterpret_cast<Object**>(args[1]);
   7691   const int length = args.smi_at(2);
   7692 
   7693   Object* result;
   7694   { MaybeObject* maybe_result =
   7695         isolate->heap()->AllocateArgumentsObject(callee, length);
   7696     if (!maybe_result->ToObject(&result)) return maybe_result;
   7697   }
   7698   // Allocate the elements if needed.
   7699   if (length > 0) {
   7700     // Allocate the fixed array.
   7701     Object* obj;
   7702     { MaybeObject* maybe_obj = isolate->heap()->AllocateRawFixedArray(length);
   7703       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   7704     }
   7705 
   7706     AssertNoAllocation no_gc;
   7707     FixedArray* array = reinterpret_cast<FixedArray*>(obj);
   7708     array->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
   7709     array->set_length(length);
   7710 
   7711     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   7712     for (int i = 0; i < length; i++) {
   7713       array->set(i, *--parameters, mode);
   7714     }
   7715     JSObject::cast(result)->set_elements(FixedArray::cast(obj));
   7716   }
   7717   return result;
   7718 }
   7719 
   7720 
   7721 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
   7722   HandleScope scope(isolate);
   7723   ASSERT(args.length() == 3);
   7724   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   7725   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
   7726   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
   7727 
   7728   // The caller ensures that we pretenure closures that are assigned
   7729   // directly to properties.
   7730   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   7731   Handle<JSFunction> result =
   7732       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   7733                                                             context,
   7734                                                             pretenure_flag);
   7735   return *result;
   7736 }
   7737 
   7738 
   7739 // Find the arguments of the JavaScript function invocation that called
   7740 // into C++ code. Collect these in a newly allocated array of handles (possibly
   7741 // prefixed by a number of empty handles).
   7742 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
   7743     int prefix_argc,
   7744     int* total_argc) {
   7745   // Find frame containing arguments passed to the caller.
   7746   JavaScriptFrameIterator it;
   7747   JavaScriptFrame* frame = it.frame();
   7748   List<JSFunction*> functions(2);
   7749   frame->GetFunctions(&functions);
   7750   if (functions.length() > 1) {
   7751     int inlined_jsframe_index = functions.length() - 1;
   7752     JSFunction* inlined_function = functions[inlined_jsframe_index];
   7753     Vector<SlotRef> args_slots =
   7754         SlotRef::ComputeSlotMappingForArguments(
   7755             frame,
   7756             inlined_jsframe_index,
   7757             inlined_function->shared()->formal_parameter_count());
   7758 
   7759     int args_count = args_slots.length();
   7760 
   7761     *total_argc = prefix_argc + args_count;
   7762     SmartArrayPointer<Handle<Object> > param_data(
   7763         NewArray<Handle<Object> >(*total_argc));
   7764     for (int i = 0; i < args_count; i++) {
   7765       Handle<Object> val = args_slots[i].GetValue();
   7766       param_data[prefix_argc + i] = val;
   7767     }
   7768 
   7769     args_slots.Dispose();
   7770 
   7771     return param_data;
   7772   } else {
   7773     it.AdvanceToArgumentsFrame();
   7774     frame = it.frame();
   7775     int args_count = frame->ComputeParametersCount();
   7776 
   7777     *total_argc = prefix_argc + args_count;
   7778     SmartArrayPointer<Handle<Object> > param_data(
   7779         NewArray<Handle<Object> >(*total_argc));
   7780     for (int i = 0; i < args_count; i++) {
   7781       Handle<Object> val = Handle<Object>(frame->GetParameter(i));
   7782       param_data[prefix_argc + i] = val;
   7783     }
   7784     return param_data;
   7785   }
   7786 }
   7787 
   7788 
   7789 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
   7790   HandleScope scope(isolate);
   7791   ASSERT(args.length() == 4);
   7792   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
   7793   RUNTIME_ASSERT(args[3]->IsNumber());
   7794   Handle<Object> bindee = args.at<Object>(1);
   7795 
   7796   // TODO(lrn): Create bound function in C++ code from premade shared info.
   7797   bound_function->shared()->set_bound(true);
   7798   // Get all arguments of calling function (Function.prototype.bind).
   7799   int argc = 0;
   7800   SmartArrayPointer<Handle<Object> > arguments = GetCallerArguments(0, &argc);
   7801   // Don't count the this-arg.
   7802   if (argc > 0) {
   7803     ASSERT(*arguments[0] == args[2]);
   7804     argc--;
   7805   } else {
   7806     ASSERT(args[2]->IsUndefined());
   7807   }
   7808   // Initialize array of bindings (function, this, and any existing arguments
   7809   // if the function was already bound).
   7810   Handle<FixedArray> new_bindings;
   7811   int i;
   7812   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
   7813     Handle<FixedArray> old_bindings(
   7814         JSFunction::cast(*bindee)->function_bindings());
   7815     new_bindings =
   7816         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
   7817     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex));
   7818     i = 0;
   7819     for (int n = old_bindings->length(); i < n; i++) {
   7820       new_bindings->set(i, old_bindings->get(i));
   7821     }
   7822   } else {
   7823     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
   7824     new_bindings = isolate->factory()->NewFixedArray(array_size);
   7825     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
   7826     new_bindings->set(JSFunction::kBoundThisIndex, args[2]);
   7827     i = 2;
   7828   }
   7829   // Copy arguments, skipping the first which is "this_arg".
   7830   for (int j = 0; j < argc; j++, i++) {
   7831     new_bindings->set(i, *arguments[j + 1]);
   7832   }
   7833   new_bindings->set_map_no_write_barrier(
   7834       isolate->heap()->fixed_cow_array_map());
   7835   bound_function->set_function_bindings(*new_bindings);
   7836 
   7837   // Update length.
   7838   Handle<String> length_symbol = isolate->factory()->length_symbol();
   7839   Handle<Object> new_length(args.at<Object>(3));
   7840   PropertyAttributes attr =
   7841       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
   7842   ForceSetProperty(bound_function, length_symbol, new_length, attr);
   7843   return *bound_function;
   7844 }
   7845 
   7846 
   7847 RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
   7848   HandleScope handles(isolate);
   7849   ASSERT(args.length() == 1);
   7850   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
   7851   if (callable->IsJSFunction()) {
   7852     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
   7853     if (function->shared()->bound()) {
   7854       Handle<FixedArray> bindings(function->function_bindings());
   7855       ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
   7856       return *isolate->factory()->NewJSArrayWithElements(bindings);
   7857     }
   7858   }
   7859   return isolate->heap()->undefined_value();
   7860 }
   7861 
   7862 
   7863 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
   7864   HandleScope scope(isolate);
   7865   ASSERT(args.length() == 1);
   7866   // First argument is a function to use as a constructor.
   7867   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   7868   RUNTIME_ASSERT(function->shared()->bound());
   7869 
   7870   // The argument is a bound function. Extract its bound arguments
   7871   // and callable.
   7872   Handle<FixedArray> bound_args =
   7873       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
   7874   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
   7875   Handle<Object> bound_function(
   7876       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)));
   7877   ASSERT(!bound_function->IsJSFunction() ||
   7878          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
   7879 
   7880   int total_argc = 0;
   7881   SmartArrayPointer<Handle<Object> > param_data =
   7882       GetCallerArguments(bound_argc, &total_argc);
   7883   for (int i = 0; i < bound_argc; i++) {
   7884     param_data[i] = Handle<Object>(bound_args->get(
   7885         JSFunction::kBoundArgumentsStartIndex + i));
   7886   }
   7887 
   7888   if (!bound_function->IsJSFunction()) {
   7889     bool exception_thrown;
   7890     bound_function = Execution::TryGetConstructorDelegate(bound_function,
   7891                                                           &exception_thrown);
   7892     if (exception_thrown) return Failure::Exception();
   7893   }
   7894   ASSERT(bound_function->IsJSFunction());
   7895 
   7896   bool exception = false;
   7897   Handle<Object> result =
   7898       Execution::New(Handle<JSFunction>::cast(bound_function),
   7899                      total_argc, *param_data, &exception);
   7900   if (exception) {
   7901     return Failure::Exception();
   7902   }
   7903   ASSERT(!result.is_null());
   7904   return *result;
   7905 }
   7906 
   7907 
   7908 static void TrySettingInlineConstructStub(Isolate* isolate,
   7909                                           Handle<JSFunction> function) {
   7910   Handle<Object> prototype = isolate->factory()->null_value();
   7911   if (function->has_instance_prototype()) {
   7912     prototype = Handle<Object>(function->instance_prototype(), isolate);
   7913   }
   7914   if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
   7915     ConstructStubCompiler compiler(isolate);
   7916     Handle<Code> code = compiler.CompileConstructStub(function);
   7917     function->shared()->set_construct_stub(*code);
   7918   }
   7919 }
   7920 
   7921 
   7922 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
   7923   HandleScope scope(isolate);
   7924   ASSERT(args.length() == 1);
   7925 
   7926   Handle<Object> constructor = args.at<Object>(0);
   7927 
   7928   // If the constructor isn't a proper function we throw a type error.
   7929   if (!constructor->IsJSFunction()) {
   7930     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   7931     Handle<Object> type_error =
   7932         isolate->factory()->NewTypeError("not_constructor", arguments);
   7933     return isolate->Throw(*type_error);
   7934   }
   7935 
   7936   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
   7937 
   7938   // If function should not have prototype, construction is not allowed. In this
   7939   // case generated code bailouts here, since function has no initial_map.
   7940   if (!function->should_have_prototype() && !function->shared()->bound()) {
   7941     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
   7942     Handle<Object> type_error =
   7943         isolate->factory()->NewTypeError("not_constructor", arguments);
   7944     return isolate->Throw(*type_error);
   7945   }
   7946 
   7947 #ifdef ENABLE_DEBUGGER_SUPPORT
   7948   Debug* debug = isolate->debug();
   7949   // Handle stepping into constructors if step into is active.
   7950   if (debug->StepInActive()) {
   7951     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
   7952   }
   7953 #endif
   7954 
   7955   if (function->has_initial_map()) {
   7956     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
   7957       // The 'Function' function ignores the receiver object when
   7958       // called using 'new' and creates a new JSFunction object that
   7959       // is returned.  The receiver object is only used for error
   7960       // reporting if an error occurs when constructing the new
   7961       // JSFunction. FACTORY->NewJSObject() should not be used to
   7962       // allocate JSFunctions since it does not properly initialize
   7963       // the shared part of the function. Since the receiver is
   7964       // ignored anyway, we use the global object as the receiver
   7965       // instead of a new JSFunction object. This way, errors are
   7966       // reported the same way whether or not 'Function' is called
   7967       // using 'new'.
   7968       return isolate->context()->global();
   7969     }
   7970   }
   7971 
   7972   // The function should be compiled for the optimization hints to be
   7973   // available. We cannot use EnsureCompiled because that forces a
   7974   // compilation through the shared function info which makes it
   7975   // impossible for us to optimize.
   7976   if (!function->is_compiled()) {
   7977     JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
   7978   }
   7979 
   7980   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
   7981   if (!function->has_initial_map() &&
   7982       shared->IsInobjectSlackTrackingInProgress()) {
   7983     // The tracking is already in progress for another function. We can only
   7984     // track one initial_map at a time, so we force the completion before the
   7985     // function is called as a constructor for the first time.
   7986     shared->CompleteInobjectSlackTracking();
   7987   }
   7988 
   7989   bool first_allocation = !shared->live_objects_may_exist();
   7990   Handle<JSObject> result = isolate->factory()->NewJSObject(function);
   7991   RETURN_IF_EMPTY_HANDLE(isolate, result);
   7992   // Delay setting the stub if inobject slack tracking is in progress.
   7993   if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) {
   7994     TrySettingInlineConstructStub(isolate, function);
   7995   }
   7996 
   7997   isolate->counters()->constructed_objects()->Increment();
   7998   isolate->counters()->constructed_objects_runtime()->Increment();
   7999 
   8000   return *result;
   8001 }
   8002 
   8003 
   8004 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) {
   8005   HandleScope scope(isolate);
   8006   ASSERT(args.length() == 1);
   8007 
   8008   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8009   function->shared()->CompleteInobjectSlackTracking();
   8010   TrySettingInlineConstructStub(isolate, function);
   8011 
   8012   return isolate->heap()->undefined_value();
   8013 }
   8014 
   8015 
   8016 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
   8017   HandleScope scope(isolate);
   8018   ASSERT(args.length() == 1);
   8019 
   8020   Handle<JSFunction> function = args.at<JSFunction>(0);
   8021 #ifdef DEBUG
   8022   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
   8023     PrintF("[lazy: ");
   8024     function->PrintName();
   8025     PrintF("]\n");
   8026   }
   8027 #endif
   8028 
   8029   // Compile the target function.
   8030   ASSERT(!function->is_compiled());
   8031   if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) {
   8032     return Failure::Exception();
   8033   }
   8034 
   8035   // All done. Return the compiled code.
   8036   ASSERT(function->is_compiled());
   8037   return function->code();
   8038 }
   8039 
   8040 
   8041 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
   8042   HandleScope scope(isolate);
   8043   ASSERT(args.length() == 1);
   8044   Handle<JSFunction> function = args.at<JSFunction>(0);
   8045 
   8046   // If the function is not compiled ignore the lazy
   8047   // recompilation. This can happen if the debugger is activated and
   8048   // the function is returned to the not compiled state.
   8049   if (!function->shared()->is_compiled()) {
   8050     function->ReplaceCode(function->shared()->code());
   8051     return function->code();
   8052   }
   8053 
   8054   // If the function is not optimizable or debugger is active continue using the
   8055   // code from the full compiler.
   8056   if (!function->shared()->code()->optimizable() ||
   8057       isolate->DebuggerHasBreakPoints()) {
   8058     if (FLAG_trace_opt) {
   8059       PrintF("[failed to optimize ");
   8060       function->PrintName();
   8061       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
   8062           function->shared()->code()->optimizable() ? "T" : "F",
   8063           isolate->DebuggerHasBreakPoints() ? "T" : "F");
   8064     }
   8065     function->ReplaceCode(function->shared()->code());
   8066     return function->code();
   8067   }
   8068   function->shared()->code()->set_profiler_ticks(0);
   8069   if (JSFunction::CompileOptimized(function,
   8070                                    AstNode::kNoNumber,
   8071                                    CLEAR_EXCEPTION)) {
   8072     return function->code();
   8073   }
   8074   if (FLAG_trace_opt) {
   8075     PrintF("[failed to optimize ");
   8076     function->PrintName();
   8077     PrintF(": optimized compilation failed]\n");
   8078   }
   8079   function->ReplaceCode(function->shared()->code());
   8080   return function->code();
   8081 }
   8082 
   8083 
   8084 class ActivationsFinder : public ThreadVisitor {
   8085  public:
   8086   explicit ActivationsFinder(JSFunction* function)
   8087       : function_(function), has_activations_(false) {}
   8088 
   8089   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
   8090     if (has_activations_) return;
   8091 
   8092     for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
   8093       JavaScriptFrame* frame = it.frame();
   8094       if (frame->is_optimized() && frame->function() == function_) {
   8095         has_activations_ = true;
   8096         return;
   8097       }
   8098     }
   8099   }
   8100 
   8101   bool has_activations() { return has_activations_; }
   8102 
   8103  private:
   8104   JSFunction* function_;
   8105   bool has_activations_;
   8106 };
   8107 
   8108 
   8109 static void MaterializeArgumentsObjectInFrame(Isolate* isolate,
   8110                                               JavaScriptFrame* frame) {
   8111   Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
   8112   Handle<Object> arguments;
   8113   for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
   8114     if (frame->GetExpression(i) == isolate->heap()->arguments_marker()) {
   8115       if (arguments.is_null()) {
   8116         // FunctionGetArguments can't throw an exception, so cast away the
   8117         // doubt with an assert.
   8118         arguments = Handle<Object>(
   8119             Accessors::FunctionGetArguments(*function,
   8120                                             NULL)->ToObjectUnchecked());
   8121         ASSERT(*arguments != isolate->heap()->null_value());
   8122         ASSERT(*arguments != isolate->heap()->undefined_value());
   8123       }
   8124       frame->SetExpression(i, *arguments);
   8125     }
   8126   }
   8127 }
   8128 
   8129 
   8130 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
   8131   HandleScope scope(isolate);
   8132   ASSERT(args.length() == 1);
   8133   RUNTIME_ASSERT(args[0]->IsSmi());
   8134   Deoptimizer::BailoutType type =
   8135       static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
   8136   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8137   ASSERT(isolate->heap()->IsAllocationAllowed());
   8138   int jsframes = deoptimizer->jsframe_count();
   8139 
   8140   deoptimizer->MaterializeHeapNumbers();
   8141   delete deoptimizer;
   8142 
   8143   JavaScriptFrameIterator it(isolate);
   8144   for (int i = 0; i < jsframes - 1; i++) {
   8145     MaterializeArgumentsObjectInFrame(isolate, it.frame());
   8146     it.Advance();
   8147   }
   8148 
   8149   JavaScriptFrame* frame = it.frame();
   8150   RUNTIME_ASSERT(frame->function()->IsJSFunction());
   8151   Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
   8152   MaterializeArgumentsObjectInFrame(isolate, frame);
   8153 
   8154   if (type == Deoptimizer::EAGER) {
   8155     RUNTIME_ASSERT(function->IsOptimized());
   8156   }
   8157 
   8158   // Avoid doing too much work when running with --always-opt and keep
   8159   // the optimized code around.
   8160   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
   8161     return isolate->heap()->undefined_value();
   8162   }
   8163 
   8164   // Find other optimized activations of the function.
   8165   bool has_other_activations = false;
   8166   while (!it.done()) {
   8167     JavaScriptFrame* frame = it.frame();
   8168     if (frame->is_optimized() && frame->function() == *function) {
   8169       has_other_activations = true;
   8170       break;
   8171     }
   8172     it.Advance();
   8173   }
   8174 
   8175   if (!has_other_activations) {
   8176     ActivationsFinder activations_finder(*function);
   8177     isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
   8178     has_other_activations = activations_finder.has_activations();
   8179   }
   8180 
   8181   if (!has_other_activations) {
   8182     if (FLAG_trace_deopt) {
   8183       PrintF("[removing optimized code for: ");
   8184       function->PrintName();
   8185       PrintF("]\n");
   8186     }
   8187     function->ReplaceCode(function->shared()->code());
   8188   } else {
   8189     Deoptimizer::DeoptimizeFunction(*function);
   8190   }
   8191   return isolate->heap()->undefined_value();
   8192 }
   8193 
   8194 
   8195 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyOSR) {
   8196   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   8197   delete deoptimizer;
   8198   return isolate->heap()->undefined_value();
   8199 }
   8200 
   8201 
   8202 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
   8203   HandleScope scope(isolate);
   8204   ASSERT(args.length() == 1);
   8205   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8206   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
   8207 
   8208   Deoptimizer::DeoptimizeFunction(*function);
   8209 
   8210   return isolate->heap()->undefined_value();
   8211 }
   8212 
   8213 
   8214 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
   8215 #if defined(USE_SIMULATOR)
   8216   return isolate->heap()->true_value();
   8217 #else
   8218   return isolate->heap()->false_value();
   8219 #endif
   8220 }
   8221 
   8222 
   8223 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
   8224   HandleScope scope(isolate);
   8225   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
   8226   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8227 
   8228   if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
   8229   function->MarkForLazyRecompilation();
   8230 
   8231   Code* unoptimized = function->shared()->code();
   8232   if (args.length() == 2 &&
   8233       unoptimized->kind() == Code::FUNCTION) {
   8234     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
   8235     CHECK(type->IsEqualTo(CStrVector("osr")));
   8236     isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
   8237     unoptimized->set_allow_osr_at_loop_nesting_level(
   8238         Code::kMaxLoopNestingMarker);
   8239   }
   8240 
   8241   return isolate->heap()->undefined_value();
   8242 }
   8243 
   8244 
   8245 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
   8246   HandleScope scope(isolate);
   8247   ASSERT(args.length() == 1);
   8248   // The least significant bit (after untagging) indicates whether the
   8249   // function is currently optimized, regardless of reason.
   8250   if (!V8::UseCrankshaft()) {
   8251     return Smi::FromInt(4);  // 4 == "never".
   8252   }
   8253   if (FLAG_always_opt) {
   8254     return Smi::FromInt(3);  // 3 == "always".
   8255   }
   8256   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8257   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
   8258                                  : Smi::FromInt(2);  // 2 == "no".
   8259 }
   8260 
   8261 
   8262 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
   8263   HandleScope scope(isolate);
   8264   ASSERT(args.length() == 1);
   8265   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8266   return Smi::FromInt(function->shared()->opt_count());
   8267 }
   8268 
   8269 
   8270 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
   8271   HandleScope scope(isolate);
   8272   ASSERT(args.length() == 1);
   8273   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   8274 
   8275   // We're not prepared to handle a function with arguments object.
   8276   ASSERT(!function->shared()->uses_arguments());
   8277 
   8278   // We have hit a back edge in an unoptimized frame for a function that was
   8279   // selected for on-stack replacement.  Find the unoptimized code object.
   8280   Handle<Code> unoptimized(function->shared()->code(), isolate);
   8281   // Keep track of whether we've succeeded in optimizing.
   8282   bool succeeded = unoptimized->optimizable();
   8283   if (succeeded) {
   8284     // If we are trying to do OSR when there are already optimized
   8285     // activations of the function, it means (a) the function is directly or
   8286     // indirectly recursive and (b) an optimized invocation has been
   8287     // deoptimized so that we are currently in an unoptimized activation.
   8288     // Check for optimized activations of this function.
   8289     JavaScriptFrameIterator it(isolate);
   8290     while (succeeded && !it.done()) {
   8291       JavaScriptFrame* frame = it.frame();
   8292       succeeded = !frame->is_optimized() || frame->function() != *function;
   8293       it.Advance();
   8294     }
   8295   }
   8296 
   8297   int ast_id = AstNode::kNoNumber;
   8298   if (succeeded) {
   8299     // The top JS function is this one, the PC is somewhere in the
   8300     // unoptimized code.
   8301     JavaScriptFrameIterator it(isolate);
   8302     JavaScriptFrame* frame = it.frame();
   8303     ASSERT(frame->function() == *function);
   8304     ASSERT(frame->LookupCode() == *unoptimized);
   8305     ASSERT(unoptimized->contains(frame->pc()));
   8306 
   8307     // Use linear search of the unoptimized code's stack check table to find
   8308     // the AST id matching the PC.
   8309     Address start = unoptimized->instruction_start();
   8310     unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start);
   8311     Address table_cursor = start + unoptimized->stack_check_table_offset();
   8312     uint32_t table_length = Memory::uint32_at(table_cursor);
   8313     table_cursor += kIntSize;
   8314     for (unsigned i = 0; i < table_length; ++i) {
   8315       // Table entries are (AST id, pc offset) pairs.
   8316       uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize);
   8317       if (pc_offset == target_pc_offset) {
   8318         ast_id = static_cast<int>(Memory::uint32_at(table_cursor));
   8319         break;
   8320       }
   8321       table_cursor += 2 * kIntSize;
   8322     }
   8323     ASSERT(ast_id != AstNode::kNoNumber);
   8324     if (FLAG_trace_osr) {
   8325       PrintF("[replacing on-stack at AST id %d in ", ast_id);
   8326       function->PrintName();
   8327       PrintF("]\n");
   8328     }
   8329 
   8330     // Try to compile the optimized code.  A true return value from
   8331     // CompileOptimized means that compilation succeeded, not necessarily
   8332     // that optimization succeeded.
   8333     if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
   8334         function->IsOptimized()) {
   8335       DeoptimizationInputData* data = DeoptimizationInputData::cast(
   8336           function->code()->deoptimization_data());
   8337       if (data->OsrPcOffset()->value() >= 0) {
   8338         if (FLAG_trace_osr) {
   8339           PrintF("[on-stack replacement offset %d in optimized code]\n",
   8340                data->OsrPcOffset()->value());
   8341         }
   8342         ASSERT(data->OsrAstId()->value() == ast_id);
   8343       } else {
   8344         // We may never generate the desired OSR entry if we emit an
   8345         // early deoptimize.
   8346         succeeded = false;
   8347       }
   8348     } else {
   8349       succeeded = false;
   8350     }
   8351   }
   8352 
   8353   // Revert to the original stack checks in the original unoptimized code.
   8354   if (FLAG_trace_osr) {
   8355     PrintF("[restoring original stack checks in ");
   8356     function->PrintName();
   8357     PrintF("]\n");
   8358   }
   8359   Handle<Code> check_code;
   8360 #if defined(V8_TARGET_ARCH_IA32) || \
   8361     defined(V8_TARGET_ARCH_ARM) || \
   8362     defined(V8_TARGET_ARCH_MIPS)
   8363   if (FLAG_count_based_interrupts) {
   8364     InterruptStub interrupt_stub;
   8365     check_code = interrupt_stub.GetCode();
   8366   } else  // NOLINT
   8367 #endif
   8368   {  // NOLINT
   8369     StackCheckStub check_stub;
   8370     check_code = check_stub.GetCode();
   8371   }
   8372   Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
   8373   Deoptimizer::RevertStackCheckCode(*unoptimized,
   8374                                     *check_code,
   8375                                     *replacement_code);
   8376 
   8377   // Allow OSR only at nesting level zero again.
   8378   unoptimized->set_allow_osr_at_loop_nesting_level(0);
   8379 
   8380   // If the optimization attempt succeeded, return the AST id tagged as a
   8381   // smi. This tells the builtin that we need to translate the unoptimized
   8382   // frame to an optimized one.
   8383   if (succeeded) {
   8384     ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
   8385     return Smi::FromInt(ast_id);
   8386   } else {
   8387     if (function->IsMarkedForLazyRecompilation()) {
   8388       function->ReplaceCode(function->shared()->code());
   8389     }
   8390     return Smi::FromInt(-1);
   8391   }
   8392 }
   8393 
   8394 
   8395 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
   8396   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8397   return isolate->heap()->undefined_value();
   8398 }
   8399 
   8400 
   8401 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
   8402   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   8403   return isolate->heap()->nan_value();
   8404 }
   8405 
   8406 
   8407 RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
   8408   HandleScope scope(isolate);
   8409   ASSERT(args.length() >= 2);
   8410   int argc = args.length() - 2;
   8411   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
   8412   Object* receiver = args[0];
   8413 
   8414   // If there are too many arguments, allocate argv via malloc.
   8415   const int argv_small_size = 10;
   8416   Handle<Object> argv_small_buffer[argv_small_size];
   8417   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8418   Handle<Object>* argv = argv_small_buffer;
   8419   if (argc > argv_small_size) {
   8420     argv = new Handle<Object>[argc];
   8421     if (argv == NULL) return isolate->StackOverflow();
   8422     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8423   }
   8424 
   8425   for (int i = 0; i < argc; ++i) {
   8426      MaybeObject* maybe = args[1 + i];
   8427      Object* object;
   8428      if (!maybe->To<Object>(&object)) return maybe;
   8429      argv[i] = Handle<Object>(object);
   8430   }
   8431 
   8432   bool threw;
   8433   Handle<JSReceiver> hfun(fun);
   8434   Handle<Object> hreceiver(receiver);
   8435   Handle<Object> result =
   8436       Execution::Call(hfun, hreceiver, argc, argv, &threw, true);
   8437 
   8438   if (threw) return Failure::Exception();
   8439   return *result;
   8440 }
   8441 
   8442 
   8443 RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
   8444   HandleScope scope(isolate);
   8445   ASSERT(args.length() == 5);
   8446   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
   8447   Handle<Object> receiver = args.at<Object>(1);
   8448   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
   8449   CONVERT_SMI_ARG_CHECKED(offset, 3);
   8450   CONVERT_SMI_ARG_CHECKED(argc, 4);
   8451   ASSERT(offset >= 0);
   8452   ASSERT(argc >= 0);
   8453 
   8454   // If there are too many arguments, allocate argv via malloc.
   8455   const int argv_small_size = 10;
   8456   Handle<Object> argv_small_buffer[argv_small_size];
   8457   SmartArrayPointer<Handle<Object> > argv_large_buffer;
   8458   Handle<Object>* argv = argv_small_buffer;
   8459   if (argc > argv_small_size) {
   8460     argv = new Handle<Object>[argc];
   8461     if (argv == NULL) return isolate->StackOverflow();
   8462     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
   8463   }
   8464 
   8465   for (int i = 0; i < argc; ++i) {
   8466     argv[i] = Object::GetElement(arguments, offset + i);
   8467   }
   8468 
   8469   bool threw;
   8470   Handle<Object> result =
   8471       Execution::Call(fun, receiver, argc, argv, &threw, true);
   8472 
   8473   if (threw) return Failure::Exception();
   8474   return *result;
   8475 }
   8476 
   8477 
   8478 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
   8479   HandleScope scope(isolate);
   8480   ASSERT(args.length() == 1);
   8481   RUNTIME_ASSERT(!args[0]->IsJSFunction());
   8482   return *Execution::GetFunctionDelegate(args.at<Object>(0));
   8483 }
   8484 
   8485 
   8486 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
   8487   HandleScope scope(isolate);
   8488   ASSERT(args.length() == 1);
   8489   RUNTIME_ASSERT(!args[0]->IsJSFunction());
   8490   return *Execution::GetConstructorDelegate(args.at<Object>(0));
   8491 }
   8492 
   8493 
   8494 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
   8495   NoHandleAllocation ha;
   8496   ASSERT(args.length() == 1);
   8497 
   8498   CONVERT_ARG_CHECKED(JSFunction, function, 0);
   8499   int length = function->shared()->scope_info()->ContextLength();
   8500   Object* result;
   8501   { MaybeObject* maybe_result =
   8502         isolate->heap()->AllocateFunctionContext(length, function);
   8503     if (!maybe_result->ToObject(&result)) return maybe_result;
   8504   }
   8505 
   8506   isolate->set_context(Context::cast(result));
   8507 
   8508   return result;  // non-failure
   8509 }
   8510 
   8511 
   8512 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
   8513   NoHandleAllocation ha;
   8514   ASSERT(args.length() == 2);
   8515   JSObject* extension_object;
   8516   if (args[0]->IsJSObject()) {
   8517     extension_object = JSObject::cast(args[0]);
   8518   } else {
   8519     // Convert the object to a proper JavaScript object.
   8520     MaybeObject* maybe_js_object = args[0]->ToObject();
   8521     if (!maybe_js_object->To(&extension_object)) {
   8522       if (Failure::cast(maybe_js_object)->IsInternalError()) {
   8523         HandleScope scope(isolate);
   8524         Handle<Object> handle = args.at<Object>(0);
   8525         Handle<Object> result =
   8526             isolate->factory()->NewTypeError("with_expression",
   8527                                              HandleVector(&handle, 1));
   8528         return isolate->Throw(*result);
   8529       } else {
   8530         return maybe_js_object;
   8531       }
   8532     }
   8533   }
   8534 
   8535   JSFunction* function;
   8536   if (args[1]->IsSmi()) {
   8537     // A smi sentinel indicates a context nested inside global code rather
   8538     // than some function.  There is a canonical empty function that can be
   8539     // gotten from the global context.
   8540     function = isolate->context()->global_context()->closure();
   8541   } else {
   8542     function = JSFunction::cast(args[1]);
   8543   }
   8544 
   8545   Context* context;
   8546   MaybeObject* maybe_context =
   8547       isolate->heap()->AllocateWithContext(function,
   8548                                            isolate->context(),
   8549                                            extension_object);
   8550   if (!maybe_context->To(&context)) return maybe_context;
   8551   isolate->set_context(context);
   8552   return context;
   8553 }
   8554 
   8555 
   8556 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
   8557   NoHandleAllocation ha;
   8558   ASSERT(args.length() == 3);
   8559   String* name = String::cast(args[0]);
   8560   Object* thrown_object = args[1];
   8561   JSFunction* function;
   8562   if (args[2]->IsSmi()) {
   8563     // A smi sentinel indicates a context nested inside global code rather
   8564     // than some function.  There is a canonical empty function that can be
   8565     // gotten from the global context.
   8566     function = isolate->context()->global_context()->closure();
   8567   } else {
   8568     function = JSFunction::cast(args[2]);
   8569   }
   8570   Context* context;
   8571   MaybeObject* maybe_context =
   8572       isolate->heap()->AllocateCatchContext(function,
   8573                                             isolate->context(),
   8574                                             name,
   8575                                             thrown_object);
   8576   if (!maybe_context->To(&context)) return maybe_context;
   8577   isolate->set_context(context);
   8578   return context;
   8579 }
   8580 
   8581 
   8582 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
   8583   NoHandleAllocation ha;
   8584   ASSERT(args.length() == 2);
   8585   ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
   8586   JSFunction* function;
   8587   if (args[1]->IsSmi()) {
   8588     // A smi sentinel indicates a context nested inside global code rather
   8589     // than some function.  There is a canonical empty function that can be
   8590     // gotten from the global context.
   8591     function = isolate->context()->global_context()->closure();
   8592   } else {
   8593     function = JSFunction::cast(args[1]);
   8594   }
   8595   Context* context;
   8596   MaybeObject* maybe_context =
   8597       isolate->heap()->AllocateBlockContext(function,
   8598                                             isolate->context(),
   8599                                             scope_info);
   8600   if (!maybe_context->To(&context)) return maybe_context;
   8601   isolate->set_context(context);
   8602   return context;
   8603 }
   8604 
   8605 
   8606 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
   8607   HandleScope scope(isolate);
   8608   ASSERT(args.length() == 2);
   8609 
   8610   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
   8611   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   8612 
   8613   int index;
   8614   PropertyAttributes attributes;
   8615   ContextLookupFlags flags = FOLLOW_CHAINS;
   8616   BindingFlags binding_flags;
   8617   Handle<Object> holder = context->Lookup(name,
   8618                                           flags,
   8619                                           &index,
   8620                                           &attributes,
   8621                                           &binding_flags);
   8622 
   8623   // If the slot was not found the result is true.
   8624   if (holder.is_null()) {
   8625     return isolate->heap()->true_value();
   8626   }
   8627 
   8628   // If the slot was found in a context, it should be DONT_DELETE.
   8629   if (holder->IsContext()) {
   8630     return isolate->heap()->false_value();
   8631   }
   8632 
   8633   // The slot was found in a JSObject, either a context extension object,
   8634   // the global object, or the subject of a with.  Try to delete it
   8635   // (respecting DONT_DELETE).
   8636   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   8637   return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
   8638 }
   8639 
   8640 
   8641 // A mechanism to return a pair of Object pointers in registers (if possible).
   8642 // How this is achieved is calling convention-dependent.
   8643 // All currently supported x86 compiles uses calling conventions that are cdecl
   8644 // variants where a 64-bit value is returned in two 32-bit registers
   8645 // (edx:eax on ia32, r1:r0 on ARM).
   8646 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
   8647 // In Win64 calling convention, a struct of two pointers is returned in memory,
   8648 // allocated by the caller, and passed as a pointer in a hidden first parameter.
   8649 #ifdef V8_HOST_ARCH_64_BIT
   8650 struct ObjectPair {
   8651   MaybeObject* x;
   8652   MaybeObject* y;
   8653 };
   8654 
   8655 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
   8656   ObjectPair result = {x, y};
   8657   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
   8658   // In Win64 they are assigned to a hidden first argument.
   8659   return result;
   8660 }
   8661 #else
   8662 typedef uint64_t ObjectPair;
   8663 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
   8664   return reinterpret_cast<uint32_t>(x) |
   8665       (reinterpret_cast<ObjectPair>(y) << 32);
   8666 }
   8667 #endif
   8668 
   8669 
   8670 static inline MaybeObject* Unhole(Heap* heap,
   8671                                   MaybeObject* x,
   8672                                   PropertyAttributes attributes) {
   8673   ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
   8674   USE(attributes);
   8675   return x->IsTheHole() ? heap->undefined_value() : x;
   8676 }
   8677 
   8678 
   8679 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
   8680                                            JSObject* holder) {
   8681   ASSERT(!holder->IsGlobalObject());
   8682   Context* top = isolate->context();
   8683   // Get the context extension function.
   8684   JSFunction* context_extension_function =
   8685       top->global_context()->context_extension_function();
   8686   // If the holder isn't a context extension object, we just return it
   8687   // as the receiver. This allows arguments objects to be used as
   8688   // receivers, but only if they are put in the context scope chain
   8689   // explicitly via a with-statement.
   8690   Object* constructor = holder->map()->constructor();
   8691   if (constructor != context_extension_function) return holder;
   8692   // Fall back to using the global object as the implicit receiver if
   8693   // the property turns out to be a local variable allocated in a
   8694   // context extension object - introduced via eval. Implicit global
   8695   // receivers are indicated with the hole value.
   8696   return isolate->heap()->the_hole_value();
   8697 }
   8698 
   8699 
   8700 static ObjectPair LoadContextSlotHelper(Arguments args,
   8701                                         Isolate* isolate,
   8702                                         bool throw_error) {
   8703   HandleScope scope(isolate);
   8704   ASSERT_EQ(2, args.length());
   8705 
   8706   if (!args[0]->IsContext() || !args[1]->IsString()) {
   8707     return MakePair(isolate->ThrowIllegalOperation(), NULL);
   8708   }
   8709   Handle<Context> context = args.at<Context>(0);
   8710   Handle<String> name = args.at<String>(1);
   8711 
   8712   int index;
   8713   PropertyAttributes attributes;
   8714   ContextLookupFlags flags = FOLLOW_CHAINS;
   8715   BindingFlags binding_flags;
   8716   Handle<Object> holder = context->Lookup(name,
   8717                                           flags,
   8718                                           &index,
   8719                                           &attributes,
   8720                                           &binding_flags);
   8721 
   8722   // If the index is non-negative, the slot has been found in a context.
   8723   if (index >= 0) {
   8724     ASSERT(holder->IsContext());
   8725     // If the "property" we were looking for is a local variable, the
   8726     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
   8727     //
   8728     // Use the hole as the receiver to signal that the receiver is implicit
   8729     // and that the global receiver should be used (as distinguished from an
   8730     // explicit receiver that happens to be a global object).
   8731     Handle<Object> receiver = isolate->factory()->the_hole_value();
   8732     Object* value = Context::cast(*holder)->get(index);
   8733     // Check for uninitialized bindings.
   8734     switch (binding_flags) {
   8735       case MUTABLE_CHECK_INITIALIZED:
   8736       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
   8737         if (value->IsTheHole()) {
   8738           Handle<Object> reference_error =
   8739               isolate->factory()->NewReferenceError("not_defined",
   8740                                                     HandleVector(&name, 1));
   8741           return MakePair(isolate->Throw(*reference_error), NULL);
   8742         }
   8743         // FALLTHROUGH
   8744       case MUTABLE_IS_INITIALIZED:
   8745       case IMMUTABLE_IS_INITIALIZED:
   8746       case IMMUTABLE_IS_INITIALIZED_HARMONY:
   8747         ASSERT(!value->IsTheHole());
   8748         return MakePair(value, *receiver);
   8749       case IMMUTABLE_CHECK_INITIALIZED:
   8750         return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
   8751       case MISSING_BINDING:
   8752         UNREACHABLE();
   8753         return MakePair(NULL, NULL);
   8754     }
   8755   }
   8756 
   8757   // Otherwise, if the slot was found the holder is a context extension
   8758   // object, subject of a with, or a global object.  We read the named
   8759   // property from it.
   8760   if (!holder.is_null()) {
   8761     Handle<JSObject> object = Handle<JSObject>::cast(holder);
   8762     ASSERT(object->HasProperty(*name));
   8763     // GetProperty below can cause GC.
   8764     Handle<Object> receiver_handle(object->IsGlobalObject()
   8765         ? GlobalObject::cast(*object)->global_receiver()
   8766         : ComputeReceiverForNonGlobal(isolate, *object));
   8767 
   8768     // No need to unhole the value here.  This is taken care of by the
   8769     // GetProperty function.
   8770     MaybeObject* value = object->GetProperty(*name);
   8771     return MakePair(value, *receiver_handle);
   8772   }
   8773 
   8774   if (throw_error) {
   8775     // The property doesn't exist - throw exception.
   8776     Handle<Object> reference_error =
   8777         isolate->factory()->NewReferenceError("not_defined",
   8778                                               HandleVector(&name, 1));
   8779     return MakePair(isolate->Throw(*reference_error), NULL);
   8780   } else {
   8781     // The property doesn't exist - return undefined.
   8782     return MakePair(isolate->heap()->undefined_value(),
   8783                     isolate->heap()->undefined_value());
   8784   }
   8785 }
   8786 
   8787 
   8788 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) {
   8789   return LoadContextSlotHelper(args, isolate, true);
   8790 }
   8791 
   8792 
   8793 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlotNoReferenceError) {
   8794   return LoadContextSlotHelper(args, isolate, false);
   8795 }
   8796 
   8797 
   8798 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
   8799   HandleScope scope(isolate);
   8800   ASSERT(args.length() == 4);
   8801 
   8802   Handle<Object> value(args[0], isolate);
   8803   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   8804   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   8805   CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
   8806   StrictModeFlag strict_mode = (language_mode == CLASSIC_MODE)
   8807       ? kNonStrictMode : kStrictMode;
   8808 
   8809   int index;
   8810   PropertyAttributes attributes;
   8811   ContextLookupFlags flags = FOLLOW_CHAINS;
   8812   BindingFlags binding_flags;
   8813   Handle<Object> holder = context->Lookup(name,
   8814                                           flags,
   8815                                           &index,
   8816                                           &attributes,
   8817                                           &binding_flags);
   8818 
   8819   if (index >= 0) {
   8820     // The property was found in a context slot.
   8821     Handle<Context> context = Handle<Context>::cast(holder);
   8822     if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
   8823         context->get(index)->IsTheHole()) {
   8824       Handle<Object> error =
   8825           isolate->factory()->NewReferenceError("not_defined",
   8826                                                 HandleVector(&name, 1));
   8827       return isolate->Throw(*error);
   8828     }
   8829     // Ignore if read_only variable.
   8830     if ((attributes & READ_ONLY) == 0) {
   8831       // Context is a fixed array and set cannot fail.
   8832       context->set(index, *value);
   8833     } else if (strict_mode == kStrictMode) {
   8834       // Setting read only property in strict mode.
   8835       Handle<Object> error =
   8836           isolate->factory()->NewTypeError("strict_cannot_assign",
   8837                                            HandleVector(&name, 1));
   8838       return isolate->Throw(*error);
   8839     }
   8840     return *value;
   8841   }
   8842 
   8843   // Slow case: The property is not in a context slot.  It is either in a
   8844   // context extension object, a property of the subject of a with, or a
   8845   // property of the global object.
   8846   Handle<JSObject> object;
   8847 
   8848   if (!holder.is_null()) {
   8849     // The property exists on the holder.
   8850     object = Handle<JSObject>::cast(holder);
   8851   } else {
   8852     // The property was not found.
   8853     ASSERT(attributes == ABSENT);
   8854 
   8855     if (strict_mode == kStrictMode) {
   8856       // Throw in strict mode (assignment to undefined variable).
   8857       Handle<Object> error =
   8858           isolate->factory()->NewReferenceError(
   8859               "not_defined", HandleVector(&name, 1));
   8860       return isolate->Throw(*error);
   8861     }
   8862     // In non-strict mode, the property is added to the global object.
   8863     attributes = NONE;
   8864     object = Handle<JSObject>(isolate->context()->global());
   8865   }
   8866 
   8867   // Set the property if it's not read only or doesn't yet exist.
   8868   if ((attributes & READ_ONLY) == 0 ||
   8869       (object->GetLocalPropertyAttribute(*name) == ABSENT)) {
   8870     RETURN_IF_EMPTY_HANDLE(
   8871         isolate,
   8872         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
   8873   } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
   8874     // Setting read only property in strict mode.
   8875     Handle<Object> error =
   8876       isolate->factory()->NewTypeError(
   8877           "strict_cannot_assign", HandleVector(&name, 1));
   8878     return isolate->Throw(*error);
   8879   }
   8880   return *value;
   8881 }
   8882 
   8883 
   8884 RUNTIME_FUNCTION(MaybeObject*, Runtime_Throw) {
   8885   HandleScope scope(isolate);
   8886   ASSERT(args.length() == 1);
   8887 
   8888   return isolate->Throw(args[0]);
   8889 }
   8890 
   8891 
   8892 RUNTIME_FUNCTION(MaybeObject*, Runtime_ReThrow) {
   8893   HandleScope scope(isolate);
   8894   ASSERT(args.length() == 1);
   8895 
   8896   return isolate->ReThrow(args[0]);
   8897 }
   8898 
   8899 
   8900 RUNTIME_FUNCTION(MaybeObject*, Runtime_PromoteScheduledException) {
   8901   ASSERT_EQ(0, args.length());
   8902   return isolate->PromoteScheduledException();
   8903 }
   8904 
   8905 
   8906 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowReferenceError) {
   8907   HandleScope scope(isolate);
   8908   ASSERT(args.length() == 1);
   8909 
   8910   Handle<Object> name(args[0], isolate);
   8911   Handle<Object> reference_error =
   8912     isolate->factory()->NewReferenceError("not_defined",
   8913                                           HandleVector(&name, 1));
   8914   return isolate->Throw(*reference_error);
   8915 }
   8916 
   8917 
   8918 RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
   8919   ASSERT(args.length() == 0);
   8920 
   8921   // First check if this is a real stack overflow.
   8922   if (isolate->stack_guard()->IsStackOverflow()) {
   8923     NoHandleAllocation na;
   8924     return isolate->StackOverflow();
   8925   }
   8926 
   8927   return Execution::HandleStackGuardInterrupt(isolate);
   8928 }
   8929 
   8930 
   8931 RUNTIME_FUNCTION(MaybeObject*, Runtime_Interrupt) {
   8932   ASSERT(args.length() == 0);
   8933   return Execution::HandleStackGuardInterrupt(isolate);
   8934 }
   8935 
   8936 
   8937 static int StackSize() {
   8938   int n = 0;
   8939   for (JavaScriptFrameIterator it; !it.done(); it.Advance()) n++;
   8940   return n;
   8941 }
   8942 
   8943 
   8944 static void PrintTransition(Object* result) {
   8945   // indentation
   8946   { const int nmax = 80;
   8947     int n = StackSize();
   8948     if (n <= nmax)
   8949       PrintF("%4d:%*s", n, n, "");
   8950     else
   8951       PrintF("%4d:%*s", n, nmax, "...");
   8952   }
   8953 
   8954   if (result == NULL) {
   8955     JavaScriptFrame::PrintTop(stdout, true, false);
   8956     PrintF(" {\n");
   8957   } else {
   8958     // function result
   8959     PrintF("} -> ");
   8960     result->ShortPrint();
   8961     PrintF("\n");
   8962   }
   8963 }
   8964 
   8965 
   8966 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
   8967   ASSERT(args.length() == 0);
   8968   NoHandleAllocation ha;
   8969   PrintTransition(NULL);
   8970   return isolate->heap()->undefined_value();
   8971 }
   8972 
   8973 
   8974 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) {
   8975   NoHandleAllocation ha;
   8976   PrintTransition(args[0]);
   8977   return args[0];  // return TOS
   8978 }
   8979 
   8980 
   8981 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrint) {
   8982   NoHandleAllocation ha;
   8983   ASSERT(args.length() == 1);
   8984 
   8985 #ifdef DEBUG
   8986   if (args[0]->IsString()) {
   8987     // If we have a string, assume it's a code "marker"
   8988     // and print some interesting cpu debugging info.
   8989     JavaScriptFrameIterator it(isolate);
   8990     JavaScriptFrame* frame = it.frame();
   8991     PrintF("fp = %p, sp = %p, caller_sp = %p: ",
   8992            frame->fp(), frame->sp(), frame->caller_sp());
   8993   } else {
   8994     PrintF("DebugPrint: ");
   8995   }
   8996   args[0]->Print();
   8997   if (args[0]->IsHeapObject()) {
   8998     PrintF("\n");
   8999     HeapObject::cast(args[0])->map()->Print();
   9000   }
   9001 #else
   9002   // ShortPrint is available in release mode. Print is not.
   9003   args[0]->ShortPrint();
   9004 #endif
   9005   PrintF("\n");
   9006   Flush();
   9007 
   9008   return args[0];  // return TOS
   9009 }
   9010 
   9011 
   9012 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugTrace) {
   9013   ASSERT(args.length() == 0);
   9014   NoHandleAllocation ha;
   9015   isolate->PrintStack();
   9016   return isolate->heap()->undefined_value();
   9017 }
   9018 
   9019 
   9020 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
   9021   NoHandleAllocation ha;
   9022   ASSERT(args.length() == 0);
   9023 
   9024   // According to ECMA-262, section 15.9.1, page 117, the precision of
   9025   // the number in a Date object representing a particular instant in
   9026   // time is milliseconds. Therefore, we floor the result of getting
   9027   // the OS time.
   9028   double millis = floor(OS::TimeCurrentMillis());
   9029   return isolate->heap()->NumberFromDouble(millis);
   9030 }
   9031 
   9032 
   9033 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
   9034   HandleScope scope(isolate);
   9035   ASSERT(args.length() == 2);
   9036 
   9037   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
   9038   FlattenString(str);
   9039 
   9040   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
   9041 
   9042   MaybeObject* maybe_result_array =
   9043       output->EnsureCanContainHeapObjectElements();
   9044   if (maybe_result_array->IsFailure()) return maybe_result_array;
   9045   RUNTIME_ASSERT(output->HasFastElements());
   9046 
   9047   AssertNoAllocation no_allocation;
   9048 
   9049   FixedArray* output_array = FixedArray::cast(output->elements());
   9050   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
   9051   bool result;
   9052   String::FlatContent str_content = str->GetFlatContent();
   9053   if (str_content.IsAscii()) {
   9054     result = DateParser::Parse(str_content.ToAsciiVector(),
   9055                                output_array,
   9056                                isolate->unicode_cache());
   9057   } else {
   9058     ASSERT(str_content.IsTwoByte());
   9059     result = DateParser::Parse(str_content.ToUC16Vector(),
   9060                                output_array,
   9061                                isolate->unicode_cache());
   9062   }
   9063 
   9064   if (result) {
   9065     return *output;
   9066   } else {
   9067     return isolate->heap()->null_value();
   9068   }
   9069 }
   9070 
   9071 
   9072 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
   9073   NoHandleAllocation ha;
   9074   ASSERT(args.length() == 1);
   9075 
   9076   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9077   int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x));
   9078   const char* zone = OS::LocalTimezone(static_cast<double>(time));
   9079   return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
   9080 }
   9081 
   9082 
   9083 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateToUTC) {
   9084   NoHandleAllocation ha;
   9085   ASSERT(args.length() == 1);
   9086 
   9087   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   9088   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
   9089 
   9090   return isolate->heap()->NumberFromDouble(static_cast<double>(time));
   9091 }
   9092 
   9093 
   9094 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
   9095   ASSERT(args.length() == 1);
   9096   Object* global = args[0];
   9097   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
   9098   return JSGlobalObject::cast(global)->global_receiver();
   9099 }
   9100 
   9101 
   9102 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
   9103   HandleScope scope(isolate);
   9104   ASSERT_EQ(1, args.length());
   9105   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9106 
   9107   source = Handle<String>(source->TryFlattenGetString());
   9108   // Optimized fast case where we only have ASCII characters.
   9109   Handle<Object> result;
   9110   if (source->IsSeqAsciiString()) {
   9111     result = JsonParser<true>::Parse(source);
   9112   } else {
   9113     result = JsonParser<false>::Parse(source);
   9114   }
   9115   if (result.is_null()) {
   9116     // Syntax error or stack overflow in scanner.
   9117     ASSERT(isolate->has_pending_exception());
   9118     return Failure::Exception();
   9119   }
   9120   return *result;
   9121 }
   9122 
   9123 
   9124 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   9125                                       Handle<Context> context) {
   9126   ASSERT(context->allow_code_gen_from_strings()->IsFalse());
   9127   // Check with callback if set.
   9128   AllowCodeGenerationFromStringsCallback callback =
   9129       isolate->allow_code_gen_callback();
   9130   if (callback == NULL) {
   9131     // No callback set and code generation disallowed.
   9132     return false;
   9133   } else {
   9134     // Callback set. Let it decide if code generation is allowed.
   9135     VMState state(isolate, EXTERNAL);
   9136     return callback(v8::Utils::ToLocal(context));
   9137   }
   9138 }
   9139 
   9140 
   9141 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
   9142   HandleScope scope(isolate);
   9143   ASSERT_EQ(1, args.length());
   9144   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   9145 
   9146   // Extract global context.
   9147   Handle<Context> context(isolate->context()->global_context());
   9148 
   9149   // Check if global context allows code generation from
   9150   // strings. Throw an exception if it doesn't.
   9151   if (context->allow_code_gen_from_strings()->IsFalse() &&
   9152       !CodeGenerationFromStringsAllowed(isolate, context)) {
   9153     return isolate->Throw(*isolate->factory()->NewError(
   9154         "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
   9155   }
   9156 
   9157   // Compile source string in the global context.
   9158   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   9159       source, context, true, CLASSIC_MODE, RelocInfo::kNoPosition);
   9160   if (shared.is_null()) return Failure::Exception();
   9161   Handle<JSFunction> fun =
   9162       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   9163                                                             context,
   9164                                                             NOT_TENURED);
   9165   return *fun;
   9166 }
   9167 
   9168 
   9169 static ObjectPair CompileGlobalEval(Isolate* isolate,
   9170                                     Handle<String> source,
   9171                                     Handle<Object> receiver,
   9172                                     LanguageMode language_mode,
   9173                                     int scope_position) {
   9174   Handle<Context> context = Handle<Context>(isolate->context());
   9175   Handle<Context> global_context = Handle<Context>(context->global_context());
   9176 
   9177   // Check if global context allows code generation from
   9178   // strings. Throw an exception if it doesn't.
   9179   if (global_context->allow_code_gen_from_strings()->IsFalse() &&
   9180       !CodeGenerationFromStringsAllowed(isolate, global_context)) {
   9181     isolate->Throw(*isolate->factory()->NewError(
   9182         "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
   9183     return MakePair(Failure::Exception(), NULL);
   9184   }
   9185 
   9186   // Deal with a normal eval call with a string argument. Compile it
   9187   // and return the compiled function bound in the local context.
   9188   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
   9189       source,
   9190       Handle<Context>(isolate->context()),
   9191       context->IsGlobalContext(),
   9192       language_mode,
   9193       scope_position);
   9194   if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
   9195   Handle<JSFunction> compiled =
   9196       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   9197           shared, context, NOT_TENURED);
   9198   return MakePair(*compiled, *receiver);
   9199 }
   9200 
   9201 
   9202 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
   9203   ASSERT(args.length() == 5);
   9204 
   9205   HandleScope scope(isolate);
   9206   Handle<Object> callee = args.at<Object>(0);
   9207 
   9208   // If "eval" didn't refer to the original GlobalEval, it's not a
   9209   // direct call to eval.
   9210   // (And even if it is, but the first argument isn't a string, just let
   9211   // execution default to an indirect call to eval, which will also return
   9212   // the first argument without doing anything).
   9213   if (*callee != isolate->global_context()->global_eval_fun() ||
   9214       !args[1]->IsString()) {
   9215     return MakePair(*callee, isolate->heap()->the_hole_value());
   9216   }
   9217 
   9218   CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
   9219   ASSERT(args[4]->IsSmi());
   9220   return CompileGlobalEval(isolate,
   9221                            args.at<String>(1),
   9222                            args.at<Object>(2),
   9223                            language_mode,
   9224                            args.smi_at(4));
   9225 }
   9226 
   9227 
   9228 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNewFunctionAttributes) {
   9229   // This utility adjusts the property attributes for newly created Function
   9230   // object ("new Function(...)") by changing the map.
   9231   // All it does is changing the prototype property to enumerable
   9232   // as specified in ECMA262, 15.3.5.2.
   9233   HandleScope scope(isolate);
   9234   ASSERT(args.length() == 1);
   9235   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   9236 
   9237   Handle<Map> map = func->shared()->is_classic_mode()
   9238       ? isolate->function_instance_map()
   9239       : isolate->strict_mode_function_instance_map();
   9240 
   9241   ASSERT(func->map()->instance_type() == map->instance_type());
   9242   ASSERT(func->map()->instance_size() == map->instance_size());
   9243   func->set_map(*map);
   9244   return *func;
   9245 }
   9246 
   9247 
   9248 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) {
   9249   // Allocate a block of memory in NewSpace (filled with a filler).
   9250   // Use as fallback for allocation in generated code when NewSpace
   9251   // is full.
   9252   ASSERT(args.length() == 1);
   9253   CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
   9254   int size = size_smi->value();
   9255   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
   9256   RUNTIME_ASSERT(size > 0);
   9257   Heap* heap = isolate->heap();
   9258   const int kMinFreeNewSpaceAfterGC = heap->InitialSemiSpaceSize() * 3/4;
   9259   RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC);
   9260   Object* allocation;
   9261   { MaybeObject* maybe_allocation = heap->new_space()->AllocateRaw(size);
   9262     if (maybe_allocation->ToObject(&allocation)) {
   9263       heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size);
   9264     }
   9265     return maybe_allocation;
   9266   }
   9267 }
   9268 
   9269 
   9270 // Push an object unto an array of objects if it is not already in the
   9271 // array.  Returns true if the element was pushed on the stack and
   9272 // false otherwise.
   9273 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
   9274   ASSERT(args.length() == 2);
   9275   CONVERT_ARG_CHECKED(JSArray, array, 0);
   9276   CONVERT_ARG_CHECKED(JSObject, element, 1);
   9277   RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
   9278   int length = Smi::cast(array->length())->value();
   9279   FixedArray* elements = FixedArray::cast(array->elements());
   9280   for (int i = 0; i < length; i++) {
   9281     if (elements->get(i) == element) return isolate->heap()->false_value();
   9282   }
   9283   Object* obj;
   9284   // Strict not needed. Used for cycle detection in Array join implementation.
   9285   { MaybeObject* maybe_obj =
   9286         array->SetFastElement(length, element, kNonStrictMode, true);
   9287     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   9288   }
   9289   return isolate->heap()->true_value();
   9290 }
   9291 
   9292 
   9293 /**
   9294  * A simple visitor visits every element of Array's.
   9295  * The backend storage can be a fixed array for fast elements case,
   9296  * or a dictionary for sparse array. Since Dictionary is a subtype
   9297  * of FixedArray, the class can be used by both fast and slow cases.
   9298  * The second parameter of the constructor, fast_elements, specifies
   9299  * whether the storage is a FixedArray or Dictionary.
   9300  *
   9301  * An index limit is used to deal with the situation that a result array
   9302  * length overflows 32-bit non-negative integer.
   9303  */
   9304 class ArrayConcatVisitor {
   9305  public:
   9306   ArrayConcatVisitor(Isolate* isolate,
   9307                      Handle<FixedArray> storage,
   9308                      bool fast_elements) :
   9309       isolate_(isolate),
   9310       storage_(Handle<FixedArray>::cast(
   9311           isolate->global_handles()->Create(*storage))),
   9312       index_offset_(0u),
   9313       fast_elements_(fast_elements) { }
   9314 
   9315   ~ArrayConcatVisitor() {
   9316     clear_storage();
   9317   }
   9318 
   9319   void visit(uint32_t i, Handle<Object> elm) {
   9320     if (i >= JSObject::kMaxElementCount - index_offset_) return;
   9321     uint32_t index = index_offset_ + i;
   9322 
   9323     if (fast_elements_) {
   9324       if (index < static_cast<uint32_t>(storage_->length())) {
   9325         storage_->set(index, *elm);
   9326         return;
   9327       }
   9328       // Our initial estimate of length was foiled, possibly by
   9329       // getters on the arrays increasing the length of later arrays
   9330       // during iteration.
   9331       // This shouldn't happen in anything but pathological cases.
   9332       SetDictionaryMode(index);
   9333       // Fall-through to dictionary mode.
   9334     }
   9335     ASSERT(!fast_elements_);
   9336     Handle<SeededNumberDictionary> dict(
   9337         SeededNumberDictionary::cast(*storage_));
   9338     Handle<SeededNumberDictionary> result =
   9339         isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
   9340     if (!result.is_identical_to(dict)) {
   9341       // Dictionary needed to grow.
   9342       clear_storage();
   9343       set_storage(*result);
   9344     }
   9345 }
   9346 
   9347   void increase_index_offset(uint32_t delta) {
   9348     if (JSObject::kMaxElementCount - index_offset_ < delta) {
   9349       index_offset_ = JSObject::kMaxElementCount;
   9350     } else {
   9351       index_offset_ += delta;
   9352     }
   9353   }
   9354 
   9355   Handle<JSArray> ToArray() {
   9356     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
   9357     Handle<Object> length =
   9358         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
   9359     Handle<Map> map;
   9360     if (fast_elements_) {
   9361       map = isolate_->factory()->GetElementsTransitionMap(array,
   9362                                                           FAST_ELEMENTS);
   9363     } else {
   9364       map = isolate_->factory()->GetElementsTransitionMap(array,
   9365                                                           DICTIONARY_ELEMENTS);
   9366     }
   9367     array->set_map(*map);
   9368     array->set_length(*length);
   9369     array->set_elements(*storage_);
   9370     return array;
   9371   }
   9372 
   9373  private:
   9374   // Convert storage to dictionary mode.
   9375   void SetDictionaryMode(uint32_t index) {
   9376     ASSERT(fast_elements_);
   9377     Handle<FixedArray> current_storage(*storage_);
   9378     Handle<SeededNumberDictionary> slow_storage(
   9379         isolate_->factory()->NewSeededNumberDictionary(
   9380             current_storage->length()));
   9381     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
   9382     for (uint32_t i = 0; i < current_length; i++) {
   9383       HandleScope loop_scope;
   9384       Handle<Object> element(current_storage->get(i));
   9385       if (!element->IsTheHole()) {
   9386         Handle<SeededNumberDictionary> new_storage =
   9387           isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
   9388         if (!new_storage.is_identical_to(slow_storage)) {
   9389           slow_storage = loop_scope.CloseAndEscape(new_storage);
   9390         }
   9391       }
   9392     }
   9393     clear_storage();
   9394     set_storage(*slow_storage);
   9395     fast_elements_ = false;
   9396   }
   9397 
   9398   inline void clear_storage() {
   9399     isolate_->global_handles()->Destroy(
   9400         Handle<Object>::cast(storage_).location());
   9401   }
   9402 
   9403   inline void set_storage(FixedArray* storage) {
   9404     storage_ = Handle<FixedArray>::cast(
   9405         isolate_->global_handles()->Create(storage));
   9406   }
   9407 
   9408   Isolate* isolate_;
   9409   Handle<FixedArray> storage_;  // Always a global handle.
   9410   // Index after last seen index. Always less than or equal to
   9411   // JSObject::kMaxElementCount.
   9412   uint32_t index_offset_;
   9413   bool fast_elements_;
   9414 };
   9415 
   9416 
   9417 static uint32_t EstimateElementCount(Handle<JSArray> array) {
   9418   uint32_t length = static_cast<uint32_t>(array->length()->Number());
   9419   int element_count = 0;
   9420   switch (array->GetElementsKind()) {
   9421     case FAST_SMI_ONLY_ELEMENTS:
   9422     case FAST_ELEMENTS: {
   9423       // Fast elements can't have lengths that are not representable by
   9424       // a 32-bit signed integer.
   9425       ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
   9426       int fast_length = static_cast<int>(length);
   9427       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
   9428       for (int i = 0; i < fast_length; i++) {
   9429         if (!elements->get(i)->IsTheHole()) element_count++;
   9430       }
   9431       break;
   9432     }
   9433     case FAST_DOUBLE_ELEMENTS:
   9434       // TODO(1810): Decide if it's worthwhile to implement this.
   9435       UNREACHABLE();
   9436       break;
   9437     case DICTIONARY_ELEMENTS: {
   9438       Handle<SeededNumberDictionary> dictionary(
   9439           SeededNumberDictionary::cast(array->elements()));
   9440       int capacity = dictionary->Capacity();
   9441       for (int i = 0; i < capacity; i++) {
   9442         Handle<Object> key(dictionary->KeyAt(i));
   9443         if (dictionary->IsKey(*key)) {
   9444           element_count++;
   9445         }
   9446       }
   9447       break;
   9448     }
   9449     case NON_STRICT_ARGUMENTS_ELEMENTS:
   9450     case EXTERNAL_BYTE_ELEMENTS:
   9451     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
   9452     case EXTERNAL_SHORT_ELEMENTS:
   9453     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
   9454     case EXTERNAL_INT_ELEMENTS:
   9455     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
   9456     case EXTERNAL_FLOAT_ELEMENTS:
   9457     case EXTERNAL_DOUBLE_ELEMENTS:
   9458     case EXTERNAL_PIXEL_ELEMENTS:
   9459       // External arrays are always dense.
   9460       return length;
   9461   }
   9462   // As an estimate, we assume that the prototype doesn't contain any
   9463   // inherited elements.
   9464   return element_count;
   9465 }
   9466 
   9467 
   9468 
   9469 template<class ExternalArrayClass, class ElementType>
   9470 static void IterateExternalArrayElements(Isolate* isolate,
   9471                                          Handle<JSObject> receiver,
   9472                                          bool elements_are_ints,
   9473                                          bool elements_are_guaranteed_smis,
   9474                                          ArrayConcatVisitor* visitor) {
   9475   Handle<ExternalArrayClass> array(
   9476       ExternalArrayClass::cast(receiver->elements()));
   9477   uint32_t len = static_cast<uint32_t>(array->length());
   9478 
   9479   ASSERT(visitor != NULL);
   9480   if (elements_are_ints) {
   9481     if (elements_are_guaranteed_smis) {
   9482       for (uint32_t j = 0; j < len; j++) {
   9483         HandleScope loop_scope;
   9484         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))));
   9485         visitor->visit(j, e);
   9486       }
   9487     } else {
   9488       for (uint32_t j = 0; j < len; j++) {
   9489         HandleScope loop_scope;
   9490         int64_t val = static_cast<int64_t>(array->get_scalar(j));
   9491         if (Smi::IsValid(static_cast<intptr_t>(val))) {
   9492           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
   9493           visitor->visit(j, e);
   9494         } else {
   9495           Handle<Object> e =
   9496               isolate->factory()->NewNumber(static_cast<ElementType>(val));
   9497           visitor->visit(j, e);
   9498         }
   9499       }
   9500     }
   9501   } else {
   9502     for (uint32_t j = 0; j < len; j++) {
   9503       HandleScope loop_scope(isolate);
   9504       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
   9505       visitor->visit(j, e);
   9506     }
   9507   }
   9508 }
   9509 
   9510 
   9511 // Used for sorting indices in a List<uint32_t>.
   9512 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
   9513   uint32_t a = *ap;
   9514   uint32_t b = *bp;
   9515   return (a == b) ? 0 : (a < b) ? -1 : 1;
   9516 }
   9517 
   9518 
   9519 static void CollectElementIndices(Handle<JSObject> object,
   9520                                   uint32_t range,
   9521                                   List<uint32_t>* indices) {
   9522   ElementsKind kind = object->GetElementsKind();
   9523   switch (kind) {
   9524     case FAST_SMI_ONLY_ELEMENTS:
   9525     case FAST_ELEMENTS: {
   9526       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
   9527       uint32_t length = static_cast<uint32_t>(elements->length());
   9528       if (range < length) length = range;
   9529       for (uint32_t i = 0; i < length; i++) {
   9530         if (!elements->get(i)->IsTheHole()) {
   9531           indices->Add(i);
   9532         }
   9533       }
   9534       break;
   9535     }
   9536     case FAST_DOUBLE_ELEMENTS: {
   9537       // TODO(1810): Decide if it's worthwhile to implement this.
   9538       UNREACHABLE();
   9539       break;
   9540     }
   9541     case DICTIONARY_ELEMENTS: {
   9542       Handle<SeededNumberDictionary> dict(
   9543           SeededNumberDictionary::cast(object->elements()));
   9544       uint32_t capacity = dict->Capacity();
   9545       for (uint32_t j = 0; j < capacity; j++) {
   9546         HandleScope loop_scope;
   9547         Handle<Object> k(dict->KeyAt(j));
   9548         if (dict->IsKey(*k)) {
   9549           ASSERT(k->IsNumber());
   9550           uint32_t index = static_cast<uint32_t>(k->Number());
   9551           if (index < range) {
   9552             indices->Add(index);
   9553           }
   9554         }
   9555       }
   9556       break;
   9557     }
   9558     default: {
   9559       int dense_elements_length;
   9560       switch (kind) {
   9561         case EXTERNAL_PIXEL_ELEMENTS: {
   9562           dense_elements_length =
   9563               ExternalPixelArray::cast(object->elements())->length();
   9564           break;
   9565         }
   9566         case EXTERNAL_BYTE_ELEMENTS: {
   9567           dense_elements_length =
   9568               ExternalByteArray::cast(object->elements())->length();
   9569           break;
   9570         }
   9571         case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
   9572           dense_elements_length =
   9573               ExternalUnsignedByteArray::cast(object->elements())->length();
   9574           break;
   9575         }
   9576         case EXTERNAL_SHORT_ELEMENTS: {
   9577           dense_elements_length =
   9578               ExternalShortArray::cast(object->elements())->length();
   9579           break;
   9580         }
   9581         case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
   9582           dense_elements_length =
   9583               ExternalUnsignedShortArray::cast(object->elements())->length();
   9584           break;
   9585         }
   9586         case EXTERNAL_INT_ELEMENTS: {
   9587           dense_elements_length =
   9588               ExternalIntArray::cast(object->elements())->length();
   9589           break;
   9590         }
   9591         case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
   9592           dense_elements_length =
   9593               ExternalUnsignedIntArray::cast(object->elements())->length();
   9594           break;
   9595         }
   9596         case EXTERNAL_FLOAT_ELEMENTS: {
   9597           dense_elements_length =
   9598               ExternalFloatArray::cast(object->elements())->length();
   9599           break;
   9600         }
   9601         case EXTERNAL_DOUBLE_ELEMENTS: {
   9602           dense_elements_length =
   9603               ExternalDoubleArray::cast(object->elements())->length();
   9604           break;
   9605         }
   9606         default:
   9607           UNREACHABLE();
   9608           dense_elements_length = 0;
   9609           break;
   9610       }
   9611       uint32_t length = static_cast<uint32_t>(dense_elements_length);
   9612       if (range <= length) {
   9613         length = range;
   9614         // We will add all indices, so we might as well clear it first
   9615         // and avoid duplicates.
   9616         indices->Clear();
   9617       }
   9618       for (uint32_t i = 0; i < length; i++) {
   9619         indices->Add(i);
   9620       }
   9621       if (length == range) return;  // All indices accounted for already.
   9622       break;
   9623     }
   9624   }
   9625 
   9626   Handle<Object> prototype(object->GetPrototype());
   9627   if (prototype->IsJSObject()) {
   9628     // The prototype will usually have no inherited element indices,
   9629     // but we have to check.
   9630     CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
   9631   }
   9632 }
   9633 
   9634 
   9635 /**
   9636  * A helper function that visits elements of a JSArray in numerical
   9637  * order.
   9638  *
   9639  * The visitor argument called for each existing element in the array
   9640  * with the element index and the element's value.
   9641  * Afterwards it increments the base-index of the visitor by the array
   9642  * length.
   9643  * Returns false if any access threw an exception, otherwise true.
   9644  */
   9645 static bool IterateElements(Isolate* isolate,
   9646                             Handle<JSArray> receiver,
   9647                             ArrayConcatVisitor* visitor) {
   9648   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
   9649   switch (receiver->GetElementsKind()) {
   9650     case FAST_SMI_ONLY_ELEMENTS:
   9651     case FAST_ELEMENTS: {
   9652       // Run through the elements FixedArray and use HasElement and GetElement
   9653       // to check the prototype for missing elements.
   9654       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
   9655       int fast_length = static_cast<int>(length);
   9656       ASSERT(fast_length <= elements->length());
   9657       for (int j = 0; j < fast_length; j++) {
   9658         HandleScope loop_scope(isolate);
   9659         Handle<Object> element_value(elements->get(j), isolate);
   9660         if (!element_value->IsTheHole()) {
   9661           visitor->visit(j, element_value);
   9662         } else if (receiver->HasElement(j)) {
   9663           // Call GetElement on receiver, not its prototype, or getters won't
   9664           // have the correct receiver.
   9665           element_value = Object::GetElement(receiver, j);
   9666           RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
   9667           visitor->visit(j, element_value);
   9668         }
   9669       }
   9670       break;
   9671     }
   9672     case FAST_DOUBLE_ELEMENTS: {
   9673       // TODO(1810): Decide if it's worthwhile to implement this.
   9674       UNREACHABLE();
   9675       break;
   9676     }
   9677     case DICTIONARY_ELEMENTS: {
   9678       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
   9679       List<uint32_t> indices(dict->Capacity() / 2);
   9680       // Collect all indices in the object and the prototypes less
   9681       // than length. This might introduce duplicates in the indices list.
   9682       CollectElementIndices(receiver, length, &indices);
   9683       indices.Sort(&compareUInt32);
   9684       int j = 0;
   9685       int n = indices.length();
   9686       while (j < n) {
   9687         HandleScope loop_scope;
   9688         uint32_t index = indices[j];
   9689         Handle<Object> element = Object::GetElement(receiver, index);
   9690         RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
   9691         visitor->visit(index, element);
   9692         // Skip to next different index (i.e., omit duplicates).
   9693         do {
   9694           j++;
   9695         } while (j < n && indices[j] == index);
   9696       }
   9697       break;
   9698     }
   9699     case EXTERNAL_PIXEL_ELEMENTS: {
   9700       Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
   9701           receiver->elements()));
   9702       for (uint32_t j = 0; j < length; j++) {
   9703         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)));
   9704         visitor->visit(j, e);
   9705       }
   9706       break;
   9707     }
   9708     case EXTERNAL_BYTE_ELEMENTS: {
   9709       IterateExternalArrayElements<ExternalByteArray, int8_t>(
   9710           isolate, receiver, true, true, visitor);
   9711       break;
   9712     }
   9713     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
   9714       IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>(
   9715           isolate, receiver, true, true, visitor);
   9716       break;
   9717     }
   9718     case EXTERNAL_SHORT_ELEMENTS: {
   9719       IterateExternalArrayElements<ExternalShortArray, int16_t>(
   9720           isolate, receiver, true, true, visitor);
   9721       break;
   9722     }
   9723     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
   9724       IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>(
   9725           isolate, receiver, true, true, visitor);
   9726       break;
   9727     }
   9728     case EXTERNAL_INT_ELEMENTS: {
   9729       IterateExternalArrayElements<ExternalIntArray, int32_t>(
   9730           isolate, receiver, true, false, visitor);
   9731       break;
   9732     }
   9733     case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
   9734       IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>(
   9735           isolate, receiver, true, false, visitor);
   9736       break;
   9737     }
   9738     case EXTERNAL_FLOAT_ELEMENTS: {
   9739       IterateExternalArrayElements<ExternalFloatArray, float>(
   9740           isolate, receiver, false, false, visitor);
   9741       break;
   9742     }
   9743     case EXTERNAL_DOUBLE_ELEMENTS: {
   9744       IterateExternalArrayElements<ExternalDoubleArray, double>(
   9745           isolate, receiver, false, false, visitor);
   9746       break;
   9747     }
   9748     default:
   9749       UNREACHABLE();
   9750       break;
   9751   }
   9752   visitor->increase_index_offset(length);
   9753   return true;
   9754 }
   9755 
   9756 
   9757 /**
   9758  * Array::concat implementation.
   9759  * See ECMAScript 262, 15.4.4.4.
   9760  * TODO(581): Fix non-compliance for very large concatenations and update to
   9761  * following the ECMAScript 5 specification.
   9762  */
   9763 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
   9764   ASSERT(args.length() == 1);
   9765   HandleScope handle_scope(isolate);
   9766 
   9767   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
   9768   int argument_count = static_cast<int>(arguments->length()->Number());
   9769   RUNTIME_ASSERT(arguments->HasFastElements());
   9770   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
   9771 
   9772   // Pass 1: estimate the length and number of elements of the result.
   9773   // The actual length can be larger if any of the arguments have getters
   9774   // that mutate other arguments (but will otherwise be precise).
   9775   // The number of elements is precise if there are no inherited elements.
   9776 
   9777   uint32_t estimate_result_length = 0;
   9778   uint32_t estimate_nof_elements = 0;
   9779   {
   9780     for (int i = 0; i < argument_count; i++) {
   9781       HandleScope loop_scope;
   9782       Handle<Object> obj(elements->get(i));
   9783       uint32_t length_estimate;
   9784       uint32_t element_estimate;
   9785       if (obj->IsJSArray()) {
   9786         Handle<JSArray> array(Handle<JSArray>::cast(obj));
   9787         // TODO(1810): Find out if it's worthwhile to properly support
   9788         // arbitrary ElementsKinds. For now, pessimistically transition to
   9789         // FAST_ELEMENTS.
   9790         if (array->HasFastDoubleElements()) {
   9791           array = Handle<JSArray>::cast(
   9792               JSObject::TransitionElementsKind(array, FAST_ELEMENTS));
   9793         }
   9794         length_estimate =
   9795             static_cast<uint32_t>(array->length()->Number());
   9796         element_estimate =
   9797             EstimateElementCount(array);
   9798       } else {
   9799         length_estimate = 1;
   9800         element_estimate = 1;
   9801       }
   9802       // Avoid overflows by capping at kMaxElementCount.
   9803       if (JSObject::kMaxElementCount - estimate_result_length <
   9804           length_estimate) {
   9805         estimate_result_length = JSObject::kMaxElementCount;
   9806       } else {
   9807         estimate_result_length += length_estimate;
   9808       }
   9809       if (JSObject::kMaxElementCount - estimate_nof_elements <
   9810           element_estimate) {
   9811         estimate_nof_elements = JSObject::kMaxElementCount;
   9812       } else {
   9813         estimate_nof_elements += element_estimate;
   9814       }
   9815     }
   9816   }
   9817 
   9818   // If estimated number of elements is more than half of length, a
   9819   // fixed array (fast case) is more time and space-efficient than a
   9820   // dictionary.
   9821   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
   9822 
   9823   Handle<FixedArray> storage;
   9824   if (fast_case) {
   9825     // The backing storage array must have non-existing elements to
   9826     // preserve holes across concat operations.
   9827     storage = isolate->factory()->NewFixedArrayWithHoles(
   9828         estimate_result_length);
   9829   } else {
   9830     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
   9831     uint32_t at_least_space_for = estimate_nof_elements +
   9832                                   (estimate_nof_elements >> 2);
   9833     storage = Handle<FixedArray>::cast(
   9834         isolate->factory()->NewSeededNumberDictionary(at_least_space_for));
   9835   }
   9836 
   9837   ArrayConcatVisitor visitor(isolate, storage, fast_case);
   9838 
   9839   for (int i = 0; i < argument_count; i++) {
   9840     Handle<Object> obj(elements->get(i));
   9841     if (obj->IsJSArray()) {
   9842       Handle<JSArray> array = Handle<JSArray>::cast(obj);
   9843       if (!IterateElements(isolate, array, &visitor)) {
   9844         return Failure::Exception();
   9845       }
   9846     } else {
   9847       visitor.visit(0, obj);
   9848       visitor.increase_index_offset(1);
   9849     }
   9850   }
   9851 
   9852   return *visitor.ToArray();
   9853 }
   9854 
   9855 
   9856 // This will not allocate (flatten the string), but it may run
   9857 // very slowly for very deeply nested ConsStrings.  For debugging use only.
   9858 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
   9859   NoHandleAllocation ha;
   9860   ASSERT(args.length() == 1);
   9861 
   9862   CONVERT_ARG_CHECKED(String, string, 0);
   9863   StringInputBuffer buffer(string);
   9864   while (buffer.has_more()) {
   9865     uint16_t character = buffer.GetNext();
   9866     PrintF("%c", character);
   9867   }
   9868   return string;
   9869 }
   9870 
   9871 // Moves all own elements of an object, that are below a limit, to positions
   9872 // starting at zero. All undefined values are placed after non-undefined values,
   9873 // and are followed by non-existing element. Does not change the length
   9874 // property.
   9875 // Returns the number of non-undefined elements collected.
   9876 RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
   9877   ASSERT(args.length() == 2);
   9878   CONVERT_ARG_CHECKED(JSObject, object, 0);
   9879   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
   9880   return object->PrepareElementsForSort(limit);
   9881 }
   9882 
   9883 
   9884 // Move contents of argument 0 (an array) to argument 1 (an array)
   9885 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
   9886   ASSERT(args.length() == 2);
   9887   CONVERT_ARG_CHECKED(JSArray, from, 0);
   9888   CONVERT_ARG_CHECKED(JSArray, to, 1);
   9889   FixedArrayBase* new_elements = from->elements();
   9890   MaybeObject* maybe_new_map;
   9891   ElementsKind elements_kind;
   9892   if (new_elements->map() == isolate->heap()->fixed_array_map() ||
   9893       new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
   9894     elements_kind = FAST_ELEMENTS;
   9895   } else if (new_elements->map() ==
   9896              isolate->heap()->fixed_double_array_map()) {
   9897     elements_kind = FAST_DOUBLE_ELEMENTS;
   9898   } else {
   9899     elements_kind = DICTIONARY_ELEMENTS;
   9900   }
   9901   maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind);
   9902   Object* new_map;
   9903   if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
   9904   to->set_map(Map::cast(new_map));
   9905   to->set_elements(new_elements);
   9906   to->set_length(from->length());
   9907   Object* obj;
   9908   { MaybeObject* maybe_obj = from->ResetElements();
   9909     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   9910   }
   9911   from->set_length(Smi::FromInt(0));
   9912   return to;
   9913 }
   9914 
   9915 
   9916 // How many elements does this object/array have?
   9917 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
   9918   ASSERT(args.length() == 1);
   9919   CONVERT_ARG_CHECKED(JSObject, object, 0);
   9920   HeapObject* elements = object->elements();
   9921   if (elements->IsDictionary()) {
   9922     int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
   9923     return Smi::FromInt(result);
   9924   } else if (object->IsJSArray()) {
   9925     return JSArray::cast(object)->length();
   9926   } else {
   9927     return Smi::FromInt(FixedArray::cast(elements)->length());
   9928   }
   9929 }
   9930 
   9931 
   9932 // Returns an array that tells you where in the [0, length) interval an array
   9933 // might have elements.  Can either return keys (positive integers) or
   9934 // intervals (pair of a negative integer (-start-1) followed by a
   9935 // positive (length)) or undefined values.
   9936 // Intervals can span over some keys that are not in the object.
   9937 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
   9938   ASSERT(args.length() == 2);
   9939   HandleScope scope(isolate);
   9940   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   9941   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
   9942   if (array->elements()->IsDictionary()) {
   9943     // Create an array and get all the keys into it, then remove all the
   9944     // keys that are not integers in the range 0 to length-1.
   9945     bool threw = false;
   9946     Handle<FixedArray> keys =
   9947         GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw);
   9948     if (threw) return Failure::Exception();
   9949 
   9950     int keys_length = keys->length();
   9951     for (int i = 0; i < keys_length; i++) {
   9952       Object* key = keys->get(i);
   9953       uint32_t index = 0;
   9954       if (!key->ToArrayIndex(&index) || index >= length) {
   9955         // Zap invalid keys.
   9956         keys->set_undefined(i);
   9957       }
   9958     }
   9959     return *isolate->factory()->NewJSArrayWithElements(keys);
   9960   } else {
   9961     ASSERT(array->HasFastElements() ||
   9962            array->HasFastSmiOnlyElements() ||
   9963            array->HasFastDoubleElements());
   9964     Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
   9965     // -1 means start of array.
   9966     single_interval->set(0, Smi::FromInt(-1));
   9967     FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
   9968     uint32_t actual_length =
   9969         static_cast<uint32_t>(elements->length());
   9970     uint32_t min_length = actual_length < length ? actual_length : length;
   9971     Handle<Object> length_object =
   9972         isolate->factory()->NewNumber(static_cast<double>(min_length));
   9973     single_interval->set(1, *length_object);
   9974     return *isolate->factory()->NewJSArrayWithElements(single_interval);
   9975   }
   9976 }
   9977 
   9978 
   9979 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
   9980   ASSERT(args.length() == 3);
   9981   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   9982   CONVERT_ARG_CHECKED(String, name, 1);
   9983   CONVERT_SMI_ARG_CHECKED(flag, 2);
   9984   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
   9985   return obj->LookupAccessor(name, component);
   9986 }
   9987 
   9988 
   9989 #ifdef ENABLE_DEBUGGER_SUPPORT
   9990 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
   9991   ASSERT(args.length() == 0);
   9992   return Execution::DebugBreakHelper();
   9993 }
   9994 
   9995 
   9996 // Helper functions for wrapping and unwrapping stack frame ids.
   9997 static Smi* WrapFrameId(StackFrame::Id id) {
   9998   ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
   9999   return Smi::FromInt(id >> 2);
   10000 }
   10001 
   10002 
   10003 static StackFrame::Id UnwrapFrameId(int wrapped) {
   10004   return static_cast<StackFrame::Id>(wrapped << 2);
   10005 }
   10006 
   10007 
   10008 // Adds a JavaScript function as a debug event listener.
   10009 // args[0]: debug event listener function to set or null or undefined for
   10010 //          clearing the event listener function
   10011 // args[1]: object supplied during callback
   10012 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDebugEventListener) {
   10013   ASSERT(args.length() == 2);
   10014   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
   10015                  args[0]->IsUndefined() ||
   10016                  args[0]->IsNull());
   10017   Handle<Object> callback = args.at<Object>(0);
   10018   Handle<Object> data = args.at<Object>(1);
   10019   isolate->debugger()->SetEventListener(callback, data);
   10020 
   10021   return isolate->heap()->undefined_value();
   10022 }
   10023 
   10024 
   10025 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
   10026   ASSERT(args.length() == 0);
   10027   isolate->stack_guard()->DebugBreak();
   10028   return isolate->heap()->undefined_value();
   10029 }
   10030 
   10031 
   10032 static MaybeObject* DebugLookupResultValue(Heap* heap,
   10033                                            Object* receiver,
   10034                                            String* name,
   10035                                            LookupResult* result,
   10036                                            bool* caught_exception) {
   10037   Object* value;
   10038   switch (result->type()) {
   10039     case NORMAL:
   10040       value = result->holder()->GetNormalizedProperty(result);
   10041       if (value->IsTheHole()) {
   10042         return heap->undefined_value();
   10043       }
   10044       return value;
   10045     case FIELD:
   10046       value =
   10047           JSObject::cast(
   10048               result->holder())->FastPropertyAt(result->GetFieldIndex());
   10049       if (value->IsTheHole()) {
   10050         return heap->undefined_value();
   10051       }
   10052       return value;
   10053     case CONSTANT_FUNCTION:
   10054       return result->GetConstantFunction();
   10055     case CALLBACKS: {
   10056       Object* structure = result->GetCallbackObject();
   10057       if (structure->IsForeign() || structure->IsAccessorInfo()) {
   10058         MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
   10059             receiver, structure, name);
   10060         if (!maybe_value->ToObject(&value)) {
   10061           if (maybe_value->IsRetryAfterGC()) return maybe_value;
   10062           ASSERT(maybe_value->IsException());
   10063           maybe_value = heap->isolate()->pending_exception();
   10064           heap->isolate()->clear_pending_exception();
   10065           if (caught_exception != NULL) {
   10066             *caught_exception = true;
   10067           }
   10068           return maybe_value;
   10069         }
   10070         return value;
   10071       } else {
   10072         return heap->undefined_value();
   10073       }
   10074     }
   10075     case INTERCEPTOR:
   10076     case MAP_TRANSITION:
   10077     case ELEMENTS_TRANSITION:
   10078     case CONSTANT_TRANSITION:
   10079     case NULL_DESCRIPTOR:
   10080       return heap->undefined_value();
   10081     case HANDLER:
   10082       UNREACHABLE();
   10083       return heap->undefined_value();
   10084   }
   10085   UNREACHABLE();  // keep the compiler happy
   10086   return heap->undefined_value();
   10087 }
   10088 
   10089 
   10090 // Get debugger related details for an object property.
   10091 // args[0]: object holding property
   10092 // args[1]: name of the property
   10093 //
   10094 // The array returned contains the following information:
   10095 // 0: Property value
   10096 // 1: Property details
   10097 // 2: Property value is exception
   10098 // 3: Getter function if defined
   10099 // 4: Setter function if defined
   10100 // Items 2-4 are only filled if the property has either a getter or a setter
   10101 // defined through __defineGetter__ and/or __defineSetter__.
   10102 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
   10103   HandleScope scope(isolate);
   10104 
   10105   ASSERT(args.length() == 2);
   10106 
   10107   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10108   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   10109 
   10110   // Make sure to set the current context to the context before the debugger was
   10111   // entered (if the debugger is entered). The reason for switching context here
   10112   // is that for some property lookups (accessors and interceptors) callbacks
   10113   // into the embedding application can occour, and the embedding application
   10114   // could have the assumption that its own global context is the current
   10115   // context and not some internal debugger context.
   10116   SaveContext save(isolate);
   10117   if (isolate->debug()->InDebugger()) {
   10118     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
   10119   }
   10120 
   10121   // Skip the global proxy as it has no properties and always delegates to the
   10122   // real global object.
   10123   if (obj->IsJSGlobalProxy()) {
   10124     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
   10125   }
   10126 
   10127 
   10128   // Check if the name is trivially convertible to an index and get the element
   10129   // if so.
   10130   uint32_t index;
   10131   if (name->AsArrayIndex(&index)) {
   10132     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
   10133     Object* element_or_char;
   10134     { MaybeObject* maybe_element_or_char =
   10135           Runtime::GetElementOrCharAt(isolate, obj, index);
   10136       if (!maybe_element_or_char->ToObject(&element_or_char)) {
   10137         return maybe_element_or_char;
   10138       }
   10139     }
   10140     details->set(0, element_or_char);
   10141     details->set(1, PropertyDetails(NONE, NORMAL).AsSmi());
   10142     return *isolate->factory()->NewJSArrayWithElements(details);
   10143   }
   10144 
   10145   // Find the number of objects making up this.
   10146   int length = LocalPrototypeChainLength(*obj);
   10147 
   10148   // Try local lookup on each of the objects.
   10149   Handle<JSObject> jsproto = obj;
   10150   for (int i = 0; i < length; i++) {
   10151     LookupResult result(isolate);
   10152     jsproto->LocalLookup(*name, &result);
   10153     if (result.IsProperty()) {
   10154       // LookupResult is not GC safe as it holds raw object pointers.
   10155       // GC can happen later in this code so put the required fields into
   10156       // local variables using handles when required for later use.
   10157       PropertyType result_type = result.type();
   10158       Handle<Object> result_callback_obj;
   10159       if (result_type == CALLBACKS) {
   10160         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
   10161                                              isolate);
   10162       }
   10163       Smi* property_details = result.GetPropertyDetails().AsSmi();
   10164       // DebugLookupResultValue can cause GC so details from LookupResult needs
   10165       // to be copied to handles before this.
   10166       bool caught_exception = false;
   10167       Object* raw_value;
   10168       { MaybeObject* maybe_raw_value =
   10169             DebugLookupResultValue(isolate->heap(), *obj, *name,
   10170                                    &result, &caught_exception);
   10171         if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value;
   10172       }
   10173       Handle<Object> value(raw_value, isolate);
   10174 
   10175       // If the callback object is a fixed array then it contains JavaScript
   10176       // getter and/or setter.
   10177       bool hasJavaScriptAccessors = result_type == CALLBACKS &&
   10178                                     result_callback_obj->IsAccessorPair();
   10179       Handle<FixedArray> details =
   10180           isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
   10181       details->set(0, *value);
   10182       details->set(1, property_details);
   10183       if (hasJavaScriptAccessors) {
   10184         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
   10185         details->set(2, isolate->heap()->ToBoolean(caught_exception));
   10186         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
   10187         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
   10188       }
   10189 
   10190       return *isolate->factory()->NewJSArrayWithElements(details);
   10191     }
   10192     if (i < length - 1) {
   10193       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
   10194     }
   10195   }
   10196 
   10197   return isolate->heap()->undefined_value();
   10198 }
   10199 
   10200 
   10201 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
   10202   HandleScope scope(isolate);
   10203 
   10204   ASSERT(args.length() == 2);
   10205 
   10206   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10207   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   10208 
   10209   LookupResult result(isolate);
   10210   obj->Lookup(*name, &result);
   10211   if (result.IsProperty()) {
   10212     return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
   10213   }
   10214   return isolate->heap()->undefined_value();
   10215 }
   10216 
   10217 
   10218 // Return the property type calculated from the property details.
   10219 // args[0]: smi with property details.
   10220 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
   10221   ASSERT(args.length() == 1);
   10222   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10223   return Smi::FromInt(static_cast<int>(details.type()));
   10224 }
   10225 
   10226 
   10227 // Return the property attribute calculated from the property details.
   10228 // args[0]: smi with property details.
   10229 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
   10230   ASSERT(args.length() == 1);
   10231   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10232   return Smi::FromInt(static_cast<int>(details.attributes()));
   10233 }
   10234 
   10235 
   10236 // Return the property insertion index calculated from the property details.
   10237 // args[0]: smi with property details.
   10238 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
   10239   ASSERT(args.length() == 1);
   10240   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
   10241   return Smi::FromInt(details.index());
   10242 }
   10243 
   10244 
   10245 // Return property value from named interceptor.
   10246 // args[0]: object
   10247 // args[1]: property name
   10248 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
   10249   HandleScope scope(isolate);
   10250   ASSERT(args.length() == 2);
   10251   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10252   RUNTIME_ASSERT(obj->HasNamedInterceptor());
   10253   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
   10254 
   10255   PropertyAttributes attributes;
   10256   return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
   10257 }
   10258 
   10259 
   10260 // Return element value from indexed interceptor.
   10261 // args[0]: object
   10262 // args[1]: index
   10263 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
   10264   HandleScope scope(isolate);
   10265   ASSERT(args.length() == 2);
   10266   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   10267   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
   10268   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
   10269 
   10270   return obj->GetElementWithInterceptor(*obj, index);
   10271 }
   10272 
   10273 
   10274 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckExecutionState) {
   10275   ASSERT(args.length() >= 1);
   10276   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   10277   // Check that the break id is valid.
   10278   if (isolate->debug()->break_id() == 0 ||
   10279       break_id != isolate->debug()->break_id()) {
   10280     return isolate->Throw(
   10281         isolate->heap()->illegal_execution_state_symbol());
   10282   }
   10283 
   10284   return isolate->heap()->true_value();
   10285 }
   10286 
   10287 
   10288 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
   10289   HandleScope scope(isolate);
   10290   ASSERT(args.length() == 1);
   10291 
   10292   // Check arguments.
   10293   Object* result;
   10294   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   10295       RUNTIME_ARGUMENTS(isolate, args));
   10296     if (!maybe_result->ToObject(&result)) return maybe_result;
   10297   }
   10298 
   10299   // Count all frames which are relevant to debugging stack trace.
   10300   int n = 0;
   10301   StackFrame::Id id = isolate->debug()->break_frame_id();
   10302   if (id == StackFrame::NO_ID) {
   10303     // If there is no JavaScript stack frame count is 0.
   10304     return Smi::FromInt(0);
   10305   }
   10306 
   10307   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
   10308     n += it.frame()->GetInlineCount();
   10309   }
   10310   return Smi::FromInt(n);
   10311 }
   10312 
   10313 
   10314 class FrameInspector {
   10315  public:
   10316   FrameInspector(JavaScriptFrame* frame,
   10317                  int inlined_jsframe_index,
   10318                  Isolate* isolate)
   10319       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
   10320     // Calculate the deoptimized frame.
   10321     if (frame->is_optimized()) {
   10322       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
   10323           frame, inlined_jsframe_index, isolate);
   10324     }
   10325     has_adapted_arguments_ = frame_->has_adapted_arguments();
   10326     is_bottommost_ = inlined_jsframe_index == 0;
   10327     is_optimized_ = frame_->is_optimized();
   10328   }
   10329 
   10330   ~FrameInspector() {
   10331     // Get rid of the calculated deoptimized frame if any.
   10332     if (deoptimized_frame_ != NULL) {
   10333       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
   10334                                                   isolate_);
   10335     }
   10336   }
   10337 
   10338   int GetParametersCount() {
   10339     return is_optimized_
   10340         ? deoptimized_frame_->parameters_count()
   10341         : frame_->ComputeParametersCount();
   10342   }
   10343   int expression_count() { return deoptimized_frame_->expression_count(); }
   10344   Object* GetFunction() {
   10345     return is_optimized_
   10346         ? deoptimized_frame_->GetFunction()
   10347         : frame_->function();
   10348   }
   10349   Object* GetParameter(int index) {
   10350     return is_optimized_
   10351         ? deoptimized_frame_->GetParameter(index)
   10352         : frame_->GetParameter(index);
   10353   }
   10354   Object* GetExpression(int index) {
   10355     return is_optimized_
   10356         ? deoptimized_frame_->GetExpression(index)
   10357         : frame_->GetExpression(index);
   10358   }
   10359   int GetSourcePosition() {
   10360     return is_optimized_
   10361         ? deoptimized_frame_->GetSourcePosition()
   10362         : frame_->LookupCode()->SourcePosition(frame_->pc());
   10363   }
   10364   bool IsConstructor() {
   10365     return is_optimized_ && !is_bottommost_
   10366         ? deoptimized_frame_->HasConstructStub()
   10367         : frame_->IsConstructor();
   10368   }
   10369 
   10370   // To inspect all the provided arguments the frame might need to be
   10371   // replaced with the arguments frame.
   10372   void SetArgumentsFrame(JavaScriptFrame* frame) {
   10373     ASSERT(has_adapted_arguments_);
   10374     frame_ = frame;
   10375     is_optimized_ = frame_->is_optimized();
   10376     ASSERT(!is_optimized_);
   10377   }
   10378 
   10379  private:
   10380   JavaScriptFrame* frame_;
   10381   DeoptimizedFrameInfo* deoptimized_frame_;
   10382   Isolate* isolate_;
   10383   bool is_optimized_;
   10384   bool is_bottommost_;
   10385   bool has_adapted_arguments_;
   10386 
   10387   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
   10388 };
   10389 
   10390 
   10391 static const int kFrameDetailsFrameIdIndex = 0;
   10392 static const int kFrameDetailsReceiverIndex = 1;
   10393 static const int kFrameDetailsFunctionIndex = 2;
   10394 static const int kFrameDetailsArgumentCountIndex = 3;
   10395 static const int kFrameDetailsLocalCountIndex = 4;
   10396 static const int kFrameDetailsSourcePositionIndex = 5;
   10397 static const int kFrameDetailsConstructCallIndex = 6;
   10398 static const int kFrameDetailsAtReturnIndex = 7;
   10399 static const int kFrameDetailsFlagsIndex = 8;
   10400 static const int kFrameDetailsFirstDynamicIndex = 9;
   10401 
   10402 
   10403 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
   10404                                              JavaScriptFrame* frame) {
   10405   SaveContext* save = isolate->save_context();
   10406   while (save != NULL && !save->IsBelowFrame(frame)) {
   10407     save = save->prev();
   10408   }
   10409   ASSERT(save != NULL);
   10410   return save;
   10411 }
   10412 
   10413 
   10414 // Return an array with frame details
   10415 // args[0]: number: break id
   10416 // args[1]: number: frame index
   10417 //
   10418 // The array returned contains the following information:
   10419 // 0: Frame id
   10420 // 1: Receiver
   10421 // 2: Function
   10422 // 3: Argument count
   10423 // 4: Local count
   10424 // 5: Source position
   10425 // 6: Constructor call
   10426 // 7: Is at return
   10427 // 8: Flags
   10428 // Arguments name, value
   10429 // Locals name, value
   10430 // Return value if any
   10431 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   10432   HandleScope scope(isolate);
   10433   ASSERT(args.length() == 2);
   10434 
   10435   // Check arguments.
   10436   Object* check;
   10437   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   10438       RUNTIME_ARGUMENTS(isolate, args));
   10439     if (!maybe_check->ToObject(&check)) return maybe_check;
   10440   }
   10441   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   10442   Heap* heap = isolate->heap();
   10443 
   10444   // Find the relevant frame with the requested index.
   10445   StackFrame::Id id = isolate->debug()->break_frame_id();
   10446   if (id == StackFrame::NO_ID) {
   10447     // If there are no JavaScript stack frames return undefined.
   10448     return heap->undefined_value();
   10449   }
   10450 
   10451   int count = 0;
   10452   JavaScriptFrameIterator it(isolate, id);
   10453   for (; !it.done(); it.Advance()) {
   10454     if (index < count + it.frame()->GetInlineCount()) break;
   10455     count += it.frame()->GetInlineCount();
   10456   }
   10457   if (it.done()) return heap->undefined_value();
   10458 
   10459   bool is_optimized = it.frame()->is_optimized();
   10460 
   10461   int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
   10462   if (is_optimized) {
   10463     inlined_jsframe_index =
   10464         it.frame()->GetInlineCount() - (index - count) - 1;
   10465   }
   10466   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
   10467 
   10468   // Traverse the saved contexts chain to find the active context for the
   10469   // selected frame.
   10470   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
   10471 
   10472   // Get the frame id.
   10473   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
   10474 
   10475   // Find source position in unoptimized code.
   10476   int position = frame_inspector.GetSourcePosition();
   10477 
   10478   // Check for constructor frame.
   10479   bool constructor = frame_inspector.IsConstructor();
   10480 
   10481   // Get scope info and read from it for local variable information.
   10482   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   10483   Handle<SharedFunctionInfo> shared(function->shared());
   10484   Handle<ScopeInfo> scope_info(shared->scope_info());
   10485   ASSERT(*scope_info != ScopeInfo::Empty());
   10486 
   10487   // Get the locals names and values into a temporary array.
   10488   //
   10489   // TODO(1240907): Hide compiler-introduced stack variables
   10490   // (e.g. .result)?  For users of the debugger, they will probably be
   10491   // confusing.
   10492   Handle<FixedArray> locals =
   10493       isolate->factory()->NewFixedArray(scope_info->LocalCount() * 2);
   10494 
   10495   // Fill in the values of the locals.
   10496   int i = 0;
   10497   for (; i < scope_info->StackLocalCount(); ++i) {
   10498     // Use the value from the stack.
   10499     locals->set(i * 2, scope_info->LocalName(i));
   10500     locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
   10501   }
   10502   if (i < scope_info->LocalCount()) {
   10503     // Get the context containing declarations.
   10504     Handle<Context> context(
   10505         Context::cast(it.frame()->context())->declaration_context());
   10506     for (; i < scope_info->LocalCount(); ++i) {
   10507       Handle<String> name(scope_info->LocalName(i));
   10508       VariableMode mode;
   10509       InitializationFlag init_flag;
   10510       locals->set(i * 2, *name);
   10511       locals->set(i * 2 + 1, context->get(
   10512           scope_info->ContextSlotIndex(*name, &mode, &init_flag)));
   10513     }
   10514   }
   10515 
   10516   // Check whether this frame is positioned at return. If not top
   10517   // frame or if the frame is optimized it cannot be at a return.
   10518   bool at_return = false;
   10519   if (!is_optimized && index == 0) {
   10520     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
   10521   }
   10522 
   10523   // If positioned just before return find the value to be returned and add it
   10524   // to the frame information.
   10525   Handle<Object> return_value = isolate->factory()->undefined_value();
   10526   if (at_return) {
   10527     StackFrameIterator it2(isolate);
   10528     Address internal_frame_sp = NULL;
   10529     while (!it2.done()) {
   10530       if (it2.frame()->is_internal()) {
   10531         internal_frame_sp = it2.frame()->sp();
   10532       } else {
   10533         if (it2.frame()->is_java_script()) {
   10534           if (it2.frame()->id() == it.frame()->id()) {
   10535             // The internal frame just before the JavaScript frame contains the
   10536             // value to return on top. A debug break at return will create an
   10537             // internal frame to store the return value (eax/rax/r0) before
   10538             // entering the debug break exit frame.
   10539             if (internal_frame_sp != NULL) {
   10540               return_value =
   10541                   Handle<Object>(Memory::Object_at(internal_frame_sp),
   10542                                  isolate);
   10543               break;
   10544             }
   10545           }
   10546         }
   10547 
   10548         // Indicate that the previous frame was not an internal frame.
   10549         internal_frame_sp = NULL;
   10550       }
   10551       it2.Advance();
   10552     }
   10553   }
   10554 
   10555   // Now advance to the arguments adapter frame (if any). It contains all
   10556   // the provided parameters whereas the function frame always have the number
   10557   // of arguments matching the functions parameters. The rest of the
   10558   // information (except for what is collected above) is the same.
   10559   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
   10560     it.AdvanceToArgumentsFrame();
   10561     frame_inspector.SetArgumentsFrame(it.frame());
   10562   }
   10563 
   10564   // Find the number of arguments to fill. At least fill the number of
   10565   // parameters for the function and fill more if more parameters are provided.
   10566   int argument_count = scope_info->ParameterCount();
   10567   if (argument_count < frame_inspector.GetParametersCount()) {
   10568     argument_count = frame_inspector.GetParametersCount();
   10569   }
   10570 
   10571   // Calculate the size of the result.
   10572   int details_size = kFrameDetailsFirstDynamicIndex +
   10573                      2 * (argument_count + scope_info->LocalCount()) +
   10574                      (at_return ? 1 : 0);
   10575   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   10576 
   10577   // Add the frame id.
   10578   details->set(kFrameDetailsFrameIdIndex, *frame_id);
   10579 
   10580   // Add the function (same as in function frame).
   10581   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
   10582 
   10583   // Add the arguments count.
   10584   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
   10585 
   10586   // Add the locals count
   10587   details->set(kFrameDetailsLocalCountIndex,
   10588                Smi::FromInt(scope_info->LocalCount()));
   10589 
   10590   // Add the source position.
   10591   if (position != RelocInfo::kNoPosition) {
   10592     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
   10593   } else {
   10594     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
   10595   }
   10596 
   10597   // Add the constructor information.
   10598   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
   10599 
   10600   // Add the at return information.
   10601   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
   10602 
   10603   // Add flags to indicate information on whether this frame is
   10604   //   bit 0: invoked in the debugger context.
   10605   //   bit 1: optimized frame.
   10606   //   bit 2: inlined in optimized frame
   10607   int flags = 0;
   10608   if (*save->context() == *isolate->debug()->debug_context()) {
   10609     flags |= 1 << 0;
   10610   }
   10611   if (is_optimized) {
   10612     flags |= 1 << 1;
   10613     flags |= inlined_jsframe_index << 2;
   10614   }
   10615   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
   10616 
   10617   // Fill the dynamic part.
   10618   int details_index = kFrameDetailsFirstDynamicIndex;
   10619 
   10620   // Add arguments name and value.
   10621   for (int i = 0; i < argument_count; i++) {
   10622     // Name of the argument.
   10623     if (i < scope_info->ParameterCount()) {
   10624       details->set(details_index++, scope_info->ParameterName(i));
   10625     } else {
   10626       details->set(details_index++, heap->undefined_value());
   10627     }
   10628 
   10629     // Parameter value.
   10630     if (i < frame_inspector.GetParametersCount()) {
   10631       // Get the value from the stack.
   10632       details->set(details_index++, frame_inspector.GetParameter(i));
   10633     } else {
   10634       details->set(details_index++, heap->undefined_value());
   10635     }
   10636   }
   10637 
   10638   // Add locals name and value from the temporary copy from the function frame.
   10639   for (int i = 0; i < scope_info->LocalCount() * 2; i++) {
   10640     details->set(details_index++, locals->get(i));
   10641   }
   10642 
   10643   // Add the value being returned.
   10644   if (at_return) {
   10645     details->set(details_index++, *return_value);
   10646   }
   10647 
   10648   // Add the receiver (same as in function frame).
   10649   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
   10650   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
   10651   Handle<Object> receiver(it.frame()->receiver(), isolate);
   10652   if (!receiver->IsJSObject() &&
   10653       shared->is_classic_mode() &&
   10654       !shared->native()) {
   10655     // If the receiver is not a JSObject and the function is not a
   10656     // builtin or strict-mode we have hit an optimization where a
   10657     // value object is not converted into a wrapped JS objects. To
   10658     // hide this optimization from the debugger, we wrap the receiver
   10659     // by creating correct wrapper object based on the calling frame's
   10660     // global context.
   10661     it.Advance();
   10662     Handle<Context> calling_frames_global_context(
   10663         Context::cast(Context::cast(it.frame()->context())->global_context()));
   10664     receiver =
   10665         isolate->factory()->ToObject(receiver, calling_frames_global_context);
   10666   }
   10667   details->set(kFrameDetailsReceiverIndex, *receiver);
   10668 
   10669   ASSERT_EQ(details_size, details_index);
   10670   return *isolate->factory()->NewJSArrayWithElements(details);
   10671 }
   10672 
   10673 
   10674 // Copy all the context locals into an object used to materialize a scope.
   10675 static bool CopyContextLocalsToScopeObject(
   10676     Isolate* isolate,
   10677     Handle<ScopeInfo> scope_info,
   10678     Handle<Context> context,
   10679     Handle<JSObject> scope_object) {
   10680   // Fill all context locals to the context extension.
   10681   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
   10682     VariableMode mode;
   10683     InitializationFlag init_flag;
   10684     int context_index = scope_info->ContextSlotIndex(
   10685         scope_info->ContextLocalName(i), &mode, &init_flag);
   10686 
   10687     RETURN_IF_EMPTY_HANDLE_VALUE(
   10688         isolate,
   10689         SetProperty(scope_object,
   10690                     Handle<String>(scope_info->ContextLocalName(i)),
   10691                     Handle<Object>(context->get(context_index), isolate),
   10692                     NONE,
   10693                     kNonStrictMode),
   10694         false);
   10695   }
   10696 
   10697   return true;
   10698 }
   10699 
   10700 
   10701 // Create a plain JSObject which materializes the local scope for the specified
   10702 // frame.
   10703 static Handle<JSObject> MaterializeLocalScopeWithFrameInspector(
   10704     Isolate* isolate,
   10705     JavaScriptFrame* frame,
   10706     FrameInspector* frame_inspector) {
   10707   Handle<JSFunction> function(JSFunction::cast(frame_inspector->GetFunction()));
   10708   Handle<SharedFunctionInfo> shared(function->shared());
   10709   Handle<ScopeInfo> scope_info(shared->scope_info());
   10710 
   10711   // Allocate and initialize a JSObject with all the arguments, stack locals
   10712   // heap locals and extension properties of the debugged function.
   10713   Handle<JSObject> local_scope =
   10714       isolate->factory()->NewJSObject(isolate->object_function());
   10715 
   10716   // First fill all parameters.
   10717   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
   10718     Handle<Object> value(
   10719         i < frame_inspector->GetParametersCount() ?
   10720         frame_inspector->GetParameter(i) : isolate->heap()->undefined_value());
   10721 
   10722     RETURN_IF_EMPTY_HANDLE_VALUE(
   10723         isolate,
   10724         SetProperty(local_scope,
   10725                     Handle<String>(scope_info->ParameterName(i)),
   10726                     value,
   10727                     NONE,
   10728                     kNonStrictMode),
   10729         Handle<JSObject>());
   10730   }
   10731 
   10732   // Second fill all stack locals.
   10733   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
   10734     RETURN_IF_EMPTY_HANDLE_VALUE(
   10735         isolate,
   10736         SetProperty(local_scope,
   10737                     Handle<String>(scope_info->StackLocalName(i)),
   10738                     Handle<Object>(frame_inspector->GetExpression(i)),
   10739                     NONE,
   10740                     kNonStrictMode),
   10741         Handle<JSObject>());
   10742   }
   10743 
   10744   if (scope_info->HasContext()) {
   10745     // Third fill all context locals.
   10746     Handle<Context> frame_context(Context::cast(frame->context()));
   10747     Handle<Context> function_context(frame_context->declaration_context());
   10748     if (!CopyContextLocalsToScopeObject(
   10749             isolate, scope_info, function_context, local_scope)) {
   10750       return Handle<JSObject>();
   10751     }
   10752 
   10753     // Finally copy any properties from the function context extension.
   10754     // These will be variables introduced by eval.
   10755     if (function_context->closure() == *function) {
   10756       if (function_context->has_extension() &&
   10757           !function_context->IsGlobalContext()) {
   10758         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
   10759         bool threw = false;
   10760         Handle<FixedArray> keys =
   10761             GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
   10762         if (threw) return Handle<JSObject>();
   10763 
   10764         for (int i = 0; i < keys->length(); i++) {
   10765           // Names of variables introduced by eval are strings.
   10766           ASSERT(keys->get(i)->IsString());
   10767           Handle<String> key(String::cast(keys->get(i)));
   10768           RETURN_IF_EMPTY_HANDLE_VALUE(
   10769               isolate,
   10770               SetProperty(local_scope,
   10771                           key,
   10772                           GetProperty(ext, key),
   10773                           NONE,
   10774                           kNonStrictMode),
   10775               Handle<JSObject>());
   10776         }
   10777       }
   10778     }
   10779   }
   10780 
   10781   return local_scope;
   10782 }
   10783 
   10784 
   10785 static Handle<JSObject> MaterializeLocalScope(
   10786     Isolate* isolate,
   10787     JavaScriptFrame* frame,
   10788     int inlined_jsframe_index) {
   10789   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   10790   return MaterializeLocalScopeWithFrameInspector(isolate,
   10791                                                  frame,
   10792                                                  &frame_inspector);
   10793 }
   10794 
   10795 
   10796 // Create a plain JSObject which materializes the closure content for the
   10797 // context.
   10798 static Handle<JSObject> MaterializeClosure(Isolate* isolate,
   10799                                            Handle<Context> context) {
   10800   ASSERT(context->IsFunctionContext());
   10801 
   10802   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   10803   Handle<ScopeInfo> scope_info(shared->scope_info());
   10804 
   10805   // Allocate and initialize a JSObject with all the content of this function
   10806   // closure.
   10807   Handle<JSObject> closure_scope =
   10808       isolate->factory()->NewJSObject(isolate->object_function());
   10809 
   10810   // Fill all context locals to the context extension.
   10811   if (!CopyContextLocalsToScopeObject(
   10812           isolate, scope_info, context, closure_scope)) {
   10813     return Handle<JSObject>();
   10814   }
   10815 
   10816   // Finally copy any properties from the function context extension. This will
   10817   // be variables introduced by eval.
   10818   if (context->has_extension()) {
   10819     Handle<JSObject> ext(JSObject::cast(context->extension()));
   10820     bool threw = false;
   10821     Handle<FixedArray> keys =
   10822         GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
   10823     if (threw) return Handle<JSObject>();
   10824 
   10825     for (int i = 0; i < keys->length(); i++) {
   10826       // Names of variables introduced by eval are strings.
   10827       ASSERT(keys->get(i)->IsString());
   10828       Handle<String> key(String::cast(keys->get(i)));
   10829        RETURN_IF_EMPTY_HANDLE_VALUE(
   10830           isolate,
   10831           SetProperty(closure_scope,
   10832                       key,
   10833                       GetProperty(ext, key),
   10834                       NONE,
   10835                       kNonStrictMode),
   10836           Handle<JSObject>());
   10837     }
   10838   }
   10839 
   10840   return closure_scope;
   10841 }
   10842 
   10843 
   10844 // Create a plain JSObject which materializes the scope for the specified
   10845 // catch context.
   10846 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
   10847                                               Handle<Context> context) {
   10848   ASSERT(context->IsCatchContext());
   10849   Handle<String> name(String::cast(context->extension()));
   10850   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX));
   10851   Handle<JSObject> catch_scope =
   10852       isolate->factory()->NewJSObject(isolate->object_function());
   10853   RETURN_IF_EMPTY_HANDLE_VALUE(
   10854       isolate,
   10855       SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
   10856       Handle<JSObject>());
   10857   return catch_scope;
   10858 }
   10859 
   10860 
   10861 // Create a plain JSObject which materializes the block scope for the specified
   10862 // block context.
   10863 static Handle<JSObject> MaterializeBlockScope(
   10864     Isolate* isolate,
   10865     Handle<Context> context) {
   10866   ASSERT(context->IsBlockContext());
   10867   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   10868 
   10869   // Allocate and initialize a JSObject with all the arguments, stack locals
   10870   // heap locals and extension properties of the debugged function.
   10871   Handle<JSObject> block_scope =
   10872       isolate->factory()->NewJSObject(isolate->object_function());
   10873 
   10874   // Fill all context locals.
   10875   if (!CopyContextLocalsToScopeObject(
   10876           isolate, scope_info, context, block_scope)) {
   10877     return Handle<JSObject>();
   10878   }
   10879 
   10880   return block_scope;
   10881 }
   10882 
   10883 
   10884 // Create a plain JSObject which materializes the module scope for the specified
   10885 // module context.
   10886 static Handle<JSObject> MaterializeModuleScope(
   10887     Isolate* isolate,
   10888     Handle<Context> context) {
   10889   ASSERT(context->IsModuleContext());
   10890   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
   10891 
   10892   // Allocate and initialize a JSObject with all the members of the debugged
   10893   // module.
   10894   Handle<JSObject> module_scope =
   10895       isolate->factory()->NewJSObject(isolate->object_function());
   10896 
   10897   // Fill all context locals.
   10898   if (!CopyContextLocalsToScopeObject(
   10899           isolate, scope_info, context, module_scope)) {
   10900     return Handle<JSObject>();
   10901   }
   10902 
   10903   return module_scope;
   10904 }
   10905 
   10906 
   10907 // Iterate over the actual scopes visible from a stack frame. The iteration
   10908 // proceeds from the innermost visible nested scope outwards. All scopes are
   10909 // backed by an actual context except the local scope, which is inserted
   10910 // "artificially" in the context chain.
   10911 class ScopeIterator {
   10912  public:
   10913   enum ScopeType {
   10914     ScopeTypeGlobal = 0,
   10915     ScopeTypeLocal,
   10916     ScopeTypeWith,
   10917     ScopeTypeClosure,
   10918     ScopeTypeCatch,
   10919     ScopeTypeBlock,
   10920     ScopeTypeModule
   10921   };
   10922 
   10923   ScopeIterator(Isolate* isolate,
   10924                 JavaScriptFrame* frame,
   10925                 int inlined_jsframe_index)
   10926     : isolate_(isolate),
   10927       frame_(frame),
   10928       inlined_jsframe_index_(inlined_jsframe_index),
   10929       function_(JSFunction::cast(frame->function())),
   10930       context_(Context::cast(frame->context())),
   10931       nested_scope_chain_(4) {
   10932 
   10933     // Catch the case when the debugger stops in an internal function.
   10934     Handle<SharedFunctionInfo> shared_info(function_->shared());
   10935     Handle<ScopeInfo> scope_info(shared_info->scope_info());
   10936     if (shared_info->script() == isolate->heap()->undefined_value()) {
   10937       while (context_->closure() == *function_) {
   10938         context_ = Handle<Context>(context_->previous(), isolate_);
   10939       }
   10940       return;
   10941     }
   10942 
   10943     // Get the debug info (create it if it does not exist).
   10944     if (!isolate->debug()->EnsureDebugInfo(shared_info)) {
   10945       // Return if ensuring debug info failed.
   10946       return;
   10947     }
   10948     Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
   10949 
   10950     // Find the break point where execution has stopped.
   10951     BreakLocationIterator break_location_iterator(debug_info,
   10952                                                   ALL_BREAK_LOCATIONS);
   10953     break_location_iterator.FindBreakLocationFromAddress(frame->pc());
   10954     if (break_location_iterator.IsExit()) {
   10955       // We are within the return sequence. At the momemt it is not possible to
   10956       // get a source position which is consistent with the current scope chain.
   10957       // Thus all nested with, catch and block contexts are skipped and we only
   10958       // provide the function scope.
   10959       if (scope_info->HasContext()) {
   10960         context_ = Handle<Context>(context_->declaration_context(), isolate_);
   10961       } else {
   10962         while (context_->closure() == *function_) {
   10963           context_ = Handle<Context>(context_->previous(), isolate_);
   10964         }
   10965       }
   10966       if (scope_info->Type() != EVAL_SCOPE) nested_scope_chain_.Add(scope_info);
   10967     } else {
   10968       // Reparse the code and analyze the scopes.
   10969       ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
   10970       Handle<Script> script(Script::cast(shared_info->script()));
   10971       Scope* scope = NULL;
   10972 
   10973       // Check whether we are in global, eval or function code.
   10974       Handle<ScopeInfo> scope_info(shared_info->scope_info());
   10975       if (scope_info->Type() != FUNCTION_SCOPE) {
   10976         // Global or eval code.
   10977         CompilationInfo info(script);
   10978         if (scope_info->Type() == GLOBAL_SCOPE) {
   10979           info.MarkAsGlobal();
   10980         } else {
   10981           ASSERT(scope_info->Type() == EVAL_SCOPE);
   10982           info.MarkAsEval();
   10983           info.SetCallingContext(Handle<Context>(function_->context()));
   10984         }
   10985         if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) {
   10986           scope = info.function()->scope();
   10987         }
   10988       } else {
   10989         // Function code
   10990         CompilationInfo info(shared_info);
   10991         if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) {
   10992           scope = info.function()->scope();
   10993         }
   10994       }
   10995 
   10996       // Retrieve the scope chain for the current position.
   10997       if (scope != NULL) {
   10998         int source_position = shared_info->code()->SourcePosition(frame_->pc());
   10999         scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
   11000       } else {
   11001         // A failed reparse indicates that the preparser has diverged from the
   11002         // parser or that the preparse data given to the initial parse has been
   11003         // faulty. We fail in debug mode but in release mode we only provide the
   11004         // information we get from the context chain but nothing about
   11005         // completely stack allocated scopes or stack allocated locals.
   11006         UNREACHABLE();
   11007       }
   11008     }
   11009   }
   11010 
   11011   // More scopes?
   11012   bool Done() { return context_.is_null(); }
   11013 
   11014   // Move to the next scope.
   11015   void Next() {
   11016     ScopeType scope_type = Type();
   11017     if (scope_type == ScopeTypeGlobal) {
   11018       // The global scope is always the last in the chain.
   11019       ASSERT(context_->IsGlobalContext());
   11020       context_ = Handle<Context>();
   11021       return;
   11022     }
   11023     if (nested_scope_chain_.is_empty()) {
   11024       context_ = Handle<Context>(context_->previous(), isolate_);
   11025     } else {
   11026       if (nested_scope_chain_.last()->HasContext()) {
   11027         ASSERT(context_->previous() != NULL);
   11028         context_ = Handle<Context>(context_->previous(), isolate_);
   11029       }
   11030       nested_scope_chain_.RemoveLast();
   11031     }
   11032   }
   11033 
   11034   // Return the type of the current scope.
   11035   ScopeType Type() {
   11036     if (!nested_scope_chain_.is_empty()) {
   11037       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
   11038       switch (scope_info->Type()) {
   11039         case FUNCTION_SCOPE:
   11040           ASSERT(context_->IsFunctionContext() ||
   11041                  !scope_info->HasContext());
   11042           return ScopeTypeLocal;
   11043         case MODULE_SCOPE:
   11044           ASSERT(context_->IsModuleContext());
   11045           return ScopeTypeModule;
   11046         case GLOBAL_SCOPE:
   11047           ASSERT(context_->IsGlobalContext());
   11048           return ScopeTypeGlobal;
   11049         case WITH_SCOPE:
   11050           ASSERT(context_->IsWithContext());
   11051           return ScopeTypeWith;
   11052         case CATCH_SCOPE:
   11053           ASSERT(context_->IsCatchContext());
   11054           return ScopeTypeCatch;
   11055         case BLOCK_SCOPE:
   11056           ASSERT(!scope_info->HasContext() ||
   11057                  context_->IsBlockContext());
   11058           return ScopeTypeBlock;
   11059         case EVAL_SCOPE:
   11060           UNREACHABLE();
   11061       }
   11062     }
   11063     if (context_->IsGlobalContext()) {
   11064       ASSERT(context_->global()->IsGlobalObject());
   11065       return ScopeTypeGlobal;
   11066     }
   11067     if (context_->IsFunctionContext()) {
   11068       return ScopeTypeClosure;
   11069     }
   11070     if (context_->IsCatchContext()) {
   11071       return ScopeTypeCatch;
   11072     }
   11073     if (context_->IsBlockContext()) {
   11074       return ScopeTypeBlock;
   11075     }
   11076     if (context_->IsModuleContext()) {
   11077       return ScopeTypeModule;
   11078     }
   11079     ASSERT(context_->IsWithContext());
   11080     return ScopeTypeWith;
   11081   }
   11082 
   11083   // Return the JavaScript object with the content of the current scope.
   11084   Handle<JSObject> ScopeObject() {
   11085     switch (Type()) {
   11086       case ScopeIterator::ScopeTypeGlobal:
   11087         return Handle<JSObject>(CurrentContext()->global());
   11088       case ScopeIterator::ScopeTypeLocal:
   11089         // Materialize the content of the local scope into a JSObject.
   11090         ASSERT(nested_scope_chain_.length() == 1);
   11091         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
   11092       case ScopeIterator::ScopeTypeWith:
   11093         // Return the with object.
   11094         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
   11095       case ScopeIterator::ScopeTypeCatch:
   11096         return MaterializeCatchScope(isolate_, CurrentContext());
   11097       case ScopeIterator::ScopeTypeClosure:
   11098         // Materialize the content of the closure scope into a JSObject.
   11099         return MaterializeClosure(isolate_, CurrentContext());
   11100       case ScopeIterator::ScopeTypeBlock:
   11101         return MaterializeBlockScope(isolate_, CurrentContext());
   11102       case ScopeIterator::ScopeTypeModule:
   11103         return MaterializeModuleScope(isolate_, CurrentContext());
   11104     }
   11105     UNREACHABLE();
   11106     return Handle<JSObject>();
   11107   }
   11108 
   11109   Handle<ScopeInfo> CurrentScopeInfo() {
   11110     if (!nested_scope_chain_.is_empty()) {
   11111       return nested_scope_chain_.last();
   11112     } else if (context_->IsBlockContext()) {
   11113       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
   11114     } else if (context_->IsFunctionContext()) {
   11115       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
   11116     }
   11117     return Handle<ScopeInfo>::null();
   11118   }
   11119 
   11120   // Return the context for this scope. For the local context there might not
   11121   // be an actual context.
   11122   Handle<Context> CurrentContext() {
   11123     if (Type() == ScopeTypeGlobal ||
   11124         nested_scope_chain_.is_empty()) {
   11125       return context_;
   11126     } else if (nested_scope_chain_.last()->HasContext()) {
   11127       return context_;
   11128     } else {
   11129       return Handle<Context>();
   11130     }
   11131   }
   11132 
   11133 #ifdef DEBUG
   11134   // Debug print of the content of the current scope.
   11135   void DebugPrint() {
   11136     switch (Type()) {
   11137       case ScopeIterator::ScopeTypeGlobal:
   11138         PrintF("Global:\n");
   11139         CurrentContext()->Print();
   11140         break;
   11141 
   11142       case ScopeIterator::ScopeTypeLocal: {
   11143         PrintF("Local:\n");
   11144         function_->shared()->scope_info()->Print();
   11145         if (!CurrentContext().is_null()) {
   11146           CurrentContext()->Print();
   11147           if (CurrentContext()->has_extension()) {
   11148             Handle<Object> extension(CurrentContext()->extension());
   11149             if (extension->IsJSContextExtensionObject()) {
   11150               extension->Print();
   11151             }
   11152           }
   11153         }
   11154         break;
   11155       }
   11156 
   11157       case ScopeIterator::ScopeTypeWith:
   11158         PrintF("With:\n");
   11159         CurrentContext()->extension()->Print();
   11160         break;
   11161 
   11162       case ScopeIterator::ScopeTypeCatch:
   11163         PrintF("Catch:\n");
   11164         CurrentContext()->extension()->Print();
   11165         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
   11166         break;
   11167 
   11168       case ScopeIterator::ScopeTypeClosure:
   11169         PrintF("Closure:\n");
   11170         CurrentContext()->Print();
   11171         if (CurrentContext()->has_extension()) {
   11172           Handle<Object> extension(CurrentContext()->extension());
   11173           if (extension->IsJSContextExtensionObject()) {
   11174             extension->Print();
   11175           }
   11176         }
   11177         break;
   11178 
   11179       default:
   11180         UNREACHABLE();
   11181     }
   11182     PrintF("\n");
   11183   }
   11184 #endif
   11185 
   11186  private:
   11187   Isolate* isolate_;
   11188   JavaScriptFrame* frame_;
   11189   int inlined_jsframe_index_;
   11190   Handle<JSFunction> function_;
   11191   Handle<Context> context_;
   11192   List<Handle<ScopeInfo> > nested_scope_chain_;
   11193 
   11194   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
   11195 };
   11196 
   11197 
   11198 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
   11199   HandleScope scope(isolate);
   11200   ASSERT(args.length() == 2);
   11201 
   11202   // Check arguments.
   11203   Object* check;
   11204   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   11205       RUNTIME_ARGUMENTS(isolate, args));
   11206     if (!maybe_check->ToObject(&check)) return maybe_check;
   11207   }
   11208   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   11209 
   11210   // Get the frame where the debugging is performed.
   11211   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   11212   JavaScriptFrameIterator it(isolate, id);
   11213   JavaScriptFrame* frame = it.frame();
   11214 
   11215   // Count the visible scopes.
   11216   int n = 0;
   11217   for (ScopeIterator it(isolate, frame, 0);
   11218        !it.Done();
   11219        it.Next()) {
   11220     n++;
   11221   }
   11222 
   11223   return Smi::FromInt(n);
   11224 }
   11225 
   11226 
   11227 static const int kScopeDetailsTypeIndex = 0;
   11228 static const int kScopeDetailsObjectIndex = 1;
   11229 static const int kScopeDetailsSize = 2;
   11230 
   11231 // Return an array with scope details
   11232 // args[0]: number: break id
   11233 // args[1]: number: frame index
   11234 // args[2]: number: inlined frame index
   11235 // args[3]: number: scope index
   11236 //
   11237 // The array returned contains the following information:
   11238 // 0: Scope type
   11239 // 1: Scope object
   11240 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
   11241   HandleScope scope(isolate);
   11242   ASSERT(args.length() == 4);
   11243 
   11244   // Check arguments.
   11245   Object* check;
   11246   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   11247       RUNTIME_ARGUMENTS(isolate, args));
   11248     if (!maybe_check->ToObject(&check)) return maybe_check;
   11249   }
   11250   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   11251   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   11252   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
   11253 
   11254   // Get the frame where the debugging is performed.
   11255   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   11256   JavaScriptFrameIterator frame_it(isolate, id);
   11257   JavaScriptFrame* frame = frame_it.frame();
   11258 
   11259   // Find the requested scope.
   11260   int n = 0;
   11261   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   11262   for (; !it.Done() && n < index; it.Next()) {
   11263     n++;
   11264   }
   11265   if (it.Done()) {
   11266     return isolate->heap()->undefined_value();
   11267   }
   11268 
   11269   // Calculate the size of the result.
   11270   int details_size = kScopeDetailsSize;
   11271   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
   11272 
   11273   // Fill in scope details.
   11274   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type()));
   11275   Handle<JSObject> scope_object = it.ScopeObject();
   11276   RETURN_IF_EMPTY_HANDLE(isolate, scope_object);
   11277   details->set(kScopeDetailsObjectIndex, *scope_object);
   11278 
   11279   return *isolate->factory()->NewJSArrayWithElements(details);
   11280 }
   11281 
   11282 
   11283 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
   11284   HandleScope scope(isolate);
   11285   ASSERT(args.length() == 0);
   11286 
   11287 #ifdef DEBUG
   11288   // Print the scopes for the top frame.
   11289   StackFrameLocator locator;
   11290   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
   11291   for (ScopeIterator it(isolate, frame, 0);
   11292        !it.Done();
   11293        it.Next()) {
   11294     it.DebugPrint();
   11295   }
   11296 #endif
   11297   return isolate->heap()->undefined_value();
   11298 }
   11299 
   11300 
   11301 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
   11302   HandleScope scope(isolate);
   11303   ASSERT(args.length() == 1);
   11304 
   11305   // Check arguments.
   11306   Object* result;
   11307   { MaybeObject* maybe_result = Runtime_CheckExecutionState(
   11308       RUNTIME_ARGUMENTS(isolate, args));
   11309     if (!maybe_result->ToObject(&result)) return maybe_result;
   11310   }
   11311 
   11312   // Count all archived V8 threads.
   11313   int n = 0;
   11314   for (ThreadState* thread =
   11315           isolate->thread_manager()->FirstThreadStateInUse();
   11316        thread != NULL;
   11317        thread = thread->Next()) {
   11318     n++;
   11319   }
   11320 
   11321   // Total number of threads is current thread and archived threads.
   11322   return Smi::FromInt(n + 1);
   11323 }
   11324 
   11325 
   11326 static const int kThreadDetailsCurrentThreadIndex = 0;
   11327 static const int kThreadDetailsThreadIdIndex = 1;
   11328 static const int kThreadDetailsSize = 2;
   11329 
   11330 // Return an array with thread details
   11331 // args[0]: number: break id
   11332 // args[1]: number: thread index
   11333 //
   11334 // The array returned contains the following information:
   11335 // 0: Is current thread?
   11336 // 1: Thread id
   11337 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
   11338   HandleScope scope(isolate);
   11339   ASSERT(args.length() == 2);
   11340 
   11341   // Check arguments.
   11342   Object* check;
   11343   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   11344       RUNTIME_ARGUMENTS(isolate, args));
   11345     if (!maybe_check->ToObject(&check)) return maybe_check;
   11346   }
   11347   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   11348 
   11349   // Allocate array for result.
   11350   Handle<FixedArray> details =
   11351       isolate->factory()->NewFixedArray(kThreadDetailsSize);
   11352 
   11353   // Thread index 0 is current thread.
   11354   if (index == 0) {
   11355     // Fill the details.
   11356     details->set(kThreadDetailsCurrentThreadIndex,
   11357                  isolate->heap()->true_value());
   11358     details->set(kThreadDetailsThreadIdIndex,
   11359                  Smi::FromInt(ThreadId::Current().ToInteger()));
   11360   } else {
   11361     // Find the thread with the requested index.
   11362     int n = 1;
   11363     ThreadState* thread =
   11364         isolate->thread_manager()->FirstThreadStateInUse();
   11365     while (index != n && thread != NULL) {
   11366       thread = thread->Next();
   11367       n++;
   11368     }
   11369     if (thread == NULL) {
   11370       return isolate->heap()->undefined_value();
   11371     }
   11372 
   11373     // Fill the details.
   11374     details->set(kThreadDetailsCurrentThreadIndex,
   11375                  isolate->heap()->false_value());
   11376     details->set(kThreadDetailsThreadIdIndex,
   11377                  Smi::FromInt(thread->id().ToInteger()));
   11378   }
   11379 
   11380   // Convert to JS array and return.
   11381   return *isolate->factory()->NewJSArrayWithElements(details);
   11382 }
   11383 
   11384 
   11385 // Sets the disable break state
   11386 // args[0]: disable break state
   11387 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDisableBreak) {
   11388   HandleScope scope(isolate);
   11389   ASSERT(args.length() == 1);
   11390   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
   11391   isolate->debug()->set_disable_break(disable_break);
   11392   return  isolate->heap()->undefined_value();
   11393 }
   11394 
   11395 
   11396 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
   11397   HandleScope scope(isolate);
   11398   ASSERT(args.length() == 1);
   11399 
   11400   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   11401   Handle<SharedFunctionInfo> shared(fun->shared());
   11402   // Find the number of break points
   11403   Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared);
   11404   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   11405   // Return array as JS array
   11406   return *isolate->factory()->NewJSArrayWithElements(
   11407       Handle<FixedArray>::cast(break_locations));
   11408 }
   11409 
   11410 
   11411 // Set a break point in a function
   11412 // args[0]: function
   11413 // args[1]: number: break source position (within the function source)
   11414 // args[2]: number: break point object
   11415 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
   11416   HandleScope scope(isolate);
   11417   ASSERT(args.length() == 3);
   11418   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   11419   Handle<SharedFunctionInfo> shared(fun->shared());
   11420   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   11421   RUNTIME_ASSERT(source_position >= 0);
   11422   Handle<Object> break_point_object_arg = args.at<Object>(2);
   11423 
   11424   // Set break point.
   11425   isolate->debug()->SetBreakPoint(shared, break_point_object_arg,
   11426                                   &source_position);
   11427 
   11428   return Smi::FromInt(source_position);
   11429 }
   11430 
   11431 
   11432 Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
   11433                                                 Handle<Script> script,
   11434                                                 int position) {
   11435   // Iterate the heap looking for SharedFunctionInfo generated from the
   11436   // script. The inner most SharedFunctionInfo containing the source position
   11437   // for the requested break point is found.
   11438   // NOTE: This might require several heap iterations. If the SharedFunctionInfo
   11439   // which is found is not compiled it is compiled and the heap is iterated
   11440   // again as the compilation might create inner functions from the newly
   11441   // compiled function and the actual requested break point might be in one of
   11442   // these functions.
   11443   bool done = false;
   11444   // The current candidate for the source position:
   11445   int target_start_position = RelocInfo::kNoPosition;
   11446   Handle<SharedFunctionInfo> target;
   11447   while (!done) {
   11448     { // Extra scope for iterator and no-allocation.
   11449       isolate->heap()->EnsureHeapIsIterable();
   11450       AssertNoAllocation no_alloc_during_heap_iteration;
   11451       HeapIterator iterator;
   11452       for (HeapObject* obj = iterator.next();
   11453            obj != NULL; obj = iterator.next()) {
   11454         if (obj->IsSharedFunctionInfo()) {
   11455           Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
   11456           if (shared->script() == *script) {
   11457             // If the SharedFunctionInfo found has the requested script data and
   11458             // contains the source position it is a candidate.
   11459             int start_position = shared->function_token_position();
   11460             if (start_position == RelocInfo::kNoPosition) {
   11461               start_position = shared->start_position();
   11462             }
   11463             if (start_position <= position &&
   11464                 position <= shared->end_position()) {
   11465               // If there is no candidate or this function is within the current
   11466               // candidate this is the new candidate.
   11467               if (target.is_null()) {
   11468                 target_start_position = start_position;
   11469                 target = shared;
   11470               } else {
   11471                 if (target_start_position == start_position &&
   11472                     shared->end_position() == target->end_position()) {
   11473                     // If a top-level function contain only one function
   11474                     // declartion the source for the top-level and the
   11475                     // function is the same. In that case prefer the non
   11476                     // top-level function.
   11477                   if (!shared->is_toplevel()) {
   11478                     target_start_position = start_position;
   11479                     target = shared;
   11480                   }
   11481                 } else if (target_start_position <= start_position &&
   11482                            shared->end_position() <= target->end_position()) {
   11483                   // This containment check includes equality as a function
   11484                   // inside a top-level function can share either start or end
   11485                   // position with the top-level function.
   11486                   target_start_position = start_position;
   11487                   target = shared;
   11488                 }
   11489               }
   11490             }
   11491           }
   11492         }
   11493       }  // End for loop.
   11494     }  // End No allocation scope.
   11495 
   11496     if (target.is_null()) {
   11497       return isolate->heap()->undefined_value();
   11498     }
   11499 
   11500     // If the candidate found is compiled we are done. NOTE: when lazy
   11501     // compilation of inner functions is introduced some additional checking
   11502     // needs to be done here to compile inner functions.
   11503     done = target->is_compiled();
   11504     if (!done) {
   11505       // If the candidate is not compiled compile it to reveal any inner
   11506       // functions which might contain the requested source position.
   11507       SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION);
   11508     }
   11509   }  // End while loop.
   11510 
   11511   return *target;
   11512 }
   11513 
   11514 
   11515 // Changes the state of a break point in a script and returns source position
   11516 // where break point was set. NOTE: Regarding performance see the NOTE for
   11517 // GetScriptFromScriptData.
   11518 // args[0]: script to set break point in
   11519 // args[1]: number: break source position (within the script source)
   11520 // args[2]: number: break point object
   11521 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
   11522   HandleScope scope(isolate);
   11523   ASSERT(args.length() == 3);
   11524   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   11525   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   11526   RUNTIME_ASSERT(source_position >= 0);
   11527   Handle<Object> break_point_object_arg = args.at<Object>(2);
   11528 
   11529   // Get the script from the script wrapper.
   11530   RUNTIME_ASSERT(wrapper->value()->IsScript());
   11531   Handle<Script> script(Script::cast(wrapper->value()));
   11532 
   11533   Object* result = Runtime::FindSharedFunctionInfoInScript(
   11534       isolate, script, source_position);
   11535   if (!result->IsUndefined()) {
   11536     Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
   11537     // Find position within function. The script position might be before the
   11538     // source position of the first function.
   11539     int position;
   11540     if (shared->start_position() > source_position) {
   11541       position = 0;
   11542     } else {
   11543       position = source_position - shared->start_position();
   11544     }
   11545     isolate->debug()->SetBreakPoint(shared, break_point_object_arg, &position);
   11546     position += shared->start_position();
   11547     return Smi::FromInt(position);
   11548   }
   11549   return  isolate->heap()->undefined_value();
   11550 }
   11551 
   11552 
   11553 // Clear a break point
   11554 // args[0]: number: break point object
   11555 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
   11556   HandleScope scope(isolate);
   11557   ASSERT(args.length() == 1);
   11558   Handle<Object> break_point_object_arg = args.at<Object>(0);
   11559 
   11560   // Clear break point.
   11561   isolate->debug()->ClearBreakPoint(break_point_object_arg);
   11562 
   11563   return isolate->heap()->undefined_value();
   11564 }
   11565 
   11566 
   11567 // Change the state of break on exceptions.
   11568 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
   11569 // args[1]: Boolean indicating on/off.
   11570 RUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
   11571   HandleScope scope(isolate);
   11572   ASSERT(args.length() == 2);
   11573   RUNTIME_ASSERT(args[0]->IsNumber());
   11574   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
   11575 
   11576   // If the number doesn't match an enum value, the ChangeBreakOnException
   11577   // function will default to affecting caught exceptions.
   11578   ExceptionBreakType type =
   11579       static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
   11580   // Update break point state.
   11581   isolate->debug()->ChangeBreakOnException(type, enable);
   11582   return isolate->heap()->undefined_value();
   11583 }
   11584 
   11585 
   11586 // Returns the state of break on exceptions
   11587 // args[0]: boolean indicating uncaught exceptions
   11588 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
   11589   HandleScope scope(isolate);
   11590   ASSERT(args.length() == 1);
   11591   RUNTIME_ASSERT(args[0]->IsNumber());
   11592 
   11593   ExceptionBreakType type =
   11594       static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
   11595   bool result = isolate->debug()->IsBreakOnException(type);
   11596   return Smi::FromInt(result);
   11597 }
   11598 
   11599 
   11600 // Prepare for stepping
   11601 // args[0]: break id for checking execution state
   11602 // args[1]: step action from the enumeration StepAction
   11603 // args[2]: number of times to perform the step, for step out it is the number
   11604 //          of frames to step down.
   11605 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
   11606   HandleScope scope(isolate);
   11607   ASSERT(args.length() == 3);
   11608   // Check arguments.
   11609   Object* check;
   11610   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
   11611       RUNTIME_ARGUMENTS(isolate, args));
   11612     if (!maybe_check->ToObject(&check)) return maybe_check;
   11613   }
   11614   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
   11615     return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   11616   }
   11617 
   11618   // Get the step action and check validity.
   11619   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   11620   if (step_action != StepIn &&
   11621       step_action != StepNext &&
   11622       step_action != StepOut &&
   11623       step_action != StepInMin &&
   11624       step_action != StepMin) {
   11625     return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   11626   }
   11627 
   11628   // Get the number of steps.
   11629   int step_count = NumberToInt32(args[2]);
   11630   if (step_count < 1) {
   11631     return isolate->Throw(isolate->heap()->illegal_argument_symbol());
   11632   }
   11633 
   11634   // Clear all current stepping setup.
   11635   isolate->debug()->ClearStepping();
   11636 
   11637   // Prepare step.
   11638   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
   11639                                 step_count);
   11640   return isolate->heap()->undefined_value();
   11641 }
   11642 
   11643 
   11644 // Clear all stepping set by PrepareStep.
   11645 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
   11646   HandleScope scope(isolate);
   11647   ASSERT(args.length() == 0);
   11648   isolate->debug()->ClearStepping();
   11649   return isolate->heap()->undefined_value();
   11650 }
   11651 
   11652 
   11653 // Creates a copy of the with context chain. The copy of the context chain is
   11654 // is linked to the function context supplied.
   11655 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
   11656                                                    Handle<JSFunction> function,
   11657                                                    Handle<Context> base,
   11658                                                    JavaScriptFrame* frame,
   11659                                                    int inlined_jsframe_index) {
   11660   HandleScope scope(isolate);
   11661   List<Handle<ScopeInfo> > scope_chain;
   11662   List<Handle<Context> > context_chain;
   11663 
   11664   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   11665   for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
   11666          it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
   11667     ASSERT(!it.Done());
   11668     scope_chain.Add(it.CurrentScopeInfo());
   11669     context_chain.Add(it.CurrentContext());
   11670   }
   11671 
   11672   // At the end of the chain. Return the base context to link to.
   11673   Handle<Context> context = base;
   11674 
   11675   // Iteratively copy and or materialize the nested contexts.
   11676   while (!scope_chain.is_empty()) {
   11677     Handle<ScopeInfo> scope_info = scope_chain.RemoveLast();
   11678     Handle<Context> current = context_chain.RemoveLast();
   11679     ASSERT(!(scope_info->HasContext() & current.is_null()));
   11680 
   11681     if (scope_info->Type() == CATCH_SCOPE) {
   11682       Handle<String> name(String::cast(current->extension()));
   11683       Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
   11684       context =
   11685           isolate->factory()->NewCatchContext(function,
   11686                                               context,
   11687                                               name,
   11688                                               thrown_object);
   11689     } else if (scope_info->Type() == BLOCK_SCOPE) {
   11690       // Materialize the contents of the block scope into a JSObject.
   11691       Handle<JSObject> block_scope_object =
   11692           MaterializeBlockScope(isolate, current);
   11693       if (block_scope_object.is_null()) {
   11694         return Handle<Context>::null();
   11695       }
   11696       // Allocate a new function context for the debug evaluation and set the
   11697       // extension object.
   11698       Handle<Context> new_context =
   11699           isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
   11700                                                  function);
   11701       new_context->set_extension(*block_scope_object);
   11702       new_context->set_previous(*context);
   11703       context = new_context;
   11704     } else {
   11705       ASSERT(scope_info->Type() == WITH_SCOPE);
   11706       ASSERT(current->IsWithContext());
   11707       Handle<JSObject> extension(JSObject::cast(current->extension()));
   11708       context =
   11709           isolate->factory()->NewWithContext(function, context, extension);
   11710     }
   11711   }
   11712 
   11713   return scope.CloseAndEscape(context);
   11714 }
   11715 
   11716 
   11717 // Helper function to find or create the arguments object for
   11718 // Runtime_DebugEvaluate.
   11719 static Handle<Object> GetArgumentsObject(Isolate* isolate,
   11720                                          JavaScriptFrame* frame,
   11721                                          FrameInspector* frame_inspector,
   11722                                          Handle<ScopeInfo> scope_info,
   11723                                          Handle<Context> function_context) {
   11724   // Try to find the value of 'arguments' to pass as parameter. If it is not
   11725   // found (that is the debugged function does not reference 'arguments' and
   11726   // does not support eval) then create an 'arguments' object.
   11727   int index;
   11728   if (scope_info->StackLocalCount() > 0) {
   11729     index = scope_info->StackSlotIndex(isolate->heap()->arguments_symbol());
   11730     if (index != -1) {
   11731       return Handle<Object>(frame->GetExpression(index), isolate);
   11732     }
   11733   }
   11734 
   11735   if (scope_info->HasHeapAllocatedLocals()) {
   11736     VariableMode mode;
   11737     InitializationFlag init_flag;
   11738     index = scope_info->ContextSlotIndex(
   11739         isolate->heap()->arguments_symbol(), &mode, &init_flag);
   11740     if (index != -1) {
   11741       return Handle<Object>(function_context->get(index), isolate);
   11742     }
   11743   }
   11744 
   11745   Handle<JSFunction> function(JSFunction::cast(frame_inspector->GetFunction()));
   11746   int length = frame_inspector->GetParametersCount();
   11747   Handle<JSObject> arguments =
   11748       isolate->factory()->NewArgumentsObject(function, length);
   11749   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
   11750 
   11751   AssertNoAllocation no_gc;
   11752   WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   11753   for (int i = 0; i < length; i++) {
   11754     array->set(i, frame_inspector->GetParameter(i), mode);
   11755   }
   11756   arguments->set_elements(*array);
   11757   return arguments;
   11758 }
   11759 
   11760 
   11761 static const char kSourceStr[] =
   11762     "(function(arguments,__source__){return eval(__source__);})";
   11763 
   11764 
   11765 // Evaluate a piece of JavaScript in the context of a stack frame for
   11766 // debugging. This is accomplished by creating a new context which in its
   11767 // extension part has all the parameters and locals of the function on the
   11768 // stack frame. A function which calls eval with the code to evaluate is then
   11769 // compiled in this context and called in this context. As this context
   11770 // replaces the context of the function on the stack frame a new (empty)
   11771 // function is created as well to be used as the closure for the context.
   11772 // This function and the context acts as replacements for the function on the
   11773 // stack frame presenting the same view of the values of parameters and
   11774 // local variables as if the piece of JavaScript was evaluated at the point
   11775 // where the function on the stack frame is currently stopped.
   11776 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   11777   HandleScope scope(isolate);
   11778 
   11779   // Check the execution state and decode arguments frame and source to be
   11780   // evaluated.
   11781   ASSERT(args.length() == 6);
   11782   Object* check_result;
   11783   { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
   11784       RUNTIME_ARGUMENTS(isolate, args));
   11785     if (!maybe_check_result->ToObject(&check_result)) {
   11786       return maybe_check_result;
   11787     }
   11788   }
   11789   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   11790   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   11791   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
   11792   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
   11793   Handle<Object> additional_context(args[5]);
   11794 
   11795   // Handle the processing of break.
   11796   DisableBreak disable_break_save(disable_break);
   11797 
   11798   // Get the frame where the debugging is performed.
   11799   StackFrame::Id id = UnwrapFrameId(wrapped_id);
   11800   JavaScriptFrameIterator it(isolate, id);
   11801   JavaScriptFrame* frame = it.frame();
   11802   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
   11803   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
   11804   Handle<ScopeInfo> scope_info(function->shared()->scope_info());
   11805 
   11806   // Traverse the saved contexts chain to find the active context for the
   11807   // selected frame.
   11808   SaveContext* save = FindSavedContextForFrame(isolate, frame);
   11809 
   11810   SaveContext savex(isolate);
   11811   isolate->set_context(*(save->context()));
   11812 
   11813   // Create the (empty) function replacing the function on the stack frame for
   11814   // the purpose of evaluating in the context created below. It is important
   11815   // that this function does not describe any parameters and local variables
   11816   // in the context. If it does then this will cause problems with the lookup
   11817   // in Context::Lookup, where context slots for parameters and local variables
   11818   // are looked at before the extension object.
   11819   Handle<JSFunction> go_between =
   11820       isolate->factory()->NewFunction(isolate->factory()->empty_string(),
   11821                                       isolate->factory()->undefined_value());
   11822   go_between->set_context(function->context());
   11823 #ifdef DEBUG
   11824   Handle<ScopeInfo> go_between_scope_info(go_between->shared()->scope_info());
   11825   ASSERT(go_between_scope_info->ParameterCount() == 0);
   11826   ASSERT(go_between_scope_info->ContextLocalCount() == 0);
   11827 #endif
   11828 
   11829   // Materialize the content of the local scope into a JSObject.
   11830   Handle<JSObject> local_scope = MaterializeLocalScopeWithFrameInspector(
   11831       isolate, frame, &frame_inspector);
   11832   RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
   11833 
   11834   // Allocate a new context for the debug evaluation and set the extension
   11835   // object build.
   11836   Handle<Context> context =
   11837       isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
   11838                                              go_between);
   11839   context->set_extension(*local_scope);
   11840   // Copy any with contexts present and chain them in front of this context.
   11841   Handle<Context> frame_context(Context::cast(frame->context()));
   11842   Handle<Context> function_context;
   11843   // Get the function's context if it has one.
   11844   if (scope_info->HasContext()) {
   11845     function_context = Handle<Context>(frame_context->declaration_context());
   11846   }
   11847   context = CopyNestedScopeContextChain(isolate,
   11848                                         go_between,
   11849                                         context,
   11850                                         frame,
   11851                                         inlined_jsframe_index);
   11852 
   11853   if (additional_context->IsJSObject()) {
   11854     Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
   11855     context =
   11856         isolate->factory()->NewWithContext(go_between, context, extension);
   11857   }
   11858 
   11859   // Wrap the evaluation statement in a new function compiled in the newly
   11860   // created context. The function has one parameter which has to be called
   11861   // 'arguments'. This it to have access to what would have been 'arguments' in
   11862   // the function being debugged.
   11863   // function(arguments,__source__) {return eval(__source__);}
   11864 
   11865   Handle<String> function_source =
   11866       isolate->factory()->NewStringFromAscii(
   11867           Vector<const char>(kSourceStr, sizeof(kSourceStr) - 1));
   11868 
   11869   // Currently, the eval code will be executed in non-strict mode,
   11870   // even in the strict code context.
   11871   Handle<SharedFunctionInfo> shared =
   11872       Compiler::CompileEval(function_source,
   11873                             context,
   11874                             context->IsGlobalContext(),
   11875                             CLASSIC_MODE,
   11876                             RelocInfo::kNoPosition);
   11877   if (shared.is_null()) return Failure::Exception();
   11878   Handle<JSFunction> compiled_function =
   11879       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
   11880 
   11881   // Invoke the result of the compilation to get the evaluation function.
   11882   bool has_pending_exception;
   11883   Handle<Object> receiver(frame->receiver(), isolate);
   11884   Handle<Object> evaluation_function =
   11885       Execution::Call(compiled_function, receiver, 0, NULL,
   11886                       &has_pending_exception);
   11887   if (has_pending_exception) return Failure::Exception();
   11888 
   11889   Handle<Object> arguments = GetArgumentsObject(isolate,
   11890                                                 frame,
   11891                                                 &frame_inspector,
   11892                                                 scope_info,
   11893                                                 function_context);
   11894 
   11895   // Invoke the evaluation function and return the result.
   11896   Handle<Object> argv[] = { arguments, source };
   11897   Handle<Object> result =
   11898       Execution::Call(Handle<JSFunction>::cast(evaluation_function),
   11899                       receiver,
   11900                       ARRAY_SIZE(argv),
   11901                       argv,
   11902                       &has_pending_exception);
   11903   if (has_pending_exception) return Failure::Exception();
   11904 
   11905   // Skip the global proxy as it has no properties and always delegates to the
   11906   // real global object.
   11907   if (result->IsJSGlobalProxy()) {
   11908     result = Handle<JSObject>(JSObject::cast(result->GetPrototype()));
   11909   }
   11910 
   11911   return *result;
   11912 }
   11913 
   11914 
   11915 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
   11916   HandleScope scope(isolate);
   11917 
   11918   // Check the execution state and decode arguments frame and source to be
   11919   // evaluated.
   11920   ASSERT(args.length() == 4);
   11921   Object* check_result;
   11922   { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
   11923       RUNTIME_ARGUMENTS(isolate, args));
   11924     if (!maybe_check_result->ToObject(&check_result)) {
   11925       return maybe_check_result;
   11926     }
   11927   }
   11928   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   11929   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
   11930   Handle<Object> additional_context(args[3]);
   11931 
   11932   // Handle the processing of break.
   11933   DisableBreak disable_break_save(disable_break);
   11934 
   11935   // Enter the top context from before the debugger was invoked.
   11936   SaveContext save(isolate);
   11937   SaveContext* top = &save;
   11938   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
   11939     top = top->prev();
   11940   }
   11941   if (top != NULL) {
   11942     isolate->set_context(*top->context());
   11943   }
   11944 
   11945   // Get the global context now set to the top context from before the
   11946   // debugger was invoked.
   11947   Handle<Context> context = isolate->global_context();
   11948 
   11949   bool is_global = true;
   11950 
   11951   if (additional_context->IsJSObject()) {
   11952     // Create a new with context with the additional context information between
   11953     // the context of the debugged function and the eval code to be executed.
   11954     context = isolate->factory()->NewWithContext(
   11955         Handle<JSFunction>(context->closure()),
   11956         context,
   11957         Handle<JSObject>::cast(additional_context));
   11958     is_global = false;
   11959   }
   11960 
   11961   // Compile the source to be evaluated.
   11962   // Currently, the eval code will be executed in non-strict mode,
   11963   // even in the strict code context.
   11964   Handle<SharedFunctionInfo> shared =
   11965       Compiler::CompileEval(source,
   11966                             context,
   11967                             is_global,
   11968                             CLASSIC_MODE,
   11969                             RelocInfo::kNoPosition);
   11970   if (shared.is_null()) return Failure::Exception();
   11971   Handle<JSFunction> compiled_function =
   11972       Handle<JSFunction>(
   11973           isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
   11974                                                                 context));
   11975 
   11976   // Invoke the result of the compilation to get the evaluation function.
   11977   bool has_pending_exception;
   11978   Handle<Object> receiver = isolate->global();
   11979   Handle<Object> result =
   11980     Execution::Call(compiled_function, receiver, 0, NULL,
   11981                     &has_pending_exception);
   11982   // Clear the oneshot breakpoints so that the debugger does not step further.
   11983   isolate->debug()->ClearStepping();
   11984   if (has_pending_exception) return Failure::Exception();
   11985   return *result;
   11986 }
   11987 
   11988 
   11989 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
   11990   HandleScope scope(isolate);
   11991   ASSERT(args.length() == 0);
   11992 
   11993   // Fill the script objects.
   11994   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
   11995 
   11996   // Convert the script objects to proper JS objects.
   11997   for (int i = 0; i < instances->length(); i++) {
   11998     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
   11999     // Get the script wrapper in a local handle before calling GetScriptWrapper,
   12000     // because using
   12001     //   instances->set(i, *GetScriptWrapper(script))
   12002     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
   12003     // already have dereferenced the instances handle.
   12004     Handle<JSValue> wrapper = GetScriptWrapper(script);
   12005     instances->set(i, *wrapper);
   12006   }
   12007 
   12008   // Return result as a JS array.
   12009   Handle<JSObject> result =
   12010       isolate->factory()->NewJSObject(isolate->array_function());
   12011   isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
   12012   return *result;
   12013 }
   12014 
   12015 
   12016 // Helper function used by Runtime_DebugReferencedBy below.
   12017 static int DebugReferencedBy(HeapIterator* iterator,
   12018                              JSObject* target,
   12019                              Object* instance_filter, int max_references,
   12020                              FixedArray* instances, int instances_size,
   12021                              JSFunction* arguments_function) {
   12022   NoHandleAllocation ha;
   12023   AssertNoAllocation no_alloc;
   12024 
   12025   // Iterate the heap.
   12026   int count = 0;
   12027   JSObject* last = NULL;
   12028   HeapObject* heap_obj = NULL;
   12029   while (((heap_obj = iterator->next()) != NULL) &&
   12030          (max_references == 0 || count < max_references)) {
   12031     // Only look at all JSObjects.
   12032     if (heap_obj->IsJSObject()) {
   12033       // Skip context extension objects and argument arrays as these are
   12034       // checked in the context of functions using them.
   12035       JSObject* obj = JSObject::cast(heap_obj);
   12036       if (obj->IsJSContextExtensionObject() ||
   12037           obj->map()->constructor() == arguments_function) {
   12038         continue;
   12039       }
   12040 
   12041       // Check if the JS object has a reference to the object looked for.
   12042       if (obj->ReferencesObject(target)) {
   12043         // Check instance filter if supplied. This is normally used to avoid
   12044         // references from mirror objects (see Runtime_IsInPrototypeChain).
   12045         if (!instance_filter->IsUndefined()) {
   12046           Object* V = obj;
   12047           while (true) {
   12048             Object* prototype = V->GetPrototype();
   12049             if (prototype->IsNull()) {
   12050               break;
   12051             }
   12052             if (instance_filter == prototype) {
   12053               obj = NULL;  // Don't add this object.
   12054               break;
   12055             }
   12056             V = prototype;
   12057           }
   12058         }
   12059 
   12060         if (obj != NULL) {
   12061           // Valid reference found add to instance array if supplied an update
   12062           // count.
   12063           if (instances != NULL && count < instances_size) {
   12064             instances->set(count, obj);
   12065           }
   12066           last = obj;
   12067           count++;
   12068         }
   12069       }
   12070     }
   12071   }
   12072 
   12073   // Check for circular reference only. This can happen when the object is only
   12074   // referenced from mirrors and has a circular reference in which case the
   12075   // object is not really alive and would have been garbage collected if not
   12076   // referenced from the mirror.
   12077   if (count == 1 && last == target) {
   12078     count = 0;
   12079   }
   12080 
   12081   // Return the number of referencing objects found.
   12082   return count;
   12083 }
   12084 
   12085 
   12086 // Scan the heap for objects with direct references to an object
   12087 // args[0]: the object to find references to
   12088 // args[1]: constructor function for instances to exclude (Mirror)
   12089 // args[2]: the the maximum number of objects to return
   12090 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
   12091   ASSERT(args.length() == 3);
   12092 
   12093   // First perform a full GC in order to avoid references from dead objects.
   12094   isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
   12095                                      "%DebugReferencedBy");
   12096   // The heap iterator reserves the right to do a GC to make the heap iterable.
   12097   // Due to the GC above we know it won't need to do that, but it seems cleaner
   12098   // to get the heap iterator constructed before we start having unprotected
   12099   // Object* locals that are not protected by handles.
   12100 
   12101   // Check parameters.
   12102   CONVERT_ARG_CHECKED(JSObject, target, 0);
   12103   Object* instance_filter = args[1];
   12104   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
   12105                  instance_filter->IsJSObject());
   12106   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
   12107   RUNTIME_ASSERT(max_references >= 0);
   12108 
   12109 
   12110   // Get the constructor function for context extension and arguments array.
   12111   JSObject* arguments_boilerplate =
   12112       isolate->context()->global_context()->arguments_boilerplate();
   12113   JSFunction* arguments_function =
   12114       JSFunction::cast(arguments_boilerplate->map()->constructor());
   12115 
   12116   // Get the number of referencing objects.
   12117   int count;
   12118   HeapIterator heap_iterator;
   12119   count = DebugReferencedBy(&heap_iterator,
   12120                             target, instance_filter, max_references,
   12121                             NULL, 0, arguments_function);
   12122 
   12123   // Allocate an array to hold the result.
   12124   Object* object;
   12125   { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count);
   12126     if (!maybe_object->ToObject(&object)) return maybe_object;
   12127   }
   12128   FixedArray* instances = FixedArray::cast(object);
   12129 
   12130   // Fill the referencing objects.
   12131   // AllocateFixedArray above does not make the heap non-iterable.
   12132   ASSERT(HEAP->IsHeapIterable());
   12133   HeapIterator heap_iterator2;
   12134   count = DebugReferencedBy(&heap_iterator2,
   12135                             target, instance_filter, max_references,
   12136                             instances, count, arguments_function);
   12137 
   12138   // Return result as JS array.
   12139   Object* result;
   12140   MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
   12141       isolate->context()->global_context()->array_function());
   12142   if (!maybe_result->ToObject(&result)) return maybe_result;
   12143   return JSArray::cast(result)->SetContent(instances);
   12144 }
   12145 
   12146 
   12147 // Helper function used by Runtime_DebugConstructedBy below.
   12148 static int DebugConstructedBy(HeapIterator* iterator,
   12149                               JSFunction* constructor,
   12150                               int max_references,
   12151                               FixedArray* instances,
   12152                               int instances_size) {
   12153   AssertNoAllocation no_alloc;
   12154 
   12155   // Iterate the heap.
   12156   int count = 0;
   12157   HeapObject* heap_obj = NULL;
   12158   while (((heap_obj = iterator->next()) != NULL) &&
   12159          (max_references == 0 || count < max_references)) {
   12160     // Only look at all JSObjects.
   12161     if (heap_obj->IsJSObject()) {
   12162       JSObject* obj = JSObject::cast(heap_obj);
   12163       if (obj->map()->constructor() == constructor) {
   12164         // Valid reference found add to instance array if supplied an update
   12165         // count.
   12166         if (instances != NULL && count < instances_size) {
   12167           instances->set(count, obj);
   12168         }
   12169         count++;
   12170       }
   12171     }
   12172   }
   12173 
   12174   // Return the number of referencing objects found.
   12175   return count;
   12176 }
   12177 
   12178 
   12179 // Scan the heap for objects constructed by a specific function.
   12180 // args[0]: the constructor to find instances of
   12181 // args[1]: the the maximum number of objects to return
   12182 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
   12183   ASSERT(args.length() == 2);
   12184 
   12185   // First perform a full GC in order to avoid dead objects.
   12186   isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
   12187                                      "%DebugConstructedBy");
   12188 
   12189   // Check parameters.
   12190   CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
   12191   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   12192   RUNTIME_ASSERT(max_references >= 0);
   12193 
   12194   // Get the number of referencing objects.
   12195   int count;
   12196   HeapIterator heap_iterator;
   12197   count = DebugConstructedBy(&heap_iterator,
   12198                              constructor,
   12199                              max_references,
   12200                              NULL,
   12201                              0);
   12202 
   12203   // Allocate an array to hold the result.
   12204   Object* object;
   12205   { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count);
   12206     if (!maybe_object->ToObject(&object)) return maybe_object;
   12207   }
   12208   FixedArray* instances = FixedArray::cast(object);
   12209 
   12210   ASSERT(HEAP->IsHeapIterable());
   12211   // Fill the referencing objects.
   12212   HeapIterator heap_iterator2;
   12213   count = DebugConstructedBy(&heap_iterator2,
   12214                              constructor,
   12215                              max_references,
   12216                              instances,
   12217                              count);
   12218 
   12219   // Return result as JS array.
   12220   Object* result;
   12221   { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
   12222           isolate->context()->global_context()->array_function());
   12223     if (!maybe_result->ToObject(&result)) return maybe_result;
   12224   }
   12225   return JSArray::cast(result)->SetContent(instances);
   12226 }
   12227 
   12228 
   12229 // Find the effective prototype object as returned by __proto__.
   12230 // args[0]: the object to find the prototype for.
   12231 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
   12232   ASSERT(args.length() == 1);
   12233 
   12234   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   12235 
   12236   // Use the __proto__ accessor.
   12237   return Accessors::ObjectPrototype.getter(obj, NULL);
   12238 }
   12239 
   12240 
   12241 // Patches script source (should be called upon BeforeCompile event).
   12242 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
   12243   HandleScope scope(isolate);
   12244   ASSERT(args.length() == 2);
   12245 
   12246   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
   12247   Handle<String> source(String::cast(args[1]));
   12248 
   12249   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
   12250   Handle<Script> script(Script::cast(script_wrapper->value()));
   12251 
   12252   int compilation_state = Smi::cast(script->compilation_state())->value();
   12253   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
   12254   script->set_source(*source);
   12255 
   12256   return isolate->heap()->undefined_value();
   12257 }
   12258 
   12259 
   12260 RUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
   12261   ASSERT(args.length() == 0);
   12262   CPU::DebugBreak();
   12263   return isolate->heap()->undefined_value();
   12264 }
   12265 
   12266 
   12267 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
   12268 #ifdef DEBUG
   12269   HandleScope scope(isolate);
   12270   ASSERT(args.length() == 1);
   12271   // Get the function and make sure it is compiled.
   12272   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   12273   Handle<SharedFunctionInfo> shared(func->shared());
   12274   if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
   12275     return Failure::Exception();
   12276   }
   12277   func->code()->PrintLn();
   12278 #endif  // DEBUG
   12279   return isolate->heap()->undefined_value();
   12280 }
   12281 
   12282 
   12283 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
   12284 #ifdef DEBUG
   12285   HandleScope scope(isolate);
   12286   ASSERT(args.length() == 1);
   12287   // Get the function and make sure it is compiled.
   12288   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
   12289   Handle<SharedFunctionInfo> shared(func->shared());
   12290   if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
   12291     return Failure::Exception();
   12292   }
   12293   shared->construct_stub()->PrintLn();
   12294 #endif  // DEBUG
   12295   return isolate->heap()->undefined_value();
   12296 }
   12297 
   12298 
   12299 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
   12300   NoHandleAllocation ha;
   12301   ASSERT(args.length() == 1);
   12302 
   12303   CONVERT_ARG_CHECKED(JSFunction, f, 0);
   12304   return f->shared()->inferred_name();
   12305 }
   12306 
   12307 
   12308 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
   12309                                             Script* script,
   12310                                             FixedArray* buffer) {
   12311   AssertNoAllocation no_allocations;
   12312   int counter = 0;
   12313   int buffer_size = buffer->length();
   12314   for (HeapObject* obj = iterator->next();
   12315        obj != NULL;
   12316        obj = iterator->next()) {
   12317     ASSERT(obj != NULL);
   12318     if (!obj->IsSharedFunctionInfo()) {
   12319       continue;
   12320     }
   12321     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
   12322     if (shared->script() != script) {
   12323       continue;
   12324     }
   12325     if (counter < buffer_size) {
   12326       buffer->set(counter, shared);
   12327     }
   12328     counter++;
   12329   }
   12330   return counter;
   12331 }
   12332 
   12333 // For a script finds all SharedFunctionInfo's in the heap that points
   12334 // to this script. Returns JSArray of SharedFunctionInfo wrapped
   12335 // in OpaqueReferences.
   12336 RUNTIME_FUNCTION(MaybeObject*,
   12337                  Runtime_LiveEditFindSharedFunctionInfosForScript) {
   12338   ASSERT(args.length() == 1);
   12339   HandleScope scope(isolate);
   12340   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
   12341 
   12342 
   12343   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
   12344 
   12345   const int kBufferSize = 32;
   12346 
   12347   Handle<FixedArray> array;
   12348   array = isolate->factory()->NewFixedArray(kBufferSize);
   12349   int number;
   12350   {
   12351     isolate->heap()->EnsureHeapIsIterable();
   12352     AssertNoAllocation no_allocations;
   12353     HeapIterator heap_iterator;
   12354     Script* scr = *script;
   12355     FixedArray* arr = *array;
   12356     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   12357   }
   12358   if (number > kBufferSize) {
   12359     array = isolate->factory()->NewFixedArray(number);
   12360     isolate->heap()->EnsureHeapIsIterable();
   12361     AssertNoAllocation no_allocations;
   12362     HeapIterator heap_iterator;
   12363     Script* scr = *script;
   12364     FixedArray* arr = *array;
   12365     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
   12366   }
   12367 
   12368   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
   12369   result->set_length(Smi::FromInt(number));
   12370 
   12371   LiveEdit::WrapSharedFunctionInfos(result);
   12372 
   12373   return *result;
   12374 }
   12375 
   12376 // For a script calculates compilation information about all its functions.
   12377 // The script source is explicitly specified by the second argument.
   12378 // The source of the actual script is not used, however it is important that
   12379 // all generated code keeps references to this particular instance of script.
   12380 // Returns a JSArray of compilation infos. The array is ordered so that
   12381 // each function with all its descendant is always stored in a continues range
   12382 // with the function itself going first. The root function is a script function.
   12383 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
   12384   ASSERT(args.length() == 2);
   12385   HandleScope scope(isolate);
   12386   CONVERT_ARG_CHECKED(JSValue, script, 0);
   12387   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   12388   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
   12389 
   12390   JSArray* result =  LiveEdit::GatherCompileInfo(script_handle, source);
   12391 
   12392   if (isolate->has_pending_exception()) {
   12393     return Failure::Exception();
   12394   }
   12395 
   12396   return result;
   12397 }
   12398 
   12399 // Changes the source of the script to a new_source.
   12400 // If old_script_name is provided (i.e. is a String), also creates a copy of
   12401 // the script with its original source and sends notification to debugger.
   12402 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
   12403   ASSERT(args.length() == 3);
   12404   HandleScope scope(isolate);
   12405   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
   12406   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
   12407   Handle<Object> old_script_name(args[2], isolate);
   12408 
   12409   RUNTIME_ASSERT(original_script_value->value()->IsScript());
   12410   Handle<Script> original_script(Script::cast(original_script_value->value()));
   12411 
   12412   Object* old_script = LiveEdit::ChangeScriptSource(original_script,
   12413                                                     new_source,
   12414                                                     old_script_name);
   12415 
   12416   if (old_script->IsScript()) {
   12417     Handle<Script> script_handle(Script::cast(old_script));
   12418     return *(GetScriptWrapper(script_handle));
   12419   } else {
   12420     return isolate->heap()->null_value();
   12421   }
   12422 }
   12423 
   12424 
   12425 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
   12426   ASSERT(args.length() == 1);
   12427   HandleScope scope(isolate);
   12428   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
   12429   return LiveEdit::FunctionSourceUpdated(shared_info);
   12430 }
   12431 
   12432 
   12433 // Replaces code of SharedFunctionInfo with a new one.
   12434 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
   12435   ASSERT(args.length() == 2);
   12436   HandleScope scope(isolate);
   12437   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
   12438   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
   12439 
   12440   return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
   12441 }
   12442 
   12443 // Connects SharedFunctionInfo to another script.
   12444 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
   12445   ASSERT(args.length() == 2);
   12446   HandleScope scope(isolate);
   12447   Handle<Object> function_object(args[0], isolate);
   12448   Handle<Object> script_object(args[1], isolate);
   12449 
   12450   if (function_object->IsJSValue()) {
   12451     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
   12452     if (script_object->IsJSValue()) {
   12453       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
   12454       Script* script = Script::cast(JSValue::cast(*script_object)->value());
   12455       script_object = Handle<Object>(script, isolate);
   12456     }
   12457 
   12458     LiveEdit::SetFunctionScript(function_wrapper, script_object);
   12459   } else {
   12460     // Just ignore this. We may not have a SharedFunctionInfo for some functions
   12461     // and we check it in this function.
   12462   }
   12463 
   12464   return isolate->heap()->undefined_value();
   12465 }
   12466 
   12467 
   12468 // In a code of a parent function replaces original function as embedded object
   12469 // with a substitution one.
   12470 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
   12471   ASSERT(args.length() == 3);
   12472   HandleScope scope(isolate);
   12473 
   12474   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
   12475   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
   12476   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
   12477 
   12478   LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
   12479                                        subst_wrapper);
   12480 
   12481   return isolate->heap()->undefined_value();
   12482 }
   12483 
   12484 
   12485 // Updates positions of a shared function info (first parameter) according
   12486 // to script source change. Text change is described in second parameter as
   12487 // array of groups of 3 numbers:
   12488 // (change_begin, change_end, change_end_new_position).
   12489 // Each group describes a change in text; groups are sorted by change_begin.
   12490 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
   12491   ASSERT(args.length() == 2);
   12492   HandleScope scope(isolate);
   12493   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   12494   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
   12495 
   12496   return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
   12497 }
   12498 
   12499 
   12500 // For array of SharedFunctionInfo's (each wrapped in JSValue)
   12501 // checks that none of them have activations on stacks (of any thread).
   12502 // Returns array of the same length with corresponding results of
   12503 // LiveEdit::FunctionPatchabilityStatus type.
   12504 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
   12505   ASSERT(args.length() == 2);
   12506   HandleScope scope(isolate);
   12507   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
   12508   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
   12509 
   12510   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
   12511 }
   12512 
   12513 // Compares 2 strings line-by-line, then token-wise and returns diff in form
   12514 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
   12515 // of diff chunks.
   12516 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
   12517   ASSERT(args.length() == 2);
   12518   HandleScope scope(isolate);
   12519   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
   12520   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
   12521 
   12522   return *LiveEdit::CompareStrings(s1, s2);
   12523 }
   12524 
   12525 
   12526 // A testing entry. Returns statement position which is the closest to
   12527 // source_position.
   12528 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
   12529   ASSERT(args.length() == 2);
   12530   HandleScope scope(isolate);
   12531   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   12532   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   12533 
   12534   Handle<Code> code(function->code(), isolate);
   12535 
   12536   if (code->kind() != Code::FUNCTION &&
   12537       code->kind() != Code::OPTIMIZED_FUNCTION) {
   12538     return isolate->heap()->undefined_value();
   12539   }
   12540 
   12541   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
   12542   int closest_pc = 0;
   12543   int distance = kMaxInt;
   12544   while (!it.done()) {
   12545     int statement_position = static_cast<int>(it.rinfo()->data());
   12546     // Check if this break point is closer that what was previously found.
   12547     if (source_position <= statement_position &&
   12548         statement_position - source_position < distance) {
   12549       closest_pc =
   12550           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
   12551       distance = statement_position - source_position;
   12552       // Check whether we can't get any closer.
   12553       if (distance == 0) break;
   12554     }
   12555     it.next();
   12556   }
   12557 
   12558   return Smi::FromInt(closest_pc);
   12559 }
   12560 
   12561 
   12562 // Calls specified function with or without entering the debugger.
   12563 // This is used in unit tests to run code as if debugger is entered or simply
   12564 // to have a stack with C++ frame in the middle.
   12565 RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
   12566   ASSERT(args.length() == 2);
   12567   HandleScope scope(isolate);
   12568   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   12569   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
   12570 
   12571   Handle<Object> result;
   12572   bool pending_exception;
   12573   {
   12574     if (without_debugger) {
   12575       result = Execution::Call(function, isolate->global(), 0, NULL,
   12576                                &pending_exception);
   12577     } else {
   12578       EnterDebugger enter_debugger;
   12579       result = Execution::Call(function, isolate->global(), 0, NULL,
   12580                                &pending_exception);
   12581     }
   12582   }
   12583   if (!pending_exception) {
   12584     return *result;
   12585   } else {
   12586     return Failure::Exception();
   12587   }
   12588 }
   12589 
   12590 
   12591 // Sets a v8 flag.
   12592 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
   12593   CONVERT_ARG_CHECKED(String, arg, 0);
   12594   SmartArrayPointer<char> flags =
   12595       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   12596   FlagList::SetFlagsFromString(*flags, StrLength(*flags));
   12597   return isolate->heap()->undefined_value();
   12598 }
   12599 
   12600 
   12601 // Performs a GC.
   12602 // Presently, it only does a full GC.
   12603 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectGarbage) {
   12604   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
   12605   return isolate->heap()->undefined_value();
   12606 }
   12607 
   12608 
   12609 // Gets the current heap usage.
   12610 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
   12611   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
   12612   if (!Smi::IsValid(usage)) {
   12613     return *isolate->factory()->NewNumberFromInt(usage);
   12614   }
   12615   return Smi::FromInt(usage);
   12616 }
   12617 
   12618 
   12619 // Captures a live object list from the present heap.
   12620 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLOLEnabled) {
   12621 #ifdef LIVE_OBJECT_LIST
   12622   return isolate->heap()->true_value();
   12623 #else
   12624   return isolate->heap()->false_value();
   12625 #endif
   12626 }
   12627 
   12628 
   12629 // Captures a live object list from the present heap.
   12630 RUNTIME_FUNCTION(MaybeObject*, Runtime_CaptureLOL) {
   12631 #ifdef LIVE_OBJECT_LIST
   12632   return LiveObjectList::Capture();
   12633 #else
   12634   return isolate->heap()->undefined_value();
   12635 #endif
   12636 }
   12637 
   12638 
   12639 // Deletes the specified live object list.
   12640 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
   12641 #ifdef LIVE_OBJECT_LIST
   12642   CONVERT_SMI_ARG_CHECKED(id, 0);
   12643   bool success = LiveObjectList::Delete(id);
   12644   return isolate->heap()->ToBoolean(success);
   12645 #else
   12646   return isolate->heap()->undefined_value();
   12647 #endif
   12648 }
   12649 
   12650 
   12651 // Generates the response to a debugger request for a dump of the objects
   12652 // contained in the difference between the captured live object lists
   12653 // specified by id1 and id2.
   12654 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
   12655 // dumped.
   12656 RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
   12657 #ifdef LIVE_OBJECT_LIST
   12658   HandleScope scope;
   12659   CONVERT_SMI_ARG_CHECKED(id1, 0);
   12660   CONVERT_SMI_ARG_CHECKED(id2, 1);
   12661   CONVERT_SMI_ARG_CHECKED(start, 2);
   12662   CONVERT_SMI_ARG_CHECKED(count, 3);
   12663   CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 4);
   12664   EnterDebugger enter_debugger;
   12665   return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
   12666 #else
   12667   return isolate->heap()->undefined_value();
   12668 #endif
   12669 }
   12670 
   12671 
   12672 // Gets the specified object as requested by the debugger.
   12673 // This is only used for obj ids shown in live object lists.
   12674 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) {
   12675 #ifdef LIVE_OBJECT_LIST
   12676   CONVERT_SMI_ARG_CHECKED(obj_id, 0);
   12677   Object* result = LiveObjectList::GetObj(obj_id);
   12678   return result;
   12679 #else
   12680   return isolate->heap()->undefined_value();
   12681 #endif
   12682 }
   12683 
   12684 
   12685 // Gets the obj id for the specified address if valid.
   12686 // This is only used for obj ids shown in live object lists.
   12687 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) {
   12688 #ifdef LIVE_OBJECT_LIST
   12689   HandleScope scope;
   12690   CONVERT_ARG_HANDLE_CHECKED(String, address, 0);
   12691   Object* result = LiveObjectList::GetObjId(address);
   12692   return result;
   12693 #else
   12694   return isolate->heap()->undefined_value();
   12695 #endif
   12696 }
   12697 
   12698 
   12699 // Gets the retainers that references the specified object alive.
   12700 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
   12701 #ifdef LIVE_OBJECT_LIST
   12702   HandleScope scope;
   12703   CONVERT_SMI_ARG_CHECKED(obj_id, 0);
   12704   RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
   12705   RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
   12706   RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
   12707   RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi());
   12708   CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 5);
   12709 
   12710   Handle<JSObject> instance_filter;
   12711   if (args[1]->IsJSObject()) {
   12712     instance_filter = args.at<JSObject>(1);
   12713   }
   12714   bool verbose = false;
   12715   if (args[2]->IsBoolean()) {
   12716     verbose = args[2]->IsTrue();
   12717   }
   12718   int start = 0;
   12719   if (args[3]->IsSmi()) {
   12720     start = args.smi_at(3);
   12721   }
   12722   int limit = Smi::kMaxValue;
   12723   if (args[4]->IsSmi()) {
   12724     limit = args.smi_at(4);
   12725   }
   12726 
   12727   return LiveObjectList::GetObjRetainers(obj_id,
   12728                                          instance_filter,
   12729                                          verbose,
   12730                                          start,
   12731                                          limit,
   12732                                          filter_obj);
   12733 #else
   12734   return isolate->heap()->undefined_value();
   12735 #endif
   12736 }
   12737 
   12738 
   12739 // Gets the reference path between 2 objects.
   12740 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
   12741 #ifdef LIVE_OBJECT_LIST
   12742   HandleScope scope;
   12743   CONVERT_SMI_ARG_CHECKED(obj_id1, 0);
   12744   CONVERT_SMI_ARG_CHECKED(obj_id2, 1);
   12745   RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
   12746 
   12747   Handle<JSObject> instance_filter;
   12748   if (args[2]->IsJSObject()) {
   12749     instance_filter = args.at<JSObject>(2);
   12750   }
   12751 
   12752   Object* result =
   12753       LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter);
   12754   return result;
   12755 #else
   12756   return isolate->heap()->undefined_value();
   12757 #endif
   12758 }
   12759 
   12760 
   12761 // Generates the response to a debugger request for a list of all
   12762 // previously captured live object lists.
   12763 RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
   12764 #ifdef LIVE_OBJECT_LIST
   12765   CONVERT_SMI_ARG_CHECKED(start, 0);
   12766   CONVERT_SMI_ARG_CHECKED(count, 1);
   12767   return LiveObjectList::Info(start, count);
   12768 #else
   12769   return isolate->heap()->undefined_value();
   12770 #endif
   12771 }
   12772 
   12773 
   12774 // Gets a dump of the specified object as requested by the debugger.
   12775 // This is only used for obj ids shown in live object lists.
   12776 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) {
   12777 #ifdef LIVE_OBJECT_LIST
   12778   HandleScope scope;
   12779   CONVERT_SMI_ARG_CHECKED(obj_id, 0);
   12780   Object* result = LiveObjectList::PrintObj(obj_id);
   12781   return result;
   12782 #else
   12783   return isolate->heap()->undefined_value();
   12784 #endif
   12785 }
   12786 
   12787 
   12788 // Resets and releases all previously captured live object lists.
   12789 RUNTIME_FUNCTION(MaybeObject*, Runtime_ResetLOL) {
   12790 #ifdef LIVE_OBJECT_LIST
   12791   LiveObjectList::Reset();
   12792   return isolate->heap()->undefined_value();
   12793 #else
   12794   return isolate->heap()->undefined_value();
   12795 #endif
   12796 }
   12797 
   12798 
   12799 // Generates the response to a debugger request for a summary of the types
   12800 // of objects in the difference between the captured live object lists
   12801 // specified by id1 and id2.
   12802 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
   12803 // summarized.
   12804 RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
   12805 #ifdef LIVE_OBJECT_LIST
   12806   HandleScope scope;
   12807   CONVERT_SMI_ARG_CHECKED(id1, 0);
   12808   CONVERT_SMI_ARG_CHECKED(id2, 1);
   12809   CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 2);
   12810 
   12811   EnterDebugger enter_debugger;
   12812   return LiveObjectList::Summarize(id1, id2, filter_obj);
   12813 #else
   12814   return isolate->heap()->undefined_value();
   12815 #endif
   12816 }
   12817 
   12818 #endif  // ENABLE_DEBUGGER_SUPPORT
   12819 
   12820 
   12821 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
   12822   NoHandleAllocation ha;
   12823   v8::V8::ResumeProfiler();
   12824   return isolate->heap()->undefined_value();
   12825 }
   12826 
   12827 
   12828 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerPause) {
   12829   NoHandleAllocation ha;
   12830   v8::V8::PauseProfiler();
   12831   return isolate->heap()->undefined_value();
   12832 }
   12833 
   12834 
   12835 // Finds the script object from the script data. NOTE: This operation uses
   12836 // heap traversal to find the function generated for the source position
   12837 // for the requested break point. For lazily compiled functions several heap
   12838 // traversals might be required rendering this operation as a rather slow
   12839 // operation. However for setting break points which is normally done through
   12840 // some kind of user interaction the performance is not crucial.
   12841 static Handle<Object> Runtime_GetScriptFromScriptName(
   12842     Handle<String> script_name) {
   12843   // Scan the heap for Script objects to find the script with the requested
   12844   // script data.
   12845   Handle<Script> script;
   12846   script_name->GetHeap()->EnsureHeapIsIterable();
   12847   AssertNoAllocation no_allocation_during_heap_iteration;
   12848   HeapIterator iterator;
   12849   HeapObject* obj = NULL;
   12850   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
   12851     // If a script is found check if it has the script data requested.
   12852     if (obj->IsScript()) {
   12853       if (Script::cast(obj)->name()->IsString()) {
   12854         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
   12855           script = Handle<Script>(Script::cast(obj));
   12856         }
   12857       }
   12858     }
   12859   }
   12860 
   12861   // If no script with the requested script data is found return undefined.
   12862   if (script.is_null()) return FACTORY->undefined_value();
   12863 
   12864   // Return the script found.
   12865   return GetScriptWrapper(script);
   12866 }
   12867 
   12868 
   12869 // Get the script object from script data. NOTE: Regarding performance
   12870 // see the NOTE for GetScriptFromScriptData.
   12871 // args[0]: script data for the script to find the source for
   12872 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
   12873   HandleScope scope(isolate);
   12874 
   12875   ASSERT(args.length() == 1);
   12876 
   12877   CONVERT_ARG_CHECKED(String, script_name, 0);
   12878 
   12879   // Find the requested script.
   12880   Handle<Object> result =
   12881       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
   12882   return *result;
   12883 }
   12884 
   12885 
   12886 // Determines whether the given stack frame should be displayed in
   12887 // a stack trace.  The caller is the error constructor that asked
   12888 // for the stack trace to be collected.  The first time a construct
   12889 // call to this function is encountered it is skipped.  The seen_caller
   12890 // in/out parameter is used to remember if the caller has been seen
   12891 // yet.
   12892 static bool ShowFrameInStackTrace(StackFrame* raw_frame,
   12893                                   Object* caller,
   12894                                   bool* seen_caller) {
   12895   // Only display JS frames.
   12896   if (!raw_frame->is_java_script()) {
   12897     return false;
   12898   }
   12899   JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
   12900   Object* raw_fun = frame->function();
   12901   // Not sure when this can happen but skip it just in case.
   12902   if (!raw_fun->IsJSFunction()) {
   12903     return false;
   12904   }
   12905   if ((raw_fun == caller) && !(*seen_caller)) {
   12906     *seen_caller = true;
   12907     return false;
   12908   }
   12909   // Skip all frames until we've seen the caller.
   12910   if (!(*seen_caller)) return false;
   12911   // Also, skip non-visible built-in functions and any call with the builtins
   12912   // object as receiver, so as to not reveal either the builtins object or
   12913   // an internal function.
   12914   // The --builtins-in-stack-traces command line flag allows including
   12915   // internal call sites in the stack trace for debugging purposes.
   12916   if (!FLAG_builtins_in_stack_traces) {
   12917     JSFunction* fun = JSFunction::cast(raw_fun);
   12918     if (frame->receiver()->IsJSBuiltinsObject() ||
   12919         (fun->IsBuiltin() && !fun->shared()->native())) {
   12920       return false;
   12921     }
   12922   }
   12923   return true;
   12924 }
   12925 
   12926 
   12927 // Collect the raw data for a stack trace.  Returns an array of 4
   12928 // element segments each containing a receiver, function, code and
   12929 // native code offset.
   12930 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
   12931   ASSERT_EQ(args.length(), 3);
   12932   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   12933   Handle<Object> caller = args.at<Object>(1);
   12934   CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
   12935 
   12936   HandleScope scope(isolate);
   12937   Factory* factory = isolate->factory();
   12938 
   12939   limit = Max(limit, 0);  // Ensure that limit is not negative.
   12940   int initial_size = Min(limit, 10);
   12941   Handle<FixedArray> elements =
   12942       factory->NewFixedArrayWithHoles(initial_size * 4);
   12943 
   12944   StackFrameIterator iter(isolate);
   12945   // If the caller parameter is a function we skip frames until we're
   12946   // under it before starting to collect.
   12947   bool seen_caller = !caller->IsJSFunction();
   12948   int cursor = 0;
   12949   int frames_seen = 0;
   12950   while (!iter.done() && frames_seen < limit) {
   12951     StackFrame* raw_frame = iter.frame();
   12952     if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) {
   12953       frames_seen++;
   12954       JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
   12955       // Set initial size to the maximum inlining level + 1 for the outermost
   12956       // function.
   12957       List<FrameSummary> frames(Compiler::kMaxInliningLevels + 1);
   12958       frame->Summarize(&frames);
   12959       for (int i = frames.length() - 1; i >= 0; i--) {
   12960         if (cursor + 4 > elements->length()) {
   12961           int new_capacity = JSObject::NewElementsCapacity(elements->length());
   12962           Handle<FixedArray> new_elements =
   12963               factory->NewFixedArrayWithHoles(new_capacity);
   12964           for (int i = 0; i < cursor; i++) {
   12965             new_elements->set(i, elements->get(i));
   12966           }
   12967           elements = new_elements;
   12968         }
   12969         ASSERT(cursor + 4 <= elements->length());
   12970 
   12971         Handle<Object> recv = frames[i].receiver();
   12972         Handle<JSFunction> fun = frames[i].function();
   12973         Handle<Code> code = frames[i].code();
   12974         Handle<Smi> offset(Smi::FromInt(frames[i].offset()));
   12975         elements->set(cursor++, *recv);
   12976         elements->set(cursor++, *fun);
   12977         elements->set(cursor++, *code);
   12978         elements->set(cursor++, *offset);
   12979       }
   12980     }
   12981     iter.Advance();
   12982   }
   12983   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
   12984   // Capture and attach a more detailed stack trace if necessary.
   12985   isolate->CaptureAndSetCurrentStackTraceFor(error_object);
   12986   result->set_length(Smi::FromInt(cursor));
   12987   return *result;
   12988 }
   12989 
   12990 
   12991 // Returns V8 version as a string.
   12992 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
   12993   ASSERT_EQ(args.length(), 0);
   12994 
   12995   NoHandleAllocation ha;
   12996 
   12997   const char* version_string = v8::V8::GetVersion();
   12998 
   12999   return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string),
   13000                                                   NOT_TENURED);
   13001 }
   13002 
   13003 
   13004 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
   13005   ASSERT(args.length() == 2);
   13006   OS::PrintError("abort: %s\n",
   13007                  reinterpret_cast<char*>(args[0]) + args.smi_at(1));
   13008   isolate->PrintStack();
   13009   OS::Abort();
   13010   UNREACHABLE();
   13011   return NULL;
   13012 }
   13013 
   13014 
   13015 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
   13016   // This is only called from codegen, so checks might be more lax.
   13017   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
   13018   Object* key = args[1];
   13019 
   13020   int finger_index = cache->finger_index();
   13021   Object* o = cache->get(finger_index);
   13022   if (o == key) {
   13023     // The fastest case: hit the same place again.
   13024     return cache->get(finger_index + 1);
   13025   }
   13026 
   13027   for (int i = finger_index - 2;
   13028        i >= JSFunctionResultCache::kEntriesIndex;
   13029        i -= 2) {
   13030     o = cache->get(i);
   13031     if (o == key) {
   13032       cache->set_finger_index(i);
   13033       return cache->get(i + 1);
   13034     }
   13035   }
   13036 
   13037   int size = cache->size();
   13038   ASSERT(size <= cache->length());
   13039 
   13040   for (int i = size - 2; i > finger_index; i -= 2) {
   13041     o = cache->get(i);
   13042     if (o == key) {
   13043       cache->set_finger_index(i);
   13044       return cache->get(i + 1);
   13045     }
   13046   }
   13047 
   13048   // There is no value in the cache.  Invoke the function and cache result.
   13049   HandleScope scope(isolate);
   13050 
   13051   Handle<JSFunctionResultCache> cache_handle(cache);
   13052   Handle<Object> key_handle(key);
   13053   Handle<Object> value;
   13054   {
   13055     Handle<JSFunction> factory(JSFunction::cast(
   13056           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
   13057     // TODO(antonm): consider passing a receiver when constructing a cache.
   13058     Handle<Object> receiver(isolate->global_context()->global());
   13059     // This handle is nor shared, nor used later, so it's safe.
   13060     Handle<Object> argv[] = { key_handle };
   13061     bool pending_exception;
   13062     value = Execution::Call(factory,
   13063                             receiver,
   13064                             ARRAY_SIZE(argv),
   13065                             argv,
   13066                             &pending_exception);
   13067     if (pending_exception) return Failure::Exception();
   13068   }
   13069 
   13070 #ifdef DEBUG
   13071   if (FLAG_verify_heap) {
   13072     cache_handle->JSFunctionResultCacheVerify();
   13073   }
   13074 #endif
   13075 
   13076   // Function invocation may have cleared the cache.  Reread all the data.
   13077   finger_index = cache_handle->finger_index();
   13078   size = cache_handle->size();
   13079 
   13080   // If we have spare room, put new data into it, otherwise evict post finger
   13081   // entry which is likely to be the least recently used.
   13082   int index = -1;
   13083   if (size < cache_handle->length()) {
   13084     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
   13085     index = size;
   13086   } else {
   13087     index = finger_index + JSFunctionResultCache::kEntrySize;
   13088     if (index == cache_handle->length()) {
   13089       index = JSFunctionResultCache::kEntriesIndex;
   13090     }
   13091   }
   13092 
   13093   ASSERT(index % 2 == 0);
   13094   ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
   13095   ASSERT(index < cache_handle->length());
   13096 
   13097   cache_handle->set(index, *key_handle);
   13098   cache_handle->set(index + 1, *value);
   13099   cache_handle->set_finger_index(index);
   13100 
   13101 #ifdef DEBUG
   13102   if (FLAG_verify_heap) {
   13103     cache_handle->JSFunctionResultCacheVerify();
   13104   }
   13105 #endif
   13106 
   13107   return *value;
   13108 }
   13109 
   13110 
   13111 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewMessageObject) {
   13112   HandleScope scope(isolate);
   13113   CONVERT_ARG_HANDLE_CHECKED(String, type, 0);
   13114   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 1);
   13115   return *isolate->factory()->NewJSMessageObject(
   13116       type,
   13117       arguments,
   13118       0,
   13119       0,
   13120       isolate->factory()->undefined_value(),
   13121       isolate->factory()->undefined_value(),
   13122       isolate->factory()->undefined_value());
   13123 }
   13124 
   13125 
   13126 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetType) {
   13127   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   13128   return message->type();
   13129 }
   13130 
   13131 
   13132 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetArguments) {
   13133   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   13134   return message->arguments();
   13135 }
   13136 
   13137 
   13138 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
   13139   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   13140   return Smi::FromInt(message->start_position());
   13141 }
   13142 
   13143 
   13144 RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
   13145   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
   13146   return message->script();
   13147 }
   13148 
   13149 
   13150 #ifdef DEBUG
   13151 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
   13152 // Exclude the code in release mode.
   13153 RUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
   13154   ASSERT(args.length() == 0);
   13155   HandleScope scope;
   13156 #define COUNT_ENTRY(Name, argc, ressize) + 1
   13157   int entry_count = 0
   13158       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
   13159       INLINE_FUNCTION_LIST(COUNT_ENTRY)
   13160       INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY);
   13161 #undef COUNT_ENTRY
   13162   Factory* factory = isolate->factory();
   13163   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
   13164   int index = 0;
   13165   bool inline_runtime_functions = false;
   13166 #define ADD_ENTRY(Name, argc, ressize)                                       \
   13167   {                                                                          \
   13168     HandleScope inner;                                                       \
   13169     Handle<String> name;                                                     \
   13170     /* Inline runtime functions have an underscore in front of the name. */  \
   13171     if (inline_runtime_functions) {                                          \
   13172       name = factory->NewStringFromAscii(                                    \
   13173           Vector<const char>("_" #Name, StrLength("_" #Name)));              \
   13174     } else {                                                                 \
   13175       name = factory->NewStringFromAscii(                                    \
   13176           Vector<const char>(#Name, StrLength(#Name)));                      \
   13177     }                                                                        \
   13178     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
   13179     pair_elements->set(0, *name);                                            \
   13180     pair_elements->set(1, Smi::FromInt(argc));                               \
   13181     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
   13182     elements->set(index++, *pair);                                           \
   13183   }
   13184   inline_runtime_functions = false;
   13185   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   13186   inline_runtime_functions = true;
   13187   INLINE_FUNCTION_LIST(ADD_ENTRY)
   13188   INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   13189 #undef ADD_ENTRY
   13190   ASSERT_EQ(index, entry_count);
   13191   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
   13192   return *result;
   13193 }
   13194 #endif
   13195 
   13196 
   13197 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
   13198   ASSERT(args.length() == 2);
   13199   CONVERT_ARG_CHECKED(String, format, 0);
   13200   CONVERT_ARG_CHECKED(JSArray, elms, 1);
   13201   String::FlatContent format_content = format->GetFlatContent();
   13202   RUNTIME_ASSERT(format_content.IsAscii());
   13203   Vector<const char> chars = format_content.ToAsciiVector();
   13204   LOGGER->LogRuntime(chars, elms);
   13205   return isolate->heap()->undefined_value();
   13206 }
   13207 
   13208 
   13209 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
   13210   UNREACHABLE();  // implemented as macro in the parser
   13211   return NULL;
   13212 }
   13213 
   13214 
   13215 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
   13216   RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) {     \
   13217     CONVERT_ARG_CHECKED(JSObject, obj, 0);              \
   13218     return isolate->heap()->ToBoolean(obj->Has##Name());  \
   13219   }
   13220 
   13221 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements)
   13222 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
   13223 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
   13224 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
   13225 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
   13226 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
   13227 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
   13228 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
   13229 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
   13230 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
   13231 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
   13232 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
   13233 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
   13234 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
   13235 
   13236 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
   13237 
   13238 
   13239 RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
   13240   ASSERT(args.length() == 2);
   13241   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
   13242   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
   13243   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
   13244 }
   13245 
   13246 // ----------------------------------------------------------------------------
   13247 // Implementation of Runtime
   13248 
   13249 #define F(name, number_of_args, result_size)                             \
   13250   { Runtime::k##name, Runtime::RUNTIME, #name,   \
   13251     FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
   13252 
   13253 
   13254 #define I(name, number_of_args, result_size)                             \
   13255   { Runtime::kInline##name, Runtime::INLINE,     \
   13256     "_" #name, NULL, number_of_args, result_size },
   13257 
   13258 static const Runtime::Function kIntrinsicFunctions[] = {
   13259   RUNTIME_FUNCTION_LIST(F)
   13260   INLINE_FUNCTION_LIST(I)
   13261   INLINE_RUNTIME_FUNCTION_LIST(I)
   13262 };
   13263 
   13264 
   13265 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
   13266                                                        Object* dictionary) {
   13267   ASSERT(Isolate::Current()->heap() == heap);
   13268   ASSERT(dictionary != NULL);
   13269   ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0);
   13270   for (int i = 0; i < kNumFunctions; ++i) {
   13271     Object* name_symbol;
   13272     { MaybeObject* maybe_name_symbol =
   13273           heap->LookupAsciiSymbol(kIntrinsicFunctions[i].name);
   13274       if (!maybe_name_symbol->ToObject(&name_symbol)) return maybe_name_symbol;
   13275     }
   13276     StringDictionary* string_dictionary = StringDictionary::cast(dictionary);
   13277     { MaybeObject* maybe_dictionary = string_dictionary->Add(
   13278           String::cast(name_symbol),
   13279           Smi::FromInt(i),
   13280           PropertyDetails(NONE, NORMAL));
   13281       if (!maybe_dictionary->ToObject(&dictionary)) {
   13282         // Non-recoverable failure.  Calling code must restart heap
   13283         // initialization.
   13284         return maybe_dictionary;
   13285       }
   13286     }
   13287   }
   13288   return dictionary;
   13289 }
   13290 
   13291 
   13292 const Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) {
   13293   Heap* heap = name->GetHeap();
   13294   int entry = heap->intrinsic_function_names()->FindEntry(*name);
   13295   if (entry != kNotFound) {
   13296     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
   13297     int function_index = Smi::cast(smi_index)->value();
   13298     return &(kIntrinsicFunctions[function_index]);
   13299   }
   13300   return NULL;
   13301 }
   13302 
   13303 
   13304 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
   13305   return &(kIntrinsicFunctions[static_cast<int>(id)]);
   13306 }
   13307 
   13308 
   13309 void Runtime::PerformGC(Object* result) {
   13310   Isolate* isolate = Isolate::Current();
   13311   Failure* failure = Failure::cast(result);
   13312   if (failure->IsRetryAfterGC()) {
   13313     if (isolate->heap()->new_space()->AddFreshPage()) {
   13314       return;
   13315     }
   13316 
   13317     // Try to do a garbage collection; ignore it if it fails. The C
   13318     // entry stub will throw an out-of-memory exception in that case.
   13319     isolate->heap()->CollectGarbage(failure->allocation_space(),
   13320                                     "Runtime::PerformGC");
   13321   } else {
   13322     // Handle last resort GC and make sure to allow future allocations
   13323     // to grow the heap without causing GCs (if possible).
   13324     isolate->counters()->gc_last_resort_from_js()->Increment();
   13325     isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
   13326                                        "Runtime::PerformGC");
   13327   }
   13328 }
   13329 
   13330 
   13331 } }  // namespace v8::internal
   13332