Commit de8e2be8 authored by dslomov's avatar dslomov Committed by Commit bot

Implement TDZ in StoreIC for top-level lexicals.

StoreIC::Store was missing a check present in LoadIC::Load.

R=rossberg@chromium.org
BUG=v8:3941
LOG=Y

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

Cr-Commit-Position: refs/heads/master@{#27182}
parent c13dda25
......@@ -5327,7 +5327,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
Handle<Context> script_context = ScriptContextTable::GetContext(
script_contexts, lookup.context_index);
Handle<Object> current_value =
FixedArray::get(script_context, lookup.context_index);
FixedArray::get(script_context, lookup.slot_index);
// If the values is not the hole, it will stay initialized,
// so no need to generate a check.
......@@ -6488,6 +6488,16 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
}
Handle<Context> script_context =
ScriptContextTable::GetContext(script_contexts, lookup.context_index);
Handle<Object> current_value =
FixedArray::get(script_context, lookup.slot_index);
// If the values is not the hole, it will stay initialized,
// so no need to generate a check.
if (*current_value == *isolate()->factory()->the_hole_value()) {
return Bailout(kReferenceToUninitializedVariable);
}
HStoreNamedField* instr = Add<HStoreNamedField>(
Add<HConstant>(script_context),
HObjectAccess::ForContextSlot(lookup.slot_index), value);
......
......@@ -1558,6 +1558,15 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
return TypeError("const_assign", object, name);
}
Handle<Object> previous_value =
FixedArray::get(script_context, lookup_result.slot_index);
if (*previous_value == *isolate()->factory()->the_hole_value()) {
// Do not install stubs and stay pre-monomorphic for
// uninitialized accesses.
return ReferenceError("not_defined", name);
}
if (FLAG_use_ic &&
StoreScriptContextFieldStub::Accepted(&lookup_result)) {
StoreScriptContextFieldStub stub(isolate(), &lookup_result);
......
......@@ -1183,3 +1183,87 @@ TEST(Regress425510) {
}
}
}
TEST(Regress3941) {
i::FLAG_harmony_scoping = true;
i::FLAG_allow_natives_syntax = true;
HandleScope handle_scope(CcTest::isolate());
{
SimpleContext context;
context.Check("function f() { x = 1; }", EXPECT_RESULT,
Undefined(CcTest::isolate()));
context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
}
{
// Train ICs.
SimpleContext context;
context.Check("function f() { x = 1; }", EXPECT_RESULT,
Undefined(CcTest::isolate()));
for (int i = 0; i < 4; i++) {
context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
}
context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
}
{
// Optimize.
SimpleContext context;
context.Check("function f() { x = 1; }", EXPECT_RESULT,
Undefined(CcTest::isolate()));
for (int i = 0; i < 4; i++) {
context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
}
context.Check("%OptimizeFunctionOnNextCall(f); f(); x", EXPECT_RESULT,
Number::New(CcTest::isolate(), 1));
context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
}
}
TEST(Regress3941_Reads) {
i::FLAG_harmony_scoping = true;
i::FLAG_allow_natives_syntax = true;
HandleScope handle_scope(CcTest::isolate());
{
SimpleContext context;
context.Check("function f() { return x; }", EXPECT_RESULT,
Undefined(CcTest::isolate()));
context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
}
{
// Train ICs.
SimpleContext context;
context.Check("function f() { return x; }", EXPECT_RESULT,
Undefined(CcTest::isolate()));
for (int i = 0; i < 4; i++) {
context.Check("f()", EXPECT_EXCEPTION);
}
context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
}
{
// Optimize.
SimpleContext context;
context.Check("function f() { return x; }", EXPECT_RESULT,
Undefined(CcTest::isolate()));
for (int i = 0; i < 4; i++) {
context.Check("f()", EXPECT_EXCEPTION);
}
context.Check("%OptimizeFunctionOnNextCall(f);", EXPECT_RESULT,
Undefined(CcTest::isolate()));
context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment