LCOV - code coverage report
Current view: top level - src/runtime - runtime-scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 363 382 95.0 %
Date: 2019-01-20 Functions: 40 63 63.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 <memory>
       6             : 
       7             : #include "src/accessors.h"
       8             : #include "src/arguments-inl.h"
       9             : #include "src/ast/scopes.h"
      10             : #include "src/bootstrapper.h"
      11             : #include "src/counters.h"
      12             : #include "src/deoptimizer.h"
      13             : #include "src/frames-inl.h"
      14             : #include "src/isolate-inl.h"
      15             : #include "src/message-template.h"
      16             : #include "src/objects/heap-object-inl.h"
      17             : #include "src/objects/module-inl.h"
      18             : #include "src/objects/smi.h"
      19             : #include "src/runtime/runtime-utils.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24       23685 : RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) {
      25       23685 :   HandleScope scope(isolate);
      26       47370 :   THROW_NEW_ERROR_RETURN_FAILURE(isolate,
      27       23685 :                                  NewTypeError(MessageTemplate::kConstAssign));
      28             : }
      29             : 
      30             : namespace {
      31             : 
      32             : enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 };
      33             : 
      34         172 : Object ThrowRedeclarationError(Isolate* isolate, Handle<String> name,
      35             :                                RedeclarationType redeclaration_type) {
      36             :   HandleScope scope(isolate);
      37             :   if (redeclaration_type == RedeclarationType::kSyntaxError) {
      38         272 :     THROW_NEW_ERROR_RETURN_FAILURE(
      39             :         isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name));
      40             :   } else {
      41          72 :     THROW_NEW_ERROR_RETURN_FAILURE(
      42             :         isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name));
      43             :   }
      44             : }
      45             : 
      46             : // May throw a RedeclarationError.
      47     2176202 : Object DeclareGlobal(
      48             :     Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name,
      49             :     Handle<Object> value, PropertyAttributes attr, bool is_var,
      50             :     bool is_function_declaration, RedeclarationType redeclaration_type,
      51             :     Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>(),
      52             :     FeedbackSlot slot = FeedbackSlot::Invalid()) {
      53             :   Handle<ScriptContextTable> script_contexts(
      54     4352404 :       global->native_context()->script_context_table(), isolate);
      55             :   ScriptContextTable::LookupResult lookup;
      56     2176231 :   if (ScriptContextTable::Lookup(isolate, script_contexts, name, &lookup) &&
      57          29 :       IsLexicalVariableMode(lookup.mode)) {
      58             :     // ES#sec-globaldeclarationinstantiation 6.a:
      59             :     // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
      60             :     // exception.
      61             :     return ThrowRedeclarationError(isolate, name,
      62          29 :                                    RedeclarationType::kSyntaxError);
      63             :   }
      64             : 
      65             :   // Do the lookup own properties only, see ES5 erratum.
      66             :   LookupIterator::Configuration lookup_config(
      67             :       LookupIterator::Configuration::OWN_SKIP_INTERCEPTOR);
      68     2176173 :   if (is_function_declaration) {
      69             :     // For function declarations, use the interceptor on the declaration. For
      70             :     // non-functions, use it only on initialization.
      71             :     lookup_config = LookupIterator::Configuration::OWN;
      72             :   }
      73     2176173 :   LookupIterator it(global, name, global, lookup_config);
      74     2176173 :   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
      75     2176173 :   if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
      76             : 
      77     2176173 :   if (it.IsFound()) {
      78             :     PropertyAttributes old_attributes = maybe.FromJust();
      79             :     // The name was declared before; check for conflicting re-declarations.
      80             : 
      81             :     // Skip var re-declarations.
      82      530452 :     if (is_var) return ReadOnlyRoots(isolate).undefined_value();
      83             : 
      84             :     DCHECK(is_function_declaration);
      85       40488 :     if ((old_attributes & DONT_DELETE) != 0) {
      86             :       // Only allow reconfiguring globals to functions in user code (no
      87             :       // natives, which are marked as read-only).
      88             :       DCHECK_EQ(attr & READ_ONLY, 0);
      89             : 
      90             :       // Check whether we can reconfigure the existing property into a
      91             :       // function.
      92       75377 :       if (old_attributes & READ_ONLY || old_attributes & DONT_ENUM ||
      93       37663 :           (it.state() == LookupIterator::ACCESSOR)) {
      94             :         // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d:
      95             :         // If hasRestrictedGlobal is true, throw a SyntaxError exception.
      96             :         // ECMA-262 section 18.2.1.3 EvalDeclarationInstantiation 8.a.iv.1.b:
      97             :         // If fnDefinable is false, throw a TypeError exception.
      98          56 :         return ThrowRedeclarationError(isolate, name, redeclaration_type);
      99             :       }
     100             :       // If the existing property is not configurable, keep its attributes. Do
     101             :       attr = old_attributes;
     102             :     }
     103             : 
     104             :     // If the current state is ACCESSOR, this could mean it's an AccessorInfo
     105             :     // type property. We are not allowed to call into such setters during global
     106             :     // function declaration since this would break e.g., onload. Meaning
     107             :     // 'function onload() {}' would invalidly register that function as the
     108             :     // onload callback. To avoid this situation, we first delete the property
     109             :     // before readding it as a regular data property below.
     110       40432 :     if (it.state() == LookupIterator::ACCESSOR) it.Delete();
     111             :   }
     112             : 
     113     1931135 :   if (is_function_declaration) {
     114      350213 :     it.Restart();
     115             :   }
     116             : 
     117             :   // Define or redefine own property.
     118     3862279 :   RETURN_FAILURE_ON_EXCEPTION(
     119             :       isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr));
     120             : 
     121     3858580 :   if (!feedback_vector.is_null() &&
     122     1927454 :       it.state() != LookupIterator::State::INTERCEPTOR) {
     123             :     DCHECK_EQ(*global, *it.GetHolder<Object>());
     124             :     // Preinitialize the feedback slot if the global object does not have
     125             :     // named interceptor or the interceptor is not masking.
     126     3855137 :     if (!global->HasNamedInterceptor() ||
     127     1927689 :         global->GetNamedInterceptor()->non_masking()) {
     128     1927207 :       FeedbackNexus nexus(feedback_vector, slot);
     129     1927207 :       nexus.ConfigurePropertyCellMode(it.GetPropertyCell());
     130             :     }
     131             :   }
     132     1931126 :   return ReadOnlyRoots(isolate).undefined_value();
     133             : }
     134             : 
     135      156736 : Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
     136             :                       int flags, Handle<FeedbackVector> feedback_vector) {
     137             :   HandleScope scope(isolate);
     138      156736 :   Handle<JSGlobalObject> global(isolate->global_object());
     139             :   Handle<Context> context(isolate->context(), isolate);
     140             : 
     141             :   // Traverse the name/value pairs and set the properties.
     142             :   int length = declarations->length();
     143    24503157 :   FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 4, {
     144             :     Handle<String> name(String::cast(declarations->get(i)), isolate);
     145             :     FeedbackSlot slot(Smi::ToInt(declarations->get(i + 1)));
     146             :     Handle<Object> possibly_feedback_cell_slot(declarations->get(i + 2),
     147             :                                                isolate);
     148             :     Handle<Object> initial_value(declarations->get(i + 3), isolate);
     149             : 
     150             :     bool is_var = initial_value->IsUndefined(isolate);
     151             :     bool is_function = initial_value->IsSharedFunctionInfo();
     152             :     DCHECK_NE(is_var, is_function);
     153             : 
     154             :     Handle<Object> value;
     155             :     if (is_function) {
     156             :       // If feedback vector was not allocated for this function, then we don't
     157             :       // have any information about number of closures. Use NoFeedbackCell to
     158             :       // indicate that.
     159             :       Handle<FeedbackCell> feedback_cell =
     160             :           isolate->factory()->no_feedback_cell();
     161             :       if (!feedback_vector.is_null()) {
     162             :         DCHECK(possibly_feedback_cell_slot->IsSmi());
     163             :         FeedbackSlot feedback_cells_slot(
     164             :             Smi::ToInt(*possibly_feedback_cell_slot));
     165             :         feedback_cell = Handle<FeedbackCell>(
     166             :             FeedbackCell::cast(feedback_vector->Get(feedback_cells_slot)
     167             :                                    ->GetHeapObjectAssumeStrong()),
     168             :             isolate);
     169             :       }
     170             :       // Copy the function and update its context. Use it as value.
     171             :       Handle<SharedFunctionInfo> shared =
     172             :           Handle<SharedFunctionInfo>::cast(initial_value);
     173             :       Handle<JSFunction> function =
     174             :           isolate->factory()->NewFunctionFromSharedFunctionInfo(
     175             :               shared, context, feedback_cell, TENURED);
     176             :       value = function;
     177             :     } else {
     178             :       value = isolate->factory()->undefined_value();
     179             :     }
     180             : 
     181             :     // Compute the property attributes. According to ECMA-262,
     182             :     // the property must be non-configurable except in eval.
     183             :     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
     184             :     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
     185             :     int attr = NONE;
     186             :     if (is_function && is_native) attr |= READ_ONLY;
     187             :     if (!is_eval) attr |= DONT_DELETE;
     188             : 
     189             :     // ES#sec-globaldeclarationinstantiation 5.d:
     190             :     // If hasRestrictedGlobal is true, throw a SyntaxError exception.
     191             :     Object result = DeclareGlobal(isolate, global, name, value,
     192             :                                   static_cast<PropertyAttributes>(attr), is_var,
     193             :                                   is_function, RedeclarationType::kSyntaxError,
     194             :                                   feedback_vector, slot);
     195             :     if (isolate->has_pending_exception()) return result;
     196             :   });
     197             : 
     198      156687 :   return ReadOnlyRoots(isolate).undefined_value();
     199             : }
     200             : 
     201             : }  // namespace
     202             : 
     203      156746 : RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
     204      156736 :   HandleScope scope(isolate);
     205             :   DCHECK_EQ(3, args.length());
     206             : 
     207      313472 :   CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0);
     208      313472 :   CONVERT_SMI_ARG_CHECKED(flags, 1);
     209      313472 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 2);
     210             : 
     211             :   Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>();
     212      156736 :   if (closure->has_feedback_vector()) {
     213             :     feedback_vector =
     214      313472 :         Handle<FeedbackVector>(closure->feedback_vector(), isolate);
     215             :   }
     216      156736 :   return DeclareGlobals(isolate, declarations, flags, feedback_vector);
     217             : }
     218             : 
     219             : namespace {
     220             : 
     221      409618 : Object DeclareEvalHelper(Isolate* isolate, Handle<String> name,
     222             :                          Handle<Object> value) {
     223             :   // Declarations are always made in a function, native, eval, or script
     224             :   // context, or a declaration block scope. Since this is called from eval, the
     225             :   // context passed is the context of the caller, which may be some nested
     226             :   // context and not the declaration context.
     227      819236 :   Handle<Context> context(isolate->context()->declaration_context(), isolate);
     228             : 
     229             :   DCHECK(context->IsFunctionContext() || context->IsNativeContext() ||
     230             :          context->IsScriptContext() || context->IsEvalContext() ||
     231             :          (context->IsBlockContext() &&
     232             :           context->scope_info()->is_declaration_scope()));
     233             : 
     234      819236 :   bool is_function = value->IsJSFunction();
     235      409618 :   bool is_var = !is_function;
     236             :   DCHECK(!is_var || value->IsUndefined(isolate));
     237             : 
     238             :   int index;
     239             :   PropertyAttributes attributes;
     240             :   InitializationFlag init_flag;
     241             :   VariableMode mode;
     242             : 
     243             :   Handle<Object> holder =
     244             :       Context::Lookup(context, name, DONT_FOLLOW_CHAINS, &index, &attributes,
     245      409618 :                       &init_flag, &mode);
     246             :   DCHECK(holder.is_null() || !holder->IsModule());
     247             :   DCHECK(!isolate->has_pending_exception());
     248             : 
     249             :   Handle<JSObject> object;
     250             : 
     251      650932 :   if (attributes != ABSENT && holder->IsJSGlobalObject()) {
     252             :     // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b:
     253             :     // If fnDefinable is false, throw a TypeError exception.
     254             :     return DeclareGlobal(isolate, Handle<JSGlobalObject>::cast(holder), name,
     255             :                          value, NONE, is_var, is_function,
     256      116501 :                          RedeclarationType::kTypeError);
     257             :   }
     258      586234 :   if (context->extension()->IsJSGlobalObject()) {
     259        2168 :     Handle<JSGlobalObject> global(JSGlobalObject::cast(context->extension()),
     260        2168 :                                   isolate);
     261             :     return DeclareGlobal(isolate, global, name, value, NONE, is_var,
     262        1084 :                          is_function, RedeclarationType::kTypeError);
     263      292033 :   } else if (context->IsScriptContext()) {
     264             :     DCHECK(context->global_object()->IsJSGlobalObject());
     265             :     Handle<JSGlobalObject> global(
     266         108 :         JSGlobalObject::cast(context->global_object()), isolate);
     267             :     return DeclareGlobal(isolate, global, name, value, NONE, is_var,
     268          54 :                          is_function, RedeclarationType::kTypeError);
     269             :   }
     270             : 
     271      291979 :   if (attributes != ABSENT) {
     272             :     DCHECK_EQ(NONE, attributes);
     273             : 
     274             :     // Skip var re-declarations.
     275        7749 :     if (is_var) return ReadOnlyRoots(isolate).undefined_value();
     276             : 
     277             :     DCHECK(is_function);
     278         563 :     if (index != Context::kNotFound) {
     279             :       DCHECK(holder.is_identical_to(context));
     280         312 :       context->set(index, *value);
     281         104 :       return ReadOnlyRoots(isolate).undefined_value();
     282             :     }
     283             : 
     284         459 :     object = Handle<JSObject>::cast(holder);
     285             : 
     286      287823 :   } else if (context->has_extension()) {
     287      532046 :     object = handle(context->extension_object(), isolate);
     288             :     DCHECK(object->IsJSContextExtensionObject());
     289             :   } else {
     290             :     // Sloppy varblock and function contexts might not have an extension object
     291             :     // yet. Sloppy eval will never have an extension object, as vars are hoisted
     292             :     // out, and lets are known statically.
     293             :     DCHECK((context->IsBlockContext() &&
     294             :             context->scope_info()->is_declaration_scope()) ||
     295             :            context->IsFunctionContext());
     296             :     object =
     297       21800 :         isolate->factory()->NewJSObject(isolate->context_extension_function());
     298             : 
     299       43600 :     context->set_extension(*object);
     300             :   }
     301             : 
     302      576564 :   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
     303             :                                            object, name, value, NONE));
     304             : 
     305      288282 :   return ReadOnlyRoots(isolate).undefined_value();
     306             : }
     307             : 
     308             : }  // namespace
     309             : 
     310       10105 : RUNTIME_FUNCTION(Runtime_DeclareEvalFunction) {
     311       10105 :   HandleScope scope(isolate);
     312             :   DCHECK_EQ(2, args.length());
     313       20210 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     314       10105 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
     315       10105 :   return DeclareEvalHelper(isolate, name, value);
     316             : }
     317             : 
     318      399513 : RUNTIME_FUNCTION(Runtime_DeclareEvalVar) {
     319      399513 :   HandleScope scope(isolate);
     320             :   DCHECK_EQ(1, args.length());
     321      799026 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     322             :   return DeclareEvalHelper(isolate, name,
     323      799026 :                            isolate->factory()->undefined_value());
     324             : }
     325             : 
     326             : namespace {
     327             : 
     328             : // Find the arguments of the JavaScript function invocation that called
     329             : // into C++ code. Collect these in a newly allocated array of handles.
     330         121 : std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate,
     331             :                                                      int* total_argc) {
     332             :   // Find frame containing arguments passed to the caller.
     333         121 :   JavaScriptFrameIterator it(isolate);
     334             :   JavaScriptFrame* frame = it.frame();
     335             :   std::vector<SharedFunctionInfo> functions;
     336         121 :   frame->GetFunctions(&functions);
     337         242 :   if (functions.size() > 1) {
     338           0 :     int inlined_jsframe_index = static_cast<int>(functions.size()) - 1;
     339           0 :     TranslatedState translated_values(frame);
     340           0 :     translated_values.Prepare(frame->fp());
     341             : 
     342           0 :     int argument_count = 0;
     343             :     TranslatedFrame* translated_frame =
     344             :         translated_values.GetArgumentsInfoFromJSFrameIndex(
     345           0 :             inlined_jsframe_index, &argument_count);
     346             :     TranslatedFrame::iterator iter = translated_frame->begin();
     347             : 
     348             :     // Skip the function.
     349           0 :     iter++;
     350             : 
     351             :     // Skip the receiver.
     352           0 :     iter++;
     353           0 :     argument_count--;
     354             : 
     355           0 :     *total_argc = argument_count;
     356             :     std::unique_ptr<Handle<Object>[]> param_data(
     357           0 :         NewArray<Handle<Object>>(*total_argc));
     358             :     bool should_deoptimize = false;
     359           0 :     for (int i = 0; i < argument_count; i++) {
     360             :       // If we materialize any object, we should deoptimize the frame because we
     361             :       // might alias an object that was eliminated by escape analysis.
     362           0 :       should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
     363           0 :       Handle<Object> value = iter->GetValue();
     364           0 :       param_data[i] = value;
     365           0 :       iter++;
     366             :     }
     367             : 
     368           0 :     if (should_deoptimize) {
     369           0 :       translated_values.StoreMaterializedValuesAndDeopt(frame);
     370             :     }
     371             : 
     372             :     return param_data;
     373             :   } else {
     374         121 :     if (it.frame()->has_adapted_arguments()) {
     375             :       it.AdvanceOneFrame();
     376             :       DCHECK(it.frame()->is_arguments_adaptor());
     377             :     }
     378             :     frame = it.frame();
     379         121 :     int args_count = frame->ComputeParametersCount();
     380             : 
     381         121 :     *total_argc = args_count;
     382             :     std::unique_ptr<Handle<Object>[]> param_data(
     383         121 :         NewArray<Handle<Object>>(*total_argc));
     384     1573383 :     for (int i = 0; i < args_count; i++) {
     385     1573262 :       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
     386     3146524 :       param_data[i] = val;
     387             :     }
     388             :     return param_data;
     389             :   }
     390             : }
     391             : 
     392             : template <typename T>
     393         114 : Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
     394             :                                     T parameters, int argument_count) {
     395         228 :   CHECK(!IsDerivedConstructor(callee->shared()->kind()));
     396             :   DCHECK(callee->shared()->has_simple_parameters());
     397             :   Handle<JSObject> result =
     398         114 :       isolate->factory()->NewArgumentsObject(callee, argument_count);
     399             : 
     400             :   // Allocate the elements if needed.
     401         228 :   int parameter_count = callee->shared()->internal_formal_parameter_count();
     402         114 :   if (argument_count > 0) {
     403         109 :     if (parameter_count > 0) {
     404             :       int mapped_count = Min(argument_count, parameter_count);
     405             :       Handle<FixedArray> parameter_map =
     406         101 :           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
     407         101 :       parameter_map->set_map(
     408         202 :           ReadOnlyRoots(isolate).sloppy_arguments_elements_map());
     409         303 :       result->set_map(isolate->native_context()->fast_aliased_arguments_map());
     410         202 :       result->set_elements(*parameter_map);
     411             : 
     412             :       // Store the context and the arguments array at the beginning of the
     413             :       // parameter map.
     414             :       Handle<Context> context(isolate->context(), isolate);
     415             :       Handle<FixedArray> arguments =
     416         101 :           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
     417         202 :       parameter_map->set(0, *context);
     418         202 :       parameter_map->set(1, *arguments);
     419             : 
     420             :       // Loop over the actual parameters backwards.
     421         101 :       int index = argument_count - 1;
     422       69878 :       while (index >= mapped_count) {
     423             :         // These go directly in the arguments array and have no
     424             :         // corresponding slot in the parameter map.
     425       69721 :         arguments->set(index, parameters[index]);
     426       69676 :         --index;
     427             :       }
     428             : 
     429         202 :       Handle<ScopeInfo> scope_info(callee->shared()->scope_info(), isolate);
     430             : 
     431             :       // First mark all mappable slots as unmapped and copy the values into the
     432             :       // arguments object.
     433         456 :       for (int i = 0; i < mapped_count; i++) {
     434         707 :         arguments->set(i, parameters[i]);
     435         708 :         parameter_map->set_the_hole(i + 2);
     436             :       }
     437             : 
     438             :       // Walk all context slots to find context allocated parameters. Mark each
     439             :       // found parameter as mapped.
     440         359 :       for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
     441         129 :         if (!scope_info->ContextLocalIsParameter(i)) continue;
     442         129 :         int parameter = scope_info->ContextLocalParameterNumber(i);
     443         129 :         if (parameter >= mapped_count) continue;
     444         110 :         arguments->set_the_hole(parameter);
     445         110 :         Smi slot = Smi::FromInt(Context::MIN_CONTEXT_SLOTS + i);
     446             :         parameter_map->set(parameter + 2, slot);
     447             :       }
     448             :     } else {
     449             :       // If there is no aliasing, the arguments object elements are not
     450             :       // special in any way.
     451             :       Handle<FixedArray> elements =
     452           8 :           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
     453          16 :       result->set_elements(*elements);
     454      540600 :       for (int i = 0; i < argument_count; ++i) {
     455      540584 :         elements->set(i, parameters[i]);
     456             :       }
     457             :     }
     458             :   }
     459         114 :   return result;
     460             : }
     461             : 
     462             : class HandleArguments {
     463             :  public:
     464         105 :   explicit HandleArguments(Handle<Object>* array) : array_(array) {}
     465         796 :   Object operator[](int index) { return *array_[index]; }
     466             : 
     467             :  private:
     468             :   Handle<Object>* array_;
     469             : };
     470             : 
     471             : class ParameterArguments {
     472             :  public:
     473           9 :   explicit ParameterArguments(Address parameters) : parameters_(parameters) {}
     474             :   Object operator[](int index) {
     475      610216 :     return *FullObjectSlot(parameters_ - (index + 1) * kSystemPointerSize);
     476             :   }
     477             : 
     478             :  private:
     479             :   Address parameters_;
     480             : };
     481             : 
     482             : }  // namespace
     483             : 
     484             : 
     485         105 : RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) {
     486         105 :   HandleScope scope(isolate);
     487             :   DCHECK_EQ(1, args.length());
     488         210 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
     489             :   // This generic runtime function can also be used when the caller has been
     490             :   // inlined, we use the slow but accurate {GetCallerArguments}.
     491         105 :   int argument_count = 0;
     492             :   std::unique_ptr<Handle<Object>[]> arguments =
     493         210 :       GetCallerArguments(isolate, &argument_count);
     494         105 :   HandleArguments argument_getter(arguments.get());
     495         315 :   return *NewSloppyArguments(isolate, callee, argument_getter, argument_count);
     496             : }
     497             : 
     498             : 
     499           8 : RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
     500           8 :   HandleScope scope(isolate);
     501             :   DCHECK_EQ(1, args.length());
     502          16 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
     503             :   // This generic runtime function can also be used when the caller has been
     504             :   // inlined, we use the slow but accurate {GetCallerArguments}.
     505           8 :   int argument_count = 0;
     506             :   std::unique_ptr<Handle<Object>[]> arguments =
     507          16 :       GetCallerArguments(isolate, &argument_count);
     508             :   Handle<JSObject> result =
     509           8 :       isolate->factory()->NewArgumentsObject(callee, argument_count);
     510           8 :   if (argument_count) {
     511             :     Handle<FixedArray> array =
     512           8 :         isolate->factory()->NewUninitializedFixedArray(argument_count);
     513             :     DisallowHeapAllocation no_gc;
     514           8 :     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
     515      786432 :     for (int i = 0; i < argument_count; i++) {
     516     1572864 :       array->set(i, *arguments[i], mode);
     517             :     }
     518          16 :     result->set_elements(*array);
     519             :   }
     520           8 :   return *result;
     521             : }
     522             : 
     523             : 
     524           8 : RUNTIME_FUNCTION(Runtime_NewRestParameter) {
     525           8 :   HandleScope scope(isolate);
     526             :   DCHECK_EQ(1, args.length());
     527          16 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
     528           8 :   int start_index = callee->shared()->internal_formal_parameter_count();
     529             :   // This generic runtime function can also be used when the caller has been
     530             :   // inlined, we use the slow but accurate {GetCallerArguments}.
     531           8 :   int argument_count = 0;
     532             :   std::unique_ptr<Handle<Object>[]> arguments =
     533          16 :       GetCallerArguments(isolate, &argument_count);
     534           8 :   int num_elements = std::max(0, argument_count - start_index);
     535             :   Handle<JSObject> result = isolate->factory()->NewJSArray(
     536             :       PACKED_ELEMENTS, num_elements, num_elements,
     537           8 :       DONT_INITIALIZE_ARRAY_ELEMENTS);
     538             :   {
     539             :     DisallowHeapAllocation no_gc;
     540          16 :     FixedArray elements = FixedArray::cast(result->elements());
     541           8 :     WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
     542      786432 :     for (int i = 0; i < num_elements; i++) {
     543     1572864 :       elements->set(i, *arguments[i + start_index], mode);
     544             :     }
     545             :   }
     546           8 :   return *result;
     547             : }
     548             : 
     549             : 
     550           9 : RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
     551           9 :   HandleScope scope(isolate);
     552             :   DCHECK_EQ(1, args.length());
     553          18 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
     554          18 :   StackFrameIterator iterator(isolate);
     555             : 
     556             :   // Stub/interpreter handler frame
     557           9 :   iterator.Advance();
     558             :   DCHECK(iterator.frame()->type() == StackFrame::STUB);
     559             : 
     560             :   // Function frame
     561           9 :   iterator.Advance();
     562           9 :   JavaScriptFrame* function_frame = JavaScriptFrame::cast(iterator.frame());
     563             :   DCHECK(function_frame->is_java_script());
     564           9 :   int argc = function_frame->ComputeParametersCount();
     565           9 :   Address fp = function_frame->fp();
     566           9 :   if (function_frame->has_adapted_arguments()) {
     567           9 :     iterator.Advance();
     568             :     ArgumentsAdaptorFrame* adaptor_frame =
     569           9 :         ArgumentsAdaptorFrame::cast(iterator.frame());
     570           9 :     argc = adaptor_frame->ComputeParametersCount();
     571           9 :     fp = adaptor_frame->fp();
     572             :   }
     573             : 
     574             :   Address parameters =
     575           9 :       fp + argc * kSystemPointerSize + StandardFrameConstants::kCallerSPOffset;
     576           9 :   ParameterArguments argument_getter(parameters);
     577          27 :   return *NewSloppyArguments(isolate, callee, argument_getter, argc);
     578             : }
     579             : 
     580           4 : RUNTIME_FUNCTION(Runtime_NewArgumentsElements) {
     581           4 :   HandleScope scope(isolate);
     582             :   DCHECK_EQ(3, args.length());
     583             :   // Note that args[0] is the address of an array of full object pointers
     584             :   // (a.k.a. FullObjectSlot), which looks like a Smi because it's aligned.
     585             :   DCHECK(args[0].IsSmi());
     586           4 :   FullObjectSlot frame(args[0]->ptr());
     587           8 :   CONVERT_SMI_ARG_CHECKED(length, 1);
     588           8 :   CONVERT_SMI_ARG_CHECKED(mapped_count, 2);
     589             :   Handle<FixedArray> result =
     590           4 :       isolate->factory()->NewUninitializedFixedArray(length);
     591           4 :   int const offset = length + 1;
     592             :   DisallowHeapAllocation no_gc;
     593           4 :   WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
     594           4 :   int number_of_holes = Min(mapped_count, length);
     595           0 :   for (int index = 0; index < number_of_holes; ++index) {
     596           0 :     result->set_the_hole(isolate, index);
     597             :   }
     598      343976 :   for (int index = number_of_holes; index < length; ++index) {
     599      687952 :     result->set(index, *(frame + (offset - index)), mode);
     600             :   }
     601           4 :   return *result;
     602             : }
     603             : 
     604     5178875 : RUNTIME_FUNCTION(Runtime_NewClosure) {
     605     5178875 :   HandleScope scope(isolate);
     606             :   DCHECK_EQ(2, args.length());
     607    10357796 :   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
     608    10357822 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackCell, feedback_cell, 1);
     609     5178912 :   Handle<Context> context(isolate->context(), isolate);
     610             :   Handle<JSFunction> function =
     611             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(
     612     5178911 :           shared, context, feedback_cell, NOT_TENURED);
     613     5178902 :   return *function;
     614             : }
     615             : 
     616      212628 : RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) {
     617      212628 :   HandleScope scope(isolate);
     618             :   DCHECK_EQ(2, args.length());
     619      425256 :   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
     620      425256 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackCell, feedback_cell, 1);
     621      212628 :   Handle<Context> context(isolate->context(), isolate);
     622             :   // The caller ensures that we pretenure closures that are assigned
     623             :   // directly to properties.
     624             :   Handle<JSFunction> function =
     625             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(
     626      212628 :           shared, context, feedback_cell, TENURED);
     627      212628 :   return *function;
     628             : }
     629             : 
     630       18104 : static Object FindNameClash(Isolate* isolate, Handle<ScopeInfo> scope_info,
     631             :                             Handle<JSGlobalObject> global_object,
     632             :                             Handle<ScriptContextTable> script_context) {
     633     1798638 :   for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
     634     1762604 :     Handle<String> name(scope_info->ContextLocalName(var), isolate);
     635      881302 :     VariableMode mode = scope_info->ContextLocalMode(var);
     636             :     ScriptContextTable::LookupResult lookup;
     637      881302 :     if (ScriptContextTable::Lookup(isolate, script_context, name, &lookup)) {
     638          49 :       if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
     639             :         // ES#sec-globaldeclarationinstantiation 5.b:
     640             :         // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
     641             :         // exception.
     642             :         return ThrowRedeclarationError(isolate, name,
     643         136 :                                        RedeclarationType::kSyntaxError);
     644             :       }
     645             :     }
     646             : 
     647      881253 :     if (IsLexicalVariableMode(mode)) {
     648             :       LookupIterator it(global_object, name, global_object,
     649      881253 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
     650      881253 :       Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
     651      881253 :       if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
     652      881253 :       if ((maybe.FromJust() & DONT_DELETE) != 0) {
     653             :         // ES#sec-globaldeclarationinstantiation 5.a:
     654             :         // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
     655             :         // exception.
     656             :         // ES#sec-globaldeclarationinstantiation 5.d:
     657             :         // If hasRestrictedGlobal is true, throw a SyntaxError exception.
     658             :         return ThrowRedeclarationError(isolate, name,
     659          38 :                                        RedeclarationType::kSyntaxError);
     660             :       }
     661             : 
     662      881215 :       JSGlobalObject::InvalidatePropertyCell(global_object, name);
     663             :     }
     664             :   }
     665       18017 :   return ReadOnlyRoots(isolate).undefined_value();
     666             : }
     667             : 
     668       18104 : RUNTIME_FUNCTION(Runtime_NewScriptContext) {
     669       18104 :   HandleScope scope(isolate);
     670             :   DCHECK_EQ(1, args.length());
     671             : 
     672       36208 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
     673             :   Handle<NativeContext> native_context(NativeContext::cast(isolate->context()),
     674       36208 :                                        isolate);
     675       36208 :   Handle<JSGlobalObject> global_object(native_context->global_object(),
     676       18104 :                                        isolate);
     677             :   Handle<ScriptContextTable> script_context_table(
     678       36208 :       native_context->script_context_table(), isolate);
     679             : 
     680             :   Object name_clash_result =
     681       18104 :       FindNameClash(isolate, scope_info, global_object, script_context_table);
     682       18104 :   if (isolate->has_pending_exception()) return name_clash_result;
     683             : 
     684             :   // We do not need script contexts here during bootstrap.
     685             :   DCHECK(!isolate->bootstrapper()->IsActive());
     686             : 
     687             :   Handle<Context> result =
     688       18017 :       isolate->factory()->NewScriptContext(native_context, scope_info);
     689             : 
     690             :   Handle<ScriptContextTable> new_script_context_table =
     691       18017 :       ScriptContextTable::Extend(script_context_table, result);
     692       18017 :   native_context->set_script_context_table(*new_script_context_table);
     693       18104 :   return *result;
     694             : }
     695             : 
     696          23 : RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
     697          23 :   HandleScope scope(isolate);
     698             :   DCHECK_EQ(1, args.length());
     699             : 
     700          46 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
     701             : 
     702          23 :   Handle<Context> outer(isolate->context(), isolate);
     703          46 :   return *isolate->factory()->NewFunctionContext(outer, scope_info);
     704             : }
     705             : 
     706      243653 : RUNTIME_FUNCTION(Runtime_PushWithContext) {
     707      243653 :   HandleScope scope(isolate);
     708             :   DCHECK_EQ(2, args.length());
     709      487306 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, extension_object, 0);
     710      487306 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
     711      243653 :   Handle<Context> current(isolate->context(), isolate);
     712             :   Handle<Context> context =
     713      243653 :       isolate->factory()->NewWithContext(current, scope_info, extension_object);
     714      243653 :   isolate->set_context(*context);
     715      243653 :   return *context;
     716             : }
     717             : 
     718        1543 : RUNTIME_FUNCTION(Runtime_PushModuleContext) {
     719        1543 :   HandleScope scope(isolate);
     720             :   DCHECK_EQ(2, args.length());
     721        3086 :   CONVERT_ARG_HANDLE_CHECKED(Module, module, 0);
     722        3086 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
     723             : 
     724        3086 :   Handle<NativeContext> outer(NativeContext::cast(isolate->context()), isolate);
     725             :   Handle<Context> context =
     726        1543 :       isolate->factory()->NewModuleContext(module, outer, scope_info);
     727        1543 :   isolate->set_context(*context);
     728        1543 :   return *context;
     729             : }
     730             : 
     731      805783 : RUNTIME_FUNCTION(Runtime_PushCatchContext) {
     732      805783 :   HandleScope scope(isolate);
     733             :   DCHECK_EQ(2, args.length());
     734      805783 :   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 0);
     735     1611566 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
     736      805783 :   Handle<Context> current(isolate->context(), isolate);
     737             :   Handle<Context> context =
     738      805783 :       isolate->factory()->NewCatchContext(current, scope_info, thrown_object);
     739      805783 :   isolate->set_context(*context);
     740      805783 :   return *context;
     741             : }
     742             : 
     743             : 
     744      181058 : RUNTIME_FUNCTION(Runtime_PushBlockContext) {
     745      181058 :   HandleScope scope(isolate);
     746             :   DCHECK_EQ(1, args.length());
     747      362122 :   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
     748      181062 :   Handle<Context> current(isolate->context(), isolate);
     749             :   Handle<Context> context =
     750      181060 :       isolate->factory()->NewBlockContext(current, scope_info);
     751      181061 :   isolate->set_context(*context);
     752      181060 :   return *context;
     753             : }
     754             : 
     755             : 
     756      900911 : RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
     757      900911 :   HandleScope scope(isolate);
     758             :   DCHECK_EQ(1, args.length());
     759     1801822 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     760             : 
     761             :   int index;
     762             :   PropertyAttributes attributes;
     763             :   InitializationFlag flag;
     764             :   VariableMode mode;
     765      900911 :   Handle<Context> context(isolate->context(), isolate);
     766             :   Handle<Object> holder = Context::Lookup(context, name, FOLLOW_CHAINS, &index,
     767      900911 :                                           &attributes, &flag, &mode);
     768             : 
     769             :   // If the slot was not found the result is true.
     770      900911 :   if (holder.is_null()) {
     771             :     // In case of JSProxy, an exception might have been thrown.
     772      900060 :     if (isolate->has_pending_exception())
     773             :       return ReadOnlyRoots(isolate).exception();
     774             :     return ReadOnlyRoots(isolate).true_value();
     775             :   }
     776             : 
     777             :   // If the slot was found in a context or in module imports and exports it
     778             :   // should be DONT_DELETE.
     779        3188 :   if (holder->IsContext() || holder->IsModule()) {
     780             :     return ReadOnlyRoots(isolate).false_value();
     781             :   }
     782             : 
     783             :   // The slot was found in a JSReceiver, either a context extension object,
     784             :   // the global object, or the subject of a with.  Try to delete it
     785             :   // (respecting DONT_DELETE).
     786         743 :   Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
     787         743 :   Maybe<bool> result = JSReceiver::DeleteProperty(object, name);
     788         743 :   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
     789         743 :   return isolate->heap()->ToBoolean(result.FromJust());
     790             : }
     791             : 
     792             : 
     793             : namespace {
     794             : 
     795     2555454 : MaybeHandle<Object> LoadLookupSlot(Isolate* isolate, Handle<String> name,
     796             :                                    ShouldThrow should_throw,
     797             :                                    Handle<Object>* receiver_return = nullptr) {
     798             :   int index;
     799             :   PropertyAttributes attributes;
     800             :   InitializationFlag flag;
     801             :   VariableMode mode;
     802             :   Handle<Context> context(isolate->context(), isolate);
     803             :   Handle<Object> holder = Context::Lookup(context, name, FOLLOW_CHAINS, &index,
     804     2555454 :                                           &attributes, &flag, &mode);
     805     2555454 :   if (isolate->has_pending_exception()) return MaybeHandle<Object>();
     806             : 
     807     7665609 :   if (!holder.is_null() && holder->IsModule()) {
     808             :     Handle<Object> receiver = isolate->factory()->undefined_value();
     809         165 :     if (receiver_return) *receiver_return = receiver;
     810         165 :     return Module::LoadVariable(isolate, Handle<Module>::cast(holder), index);
     811             :   }
     812     2555256 :   if (index != Context::kNotFound) {
     813             :     DCHECK(holder->IsContext());
     814             :     // If the "property" we were looking for is a local variable, the
     815             :     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
     816             :     Handle<Object> receiver = isolate->factory()->undefined_value();
     817      564138 :     Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate);
     818             :     // Check for uninitialized bindings.
     819      283811 :     if (flag == kNeedsInitialization && value->IsTheHole(isolate)) {
     820         234 :       THROW_NEW_ERROR(isolate,
     821             :                       NewReferenceError(MessageTemplate::kNotDefined, name),
     822             :                       Object);
     823             :     }
     824             :     DCHECK(!value->IsTheHole(isolate));
     825      281835 :     if (receiver_return) *receiver_return = receiver;
     826      281835 :     return value;
     827             :   }
     828             : 
     829             :   // Otherwise, if the slot was found the holder is a context extension
     830             :   // object, subject of a with, or a global object.  We read the named
     831             :   // property from it.
     832     2273187 :   if (!holder.is_null()) {
     833             :     // No need to unhole the value here.  This is taken care of by the
     834             :     // GetProperty function.
     835             :     Handle<Object> value;
     836     4545720 :     ASSIGN_RETURN_ON_EXCEPTION(
     837             :         isolate, value, Object::GetProperty(isolate, holder, name), Object);
     838     2272833 :     if (receiver_return) {
     839             :       *receiver_return =
     840      856728 :           (holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject())
     841             :               ? Handle<Object>::cast(isolate->factory()->undefined_value())
     842      818408 :               : holder;
     843             :     }
     844     2272833 :     return value;
     845             :   }
     846             : 
     847         327 :   if (should_throw == kThrowOnError) {
     848             :     // The property doesn't exist - throw exception.
     849         273 :     THROW_NEW_ERROR(
     850             :         isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
     851             :   }
     852             : 
     853             :   // The property doesn't exist - return undefined.
     854          54 :   if (receiver_return) *receiver_return = isolate->factory()->undefined_value();
     855          54 :   return isolate->factory()->undefined_value();
     856             : }
     857             : 
     858             : }  // namespace
     859             : 
     860             : 
     861     2139696 : RUNTIME_FUNCTION(Runtime_LoadLookupSlot) {
     862     2139696 :   HandleScope scope(isolate);
     863             :   DCHECK_EQ(1, args.length());
     864     4279392 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     865     4279392 :   RETURN_RESULT_OR_FAILURE(isolate,
     866     2139696 :                            LoadLookupSlot(isolate, name, kThrowOnError));
     867             : }
     868             : 
     869             : 
     870         304 : RUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) {
     871         304 :   HandleScope scope(isolate);
     872             :   DCHECK_EQ(1, args.length());
     873         608 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     874         912 :   RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(isolate, name, kDontThrow));
     875             : }
     876             : 
     877             : 
     878      415454 : RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) {
     879      415454 :   HandleScope scope(isolate);
     880             :   DCHECK_EQ(1, args.length());
     881             :   DCHECK(args[0]->IsString());
     882      415454 :   Handle<String> name = args.at<String>(0);
     883             :   Handle<Object> value;
     884             :   Handle<Object> receiver;
     885      830926 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     886             :       isolate, value, LoadLookupSlot(isolate, name, kThrowOnError, &receiver),
     887             :       MakePair(ReadOnlyRoots(isolate).exception(), Object()));
     888      415436 :   return MakePair(*value, *receiver);
     889             : }
     890             : 
     891             : 
     892             : namespace {
     893             : 
     894     2669759 : MaybeHandle<Object> StoreLookupSlot(
     895             :     Isolate* isolate, Handle<Context> context, Handle<String> name,
     896             :     Handle<Object> value, LanguageMode language_mode,
     897             :     ContextLookupFlags context_lookup_flags = FOLLOW_CHAINS) {
     898             :   int index;
     899             :   PropertyAttributes attributes;
     900             :   InitializationFlag flag;
     901             :   VariableMode mode;
     902             :   bool is_sloppy_function_name;
     903             :   Handle<Object> holder =
     904             :       Context::Lookup(context, name, context_lookup_flags, &index, &attributes,
     905     2669759 :                       &flag, &mode, &is_sloppy_function_name);
     906     2669759 :   if (holder.is_null()) {
     907             :     // In case of JSProxy, an exception might have been thrown.
     908         545 :     if (isolate->has_pending_exception()) return MaybeHandle<Object>();
     909     5338428 :   } else if (holder->IsModule()) {
     910          70 :     if ((attributes & READ_ONLY) == 0) {
     911          50 :       Module::StoreVariable(Handle<Module>::cast(holder), index, value);
     912             :     } else {
     913          20 :       THROW_NEW_ERROR(
     914             :           isolate, NewTypeError(MessageTemplate::kConstAssign, name), Object);
     915             :     }
     916          50 :     return value;
     917             :   }
     918             :   // The property was found in a context slot.
     919     2669647 :   if (index != Context::kNotFound) {
     920     4222254 :     if (flag == kNeedsInitialization &&
     921     1410466 :         Handle<Context>::cast(holder)->get(index)->IsTheHole(isolate)) {
     922          54 :       THROW_NEW_ERROR(isolate,
     923             :                       NewReferenceError(MessageTemplate::kNotDefined, name),
     924             :                       Object);
     925             :     }
     926     1407364 :     if ((attributes & READ_ONLY) == 0) {
     927     4221822 :       Handle<Context>::cast(holder)->set(index, *value);
     928          90 :     } else if (!is_sloppy_function_name || is_strict(language_mode)) {
     929          36 :       THROW_NEW_ERROR(
     930             :           isolate, NewTypeError(MessageTemplate::kConstAssign, name), Object);
     931             :     }
     932     1407328 :     return value;
     933             :   }
     934             : 
     935             :   // Slow case: The property is not in a context slot.  It is either in a
     936             :   // context extension object, a property of the subject of a with, or a
     937             :   // property of the global object.
     938             :   Handle<JSReceiver> object;
     939     1262229 :   if (attributes != ABSENT) {
     940             :     // The property exists on the holder.
     941     1261726 :     object = Handle<JSReceiver>::cast(holder);
     942         503 :   } else if (is_strict(language_mode)) {
     943             :     // If absent in strict mode: throw.
     944          29 :     THROW_NEW_ERROR(
     945             :         isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
     946             :   } else {
     947             :     // If absent in sloppy mode: add the property to the global object.
     948         948 :     object = handle(context->global_object(), isolate);
     949             :   }
     950             : 
     951     2524400 :   ASSIGN_RETURN_ON_EXCEPTION(
     952             :       isolate, value,
     953             :       Object::SetProperty(isolate, object, name, value, language_mode), Object);
     954     1262110 :   return value;
     955             : }
     956             : 
     957             : }  // namespace
     958             : 
     959             : 
     960     2666480 : RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) {
     961     2666480 :   HandleScope scope(isolate);
     962             :   DCHECK_EQ(2, args.length());
     963     5332960 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     964     2666480 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
     965     2666480 :   Handle<Context> context(isolate->context(), isolate);
     966     5332960 :   RETURN_RESULT_OR_FAILURE(
     967             :       isolate,
     968     2666480 :       StoreLookupSlot(isolate, context, name, value, LanguageMode::kSloppy));
     969             : }
     970             : 
     971        2748 : RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) {
     972        2748 :   HandleScope scope(isolate);
     973             :   DCHECK_EQ(2, args.length());
     974        5496 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     975        2748 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
     976        2748 :   Handle<Context> context(isolate->context(), isolate);
     977        5496 :   RETURN_RESULT_OR_FAILURE(
     978             :       isolate,
     979        2748 :       StoreLookupSlot(isolate, context, name, value, LanguageMode::kStrict));
     980             : }
     981             : 
     982             : // Store into a dynamic declaration context for sloppy-mode block-scoped
     983             : // function hoisting which leaks out of an eval.
     984         531 : RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) {
     985         531 :   HandleScope scope(isolate);
     986             :   DCHECK_EQ(2, args.length());
     987        1062 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
     988         531 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
     989             :   const ContextLookupFlags lookup_flags =
     990             :       static_cast<ContextLookupFlags>(DONT_FOLLOW_CHAINS);
     991             :   Handle<Context> declaration_context(isolate->context()->declaration_context(),
     992        1062 :                                       isolate);
     993        1062 :   RETURN_RESULT_OR_FAILURE(
     994             :       isolate, StoreLookupSlot(isolate, declaration_context, name, value,
     995         531 :                                LanguageMode::kSloppy, lookup_flags));
     996             : }
     997             : 
     998             : }  // namespace internal
     999      183867 : }  // namespace v8

Generated by: LCOV version 1.10