Index: src/hydrogen.cc |
=================================================================== |
--- src/hydrogen.cc (revision 8094) |
+++ src/hydrogen.cc (working copy) |
@@ -521,6 +521,12 @@ |
return GetConstant(&constant_false_, isolate()->heap()->false_value()); |
} |
+ |
+HConstant* HGraph::GetConstantHole() { |
+ return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value()); |
+} |
+ |
+ |
HGraphBuilder::HGraphBuilder(CompilationInfo* info, |
TypeFeedbackOracle* oracle) |
: function_state_(NULL), |
@@ -826,6 +832,10 @@ |
phi_list_->Add(phi); |
// We don't support phi uses of arguments for now. |
if (phi->CheckFlag(HValue::kIsArguments)) return false; |
+ // Check for the hole value (from an uninitialized const). |
+ for (int k = 0; k < phi->OperandCount(); k++) { |
+ if (phi->OperandAt(k) == GetConstantHole()) return false; |
+ } |
} |
} |
return true; |
@@ -2225,7 +2235,7 @@ |
graph()->EliminateRedundantPhis(); |
if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); |
if (!graph()->CollectPhis()) { |
- Bailout("Phi-use of arguments object"); |
+ Bailout("Unsupported phi-use"); |
return NULL; |
} |
@@ -2301,6 +2311,9 @@ |
// We don't yet handle the function name for named function expressions. |
if (scope->function() != NULL) return Bailout("named function expression"); |
+ //TODO: ?? |
+ //if (scope->HasIllegalRedeclaration()) BAILOUT("illegal redeclaration"); |
Kevin Millikin (Chromium)
2011/05/30 10:50:34
This should not be necessary, I think we check it
fschneider
2011/05/30 11:15:40
Done.
|
+ |
HConstant* undefined_constant = new(zone()) HConstant( |
isolate()->factory()->undefined_value(), Representation::Tagged()); |
AddInstruction(undefined_constant); |
@@ -2996,7 +3009,12 @@ |
if (variable == NULL) { |
return Bailout("reference to rewritten variable"); |
} else if (variable->IsStackAllocated()) { |
- ast_context()->ReturnValue(environment()->Lookup(variable)); |
+ HValue* value = environment()->Lookup(variable); |
+ if (variable->mode() == Variable::CONST && |
+ value == graph()->GetConstantHole()) { |
+ return Bailout("unsupported reference to const variable"); |
Kevin Millikin (Chromium)
2011/05/30 10:50:34
Let's make this say something like "reference to u
fschneider
2011/05/30 11:15:40
Done.
|
+ } |
+ ast_context()->ReturnValue(value); |
} else if (variable->IsContextSlot()) { |
if (variable->mode() == Variable::CONST) { |
return Bailout("reference to const context slot"); |
@@ -3451,6 +3469,8 @@ |
BinaryOperation* operation = expr->binary_operation(); |
if (var != NULL) { |
+ if (var->mode() == Variable::CONST) return Bailout("unsupported const compound assignment"); |
Kevin Millikin (Chromium)
2011/05/30 10:50:34
Needs a line break before committing.
fschneider
2011/05/30 11:15:40
Done.
|
+ |
CHECK_ALIVE(VisitForValue(operation)); |
if (var->is_global()) { |
@@ -3557,6 +3577,16 @@ |
} |
if (var != NULL) { |
+ if (var->mode() == Variable::CONST) { |
+ if (expr->op() != Token::INIT_CONST) { |
+ return Bailout("unsupported const assignment"); |
Kevin Millikin (Chromium)
2011/05/30 10:50:34
Let's make the message something like "non-initial
fschneider
2011/05/30 11:15:40
Done.
|
+ } |
+ // We insert a use of the old value to detect unsupported uses of const |
+ // variables (e.g. initialization inside a loop). |
+ HValue* old_value = environment()->Lookup(var); |
+ AddInstruction(new HUseConst(old_value)); |
+ } |
+ |
if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
// Handle the assignment. |
@@ -4871,6 +4901,7 @@ |
HValue* after = NULL; // The result after incrementing or decrementing. |
if (var != NULL) { |
+ if (var->mode() == Variable::CONST) return Bailout("unsupported count operation"); |
Kevin Millikin (Chromium)
2011/05/30 10:50:34
Line break.
fschneider
2011/05/30 11:15:40
Done.
|
// Argument of the count operation is a variable, not a property. |
ASSERT(prop == NULL); |
CHECK_ALIVE(VisitForValue(target)); |
@@ -5335,17 +5366,20 @@ |
void HGraphBuilder::VisitDeclaration(Declaration* decl) { |
// We allow only declarations that do not require code generation. |
- // The following all require code generation: global variables and |
- // functions, variables with slot type LOOKUP, declarations with |
- // mode CONST, and functions. |
+ // The following all require code generation: global variables, |
+ // functions, and variables with slot type LOOKUP |
Variable* var = decl->proxy()->var(); |
Slot* slot = var->AsSlot(); |
if (var->is_global() || |
+ !var->IsStackAllocated() || |
(slot != NULL && slot->type() == Slot::LOOKUP) || |
- decl->mode() == Variable::CONST || |
decl->fun() != NULL) { |
return Bailout("unsupported declaration"); |
} |
+ |
+ if (decl->mode() == Variable::CONST) { |
+ environment()->Bind(var, graph()->GetConstantHole()); |
+ } |
} |