Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/contexts.h" | 5 #include "src/contexts.h" |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 } | 54 } |
| 55 return false; | 55 return false; |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 bool Context::is_declaration_context() { | 59 bool Context::is_declaration_context() { |
| 60 if (IsFunctionContext() || IsNativeContext() || IsScriptContext() || | 60 if (IsFunctionContext() || IsNativeContext() || IsScriptContext() || |
| 61 IsModuleContext()) { | 61 IsModuleContext()) { |
| 62 return true; | 62 return true; |
| 63 } | 63 } |
| 64 if (IsEvalContext()) return closure()->shared()->language_mode() == STRICT; | |
| 64 if (!IsBlockContext()) return false; | 65 if (!IsBlockContext()) return false; |
| 65 Object* ext = extension(); | 66 Object* ext = extension(); |
| 66 // If we have the special extension, we immediately know it must be a | 67 // If we have the special extension, we immediately know it must be a |
| 67 // declaration scope. That's just a small performance shortcut. | 68 // declaration scope. That's just a small performance shortcut. |
| 68 return ext->IsContextExtension() || | 69 return ext->IsContextExtension() || |
| 69 ScopeInfo::cast(ext)->is_declaration_scope(); | 70 ScopeInfo::cast(ext)->is_declaration_scope(); |
| 70 } | 71 } |
| 71 | 72 |
| 72 | 73 |
| 73 Context* Context::declaration_context() { | 74 Context* Context::declaration_context() { |
| 74 Context* current = this; | 75 Context* current = this; |
| 75 while (!current->is_declaration_context()) { | 76 while (!current->is_declaration_context()) { |
| 76 current = current->previous(); | 77 current = current->previous(); |
| 77 DCHECK(current->closure() == closure()); | 78 // 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.
| |
| 79 // e.g., for sloppy direct eval | |
| 78 } | 80 } |
| 79 return current; | 81 return current; |
| 80 } | 82 } |
| 81 | 83 |
| 82 Context* Context::closure_context() { | 84 Context* Context::closure_context() { |
| 83 Context* current = this; | 85 Context* current = this; |
| 84 while (!current->IsFunctionContext() && !current->IsScriptContext() && | 86 while (!current->IsFunctionContext() && !current->IsScriptContext() && |
| 85 !current->IsModuleContext() && !current->IsNativeContext()) { | 87 !current->IsModuleContext() && !current->IsNativeContext() && |
| 88 !current->IsEvalContext()) { | |
| 86 current = current->previous(); | 89 current = current->previous(); |
| 87 DCHECK(current->closure() == closure()); | 90 DCHECK(current->closure() == closure()); |
| 88 } | 91 } |
| 89 return current; | 92 return current; |
| 90 } | 93 } |
| 91 | 94 |
| 92 JSObject* Context::extension_object() { | 95 JSObject* Context::extension_object() { |
| 93 DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext()); | 96 DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext() || |
| 97 IsEvalContext()); | |
| 94 HeapObject* object = extension(); | 98 HeapObject* object = extension(); |
| 95 if (object->IsTheHole(GetIsolate())) return nullptr; | 99 if (object->IsTheHole(GetIsolate())) return nullptr; |
| 96 if (IsBlockContext()) { | 100 if (IsBlockContext()) { |
| 97 if (!object->IsContextExtension()) return nullptr; | 101 if (!object->IsContextExtension()) return nullptr; |
| 98 object = JSObject::cast(ContextExtension::cast(object)->extension()); | 102 object = JSObject::cast(ContextExtension::cast(object)->extension()); |
| 99 } | 103 } |
| 100 DCHECK(object->IsJSContextExtensionObject() || | 104 DCHECK(object->IsJSContextExtensionObject() || |
| 101 (IsNativeContext() && object->IsJSGlobalObject())); | 105 (IsNativeContext() && object->IsJSGlobalObject())); |
| 102 return JSObject::cast(object); | 106 return JSObject::cast(object); |
| 103 } | 107 } |
| 104 | 108 |
| 105 JSReceiver* Context::extension_receiver() { | 109 JSReceiver* Context::extension_receiver() { |
| 106 DCHECK(IsNativeContext() || IsWithContext() || | 110 DCHECK(IsNativeContext() || IsWithContext() || IsEvalContext() || |
| 107 IsFunctionContext() || IsBlockContext()); | 111 IsFunctionContext() || IsBlockContext()); |
| 108 return IsWithContext() ? JSReceiver::cast( | 112 return IsWithContext() ? JSReceiver::cast( |
| 109 ContextExtension::cast(extension())->extension()) | 113 ContextExtension::cast(extension())->extension()) |
| 110 : extension_object(); | 114 : extension_object(); |
| 111 } | 115 } |
| 112 | 116 |
| 113 ScopeInfo* Context::scope_info() { | 117 ScopeInfo* Context::scope_info() { |
| 114 DCHECK(!IsNativeContext()); | 118 DCHECK(!IsNativeContext()); |
| 115 if (IsFunctionContext() || IsModuleContext()) { | 119 if (IsFunctionContext() || IsModuleContext() || IsEvalContext()) { |
| 116 return closure()->shared()->scope_info(); | 120 return closure()->shared()->scope_info(); |
| 117 } | 121 } |
| 118 HeapObject* object = extension(); | 122 HeapObject* object = extension(); |
| 119 if (object->IsContextExtension()) { | 123 if (object->IsContextExtension()) { |
| 120 DCHECK(IsBlockContext() || IsCatchContext() || IsWithContext() || | 124 DCHECK(IsBlockContext() || IsCatchContext() || IsWithContext() || |
| 121 IsDebugEvaluateContext()); | 125 IsDebugEvaluateContext()); |
| 122 object = ContextExtension::cast(object)->scope_info(); | 126 object = ContextExtension::cast(object)->scope_info(); |
| 123 } | 127 } |
| 124 return ScopeInfo::cast(object); | 128 return ScopeInfo::cast(object); |
| 125 } | 129 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 if (FLAG_trace_contexts) { | 222 if (FLAG_trace_contexts) { |
| 219 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); | 223 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); |
| 220 if (context->IsScriptContext()) PrintF(" (script context)"); | 224 if (context->IsScriptContext()) PrintF(" (script context)"); |
| 221 if (context->IsNativeContext()) PrintF(" (native context)"); | 225 if (context->IsNativeContext()) PrintF(" (native context)"); |
| 222 PrintF("\n"); | 226 PrintF("\n"); |
| 223 } | 227 } |
| 224 | 228 |
| 225 // 1. Check global objects, subjects of with, and extension objects. | 229 // 1. Check global objects, subjects of with, and extension objects. |
| 226 if ((context->IsNativeContext() || | 230 if ((context->IsNativeContext() || |
| 227 (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || | 231 (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || |
| 228 context->IsFunctionContext() || context->IsBlockContext()) && | 232 context->IsFunctionContext() || context->IsEvalContext() || |
| 233 context->IsBlockContext()) && | |
| 229 context->extension_receiver() != nullptr) { | 234 context->extension_receiver() != nullptr) { |
| 230 Handle<JSReceiver> object(context->extension_receiver()); | 235 Handle<JSReceiver> object(context->extension_receiver()); |
| 231 | 236 |
| 232 if (context->IsNativeContext()) { | 237 if (context->IsNativeContext()) { |
| 233 if (FLAG_trace_contexts) { | 238 if (FLAG_trace_contexts) { |
| 234 PrintF(" - trying other script contexts\n"); | 239 PrintF(" - trying other script contexts\n"); |
| 235 } | 240 } |
| 236 // Try other script contexts. | 241 // Try other script contexts. |
| 237 Handle<ScriptContextTable> script_contexts( | 242 Handle<ScriptContextTable> script_contexts( |
| 238 context->global_object()->native_context()->script_context_table()); | 243 context->global_object()->native_context()->script_context_table()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 if (FLAG_trace_contexts) { | 299 if (FLAG_trace_contexts) { |
| 295 PrintF("=> found property in context object %p\n", | 300 PrintF("=> found property in context object %p\n", |
| 296 reinterpret_cast<void*>(*object)); | 301 reinterpret_cast<void*>(*object)); |
| 297 } | 302 } |
| 298 return object; | 303 return object; |
| 299 } | 304 } |
| 300 } | 305 } |
| 301 | 306 |
| 302 // 2. Check the context proper if it has slots. | 307 // 2. Check the context proper if it has slots. |
| 303 if (context->IsFunctionContext() || context->IsBlockContext() || | 308 if (context->IsFunctionContext() || context->IsBlockContext() || |
| 304 context->IsScriptContext()) { | 309 context->IsScriptContext() || context->IsEvalContext()) { |
| 305 // Use serialized scope information of functions and blocks to search | 310 // Use serialized scope information of functions and blocks to search |
| 306 // for the context index. | 311 // for the context index. |
| 307 Handle<ScopeInfo> scope_info(context->IsFunctionContext() | 312 Handle<ScopeInfo> scope_info( |
| 308 ? context->closure()->shared()->scope_info() | 313 (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.
| |
| 309 : context->scope_info()); | 314 ? context->closure()->shared()->scope_info() |
| 315 : context->scope_info()); | |
| 310 VariableMode mode; | 316 VariableMode mode; |
| 311 InitializationFlag flag; | 317 InitializationFlag flag; |
| 312 MaybeAssignedFlag maybe_assigned_flag; | 318 MaybeAssignedFlag maybe_assigned_flag; |
| 313 int slot_index = ScopeInfo::ContextSlotIndex(scope_info, name, &mode, | 319 int slot_index = ScopeInfo::ContextSlotIndex(scope_info, name, &mode, |
| 314 &flag, &maybe_assigned_flag); | 320 &flag, &maybe_assigned_flag); |
| 315 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); | 321 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); |
| 316 if (slot_index >= 0) { | 322 if (slot_index >= 0) { |
| 317 if (FLAG_trace_contexts) { | 323 if (FLAG_trace_contexts) { |
| 318 PrintF("=> found local in context slot %d (mode = %d)\n", | 324 PrintF("=> found local in context slot %d (mode = %d)\n", |
| 319 slot_index, mode); | 325 slot_index, mode); |
| 320 } | 326 } |
| 321 *index = slot_index; | 327 *index = slot_index; |
| 322 *variable_mode = mode; | 328 *variable_mode = mode; |
| 323 *init_flag = flag; | 329 *init_flag = flag; |
| 324 *attributes = GetAttributesForMode(mode); | 330 *attributes = GetAttributesForMode(mode); |
| 325 return context; | 331 return context; |
| 326 } | 332 } |
| 327 | 333 |
| 328 // Check the slot corresponding to the intermediate context holding | 334 // Check the slot corresponding to the intermediate context holding |
| 329 // only the function name variable. It's conceptually (and spec-wise) | 335 // only the function name variable. It's conceptually (and spec-wise) |
| 330 // in an outer scope of the function's declaration scope. | 336 // in an outer scope of the function's declaration scope. |
| 331 if (follow_context_chain && (flags & STOP_AT_DECLARATION_SCOPE) == 0 && | 337 if (follow_context_chain && (flags & STOP_AT_DECLARATION_SCOPE) == 0 && |
| 332 context->IsFunctionContext()) { | 338 (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.
| |
| 333 int function_index = scope_info->FunctionContextSlotIndex(*name); | 339 int function_index = scope_info->FunctionContextSlotIndex(*name); |
| 334 if (function_index >= 0) { | 340 if (function_index >= 0) { |
| 335 if (FLAG_trace_contexts) { | 341 if (FLAG_trace_contexts) { |
| 336 PrintF("=> found intermediate function in context slot %d\n", | 342 PrintF("=> found intermediate function in context slot %d\n", |
| 337 function_index); | 343 function_index); |
| 338 } | 344 } |
| 339 *index = function_index; | 345 *index = function_index; |
| 340 *attributes = READ_ONLY; | 346 *attributes = READ_ONLY; |
| 341 *init_flag = kCreatedInitialized; | 347 *init_flag = kCreatedInitialized; |
| 342 *variable_mode = CONST; | 348 *variable_mode = CONST; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 | 594 |
| 589 int previous_value = errors_thrown()->value(); | 595 int previous_value = errors_thrown()->value(); |
| 590 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 596 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
| 591 } | 597 } |
| 592 | 598 |
| 593 | 599 |
| 594 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 600 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
| 595 | 601 |
| 596 } // namespace internal | 602 } // namespace internal |
| 597 } // namespace v8 | 603 } // namespace v8 |
| OLD | NEW |