OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1936 | 1936 |
1937 | 1937 |
1938 void EffectContext::ReturnValue(HValue* value) { | 1938 void EffectContext::ReturnValue(HValue* value) { |
1939 // The value is simply ignored. | 1939 // The value is simply ignored. |
1940 } | 1940 } |
1941 | 1941 |
1942 | 1942 |
1943 void ValueContext::ReturnValue(HValue* value) { | 1943 void ValueContext::ReturnValue(HValue* value) { |
1944 // The value is tracked in the bailout environment, and communicated | 1944 // The value is tracked in the bailout environment, and communicated |
1945 // through the environment as the result of the expression. | 1945 // through the environment as the result of the expression. |
1946 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { | |
1947 owner()->Bailout("bad value context for arguments value"); | |
1948 } | |
1946 owner()->Push(value); | 1949 owner()->Push(value); |
1947 } | 1950 } |
1948 | 1951 |
1949 | 1952 |
1950 void TestContext::ReturnValue(HValue* value) { | 1953 void TestContext::ReturnValue(HValue* value) { |
1951 BuildBranch(value); | 1954 BuildBranch(value); |
1952 } | 1955 } |
1953 | 1956 |
1954 | 1957 |
1955 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 1958 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
1956 owner()->AddInstruction(instr); | 1959 owner()->AddInstruction(instr); |
1957 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); | 1960 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); |
1958 } | 1961 } |
1959 | 1962 |
1960 | 1963 |
1961 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 1964 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
1965 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | |
1966 owner()->Bailout("bad value context for arguments object value"); | |
1967 } | |
1962 owner()->AddInstruction(instr); | 1968 owner()->AddInstruction(instr); |
1963 owner()->Push(instr); | 1969 owner()->Push(instr); |
1964 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); | 1970 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); |
1965 } | 1971 } |
1966 | 1972 |
1967 | 1973 |
1968 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 1974 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
1969 HGraphBuilder* builder = owner(); | 1975 HGraphBuilder* builder = owner(); |
1970 builder->AddInstruction(instr); | 1976 builder->AddInstruction(instr); |
1971 // We expect a simulate after every expression with side effects, though | 1977 // We expect a simulate after every expression with side effects, though |
1972 // this one isn't actually needed (and wouldn't work if it were targeted). | 1978 // this one isn't actually needed (and wouldn't work if it were targeted). |
1973 if (instr->HasSideEffects()) { | 1979 if (instr->HasSideEffects()) { |
1974 builder->Push(instr); | 1980 builder->Push(instr); |
1975 builder->AddSimulate(ast_id); | 1981 builder->AddSimulate(ast_id); |
1976 builder->Pop(); | 1982 builder->Pop(); |
1977 } | 1983 } |
1978 BuildBranch(instr); | 1984 BuildBranch(instr); |
1979 } | 1985 } |
1980 | 1986 |
1981 | 1987 |
1982 void TestContext::BuildBranch(HValue* value) { | 1988 void TestContext::BuildBranch(HValue* value) { |
1983 // We expect the graph to be in edge-split form: there is no edge that | 1989 // We expect the graph to be in edge-split form: there is no edge that |
1984 // connects a branch node to a join node. We conservatively ensure that | 1990 // connects a branch node to a join node. We conservatively ensure that |
1985 // property by always adding an empty block on the outgoing edges of this | 1991 // property by always adding an empty block on the outgoing edges of this |
1986 // branch. | 1992 // branch. |
1987 HGraphBuilder* builder = owner(); | 1993 HGraphBuilder* builder = owner(); |
1994 if (value->CheckFlag(HValue::kIsArguments)) { | |
1995 builder->Bailout("arguments object value in a test context"); | |
1996 } | |
1988 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 1997 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
1989 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 1998 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
1990 HTest* test = new(zone()) HTest(value, empty_true, empty_false); | 1999 HTest* test = new(zone()) HTest(value, empty_true, empty_false); |
1991 builder->current_block()->Finish(test); | 2000 builder->current_block()->Finish(test); |
1992 | 2001 |
1993 empty_true->Goto(if_true(), false); | 2002 empty_true->Goto(if_true(), false); |
1994 empty_false->Goto(if_false(), false); | 2003 empty_false->Goto(if_false(), false); |
1995 builder->set_current_block(NULL); | 2004 builder->set_current_block(NULL); |
1996 } | 2005 } |
1997 | 2006 |
(...skipping 21 matching lines...) Expand all Loading... | |
2019 SetStackOverflow(); | 2028 SetStackOverflow(); |
2020 } | 2029 } |
2021 | 2030 |
2022 | 2031 |
2023 void HGraphBuilder::VisitForEffect(Expression* expr) { | 2032 void HGraphBuilder::VisitForEffect(Expression* expr) { |
2024 EffectContext for_effect(this); | 2033 EffectContext for_effect(this); |
2025 Visit(expr); | 2034 Visit(expr); |
2026 } | 2035 } |
2027 | 2036 |
2028 | 2037 |
2029 void HGraphBuilder::VisitForValue(Expression* expr) { | 2038 void HGraphBuilder::VisitForValue(Expression* expr, ArgumentsAllowedFlag flag) { |
2030 ValueContext for_value(this); | 2039 ValueContext for_value(this, flag); |
2031 Visit(expr); | 2040 Visit(expr); |
2032 } | 2041 } |
2033 | 2042 |
2034 | 2043 |
2035 void HGraphBuilder::VisitForTypeOf(Expression* expr) { | 2044 void HGraphBuilder::VisitForTypeOf(Expression* expr) { |
2036 ValueContext for_value(this); | 2045 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
2037 for_value.set_for_typeof(true); | 2046 for_value.set_for_typeof(true); |
2038 Visit(expr); | 2047 Visit(expr); |
2039 } | 2048 } |
2040 | 2049 |
2041 | 2050 |
2042 | 2051 |
2043 void HGraphBuilder::VisitForControl(Expression* expr, | 2052 void HGraphBuilder::VisitForControl(Expression* expr, |
2044 HBasicBlock* true_block, | 2053 HBasicBlock* true_block, |
2045 HBasicBlock* false_block) { | 2054 HBasicBlock* false_block) { |
2046 TestContext for_test(this, true_block, false_block); | 2055 TestContext for_test(this, true_block, false_block); |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2872 | 2881 |
2873 | 2882 |
2874 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 2883 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
2875 ASSERT(!HasStackOverflow()); | 2884 ASSERT(!HasStackOverflow()); |
2876 ASSERT(current_block() != NULL); | 2885 ASSERT(current_block() != NULL); |
2877 ASSERT(current_block()->HasPredecessor()); | 2886 ASSERT(current_block()->HasPredecessor()); |
2878 Variable* variable = expr->AsVariable(); | 2887 Variable* variable = expr->AsVariable(); |
2879 if (variable == NULL) { | 2888 if (variable == NULL) { |
2880 return Bailout("reference to rewritten variable"); | 2889 return Bailout("reference to rewritten variable"); |
2881 } else if (variable->IsStackAllocated()) { | 2890 } else if (variable->IsStackAllocated()) { |
2882 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { | |
2883 return Bailout("unsupported context for arguments object"); | |
2884 } | |
2885 ast_context()->ReturnValue(environment()->Lookup(variable)); | 2891 ast_context()->ReturnValue(environment()->Lookup(variable)); |
2886 } else if (variable->IsContextSlot()) { | 2892 } else if (variable->IsContextSlot()) { |
2887 if (variable->mode() == Variable::CONST) { | 2893 if (variable->mode() == Variable::CONST) { |
2888 return Bailout("reference to const context slot"); | 2894 return Bailout("reference to const context slot"); |
2889 } | 2895 } |
2890 HValue* context = BuildContextChainWalk(variable); | 2896 HValue* context = BuildContextChainWalk(variable); |
2891 int index = variable->AsSlot()->index(); | 2897 int index = variable->AsSlot()->index(); |
2892 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index); | 2898 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index); |
2893 ast_context()->ReturnInstruction(instr, expr->id()); | 2899 ast_context()->ReturnInstruction(instr, expr->id()); |
2894 } else if (variable->is_global()) { | 2900 } else if (variable->is_global()) { |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3445 HandleCompoundAssignment(expr); | 3451 HandleCompoundAssignment(expr); |
3446 return; | 3452 return; |
3447 } | 3453 } |
3448 | 3454 |
3449 if (var != NULL) { | 3455 if (var != NULL) { |
3450 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 3456 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
3451 | 3457 |
3452 // Handle the assignment. | 3458 // Handle the assignment. |
3453 if (var->IsStackAllocated()) { | 3459 if (var->IsStackAllocated()) { |
3454 HValue* value = NULL; | 3460 HValue* value = NULL; |
3455 // Handle stack-allocated variables on the right-hand side directly. | |
3456 // We do not allow the arguments object to occur in a context where it | 3461 // We do not allow the arguments object to occur in a context where it |
3457 // may escape, but assignments to stack-allocated locals are | 3462 // may escape, but assignments to stack-allocated locals are |
3458 // permitted. Handling such assignments here bypasses the check for | 3463 // permitted. |
3459 // the arguments object in VisitVariableProxy. | |
3460 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable(); | 3464 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable(); |
3461 if (rhs_var != NULL && rhs_var->IsStackAllocated()) { | 3465 ArgumentsAllowedFlag arguments_allowed = |
3462 value = environment()->Lookup(rhs_var); | 3466 (rhs_var != NULL && rhs_var->IsStackAllocated()) |
3463 } else { | 3467 ? ARGUMENTS_ALLOWED |
3464 CHECK_ALIVE(VisitForValue(expr->value())); | 3468 : ARGUMENTS_NOT_ALLOWED; |
3465 value = Pop(); | 3469 CHECK_ALIVE(VisitForValue(expr->value(), arguments_allowed)); |
Kevin Millikin (Chromium)
2011/05/02 11:08:41
This is actually simpler, arguments is always allo
| |
3466 } | 3470 value = Pop(); |
3467 Bind(var, value); | 3471 Bind(var, value); |
3468 ast_context()->ReturnValue(value); | 3472 ast_context()->ReturnValue(value); |
3469 | 3473 |
3470 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { | 3474 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { |
3471 CHECK_ALIVE(VisitForValue(expr->value())); | 3475 CHECK_ALIVE(VisitForValue(expr->value())); |
3472 HValue* context = BuildContextChainWalk(var); | 3476 HValue* context = BuildContextChainWalk(var); |
3473 int index = var->AsSlot()->index(); | 3477 int index = var->AsSlot()->index(); |
3474 HStoreContextSlot* instr = | 3478 HStoreContextSlot* instr = |
3475 new(zone()) HStoreContextSlot(context, index, Top()); | 3479 new(zone()) HStoreContextSlot(context, index, Top()); |
3476 AddInstruction(instr); | 3480 AddInstruction(instr); |
(...skipping 2600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6077 } | 6081 } |
6078 } | 6082 } |
6079 | 6083 |
6080 #ifdef DEBUG | 6084 #ifdef DEBUG |
6081 if (graph_ != NULL) graph_->Verify(); | 6085 if (graph_ != NULL) graph_->Verify(); |
6082 if (allocator_ != NULL) allocator_->Verify(); | 6086 if (allocator_ != NULL) allocator_->Verify(); |
6083 #endif | 6087 #endif |
6084 } | 6088 } |
6085 | 6089 |
6086 } } // namespace v8::internal | 6090 } } // namespace v8::internal |
OLD | NEW |