| 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 } | 78 } |
| 79 return current; | 79 return current; |
| 80 } | 80 } |
| 81 | 81 |
| 82 Context* Context::closure_context() { | 82 Context* Context::closure_context() { |
| 83 Context* current = this; | 83 Context* current = this; |
| 84 while (!current->IsFunctionContext() && !current->IsScriptContext() && | 84 while (!current->IsFunctionContext() && !current->IsScriptContext() && |
| 85 !current->IsModuleContext() && !current->IsNativeContext()) { | 85 !current->IsModuleContext() && !current->IsNativeContext() && |
| 86 !current->IsEvalContext()) { |
| 86 current = current->previous(); | 87 current = current->previous(); |
| 87 DCHECK(current->closure() == closure()); | 88 DCHECK(current->closure() == closure()); |
| 88 } | 89 } |
| 89 return current; | 90 return current; |
| 90 } | 91 } |
| 91 | 92 |
| 92 JSObject* Context::extension_object() { | 93 JSObject* Context::extension_object() { |
| 93 DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext()); | 94 DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext() || |
| 95 IsEvalContext()); |
| 94 HeapObject* object = extension(); | 96 HeapObject* object = extension(); |
| 95 if (object->IsTheHole(GetIsolate())) return nullptr; | 97 if (object->IsTheHole(GetIsolate())) return nullptr; |
| 96 if (IsBlockContext()) { | 98 if (IsBlockContext()) { |
| 97 if (!object->IsContextExtension()) return nullptr; | 99 if (!object->IsContextExtension()) return nullptr; |
| 98 object = JSObject::cast(ContextExtension::cast(object)->extension()); | 100 object = JSObject::cast(ContextExtension::cast(object)->extension()); |
| 99 } | 101 } |
| 100 DCHECK(object->IsJSContextExtensionObject() || | 102 DCHECK(object->IsJSContextExtensionObject() || |
| 101 (IsNativeContext() && object->IsJSGlobalObject())); | 103 (IsNativeContext() && object->IsJSGlobalObject())); |
| 102 return JSObject::cast(object); | 104 return JSObject::cast(object); |
| 103 } | 105 } |
| 104 | 106 |
| 105 JSReceiver* Context::extension_receiver() { | 107 JSReceiver* Context::extension_receiver() { |
| 106 DCHECK(IsNativeContext() || IsWithContext() || | 108 DCHECK(IsNativeContext() || IsWithContext() || IsEvalContext() || |
| 107 IsFunctionContext() || IsBlockContext()); | 109 IsFunctionContext() || IsBlockContext()); |
| 108 return IsWithContext() ? JSReceiver::cast( | 110 return IsWithContext() ? JSReceiver::cast( |
| 109 ContextExtension::cast(extension())->extension()) | 111 ContextExtension::cast(extension())->extension()) |
| 110 : extension_object(); | 112 : extension_object(); |
| 111 } | 113 } |
| 112 | 114 |
| 113 ScopeInfo* Context::scope_info() { | 115 ScopeInfo* Context::scope_info() { |
| 114 DCHECK(!IsNativeContext()); | 116 DCHECK(!IsNativeContext()); |
| 115 if (IsFunctionContext() || IsModuleContext()) { | 117 if (IsFunctionContext() || IsModuleContext() || IsEvalContext()) { |
| 116 return closure()->shared()->scope_info(); | 118 return closure()->shared()->scope_info(); |
| 117 } | 119 } |
| 118 HeapObject* object = extension(); | 120 HeapObject* object = extension(); |
| 119 if (object->IsContextExtension()) { | 121 if (object->IsContextExtension()) { |
| 120 DCHECK(IsBlockContext() || IsCatchContext() || IsWithContext() || | 122 DCHECK(IsBlockContext() || IsCatchContext() || IsWithContext() || |
| 121 IsDebugEvaluateContext()); | 123 IsDebugEvaluateContext()); |
| 122 object = ContextExtension::cast(object)->scope_info(); | 124 object = ContextExtension::cast(object)->scope_info(); |
| 123 } | 125 } |
| 124 return ScopeInfo::cast(object); | 126 return ScopeInfo::cast(object); |
| 125 } | 127 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 | 218 |
| 217 do { | 219 do { |
| 218 if (FLAG_trace_contexts) { | 220 if (FLAG_trace_contexts) { |
| 219 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); | 221 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); |
| 220 if (context->IsScriptContext()) PrintF(" (script context)"); | 222 if (context->IsScriptContext()) PrintF(" (script context)"); |
| 221 if (context->IsNativeContext()) PrintF(" (native context)"); | 223 if (context->IsNativeContext()) PrintF(" (native context)"); |
| 222 PrintF("\n"); | 224 PrintF("\n"); |
| 223 } | 225 } |
| 224 | 226 |
| 225 // 1. Check global objects, subjects of with, and extension objects. | 227 // 1. Check global objects, subjects of with, and extension objects. |
| 228 DCHECK_IMPLIES(context->IsEvalContext(), |
| 229 context->extension()->IsTheHole(isolate)); |
| 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->IsBlockContext()) && |
| 229 context->extension_receiver() != nullptr) { | 233 context->extension_receiver() != nullptr) { |
| 230 Handle<JSReceiver> object(context->extension_receiver()); | 234 Handle<JSReceiver> object(context->extension_receiver()); |
| 231 | 235 |
| 232 if (context->IsNativeContext()) { | 236 if (context->IsNativeContext()) { |
| 233 if (FLAG_trace_contexts) { | 237 if (FLAG_trace_contexts) { |
| 234 PrintF(" - trying other script contexts\n"); | 238 PrintF(" - trying other script contexts\n"); |
| 235 } | 239 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 if (FLAG_trace_contexts) { | 298 if (FLAG_trace_contexts) { |
| 295 PrintF("=> found property in context object %p\n", | 299 PrintF("=> found property in context object %p\n", |
| 296 reinterpret_cast<void*>(*object)); | 300 reinterpret_cast<void*>(*object)); |
| 297 } | 301 } |
| 298 return object; | 302 return object; |
| 299 } | 303 } |
| 300 } | 304 } |
| 301 | 305 |
| 302 // 2. Check the context proper if it has slots. | 306 // 2. Check the context proper if it has slots. |
| 303 if (context->IsFunctionContext() || context->IsBlockContext() || | 307 if (context->IsFunctionContext() || context->IsBlockContext() || |
| 304 context->IsScriptContext()) { | 308 context->IsScriptContext() || context->IsEvalContext()) { |
| 305 // Use serialized scope information of functions and blocks to search | 309 // Use serialized scope information of functions and blocks to search |
| 306 // for the context index. | 310 // for the context index. |
| 307 Handle<ScopeInfo> scope_info(context->IsFunctionContext() | 311 Handle<ScopeInfo> scope_info(context->scope_info()); |
| 308 ? context->closure()->shared()->scope_info() | |
| 309 : context->scope_info()); | |
| 310 VariableMode mode; | 312 VariableMode mode; |
| 311 InitializationFlag flag; | 313 InitializationFlag flag; |
| 312 MaybeAssignedFlag maybe_assigned_flag; | 314 MaybeAssignedFlag maybe_assigned_flag; |
| 313 int slot_index = ScopeInfo::ContextSlotIndex(scope_info, name, &mode, | 315 int slot_index = ScopeInfo::ContextSlotIndex(scope_info, name, &mode, |
| 314 &flag, &maybe_assigned_flag); | 316 &flag, &maybe_assigned_flag); |
| 315 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); | 317 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); |
| 316 if (slot_index >= 0) { | 318 if (slot_index >= 0) { |
| 317 if (FLAG_trace_contexts) { | 319 if (FLAG_trace_contexts) { |
| 318 PrintF("=> found local in context slot %d (mode = %d)\n", | 320 PrintF("=> found local in context slot %d (mode = %d)\n", |
| 319 slot_index, mode); | 321 slot_index, mode); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 | 770 |
| 769 int previous_value = errors_thrown()->value(); | 771 int previous_value = errors_thrown()->value(); |
| 770 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 772 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
| 771 } | 773 } |
| 772 | 774 |
| 773 | 775 |
| 774 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 776 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
| 775 | 777 |
| 776 } // namespace internal | 778 } // namespace internal |
| 777 } // namespace v8 | 779 } // namespace v8 |
| OLD | NEW |