Protect against uninitialized lexical variables at top-level.

R=rossberg@chromium.org
BUG=chromium:452510
LOG=Y

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

Cr-Commit-Position: refs/heads/master@{#26466}
This commit is contained in:
dslomov 2015-02-05 08:35:09 -08:00 committed by Commit bot
parent 015e7865a0
commit 8241147f46
3 changed files with 37 additions and 3 deletions

View File

@ -5382,6 +5382,14 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
&lookup)) {
Handle<Context> script_context = ScriptContextTable::GetContext(
script_contexts, lookup.context_index);
Handle<Object> current_value =
FixedArray::get(script_context, lookup.context_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);
}
HInstruction* result = New<HLoadNamedField>(
Add<HConstant>(script_context), nullptr,
HObjectAccess::ForContextSlot(lookup.slot_index));

View File

@ -725,13 +725,21 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
ScriptContextTable::LookupResult lookup_result;
if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
Handle<Object> result =
FixedArray::get(ScriptContextTable::GetContext(
script_contexts, lookup_result.context_index),
lookup_result.slot_index);
if (*result == *isolate()->factory()->the_hole_value()) {
// Do not install stubs and stay pre-monomorphic for
// uninitialized accesses.
return ReferenceError("not_defined", name);
}
if (use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) {
LoadScriptContextFieldStub stub(isolate(), &lookup_result);
PatchCache(name, stub.GetCode());
}
return FixedArray::get(ScriptContextTable::GetContext(
script_contexts, lookup_result.context_index),
lookup_result.slot_index);
return result;
}
}

View File

@ -1145,3 +1145,21 @@ TEST(CrossScriptAssignmentToConst) {
context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
}
}
TEST(Regress425510) {
i::FLAG_harmony_scoping = true;
i::FLAG_allow_natives_syntax = true;
HandleScope handle_scope(CcTest::isolate());
{
SimpleContext context;
context.Check("'use strict'; o; const o = 10", EXPECT_EXCEPTION);
for (int i = 0; i < 100; i++) {
context.Check("o.prototype", EXPECT_EXCEPTION);
}
}
}