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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 if (context->IsScriptContext()) PrintF(" (script context)"); | 220 if (context->IsScriptContext()) PrintF(" (script context)"); |
221 if (context->IsNativeContext()) PrintF(" (native context)"); | 221 if (context->IsNativeContext()) PrintF(" (native context)"); |
222 PrintF("\n"); | 222 PrintF("\n"); |
223 } | 223 } |
224 | 224 |
225 // 1. Check global objects, subjects of with, and extension objects. | 225 // 1. Check global objects, subjects of with, and extension objects. |
226 if ((context->IsNativeContext() || | 226 if ((context->IsNativeContext() || |
227 (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || | 227 (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || |
228 context->IsFunctionContext() || context->IsBlockContext()) && | 228 context->IsFunctionContext() || context->IsBlockContext()) && |
229 context->extension_receiver() != nullptr) { | 229 context->extension_receiver() != nullptr) { |
| 230 // A dynamic context will never bind "this" or a synthetic variable; |
| 231 // scope analysis has already ensured that these are resolved |
| 232 // statically. |
| 233 DCHECK(!ScopeInfo::VariableIsSynthetic(*name)); |
| 234 |
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()); |
239 ScriptContextTable::LookupResult r; | 244 ScriptContextTable::LookupResult r; |
(...skipping 14 matching lines...) Expand all Loading... |
254 } | 259 } |
255 | 260 |
256 // Context extension objects needs to behave as if they have no | 261 // Context extension objects needs to behave as if they have no |
257 // prototype. So even if we want to follow prototype chains, we need | 262 // prototype. So even if we want to follow prototype chains, we need |
258 // to only do a local lookup for context extension objects. | 263 // to only do a local lookup for context extension objects. |
259 Maybe<PropertyAttributes> maybe = Nothing<PropertyAttributes>(); | 264 Maybe<PropertyAttributes> maybe = Nothing<PropertyAttributes>(); |
260 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || | 265 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || |
261 object->IsJSContextExtensionObject()) { | 266 object->IsJSContextExtensionObject()) { |
262 maybe = JSReceiver::GetOwnPropertyAttributes(object, name); | 267 maybe = JSReceiver::GetOwnPropertyAttributes(object, name); |
263 } else if (context->IsWithContext()) { | 268 } else if (context->IsWithContext()) { |
264 // A with context will never bind "this". | 269 LookupIterator it(object, name, object); |
265 if (name->Equals(*isolate->factory()->this_string())) { | 270 Maybe<bool> found = UnscopableLookup(&it); |
266 maybe = Just(ABSENT); | 271 if (found.IsNothing()) { |
| 272 maybe = Nothing<PropertyAttributes>(); |
267 } else { | 273 } else { |
268 LookupIterator it(object, name, object); | 274 // Luckily, consumers of |maybe| only care whether the property |
269 Maybe<bool> found = UnscopableLookup(&it); | 275 // was absent or not, so we can return a dummy |NONE| value |
270 if (found.IsNothing()) { | 276 // for its attributes when it was present. |
271 maybe = Nothing<PropertyAttributes>(); | 277 maybe = Just(found.FromJust() ? NONE : ABSENT); |
272 } else { | |
273 // Luckily, consumers of |maybe| only care whether the property | |
274 // was absent or not, so we can return a dummy |NONE| value | |
275 // for its attributes when it was present. | |
276 maybe = Just(found.FromJust() ? NONE : ABSENT); | |
277 } | |
278 } | 278 } |
279 } else { | 279 } else { |
280 maybe = JSReceiver::GetPropertyAttributes(object, name); | 280 maybe = JSReceiver::GetPropertyAttributes(object, name); |
281 } | 281 } |
282 | 282 |
283 if (!maybe.IsJust()) return Handle<Object>(); | 283 if (!maybe.IsJust()) return Handle<Object>(); |
284 DCHECK(!isolate->has_pending_exception()); | 284 DCHECK(!isolate->has_pending_exception()); |
285 *attributes = maybe.FromJust(); | 285 *attributes = maybe.FromJust(); |
286 | 286 |
287 if (maybe.FromJust() != ABSENT) { | 287 if (maybe.FromJust() != ABSENT) { |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 | 582 |
583 int previous_value = errors_thrown()->value(); | 583 int previous_value = errors_thrown()->value(); |
584 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 584 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
585 } | 585 } |
586 | 586 |
587 | 587 |
588 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 588 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
589 | 589 |
590 } // namespace internal | 590 } // namespace internal |
591 } // namespace v8 | 591 } // namespace v8 |
OLD | NEW |