| 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 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 | 14 |
| 15 Handle<GlobalContextTable> GlobalContextTable::Extend( | 15 Handle<ScriptContextTable> ScriptContextTable::Extend( |
| 16 Handle<GlobalContextTable> table, Handle<Context> global_context) { | 16 Handle<ScriptContextTable> table, Handle<Context> script_context) { |
| 17 Handle<GlobalContextTable> result; | 17 Handle<ScriptContextTable> result; |
| 18 int used = table->used(); | 18 int used = table->used(); |
| 19 int length = table->length(); | 19 int length = table->length(); |
| 20 CHECK(used >= 0 && length > 0 && used < length); | 20 CHECK(used >= 0 && length > 0 && used < length); |
| 21 if (used + 1 == length) { | 21 if (used + 1 == length) { |
| 22 CHECK(length < Smi::kMaxValue / 2); | 22 CHECK(length < Smi::kMaxValue / 2); |
| 23 result = Handle<GlobalContextTable>::cast( | 23 result = Handle<ScriptContextTable>::cast( |
| 24 FixedArray::CopySize(table, length * 2)); | 24 FixedArray::CopySize(table, length * 2)); |
| 25 } else { | 25 } else { |
| 26 result = table; | 26 result = table; |
| 27 } | 27 } |
| 28 result->set_used(used + 1); | 28 result->set_used(used + 1); |
| 29 | 29 |
| 30 DCHECK(global_context->IsGlobalContext()); | 30 DCHECK(script_context->IsScriptContext()); |
| 31 result->set(used + 1, *global_context); | 31 result->set(used + 1, *script_context); |
| 32 return result; | 32 return result; |
| 33 } | 33 } |
| 34 | 34 |
| 35 | 35 |
| 36 bool GlobalContextTable::Lookup(Handle<GlobalContextTable> table, | 36 bool ScriptContextTable::Lookup(Handle<ScriptContextTable> table, |
| 37 Handle<String> name, LookupResult* result) { | 37 Handle<String> name, LookupResult* result) { |
| 38 for (int i = 0; i < table->used(); i++) { | 38 for (int i = 0; i < table->used(); i++) { |
| 39 Handle<Context> context = GetContext(table, i); | 39 Handle<Context> context = GetContext(table, i); |
| 40 DCHECK(context->IsGlobalContext()); | 40 DCHECK(context->IsScriptContext()); |
| 41 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); | 41 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); |
| 42 int slot_index = ScopeInfo::ContextSlotIndex( | 42 int slot_index = ScopeInfo::ContextSlotIndex( |
| 43 scope_info, name, &result->mode, &result->init_flag, | 43 scope_info, name, &result->mode, &result->init_flag, |
| 44 &result->maybe_assigned_flag); | 44 &result->maybe_assigned_flag); |
| 45 | 45 |
| 46 if (slot_index >= 0) { | 46 if (slot_index >= 0) { |
| 47 result->context_index = i; | 47 result->context_index = i; |
| 48 result->slot_index = slot_index; | 48 result->slot_index = slot_index; |
| 49 return true; | 49 return true; |
| 50 } | 50 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 67 GlobalObject* object = global_object(); | 67 GlobalObject* object = global_object(); |
| 68 if (object->IsJSGlobalObject()) { | 68 if (object->IsJSGlobalObject()) { |
| 69 return JSGlobalObject::cast(object)->builtins(); | 69 return JSGlobalObject::cast(object)->builtins(); |
| 70 } else { | 70 } else { |
| 71 DCHECK(object->IsJSBuiltinsObject()); | 71 DCHECK(object->IsJSBuiltinsObject()); |
| 72 return JSBuiltinsObject::cast(object); | 72 return JSBuiltinsObject::cast(object); |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 Context* Context::global_context() { | 77 Context* Context::script_context() { |
| 78 Context* current = this; | 78 Context* current = this; |
| 79 while (!current->IsGlobalContext()) { | 79 while (!current->IsScriptContext()) { |
| 80 current = current->previous(); | 80 current = current->previous(); |
| 81 } | 81 } |
| 82 return current; | 82 return current; |
| 83 } | 83 } |
| 84 | 84 |
| 85 | 85 |
| 86 Context* Context::native_context() { | 86 Context* Context::native_context() { |
| 87 // Fast case: the global object for this context has been set. In | 87 // Fast case: the global object for this context has been set. In |
| 88 // that case, the global object has a direct pointer to the global | 88 // that case, the global object has a direct pointer to the global |
| 89 // context. | 89 // context. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 | 207 |
| 208 if (FLAG_trace_contexts) { | 208 if (FLAG_trace_contexts) { |
| 209 PrintF("Context::Lookup("); | 209 PrintF("Context::Lookup("); |
| 210 name->ShortPrint(); | 210 name->ShortPrint(); |
| 211 PrintF(")\n"); | 211 PrintF(")\n"); |
| 212 } | 212 } |
| 213 | 213 |
| 214 do { | 214 do { |
| 215 if (FLAG_trace_contexts) { | 215 if (FLAG_trace_contexts) { |
| 216 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); | 216 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); |
| 217 if (context->IsGlobalContext()) PrintF(" (global context)"); | 217 if (context->IsScriptContext()) PrintF(" (script context)"); |
| 218 if (context->IsNativeContext()) PrintF(" (native context)"); | 218 if (context->IsNativeContext()) PrintF(" (native context)"); |
| 219 PrintF("\n"); | 219 PrintF("\n"); |
| 220 } | 220 } |
| 221 | 221 |
| 222 | 222 |
| 223 // 1. Check global objects, subjects of with, and extension objects. | 223 // 1. Check global objects, subjects of with, and extension objects. |
| 224 if (context->IsNativeContext() || | 224 if (context->IsNativeContext() || |
| 225 context->IsWithContext() || | 225 context->IsWithContext() || |
| 226 (context->IsFunctionContext() && context->has_extension())) { | 226 (context->IsFunctionContext() && context->has_extension())) { |
| 227 Handle<JSReceiver> object( | 227 Handle<JSReceiver> object( |
| 228 JSReceiver::cast(context->extension()), isolate); | 228 JSReceiver::cast(context->extension()), isolate); |
| 229 | 229 |
| 230 if (context->IsNativeContext()) { | 230 if (context->IsNativeContext()) { |
| 231 if (FLAG_trace_contexts) { | 231 if (FLAG_trace_contexts) { |
| 232 PrintF(" - trying other global contexts\n"); | 232 PrintF(" - trying other script contexts\n"); |
| 233 } | 233 } |
| 234 // Try other global contexts. | 234 // Try other script contexts. |
| 235 Handle<GlobalContextTable> global_contexts( | 235 Handle<ScriptContextTable> script_contexts( |
| 236 context->global_object()->native_context()->global_context_table()); | 236 context->global_object()->native_context()->script_context_table()); |
| 237 GlobalContextTable::LookupResult r; | 237 ScriptContextTable::LookupResult r; |
| 238 if (GlobalContextTable::Lookup(global_contexts, name, &r)) { | 238 if (ScriptContextTable::Lookup(script_contexts, name, &r)) { |
| 239 if (FLAG_trace_contexts) { | 239 if (FLAG_trace_contexts) { |
| 240 Handle<Context> c = GlobalContextTable::GetContext(global_contexts, | 240 Handle<Context> c = ScriptContextTable::GetContext(script_contexts, |
| 241 r.context_index); | 241 r.context_index); |
| 242 PrintF("=> found property in global context %d: %p\n", | 242 PrintF("=> found property in script context %d: %p\n", |
| 243 r.context_index, reinterpret_cast<void*>(*c)); | 243 r.context_index, reinterpret_cast<void*>(*c)); |
| 244 } | 244 } |
| 245 *index = r.slot_index; | 245 *index = r.slot_index; |
| 246 GetAttributesAndBindingFlags(r.mode, r.init_flag, attributes, | 246 GetAttributesAndBindingFlags(r.mode, r.init_flag, attributes, |
| 247 binding_flags); | 247 binding_flags); |
| 248 return GlobalContextTable::GetContext(global_contexts, | 248 return ScriptContextTable::GetContext(script_contexts, |
| 249 r.context_index); | 249 r.context_index); |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 // Context extension objects needs to behave as if they have no | 253 // Context extension objects needs to behave as if they have no |
| 254 // prototype. So even if we want to follow prototype chains, we need | 254 // prototype. So even if we want to follow prototype chains, we need |
| 255 // to only do a local lookup for context extension objects. | 255 // to only do a local lookup for context extension objects. |
| 256 Maybe<PropertyAttributes> maybe; | 256 Maybe<PropertyAttributes> maybe; |
| 257 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || | 257 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || |
| 258 object->IsJSContextExtensionObject()) { | 258 object->IsJSContextExtensionObject()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 272 if (FLAG_trace_contexts) { | 272 if (FLAG_trace_contexts) { |
| 273 PrintF("=> found property in context object %p\n", | 273 PrintF("=> found property in context object %p\n", |
| 274 reinterpret_cast<void*>(*object)); | 274 reinterpret_cast<void*>(*object)); |
| 275 } | 275 } |
| 276 return object; | 276 return object; |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 | 279 |
| 280 // 2. Check the context proper if it has slots. | 280 // 2. Check the context proper if it has slots. |
| 281 if (context->IsFunctionContext() || context->IsBlockContext() || | 281 if (context->IsFunctionContext() || context->IsBlockContext() || |
| 282 (FLAG_harmony_scoping && context->IsGlobalContext())) { | 282 (FLAG_harmony_scoping && context->IsScriptContext())) { |
| 283 // Use serialized scope information of functions and blocks to search | 283 // Use serialized scope information of functions and blocks to search |
| 284 // for the context index. | 284 // for the context index. |
| 285 Handle<ScopeInfo> scope_info; | 285 Handle<ScopeInfo> scope_info; |
| 286 if (context->IsFunctionContext()) { | 286 if (context->IsFunctionContext()) { |
| 287 scope_info = Handle<ScopeInfo>( | 287 scope_info = Handle<ScopeInfo>( |
| 288 context->closure()->shared()->scope_info(), isolate); | 288 context->closure()->shared()->scope_info(), isolate); |
| 289 } else { | 289 } else { |
| 290 scope_info = Handle<ScopeInfo>( | 290 scope_info = Handle<ScopeInfo>( |
| 291 ScopeInfo::cast(context->extension()), isolate); | 291 ScopeInfo::cast(context->extension()), isolate); |
| 292 } | 292 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 | 473 |
| 474 | 474 |
| 475 #ifdef DEBUG | 475 #ifdef DEBUG |
| 476 bool Context::IsBootstrappingOrValidParentContext( | 476 bool Context::IsBootstrappingOrValidParentContext( |
| 477 Object* object, Context* child) { | 477 Object* object, Context* child) { |
| 478 // During bootstrapping we allow all objects to pass as | 478 // During bootstrapping we allow all objects to pass as |
| 479 // contexts. This is necessary to fix circular dependencies. | 479 // contexts. This is necessary to fix circular dependencies. |
| 480 if (child->GetIsolate()->bootstrapper()->IsActive()) return true; | 480 if (child->GetIsolate()->bootstrapper()->IsActive()) return true; |
| 481 if (!object->IsContext()) return false; | 481 if (!object->IsContext()) return false; |
| 482 Context* context = Context::cast(object); | 482 Context* context = Context::cast(object); |
| 483 return context->IsNativeContext() || context->IsGlobalContext() || | 483 return context->IsNativeContext() || context->IsScriptContext() || |
| 484 context->IsModuleContext() || !child->IsModuleContext(); | 484 context->IsModuleContext() || !child->IsModuleContext(); |
| 485 } | 485 } |
| 486 | 486 |
| 487 | 487 |
| 488 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { | 488 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { |
| 489 // During bootstrapping we allow all objects to pass as global | 489 // During bootstrapping we allow all objects to pass as global |
| 490 // objects. This is necessary to fix circular dependencies. | 490 // objects. This is necessary to fix circular dependencies. |
| 491 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || | 491 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || |
| 492 isolate->bootstrapper()->IsActive() || | 492 isolate->bootstrapper()->IsActive() || |
| 493 object->IsGlobalObject(); | 493 object->IsGlobalObject(); |
| 494 } | 494 } |
| 495 #endif | 495 #endif |
| 496 | 496 |
| 497 } } // namespace v8::internal | 497 } } // namespace v8::internal |
| OLD | NEW |