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:
parent
3901244107
commit
65fb2cf129
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user