Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index ef7e363658ca7692ad7bec6fb731166f56eda086..67ff14d931480583d226fbbad2798a8b3b423862 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -1943,6 +1943,9 @@ void EffectContext::ReturnValue(HValue* value) { |
void ValueContext::ReturnValue(HValue* value) { |
// The value is tracked in the bailout environment, and communicated |
// through the environment as the result of the expression. |
+ if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { |
+ owner()->Bailout("bad value context for arguments value"); |
+ } |
owner()->Push(value); |
} |
@@ -1959,6 +1962,9 @@ void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
+ if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
+ owner()->Bailout("bad value context for arguments object value"); |
+ } |
owner()->AddInstruction(instr); |
owner()->Push(instr); |
if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); |
@@ -1985,6 +1991,9 @@ void TestContext::BuildBranch(HValue* value) { |
// property by always adding an empty block on the outgoing edges of this |
// branch. |
HGraphBuilder* builder = owner(); |
+ if (value->CheckFlag(HValue::kIsArguments)) { |
+ builder->Bailout("arguments object value in a test context"); |
+ } |
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
HTest* test = new(zone()) HTest(value, empty_true, empty_false); |
@@ -2026,14 +2035,14 @@ void HGraphBuilder::VisitForEffect(Expression* expr) { |
} |
-void HGraphBuilder::VisitForValue(Expression* expr) { |
- ValueContext for_value(this); |
+void HGraphBuilder::VisitForValue(Expression* expr, ArgumentsAllowedFlag flag) { |
+ ValueContext for_value(this, flag); |
Visit(expr); |
} |
void HGraphBuilder::VisitForTypeOf(Expression* expr) { |
- ValueContext for_value(this); |
+ ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
for_value.set_for_typeof(true); |
Visit(expr); |
} |
@@ -2879,9 +2888,6 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
if (variable == NULL) { |
return Bailout("reference to rewritten variable"); |
} else if (variable->IsStackAllocated()) { |
- if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { |
- return Bailout("unsupported context for arguments object"); |
- } |
ast_context()->ReturnValue(environment()->Lookup(variable)); |
} else if (variable->IsContextSlot()) { |
if (variable->mode() == Variable::CONST) { |
@@ -3451,19 +3457,11 @@ void HGraphBuilder::VisitAssignment(Assignment* expr) { |
// Handle the assignment. |
if (var->IsStackAllocated()) { |
- HValue* value = NULL; |
- // Handle stack-allocated variables on the right-hand side directly. |
// We do not allow the arguments object to occur in a context where it |
// may escape, but assignments to stack-allocated locals are |
- // permitted. Handling such assignments here bypasses the check for |
- // the arguments object in VisitVariableProxy. |
- Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable(); |
- if (rhs_var != NULL && rhs_var->IsStackAllocated()) { |
- value = environment()->Lookup(rhs_var); |
- } else { |
- CHECK_ALIVE(VisitForValue(expr->value())); |
- value = Pop(); |
- } |
+ // permitted. |
+ CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
+ HValue* value = Pop(); |
Bind(var, value); |
ast_context()->ReturnValue(value); |