| 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 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2098 Visit(expr); | 2098 Visit(expr); |
| 2099 } | 2099 } |
| 2100 | 2100 |
| 2101 | 2101 |
| 2102 void HGraphBuilder::VisitForValue(Expression* expr) { | 2102 void HGraphBuilder::VisitForValue(Expression* expr) { |
| 2103 ValueContext for_value(this); | 2103 ValueContext for_value(this); |
| 2104 Visit(expr); | 2104 Visit(expr); |
| 2105 } | 2105 } |
| 2106 | 2106 |
| 2107 | 2107 |
| 2108 void HGraphBuilder::VisitForTypeofValue(Expression* expr) { |
| 2109 ValueContext for_value(this); |
| 2110 for_value.MarkAsTypeof(); |
| 2111 Visit(expr); |
| 2112 } |
| 2113 |
| 2114 |
| 2108 void HGraphBuilder::VisitForControl(Expression* expr, | 2115 void HGraphBuilder::VisitForControl(Expression* expr, |
| 2109 HBasicBlock* true_block, | 2116 HBasicBlock* true_block, |
| 2110 HBasicBlock* false_block) { | 2117 HBasicBlock* false_block) { |
| 2111 TestContext for_test(this, true_block, false_block); | 2118 TestContext for_test(this, true_block, false_block); |
| 2112 Visit(expr); | 2119 Visit(expr); |
| 2113 } | 2120 } |
| 2114 | 2121 |
| 2115 | 2122 |
| 2116 void HGraphBuilder::VisitArgument(Expression* expr) { | 2123 void HGraphBuilder::VisitArgument(Expression* expr) { |
| 2117 VISIT_FOR_VALUE(expr); | 2124 VISIT_FOR_VALUE(expr); |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2790 CHECK_BAILOUT; | 2797 CHECK_BAILOUT; |
| 2791 | 2798 |
| 2792 if (!ast_context()->IsTest()) { | 2799 if (!ast_context()->IsTest()) { |
| 2793 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); | 2800 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); |
| 2794 set_current_block(join); | 2801 set_current_block(join); |
| 2795 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 2802 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
| 2796 } | 2803 } |
| 2797 } | 2804 } |
| 2798 | 2805 |
| 2799 | 2806 |
| 2800 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, | 2807 bool HGraphBuilder::LookupGlobalPropertyCell(Variable* var, |
| 2801 LookupResult* lookup, | 2808 LookupResult* lookup, |
| 2802 bool is_store) { | 2809 bool is_store) { |
| 2803 if (var->is_this()) { | 2810 if (var->is_this()) { |
| 2804 BAILOUT("global this reference"); | 2811 Bailout("global this reference"); |
| 2812 return true; |
| 2805 } | 2813 } |
| 2806 if (!info()->has_global_object()) { | 2814 if (!info()->has_global_object()) { |
| 2807 BAILOUT("no global object to optimize VariableProxy"); | 2815 Bailout("no global object to optimize VariableProxy"); |
| 2816 return true; |
| 2808 } | 2817 } |
| 2809 Handle<GlobalObject> global(info()->global_object()); | 2818 Handle<GlobalObject> global(info()->global_object()); |
| 2810 global->Lookup(*var->name(), lookup); | 2819 global->Lookup(*var->name(), lookup); |
| 2811 if (!lookup->IsProperty()) { | 2820 if (!lookup->IsProperty()) return true; |
| 2812 BAILOUT("global variable cell not yet introduced"); | 2821 if (is_store && lookup->IsReadOnly()) { |
| 2822 Bailout("store to read-only global variable"); |
| 2823 return true; |
| 2813 } | 2824 } |
| 2814 if (lookup->type() != NORMAL) { | 2825 if (lookup->type() != NORMAL) return true; |
| 2815 BAILOUT("global variable has accessors"); | 2826 if (!lookup->IsProperty()) return true; |
| 2816 } | 2827 if (lookup->holder() != *global) return true; |
| 2817 if (is_store && lookup->IsReadOnly()) { | 2828 return false; |
| 2818 BAILOUT("read-only global variable"); | |
| 2819 } | |
| 2820 if (lookup->holder() != *global) { | |
| 2821 BAILOUT("global property on prototype of global object"); | |
| 2822 } | |
| 2823 } | 2829 } |
| 2824 | 2830 |
| 2825 | 2831 |
| 2826 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { | 2832 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { |
| 2827 ASSERT(var->IsContextSlot()); | 2833 ASSERT(var->IsContextSlot()); |
| 2828 HInstruction* context = new HContext; | 2834 HInstruction* context = new HContext; |
| 2829 AddInstruction(context); | 2835 AddInstruction(context); |
| 2830 int length = info()->scope()->ContextChainLength(var->scope()); | 2836 int length = info()->scope()->ContextChainLength(var->scope()); |
| 2831 while (length-- > 0) { | 2837 while (length-- > 0) { |
| 2832 context = new HOuterContext(context); | 2838 context = new HOuterContext(context); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2848 } else if (variable->IsContextSlot()) { | 2854 } else if (variable->IsContextSlot()) { |
| 2849 if (variable->mode() == Variable::CONST) { | 2855 if (variable->mode() == Variable::CONST) { |
| 2850 BAILOUT("reference to const context slot"); | 2856 BAILOUT("reference to const context slot"); |
| 2851 } | 2857 } |
| 2852 HValue* context = BuildContextChainWalk(variable); | 2858 HValue* context = BuildContextChainWalk(variable); |
| 2853 int index = variable->AsSlot()->index(); | 2859 int index = variable->AsSlot()->index(); |
| 2854 HLoadContextSlot* instr = new HLoadContextSlot(context, index); | 2860 HLoadContextSlot* instr = new HLoadContextSlot(context, index); |
| 2855 ast_context()->ReturnInstruction(instr, expr->id()); | 2861 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2856 } else if (variable->is_global()) { | 2862 } else if (variable->is_global()) { |
| 2857 LookupResult lookup; | 2863 LookupResult lookup; |
| 2858 LookupGlobalPropertyCell(variable, &lookup, false); | 2864 bool is_generic = LookupGlobalPropertyCell(variable, &lookup, false); |
| 2859 CHECK_BAILOUT; | 2865 CHECK_BAILOUT; |
| 2860 | |
| 2861 Handle<GlobalObject> global(info()->global_object()); | 2866 Handle<GlobalObject> global(info()->global_object()); |
| 2862 // TODO(3039103): Handle global property load through an IC call when access | 2867 HInstruction* instr = NULL; |
| 2863 // checks are enabled. | 2868 if (is_generic || global->IsAccessCheckNeeded()) { |
| 2864 if (global->IsAccessCheckNeeded()) { | 2869 HContext* context = new HContext; |
| 2865 BAILOUT("global object requires access check"); | 2870 AddInstruction(context); |
| 2871 HGlobalObject* global_object = new HGlobalObject(context); |
| 2872 AddInstruction(global_object); |
| 2873 instr = new HLoadGlobalGeneric(context, |
| 2874 global_object, |
| 2875 variable->name(), |
| 2876 ast_context()->IsTypeof()); |
| 2877 } else { |
| 2878 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 2879 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| 2880 instr = new HLoadGlobal(cell, check_hole); |
| 2866 } | 2881 } |
| 2867 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | |
| 2868 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | |
| 2869 HLoadGlobal* instr = new HLoadGlobal(cell, check_hole); | |
| 2870 ast_context()->ReturnInstruction(instr, expr->id()); | 2882 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2871 } else { | 2883 } else { |
| 2872 BAILOUT("reference to a variable which requires dynamic lookup"); | 2884 BAILOUT("reference to a variable which requires dynamic lookup"); |
| 2873 } | 2885 } |
| 2874 } | 2886 } |
| 2875 | 2887 |
| 2876 | 2888 |
| 2877 void HGraphBuilder::VisitLiteral(Literal* expr) { | 2889 void HGraphBuilder::VisitLiteral(Literal* expr) { |
| 2878 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); | 2890 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); |
| 2879 ast_context()->ReturnInstruction(instr, expr->id()); | 2891 ast_context()->ReturnInstruction(instr, expr->id()); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3217 | 3229 |
| 3218 | 3230 |
| 3219 // Because not every expression has a position and there is not common | 3231 // Because not every expression has a position and there is not common |
| 3220 // superclass of Assignment and CountOperation, we cannot just pass the | 3232 // superclass of Assignment and CountOperation, we cannot just pass the |
| 3221 // owning expression instead of position and ast_id separately. | 3233 // owning expression instead of position and ast_id separately. |
| 3222 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3234 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| 3223 HValue* value, | 3235 HValue* value, |
| 3224 int position, | 3236 int position, |
| 3225 int ast_id) { | 3237 int ast_id) { |
| 3226 LookupResult lookup; | 3238 LookupResult lookup; |
| 3227 LookupGlobalPropertyCell(var, &lookup, true); | 3239 bool is_generic = LookupGlobalPropertyCell(var, &lookup, true); |
| 3228 CHECK_BAILOUT; | 3240 CHECK_BAILOUT; |
| 3229 | 3241 |
| 3230 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 3242 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| 3231 Handle<GlobalObject> global(info()->global_object()); | 3243 Handle<GlobalObject> global(info()->global_object()); |
| 3232 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3244 if (!is_generic && !global->IsAccessCheckNeeded()) { |
| 3233 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); | 3245 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 3234 instr->set_position(position); | 3246 HStoreGlobal* instr = new HStoreGlobal(value, cell, check_hole); |
| 3235 AddInstruction(instr); | 3247 instr->set_position(position); |
| 3236 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3248 AddInstruction(instr); |
| 3249 if (instr->HasSideEffects()) AddSimulate(ast_id); |
| 3250 } else { |
| 3251 BAILOUT("unsupported store to global"); |
| 3252 } |
| 3237 } | 3253 } |
| 3238 | 3254 |
| 3239 | 3255 |
| 3240 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 3256 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 3241 Expression* target = expr->target(); | 3257 Expression* target = expr->target(); |
| 3242 VariableProxy* proxy = target->AsVariableProxy(); | 3258 VariableProxy* proxy = target->AsVariableProxy(); |
| 3243 Variable* var = proxy->AsVariable(); | 3259 Variable* var = proxy->AsVariable(); |
| 3244 Property* prop = target->AsProperty(); | 3260 Property* prop = target->AsProperty(); |
| 3245 ASSERT(var == NULL || prop == NULL); | 3261 ASSERT(var == NULL || prop == NULL); |
| 3246 | 3262 |
| (...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4527 break; | 4543 break; |
| 4528 case Token::SUB: | 4544 case Token::SUB: |
| 4529 instr = new HMul(graph_->GetConstantMinus1(), value); | 4545 instr = new HMul(graph_->GetConstantMinus1(), value); |
| 4530 break; | 4546 break; |
| 4531 default: | 4547 default: |
| 4532 UNREACHABLE(); | 4548 UNREACHABLE(); |
| 4533 break; | 4549 break; |
| 4534 } | 4550 } |
| 4535 ast_context()->ReturnInstruction(instr, expr->id()); | 4551 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4536 } else if (op == Token::TYPEOF) { | 4552 } else if (op == Token::TYPEOF) { |
| 4537 VISIT_FOR_VALUE(expr->expression()); | 4553 VisitForTypeofValue(expr->expression()); |
| 4554 if (HasStackOverflow()) return; |
| 4538 HValue* value = Pop(); | 4555 HValue* value = Pop(); |
| 4539 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); | 4556 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); |
| 4540 } else { | 4557 } else { |
| 4541 BAILOUT("Value: unsupported unary operation"); | 4558 BAILOUT("Value: unsupported unary operation"); |
| 4542 } | 4559 } |
| 4543 } | 4560 } |
| 4544 | 4561 |
| 4545 | 4562 |
| 4546 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { | 4563 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { |
| 4547 // IncrementOperation is never visited by the visitor. It only | 4564 // IncrementOperation is never visited by the visitor. It only |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4912 ast_context()->ReturnInstruction(instr, expr->id()); | 4929 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4913 return; | 4930 return; |
| 4914 } | 4931 } |
| 4915 | 4932 |
| 4916 // Check for the pattern: typeof <expression> == <string literal>. | 4933 // Check for the pattern: typeof <expression> == <string literal>. |
| 4917 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); | 4934 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); |
| 4918 Literal* right_literal = expr->right()->AsLiteral(); | 4935 Literal* right_literal = expr->right()->AsLiteral(); |
| 4919 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && | 4936 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && |
| 4920 left_unary != NULL && left_unary->op() == Token::TYPEOF && | 4937 left_unary != NULL && left_unary->op() == Token::TYPEOF && |
| 4921 right_literal != NULL && right_literal->handle()->IsString()) { | 4938 right_literal != NULL && right_literal->handle()->IsString()) { |
| 4922 VISIT_FOR_VALUE(left_unary->expression()); | 4939 VisitForTypeofValue(left_unary->expression()); |
| 4940 if (HasStackOverflow()) return; |
| 4923 HValue* left = Pop(); | 4941 HValue* left = Pop(); |
| 4924 HInstruction* instr = new HTypeofIs(left, | 4942 HInstruction* instr = new HTypeofIs(left, |
| 4925 Handle<String>::cast(right_literal->handle())); | 4943 Handle<String>::cast(right_literal->handle())); |
| 4926 instr->set_position(expr->position()); | 4944 instr->set_position(expr->position()); |
| 4927 ast_context()->ReturnInstruction(instr, expr->id()); | 4945 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4928 return; | 4946 return; |
| 4929 } | 4947 } |
| 4930 | 4948 |
| 4931 VISIT_FOR_VALUE(expr->left()); | 4949 VISIT_FOR_VALUE(expr->left()); |
| 4932 VISIT_FOR_VALUE(expr->right()); | 4950 VISIT_FOR_VALUE(expr->right()); |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5904 } | 5922 } |
| 5905 } | 5923 } |
| 5906 | 5924 |
| 5907 #ifdef DEBUG | 5925 #ifdef DEBUG |
| 5908 if (graph_ != NULL) graph_->Verify(); | 5926 if (graph_ != NULL) graph_->Verify(); |
| 5909 if (allocator_ != NULL) allocator_->Verify(); | 5927 if (allocator_ != NULL) allocator_->Verify(); |
| 5910 #endif | 5928 #endif |
| 5911 } | 5929 } |
| 5912 | 5930 |
| 5913 } } // namespace v8::internal | 5931 } } // namespace v8::internal |
| OLD | NEW |