PrintF(")\n");
}
+ bool visited_global_context = false;
+
do {
if (FLAG_trace_contexts) {
PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
+ if (context->IsGlobalContext()) PrintF(" (global context)");
if (context->IsNativeContext()) PrintF(" (native context)");
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() ||
context->IsWithContext() ||
}
// 2. Check the context proper if it has slots.
- if (context->IsFunctionContext() || context->IsBlockContext()) {
+ if (context->IsFunctionContext() || context->IsBlockContext() ||
+ (FLAG_harmony_scoping && context->IsGlobalContext())) {
// Use serialized scope information of functions and blocks to search
// for the context index.
Handle<ScopeInfo> scope_info;
}
}
}
+
+
+TEST(CrossScriptDynamicLookup) {
+ i::FLAG_harmony_scoping = true;
+
+ HandleScope handle_scope(CcTest::isolate());
+
+ {
+ SimpleContext context;
+ Local<String> undefined_string = String::NewFromUtf8(
+ CcTest::isolate(), "undefined", String::kInternalizedString);
+ Local<String> number_string = String::NewFromUtf8(
+ CcTest::isolate(), "number", String::kInternalizedString);
+
+ context.Check(
+ "function f(o) { with(o) { return x; } }"
+ "function g(o) { with(o) { x = 15; } }"
+ "function h(o) { with(o) { return typeof x; } }",
+ EXPECT_RESULT, Undefined(CcTest::isolate()));
+ context.Check("h({})", EXPECT_RESULT, undefined_string);
+ context.Check(
+ "'use strict';"
+ "let x = 1;"
+ "f({})",
+ EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
+ context.Check(
+ "'use strict';"
+ "g({});"
+ "x",
+ EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+ context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+ context.Check("h({})", EXPECT_RESULT, number_string);
+ }
+}