LCOV - code coverage report
Current view: top level - src/runtime - runtime-scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 360 392 91.8 %
Date: 2017-10-20 Functions: 35 62 56.5 %

          Line data    Source code
       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 <memory>
       8             : 
       9             : #include "src/accessors.h"
      10             : #include "src/arguments.h"
      11             : #include "src/ast/scopes.h"
      12             : #include "src/deoptimizer.h"
      13             : #include "src/frames-inl.h"
      14             : #include "src/isolate-inl.h"
      15             : #include "src/messages.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20       47492 : RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) {
      21       23746 :   HandleScope scope(isolate);
      22       47492 :   THROW_NEW_ERROR_RETURN_FAILURE(isolate,
      23       23746 :                                  NewTypeError(MessageTemplate::kConstAssign));
      24             : }
      25             : 
      26             : namespace {
      27             : 
      28             : enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 };
      29             : 
      30         341 : Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name,
      31             :                                 RedeclarationType redeclaration_type) {
      32             :   HandleScope scope(isolate);
      33         341 :   if (redeclaration_type == RedeclarationType::kSyntaxError) {
      34         602 :     THROW_NEW_ERROR_RETURN_FAILURE(
      35             :         isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name));
      36             :   } else {
      37          80 :     THROW_NEW_ERROR_RETURN_FAILURE(
      38             :         isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name));
      39             :   }
      40             : }
      41             : 
      42             : 
      43             : // May throw a RedeclarationError.
      44     1841414 : Object* DeclareGlobal(
      45             :     Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name,
      46             :     Handle<Object> value, PropertyAttributes attr, bool is_var,
      47             :     bool is_function_declaration, RedeclarationType redeclaration_type,
      48             :     Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>(),
      49             :     FeedbackSlot slot = FeedbackSlot::Invalid()) {
      50             :   Handle<ScriptContextTable> script_contexts(
      51             :       global->native_context()->script_context_table());
      52             :   ScriptContextTable::LookupResult lookup;
      53     1841444 :   if (ScriptContextTable::Lookup(script_contexts, name, &lookup) &&
      54          30 :       IsLexicalVariableMode(lookup.mode)) {
      55             :     // ES#sec-globaldeclarationinstantiation 6.a:
      56             :     // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
      57             :     // exception.
      58             :     return ThrowRedeclarationError(isolate, name,
      59          30 :                                    RedeclarationType::kSyntaxError);
      60             :   }
      61             : 
      62             :   // Do the lookup own properties only, see ES5 erratum.
      63             :   LookupIterator::Configuration lookup_config(
      64             :       LookupIterator::Configuration::OWN_SKIP_INTERCEPTOR);
      65     1841384 :   if (is_function_declaration) {
      66             :     // For function declarations, use the interceptor on the declaration. For
      67             :     // non-functions, use it only on initialization.
      68             :     lookup_config = LookupIterator::Configuration::OWN;
      69             :   }
      70     1841384 :   LookupIterator it(global, name, global, lookup_config);
      71     1841384 :   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
      72     1841384 :   if (!maybe.IsJust()) return isolate->heap()->exception();
      73             : 
      74     1841384 :   if (it.IsFound()) {
      75             :     PropertyAttributes old_attributes = maybe.FromJust();
      76             :     // The name was declared before; check for conflicting re-declarations.
      77             : 
      78             :     // Skip var re-declarations.
      79      232449 :     if (is_var) return isolate->heap()->undefined_value();
      80             : 
      81             :     DCHECK(is_function_declaration);
      82       31672 :     if ((old_attributes & DONT_DELETE) != 0) {
      83             :       // Only allow reconfiguring globals to functions in user code (no
      84             :       // natives, which are marked as read-only).
      85             :       DCHECK_EQ(attr & READ_ONLY, 0);
      86             : 
      87             :       // Check whether we can reconfigure the existing property into a
      88             :       // function.
      89       58006 :       if (old_attributes & READ_ONLY || old_attributes & DONT_ENUM ||
      90       28975 :           (it.state() == LookupIterator::ACCESSOR)) {
      91             :         // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d:
      92             :         // If hasRestrictedGlobal is true, throw a SyntaxError exception.
      93             :         // ECMA-262 section 18.2.1.3 EvalDeclarationInstantiation 8.a.iv.1.b:
      94             :         // If fnDefinable is false, throw a TypeError exception.
      95          62 :         return ThrowRedeclarationError(isolate, name, redeclaration_type);
      96             :       }
      97             :       // If the existing property is not configurable, keep its attributes. Do
      98             :       attr = old_attributes;
      99             :     }
     100             : 
     101             :     // If the current state is ACCESSOR, this could mean it's an AccessorInfo
     102             :     // type property. We are not allowed to call into such setters during global
     103             :     // function declaration since this would break e.g., onload. Meaning
     104             :     // 'function onload() {}' would invalidly register that function as the
     105             :     // onload callback. To avoid this situation, we first delete the property
     106             :     // before readding it as a regular data property below.
     107       31610 :     if (it.state() == LookupIterator::ACCESSOR) it.Delete();
     108             :   }
     109             : 
     110     1640545 :   if (is_function_declaration) {
     111      303127 :     it.Restart();
     112             :   }
     113             : 
     114             :   // Define or redefine own property.
     115     3281090 :   RETURN_FAILURE_ON_EXCEPTION(
     116             :       isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr));
     117             : 
     118     3277543 :   if (!feedback_vector.is_null() &&
     119     1637007 :       it.state() != LookupIterator::State::INTERCEPTOR) {
     120             :     DCHECK_EQ(*global, *it.GetHolder<Object>());
     121             :     // Preinitialize the feedback slot if the global object does not have
     122             :     // named interceptor or the interceptor is not masking.
     123     1637267 :     if (!global->HasNamedInterceptor() ||
     124         266 :         global->GetNamedInterceptor()->non_masking()) {
     125             :       LoadGlobalICNexus nexus(feedback_vector, slot);
     126     1636735 :       nexus.ConfigurePropertyCellMode(it.GetPropertyCell());
     127             :     }
     128             :   }
     129     1640536 :   return isolate->heap()->undefined_value();
     130             : }
     131             : 
     132      263136 : Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
     133             :                        int flags, Handle<FeedbackVector> feedback_vector) {
     134             :   HandleScope scope(isolate);
     135      131568 :   Handle<JSGlobalObject> global(isolate->global_object());
     136             :   Handle<Context> context(isolate->context());
     137             : 
     138             :   // Traverse the name/value pairs and set the properties.
     139             :   int length = declarations->length();
     140    12377453 :   FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 4, {
     141             :     Handle<String> name(String::cast(declarations->get(i)), isolate);
     142             :     FeedbackSlot slot(Smi::ToInt(declarations->get(i + 1)));
     143             :     Handle<Object> possibly_literal_slot(declarations->get(i + 2), isolate);
     144             :     Handle<Object> initial_value(declarations->get(i + 3), isolate);
     145             : 
     146             :     bool is_var = initial_value->IsUndefined(isolate);
     147             :     bool is_function = initial_value->IsSharedFunctionInfo();
     148             :     DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function));
     149             : 
     150             :     Handle<Object> value;
     151             :     if (is_function) {
     152             :       DCHECK(possibly_literal_slot->IsSmi());
     153             :       // Copy the function and update its context. Use it as value.
     154             :       Handle<SharedFunctionInfo> shared =
     155             :           Handle<SharedFunctionInfo>::cast(initial_value);
     156             :       FeedbackSlot literals_slot(Smi::ToInt(*possibly_literal_slot));
     157             :       Handle<Cell> literals(Cell::cast(feedback_vector->Get(literals_slot)),
     158             :                             isolate);
     159             :       Handle<JSFunction> function =
     160             :           isolate->factory()->NewFunctionFromSharedFunctionInfo(
     161             :               shared, context, literals, TENURED);
     162             :       value = function;
     163             :     } else {
     164             :       value = isolate->factory()->undefined_value();
     165             :     }
     166             : 
     167             :     // Compute the property attributes. According to ECMA-262,
     168             :     // the property must be non-configurable except in eval.
     169             :     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
     170             :     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
     171             :     int attr = NONE;
     172             :     if (is_function && is_native) attr |= READ_ONLY;
     173             :     if (!is_eval) attr |= DONT_DELETE;
     174             : 
     175             :     // ES#sec-globaldeclarationinstantiation 5.d:
     176             :     // If hasRestrictedGlobal is true, throw a SyntaxError exception.
     177             :     Object* result = DeclareGlobal(
     178             :         isolate, global, name, value, static_cast<PropertyAttributes>(attr),
     179             :         is_var, is_function, RedeclarationType::kSyntaxError, feedback_vector,
     180             :         slot);
     181             :     if (isolate->has_pending_exception()) return result;
     182             :   });
     183             : 
     184      131516 :   return isolate->heap()->undefined_value();
     185             : }
     186             : 
     187             : }  // namespace
     188             : 
     189           0 : RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
     190           0 :   HandleScope scope(isolate);
     191             :   DCHECK_EQ(3, args.length());
     192             : 
     193           0 :   CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0);
     194           0 :   CONVERT_SMI_ARG_CHECKED(flags, 1);
     195           0 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, feedback_vector, 2);
     196             : 
     197           0 :   return DeclareGlobals(isolate, declarations, flags, feedback_vector);
     198             : }
     199             : 
     200             : // TODO(ishell): merge this with Runtime::kDeclareGlobals once interpreter
     201             : // is able to pass feedback vector.
     202      263136 : RUNTIME_FUNCTION(Runtime_DeclareGlobalsForInterpreter) {
     203      131568 :   HandleScope scope(isolate);
     204             :   DCHECK_EQ(3, args.length());
     205             : 
     206      263136 :   CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0);
     207      263136 :   CONVERT_SMI_ARG_CHECKED(flags, 1);
     208      263136 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 2);
     209             : 
     210      131568 :   Handle<FeedbackVector> feedback_vector(closure->feedback_vector(), isolate);
     211      131568 :   return DeclareGlobals(isolate, declarations, flags, feedback_vector);
     212             : }
     213             : 
     214             : namespace {
     215             : 
     216      422980 : Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name,
     217             :                           Handle<Object> value) {
     218             :   // Declarations are always made in a function, native, eval, or script
     219             :   // context, or a declaration block scope. Since this is called from eval, the
     220             :   // context passed is the context of the caller, which may be some nested
     221             :   // context and not the declaration context.
     222             :   Handle<Context> context_arg(isolate->context(), isolate);
     223      422980 :   Handle<Context> context(context_arg->declaration_context(), isolate);
     224             : 
     225             :   DCHECK(context->IsFunctionContext() || context->IsNativeContext() ||
     226             :          context->IsScriptContext() || context->IsEvalContext() ||
     227             :          (context->IsBlockContext() && context->has_extension()));
     228             : 
     229             :   bool is_function = value->IsJSFunction();
     230      422980 :   bool is_var = !is_function;
     231             :   DCHECK(!is_var || value->IsUndefined(isolate));
     232             : 
     233             :   int index;
     234             :   PropertyAttributes attributes;
     235             :   InitializationFlag init_flag;
     236             :   VariableMode mode;
     237             : 
     238             :   // Check for a conflict with a lexically scoped variable
     239             :   const ContextLookupFlags lookup_flags = static_cast<ContextLookupFlags>(
     240             :       FOLLOW_CONTEXT_CHAIN | STOP_AT_DECLARATION_SCOPE | SKIP_WITH_CONTEXT);
     241             :   context_arg->Lookup(name, lookup_flags, &index, &attributes, &init_flag,
     242      422980 :                       &mode);
     243      422980 :   if (attributes != ABSENT && IsLexicalVariableMode(mode)) {
     244             :     // ES#sec-evaldeclarationinstantiation 5.a.i.1:
     245             :     // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
     246             :     // exception.
     247             :     // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i:
     248             :     // Throw a SyntaxError exception.
     249             :     return ThrowRedeclarationError(isolate, name,
     250         159 :                                    RedeclarationType::kSyntaxError);
     251             :   }
     252             : 
     253             :   Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index,
     254      422821 :                                           &attributes, &init_flag, &mode);
     255             :   DCHECK(holder.is_null() || !holder->IsModule());
     256             :   DCHECK(!isolate->has_pending_exception());
     257             : 
     258             :   Handle<JSObject> object;
     259             : 
     260      555784 :   if (attributes != ABSENT && holder->IsJSGlobalObject()) {
     261             :     // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b:
     262             :     // If fnDefinable is false, throw a TypeError exception.
     263             :     return DeclareGlobal(isolate, Handle<JSGlobalObject>::cast(holder), name,
     264             :                          value, NONE, is_var, is_function,
     265      128529 :                          RedeclarationType::kTypeError);
     266             :   }
     267      294292 :   if (context_arg->extension()->IsJSGlobalObject()) {
     268             :     Handle<JSGlobalObject> global(
     269             :         JSGlobalObject::cast(context_arg->extension()), isolate);
     270             :     return DeclareGlobal(isolate, global, name, value, NONE, is_var,
     271        1026 :                          is_function, RedeclarationType::kTypeError);
     272      293266 :   } else if (context->IsScriptContext()) {
     273             :     DCHECK(context->global_object()->IsJSGlobalObject());
     274             :     Handle<JSGlobalObject> global(
     275          55 :         JSGlobalObject::cast(context->global_object()), isolate);
     276             :     return DeclareGlobal(isolate, global, name, value, NONE, is_var,
     277          55 :                          is_function, RedeclarationType::kTypeError);
     278             :   }
     279             : 
     280      293211 :   if (attributes != ABSENT) {
     281             :     DCHECK_EQ(NONE, attributes);
     282             : 
     283             :     // Skip var re-declarations.
     284        4434 :     if (is_var) return isolate->heap()->undefined_value();
     285             : 
     286             :     DCHECK(is_function);
     287         574 :     if (index != Context::kNotFound) {
     288             :       DCHECK(holder.is_identical_to(context));
     289         112 :       context->set(index, *value);
     290         112 :       return isolate->heap()->undefined_value();
     291             :     }
     292             : 
     293             :     object = Handle<JSObject>::cast(holder);
     294             : 
     295      288777 :   } else if (context->has_extension()) {
     296             :     // Sloppy varblock contexts might not have an extension object yet,
     297             :     // in which case their extension is a ScopeInfo.
     298      267114 :     if (context->extension()->IsScopeInfo()) {
     299             :       DCHECK(context->IsBlockContext());
     300             :       object = isolate->factory()->NewJSObject(
     301         981 :           isolate->context_extension_function());
     302             :       Handle<HeapObject> extension = isolate->factory()->NewContextExtension(
     303        1962 :           handle(context->scope_info()), object);
     304             :       context->set_extension(*extension);
     305             :     } else {
     306      266133 :       object = handle(context->extension_object(), isolate);
     307             :     }
     308             :     DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
     309             :   } else {
     310             :     // Sloppy eval will never have an extension object, as vars are hoisted out,
     311             :     // and lets are known statically.
     312             :     DCHECK(context->IsFunctionContext());
     313             :     object =
     314       21663 :         isolate->factory()->NewJSObject(isolate->context_extension_function());
     315             :     context->set_extension(*object);
     316             :   }
     317             : 
     318      578478 :   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
     319             :                                            object, name, value, NONE));
     320             : 
     321      289239 :   return isolate->heap()->undefined_value();
     322             : }
     323             : 
     324             : }  // namespace
     325             : 
     326       21036 : RUNTIME_FUNCTION(Runtime_DeclareEvalFunction) {
     327       10518 :   HandleScope scope(isolate);
     328             :   DCHECK_EQ(2, args.length());
     329       21036 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     330       10518 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
     331       10518 :   return DeclareEvalHelper(isolate, name, value);
     332             : }
     333             : 
     334      824924 : RUNTIME_FUNCTION(Runtime_DeclareEvalVar) {
     335      412462 :   HandleScope scope(isolate);
     336             :   DCHECK_EQ(1, args.length());
     337      824924 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     338             :   return DeclareEvalHelper(isolate, name,
     339      824924 :                            isolate->factory()->undefined_value());
     340             : }
     341             : 
     342             : namespace {
     343             : 
     344             : // Find the arguments of the JavaScript function invocation that called
     345             : // into C++ code. Collect these in a newly allocated array of handles.
     346         114 : std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate,
     347             :                                                      int* total_argc) {
     348             :   // Find frame containing arguments passed to the caller.
     349         114 :   JavaScriptFrameIterator it(isolate);
     350             :   JavaScriptFrame* frame = it.frame();
     351             :   std::vector<SharedFunctionInfo*> functions;
     352         114 :   frame->GetFunctions(&functions);
     353         228 :   if (functions.size() > 1) {
     354           0 :     int inlined_jsframe_index = static_cast<int>(functions.size()) - 1;
     355           0 :     TranslatedState translated_values(frame);
     356           0 :     translated_values.Prepare(frame->fp());
     357             : 
     358           0 :     int argument_count = 0;
     359             :     TranslatedFrame* translated_frame =
     360             :         translated_values.GetArgumentsInfoFromJSFrameIndex(
     361           0 :             inlined_jsframe_index, &argument_count);
     362             :     TranslatedFrame::iterator iter = translated_frame->begin();
     363             : 
     364             :     // Skip the function.
     365             :     iter++;
     366             : 
     367             :     // Skip the receiver.
     368             :     iter++;
     369           0 :     argument_count--;
     370             : 
     371           0 :     *total_argc = argument_count;
     372             :     std::unique_ptr<Handle<Object>[]> param_data(
     373           0 :         NewArray<Handle<Object>>(*total_argc));
     374             :     bool should_deoptimize = false;
     375           0 :     for (int i = 0; i < argument_count; i++) {
     376             :       // If we materialize any object, we should deoptimize the frame because we
     377             :       // might alias an object that was eliminated by escape analysis.
     378           0 :       should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
     379           0 :       Handle<Object> value = iter->GetValue();
     380           0 :       param_data[i] = value;
     381             :       iter++;
     382             :     }
     383             : 
     384           0 :     if (should_deoptimize) {
     385           0 :       translated_values.StoreMaterializedValuesAndDeopt(frame);
     386             :     }
     387             : 
     388             :     return param_data;
     389             :   } else {
     390         114 :     if (it.frame()->has_adapted_arguments()) {
     391             :       it.AdvanceOneFrame();
     392             :       DCHECK(it.frame()->is_arguments_adaptor());
     393             :     }
     394             :     frame = it.frame();
     395         114 :     int args_count = frame->ComputeParametersCount();
     396             : 
     397         114 :     *total_argc = args_count;
     398             :     std::unique_ptr<Handle<Object>[]> param_data(
     399         114 :         NewArray<Handle<Object>>(*total_argc));
     400     1769944 :     for (int i = 0; i < args_count; i++) {
     401     1769830 :       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
     402     3539660 :       param_data[i] = val;
     403             :     }
     404             :     return param_data;
     405             :   }
     406             : }
     407             : 
     408             : template <typename T>
     409         194 : Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
     410             :                                     T parameters, int argument_count) {
     411         104 :   CHECK(!IsDerivedConstructor(callee->shared()->kind()));
     412             :   DCHECK(callee->shared()->has_simple_parameters());
     413             :   Handle<JSObject> result =
     414         104 :       isolate->factory()->NewArgumentsObject(callee, argument_count);
     415             : 
     416             :   // Allocate the elements if needed.
     417             :   int parameter_count = callee->shared()->internal_formal_parameter_count();
     418         104 :   if (argument_count > 0) {
     419          98 :     if (parameter_count > 0) {
     420             :       int mapped_count = Min(argument_count, parameter_count);
     421             :       Handle<FixedArray> parameter_map =
     422          90 :           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
     423         180 :       parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map());
     424         180 :       result->set_map(isolate->native_context()->fast_aliased_arguments_map());
     425          90 :       result->set_elements(*parameter_map);
     426             : 
     427             :       // Store the context and the arguments array at the beginning of the
     428             :       // parameter map.
     429             :       Handle<Context> context(isolate->context());
     430             :       Handle<FixedArray> arguments =
     431          90 :           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
     432          90 :       parameter_map->set(0, *context);
     433          90 :       parameter_map->set(1, *arguments);
     434             : 
     435             :       // Loop over the actual parameters backwards.
     436          90 :       int index = argument_count - 1;
     437         209 :       while (index >= mapped_count) {
     438             :         // These go directly in the arguments array and have no
     439             :         // corresponding slot in the parameter map.
     440          29 :         arguments->set(index, parameters[index]);
     441          29 :         --index;
     442             :       }
     443             : 
     444             :       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
     445         419 :       while (index >= 0) {
     446             :         // Detect duplicate names to the right in the parameter list.
     447         329 :         Handle<String> name(scope_info->ParameterName(index));
     448         329 :         int context_local_count = scope_info->ContextLocalCount();
     449             :         bool duplicate = false;
     450         335 :         for (int j = index + 1; j < parameter_count; ++j) {
     451         510 :           if (scope_info->ParameterName(j) == *name) {
     452             :             duplicate = true;
     453             :             break;
     454             :           }
     455             :         }
     456             : 
     457         329 :         if (duplicate) {
     458             :           // This goes directly in the arguments array with a hole in the
     459             :           // parameter map.
     460         249 :           arguments->set(index, parameters[index]);
     461         498 :           parameter_map->set_the_hole(index + 2);
     462             :         } else {
     463             :           // The context index goes in the parameter map with a hole in the
     464             :           // arguments array.
     465             :           int context_index = -1;
     466           6 :           for (int j = 0; j < context_local_count; ++j) {
     467         172 :             if (scope_info->ContextLocalName(j) == *name) {
     468             :               context_index = j;
     469             :               break;
     470             :             }
     471             :           }
     472             : 
     473             :           DCHECK_GE(context_index, 0);
     474          80 :           arguments->set_the_hole(index);
     475             :           parameter_map->set(
     476             :               index + 2,
     477          80 :               Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index));
     478             :         }
     479             : 
     480         329 :         --index;
     481             :       }
     482             :     } else {
     483             :       // If there is no aliasing, the arguments object elements are not
     484             :       // special in any way.
     485             :       Handle<FixedArray> elements =
     486           8 :           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
     487           8 :       result->set_elements(*elements);
     488      524296 :       for (int i = 0; i < argument_count; ++i) {
     489     1048576 :         elements->set(i, parameters[i]);
     490             :       }
     491             :     }
     492             :   }
     493         104 :   return result;
     494             : }
     495             : 
     496             : 
     497             : class HandleArguments BASE_EMBEDDED {
     498             :  public:
     499          96 :   explicit HandleArguments(Handle<Object>* array) : array_(array) {}
     500         278 :   Object* operator[](int index) { return *array_[index]; }
     501             : 
     502             :  private:
     503             :   Handle<Object>* array_;
     504             : };
     505             : 
     506             : 
     507             : class ParameterArguments BASE_EMBEDDED {
     508             :  public:
     509           8 :   explicit ParameterArguments(Object** parameters) : parameters_(parameters) {}
     510      524288 :   Object*& operator[](int index) { return *(parameters_ - index - 1); }
     511             : 
     512             :  private:
     513             :   Object** parameters_;
     514             : };
     515             : 
     516             : }  // namespace
     517             : 
     518             : 
     519         192 : RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) {
     520          96 :   HandleScope scope(isolate);
     521             :   DCHECK_EQ(1, args.length());
     522         192 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
     523             :   // This generic runtime function can also be used when the caller has been
     524             :   // inlined, we use the slow but accurate {GetCallerArguments}.
     525          96 :   int argument_count = 0;
     526             :   std::unique_ptr<Handle<Object>[]> arguments =
     527         192 :       GetCallerArguments(isolate, &argument_count);
     528          96 :   HandleArguments argument_getter(arguments.get());
     529         288 :   return *NewSloppyArguments(isolate, callee, argument_getter, argument_count);
     530             : }
     531             : 
     532             : 
     533          18 : RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
     534           9 :   HandleScope scope(isolate);
     535             :   DCHECK_EQ(1, args.length());
     536          18 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
     537             :   // This generic runtime function can also be used when the caller has been
     538             :   // inlined, we use the slow but accurate {GetCallerArguments}.
     539           9 :   int argument_count = 0;
     540             :   std::unique_ptr<Handle<Object>[]> arguments =
     541          18 :       GetCallerArguments(isolate, &argument_count);
     542             :   Handle<JSObject> result =
     543           9 :       isolate->factory()->NewArgumentsObject(callee, argument_count);
     544           9 :   if (argument_count) {
     545             :     Handle<FixedArray> array =
     546           9 :         isolate->factory()->NewUninitializedFixedArray(argument_count);
     547             :     DisallowHeapAllocation no_gc;
     548           9 :     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
     549      884736 :     for (int i = 0; i < argument_count; i++) {
     550     1769472 :       array->set(i, *arguments[i], mode);
     551             :     }
     552           9 :     result->set_elements(*array);
     553             :   }
     554           9 :   return *result;
     555             : }
     556             : 
     557             : 
     558          18 : RUNTIME_FUNCTION(Runtime_NewRestParameter) {
     559           9 :   HandleScope scope(isolate);
     560             :   DCHECK_EQ(1, args.length());
     561          18 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
     562           9 :   int start_index = callee->shared()->internal_formal_parameter_count();
     563             :   // This generic runtime function can also be used when the caller has been
     564             :   // inlined, we use the slow but accurate {GetCallerArguments}.
     565           9 :   int argument_count = 0;
     566             :   std::unique_ptr<Handle<Object>[]> arguments =
     567          18 :       GetCallerArguments(isolate, &argument_count);
     568           9 :   int num_elements = std::max(0, argument_count - start_index);
     569             :   Handle<JSObject> result = isolate->factory()->NewJSArray(
     570             :       PACKED_ELEMENTS, num_elements, num_elements,
     571           9 :       DONT_INITIALIZE_ARRAY_ELEMENTS);
     572             :   {
     573             :     DisallowHeapAllocation no_gc;
     574           9 :     FixedArray* elements = FixedArray::cast(result->elements());
     575           9 :     WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
     576      884736 :     for (int i = 0; i < num_elements; i++) {
     577     1769472 :       elements->set(i, *arguments[i + start_index], mode);
     578             :     }
     579             :   }
     580           9 :   return *result;
     581             : }
     582             : 
     583             : 
     584          16 : RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
     585           8 :   HandleScope scope(isolate);
     586             :   DCHECK_EQ(1, args.length());
     587          16 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
     588          16 :   StackFrameIterator iterator(isolate);
     589             : 
     590             :   // Stub/interpreter handler frame
     591           8 :   iterator.Advance();
     592             :   DCHECK(iterator.frame()->type() == StackFrame::STUB);
     593             : 
     594             :   // Function frame
     595           8 :   iterator.Advance();
     596           8 :   JavaScriptFrame* function_frame = JavaScriptFrame::cast(iterator.frame());
     597             :   DCHECK(function_frame->is_java_script());
     598           8 :   int argc = function_frame->GetArgumentsLength();
     599           8 :   Address fp = function_frame->fp();
     600           8 :   if (function_frame->has_adapted_arguments()) {
     601           8 :     iterator.Advance();
     602           8 :     fp = iterator.frame()->fp();
     603             :   }
     604             : 
     605             :   Object** parameters = reinterpret_cast<Object**>(
     606           8 :       fp + argc * kPointerSize + StandardFrameConstants::kCallerSPOffset);
     607           8 :   ParameterArguments argument_getter(parameters);
     608          24 :   return *NewSloppyArguments(isolate, callee, argument_getter, argc);
     609             : }
     610             : 
     611           6 : RUNTIME_FUNCTION(Runtime_NewArgumentsElements) {
     612           3 :   HandleScope scope(isolate);
     613             :   DCHECK_EQ(3, args.length());
     614           3 :   Object** frame = reinterpret_cast<Object**>(args[0]);
     615           6 :   CONVERT_SMI_ARG_CHECKED(length, 1);
     616           6 :   CONVERT_SMI_ARG_CHECKED(mapped_count, 2);
     617             :   Handle<FixedArray> result =
     618           3 :       isolate->factory()->NewUninitializedFixedArray(length);
     619           3 :   int const offset = length + 1;
     620             :   DisallowHeapAllocation no_gc;
     621           3 :   WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
     622           3 :   int number_of_holes = Min(mapped_count, length);
     623           0 :   for (int index = 0; index < number_of_holes; ++index) {
     624           0 :     result->set_the_hole(isolate, index);
     625             :   }
     626      262144 :   for (int index = number_of_holes; index < length; ++index) {
     627      524288 :     result->set(index, frame[offset - index], mode);
     628             :   }
     629           3 :   return *result;
     630             : }
     631             : 
     632           0 : RUNTIME_FUNCTION(Runtime_NewClosure) {
     633           0 :   HandleScope scope(isolate);
     634             :   DCHECK_EQ(3, args.length());
     635           0 :   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
     636           0 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1);
     637           0 :   CONVERT_SMI_ARG_CHECKED(index, 2);
     638           0 :   Handle<Context> context(isolate->context(), isolate);
     639           0 :   FeedbackSlot slot = FeedbackVector::ToSlot(index);
     640           0 :   Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate);
     641             :   Handle<JSFunction> function =
     642             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(
     643           0 :           shared, context, vector_cell, NOT_TENURED);
     644           0 :   return *function;
     645             : }
     646             : 
     647             : 
     648     1427703 : RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) {
     649      475901 :   HandleScope scope(isolate);
     650             :   DCHECK_EQ(3, args.length());
     651      951802 :   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
     652      951802 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1);
     653      951802 :   CONVERT_SMI_ARG_CHECKED(index, 2);
     654      475901 :   Handle<Context> context(isolate->context(), isolate);
     655      475901 :   FeedbackSlot slot = FeedbackVector::ToSlot(index);
     656      475901 :   Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate);
     657             :   // The caller ensures that we pretenure closures that are assigned
     658             :   // directly to properties.
     659             :   Handle<JSFunction> function =
     660             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(
     661      475901 :           shared, context, vector_cell, TENURED);
     662      475901 :   return *function;
     663             : }
     664             : 
     665       11183 : static Object* FindNameClash(Handle<ScopeInfo> scope_info,
     666             :                              Handle<JSGlobalObject> global_object,
     667             :                              Handle<ScriptContextTable> script_context) {
     668             :   Isolate* isolate = scope_info->GetIsolate();
     669      781462 :   for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
     670      379638 :     Handle<String> name(scope_info->ContextLocalName(var));
     671      379638 :     VariableMode mode = scope_info->ContextLocalMode(var);
     672             :     ScriptContextTable::LookupResult lookup;
     673      379638 :     if (ScriptContextTable::Lookup(script_context, name, &lookup)) {
     674          50 :       if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
     675             :         // ES#sec-globaldeclarationinstantiation 5.b:
     676             :         // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
     677             :         // exception.
     678             :         return ThrowRedeclarationError(isolate, name,
     679         140 :                                        RedeclarationType::kSyntaxError);
     680             :       }
     681             :     }
     682             : 
     683      379588 :     if (IsLexicalVariableMode(mode)) {
     684             :       LookupIterator it(global_object, name, global_object,
     685      379588 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
     686      379588 :       Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
     687      379628 :       if (!maybe.IsJust()) return isolate->heap()->exception();
     688      379588 :       if ((maybe.FromJust() & DONT_DELETE) != 0) {
     689             :         // ES#sec-globaldeclarationinstantiation 5.a:
     690             :         // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
     691             :         // exception.
     692             :         // ES#sec-globaldeclarationinstantiation 5.d:
     693             :         // If hasRestrictedGlobal is true, throw a SyntaxError exception.
     694             :         return ThrowRedeclarationError(isolate, name,
     695          40 :                                        RedeclarationType::kSyntaxError);
     696             :       }
     697             : 
     698      379548 :       JSGlobalObject::InvalidatePropertyCell(global_object, name);
     699             :     }
     700             :   }
     701       11093 :   return isolate->heap()->undefined_value();
     702             : }
     703             : 
     704             : 
     705       22366 : RUNTIME_FUNCTION(Runtime_NewScriptContext) {
     706       11183 :   HandleScope scope(isolate);
     707             :   DCHECK_EQ(2, args.length());
     708             : 
     709       22366 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     710       22366 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
     711       11183 :   Handle<JSGlobalObject> global_object(function->context()->global_object());
     712       11183 :   Handle<Context> native_context(global_object->native_context());
     713             :   Handle<ScriptContextTable> script_context_table(
     714       11183 :       native_context->script_context_table());
     715             : 
     716             :   Object* name_clash_result =
     717       11183 :       FindNameClash(scope_info, global_object, script_context_table);
     718       11183 :   if (isolate->has_pending_exception()) return name_clash_result;
     719             : 
     720             :   // Script contexts have a canonical empty function as their closure, not the
     721             :   // anonymous closure containing the global code.  See
     722             :   // FullCodeGenerator::PushFunctionArgumentForContextAllocation.
     723       11093 :   Handle<JSFunction> closure(function->shared()->IsUserJavaScript()
     724             :                                  ? native_context->closure()
     725       22186 :                                  : *function);
     726             :   Handle<Context> result =
     727       11093 :       isolate->factory()->NewScriptContext(closure, scope_info);
     728             : 
     729             :   DCHECK(function->context() == isolate->context());
     730             :   DCHECK(*global_object == result->global_object());
     731             : 
     732             :   Handle<ScriptContextTable> new_script_context_table =
     733       11093 :       ScriptContextTable::Extend(script_context_table, result);
     734       11093 :   native_context->set_script_context_table(*new_script_context_table);
     735       11183 :   return *result;
     736             : }
     737             : 
     738          12 : RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
     739           6 :   HandleScope scope(isolate);
     740             :   DCHECK_EQ(2, args.length());
     741             : 
     742          12 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     743          12 :   CONVERT_SMI_ARG_CHECKED(scope_type, 1);
     744             : 
     745             :   DCHECK(function->context() == isolate->context());
     746           6 :   int length = function->shared()->scope_info()->ContextLength();
     747             :   return *isolate->factory()->NewFunctionContext(
     748          12 :       length, function, static_cast<ScopeType>(scope_type));
     749             : }
     750             : 
     751      761559 : RUNTIME_FUNCTION(Runtime_PushWithContext) {
     752      253853 :   HandleScope scope(isolate);
     753             :   DCHECK_EQ(3, args.length());
     754      507706 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, extension_object, 0);
     755      507706 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
     756      507706 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
     757      253853 :   Handle<Context> current(isolate->context());
     758             :   Handle<Context> context = isolate->factory()->NewWithContext(
     759      253853 :       function, current, scope_info, extension_object);
     760      253853 :   isolate->set_context(*context);
     761      253853 :   return *context;
     762             : }
     763             : 
     764        2918 : RUNTIME_FUNCTION(Runtime_PushModuleContext) {
     765        1459 :   HandleScope scope(isolate);
     766             :   DCHECK_EQ(3, args.length());
     767        2918 :   CONVERT_ARG_HANDLE_CHECKED(Module, module, 0);
     768        2918 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
     769        2918 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 2);
     770             :   DCHECK(function->context() == isolate->context());
     771             : 
     772             :   Handle<Context> context =
     773        1459 :       isolate->factory()->NewModuleContext(module, function, scope_info);
     774        1459 :   isolate->set_context(*context);
     775        1459 :   return *context;
     776             : }
     777             : 
     778     2361981 : RUNTIME_FUNCTION(Runtime_PushCatchContext) {
     779      787327 :   HandleScope scope(isolate);
     780             :   DCHECK_EQ(4, args.length());
     781     1574654 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     782      787327 :   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
     783     1574654 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 2);
     784     1574654 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 3);
     785      787327 :   Handle<Context> current(isolate->context());
     786             :   Handle<Context> context = isolate->factory()->NewCatchContext(
     787      787327 :       function, current, scope_info, name, thrown_object);
     788      787327 :   isolate->set_context(*context);
     789      787327 :   return *context;
     790             : }
     791             : 
     792             : 
     793      278058 : RUNTIME_FUNCTION(Runtime_PushBlockContext) {
     794       92686 :   HandleScope scope(isolate);
     795             :   DCHECK_EQ(2, args.length());
     796      185372 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
     797      185372 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
     798       92686 :   Handle<Context> current(isolate->context());
     799             :   Handle<Context> context =
     800       92686 :       isolate->factory()->NewBlockContext(function, current, scope_info);
     801       92686 :   isolate->set_context(*context);
     802       92686 :   return *context;
     803             : }
     804             : 
     805             : 
     806     3002937 : RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
     807     1000979 :   HandleScope scope(isolate);
     808             :   DCHECK_EQ(1, args.length());
     809     2001958 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     810             : 
     811             :   int index;
     812             :   PropertyAttributes attributes;
     813             :   InitializationFlag flag;
     814             :   VariableMode mode;
     815             :   Handle<Object> holder = isolate->context()->Lookup(
     816     1000979 :       name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode);
     817             : 
     818             :   // If the slot was not found the result is true.
     819     1000979 :   if (holder.is_null()) {
     820             :     // In case of JSProxy, an exception might have been thrown.
     821     1000067 :     if (isolate->has_pending_exception()) return isolate->heap()->exception();
     822     1000067 :     return isolate->heap()->true_value();
     823             :   }
     824             : 
     825             :   // If the slot was found in a context or in module imports and exports it
     826             :   // should be DONT_DELETE.
     827        1704 :   if (holder->IsContext() || holder->IsModule()) {
     828         120 :     return isolate->heap()->false_value();
     829             :   }
     830             : 
     831             :   // The slot was found in a JSReceiver, either a context extension object,
     832             :   // the global object, or the subject of a with.  Try to delete it
     833             :   // (respecting DONT_DELETE).
     834         792 :   Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
     835         792 :   Maybe<bool> result = JSReceiver::DeleteProperty(object, name);
     836         792 :   MAYBE_RETURN(result, isolate->heap()->exception());
     837         792 :   return isolate->heap()->ToBoolean(result.FromJust());
     838             : }
     839             : 
     840             : 
     841             : namespace {
     842             : 
     843     1372619 : MaybeHandle<Object> LoadLookupSlot(Handle<String> name,
     844             :                                    Object::ShouldThrow should_throw,
     845             :                                    Handle<Object>* receiver_return = nullptr) {
     846     1372619 :   Isolate* const isolate = name->GetIsolate();
     847             : 
     848             :   int index;
     849             :   PropertyAttributes attributes;
     850             :   InitializationFlag flag;
     851             :   VariableMode mode;
     852             :   Handle<Object> holder = isolate->context()->Lookup(
     853     1372619 :       name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode);
     854     1372619 :   if (isolate->has_pending_exception()) return MaybeHandle<Object>();
     855             : 
     856     2744737 :   if (!holder.is_null() && holder->IsModule()) {
     857         160 :     return Module::LoadVariable(Handle<Module>::cast(holder), index);
     858             :   }
     859     1372426 :   if (index != Context::kNotFound) {
     860             :     DCHECK(holder->IsContext());
     861             :     // If the "property" we were looking for is a local variable, the
     862             :     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
     863             :     Handle<Object> receiver = isolate->factory()->undefined_value();
     864             :     Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate);
     865             :     // Check for uninitialized bindings.
     866      334597 :     if (flag == kNeedsInitialization && value->IsTheHole(isolate)) {
     867         974 :       THROW_NEW_ERROR(isolate,
     868             :                       NewReferenceError(MessageTemplate::kNotDefined, name),
     869             :                       Object);
     870             :     }
     871             :     DCHECK(!value->IsTheHole(isolate));
     872      306690 :     if (receiver_return) *receiver_return = receiver;
     873      306690 :     return value;
     874             :   }
     875             : 
     876             :   // Otherwise, if the slot was found the holder is a context extension
     877             :   // object, subject of a with, or a global object.  We read the named
     878             :   // property from it.
     879     1065249 :   if (!holder.is_null()) {
     880             :     // No need to unhole the value here.  This is taken care of by the
     881             :     // GetProperty function.
     882             :     Handle<Object> value;
     883     2129628 :     ASSIGN_RETURN_ON_EXCEPTION(
     884             :         isolate, value, Object::GetProperty(holder, name),
     885             :         Object);
     886     1064784 :     if (receiver_return) {
     887             :       *receiver_return =
     888       12177 :           (holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject())
     889             :               ? Handle<Object>::cast(isolate->factory()->undefined_value())
     890      355065 :               : holder;
     891             :     }
     892     1064784 :     return value;
     893             :   }
     894             : 
     895         435 :   if (should_throw == Object::THROW_ON_ERROR) {
     896             :     // The property doesn't exist - throw exception.
     897         748 :     THROW_NEW_ERROR(
     898             :         isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
     899             :   }
     900             : 
     901             :   // The property doesn't exist - return undefined.
     902          61 :   if (receiver_return) *receiver_return = isolate->factory()->undefined_value();
     903          61 :   return isolate->factory()->undefined_value();
     904             : }
     905             : 
     906             : }  // namespace
     907             : 
     908             : 
     909     2376598 : RUNTIME_FUNCTION(Runtime_LoadLookupSlot) {
     910     1188299 :   HandleScope scope(isolate);
     911             :   DCHECK_EQ(1, args.length());
     912     2376598 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     913     2376598 :   RETURN_RESULT_OR_FAILURE(isolate,
     914     1188299 :                            LoadLookupSlot(name, Object::THROW_ON_ERROR));
     915             : }
     916             : 
     917             : 
     918         904 : RUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) {
     919         452 :   HandleScope scope(isolate);
     920             :   DCHECK_EQ(1, args.length());
     921         904 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     922        1356 :   RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(name, Object::DONT_THROW));
     923             : }
     924             : 
     925             : 
     926      183868 : RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) {
     927      183868 :   HandleScope scope(isolate);
     928             :   DCHECK_EQ(1, args.length());
     929             :   DCHECK(args[0]->IsString());
     930      183868 :   Handle<String> name = args.at<String>(0);
     931             :   Handle<Object> value;
     932             :   Handle<Object> receiver;
     933      367736 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     934             :       isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR, &receiver),
     935             :       MakePair(isolate->heap()->exception(), nullptr));
     936      183848 :   return MakePair(*value, *receiver);
     937             : }
     938             : 
     939             : 
     940             : namespace {
     941             : 
     942     2314373 : MaybeHandle<Object> StoreLookupSlot(
     943             :     Handle<String> name, Handle<Object> value, LanguageMode language_mode,
     944             :     ContextLookupFlags context_lookup_flags = FOLLOW_CHAINS) {
     945     2314373 :   Isolate* const isolate = name->GetIsolate();
     946             :   Handle<Context> context(isolate->context(), isolate);
     947             : 
     948             :   int index;
     949             :   PropertyAttributes attributes;
     950             :   InitializationFlag flag;
     951             :   VariableMode mode;
     952             :   bool is_sloppy_function_name;
     953             :   Handle<Object> holder =
     954             :       context->Lookup(name, context_lookup_flags, &index, &attributes, &flag,
     955     2314373 :                       &mode, &is_sloppy_function_name);
     956     2314373 :   if (holder.is_null()) {
     957             :     // In case of JSProxy, an exception might have been thrown.
     958         518 :     if (isolate->has_pending_exception()) return MaybeHandle<Object>();
     959     2313855 :   } else if (holder->IsModule()) {
     960          70 :     if ((attributes & READ_ONLY) == 0) {
     961          50 :       Module::StoreVariable(Handle<Module>::cast(holder), index, value);
     962             :     } else {
     963          40 :       THROW_NEW_ERROR(
     964             :           isolate, NewTypeError(MessageTemplate::kConstAssign, name), Object);
     965             :     }
     966          50 :     return value;
     967             :   }
     968             :   // The property was found in a context slot.
     969     2314261 :   if (index != Context::kNotFound) {
     970     1556098 :     if (flag == kNeedsInitialization &&
     971         287 :         Handle<Context>::cast(holder)->is_the_hole(isolate, index)) {
     972         108 :       THROW_NEW_ERROR(isolate,
     973             :                       NewReferenceError(MessageTemplate::kNotDefined, name),
     974             :                       Object);
     975             :     }
     976     1555757 :     if ((attributes & READ_ONLY) == 0) {
     977     3111316 :       Handle<Context>::cast(holder)->set(index, *value);
     978          99 :     } else if (!is_sloppy_function_name || is_strict(language_mode)) {
     979          80 :       THROW_NEW_ERROR(
     980             :           isolate, NewTypeError(MessageTemplate::kConstAssign, name), Object);
     981             :     }
     982     1555717 :     return value;
     983             :   }
     984             : 
     985             :   // Slow case: The property is not in a context slot.  It is either in a
     986             :   // context extension object, a property of the subject of a with, or a
     987             :   // property of the global object.
     988             :   Handle<JSReceiver> object;
     989      758450 :   if (attributes != ABSENT) {
     990             :     // The property exists on the holder.
     991             :     object = Handle<JSReceiver>::cast(holder);
     992         476 :   } else if (is_strict(language_mode)) {
     993             :     // If absent in strict mode: throw.
     994          66 :     THROW_NEW_ERROR(
     995             :         isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
     996             :   } else {
     997             :     // If absent in sloppy mode: add the property to the global object.
     998         443 :     object = Handle<JSReceiver>(context->global_object());
     999             :   }
    1000             : 
    1001     1516834 :   ASSIGN_RETURN_ON_EXCEPTION(
    1002             :       isolate, value, Object::SetProperty(object, name, value, language_mode),
    1003             :       Object);
    1004      758335 :   return value;
    1005             : }
    1006             : 
    1007             : }  // namespace
    1008             : 
    1009             : 
    1010     4621254 : RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) {
    1011     2310627 :   HandleScope scope(isolate);
    1012             :   DCHECK_EQ(2, args.length());
    1013     4621254 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    1014     2310627 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    1015     4621254 :   RETURN_RESULT_OR_FAILURE(isolate,
    1016     2310627 :                            StoreLookupSlot(name, value, LanguageMode::kSloppy));
    1017             : }
    1018             : 
    1019             : // Store into a dynamic context for sloppy-mode block-scoped function hoisting
    1020             : // which leaks out of an eval. In particular, with-scopes are be skipped to
    1021             : // reach the appropriate var-like declaration.
    1022         938 : RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) {
    1023         469 :   HandleScope scope(isolate);
    1024             :   DCHECK_EQ(2, args.length());
    1025         938 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    1026         469 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    1027             :   const ContextLookupFlags lookup_flags = static_cast<ContextLookupFlags>(
    1028             :       FOLLOW_CONTEXT_CHAIN | STOP_AT_DECLARATION_SCOPE | SKIP_WITH_CONTEXT);
    1029         938 :   RETURN_RESULT_OR_FAILURE(
    1030             :       isolate,
    1031         469 :       StoreLookupSlot(name, value, LanguageMode::kSloppy, lookup_flags));
    1032             : }
    1033             : 
    1034        6554 : RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) {
    1035        3277 :   HandleScope scope(isolate);
    1036             :   DCHECK_EQ(2, args.length());
    1037        6554 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    1038        3277 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    1039        6554 :   RETURN_RESULT_OR_FAILURE(isolate,
    1040        3277 :                            StoreLookupSlot(name, value, LanguageMode::kStrict));
    1041             : }
    1042             : 
    1043             : }  // namespace internal
    1044             : }  // namespace v8

Generated by: LCOV version 1.10