Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(621)

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 2227203002: [interpreter] Logically separate hole-checking and const assignment errors (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove unused var Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 7a0b9aced657ad162cb873a84bde5d99a4d17185..98fab3548d23b28442997fd98d02ecdf6de76df8 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -2001,30 +2001,16 @@ void BytecodeGenerator::BuildThrowIfNotHole(Handle<String> name) {
builder()->Bind(&no_reference_error);
}
-void BytecodeGenerator::BuildThrowReassignConstant(Handle<String> name) {
- // TODO(mythria): This will be replaced by a new bytecode that throws an
- // appropriate error depending on the whether the value is a hole or not.
- BytecodeLabel const_assign_error;
- builder()->JumpIfNotHole(&const_assign_error);
- BuildThrowReferenceError(name);
- builder()
- ->Bind(&const_assign_error)
- .CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
-}
-
void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
Token::Value op) {
- VariableMode mode = variable->mode();
- DCHECK(mode != CONST_LEGACY);
- if (mode == CONST && op != Token::INIT) {
- // Non-intializing assignments to constant is not allowed.
- BuildThrowReassignConstant(variable->name());
- } else if (mode == LET && op != Token::INIT) {
- // Perform an initialization check for let declared variables.
+ DCHECK(variable->mode() != CONST_LEGACY);
+ if (op != Token::INIT) {
+ // Perform an initialization check for let/const declared variables.
// E.g. let x = (x = 20); is not allowed.
BuildThrowIfHole(variable->name());
} else {
- DCHECK(variable->is_this() && mode == CONST && op == Token::INIT);
+ DCHECK(variable->is_this() && variable->mode() == CONST &&
+ op == Token::INIT);
// Perform an initialization check for 'this'. 'this' variable is the
// only variable able to trigger bind operations outside the TDZ
// via 'super' calls.
@@ -2039,9 +2025,9 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
RegisterAllocationScope assignment_register_scope(this);
BytecodeLabel end_label;
bool hole_check_required =
- (mode == LET && op != Token::INIT) ||
- (mode == CONST && op != Token::INIT) ||
- (mode == CONST && op == Token::INIT && variable->is_this());
+ variable->binding_needs_init() &&
+ ((IsLexicalVariableMode(mode) && op != Token::INIT) ||
+ (mode == CONST && op == Token::INIT && variable->is_this()));
switch (variable->location()) {
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL: {
@@ -2052,16 +2038,6 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
destination = Register(variable->index());
}
- if (mode == CONST_LEGACY && op != Token::INIT) {
- if (is_strict(language_mode())) {
- builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
- 0);
- }
- // Non-initializing assignments to legacy constants are ignored
- // in sloppy mode. Break here to avoid storing into variable.
- break;
- }
-
if (hole_check_required) {
// Load destination to check for hole.
Register value_temp = register_allocator()->NewRegister();
@@ -2072,6 +2048,17 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
BuildHoleCheckForVariableAssignment(variable, op);
builder()->LoadAccumulatorWithRegister(value_temp);
}
+
+ if ((mode == CONST || mode == CONST_LEGACY) && op != Token::INIT) {
+ if (mode == CONST || is_strict(language_mode())) {
+ builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
+ 0);
+ }
+ // Non-initializing assignments to legacy constants are ignored
+ // in sloppy mode. Break here to avoid storing into variable.
+ break;
+ }
+
builder()->StoreAccumulatorInRegister(destination);
break;
}
@@ -2108,16 +2095,6 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
builder()->LoadAccumulatorWithRegister(value_temp);
}
- if (mode == CONST_LEGACY && op != Token::INIT) {
- if (is_strict(language_mode())) {
- builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
- 0);
- }
- // Non-initializing assignments to legacy constants are ignored
- // in sloppy mode. Break here to avoid storing into variable.
- break;
- }
-
if (hole_check_required) {
// Load destination to check for hole.
Register value_temp = register_allocator()->NewRegister();
@@ -2129,6 +2106,16 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
builder()->LoadAccumulatorWithRegister(value_temp);
}
+ if ((mode == CONST || mode == CONST_LEGACY) && op != Token::INIT) {
+ if (mode == CONST || is_strict(language_mode())) {
+ builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
+ 0);
+ }
+ // Non-initializing assignments to legacy constants are ignored
+ // in sloppy mode. Break here to avoid storing into variable.
+ break;
+ }
+
builder()->StoreContextSlot(context_reg, variable->index());
break;
}
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | test/cctest/interpreter/bytecode_expectations/ConstVariable.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698