Index: src/debug/debug-scopes.cc |
diff --git a/src/debug/debug-scopes.cc b/src/debug/debug-scopes.cc |
index 4703e9c3c450ad047f4c1b4e73de6fa53270b69b..8502c483bd86613388076cfc7bac56361bda6dee 100644 |
--- a/src/debug/debug-scopes.cc |
+++ b/src/debug/debug-scopes.cc |
@@ -237,7 +237,8 @@ MaybeHandle<JSObject> ScopeIterator::ScopeObject() { |
return MaterializeLocalScope(); |
case ScopeIterator::ScopeTypeWith: |
// Return the with object. |
- return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
+ // TODO(neis): This breaks for proxies. |
+ return handle(JSObject::cast(CurrentContext()->extension_receiver())); |
case ScopeIterator::ScopeTypeCatch: |
return MaterializeCatchScope(); |
case ScopeIterator::ScopeTypeClosure: |
@@ -295,7 +296,7 @@ Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() { |
if (!nested_scope_chain_.is_empty()) { |
return nested_scope_chain_.last(); |
} else if (context_->IsBlockContext()) { |
- return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); |
+ return Handle<ScopeInfo>(context_->scope_info()); |
} else if (context_->IsFunctionContext()) { |
return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
} |
@@ -410,7 +411,7 @@ MaybeHandle<JSObject> ScopeIterator::MaterializeScriptScope() { |
context_index++) { |
Handle<Context> context = |
ScriptContextTable::GetContext(script_contexts, context_index); |
- Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); |
+ Handle<ScopeInfo> scope_info(context->scope_info()); |
CopyContextLocalsToScopeObject(scope_info, context, script_scope); |
} |
return script_scope; |
@@ -438,28 +439,13 @@ MaybeHandle<JSObject> ScopeIterator::MaterializeLocalScope() { |
// Finally copy any properties from the function context extension. |
// These will be variables introduced by eval. |
- if (function_context->closure() == *function) { |
- if (function_context->has_extension() && |
- !function_context->IsNativeContext()) { |
- Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
- Handle<FixedArray> keys; |
- ASSIGN_RETURN_ON_EXCEPTION( |
- isolate_, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), |
- JSObject); |
- |
- 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( |
- isolate_, value, Object::GetPropertyOrElement(ext, key), JSObject); |
- RETURN_ON_EXCEPTION(isolate_, |
- Runtime::SetObjectProperty(isolate_, local_scope, |
- key, value, SLOPPY), |
- JSObject); |
- } |
- } |
+ if (function_context->closure() == *function && |
+ function_context->has_extension() && |
+ !function_context->IsNativeContext()) { |
+ bool success = CopyContextExtensionToScopeObject( |
+ handle(function_context->extension_object(), isolate_), |
+ local_scope, JSReceiver::INCLUDE_PROTOS); |
+ if (!success) return MaybeHandle<JSObject>(); |
} |
return local_scope; |
@@ -486,20 +472,11 @@ Handle<JSObject> ScopeIterator::MaterializeClosure() { |
// Finally copy any properties from the function context extension. This will |
// be variables introduced by eval. |
if (context->has_extension()) { |
- Handle<JSObject> ext(JSObject::cast(context->extension())); |
- DCHECK(ext->IsJSContextExtensionObject()); |
- Handle<FixedArray> keys = |
- JSReceiver::GetKeys(ext, JSReceiver::OWN_ONLY).ToHandleChecked(); |
- |
- for (int i = 0; i < keys->length(); i++) { |
- HandleScope scope(isolate_); |
- // Names of variables introduced by eval are strings. |
- DCHECK(keys->get(i)->IsString()); |
- Handle<String> key(String::cast(keys->get(i))); |
- Handle<Object> value = Object::GetProperty(ext, key).ToHandleChecked(); |
- JSObject::SetOwnPropertyIgnoreAttributes(closure_scope, key, value, NONE) |
- .Check(); |
- } |
+ bool success = CopyContextExtensionToScopeObject( |
+ handle(context->extension_object(), isolate_), closure_scope, |
+ JSReceiver::OWN_ONLY); |
+ DCHECK(success); |
+ USE(success); |
} |
return closure_scope; |
@@ -511,7 +488,7 @@ Handle<JSObject> ScopeIterator::MaterializeClosure() { |
Handle<JSObject> ScopeIterator::MaterializeCatchScope() { |
Handle<Context> context = CurrentContext(); |
DCHECK(context->IsCatchContext()); |
- Handle<String> name(String::cast(context->extension())); |
+ Handle<String> name(context->catch_name()); |
Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX), |
isolate_); |
Handle<JSObject> catch_scope = |
@@ -539,11 +516,17 @@ Handle<JSObject> ScopeIterator::MaterializeBlockScope() { |
} |
if (!context.is_null()) { |
- Handle<ScopeInfo> scope_info_from_context( |
- ScopeInfo::cast(context->extension())); |
// Fill all context locals. |
- CopyContextLocalsToScopeObject(scope_info_from_context, context, |
- block_scope); |
+ 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, |
+ JSReceiver::OWN_ONLY); |
+ DCHECK(success); |
+ USE(success); |
+ } |
} |
return block_scope; |
} |
@@ -554,7 +537,7 @@ Handle<JSObject> ScopeIterator::MaterializeBlockScope() { |
MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() { |
Handle<Context> context = CurrentContext(); |
DCHECK(context->IsModuleContext()); |
- Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); |
+ Handle<ScopeInfo> scope_info(context->scope_info()); |
// Allocate and initialize a JSObject with all the members of the debugged |
// module. |
@@ -636,7 +619,7 @@ bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name, |
if (function_context->closure() == *function) { |
if (function_context->has_extension() && |
!function_context->IsNativeContext()) { |
- Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
+ Handle<JSObject> ext(function_context->extension_object()); |
Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name); |
DCHECK(maybe.IsJust()); |
@@ -670,9 +653,25 @@ bool ScopeIterator::SetBlockVariableValue(Handle<String> variable_name, |
} |
if (HasContext()) { |
- return SetContextLocalValue(scope_info, CurrentContext(), variable_name, |
- new_value); |
+ 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; |
} |
@@ -693,8 +692,7 @@ bool ScopeIterator::SetClosureVariableValue(Handle<String> variable_name, |
// Properties from the function context extension. This will |
// be variables introduced by eval. |
if (context->has_extension()) { |
- Handle<JSObject> ext(JSObject::cast(context->extension())); |
- DCHECK(ext->IsJSContextExtensionObject()); |
+ Handle<JSObject> ext(JSObject::cast(context->extension_object())); |
Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name); |
DCHECK(maybe.IsJust()); |
if (maybe.FromJust()) { |
@@ -732,7 +730,7 @@ bool ScopeIterator::SetCatchVariableValue(Handle<String> variable_name, |
Handle<Object> new_value) { |
Handle<Context> context = CurrentContext(); |
DCHECK(context->IsCatchContext()); |
- Handle<String> name(String::cast(context->extension())); |
+ Handle<String> name(context->catch_name()); |
if (!String::Equals(name, variable_name)) { |
return false; |
} |
@@ -765,5 +763,27 @@ void ScopeIterator::CopyContextLocalsToScopeObject( |
} |
} |
+ |
+bool ScopeIterator::CopyContextExtensionToScopeObject( |
+ Handle<JSObject> extension, Handle<JSObject> scope_object, |
+ JSReceiver::KeyCollectionType type) { |
+ Handle<FixedArray> keys; |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate_, keys, JSReceiver::GetKeys(extension, type), false); |
+ |
+ 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); |
+ } |
+ return true; |
+} |
+ |
} // namespace internal |
} // namespace v8 |