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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/debug.h" | 8 #include "src/debug.h" |
9 #include "src/scopeinfo.h" | 9 #include "src/scopeinfo.h" |
10 | 10 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 *index = -1; | 115 *index = -1; |
116 *attributes = ABSENT; | 116 *attributes = ABSENT; |
117 *binding_flags = MISSING_BINDING; | 117 *binding_flags = MISSING_BINDING; |
118 | 118 |
119 if (FLAG_trace_contexts) { | 119 if (FLAG_trace_contexts) { |
120 PrintF("Context::Lookup("); | 120 PrintF("Context::Lookup("); |
121 name->ShortPrint(); | 121 name->ShortPrint(); |
122 PrintF(")\n"); | 122 PrintF(")\n"); |
123 } | 123 } |
124 | 124 |
| 125 bool visited_global_context = false; |
| 126 |
125 do { | 127 do { |
126 if (FLAG_trace_contexts) { | 128 if (FLAG_trace_contexts) { |
127 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); | 129 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); |
| 130 if (context->IsGlobalContext()) PrintF(" (global context)"); |
128 if (context->IsNativeContext()) PrintF(" (native context)"); | 131 if (context->IsNativeContext()) PrintF(" (native context)"); |
129 PrintF("\n"); | 132 PrintF("\n"); |
130 } | 133 } |
131 | 134 |
| 135 if (follow_context_chain && FLAG_harmony_scoping && |
| 136 !visited_global_context && |
| 137 (context->IsGlobalContext() || context->IsNativeContext())) { |
| 138 // For lexical scoping, on a top level, we might resolve to the |
| 139 // lexical bindings introduced by later scrips. Therefore we need to |
| 140 // switch to the the last added global context during lookup here. |
| 141 context = Handle<Context>(context->global_object()->global_context()); |
| 142 visited_global_context = true; |
| 143 if (FLAG_trace_contexts) { |
| 144 PrintF(" - switching to current global context %p\n", |
| 145 reinterpret_cast<void*>(*context)); |
| 146 } |
| 147 } |
| 148 |
132 // 1. Check global objects, subjects of with, and extension objects. | 149 // 1. Check global objects, subjects of with, and extension objects. |
133 if (context->IsNativeContext() || | 150 if (context->IsNativeContext() || |
134 context->IsWithContext() || | 151 context->IsWithContext() || |
135 (context->IsFunctionContext() && context->has_extension())) { | 152 (context->IsFunctionContext() && context->has_extension())) { |
136 Handle<JSReceiver> object( | 153 Handle<JSReceiver> object( |
137 JSReceiver::cast(context->extension()), isolate); | 154 JSReceiver::cast(context->extension()), isolate); |
138 // Context extension objects needs to behave as if they have no | 155 // Context extension objects needs to behave as if they have no |
139 // prototype. So even if we want to follow prototype chains, we need | 156 // prototype. So even if we want to follow prototype chains, we need |
140 // to only do a local lookup for context extension objects. | 157 // to only do a local lookup for context extension objects. |
141 Maybe<PropertyAttributes> maybe; | 158 Maybe<PropertyAttributes> maybe; |
(...skipping 14 matching lines...) Expand all Loading... |
156 if (maybe.value != ABSENT) { | 173 if (maybe.value != ABSENT) { |
157 if (FLAG_trace_contexts) { | 174 if (FLAG_trace_contexts) { |
158 PrintF("=> found property in context object %p\n", | 175 PrintF("=> found property in context object %p\n", |
159 reinterpret_cast<void*>(*object)); | 176 reinterpret_cast<void*>(*object)); |
160 } | 177 } |
161 return object; | 178 return object; |
162 } | 179 } |
163 } | 180 } |
164 | 181 |
165 // 2. Check the context proper if it has slots. | 182 // 2. Check the context proper if it has slots. |
166 if (context->IsFunctionContext() || context->IsBlockContext()) { | 183 if (context->IsFunctionContext() || context->IsBlockContext() || |
| 184 (FLAG_harmony_scoping && context->IsGlobalContext())) { |
167 // Use serialized scope information of functions and blocks to search | 185 // Use serialized scope information of functions and blocks to search |
168 // for the context index. | 186 // for the context index. |
169 Handle<ScopeInfo> scope_info; | 187 Handle<ScopeInfo> scope_info; |
170 if (context->IsFunctionContext()) { | 188 if (context->IsFunctionContext()) { |
171 scope_info = Handle<ScopeInfo>( | 189 scope_info = Handle<ScopeInfo>( |
172 context->closure()->shared()->scope_info(), isolate); | 190 context->closure()->shared()->scope_info(), isolate); |
173 } else { | 191 } else { |
174 scope_info = Handle<ScopeInfo>( | 192 scope_info = Handle<ScopeInfo>( |
175 ScopeInfo::cast(context->extension()), isolate); | 193 ScopeInfo::cast(context->extension()), isolate); |
176 } | 194 } |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { | 427 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { |
410 // During bootstrapping we allow all objects to pass as global | 428 // During bootstrapping we allow all objects to pass as global |
411 // objects. This is necessary to fix circular dependencies. | 429 // objects. This is necessary to fix circular dependencies. |
412 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || | 430 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || |
413 isolate->bootstrapper()->IsActive() || | 431 isolate->bootstrapper()->IsActive() || |
414 object->IsGlobalObject(); | 432 object->IsGlobalObject(); |
415 } | 433 } |
416 #endif | 434 #endif |
417 | 435 |
418 } } // namespace v8::internal | 436 } } // namespace v8::internal |
OLD | NEW |