Chromium Code Reviews| 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()); |
| + } |
| } |