harmony-scoping: Correct dynamic lookups on a top level.

R=rossberg@chromium.org

Review URL: https://codereview.chromium.org/650663003

Cr-Commit-Position: refs/heads/master@{#24975}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24975 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
dslomov@chromium.org 2014-10-29 10:59:41 +00:00
parent 3901244107
commit 65fb2cf129
2 changed files with 53 additions and 1 deletions

View File

@ -122,13 +122,30 @@ 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));
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() ||
@ -163,7 +180,8 @@ Handle<Object> Context::Lookup(Handle<String> name,
}
// 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;

View File

@ -713,3 +713,37 @@ TEST(CrossScriptConflicts) {
}
}
}
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);
}
}