Home | History | Annotate | Download | only in runtime
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/runtime/runtime-utils.h"
      6 
      7 #include "src/accessors.h"
      8 #include "src/arguments.h"
      9 #include "src/ast/scopeinfo.h"
     10 #include "src/ast/scopes.h"
     11 #include "src/deoptimizer.h"
     12 #include "src/frames-inl.h"
     13 #include "src/isolate-inl.h"
     14 #include "src/messages.h"
     15 
     16 namespace v8 {
     17 namespace internal {
     18 
     19 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
     20   HandleScope scope(isolate);
     21   THROW_NEW_ERROR_RETURN_FAILURE(
     22       isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name));
     23 }
     24 
     25 
     26 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) {
     27   HandleScope scope(isolate);
     28   THROW_NEW_ERROR_RETURN_FAILURE(isolate,
     29                                  NewTypeError(MessageTemplate::kConstAssign));
     30 }
     31 
     32 
     33 // May throw a RedeclarationError.
     34 static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global,
     35                               Handle<String> name, Handle<Object> value,
     36                               PropertyAttributes attr, bool is_var,
     37                               bool is_const, bool is_function) {
     38   Handle<ScriptContextTable> script_contexts(
     39       global->native_context()->script_context_table());
     40   ScriptContextTable::LookupResult lookup;
     41   if (ScriptContextTable::Lookup(script_contexts, name, &lookup) &&
     42       IsLexicalVariableMode(lookup.mode)) {
     43     return ThrowRedeclarationError(isolate, name);
     44   }
     45 
     46   // Do the lookup own properties only, see ES5 erratum.
     47   LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
     48   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
     49   if (!maybe.IsJust()) return isolate->heap()->exception();
     50 
     51   if (it.IsFound()) {
     52     PropertyAttributes old_attributes = maybe.FromJust();
     53     // The name was declared before; check for conflicting re-declarations.
     54     if (is_const) return ThrowRedeclarationError(isolate, name);
     55 
     56     // Skip var re-declarations.
     57     if (is_var) return isolate->heap()->undefined_value();
     58 
     59     DCHECK(is_function);
     60     if ((old_attributes & DONT_DELETE) != 0) {
     61       // Only allow reconfiguring globals to functions in user code (no
     62       // natives, which are marked as read-only).
     63       DCHECK((attr & READ_ONLY) == 0);
     64 
     65       // Check whether we can reconfigure the existing property into a
     66       // function.
     67       PropertyDetails old_details = it.property_details();
     68       // TODO(verwaest): ACCESSOR_CONSTANT invalidly includes
     69       // ExecutableAccessInfo,
     70       // which are actually data properties, not accessor properties.
     71       if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
     72           old_details.type() == ACCESSOR_CONSTANT) {
     73         return ThrowRedeclarationError(isolate, name);
     74       }
     75       // If the existing property is not configurable, keep its attributes. Do
     76       attr = old_attributes;
     77     }
     78   }
     79 
     80   // Define or redefine own property.
     81   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
     82                                            global, name, value, attr));
     83 
     84   return isolate->heap()->undefined_value();
     85 }
     86 
     87 
     88 RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
     89   HandleScope scope(isolate);
     90   DCHECK_EQ(2, args.length());
     91   Handle<JSGlobalObject> global(isolate->global_object());
     92   Handle<Context> context(isolate->context());
     93 
     94   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0);
     95   CONVERT_SMI_ARG_CHECKED(flags, 1);
     96 
     97   // Traverse the name/value pairs and set the properties.
     98   int length = pairs->length();
     99   for (int i = 0; i < length; i += 2) {
    100     HandleScope scope(isolate);
    101     Handle<String> name(String::cast(pairs->get(i)));
    102     Handle<Object> initial_value(pairs->get(i + 1), isolate);
    103 
    104     // We have to declare a global const property. To capture we only
    105     // assign to it when evaluating the assignment for "const x =
    106     // <expr>" the initial value is the hole.
    107     bool is_var = initial_value->IsUndefined();
    108     bool is_const = initial_value->IsTheHole();
    109     bool is_function = initial_value->IsSharedFunctionInfo();
    110     DCHECK_EQ(1,
    111               BoolToInt(is_var) + BoolToInt(is_const) + BoolToInt(is_function));
    112 
    113     Handle<Object> value;
    114     if (is_function) {
    115       // Copy the function and update its context. Use it as value.
    116       Handle<SharedFunctionInfo> shared =
    117           Handle<SharedFunctionInfo>::cast(initial_value);
    118       Handle<JSFunction> function =
    119           isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
    120                                                                 TENURED);
    121       value = function;
    122     } else {
    123       value = isolate->factory()->undefined_value();
    124     }
    125 
    126     // Compute the property attributes. According to ECMA-262,
    127     // the property must be non-configurable except in eval.
    128     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
    129     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
    130     int attr = NONE;
    131     if (is_const) attr |= READ_ONLY;
    132     if (is_function && is_native) attr |= READ_ONLY;
    133     if (!is_const && !is_eval) attr |= DONT_DELETE;
    134 
    135     Object* result = DeclareGlobals(isolate, global, name, value,
    136                                     static_cast<PropertyAttributes>(attr),
    137                                     is_var, is_const, is_function);
    138     if (isolate->has_pending_exception()) return result;
    139   }
    140 
    141   return isolate->heap()->undefined_value();
    142 }
    143 
    144 
    145 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
    146   HandleScope scope(isolate);
    147   // args[0] == name
    148   // args[1] == language_mode
    149   // args[2] == value (optional)
    150 
    151   // Determine if we need to assign to the variable if it already
    152   // exists (based on the number of arguments).
    153   RUNTIME_ASSERT(args.length() == 3);
    154 
    155   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    156   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 1);
    157   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
    158 
    159   Handle<JSGlobalObject> global(isolate->context()->global_object());
    160   Handle<Object> result;
    161   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    162       isolate, result, Object::SetProperty(global, name, value, language_mode));
    163   return *result;
    164 }
    165 
    166 
    167 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
    168   HandleScope handle_scope(isolate);
    169   // All constants are declared with an initial value. The name
    170   // of the constant is the first argument and the initial value
    171   // is the second.
    172   RUNTIME_ASSERT(args.length() == 2);
    173   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    174   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    175 
    176   Handle<JSGlobalObject> global = isolate->global_object();
    177 
    178   // Lookup the property as own on the global object.
    179   LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
    180   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    181   DCHECK(maybe.IsJust());
    182   PropertyAttributes old_attributes = maybe.FromJust();
    183 
    184   PropertyAttributes attr =
    185       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
    186   // Set the value if the property is either missing, or the property attributes
    187   // allow setting the value without invoking an accessor.
    188   if (it.IsFound()) {
    189     // Ignore if we can't reconfigure the value.
    190     if ((old_attributes & DONT_DELETE) != 0) {
    191       if ((old_attributes & READ_ONLY) != 0 ||
    192           it.state() == LookupIterator::ACCESSOR) {
    193         return *value;
    194       }
    195       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
    196     }
    197   }
    198 
    199   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
    200                                            global, name, value, attr));
    201 
    202   return *value;
    203 }
    204 
    205 
    206 namespace {
    207 
    208 Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name,
    209                           Handle<Object> initial_value,
    210                           PropertyAttributes attr) {
    211   // Declarations are always made in a function, eval or script context, or
    212   // a declaration block scope.
    213   // In the case of eval code, the context passed is the context of the caller,
    214   // which may be some nested context and not the declaration context.
    215   Handle<Context> context_arg(isolate->context(), isolate);
    216   Handle<Context> context(context_arg->declaration_context(), isolate);
    217 
    218   // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
    219   bool is_var = *initial_value == NULL;
    220   bool is_const = initial_value->IsTheHole();
    221   bool is_function = initial_value->IsJSFunction();
    222   DCHECK_EQ(1,
    223             BoolToInt(is_var) + BoolToInt(is_const) + BoolToInt(is_function));
    224 
    225   int index;
    226   PropertyAttributes attributes;
    227   BindingFlags binding_flags;
    228 
    229   if ((attr & EVAL_DECLARED) != 0) {
    230     // Check for a conflict with a lexically scoped variable
    231     context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes,
    232                         &binding_flags);
    233     if (attributes != ABSENT &&
    234         (binding_flags == MUTABLE_CHECK_INITIALIZED ||
    235          binding_flags == IMMUTABLE_CHECK_INITIALIZED ||
    236          binding_flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY)) {
    237       return ThrowRedeclarationError(isolate, name);
    238     }
    239     attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED);
    240   }
    241 
    242   Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index,
    243                                           &attributes, &binding_flags);
    244   if (holder.is_null()) {
    245     // In case of JSProxy, an exception might have been thrown.
    246     if (isolate->has_pending_exception()) return isolate->heap()->exception();
    247   }
    248 
    249   Handle<JSObject> object;
    250   Handle<Object> value =
    251       is_function ? initial_value
    252                   : Handle<Object>::cast(isolate->factory()->undefined_value());
    253 
    254   // TODO(verwaest): This case should probably not be covered by this function,
    255   // but by DeclareGlobals instead.
    256   if (attributes != ABSENT && holder->IsJSGlobalObject()) {
    257     return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
    258                           value, attr, is_var, is_const, is_function);
    259   }
    260   if (context_arg->extension()->IsJSGlobalObject()) {
    261     Handle<JSGlobalObject> global(
    262         JSGlobalObject::cast(context_arg->extension()), isolate);
    263     return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const,
    264                           is_function);
    265   } else if (context->IsScriptContext()) {
    266     DCHECK(context->global_object()->IsJSGlobalObject());
    267     Handle<JSGlobalObject> global(
    268         JSGlobalObject::cast(context->global_object()), isolate);
    269     return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const,
    270                           is_function);
    271   }
    272 
    273   if (attributes != ABSENT) {
    274     // The name was declared before; check for conflicting re-declarations.
    275     if (is_const || (attributes & READ_ONLY) != 0) {
    276       return ThrowRedeclarationError(isolate, name);
    277     }
    278 
    279     // Skip var re-declarations.
    280     if (is_var) return isolate->heap()->undefined_value();
    281 
    282     DCHECK(is_function);
    283     if (index != Context::kNotFound) {
    284       DCHECK(holder.is_identical_to(context));
    285       context->set(index, *initial_value);
    286       return isolate->heap()->undefined_value();
    287     }
    288 
    289     object = Handle<JSObject>::cast(holder);
    290 
    291   } else if (context->has_extension()) {
    292     // Sloppy varblock contexts might not have an extension object yet,
    293     // in which case their extension is a ScopeInfo.
    294     if (context->extension()->IsScopeInfo()) {
    295       DCHECK(context->IsBlockContext());
    296       object = isolate->factory()->NewJSObject(
    297           isolate->context_extension_function());
    298       Handle<HeapObject> extension =
    299           isolate->factory()->NewSloppyBlockWithEvalContextExtension(
    300               handle(context->scope_info()), object);
    301       context->set_extension(*extension);
    302     } else {
    303       object = handle(context->extension_object(), isolate);
    304     }
    305     DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
    306   } else {
    307     DCHECK(context->IsFunctionContext());
    308     object =
    309         isolate->factory()->NewJSObject(isolate->context_extension_function());
    310     context->set_extension(*object);
    311   }
    312 
    313   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
    314                                            object, name, value, attr));
    315 
    316   return isolate->heap()->undefined_value();
    317 }
    318 
    319 }  // namespace
    320 
    321 
    322 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
    323   HandleScope scope(isolate);
    324   DCHECK_EQ(3, args.length());
    325   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    326   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 1);
    327   CONVERT_ARG_HANDLE_CHECKED(Smi, property_attributes, 2);
    328 
    329   PropertyAttributes attributes =
    330       static_cast<PropertyAttributes>(property_attributes->value());
    331   return DeclareLookupSlot(isolate, name, initial_value, attributes);
    332 }
    333 
    334 
    335 RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
    336   HandleScope scope(isolate);
    337   DCHECK(args.length() == 3);
    338 
    339   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
    340   DCHECK(!value->IsTheHole());
    341   // Initializations are always done in a function or native context.
    342   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
    343   Handle<Context> context(context_arg->declaration_context());
    344   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
    345 
    346   int index;
    347   PropertyAttributes attributes;
    348   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
    349   BindingFlags binding_flags;
    350   Handle<Object> holder =
    351       context->Lookup(name, flags, &index, &attributes, &binding_flags);
    352   if (holder.is_null()) {
    353     // In case of JSProxy, an exception might have been thrown.
    354     if (isolate->has_pending_exception()) return isolate->heap()->exception();
    355   }
    356 
    357   if (index != Context::kNotFound) {
    358     DCHECK(holder->IsContext());
    359     // Property was found in a context.  Perform the assignment if the constant
    360     // was uninitialized.
    361     Handle<Context> context = Handle<Context>::cast(holder);
    362     DCHECK((attributes & READ_ONLY) != 0);
    363     if (context->get(index)->IsTheHole()) context->set(index, *value);
    364     return *value;
    365   }
    366 
    367   PropertyAttributes attr =
    368       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
    369 
    370   // Strict mode handling not needed (legacy const is disallowed in strict
    371   // mode).
    372 
    373   // The declared const was configurable, and may have been deleted in the
    374   // meanwhile. If so, re-introduce the variable in the context extension.
    375   if (attributes == ABSENT) {
    376     Handle<Context> declaration_context(context_arg->declaration_context());
    377     if (declaration_context->IsScriptContext()) {
    378       holder = handle(declaration_context->global_object(), isolate);
    379     } else {
    380       holder = handle(declaration_context->extension_object(), isolate);
    381       DCHECK(!holder.is_null());
    382     }
    383     CHECK(holder->IsJSObject());
    384   } else {
    385     // For JSContextExtensionObjects, the initializer can be run multiple times
    386     // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
    387     // first assignment should go through. For JSGlobalObjects, additionally any
    388     // code can run in between that modifies the declared property.
    389     DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
    390 
    391     LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
    392     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    393     if (!maybe.IsJust()) return isolate->heap()->exception();
    394     PropertyAttributes old_attributes = maybe.FromJust();
    395 
    396     // Ignore if we can't reconfigure the value.
    397     if ((old_attributes & DONT_DELETE) != 0) {
    398       if ((old_attributes & READ_ONLY) != 0 ||
    399           it.state() == LookupIterator::ACCESSOR) {
    400         return *value;
    401       }
    402       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
    403     }
    404   }
    405 
    406   RETURN_FAILURE_ON_EXCEPTION(
    407       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
    408                    Handle<JSObject>::cast(holder), name, value, attr));
    409 
    410   return *value;
    411 }
    412 
    413 
    414 namespace {
    415 
    416 // Find the arguments of the JavaScript function invocation that called
    417 // into C++ code. Collect these in a newly allocated array of handles (possibly
    418 // prefixed by a number of empty handles).
    419 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate,
    420                                                            int prefix_argc,
    421                                                            int* total_argc) {
    422   // Find frame containing arguments passed to the caller.
    423   JavaScriptFrameIterator it(isolate);
    424   JavaScriptFrame* frame = it.frame();
    425   List<JSFunction*> functions(2);
    426   frame->GetFunctions(&functions);
    427   if (functions.length() > 1) {
    428     int inlined_jsframe_index = functions.length() - 1;
    429     TranslatedState translated_values(frame);
    430     translated_values.Prepare(false, frame->fp());
    431 
    432     int argument_count = 0;
    433     TranslatedFrame* translated_frame =
    434         translated_values.GetArgumentsInfoFromJSFrameIndex(
    435             inlined_jsframe_index, &argument_count);
    436     TranslatedFrame::iterator iter = translated_frame->begin();
    437 
    438     // Skip the function.
    439     iter++;
    440 
    441     // Skip the receiver.
    442     iter++;
    443     argument_count--;
    444 
    445     *total_argc = prefix_argc + argument_count;
    446     base::SmartArrayPointer<Handle<Object>> param_data(
    447         NewArray<Handle<Object>>(*total_argc));
    448     bool should_deoptimize = false;
    449     for (int i = 0; i < argument_count; i++) {
    450       should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
    451       Handle<Object> value = iter->GetValue();
    452       param_data[prefix_argc + i] = value;
    453       iter++;
    454     }
    455 
    456     if (should_deoptimize) {
    457       translated_values.StoreMaterializedValuesAndDeopt();
    458     }
    459 
    460     return param_data;
    461   } else {
    462     it.AdvanceToArgumentsFrame();
    463     frame = it.frame();
    464     int args_count = frame->ComputeParametersCount();
    465 
    466     *total_argc = prefix_argc + args_count;
    467     base::SmartArrayPointer<Handle<Object>> param_data(
    468         NewArray<Handle<Object>>(*total_argc));
    469     for (int i = 0; i < args_count; i++) {
    470       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
    471       param_data[prefix_argc + i] = val;
    472     }
    473     return param_data;
    474   }
    475 }
    476 
    477 
    478 template <typename T>
    479 Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
    480                                     T parameters, int argument_count) {
    481   CHECK(!IsSubclassConstructor(callee->shared()->kind()));
    482   DCHECK(callee->shared()->has_simple_parameters());
    483   Handle<JSObject> result =
    484       isolate->factory()->NewArgumentsObject(callee, argument_count);
    485 
    486   // Allocate the elements if needed.
    487   int parameter_count = callee->shared()->internal_formal_parameter_count();
    488   if (argument_count > 0) {
    489     if (parameter_count > 0) {
    490       int mapped_count = Min(argument_count, parameter_count);
    491       Handle<FixedArray> parameter_map =
    492           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
    493       parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map());
    494       result->set_map(isolate->native_context()->fast_aliased_arguments_map());
    495       result->set_elements(*parameter_map);
    496 
    497       // Store the context and the arguments array at the beginning of the
    498       // parameter map.
    499       Handle<Context> context(isolate->context());
    500       Handle<FixedArray> arguments =
    501           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
    502       parameter_map->set(0, *context);
    503       parameter_map->set(1, *arguments);
    504 
    505       // Loop over the actual parameters backwards.
    506       int index = argument_count - 1;
    507       while (index >= mapped_count) {
    508         // These go directly in the arguments array and have no
    509         // corresponding slot in the parameter map.
    510         arguments->set(index, parameters[index]);
    511         --index;
    512       }
    513 
    514       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
    515       while (index >= 0) {
    516         // Detect duplicate names to the right in the parameter list.
    517         Handle<String> name(scope_info->ParameterName(index));
    518         int context_local_count = scope_info->ContextLocalCount();
    519         bool duplicate = false;
    520         for (int j = index + 1; j < parameter_count; ++j) {
    521           if (scope_info->ParameterName(j) == *name) {
    522             duplicate = true;
    523             break;
    524           }
    525         }
    526 
    527         if (duplicate) {
    528           // This goes directly in the arguments array with a hole in the
    529           // parameter map.
    530           arguments->set(index, parameters[index]);
    531           parameter_map->set_the_hole(index + 2);
    532         } else {
    533           // The context index goes in the parameter map with a hole in the
    534           // arguments array.
    535           int context_index = -1;
    536           for (int j = 0; j < context_local_count; ++j) {
    537             if (scope_info->ContextLocalName(j) == *name) {
    538               context_index = j;
    539               break;
    540             }
    541           }
    542 
    543           DCHECK(context_index >= 0);
    544           arguments->set_the_hole(index);
    545           parameter_map->set(
    546               index + 2,
    547               Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index));
    548         }
    549 
    550         --index;
    551       }
    552     } else {
    553       // If there is no aliasing, the arguments object elements are not
    554       // special in any way.
    555       Handle<FixedArray> elements =
    556           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
    557       result->set_elements(*elements);
    558       for (int i = 0; i < argument_count; ++i) {
    559         elements->set(i, parameters[i]);
    560       }
    561     }
    562   }
    563   return result;
    564 }
    565 
    566 
    567 template <typename T>
    568 Handle<JSObject> NewStrictArguments(Isolate* isolate, Handle<JSFunction> callee,
    569                                     T parameters, int argument_count) {
    570   Handle<JSObject> result =
    571       isolate->factory()->NewArgumentsObject(callee, argument_count);
    572 
    573   if (argument_count > 0) {
    574     Handle<FixedArray> array =
    575         isolate->factory()->NewUninitializedFixedArray(argument_count);
    576     DisallowHeapAllocation no_gc;
    577     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
    578     for (int i = 0; i < argument_count; i++) {
    579       array->set(i, parameters[i], mode);
    580     }
    581     result->set_elements(*array);
    582   }
    583   return result;
    584 }
    585 
    586 
    587 template <typename T>
    588 Handle<JSObject> NewRestArguments(Isolate* isolate, Handle<JSFunction> callee,
    589                                   T parameters, int argument_count,
    590                                   int start_index) {
    591   int num_elements = std::max(0, argument_count - start_index);
    592   Handle<JSObject> result = isolate->factory()->NewJSArray(
    593       FAST_ELEMENTS, num_elements, num_elements, Strength::WEAK,
    594       DONT_INITIALIZE_ARRAY_ELEMENTS);
    595   {
    596     DisallowHeapAllocation no_gc;
    597     FixedArray* elements = FixedArray::cast(result->elements());
    598     WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
    599     for (int i = 0; i < num_elements; i++) {
    600       elements->set(i, parameters[i + start_index], mode);
    601     }
    602   }
    603   return result;
    604 }
    605 
    606 
    607 class HandleArguments BASE_EMBEDDED {
    608  public:
    609   explicit HandleArguments(Handle<Object>* array) : array_(array) {}
    610   Object* operator[](int index) { return *array_[index]; }
    611 
    612  private:
    613   Handle<Object>* array_;
    614 };
    615 
    616 
    617 class ParameterArguments BASE_EMBEDDED {
    618  public:
    619   explicit ParameterArguments(Object** parameters) : parameters_(parameters) {}
    620   Object*& operator[](int index) { return *(parameters_ - index - 1); }
    621 
    622  private:
    623   Object** parameters_;
    624 };
    625 
    626 }  // namespace
    627 
    628 
    629 RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) {
    630   HandleScope scope(isolate);
    631   DCHECK(args.length() == 1);
    632   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
    633   // This generic runtime function can also be used when the caller has been
    634   // inlined, we use the slow but accurate {GetCallerArguments}.
    635   int argument_count = 0;
    636   base::SmartArrayPointer<Handle<Object>> arguments =
    637       GetCallerArguments(isolate, 0, &argument_count);
    638   HandleArguments argument_getter(arguments.get());
    639   return *NewSloppyArguments(isolate, callee, argument_getter, argument_count);
    640 }
    641 
    642 
    643 RUNTIME_FUNCTION(Runtime_NewStrictArguments_Generic) {
    644   HandleScope scope(isolate);
    645   DCHECK(args.length() == 1);
    646   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
    647   // This generic runtime function can also be used when the caller has been
    648   // inlined, we use the slow but accurate {GetCallerArguments}.
    649   int argument_count = 0;
    650   base::SmartArrayPointer<Handle<Object>> arguments =
    651       GetCallerArguments(isolate, 0, &argument_count);
    652   HandleArguments argument_getter(arguments.get());
    653   return *NewStrictArguments(isolate, callee, argument_getter, argument_count);
    654 }
    655 
    656 
    657 RUNTIME_FUNCTION(Runtime_NewRestArguments_Generic) {
    658   HandleScope scope(isolate);
    659   DCHECK(args.length() == 2);
    660   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
    661   CONVERT_SMI_ARG_CHECKED(start_index, 1);
    662   // This generic runtime function can also be used when the caller has been
    663   // inlined, we use the slow but accurate {GetCallerArguments}.
    664   int argument_count = 0;
    665   base::SmartArrayPointer<Handle<Object>> arguments =
    666       GetCallerArguments(isolate, 0, &argument_count);
    667   HandleArguments argument_getter(arguments.get());
    668   return *NewRestArguments(isolate, callee, argument_getter, argument_count,
    669                            start_index);
    670 }
    671 
    672 
    673 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
    674   HandleScope scope(isolate);
    675   DCHECK(args.length() == 3);
    676   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
    677   Object** parameters = reinterpret_cast<Object**>(args[1]);
    678   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
    679 #ifdef DEBUG
    680   // This runtime function does not materialize the correct arguments when the
    681   // caller has been inlined, better make sure we are not hitting that case.
    682   JavaScriptFrameIterator it(isolate);
    683   DCHECK(!it.frame()->HasInlinedFrames());
    684 #endif  // DEBUG
    685   ParameterArguments argument_getter(parameters);
    686   return *NewSloppyArguments(isolate, callee, argument_getter, argument_count);
    687 }
    688 
    689 
    690 RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
    691   HandleScope scope(isolate);
    692   DCHECK(args.length() == 3);
    693   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
    694   Object** parameters = reinterpret_cast<Object**>(args[1]);
    695   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
    696 #ifdef DEBUG
    697   // This runtime function does not materialize the correct arguments when the
    698   // caller has been inlined, better make sure we are not hitting that case.
    699   JavaScriptFrameIterator it(isolate);
    700   DCHECK(!it.frame()->HasInlinedFrames());
    701 #endif  // DEBUG
    702   ParameterArguments argument_getter(parameters);
    703   return *NewStrictArguments(isolate, callee, argument_getter, argument_count);
    704 }
    705 
    706 
    707 RUNTIME_FUNCTION(Runtime_NewRestParam) {
    708   HandleScope scope(isolate);
    709   DCHECK(args.length() == 3);
    710   CONVERT_SMI_ARG_CHECKED(num_params, 0);
    711   Object** parameters = reinterpret_cast<Object**>(args[1]);
    712   CONVERT_SMI_ARG_CHECKED(rest_index, 2);
    713 #ifdef DEBUG
    714   // This runtime function does not materialize the correct arguments when the
    715   // caller has been inlined, better make sure we are not hitting that case.
    716   JavaScriptFrameIterator it(isolate);
    717   DCHECK(!it.frame()->HasInlinedFrames());
    718 #endif  // DEBUG
    719   Handle<JSFunction> callee;
    720   ParameterArguments argument_getter(parameters);
    721   return *NewRestArguments(isolate, callee, argument_getter, num_params,
    722                            rest_index);
    723 }
    724 
    725 
    726 RUNTIME_FUNCTION(Runtime_NewClosure) {
    727   HandleScope scope(isolate);
    728   DCHECK_EQ(1, args.length());
    729   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
    730   Handle<Context> context(isolate->context(), isolate);
    731   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
    732                                                                 NOT_TENURED);
    733 }
    734 
    735 
    736 RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) {
    737   HandleScope scope(isolate);
    738   DCHECK_EQ(1, args.length());
    739   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
    740   Handle<Context> context(isolate->context(), isolate);
    741   // The caller ensures that we pretenure closures that are assigned
    742   // directly to properties.
    743   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
    744                                                                 TENURED);
    745 }
    746 
    747 static Object* FindNameClash(Handle<ScopeInfo> scope_info,
    748                              Handle<JSGlobalObject> global_object,
    749                              Handle<ScriptContextTable> script_context) {
    750   Isolate* isolate = scope_info->GetIsolate();
    751   for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
    752     Handle<String> name(scope_info->ContextLocalName(var));
    753     VariableMode mode = scope_info->ContextLocalMode(var);
    754     ScriptContextTable::LookupResult lookup;
    755     if (ScriptContextTable::Lookup(script_context, name, &lookup)) {
    756       if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
    757         return ThrowRedeclarationError(isolate, name);
    758       }
    759     }
    760 
    761     if (IsLexicalVariableMode(mode)) {
    762       LookupIterator it(global_object, name,
    763                         LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
    764       Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
    765       if (!maybe.IsJust()) return isolate->heap()->exception();
    766       if ((maybe.FromJust() & DONT_DELETE) != 0) {
    767         return ThrowRedeclarationError(isolate, name);
    768       }
    769 
    770       JSGlobalObject::InvalidatePropertyCell(global_object, name);
    771     }
    772   }
    773   return isolate->heap()->undefined_value();
    774 }
    775 
    776 
    777 RUNTIME_FUNCTION(Runtime_NewScriptContext) {
    778   HandleScope scope(isolate);
    779   DCHECK(args.length() == 2);
    780 
    781   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
    782   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
    783   Handle<JSGlobalObject> global_object(function->context()->global_object());
    784   Handle<Context> native_context(global_object->native_context());
    785   Handle<ScriptContextTable> script_context_table(
    786       native_context->script_context_table());
    787 
    788   Object* name_clash_result =
    789       FindNameClash(scope_info, global_object, script_context_table);
    790   if (isolate->has_pending_exception()) return name_clash_result;
    791 
    792   // Script contexts have a canonical empty function as their closure, not the
    793   // anonymous closure containing the global code.  See
    794   // FullCodeGenerator::PushFunctionArgumentForContextAllocation.
    795   Handle<JSFunction> closure(
    796       function->shared()->IsBuiltin() ? *function : native_context->closure());
    797   Handle<Context> result =
    798       isolate->factory()->NewScriptContext(closure, scope_info);
    799 
    800   result->InitializeGlobalSlots();
    801 
    802   DCHECK(function->context() == isolate->context());
    803   DCHECK(*global_object == result->global_object());
    804 
    805   Handle<ScriptContextTable> new_script_context_table =
    806       ScriptContextTable::Extend(script_context_table, result);
    807   native_context->set_script_context_table(*new_script_context_table);
    808   return *result;
    809 }
    810 
    811 
    812 RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
    813   HandleScope scope(isolate);
    814   DCHECK(args.length() == 1);
    815 
    816   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
    817 
    818   DCHECK(function->context() == isolate->context());
    819   int length = function->shared()->scope_info()->ContextLength();
    820   return *isolate->factory()->NewFunctionContext(length, function);
    821 }
    822 
    823 
    824 RUNTIME_FUNCTION(Runtime_PushWithContext) {
    825   HandleScope scope(isolate);
    826   DCHECK_EQ(2, args.length());
    827   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, extension_object, 0);
    828   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
    829   Handle<Context> current(isolate->context());
    830   Handle<Context> context =
    831       isolate->factory()->NewWithContext(function, current, extension_object);
    832   isolate->set_context(*context);
    833   return *context;
    834 }
    835 
    836 
    837 RUNTIME_FUNCTION(Runtime_PushCatchContext) {
    838   HandleScope scope(isolate);
    839   DCHECK_EQ(3, args.length());
    840   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    841   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
    842   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
    843   Handle<Context> current(isolate->context());
    844   Handle<Context> context = isolate->factory()->NewCatchContext(
    845       function, current, name, thrown_object);
    846   isolate->set_context(*context);
    847   return *context;
    848 }
    849 
    850 
    851 RUNTIME_FUNCTION(Runtime_PushBlockContext) {
    852   HandleScope scope(isolate);
    853   DCHECK_EQ(2, args.length());
    854   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
    855   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
    856   Handle<Context> current(isolate->context());
    857   Handle<Context> context =
    858       isolate->factory()->NewBlockContext(function, current, scope_info);
    859   isolate->set_context(*context);
    860   return *context;
    861 }
    862 
    863 
    864 RUNTIME_FUNCTION(Runtime_IsJSModule) {
    865   SealHandleScope shs(isolate);
    866   DCHECK(args.length() == 1);
    867   CONVERT_ARG_CHECKED(Object, obj, 0);
    868   return isolate->heap()->ToBoolean(obj->IsJSModule());
    869 }
    870 
    871 
    872 RUNTIME_FUNCTION(Runtime_PushModuleContext) {
    873   SealHandleScope shs(isolate);
    874   DCHECK(args.length() == 2);
    875   CONVERT_SMI_ARG_CHECKED(index, 0);
    876 
    877   if (!args[1]->IsScopeInfo()) {
    878     // Module already initialized. Find hosting context and retrieve context.
    879     Context* host = Context::cast(isolate->context())->script_context();
    880     Context* context = Context::cast(host->get(index));
    881     DCHECK(context->previous() == isolate->context());
    882     isolate->set_context(context);
    883     return context;
    884   }
    885 
    886   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
    887 
    888   // Allocate module context.
    889   HandleScope scope(isolate);
    890   Factory* factory = isolate->factory();
    891   Handle<Context> context = factory->NewModuleContext(scope_info);
    892   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
    893   context->set_module(*module);
    894   Context* previous = isolate->context();
    895   context->set_previous(previous);
    896   context->set_closure(previous->closure());
    897   context->set_native_context(previous->native_context());
    898   isolate->set_context(*context);
    899 
    900   // Find hosting scope and initialize internal variable holding module there.
    901   previous->script_context()->set(index, *context);
    902 
    903   return *context;
    904 }
    905 
    906 
    907 RUNTIME_FUNCTION(Runtime_DeclareModules) {
    908   HandleScope scope(isolate);
    909   DCHECK(args.length() == 1);
    910   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
    911   Context* host_context = isolate->context();
    912 
    913   for (int i = 0; i < descriptions->length(); ++i) {
    914     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
    915     int host_index = description->host_index();
    916     Handle<Context> context(Context::cast(host_context->get(host_index)));
    917     Handle<JSModule> module(context->module());
    918 
    919     for (int j = 0; j < description->length(); ++j) {
    920       Handle<String> name(description->name(j));
    921       VariableMode mode = description->mode(j);
    922       int index = description->index(j);
    923       switch (mode) {
    924         case VAR:
    925         case LET:
    926         case CONST:
    927         case CONST_LEGACY:
    928         case IMPORT: {
    929           PropertyAttributes attr =
    930               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
    931           Handle<AccessorInfo> info =
    932               Accessors::MakeModuleExport(name, index, attr);
    933           Handle<Object> result =
    934               JSObject::SetAccessor(module, info).ToHandleChecked();
    935           DCHECK(!result->IsUndefined());
    936           USE(result);
    937           break;
    938         }
    939         case TEMPORARY:
    940         case DYNAMIC:
    941         case DYNAMIC_GLOBAL:
    942         case DYNAMIC_LOCAL:
    943           UNREACHABLE();
    944       }
    945     }
    946 
    947     if (JSObject::PreventExtensions(module, Object::THROW_ON_ERROR)
    948             .IsNothing()) {
    949       DCHECK(false);
    950     }
    951   }
    952 
    953   DCHECK(!isolate->has_pending_exception());
    954   return isolate->heap()->undefined_value();
    955 }
    956 
    957 
    958 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
    959   HandleScope scope(isolate);
    960   DCHECK(args.length() == 2);
    961 
    962   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
    963   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
    964 
    965   int index;
    966   PropertyAttributes attributes;
    967   ContextLookupFlags flags = FOLLOW_CHAINS;
    968   BindingFlags binding_flags;
    969   Handle<Object> holder =
    970       context->Lookup(name, flags, &index, &attributes, &binding_flags);
    971 
    972   // If the slot was not found the result is true.
    973   if (holder.is_null()) {
    974     // In case of JSProxy, an exception might have been thrown.
    975     if (isolate->has_pending_exception()) return isolate->heap()->exception();
    976     return isolate->heap()->true_value();
    977   }
    978 
    979   // If the slot was found in a context, it should be DONT_DELETE.
    980   if (holder->IsContext()) {
    981     return isolate->heap()->false_value();
    982   }
    983 
    984   // The slot was found in a JSReceiver, either a context extension object,
    985   // the global object, or the subject of a with.  Try to delete it
    986   // (respecting DONT_DELETE).
    987   Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
    988   Maybe<bool> result = JSReceiver::DeleteProperty(object, name);
    989   MAYBE_RETURN(result, isolate->heap()->exception());
    990   return isolate->heap()->ToBoolean(result.FromJust());
    991 }
    992 
    993 
    994 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) {
    995   DCHECK(!holder->IsJSGlobalObject());
    996 
    997   // If the holder isn't a context extension object, we just return it
    998   // as the receiver. This allows arguments objects to be used as
    999   // receivers, but only if they are put in the context scope chain
   1000   // explicitly via a with-statement.
   1001   if (holder->map()->instance_type() != JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
   1002     return holder;
   1003   }
   1004   // Fall back to using the global object as the implicit receiver if
   1005   // the property turns out to be a local variable allocated in a
   1006   // context extension object - introduced via eval.
   1007   return isolate->heap()->undefined_value();
   1008 }
   1009 
   1010 
   1011 static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
   1012                                        bool throw_error) {
   1013   HandleScope scope(isolate);
   1014   DCHECK_EQ(2, args.length());
   1015 
   1016   if (!args[0]->IsContext() || !args[1]->IsString()) {
   1017     return MakePair(isolate->ThrowIllegalOperation(), NULL);
   1018   }
   1019   Handle<Context> context = args.at<Context>(0);
   1020   Handle<String> name = args.at<String>(1);
   1021 
   1022   int index;
   1023   PropertyAttributes attributes;
   1024   ContextLookupFlags flags = FOLLOW_CHAINS;
   1025   BindingFlags binding_flags;
   1026   Handle<Object> holder =
   1027       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   1028   if (isolate->has_pending_exception()) {
   1029     return MakePair(isolate->heap()->exception(), NULL);
   1030   }
   1031 
   1032   if (index != Context::kNotFound) {
   1033     DCHECK(holder->IsContext());
   1034     // If the "property" we were looking for is a local variable, the
   1035     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
   1036     Handle<Object> receiver = isolate->factory()->undefined_value();
   1037     Object* value = Context::cast(*holder)->get(index);
   1038     // Check for uninitialized bindings.
   1039     switch (binding_flags) {
   1040       case MUTABLE_CHECK_INITIALIZED:
   1041       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
   1042         if (value->IsTheHole()) {
   1043           Handle<Object> error = isolate->factory()->NewReferenceError(
   1044               MessageTemplate::kNotDefined, name);
   1045           isolate->Throw(*error);
   1046           return MakePair(isolate->heap()->exception(), NULL);
   1047         }
   1048       // FALLTHROUGH
   1049       case MUTABLE_IS_INITIALIZED:
   1050       case IMMUTABLE_IS_INITIALIZED:
   1051       case IMMUTABLE_IS_INITIALIZED_HARMONY:
   1052         DCHECK(!value->IsTheHole());
   1053         return MakePair(value, *receiver);
   1054       case IMMUTABLE_CHECK_INITIALIZED:
   1055         if (value->IsTheHole()) {
   1056           DCHECK((attributes & READ_ONLY) != 0);
   1057           value = isolate->heap()->undefined_value();
   1058         }
   1059         return MakePair(value, *receiver);
   1060       case MISSING_BINDING:
   1061         UNREACHABLE();
   1062         return MakePair(NULL, NULL);
   1063     }
   1064   }
   1065 
   1066   // Otherwise, if the slot was found the holder is a context extension
   1067   // object, subject of a with, or a global object.  We read the named
   1068   // property from it.
   1069   if (!holder.is_null()) {
   1070     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
   1071     // GetProperty below can cause GC.
   1072     Handle<Object> receiver_handle(
   1073         object->IsJSGlobalObject()
   1074             ? Object::cast(isolate->heap()->undefined_value())
   1075             : object->IsJSProxy() ? static_cast<Object*>(*object)
   1076                                   : ComputeReceiverForNonGlobal(
   1077                                         isolate, JSObject::cast(*object)),
   1078         isolate);
   1079 
   1080     // No need to unhole the value here.  This is taken care of by the
   1081     // GetProperty function.
   1082     Handle<Object> value;
   1083     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
   1084         isolate, value, Object::GetProperty(object, name),
   1085         MakePair(isolate->heap()->exception(), NULL));
   1086     return MakePair(*value, *receiver_handle);
   1087   }
   1088 
   1089   if (throw_error) {
   1090     // The property doesn't exist - throw exception.
   1091     Handle<Object> error = isolate->factory()->NewReferenceError(
   1092         MessageTemplate::kNotDefined, name);
   1093     isolate->Throw(*error);
   1094     return MakePair(isolate->heap()->exception(), NULL);
   1095   } else {
   1096     // The property doesn't exist - return undefined.
   1097     return MakePair(isolate->heap()->undefined_value(),
   1098                     isolate->heap()->undefined_value());
   1099   }
   1100 }
   1101 
   1102 
   1103 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) {
   1104   return LoadLookupSlotHelper(args, isolate, true);
   1105 }
   1106 
   1107 
   1108 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) {
   1109   return LoadLookupSlotHelper(args, isolate, false);
   1110 }
   1111 
   1112 
   1113 RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
   1114   HandleScope scope(isolate);
   1115   DCHECK(args.length() == 4);
   1116 
   1117   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
   1118   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   1119   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
   1120   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
   1121 
   1122   int index;
   1123   PropertyAttributes attributes;
   1124   ContextLookupFlags flags = FOLLOW_CHAINS;
   1125   BindingFlags binding_flags;
   1126   Handle<Object> holder =
   1127       context->Lookup(name, flags, &index, &attributes, &binding_flags);
   1128   if (holder.is_null()) {
   1129     // In case of JSProxy, an exception might have been thrown.
   1130     if (isolate->has_pending_exception()) return isolate->heap()->exception();
   1131   }
   1132 
   1133   // The property was found in a context slot.
   1134   if (index != Context::kNotFound) {
   1135     if ((binding_flags == MUTABLE_CHECK_INITIALIZED ||
   1136          binding_flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY) &&
   1137         Handle<Context>::cast(holder)->is_the_hole(index)) {
   1138       THROW_NEW_ERROR_RETURN_FAILURE(
   1139           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
   1140     }
   1141     if ((attributes & READ_ONLY) == 0) {
   1142       Handle<Context>::cast(holder)->set(index, *value);
   1143     } else if (is_strict(language_mode)) {
   1144       // Setting read only property in strict mode.
   1145       THROW_NEW_ERROR_RETURN_FAILURE(
   1146           isolate, NewTypeError(MessageTemplate::kStrictCannotAssign, name));
   1147     }
   1148     return *value;
   1149   }
   1150 
   1151   // Slow case: The property is not in a context slot.  It is either in a
   1152   // context extension object, a property of the subject of a with, or a
   1153   // property of the global object.
   1154   Handle<JSReceiver> object;
   1155   if (attributes != ABSENT) {
   1156     // The property exists on the holder.
   1157     object = Handle<JSReceiver>::cast(holder);
   1158   } else if (is_strict(language_mode)) {
   1159     // If absent in strict mode: throw.
   1160     THROW_NEW_ERROR_RETURN_FAILURE(
   1161         isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
   1162   } else {
   1163     // If absent in sloppy mode: add the property to the global object.
   1164     object = Handle<JSReceiver>(context->global_object());
   1165   }
   1166 
   1167   RETURN_FAILURE_ON_EXCEPTION(
   1168       isolate, Object::SetProperty(object, name, value, language_mode));
   1169 
   1170   return *value;
   1171 }
   1172 
   1173 
   1174 RUNTIME_FUNCTION(Runtime_ArgumentsLength) {
   1175   HandleScope scope(isolate);
   1176   DCHECK(args.length() == 0);
   1177   int argument_count = 0;
   1178   GetCallerArguments(isolate, 0, &argument_count);
   1179   return Smi::FromInt(argument_count);
   1180 }
   1181 
   1182 
   1183 RUNTIME_FUNCTION(Runtime_Arguments) {
   1184   HandleScope scope(isolate);
   1185   DCHECK(args.length() == 1);
   1186   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
   1187 
   1188   // Determine the actual arguments passed to the function.
   1189   int argument_count_signed = 0;
   1190   base::SmartArrayPointer<Handle<Object>> arguments =
   1191       GetCallerArguments(isolate, 0, &argument_count_signed);
   1192   const uint32_t argument_count = argument_count_signed;
   1193 
   1194   // Try to convert the key to an index. If successful and within
   1195   // index return the the argument from the frame.
   1196   uint32_t index = 0;
   1197   if (raw_key->ToArrayIndex(&index) && index < argument_count) {
   1198     return *arguments[index];
   1199   }
   1200 
   1201   if (raw_key->IsSymbol()) {
   1202     Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
   1203     if (Name::Equals(symbol, isolate->factory()->iterator_symbol())) {
   1204       return isolate->native_context()->array_values_iterator();
   1205     }
   1206     // Lookup in the initial Object.prototype object.
   1207     Handle<Object> result;
   1208     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1209         isolate, result,
   1210         Object::GetProperty(isolate->initial_object_prototype(),
   1211                             Handle<Symbol>::cast(raw_key)));
   1212     return *result;
   1213   }
   1214 
   1215   // Convert the key to a string.
   1216   Handle<Object> converted;
   1217   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted,
   1218                                      Object::ToString(isolate, raw_key));
   1219   Handle<String> key = Handle<String>::cast(converted);
   1220 
   1221   // Try to convert the string key into an array index.
   1222   if (key->AsArrayIndex(&index)) {
   1223     if (index < argument_count) {
   1224       return *arguments[index];
   1225     } else {
   1226       Handle<Object> initial_prototype(isolate->initial_object_prototype());
   1227       Handle<Object> result;
   1228       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1229           isolate, result,
   1230           Object::GetElement(isolate, initial_prototype, index));
   1231       return *result;
   1232     }
   1233   }
   1234 
   1235   // Handle special arguments properties.
   1236   if (String::Equals(isolate->factory()->length_string(), key)) {
   1237     return Smi::FromInt(argument_count);
   1238   }
   1239   if (String::Equals(isolate->factory()->callee_string(), key)) {
   1240     JavaScriptFrameIterator it(isolate);
   1241     JSFunction* function = it.frame()->function();
   1242     if (is_strict(function->shared()->language_mode())) {
   1243       THROW_NEW_ERROR_RETURN_FAILURE(
   1244           isolate, NewTypeError(MessageTemplate::kStrictPoisonPill));
   1245     }
   1246     return function;
   1247   }
   1248 
   1249   // Lookup in the initial Object.prototype object.
   1250   Handle<Object> result;
   1251   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1252       isolate, result,
   1253       Object::GetProperty(isolate->initial_object_prototype(), key));
   1254   return *result;
   1255 }
   1256 }  // namespace internal
   1257 }  // namespace v8
   1258