Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: src/contexts.cc

Issue 705663004: harmony_scoping: Implement lexical bindings at top level (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased patch for landing Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/contexts.h ('k') | src/factory.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/contexts.cc
diff --git a/src/contexts.cc b/src/contexts.cc
index 537d92d0f4032cf5be4d6db03b850d9f8c6beeb7..37db84d04bd0e97cf2ef83b5aca9ce45da01712b 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -11,6 +11,48 @@
namespace v8 {
namespace internal {
+
+Handle<GlobalContextTable> GlobalContextTable::Extend(
+ Handle<GlobalContextTable> table, Handle<Context> global_context) {
+ Handle<GlobalContextTable> result;
+ int used = table->used();
+ int length = table->length();
+ CHECK(used >= 0 && length > 0 && used < length);
+ if (used + 1 == length) {
+ CHECK(length < Smi::kMaxValue / 2);
+ result = Handle<GlobalContextTable>::cast(
+ FixedArray::CopySize(table, length * 2));
+ } else {
+ result = table;
+ }
+ result->set_used(used + 1);
+
+ DCHECK(global_context->IsGlobalContext());
+ result->set(used + 1, *global_context);
+ return result;
+}
+
+
+bool GlobalContextTable::Lookup(Handle<GlobalContextTable> table,
+ Handle<String> name, LookupResult* result) {
+ for (int i = 0; i < table->used(); i++) {
+ Handle<Context> context = GetContext(table, i);
+ DCHECK(context->IsGlobalContext());
+ Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+ int slot_index = ScopeInfo::ContextSlotIndex(
+ scope_info, name, &result->mode, &result->init_flag,
+ &result->maybe_assigned_flag);
+
+ if (slot_index >= 0) {
+ result->context_index = i;
+ result->slot_index = slot_index;
+ return true;
+ }
+ }
+ return false;
+}
+
+
Context* Context::declaration_context() {
Context* current = this;
while (!current->IsFunctionContext() && !current->IsNativeContext()) {
@@ -102,6 +144,53 @@ static Maybe<PropertyAttributes> UnscopableLookup(LookupIterator* it) {
return attrs;
}
+static void GetAttributesAndBindingFlags(VariableMode mode,
+ InitializationFlag init_flag,
+ PropertyAttributes* attributes,
+ BindingFlags* binding_flags) {
+ switch (mode) {
+ case INTERNAL: // Fall through.
+ case VAR:
+ *attributes = NONE;
+ *binding_flags = MUTABLE_IS_INITIALIZED;
+ break;
+ case LET:
+ *attributes = NONE;
+ *binding_flags = (init_flag == kNeedsInitialization)
+ ? MUTABLE_CHECK_INITIALIZED
+ : MUTABLE_IS_INITIALIZED;
+ break;
+ case CONST_LEGACY:
+ *attributes = READ_ONLY;
+ *binding_flags = (init_flag == kNeedsInitialization)
+ ? IMMUTABLE_CHECK_INITIALIZED
+ : IMMUTABLE_IS_INITIALIZED;
+ break;
+ case CONST:
+ *attributes = READ_ONLY;
+ *binding_flags = (init_flag == kNeedsInitialization)
+ ? IMMUTABLE_CHECK_INITIALIZED_HARMONY
+ : IMMUTABLE_IS_INITIALIZED_HARMONY;
+ break;
+ case MODULE:
+ *attributes = READ_ONLY;
+ *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
+ break;
+ case DYNAMIC:
+ case DYNAMIC_GLOBAL:
+ case DYNAMIC_LOCAL:
+ case TEMPORARY:
+ // Note: Fixed context slots are statically allocated by the compiler.
+ // Statically allocated variables always have a statically known mode,
+ // which is the mode with which they were declared when added to the
+ // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
+ // declared variables that were introduced through declaration nodes)
+ // must not appear here.
+ UNREACHABLE();
+ break;
+ }
+}
+
Handle<Object> Context::Lookup(Handle<String> name,
ContextLookupFlags flags,
@@ -122,8 +211,6 @@ Handle<Object> Context::Lookup(Handle<String> name,
PrintF(")\n");
}
- bool visited_global_context = false;
-
do {
if (FLAG_trace_contexts) {
PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
@@ -132,19 +219,6 @@ Handle<Object> Context::Lookup(Handle<String> name,
PrintF("\n");
}
- if (follow_context_chain && FLAG_harmony_scoping &&
- !visited_global_context &&
- (context->IsGlobalContext() || context->IsNativeContext())) {
- // For lexical scoping, on a top level, we might resolve to the
- // lexical bindings introduced by later scrips. Therefore we need to
- // switch to the the last added global context during lookup here.
- context = Handle<Context>(context->global_object()->global_context());
- visited_global_context = true;
- if (FLAG_trace_contexts) {
- PrintF(" - switching to current global context %p\n",
- reinterpret_cast<void*>(*context));
- }
- }
// 1. Check global objects, subjects of with, and extension objects.
if (context->IsNativeContext() ||
@@ -152,6 +226,30 @@ Handle<Object> Context::Lookup(Handle<String> name,
(context->IsFunctionContext() && context->has_extension())) {
Handle<JSReceiver> object(
JSReceiver::cast(context->extension()), isolate);
+
+ if (context->IsNativeContext()) {
+ if (FLAG_trace_contexts) {
+ PrintF(" - trying other global contexts\n");
+ }
+ // Try other global contexts.
+ Handle<GlobalContextTable> global_contexts(
+ context->global_object()->native_context()->global_context_table());
+ GlobalContextTable::LookupResult r;
+ if (GlobalContextTable::Lookup(global_contexts, name, &r)) {
+ if (FLAG_trace_contexts) {
+ Handle<Context> c = GlobalContextTable::GetContext(global_contexts,
+ r.context_index);
+ PrintF("=> found property in global context %d: %p\n",
+ r.context_index, reinterpret_cast<void*>(*c));
+ }
+ *index = r.slot_index;
+ GetAttributesAndBindingFlags(r.mode, r.init_flag, attributes,
+ binding_flags);
+ return GlobalContextTable::GetContext(global_contexts,
+ r.context_index);
+ }
+ }
+
// Context extension objects needs to behave as if they have no
// prototype. So even if we want to follow prototype chains, we need
// to only do a local lookup for context extension objects.
@@ -206,45 +304,8 @@ Handle<Object> Context::Lookup(Handle<String> name,
slot_index, mode);
}
*index = slot_index;
- // Note: Fixed context slots are statically allocated by the compiler.
- // Statically allocated variables always have a statically known mode,
- // which is the mode with which they were declared when added to the
- // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
- // declared variables that were introduced through declaration nodes)
- // must not appear here.
- switch (mode) {
- case INTERNAL: // Fall through.
- case VAR:
- *attributes = NONE;
- *binding_flags = MUTABLE_IS_INITIALIZED;
- break;
- case LET:
- *attributes = NONE;
- *binding_flags = (init_flag == kNeedsInitialization)
- ? MUTABLE_CHECK_INITIALIZED : MUTABLE_IS_INITIALIZED;
- break;
- case CONST_LEGACY:
- *attributes = READ_ONLY;
- *binding_flags = (init_flag == kNeedsInitialization)
- ? IMMUTABLE_CHECK_INITIALIZED : IMMUTABLE_IS_INITIALIZED;
- break;
- case CONST:
- *attributes = READ_ONLY;
- *binding_flags = (init_flag == kNeedsInitialization)
- ? IMMUTABLE_CHECK_INITIALIZED_HARMONY :
- IMMUTABLE_IS_INITIALIZED_HARMONY;
- break;
- case MODULE:
- *attributes = READ_ONLY;
- *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
- break;
- case DYNAMIC:
- case DYNAMIC_GLOBAL:
- case DYNAMIC_LOCAL:
- case TEMPORARY:
- UNREACHABLE();
- break;
- }
+ GetAttributesAndBindingFlags(mode, init_flag, attributes,
+ binding_flags);
return context;
}
« no previous file with comments | « src/contexts.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698