| 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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3444 if (expr->is_compound()) { | 3450 if (expr->is_compound()) { |
| 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; | |
| 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 | 3460 // We do not allow the arguments object to occur in a context where it |
| 3457 // may escape, but assignments to stack-allocated locals are | 3461 // may escape, but assignments to stack-allocated locals are |
| 3458 // permitted. Handling such assignments here bypasses the check for | 3462 // permitted. |
| 3459 // the arguments object in VisitVariableProxy. | 3463 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
| 3460 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable(); | 3464 HValue* value = Pop(); |
| 3461 if (rhs_var != NULL && rhs_var->IsStackAllocated()) { | |
| 3462 value = environment()->Lookup(rhs_var); | |
| 3463 } else { | |
| 3464 CHECK_ALIVE(VisitForValue(expr->value())); | |
| 3465 value = Pop(); | |
| 3466 } | |
| 3467 Bind(var, value); | 3465 Bind(var, value); |
| 3468 ast_context()->ReturnValue(value); | 3466 ast_context()->ReturnValue(value); |
| 3469 | 3467 |
| 3470 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { | 3468 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { |
| 3471 CHECK_ALIVE(VisitForValue(expr->value())); | 3469 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3472 HValue* context = BuildContextChainWalk(var); | 3470 HValue* context = BuildContextChainWalk(var); |
| 3473 int index = var->AsSlot()->index(); | 3471 int index = var->AsSlot()->index(); |
| 3474 HStoreContextSlot* instr = | 3472 HStoreContextSlot* instr = |
| 3475 new(zone()) HStoreContextSlot(context, index, Top()); | 3473 new(zone()) HStoreContextSlot(context, index, Top()); |
| 3476 AddInstruction(instr); | 3474 AddInstruction(instr); |
| (...skipping 2600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6077 } | 6075 } |
| 6078 } | 6076 } |
| 6079 | 6077 |
| 6080 #ifdef DEBUG | 6078 #ifdef DEBUG |
| 6081 if (graph_ != NULL) graph_->Verify(); | 6079 if (graph_ != NULL) graph_->Verify(); |
| 6082 if (allocator_ != NULL) allocator_->Verify(); | 6080 if (allocator_ != NULL) allocator_->Verify(); |
| 6083 #endif | 6081 #endif |
| 6084 } | 6082 } |
| 6085 | 6083 |
| 6086 } } // namespace v8::internal | 6084 } } // namespace v8::internal |
| OLD | NEW |