Index: src/contexts.cc |
diff --git a/src/contexts.cc b/src/contexts.cc |
index 9adccb2897778611d6a89556561218371791175e..67a9fea8b896d2be7115b7fb56ad724cc02c4e0b 100644 |
--- a/src/contexts.cc |
+++ b/src/contexts.cc |
@@ -233,6 +233,7 @@ Handle<Object> Context::Lookup(Handle<String> name, |
Handle<Context> context(this, isolate); |
bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; |
+ bool failed_whitelist = false; |
*index = kNotFound; |
*attributes = ABSENT; |
*binding_flags = MISSING_BINDING; |
@@ -378,6 +379,31 @@ Handle<Object> Context::Lookup(Handle<String> name, |
*binding_flags = MUTABLE_IS_INITIALIZED; |
return context; |
} |
+ } else if (context->IsDebugEvaluateContext()) { |
+ // Check materialized locals. |
+ Object* obj = context->get(EXTENSION_INDEX); |
+ if (obj->IsJSReceiver()) { |
+ Handle<JSReceiver> extension(JSReceiver::cast(obj)); |
+ LookupIterator it(extension, name, extension); |
+ Maybe<bool> found = JSReceiver::HasProperty(&it); |
+ if (found.FromMaybe(false)) { |
+ *attributes = NONE; |
+ return extension; |
+ } |
+ } |
+ // Check the original context, but do not follow its context chain. |
+ obj = context->get(WRAPPED_CONTEXT_INDEX); |
+ if (obj->IsContext()) { |
+ Handle<Object> result = Context::cast(obj)->Lookup( |
+ name, DONT_FOLLOW_CHAINS, index, attributes, binding_flags); |
+ if (!result.is_null()) return result; |
+ } |
+ // Check whitelist. Names that do not pass whitelist shall only resolve |
+ // to with, script or native contexts up the context chain. |
+ obj = context->get(WHITE_LIST_INDEX); |
+ if (obj->IsStringSet()) { |
+ failed_whitelist = failed_whitelist || !StringSet::cast(obj)->Has(name); |
+ } |
} |
// 3. Prepare to continue with the previous (next outermost) context. |
@@ -386,7 +412,12 @@ Handle<Object> Context::Lookup(Handle<String> name, |
context->is_declaration_context())) { |
follow_context_chain = false; |
} else { |
- context = Handle<Context>(context->previous(), isolate); |
+ do { |
+ context = Handle<Context>(context->previous(), isolate); |
+ // If we come across a whitelist context, and the name is not |
+ // whitelisted, then only consider with, script or native contexts. |
+ } while (failed_whitelist && !context->IsScriptContext() && |
+ !context->IsNativeContext() && !context->IsWithContext()); |
} |
} while (follow_context_chain); |