| 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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 // Statically allocated variables always have a statically known mode, | 211 // Statically allocated variables always have a statically known mode, |
| 212 // which is the mode with which they were declared when added to the | 212 // which is the mode with which they were declared when added to the |
| 213 // scope. Thus, the DYNAMIC mode (which corresponds to dynamically | 213 // scope. Thus, the DYNAMIC mode (which corresponds to dynamically |
| 214 // declared variables that were introduced through declaration nodes) | 214 // declared variables that were introduced through declaration nodes) |
| 215 // must not appear here. | 215 // must not appear here. |
| 216 UNREACHABLE(); | 216 UNREACHABLE(); |
| 217 break; | 217 break; |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, |
| 222 Handle<Object> Context::Lookup(Handle<String> name, | 222 int* index, PropertyAttributes* attributes, |
| 223 ContextLookupFlags flags, | 223 BindingFlags* binding_flags, |
| 224 int* index, | 224 VariableMode* variable_mode) { |
| 225 PropertyAttributes* attributes, | |
| 226 BindingFlags* binding_flags) { | |
| 227 Isolate* isolate = GetIsolate(); | 225 Isolate* isolate = GetIsolate(); |
| 228 Handle<Context> context(this, isolate); | 226 Handle<Context> context(this, isolate); |
| 229 | 227 |
| 230 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; | 228 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; |
| 231 bool failed_whitelist = false; | 229 bool failed_whitelist = false; |
| 232 *index = kNotFound; | 230 *index = kNotFound; |
| 233 *attributes = ABSENT; | 231 *attributes = ABSENT; |
| 234 *binding_flags = MISSING_BINDING; | 232 *binding_flags = MISSING_BINDING; |
| 233 *variable_mode = VAR; |
| 235 | 234 |
| 236 if (FLAG_trace_contexts) { | 235 if (FLAG_trace_contexts) { |
| 237 PrintF("Context::Lookup("); | 236 PrintF("Context::Lookup("); |
| 238 name->ShortPrint(); | 237 name->ShortPrint(); |
| 239 PrintF(")\n"); | 238 PrintF(")\n"); |
| 240 } | 239 } |
| 241 | 240 |
| 242 do { | 241 do { |
| 243 if (FLAG_trace_contexts) { | 242 if (FLAG_trace_contexts) { |
| 244 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); | 243 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 263 context->global_object()->native_context()->script_context_table()); | 262 context->global_object()->native_context()->script_context_table()); |
| 264 ScriptContextTable::LookupResult r; | 263 ScriptContextTable::LookupResult r; |
| 265 if (ScriptContextTable::Lookup(script_contexts, name, &r)) { | 264 if (ScriptContextTable::Lookup(script_contexts, name, &r)) { |
| 266 if (FLAG_trace_contexts) { | 265 if (FLAG_trace_contexts) { |
| 267 Handle<Context> c = ScriptContextTable::GetContext(script_contexts, | 266 Handle<Context> c = ScriptContextTable::GetContext(script_contexts, |
| 268 r.context_index); | 267 r.context_index); |
| 269 PrintF("=> found property in script context %d: %p\n", | 268 PrintF("=> found property in script context %d: %p\n", |
| 270 r.context_index, reinterpret_cast<void*>(*c)); | 269 r.context_index, reinterpret_cast<void*>(*c)); |
| 271 } | 270 } |
| 272 *index = r.slot_index; | 271 *index = r.slot_index; |
| 272 *variable_mode = r.mode; |
| 273 GetAttributesAndBindingFlags(r.mode, r.init_flag, attributes, | 273 GetAttributesAndBindingFlags(r.mode, r.init_flag, attributes, |
| 274 binding_flags); | 274 binding_flags); |
| 275 return ScriptContextTable::GetContext(script_contexts, | 275 return ScriptContextTable::GetContext(script_contexts, |
| 276 r.context_index); | 276 r.context_index); |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 | 279 |
| 280 // Context extension objects needs to behave as if they have no | 280 // Context extension objects needs to behave as if they have no |
| 281 // prototype. So even if we want to follow prototype chains, we need | 281 // prototype. So even if we want to follow prototype chains, we need |
| 282 // to only do a local lookup for context extension objects. | 282 // to only do a local lookup for context extension objects. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 MaybeAssignedFlag maybe_assigned_flag; | 332 MaybeAssignedFlag maybe_assigned_flag; |
| 333 int slot_index = ScopeInfo::ContextSlotIndex( | 333 int slot_index = ScopeInfo::ContextSlotIndex( |
| 334 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); | 334 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); |
| 335 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); | 335 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); |
| 336 if (slot_index >= 0) { | 336 if (slot_index >= 0) { |
| 337 if (FLAG_trace_contexts) { | 337 if (FLAG_trace_contexts) { |
| 338 PrintF("=> found local in context slot %d (mode = %d)\n", | 338 PrintF("=> found local in context slot %d (mode = %d)\n", |
| 339 slot_index, mode); | 339 slot_index, mode); |
| 340 } | 340 } |
| 341 *index = slot_index; | 341 *index = slot_index; |
| 342 *variable_mode = mode; |
| 342 GetAttributesAndBindingFlags(mode, init_flag, attributes, | 343 GetAttributesAndBindingFlags(mode, init_flag, attributes, |
| 343 binding_flags); | 344 binding_flags); |
| 344 return context; | 345 return context; |
| 345 } | 346 } |
| 346 | 347 |
| 347 // Check the slot corresponding to the intermediate context holding | 348 // Check the slot corresponding to the intermediate context holding |
| 348 // only the function name variable. | 349 // only the function name variable. |
| 349 if (follow_context_chain && context->IsFunctionContext()) { | 350 if (follow_context_chain && context->IsFunctionContext()) { |
| 350 VariableMode mode; | 351 VariableMode mode; |
| 351 int function_index = scope_info->FunctionContextSlotIndex(*name, &mode); | 352 int function_index = scope_info->FunctionContextSlotIndex(*name, &mode); |
| 352 if (function_index >= 0) { | 353 if (function_index >= 0) { |
| 353 if (FLAG_trace_contexts) { | 354 if (FLAG_trace_contexts) { |
| 354 PrintF("=> found intermediate function in context slot %d\n", | 355 PrintF("=> found intermediate function in context slot %d\n", |
| 355 function_index); | 356 function_index); |
| 356 } | 357 } |
| 357 *index = function_index; | 358 *index = function_index; |
| 358 *attributes = READ_ONLY; | 359 *attributes = READ_ONLY; |
| 359 DCHECK(mode == CONST_LEGACY || mode == CONST); | 360 DCHECK(mode == CONST_LEGACY || mode == CONST); |
| 360 *binding_flags = BINDING_IS_INITIALIZED; | 361 *binding_flags = BINDING_IS_INITIALIZED; |
| 362 *variable_mode = mode; |
| 361 return context; | 363 return context; |
| 362 } | 364 } |
| 363 } | 365 } |
| 364 | 366 |
| 365 } else if (context->IsCatchContext()) { | 367 } else if (context->IsCatchContext()) { |
| 366 // Catch contexts have the variable name in the extension slot. | 368 // Catch contexts have the variable name in the extension slot. |
| 367 if (String::Equals(name, handle(context->catch_name()))) { | 369 if (String::Equals(name, handle(context->catch_name()))) { |
| 368 if (FLAG_trace_contexts) { | 370 if (FLAG_trace_contexts) { |
| 369 PrintF("=> found in catch context\n"); | 371 PrintF("=> found in catch context\n"); |
| 370 } | 372 } |
| 371 *index = Context::THROWN_OBJECT_INDEX; | 373 *index = Context::THROWN_OBJECT_INDEX; |
| 372 *attributes = NONE; | 374 *attributes = NONE; |
| 373 *binding_flags = BINDING_IS_INITIALIZED; | 375 *binding_flags = BINDING_IS_INITIALIZED; |
| 376 *variable_mode = VAR; |
| 374 return context; | 377 return context; |
| 375 } | 378 } |
| 376 } else if (context->IsDebugEvaluateContext()) { | 379 } else if (context->IsDebugEvaluateContext()) { |
| 377 // Check materialized locals. | 380 // Check materialized locals. |
| 378 Object* obj = context->get(EXTENSION_INDEX); | 381 Object* obj = context->get(EXTENSION_INDEX); |
| 379 if (obj->IsJSReceiver()) { | 382 if (obj->IsJSReceiver()) { |
| 380 Handle<JSReceiver> extension(JSReceiver::cast(obj)); | 383 Handle<JSReceiver> extension(JSReceiver::cast(obj)); |
| 381 LookupIterator it(extension, name, extension); | 384 LookupIterator it(extension, name, extension); |
| 382 Maybe<bool> found = JSReceiver::HasProperty(&it); | 385 Maybe<bool> found = JSReceiver::HasProperty(&it); |
| 383 if (found.FromMaybe(false)) { | 386 if (found.FromMaybe(false)) { |
| 384 *attributes = NONE; | 387 *attributes = NONE; |
| 385 return extension; | 388 return extension; |
| 386 } | 389 } |
| 387 } | 390 } |
| 388 // Check the original context, but do not follow its context chain. | 391 // Check the original context, but do not follow its context chain. |
| 389 obj = context->get(WRAPPED_CONTEXT_INDEX); | 392 obj = context->get(WRAPPED_CONTEXT_INDEX); |
| 390 if (obj->IsContext()) { | 393 if (obj->IsContext()) { |
| 391 Handle<Object> result = Context::cast(obj)->Lookup( | 394 Handle<Object> result = Context::cast(obj)->Lookup( |
| 392 name, DONT_FOLLOW_CHAINS, index, attributes, binding_flags); | 395 name, DONT_FOLLOW_CHAINS, index, attributes, binding_flags, |
| 396 variable_mode); |
| 393 if (!result.is_null()) return result; | 397 if (!result.is_null()) return result; |
| 394 } | 398 } |
| 395 // Check whitelist. Names that do not pass whitelist shall only resolve | 399 // Check whitelist. Names that do not pass whitelist shall only resolve |
| 396 // to with, script or native contexts up the context chain. | 400 // to with, script or native contexts up the context chain. |
| 397 obj = context->get(WHITE_LIST_INDEX); | 401 obj = context->get(WHITE_LIST_INDEX); |
| 398 if (obj->IsStringSet()) { | 402 if (obj->IsStringSet()) { |
| 399 failed_whitelist = failed_whitelist || !StringSet::cast(obj)->Has(name); | 403 failed_whitelist = failed_whitelist || !StringSet::cast(obj)->Has(name); |
| 400 } | 404 } |
| 401 } | 405 } |
| 402 | 406 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 | 613 |
| 610 int previous_value = errors_thrown()->value(); | 614 int previous_value = errors_thrown()->value(); |
| 611 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 615 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
| 612 } | 616 } |
| 613 | 617 |
| 614 | 618 |
| 615 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 619 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
| 616 | 620 |
| 617 } // namespace internal | 621 } // namespace internal |
| 618 } // namespace v8 | 622 } // namespace v8 |
| OLD | NEW |