summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-scopes.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-scopes.cc')
-rw-r--r--deps/v8/src/runtime/runtime-scopes.cc175
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