Index: src/full-codegen/arm/full-codegen-arm.cc |
diff --git a/src/full-codegen/arm/full-codegen-arm.cc b/src/full-codegen/arm/full-codegen-arm.cc |
index 598d8e9f6e2af813515a1d6a70591757c6d32318..41f61587ac801f09397380204e0720fbfae60fe8 100644 |
--- a/src/full-codegen/arm/full-codegen-arm.cc |
+++ b/src/full-codegen/arm/full-codegen-arm.cc |
@@ -1454,67 +1454,26 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); |
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
: "[ Stack variable"); |
- if (var->binding_needs_init()) { |
- // var->scope() may be NULL when the proxy is located in eval code and |
- // refers to a potential outside binding. Currently those bindings are |
- // always looked up dynamically, i.e. in that case |
- // var->location() == LOOKUP. |
- // always holds. |
- DCHECK(var->scope() != NULL); |
- |
- // Check if the binding really needs an initialization check. The check |
- // can be skipped in the following situation: we have a LET or CONST |
- // binding in harmony mode, both the Variable and the VariableProxy have |
- // the same declaration scope (i.e. they are both in global code, in the |
- // same function or in the same eval code) and the VariableProxy is in |
- // the source physically located after the initializer of the variable. |
- // |
- // We cannot skip any initialization checks for CONST in non-harmony |
- // mode because const variables may be declared but never initialized: |
- // if (false) { const x; }; var y = x; |
- // |
- // The condition on the declaration scopes is a conservative check for |
- // nested functions that access a binding and are called before the |
- // binding is initialized: |
- // function() { f(); let x = 1; function f() { x = 2; } } |
- // |
- bool skip_init_check; |
- if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { |
- skip_init_check = false; |
- } else if (var->is_this()) { |
- CHECK(info_->has_literal() && |
- (info_->literal()->kind() & kSubclassConstructor) != 0); |
- // TODO(dslomov): implement 'this' hole check elimination. |
- skip_init_check = false; |
+ if (NeedsHoleCheckForLoad(proxy)) { |
+ // Let and const need a read barrier. |
+ GetVar(r0, var); |
+ __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
+ if (var->mode() == LET || var->mode() == CONST) { |
+ // Throw a reference error when using an uninitialized let/const |
+ // binding in harmony mode. |
+ Label done; |
+ __ b(ne, &done); |
+ __ mov(r0, Operand(var->name())); |
+ __ push(r0); |
+ __ CallRuntime(Runtime::kThrowReferenceError, 1); |
+ __ bind(&done); |
} else { |
- // Check that we always have valid source position. |
- DCHECK(var->initializer_position() != RelocInfo::kNoPosition); |
- DCHECK(proxy->position() != RelocInfo::kNoPosition); |
- skip_init_check = var->mode() != CONST_LEGACY && |
- var->initializer_position() < proxy->position(); |
- } |
- |
- if (!skip_init_check) { |
- // Let and const need a read barrier. |
- GetVar(r0, var); |
- __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
- if (var->mode() == LET || var->mode() == CONST) { |
- // Throw a reference error when using an uninitialized let/const |
- // binding in harmony mode. |
- Label done; |
- __ b(ne, &done); |
- __ mov(r0, Operand(var->name())); |
- __ push(r0); |
- __ CallRuntime(Runtime::kThrowReferenceError, 1); |
- __ bind(&done); |
- } else { |
- // Uninitalized const bindings outside of harmony mode are unholed. |
- DCHECK(var->mode() == CONST_LEGACY); |
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
- } |
- context()->Plug(r0); |
- break; |
+ // Uninitialized legacy const bindings are unholed. |
+ DCHECK(var->mode() == CONST_LEGACY); |
+ __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
} |
+ context()->Plug(r0); |
+ break; |
} |
context()->Plug(var); |
break; |