Index: src/debug/debug-scopes.cc |
diff --git a/src/debug/debug-scopes.cc b/src/debug/debug-scopes.cc |
index c21b4e634292871148dcf131e8d5ef6e8a79052f..16027110ef6d6ba318566294642ec294b2ad3758 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 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, |
} |
// 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())); |
- } |
- if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) { |
- scope = info.literal()->scope(); |
+ info->set_eval(); |
+ info->set_context(Handle<Context>(function->context())); |
} |
- 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 @@ void ScopeIterator::UnwrapEvaluationContext() { |
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()) { |
@@ -240,8 +234,10 @@ ScopeIterator::ScopeType ScopeIterator::Type() { |
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()); |
@@ -288,7 +284,8 @@ MaybeHandle<JSObject> ScopeIterator::ScopeObject() { |
// 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(); |
} |
@@ -299,7 +296,8 @@ MaybeHandle<JSObject> ScopeIterator::ScopeObject() { |
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(); |
} |
@@ -325,7 +323,8 @@ bool ScopeIterator::SetVariableValue(Handle<String> variable_name, |
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; |
@@ -486,19 +485,16 @@ MaybeHandle<JSObject> ScopeIterator::MaterializeLocalScope() { |
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; |
@@ -524,12 +520,7 @@ Handle<JSObject> ScopeIterator::MaterializeClosure() { |
// 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; |
} |
@@ -564,14 +555,14 @@ Handle<JSObject> ScopeIterator::WithContextExtension() { |
// Create a plain JSObject which materializes the block scope for the specified |
// block context. |
-Handle<JSObject> ScopeIterator::MaterializeBlockScope() { |
- Handle<JSObject> block_scope = |
+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(); |
@@ -579,17 +570,10 @@ Handle<JSObject> ScopeIterator::MaterializeBlockScope() { |
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; |
} |
@@ -699,9 +683,11 @@ bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name, |
return result; |
} |
-bool ScopeIterator::SetBlockVariableValue(Handle<String> variable_name, |
- Handle<Object> new_value) { |
+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. |
@@ -776,40 +762,36 @@ void ScopeIterator::CopyContextLocalsToScopeObject( |
} |
} |
-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())); |
- } |
+ 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())); |
} |
for (int i = 0; i < scope->inner_scopes()->length(); i++) { |
Scope* inner_scope = scope->inner_scopes()->at(i); |