 Chromium Code Reviews
 Chromium Code Reviews Issue 2435023002:
  Use a different map to distinguish eval contexts  (Closed)
    
  
    Issue 2435023002:
  Use a different map to distinguish eval contexts  (Closed) 
  | Index: src/contexts.cc | 
| diff --git a/src/contexts.cc b/src/contexts.cc | 
| index 012944e2c28b5344240852166b40ec2a6cd48cf4..7d3f294cd7e665333c57b8306baf3fbeff043850 100644 | 
| --- a/src/contexts.cc | 
| +++ b/src/contexts.cc | 
| @@ -61,6 +61,7 @@ bool Context::is_declaration_context() { | 
| IsModuleContext()) { | 
| return true; | 
| } | 
| + if (IsEvalContext()) return closure()->shared()->language_mode() == STRICT; | 
| if (!IsBlockContext()) return false; | 
| Object* ext = extension(); | 
| // If we have the special extension, we immediately know it must be a | 
| @@ -74,7 +75,8 @@ Context* Context::declaration_context() { | 
| Context* current = this; | 
| while (!current->is_declaration_context()) { | 
| current = current->previous(); | 
| - DCHECK(current->closure() == closure()); | 
| + // Note: the closure may change while finding the declaration context, | 
| 
adamk
2016/11/12 00:26:05
Seems like this comment won't be as useful after t
 
Dan Ehrenberg
2016/12/07 05:41:26
Done.
 | 
| + // e.g., for sloppy direct eval | 
| } | 
| return current; | 
| } | 
| @@ -82,7 +84,8 @@ Context* Context::declaration_context() { | 
| Context* Context::closure_context() { | 
| Context* current = this; | 
| while (!current->IsFunctionContext() && !current->IsScriptContext() && | 
| - !current->IsModuleContext() && !current->IsNativeContext()) { | 
| + !current->IsModuleContext() && !current->IsNativeContext() && | 
| + !current->IsEvalContext()) { | 
| current = current->previous(); | 
| DCHECK(current->closure() == closure()); | 
| } | 
| @@ -90,7 +93,8 @@ Context* Context::closure_context() { | 
| } | 
| JSObject* Context::extension_object() { | 
| - DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext()); | 
| + DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext() || | 
| + IsEvalContext()); | 
| HeapObject* object = extension(); | 
| if (object->IsTheHole(GetIsolate())) return nullptr; | 
| if (IsBlockContext()) { | 
| @@ -103,7 +107,7 @@ JSObject* Context::extension_object() { | 
| } | 
| JSReceiver* Context::extension_receiver() { | 
| - DCHECK(IsNativeContext() || IsWithContext() || | 
| + DCHECK(IsNativeContext() || IsWithContext() || IsEvalContext() || | 
| IsFunctionContext() || IsBlockContext()); | 
| return IsWithContext() ? JSReceiver::cast( | 
| ContextExtension::cast(extension())->extension()) | 
| @@ -112,7 +116,7 @@ JSReceiver* Context::extension_receiver() { | 
| ScopeInfo* Context::scope_info() { | 
| DCHECK(!IsNativeContext()); | 
| - if (IsFunctionContext() || IsModuleContext()) { | 
| + if (IsFunctionContext() || IsModuleContext() || IsEvalContext()) { | 
| return closure()->shared()->scope_info(); | 
| } | 
| HeapObject* object = extension(); | 
| @@ -225,7 +229,8 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, | 
| // 1. Check global objects, subjects of with, and extension objects. | 
| if ((context->IsNativeContext() || | 
| (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || | 
| - context->IsFunctionContext() || context->IsBlockContext()) && | 
| + context->IsFunctionContext() || context->IsEvalContext() || | 
| + context->IsBlockContext()) && | 
| context->extension_receiver() != nullptr) { | 
| Handle<JSReceiver> object(context->extension_receiver()); | 
| @@ -301,12 +306,13 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, | 
| // 2. Check the context proper if it has slots. | 
| if (context->IsFunctionContext() || context->IsBlockContext() || | 
| - context->IsScriptContext()) { | 
| + context->IsScriptContext() || context->IsEvalContext()) { | 
| // Use serialized scope information of functions and blocks to search | 
| // for the context index. | 
| - Handle<ScopeInfo> scope_info(context->IsFunctionContext() | 
| - ? context->closure()->shared()->scope_info() | 
| - : context->scope_info()); | 
| + Handle<ScopeInfo> scope_info( | 
| + (context->IsFunctionContext() || context->IsEvalContext()) | 
| 
adamk
2016/11/12 00:26:05
Isn't this logic already present in Context::scope
 
Dan Ehrenberg
2016/12/07 05:41:26
Done.
 | 
| + ? context->closure()->shared()->scope_info() | 
| + : context->scope_info()); | 
| VariableMode mode; | 
| InitializationFlag flag; | 
| MaybeAssignedFlag maybe_assigned_flag; | 
| @@ -329,7 +335,7 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, | 
| // only the function name variable. It's conceptually (and spec-wise) | 
| // in an outer scope of the function's declaration scope. | 
| if (follow_context_chain && (flags & STOP_AT_DECLARATION_SCOPE) == 0 && | 
| - context->IsFunctionContext()) { | 
| + (context->IsFunctionContext() || context->IsEvalContext())) { | 
| 
adamk
2016/11/12 00:26:05
I don't think it makes sense to add IsEvalContext
 
Dan Ehrenberg
2016/12/07 05:41:26
Done.
 | 
| int function_index = scope_info->FunctionContextSlotIndex(*name); | 
| if (function_index >= 0) { | 
| if (FLAG_trace_contexts) { |