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/ast/scopeinfo.h" | 7 #include "src/ast/scopeinfo.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 | 226 |
227 Handle<Object> Context::Lookup(Handle<String> name, | 227 Handle<Object> Context::Lookup(Handle<String> name, |
228 ContextLookupFlags flags, | 228 ContextLookupFlags flags, |
229 int* index, | 229 int* index, |
230 PropertyAttributes* attributes, | 230 PropertyAttributes* attributes, |
231 BindingFlags* binding_flags) { | 231 BindingFlags* binding_flags) { |
232 Isolate* isolate = GetIsolate(); | 232 Isolate* isolate = GetIsolate(); |
233 Handle<Context> context(this, isolate); | 233 Handle<Context> context(this, isolate); |
234 | 234 |
235 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; | 235 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; |
| 236 bool failed_whitelist = false; |
236 *index = kNotFound; | 237 *index = kNotFound; |
237 *attributes = ABSENT; | 238 *attributes = ABSENT; |
238 *binding_flags = MISSING_BINDING; | 239 *binding_flags = MISSING_BINDING; |
239 | 240 |
240 if (FLAG_trace_contexts) { | 241 if (FLAG_trace_contexts) { |
241 PrintF("Context::Lookup("); | 242 PrintF("Context::Lookup("); |
242 name->ShortPrint(); | 243 name->ShortPrint(); |
243 PrintF(")\n"); | 244 PrintF(")\n"); |
244 } | 245 } |
245 | 246 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 // Catch contexts have the variable name in the extension slot. | 372 // Catch contexts have the variable name in the extension slot. |
372 if (String::Equals(name, handle(context->catch_name()))) { | 373 if (String::Equals(name, handle(context->catch_name()))) { |
373 if (FLAG_trace_contexts) { | 374 if (FLAG_trace_contexts) { |
374 PrintF("=> found in catch context\n"); | 375 PrintF("=> found in catch context\n"); |
375 } | 376 } |
376 *index = Context::THROWN_OBJECT_INDEX; | 377 *index = Context::THROWN_OBJECT_INDEX; |
377 *attributes = NONE; | 378 *attributes = NONE; |
378 *binding_flags = MUTABLE_IS_INITIALIZED; | 379 *binding_flags = MUTABLE_IS_INITIALIZED; |
379 return context; | 380 return context; |
380 } | 381 } |
| 382 } else if (context->IsDebugEvaluateContext()) { |
| 383 // Check materialized locals. |
| 384 Object* obj = context->get(EXTENSION_INDEX); |
| 385 if (obj->IsJSReceiver()) { |
| 386 Handle<JSReceiver> extension(JSReceiver::cast(obj)); |
| 387 LookupIterator it(extension, name, extension); |
| 388 Maybe<bool> found = JSReceiver::HasProperty(&it); |
| 389 if (found.FromMaybe(false)) { |
| 390 *attributes = NONE; |
| 391 return extension; |
| 392 } |
| 393 } |
| 394 // Check the original context, but do not follow its context chain. |
| 395 obj = context->get(WRAPPED_CONTEXT_INDEX); |
| 396 if (obj->IsContext()) { |
| 397 Handle<Object> result = Context::cast(obj)->Lookup( |
| 398 name, DONT_FOLLOW_CHAINS, index, attributes, binding_flags); |
| 399 if (!result.is_null()) return result; |
| 400 } |
| 401 // Check whitelist. Names that do not pass whitelist shall only resolve |
| 402 // to with, script or native contexts up the context chain. |
| 403 obj = context->get(WHITE_LIST_INDEX); |
| 404 if (obj->IsStringSet()) { |
| 405 failed_whitelist = failed_whitelist || !StringSet::cast(obj)->Has(name); |
| 406 } |
381 } | 407 } |
382 | 408 |
383 // 3. Prepare to continue with the previous (next outermost) context. | 409 // 3. Prepare to continue with the previous (next outermost) context. |
384 if (context->IsNativeContext() || | 410 if (context->IsNativeContext() || |
385 ((flags & STOP_AT_DECLARATION_SCOPE) != 0 && | 411 ((flags & STOP_AT_DECLARATION_SCOPE) != 0 && |
386 context->is_declaration_context())) { | 412 context->is_declaration_context())) { |
387 follow_context_chain = false; | 413 follow_context_chain = false; |
388 } else { | 414 } else { |
389 context = Handle<Context>(context->previous(), isolate); | 415 do { |
| 416 context = Handle<Context>(context->previous(), isolate); |
| 417 // If we come across a whitelist context, and the name is not |
| 418 // whitelisted, then only consider with, script or native contexts. |
| 419 } while (failed_whitelist && !context->IsScriptContext() && |
| 420 !context->IsNativeContext() && !context->IsWithContext()); |
390 } | 421 } |
391 } while (follow_context_chain); | 422 } while (follow_context_chain); |
392 | 423 |
393 if (FLAG_trace_contexts) { | 424 if (FLAG_trace_contexts) { |
394 PrintF("=> no property/slot found\n"); | 425 PrintF("=> no property/slot found\n"); |
395 } | 426 } |
396 return Handle<Object>::null(); | 427 return Handle<Object>::null(); |
397 } | 428 } |
398 | 429 |
399 | 430 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 | 613 |
583 int previous_value = errors_thrown()->value(); | 614 int previous_value = errors_thrown()->value(); |
584 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 615 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
585 } | 616 } |
586 | 617 |
587 | 618 |
588 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 619 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
589 | 620 |
590 } // namespace internal | 621 } // namespace internal |
591 } // namespace v8 | 622 } // namespace v8 |
OLD | NEW |