diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-scopes.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-scopes.cc | 175 |
1 files changed, 91 insertions, 84 deletions
diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index 7a24b066c1..8227242940 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -8,11 +8,14 @@ #include "src/arguments-inl.h" #include "src/ast/scopes.h" #include "src/bootstrapper.h" +#include "src/counters.h" #include "src/deoptimizer.h" #include "src/frames-inl.h" #include "src/isolate-inl.h" -#include "src/messages.h" +#include "src/message-template.h" +#include "src/objects/heap-object-inl.h" #include "src/objects/module-inl.h" +#include "src/objects/smi.h" #include "src/runtime/runtime-utils.h" namespace v8 { @@ -28,8 +31,8 @@ namespace { enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 }; -Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name, - RedeclarationType redeclaration_type) { +Object ThrowRedeclarationError(Isolate* isolate, Handle<String> name, + RedeclarationType redeclaration_type) { HandleScope scope(isolate); if (redeclaration_type == RedeclarationType::kSyntaxError) { THROW_NEW_ERROR_RETURN_FAILURE( @@ -40,9 +43,8 @@ Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name, } } - // May throw a RedeclarationError. -Object* DeclareGlobal( +Object DeclareGlobal( Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, Handle<Object> value, PropertyAttributes attr, bool is_var, bool is_function_declaration, RedeclarationType redeclaration_type, @@ -130,8 +132,8 @@ Object* DeclareGlobal( return ReadOnlyRoots(isolate).undefined_value(); } -Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, - int flags, Handle<FeedbackVector> feedback_vector) { +Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, + int flags, Handle<FeedbackVector> feedback_vector) { HandleScope scope(isolate); Handle<JSGlobalObject> global(isolate->global_object()); Handle<Context> context(isolate->context(), isolate); @@ -147,20 +149,27 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, bool is_var = initial_value->IsUndefined(isolate); bool is_function = initial_value->IsSharedFunctionInfo(); - DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); + DCHECK_NE(is_var, is_function); Handle<Object> value; if (is_function) { - DCHECK(possibly_feedback_cell_slot->IsSmi()); + // If feedback vector was not allocated for this function, then we don't + // have any information about number of closures. Use NoFeedbackCell to + // indicate that. + Handle<FeedbackCell> feedback_cell = + isolate->factory()->no_feedback_cell(); + if (!feedback_vector.is_null()) { + DCHECK(possibly_feedback_cell_slot->IsSmi()); + FeedbackSlot feedback_cells_slot( + Smi::ToInt(*possibly_feedback_cell_slot)); + feedback_cell = Handle<FeedbackCell>( + FeedbackCell::cast(feedback_vector->Get(feedback_cells_slot) + ->GetHeapObjectAssumeStrong()), + isolate); + } // Copy the function and update its context. Use it as value. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(initial_value); - FeedbackSlot feedback_cells_slot( - Smi::ToInt(*possibly_feedback_cell_slot)); - Handle<FeedbackCell> feedback_cell( - FeedbackCell::cast(feedback_vector->Get(feedback_cells_slot) - ->GetHeapObjectAssumeStrong()), - isolate); Handle<JSFunction> function = isolate->factory()->NewFunctionFromSharedFunctionInfo( shared, context, feedback_cell, TENURED); @@ -179,10 +188,10 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, // ES#sec-globaldeclarationinstantiation 5.d: // If hasRestrictedGlobal is true, throw a SyntaxError exception. - Object* result = DeclareGlobal( - isolate, global, name, value, static_cast<PropertyAttributes>(attr), - is_var, is_function, RedeclarationType::kSyntaxError, feedback_vector, - slot); + Object result = DeclareGlobal(isolate, global, name, value, + static_cast<PropertyAttributes>(attr), is_var, + is_function, RedeclarationType::kSyntaxError, + feedback_vector, slot); if (isolate->has_pending_exception()) return result; }); @@ -199,20 +208,23 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobals) { CONVERT_SMI_ARG_CHECKED(flags, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 2); - Handle<FeedbackVector> feedback_vector(closure->feedback_vector(), isolate); + Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>(); + if (closure->has_feedback_vector()) { + feedback_vector = + Handle<FeedbackVector>(closure->feedback_vector(), isolate); + } return DeclareGlobals(isolate, declarations, flags, feedback_vector); } namespace { -Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, - Handle<Object> value) { +Object DeclareEvalHelper(Isolate* isolate, Handle<String> name, + Handle<Object> value) { // Declarations are always made in a function, native, eval, or script // context, or a declaration block scope. Since this is called from eval, the // context passed is the context of the caller, which may be some nested // context and not the declaration context. - Handle<Context> context_arg(isolate->context(), isolate); - Handle<Context> context(context_arg->declaration_context(), isolate); + Handle<Context> context(isolate->context()->declaration_context(), isolate); DCHECK(context->IsFunctionContext() || context->IsNativeContext() || context->IsScriptContext() || context->IsEvalContext() || @@ -228,23 +240,9 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, InitializationFlag init_flag; VariableMode mode; - // Check for a conflict with a lexically scoped variable - const ContextLookupFlags lookup_flags = static_cast<ContextLookupFlags>( - FOLLOW_CONTEXT_CHAIN | STOP_AT_DECLARATION_SCOPE | SKIP_WITH_CONTEXT); - context_arg->Lookup(name, lookup_flags, &index, &attributes, &init_flag, - &mode); - if (attributes != ABSENT && IsLexicalVariableMode(mode)) { - // ES#sec-evaldeclarationinstantiation 5.a.i.1: - // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError - // exception. - // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i: - // Throw a SyntaxError exception. - return ThrowRedeclarationError(isolate, name, - RedeclarationType::kSyntaxError); - } - - Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, - &attributes, &init_flag, &mode); + Handle<Object> holder = + Context::Lookup(context, name, DONT_FOLLOW_CHAINS, &index, &attributes, + &init_flag, &mode); DCHECK(holder.is_null() || !holder->IsModule()); DCHECK(!isolate->has_pending_exception()); @@ -257,9 +255,9 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, value, NONE, is_var, is_function, RedeclarationType::kTypeError); } - if (context_arg->extension()->IsJSGlobalObject()) { - Handle<JSGlobalObject> global( - JSGlobalObject::cast(context_arg->extension()), isolate); + if (context->extension()->IsJSGlobalObject()) { + Handle<JSGlobalObject> global(JSGlobalObject::cast(context->extension()), + isolate); return DeclareGlobal(isolate, global, name, value, NONE, is_var, is_function, RedeclarationType::kTypeError); } else if (context->IsScriptContext()) { @@ -287,7 +285,7 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, } else if (context->has_extension()) { object = handle(context->extension_object(), isolate); - DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); + DCHECK(object->IsJSContextExtensionObject()); } else { // Sloppy varblock and function contexts might not have an extension object // yet. Sloppy eval will never have an extension object, as vars are hoisted @@ -334,7 +332,7 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, // Find frame containing arguments passed to the caller. JavaScriptFrameIterator it(isolate); JavaScriptFrame* frame = it.frame(); - std::vector<SharedFunctionInfo*> functions; + std::vector<SharedFunctionInfo> functions; frame->GetFunctions(&functions); if (functions.size() > 1) { int inlined_jsframe_index = static_cast<int>(functions.size()) - 1; @@ -444,7 +442,7 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, int parameter = scope_info->ContextLocalParameterNumber(i); if (parameter >= mapped_count) continue; arguments->set_the_hole(parameter); - Smi* slot = Smi::FromInt(Context::MIN_CONTEXT_SLOTS + i); + Smi slot = Smi::FromInt(Context::MIN_CONTEXT_SLOTS + i); parameter_map->set(parameter + 2, slot); } } else { @@ -464,7 +462,7 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, class HandleArguments { public: explicit HandleArguments(Handle<Object>* array) : array_(array) {} - Object* operator[](int index) { return *array_[index]; } + Object operator[](int index) { return *array_[index]; } private: Handle<Object>* array_; @@ -472,11 +470,13 @@ class HandleArguments { class ParameterArguments { public: - explicit ParameterArguments(Object** parameters) : parameters_(parameters) {} - Object*& operator[](int index) { return *(parameters_ - index - 1); } + explicit ParameterArguments(Address parameters) : parameters_(parameters) {} + Object operator[](int index) { + return *FullObjectSlot(parameters_ - (index + 1) * kSystemPointerSize); + } private: - Object** parameters_; + Address parameters_; }; } // namespace @@ -537,7 +537,7 @@ RUNTIME_FUNCTION(Runtime_NewRestParameter) { DONT_INITIALIZE_ARRAY_ELEMENTS); { DisallowHeapAllocation no_gc; - FixedArray* elements = FixedArray::cast(result->elements()); + FixedArray elements = FixedArray::cast(result->elements()); WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); for (int i = 0; i < num_elements; i++) { elements->set(i, *arguments[i + start_index], mode); @@ -571,8 +571,8 @@ RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { fp = adaptor_frame->fp(); } - Object** parameters = reinterpret_cast<Object**>( - fp + argc * kPointerSize + StandardFrameConstants::kCallerSPOffset); + Address parameters = + fp + argc * kSystemPointerSize + StandardFrameConstants::kCallerSPOffset; ParameterArguments argument_getter(parameters); return *NewSloppyArguments(isolate, callee, argument_getter, argc); } @@ -580,7 +580,10 @@ RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { RUNTIME_FUNCTION(Runtime_NewArgumentsElements) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); - Object** frame = reinterpret_cast<Object**>(args[0]); + // Note that args[0] is the address of an array of full object pointers + // (a.k.a. FullObjectSlot), which looks like a Smi because it's aligned. + DCHECK(args[0].IsSmi()); + FullObjectSlot frame(args[0]->ptr()); CONVERT_SMI_ARG_CHECKED(length, 1); CONVERT_SMI_ARG_CHECKED(mapped_count, 2); Handle<FixedArray> result = @@ -593,7 +596,7 @@ RUNTIME_FUNCTION(Runtime_NewArgumentsElements) { result->set_the_hole(isolate, index); } for (int index = number_of_holes; index < length; ++index) { - result->set(index, frame[offset - index], mode); + result->set(index, *(frame + (offset - index)), mode); } return *result; } @@ -624,9 +627,9 @@ RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) { return *function; } -static Object* FindNameClash(Isolate* isolate, Handle<ScopeInfo> scope_info, - Handle<JSGlobalObject> global_object, - Handle<ScriptContextTable> script_context) { +static Object FindNameClash(Isolate* isolate, Handle<ScopeInfo> scope_info, + Handle<JSGlobalObject> global_object, + Handle<ScriptContextTable> script_context) { for (int var = 0; var < scope_info->ContextLocalCount(); var++) { Handle<String> name(scope_info->ContextLocalName(var), isolate); VariableMode mode = scope_info->ContextLocalMode(var); @@ -662,7 +665,6 @@ static Object* FindNameClash(Isolate* isolate, Handle<ScopeInfo> scope_info, return ReadOnlyRoots(isolate).undefined_value(); } - RUNTIME_FUNCTION(Runtime_NewScriptContext) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -675,7 +677,7 @@ RUNTIME_FUNCTION(Runtime_NewScriptContext) { Handle<ScriptContextTable> script_context_table( native_context->script_context_table(), isolate); - Object* name_clash_result = + Object name_clash_result = FindNameClash(isolate, scope_info, global_object, script_context_table); if (isolate->has_pending_exception()) return name_clash_result; @@ -760,8 +762,9 @@ RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { PropertyAttributes attributes; InitializationFlag flag; VariableMode mode; - Handle<Object> holder = isolate->context()->Lookup( - name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); + Handle<Context> context(isolate->context(), isolate); + Handle<Object> holder = Context::Lookup(context, name, FOLLOW_CHAINS, &index, + &attributes, &flag, &mode); // If the slot was not found the result is true. if (holder.is_null()) { @@ -796,8 +799,9 @@ MaybeHandle<Object> LoadLookupSlot(Isolate* isolate, Handle<String> name, PropertyAttributes attributes; InitializationFlag flag; VariableMode mode; - Handle<Object> holder = isolate->context()->Lookup( - name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); + Handle<Context> context(isolate->context(), isolate); + Handle<Object> holder = Context::Lookup(context, name, FOLLOW_CHAINS, &index, + &attributes, &flag, &mode); if (isolate->has_pending_exception()) return MaybeHandle<Object>(); if (!holder.is_null() && holder->IsModule()) { @@ -880,7 +884,7 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) { Handle<Object> receiver; ASSIGN_RETURN_ON_EXCEPTION_VALUE( isolate, value, LoadLookupSlot(isolate, name, kThrowOnError, &receiver), - MakePair(ReadOnlyRoots(isolate).exception(), nullptr)); + MakePair(ReadOnlyRoots(isolate).exception(), Object())); return MakePair(*value, *receiver); } @@ -888,19 +892,17 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) { namespace { MaybeHandle<Object> StoreLookupSlot( - Isolate* isolate, Handle<String> name, Handle<Object> value, - LanguageMode language_mode, + Isolate* isolate, Handle<Context> context, Handle<String> name, + Handle<Object> value, LanguageMode language_mode, ContextLookupFlags context_lookup_flags = FOLLOW_CHAINS) { - Handle<Context> context(isolate->context(), isolate); - int index; PropertyAttributes attributes; InitializationFlag flag; VariableMode mode; bool is_sloppy_function_name; Handle<Object> holder = - context->Lookup(name, context_lookup_flags, &index, &attributes, &flag, - &mode, &is_sloppy_function_name); + Context::Lookup(context, name, context_lookup_flags, &index, &attributes, + &flag, &mode, &is_sloppy_function_name); if (holder.is_null()) { // In case of JSProxy, an exception might have been thrown. if (isolate->has_pending_exception()) return MaybeHandle<Object>(); @@ -916,7 +918,7 @@ MaybeHandle<Object> StoreLookupSlot( // The property was found in a context slot. if (index != Context::kNotFound) { if (flag == kNeedsInitialization && - Handle<Context>::cast(holder)->is_the_hole(isolate, index)) { + Handle<Context>::cast(holder)->get(index)->IsTheHole(isolate)) { THROW_NEW_ERROR(isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); @@ -960,32 +962,37 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + Handle<Context> context(isolate->context(), isolate); RETURN_RESULT_OR_FAILURE( - isolate, StoreLookupSlot(isolate, name, value, LanguageMode::kSloppy)); + isolate, + StoreLookupSlot(isolate, context, name, value, LanguageMode::kSloppy)); } -// Store into a dynamic context for sloppy-mode block-scoped function hoisting -// which leaks out of an eval. In particular, with-scopes are be skipped to -// reach the appropriate var-like declaration. -RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) { +RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); - const ContextLookupFlags lookup_flags = static_cast<ContextLookupFlags>( - FOLLOW_CONTEXT_CHAIN | STOP_AT_DECLARATION_SCOPE | SKIP_WITH_CONTEXT); + Handle<Context> context(isolate->context(), isolate); RETURN_RESULT_OR_FAILURE( - isolate, StoreLookupSlot(isolate, name, value, LanguageMode::kSloppy, - lookup_flags)); + isolate, + StoreLookupSlot(isolate, context, name, value, LanguageMode::kStrict)); } -RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { +// Store into a dynamic declaration context for sloppy-mode block-scoped +// function hoisting which leaks out of an eval. +RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + const ContextLookupFlags lookup_flags = + static_cast<ContextLookupFlags>(DONT_FOLLOW_CHAINS); + Handle<Context> declaration_context(isolate->context()->declaration_context(), + isolate); RETURN_RESULT_OR_FAILURE( - isolate, StoreLookupSlot(isolate, name, value, LanguageMode::kStrict)); + isolate, StoreLookupSlot(isolate, declaration_context, name, value, + LanguageMode::kSloppy, lookup_flags)); } } // namespace internal |