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 context = Handle<Context>(context->global_object()->global_context()); | |
rossberg
2014/10/29 06:37:17
Add a comment why this detour is necessary.
| |
139 visited_global_context = true; | |
140 if (FLAG_trace_contexts) { | |
141 PrintF(" - switching to current global context %p\n", | |
142 reinterpret_cast<void*>(*context)); | |
143 } | |
144 } | |
145 | |
132 // 1. Check global objects, subjects of with, and extension objects. | 146 // 1. Check global objects, subjects of with, and extension objects. |
133 if (context->IsNativeContext() || | 147 if (context->IsNativeContext() || |
134 context->IsWithContext() || | 148 context->IsWithContext() || |
135 (context->IsFunctionContext() && context->has_extension())) { | 149 (context->IsFunctionContext() && context->has_extension())) { |
136 Handle<JSReceiver> object( | 150 Handle<JSReceiver> object( |
137 JSReceiver::cast(context->extension()), isolate); | 151 JSReceiver::cast(context->extension()), isolate); |
138 // Context extension objects needs to behave as if they have no | 152 // Context extension objects needs to behave as if they have no |
139 // prototype. So even if we want to follow prototype chains, we need | 153 // prototype. So even if we want to follow prototype chains, we need |
140 // to only do a local lookup for context extension objects. | 154 // to only do a local lookup for context extension objects. |
141 Maybe<PropertyAttributes> maybe; | 155 Maybe<PropertyAttributes> maybe; |
(...skipping 14 matching lines...) Expand all Loading... | |
156 if (maybe.value != ABSENT) { | 170 if (maybe.value != ABSENT) { |
157 if (FLAG_trace_contexts) { | 171 if (FLAG_trace_contexts) { |
158 PrintF("=> found property in context object %p\n", | 172 PrintF("=> found property in context object %p\n", |
159 reinterpret_cast<void*>(*object)); | 173 reinterpret_cast<void*>(*object)); |
160 } | 174 } |
161 return object; | 175 return object; |
162 } | 176 } |
163 } | 177 } |
164 | 178 |
165 // 2. Check the context proper if it has slots. | 179 // 2. Check the context proper if it has slots. |
166 if (context->IsFunctionContext() || context->IsBlockContext()) { | 180 if (context->IsFunctionContext() || context->IsBlockContext() || |
181 (FLAG_harmony_scoping && context->IsGlobalContext())) { | |
167 // Use serialized scope information of functions and blocks to search | 182 // Use serialized scope information of functions and blocks to search |
168 // for the context index. | 183 // for the context index. |
169 Handle<ScopeInfo> scope_info; | 184 Handle<ScopeInfo> scope_info; |
170 if (context->IsFunctionContext()) { | 185 if (context->IsFunctionContext()) { |
171 scope_info = Handle<ScopeInfo>( | 186 scope_info = Handle<ScopeInfo>( |
172 context->closure()->shared()->scope_info(), isolate); | 187 context->closure()->shared()->scope_info(), isolate); |
173 } else { | 188 } else { |
174 scope_info = Handle<ScopeInfo>( | 189 scope_info = Handle<ScopeInfo>( |
175 ScopeInfo::cast(context->extension()), isolate); | 190 ScopeInfo::cast(context->extension()), isolate); |
176 } | 191 } |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { | 424 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { |
410 // During bootstrapping we allow all objects to pass as global | 425 // During bootstrapping we allow all objects to pass as global |
411 // objects. This is necessary to fix circular dependencies. | 426 // objects. This is necessary to fix circular dependencies. |
412 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || | 427 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || |
413 isolate->bootstrapper()->IsActive() || | 428 isolate->bootstrapper()->IsActive() || |
414 object->IsGlobalObject(); | 429 object->IsGlobalObject(); |
415 } | 430 } |
416 #endif | 431 #endif |
417 | 432 |
418 } } // namespace v8::internal | 433 } } // namespace v8::internal |
OLD | NEW |