Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/debug/debug-scopes.cc b/src/debug/debug-scopes.cc
index d9c615b..1602711 100644
--- a/src/debug/debug-scopes.cc
+++ b/src/debug/debug-scopes.cc
@@ -5,6 +5,7 @@
#include "src/debug/debug-scopes.h"
#include "src/ast/scopes.h"
+#include "src/compiler.h"
#include "src/debug/debug.h"
#include "src/frames-inl.h"
#include "src/globals.h"
@@ -80,34 +81,29 @@
}
// Reparse the code and analyze the scopes.
- Scope* scope = NULL;
// Check whether we are in global, eval or function code.
Zone zone(isolate->allocator());
+ base::SmartPointer<ParseInfo> info;
if (scope_info->scope_type() != FUNCTION_SCOPE) {
// Global or eval code.
Handle<Script> script(Script::cast(shared_info->script()));
- ParseInfo info(&zone, script);
+ info.Reset(new ParseInfo(&zone, script));
+ info->set_toplevel();
if (scope_info->scope_type() == SCRIPT_SCOPE) {
- info.set_global();
+ info->set_global();
} else {
DCHECK(scope_info->scope_type() == EVAL_SCOPE);
- info.set_eval();
- info.set_context(Handle<Context>(function->context()));
+ info->set_eval();
+ info->set_context(Handle<Context>(function->context()));
}
- if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
- scope = info.literal()->scope();
- }
- if (!ignore_nested_scopes) RetrieveScopeChain(scope);
- if (collect_non_locals) CollectNonLocals(scope);
} else {
- // Function code
- ParseInfo info(&zone, function);
- if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
- scope = info.literal()->scope();
- }
- if (!ignore_nested_scopes) RetrieveScopeChain(scope);
- if (collect_non_locals) CollectNonLocals(scope);
+ // Inner function.
+ info.Reset(new ParseInfo(&zone, function));
}
+ Scope* scope = NULL;
+ if (Compiler::ParseAndAnalyze(info.get())) scope = info->literal()->scope();
+ if (!ignore_nested_scopes) RetrieveScopeChain(scope);
+ if (collect_non_locals) CollectNonLocals(scope);
UnwrapEvaluationContext();
}
@@ -126,8 +122,6 @@
while (true) {
if (context_.is_null()) return;
if (!context_->IsDebugEvaluateContext()) return;
- // An existing debug-evaluate context can only be outside the local scope.
- DCHECK(nested_scope_chain_.is_empty());
Handle<Object> wrapped(context_->get(Context::WRAPPED_CONTEXT_INDEX),
isolate_);
if (wrapped->IsContext()) {
@@ -201,11 +195,15 @@
} else if (nested_scope_chain_.is_empty()) {
context_ = Handle<Context>(context_->previous(), isolate_);
} else {
- if (nested_scope_chain_.last().scope_info->HasContext()) {
- DCHECK(context_->previous() != NULL);
- context_ = Handle<Context>(context_->previous(), isolate_);
- }
- nested_scope_chain_.RemoveLast();
+ do {
+ if (nested_scope_chain_.last().scope_info->HasContext()) {
+ DCHECK(context_->previous() != NULL);
+ context_ = Handle<Context>(context_->previous(), isolate_);
+ }
+ nested_scope_chain_.RemoveLast();
+ if (nested_scope_chain_.is_empty()) break;
+ // Repeat to skip hidden scopes.
+ } while (nested_scope_chain_.last().is_hidden());
}
UnwrapEvaluationContext();
}
@@ -236,8 +234,10 @@
DCHECK(!scope_info->HasContext() || context_->IsBlockContext());
return ScopeTypeBlock;
case EVAL_SCOPE:
- UNREACHABLE();
+ DCHECK(!scope_info->HasContext() || context_->IsFunctionContext());
+ return ScopeTypeEval;
}
+ UNREACHABLE();
}
if (context_->IsNativeContext()) {
DCHECK(context_->global_object()->IsJSGlobalObject());
@@ -284,7 +284,8 @@
// Materialize the content of the closure scope into a JSObject.
return MaterializeClosure();
case ScopeIterator::ScopeTypeBlock:
- return MaterializeBlockScope();
+ case ScopeIterator::ScopeTypeEval:
+ return MaterializeInnerScope();
case ScopeIterator::ScopeTypeModule:
return MaterializeModuleScope();
}
@@ -295,7 +296,8 @@
bool ScopeIterator::HasContext() {
ScopeType type = Type();
- if (type == ScopeTypeBlock || type == ScopeTypeLocal) {
+ if (type == ScopeTypeBlock || type == ScopeTypeLocal ||
+ type == ScopeTypeEval) {
if (!nested_scope_chain_.is_empty()) {
return nested_scope_chain_.last().scope_info->HasContext();
}
@@ -321,7 +323,8 @@
case ScopeIterator::ScopeTypeScript:
return SetScriptVariableValue(variable_name, new_value);
case ScopeIterator::ScopeTypeBlock:
- return SetBlockVariableValue(variable_name, new_value);
+ case ScopeIterator::ScopeTypeEval:
+ return SetInnerScopeVariableValue(variable_name, new_value);
case ScopeIterator::ScopeTypeModule:
// TODO(2399): should we implement it?
break;
@@ -453,7 +456,7 @@
global->native_context()->script_context_table());
Handle<JSObject> script_scope =
- isolate_->factory()->NewJSObject(isolate_->object_function());
+ isolate_->factory()->NewJSObjectWithNullProto();
for (int context_index = 0; context_index < script_contexts->used();
context_index++) {
@@ -470,7 +473,7 @@
Handle<JSFunction> function = GetFunction();
Handle<JSObject> local_scope =
- isolate_->factory()->NewJSObject(isolate_->object_function());
+ isolate_->factory()->NewJSObjectWithNullProto();
frame_inspector_->MaterializeStackLocals(local_scope, function);
Handle<Context> frame_context =
@@ -482,19 +485,16 @@
if (!scope_info->HasContext()) return local_scope;
- // Third fill all context locals.
+ // Fill all context locals.
Handle<Context> function_context(frame_context->closure_context());
CopyContextLocalsToScopeObject(scope_info, function_context, local_scope);
// Finally copy any properties from the function context extension.
// These will be variables introduced by eval.
if (function_context->closure() == *function &&
- function_context->has_extension() &&
!function_context->IsNativeContext()) {
- bool success = CopyContextExtensionToScopeObject(
- handle(function_context->extension_object(), isolate_), local_scope,
- INCLUDE_PROTOS);
- if (!success) return MaybeHandle<JSObject>();
+ CopyContextExtensionToScopeObject(function_context, local_scope,
+ INCLUDE_PROTOS);
}
return local_scope;
@@ -513,19 +513,14 @@
// Allocate and initialize a JSObject with all the content of this function
// closure.
Handle<JSObject> closure_scope =
- isolate_->factory()->NewJSObject(isolate_->object_function());
+ isolate_->factory()->NewJSObjectWithNullProto();
// Fill all context locals to the context extension.
CopyContextLocalsToScopeObject(scope_info, context, closure_scope);
// Finally copy any properties from the function context extension. This will
// be variables introduced by eval.
- if (context->has_extension()) {
- bool success = CopyContextExtensionToScopeObject(
- handle(context->extension_object(), isolate_), closure_scope, OWN_ONLY);
- DCHECK(success);
- USE(success);
- }
+ CopyContextExtensionToScopeObject(context, closure_scope, OWN_ONLY);
return closure_scope;
}
@@ -540,7 +535,7 @@
Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
isolate_);
Handle<JSObject> catch_scope =
- isolate_->factory()->NewJSObject(isolate_->object_function());
+ isolate_->factory()->NewJSObjectWithNullProto();
JSObject::SetOwnPropertyIgnoreAttributes(catch_scope, name, thrown_object,
NONE)
.Check();
@@ -560,14 +555,14 @@
// Create a plain JSObject which materializes the block scope for the specified
// block context.
-Handle<JSObject> ScopeIterator::MaterializeBlockScope() {
- Handle<JSObject> block_scope =
- isolate_->factory()->NewJSObject(isolate_->object_function());
+Handle<JSObject> ScopeIterator::MaterializeInnerScope() {
+ Handle<JSObject> inner_scope =
+ isolate_->factory()->NewJSObjectWithNullProto();
Handle<Context> context = Handle<Context>::null();
if (!nested_scope_chain_.is_empty()) {
Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info;
- frame_inspector_->MaterializeStackLocals(block_scope, scope_info);
+ frame_inspector_->MaterializeStackLocals(inner_scope, scope_info);
if (scope_info->HasContext()) context = CurrentContext();
} else {
context = CurrentContext();
@@ -575,17 +570,10 @@
if (!context.is_null()) {
// Fill all context locals.
- CopyContextLocalsToScopeObject(handle(context->scope_info()),
- context, block_scope);
- // Fill all extension variables.
- if (context->extension_object() != nullptr) {
- bool success = CopyContextExtensionToScopeObject(
- handle(context->extension_object()), block_scope, OWN_ONLY);
- DCHECK(success);
- USE(success);
- }
+ CopyContextLocalsToScopeObject(CurrentScopeInfo(), context, inner_scope);
+ CopyContextExtensionToScopeObject(context, inner_scope, OWN_ONLY);
}
- return block_scope;
+ return inner_scope;
}
@@ -599,7 +587,7 @@
// Allocate and initialize a JSObject with all the members of the debugged
// module.
Handle<JSObject> module_scope =
- isolate_->factory()->NewJSObject(isolate_->object_function());
+ isolate_->factory()->NewJSObjectWithNullProto();
// Fill all context locals.
CopyContextLocalsToScopeObject(scope_info, context, module_scope);
@@ -607,12 +595,43 @@
return module_scope;
}
+bool ScopeIterator::SetParameterValue(Handle<ScopeInfo> scope_info,
+ JavaScriptFrame* frame,
+ Handle<String> parameter_name,
+ Handle<Object> new_value) {
+ // Setting stack locals of optimized frames is not supported.
+ if (frame->is_optimized()) return false;
+ HandleScope scope(isolate_);
+ for (int i = 0; i < scope_info->ParameterCount(); ++i) {
+ if (String::Equals(handle(scope_info->ParameterName(i)), parameter_name)) {
+ frame->SetParameterValue(i, *new_value);
+ return true;
+ }
+ }
+ return false;
+}
-// Set the context local variable value.
-bool ScopeIterator::SetContextLocalValue(Handle<ScopeInfo> scope_info,
- Handle<Context> context,
- Handle<String> variable_name,
- Handle<Object> new_value) {
+bool ScopeIterator::SetStackVariableValue(Handle<ScopeInfo> scope_info,
+ JavaScriptFrame* frame,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ // Setting stack locals of optimized frames is not supported.
+ if (frame->is_optimized()) return false;
+ HandleScope scope(isolate_);
+ for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+ if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
+ frame->SetExpression(scope_info->StackLocalIndex(i), *new_value);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ScopeIterator::SetContextVariableValue(Handle<ScopeInfo> scope_info,
+ Handle<Context> context,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ HandleScope scope(isolate_);
for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
Handle<String> next_name(scope_info->ContextLocalName(i));
if (String::Equals(variable_name, next_name)) {
@@ -626,128 +645,8 @@
}
}
- return false;
-}
-
-
-bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name,
- Handle<Object> new_value) {
- JavaScriptFrame* frame = GetFrame();
- // Optimized frames are not supported.
- if (frame->is_optimized()) return false;
-
- Handle<JSFunction> function(frame->function());
- Handle<SharedFunctionInfo> shared(function->shared());
- Handle<ScopeInfo> scope_info(shared->scope_info());
-
- bool default_result = false;
-
- // Parameters.
- for (int i = 0; i < scope_info->ParameterCount(); ++i) {
- HandleScope scope(isolate_);
- if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
- frame->SetParameterValue(i, *new_value);
- // Argument might be shadowed in heap context, don't stop here.
- default_result = true;
- }
- }
-
- // Stack locals.
- for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
- HandleScope scope(isolate_);
- if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
- frame->SetExpression(scope_info->StackLocalIndex(i), *new_value);
- return true;
- }
- }
-
- if (scope_info->HasContext()) {
- // Context locals.
- Handle<Context> frame_context(Context::cast(frame->context()));
- Handle<Context> function_context(frame_context->declaration_context());
- if (SetContextLocalValue(scope_info, function_context, variable_name,
- new_value)) {
- return true;
- }
-
- // Function context extension. These are variables introduced by eval.
- if (function_context->closure() == *function) {
- if (function_context->has_extension() &&
- !function_context->IsNativeContext()) {
- Handle<JSObject> ext(function_context->extension_object());
-
- Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
- DCHECK(maybe.IsJust());
- if (maybe.FromJust()) {
- // We don't expect this to do anything except replacing
- // property value.
- Runtime::SetObjectProperty(isolate_, ext, variable_name, new_value,
- SLOPPY)
- .Assert();
- return true;
- }
- }
- }
- }
-
- return default_result;
-}
-
-
-bool ScopeIterator::SetBlockVariableValue(Handle<String> variable_name,
- Handle<Object> new_value) {
- Handle<ScopeInfo> scope_info = CurrentScopeInfo();
- JavaScriptFrame* frame = GetFrame();
-
- for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
- HandleScope scope(isolate_);
- if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
- frame->SetExpression(scope_info->StackLocalIndex(i), *new_value);
- return true;
- }
- }
-
- if (HasContext()) {
- Handle<Context> context = CurrentContext();
- if (SetContextLocalValue(scope_info, context, variable_name, new_value)) {
- return true;
- }
-
- Handle<JSObject> ext(context->extension_object(), isolate_);
- if (!ext.is_null()) {
- Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name);
- DCHECK(maybe.IsJust());
- if (maybe.FromJust()) {
- // We don't expect this to do anything except replacing property value.
- JSObject::SetOwnPropertyIgnoreAttributes(ext, variable_name, new_value,
- NONE)
- .Check();
- return true;
- }
- }
- }
-
- return false;
-}
-
-
-// This method copies structure of MaterializeClosure method above.
-bool ScopeIterator::SetClosureVariableValue(Handle<String> variable_name,
- Handle<Object> new_value) {
- Handle<Context> context = CurrentContext();
- DCHECK(context->IsFunctionContext());
-
- // Context locals to the context extension.
- Handle<SharedFunctionInfo> shared(context->closure()->shared());
- Handle<ScopeInfo> scope_info(shared->scope_info());
- if (SetContextLocalValue(scope_info, context, variable_name, new_value)) {
- return true;
- }
-
- // Properties from the function context extension. This will
- // be variables introduced by eval.
if (context->has_extension()) {
- Handle<JSObject> ext(JSObject::cast(context->extension_object()));
+ Handle<JSObject> ext(context->extension_object());
Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name);
DCHECK(maybe.IsJust());
if (maybe.FromJust()) {
@@ -762,6 +661,55 @@
return false;
}
+bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name,
+ Handle<Object> new_value) {
+ JavaScriptFrame* frame = GetFrame();
+ Handle<ScopeInfo> scope_info(frame->function()->shared()->scope_info());
+
+ // Parameter might be shadowed in context. Don't stop here.
+ bool result = SetParameterValue(scope_info, frame, variable_name, new_value);
+
+ // Stack locals.
+ if (SetStackVariableValue(scope_info, frame, variable_name, new_value)) {
+ return true;
+ }
+
+ if (scope_info->HasContext() &&
+ SetContextVariableValue(scope_info, CurrentContext(), variable_name,
+ new_value)) {
+ return true;
+ }
+
+ return result;
+}
+
+bool ScopeIterator::SetInnerScopeVariableValue(Handle<String> variable_name,
+ Handle<Object> new_value) {
+ Handle<ScopeInfo> scope_info = CurrentScopeInfo();
+ DCHECK(scope_info->scope_type() == BLOCK_SCOPE ||
+ scope_info->scope_type() == EVAL_SCOPE);
+ JavaScriptFrame* frame = GetFrame();
+
+ // Setting stack locals of optimized frames is not supported.
+ if (SetStackVariableValue(scope_info, frame, variable_name, new_value)) {
+ return true;
+ }
+
+ if (HasContext() && SetContextVariableValue(scope_info, CurrentContext(),
+ variable_name, new_value)) {
+ return true;
+ }
+
+ return false;
+}
+
+// This method copies structure of MaterializeClosure method above.
+bool ScopeIterator::SetClosureVariableValue(Handle<String> variable_name,
+ Handle<Object> new_value) {
+ DCHECK(CurrentContext()->IsFunctionContext());
+ return SetContextVariableValue(CurrentScopeInfo(), CurrentContext(),
+ variable_name, new_value);
+}
bool ScopeIterator::SetScriptVariableValue(Handle<String> variable_name,
Handle<Object> new_value) {
@@ -780,7 +728,6 @@
return false;
}
-
bool ScopeIterator::SetCatchVariableValue(Handle<String> variable_name,
Handle<Object> new_value) {
Handle<Context> context = CurrentContext();
@@ -801,48 +748,47 @@
int local_count = scope_info->ContextLocalCount();
if (local_count == 0) return;
// Fill all context locals to the context extension.
- int first_context_var = scope_info->StackLocalCount();
- int start = scope_info->ContextLocalNameEntriesIndex();
for (int i = 0; i < local_count; ++i) {
- if (scope_info->LocalIsSynthetic(first_context_var + i)) continue;
+ Handle<String> name(scope_info->ContextLocalName(i));
+ if (ScopeInfo::VariableIsSynthetic(*name)) continue;
int context_index = Context::MIN_CONTEXT_SLOTS + i;
Handle<Object> value = Handle<Object>(context->get(context_index), isolate);
// Reflect variables under TDZ as undefined in scope object.
if (value->IsTheHole()) continue;
// This should always succeed.
// TODO(verwaest): Use AddDataProperty instead.
- JSObject::SetOwnPropertyIgnoreAttributes(
- scope_object, handle(String::cast(scope_info->get(i + start))), value,
- NONE)
+ JSObject::SetOwnPropertyIgnoreAttributes(scope_object, name, value, NONE)
.Check();
}
}
-bool ScopeIterator::CopyContextExtensionToScopeObject(
- Handle<JSObject> extension, Handle<JSObject> scope_object,
+void ScopeIterator::CopyContextExtensionToScopeObject(
+ Handle<Context> context, Handle<JSObject> scope_object,
KeyCollectionType type) {
- Handle<FixedArray> keys;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate_, keys, JSReceiver::GetKeys(extension, type, ENUMERABLE_STRINGS),
- false);
+ if (context->extension_object() == nullptr) return;
+ Handle<JSObject> extension(context->extension_object());
+ Handle<FixedArray> keys =
+ JSReceiver::GetKeys(extension, type, ENUMERABLE_STRINGS)
+ .ToHandleChecked();
for (int i = 0; i < keys->length(); i++) {
// Names of variables introduced by eval are strings.
DCHECK(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
- Handle<Object> value;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate_, value, Object::GetPropertyOrElement(extension, key), false);
- RETURN_ON_EXCEPTION_VALUE(
- isolate_, JSObject::SetOwnPropertyIgnoreAttributes(
- scope_object, key, value, NONE), false);
+ Handle<Object> value =
+ Object::GetPropertyOrElement(extension, key).ToHandleChecked();
+ JSObject::SetOwnPropertyIgnoreAttributes(scope_object, key, value, NONE)
+ .Check();
}
- return true;
}
void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope,
int position) {
- if (!scope->is_eval_scope()) {
+ if (scope->is_hidden()) {
+ // We need to add this chain element in case the scope has a context
+ // associated. We need to keep the scope chain and context chain in sync.
+ nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate)));
+ } else {
nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate),
scope->start_position(),
scope->end_position()));
@@ -851,7 +797,7 @@
Scope* inner_scope = scope->inner_scopes()->at(i);
int beg_pos = inner_scope->start_position();
int end_pos = inner_scope->end_position();
- DCHECK(beg_pos >= 0 && end_pos >= 0);
+ DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden());
if (beg_pos <= position && position < end_pos) {
GetNestedScopeChain(isolate, inner_scope, position);
return;