Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index ef7e363658ca7692ad7bec6fb731166f56eda086..46632eaa914d1e9175a1904bfd987f1d27ba2ecd 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) { |
@@ -3452,18 +3458,16 @@ 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. |
+ // permitted. |
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(); |
- } |
+ ArgumentsAllowedFlag arguments_allowed = |
+ (rhs_var != NULL && rhs_var->IsStackAllocated()) |
+ ? ARGUMENTS_ALLOWED |
+ : ARGUMENTS_NOT_ALLOWED; |
+ CHECK_ALIVE(VisitForValue(expr->value(), arguments_allowed)); |
Kevin Millikin (Chromium)
2011/05/02 11:08:41
This is actually simpler, arguments is always allo
|
+ value = Pop(); |
Bind(var, value); |
ast_context()->ReturnValue(value); |