OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2823 return true; | 2823 return true; |
2824 } else if (FLAG_harmony_iteration && | 2824 } else if (FLAG_harmony_iteration && |
2825 CheckContextualKeyword(CStrVector("of"))) { | 2825 CheckContextualKeyword(CStrVector("of"))) { |
2826 *visit_mode = ForEachStatement::ITERATE; | 2826 *visit_mode = ForEachStatement::ITERATE; |
2827 return true; | 2827 return true; |
2828 } | 2828 } |
2829 return false; | 2829 return false; |
2830 } | 2830 } |
2831 | 2831 |
2832 | 2832 |
| 2833 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 2834 Expression* each, |
| 2835 Expression* subject, |
| 2836 Statement* body) { |
| 2837 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2838 |
| 2839 if (for_of != NULL) { |
| 2840 Factory* heap_factory = isolate()->factory(); |
| 2841 Handle<String> iterator_str = heap_factory->InternalizeOneByteString( |
| 2842 STATIC_ASCII_VECTOR(".iterator")); |
| 2843 Handle<String> result_str = heap_factory->InternalizeOneByteString( |
| 2844 STATIC_ASCII_VECTOR(".result")); |
| 2845 Variable* iterator = |
| 2846 top_scope_->DeclarationScope()->NewTemporary(iterator_str); |
| 2847 Variable* result = top_scope_->DeclarationScope()->NewTemporary(result_str); |
| 2848 |
| 2849 Expression* assign_iterator; |
| 2850 Expression* next_result; |
| 2851 Expression* result_done; |
| 2852 Expression* assign_each; |
| 2853 |
| 2854 // var iterator = iterable; |
| 2855 { |
| 2856 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2857 assign_iterator = factory()->NewAssignment( |
| 2858 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
| 2859 } |
| 2860 |
| 2861 // var result = iterator.next(); |
| 2862 { |
| 2863 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2864 Expression* next_literal = |
| 2865 factory()->NewLiteral(heap_factory->next_string()); |
| 2866 Expression* next_property = factory()->NewProperty( |
| 2867 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
| 2868 ZoneList<Expression*>* next_arguments = |
| 2869 new(zone()) ZoneList<Expression*>(0, zone()); |
| 2870 Expression* next_call = factory()->NewCall( |
| 2871 next_property, next_arguments, RelocInfo::kNoPosition); |
| 2872 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2873 next_result = factory()->NewAssignment( |
| 2874 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
| 2875 } |
| 2876 |
| 2877 // result.done |
| 2878 { |
| 2879 Expression* done_literal = |
| 2880 factory()->NewLiteral(heap_factory->done_string()); |
| 2881 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2882 result_done = factory()->NewProperty( |
| 2883 result_proxy, done_literal, RelocInfo::kNoPosition); |
| 2884 } |
| 2885 |
| 2886 // each = result.value |
| 2887 { |
| 2888 Expression* value_literal = |
| 2889 factory()->NewLiteral(heap_factory->value_string()); |
| 2890 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2891 Expression* result_value = factory()->NewProperty( |
| 2892 result_proxy, value_literal, RelocInfo::kNoPosition); |
| 2893 assign_each = factory()->NewAssignment( |
| 2894 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
| 2895 } |
| 2896 |
| 2897 for_of->Initialize(each, subject, body, |
| 2898 assign_iterator, next_result, result_done, assign_each); |
| 2899 } else { |
| 2900 stmt->Initialize(each, subject, body); |
| 2901 } |
| 2902 } |
| 2903 |
| 2904 |
2833 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2905 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
2834 // ForStatement :: | 2906 // ForStatement :: |
2835 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2907 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2836 | 2908 |
2837 Statement* init = NULL; | 2909 Statement* init = NULL; |
2838 | 2910 |
2839 // Create an in-between scope for let-bound iteration variables. | 2911 // Create an in-between scope for let-bound iteration variables. |
2840 Scope* saved_scope = top_scope_; | 2912 Scope* saved_scope = top_scope_; |
2841 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2913 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
2842 top_scope_ = for_scope; | 2914 top_scope_ = for_scope; |
(...skipping 14 matching lines...) Expand all Loading... |
2857 is_const ? Interface::NewConst() : Interface::NewValue(); | 2929 is_const ? Interface::NewConst() : Interface::NewValue(); |
2858 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2930 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2859 Target target(&this->target_stack_, loop); | 2931 Target target(&this->target_stack_, loop); |
2860 | 2932 |
2861 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2933 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2862 Expect(Token::RPAREN, CHECK_OK); | 2934 Expect(Token::RPAREN, CHECK_OK); |
2863 | 2935 |
2864 VariableProxy* each = | 2936 VariableProxy* each = |
2865 top_scope_->NewUnresolved(factory(), name, interface); | 2937 top_scope_->NewUnresolved(factory(), name, interface); |
2866 Statement* body = ParseStatement(NULL, CHECK_OK); | 2938 Statement* body = ParseStatement(NULL, CHECK_OK); |
2867 loop->Initialize(each, enumerable, body); | 2939 InitializeForEachStatement(loop, each, enumerable, body); |
2868 Block* result = factory()->NewBlock(NULL, 2, false); | 2940 Block* result = factory()->NewBlock(NULL, 2, false); |
2869 result->AddStatement(variable_statement, zone()); | 2941 result->AddStatement(variable_statement, zone()); |
2870 result->AddStatement(loop, zone()); | 2942 result->AddStatement(loop, zone()); |
2871 top_scope_ = saved_scope; | 2943 top_scope_ = saved_scope; |
2872 for_scope->set_end_position(scanner().location().end_pos); | 2944 for_scope->set_end_position(scanner().location().end_pos); |
2873 for_scope = for_scope->FinalizeBlockScope(); | 2945 for_scope = for_scope->FinalizeBlockScope(); |
2874 ASSERT(for_scope == NULL); | 2946 ASSERT(for_scope == NULL); |
2875 // Parsed for-in loop w/ variable/const declaration. | 2947 // Parsed for-in loop w/ variable/const declaration. |
2876 return result; | 2948 return result; |
2877 } else { | 2949 } else { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2921 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2993 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
2922 Statement* body = ParseStatement(NULL, CHECK_OK); | 2994 Statement* body = ParseStatement(NULL, CHECK_OK); |
2923 Block* body_block = factory()->NewBlock(NULL, 3, false); | 2995 Block* body_block = factory()->NewBlock(NULL, 3, false); |
2924 Assignment* assignment = factory()->NewAssignment( | 2996 Assignment* assignment = factory()->NewAssignment( |
2925 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2997 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
2926 Statement* assignment_statement = | 2998 Statement* assignment_statement = |
2927 factory()->NewExpressionStatement(assignment); | 2999 factory()->NewExpressionStatement(assignment); |
2928 body_block->AddStatement(variable_statement, zone()); | 3000 body_block->AddStatement(variable_statement, zone()); |
2929 body_block->AddStatement(assignment_statement, zone()); | 3001 body_block->AddStatement(assignment_statement, zone()); |
2930 body_block->AddStatement(body, zone()); | 3002 body_block->AddStatement(body, zone()); |
2931 loop->Initialize(temp_proxy, enumerable, body_block); | 3003 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
2932 top_scope_ = saved_scope; | 3004 top_scope_ = saved_scope; |
2933 for_scope->set_end_position(scanner().location().end_pos); | 3005 for_scope->set_end_position(scanner().location().end_pos); |
2934 for_scope = for_scope->FinalizeBlockScope(); | 3006 for_scope = for_scope->FinalizeBlockScope(); |
2935 body_block->set_scope(for_scope); | 3007 body_block->set_scope(for_scope); |
2936 // Parsed for-in loop w/ let declaration. | 3008 // Parsed for-in loop w/ let declaration. |
2937 return loop; | 3009 return loop; |
2938 | 3010 |
2939 } else { | 3011 } else { |
2940 init = variable_statement; | 3012 init = variable_statement; |
2941 } | 3013 } |
(...skipping 11 matching lines...) Expand all Loading... |
2953 isolate()->factory()->invalid_lhs_in_for_in_string(); | 3025 isolate()->factory()->invalid_lhs_in_for_in_string(); |
2954 expression = NewThrowReferenceError(type); | 3026 expression = NewThrowReferenceError(type); |
2955 } | 3027 } |
2956 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 3028 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2957 Target target(&this->target_stack_, loop); | 3029 Target target(&this->target_stack_, loop); |
2958 | 3030 |
2959 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3031 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2960 Expect(Token::RPAREN, CHECK_OK); | 3032 Expect(Token::RPAREN, CHECK_OK); |
2961 | 3033 |
2962 Statement* body = ParseStatement(NULL, CHECK_OK); | 3034 Statement* body = ParseStatement(NULL, CHECK_OK); |
2963 loop->Initialize(expression, enumerable, body); | 3035 InitializeForEachStatement(loop, expression, enumerable, body); |
2964 top_scope_ = saved_scope; | 3036 top_scope_ = saved_scope; |
2965 for_scope->set_end_position(scanner().location().end_pos); | 3037 for_scope->set_end_position(scanner().location().end_pos); |
2966 for_scope = for_scope->FinalizeBlockScope(); | 3038 for_scope = for_scope->FinalizeBlockScope(); |
2967 ASSERT(for_scope == NULL); | 3039 ASSERT(for_scope == NULL); |
2968 // Parsed for-in loop. | 3040 // Parsed for-in loop. |
2969 return loop; | 3041 return loop; |
2970 | 3042 |
2971 } else { | 3043 } else { |
2972 init = factory()->NewExpressionStatement(expression); | 3044 init = factory()->NewExpressionStatement(expression); |
2973 } | 3045 } |
(...skipping 3078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6052 ASSERT(info()->isolate()->has_pending_exception()); | 6124 ASSERT(info()->isolate()->has_pending_exception()); |
6053 } else { | 6125 } else { |
6054 result = ParseProgram(); | 6126 result = ParseProgram(); |
6055 } | 6127 } |
6056 } | 6128 } |
6057 info()->SetFunction(result); | 6129 info()->SetFunction(result); |
6058 return (result != NULL); | 6130 return (result != NULL); |
6059 } | 6131 } |
6060 | 6132 |
6061 } } // namespace v8::internal | 6133 } } // namespace v8::internal |
OLD | NEW |