| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" | 
| 6 | 6 | 
| 7 #include "src/api.h" | 7 #include "src/api.h" | 
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" | 
| 9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" | 
| 10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" | 
| (...skipping 5779 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5790   } else { | 5790   } else { | 
| 5791     DCHECK(value->IsClassLiteral()); | 5791     DCHECK(value->IsClassLiteral()); | 
| 5792     auto class_literal = value->AsClassLiteral(); | 5792     auto class_literal = value->AsClassLiteral(); | 
| 5793     if (class_literal->raw_name() == nullptr) { | 5793     if (class_literal->raw_name() == nullptr) { | 
| 5794       class_literal->set_raw_name(name); | 5794       class_literal->set_raw_name(name); | 
| 5795     } | 5795     } | 
| 5796   } | 5796   } | 
| 5797 } | 5797 } | 
| 5798 | 5798 | 
| 5799 | 5799 | 
|  | 5800 // Desugaring of yield* | 
|  | 5801 // ==================== | 
|  | 5802 // | 
|  | 5803 // With the help of do-expressions and function.sent, we desugar yield* into a | 
|  | 5804 // loop containing a "raw" yield (a yield that doesn't wrap an iterator result | 
|  | 5805 // object around its argument).  Concretely, "yield* iterable" turns into | 
|  | 5806 // roughly the following code: | 
|  | 5807 // | 
|  | 5808 //   do { | 
|  | 5809 //     const kNext = 0; | 
|  | 5810 //     const kReturn = 1; | 
|  | 5811 //     const kThrow = 2; | 
|  | 5812 // | 
|  | 5813 //     let input = function.sent; | 
|  | 5814 //     let mode = kNext; | 
|  | 5815 //     let output = undefined; | 
|  | 5816 // | 
|  | 5817 //     let iterator = iterable[Symbol.iterator](); | 
|  | 5818 //     if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid); | 
|  | 5819 // | 
|  | 5820 //     while (true) { | 
|  | 5821 //       // From the generator to the iterator: | 
|  | 5822 //       // Forward input according to resume mode and obtain output. | 
|  | 5823 //       switch (mode) { | 
|  | 5824 //         case kNext: | 
|  | 5825 //           output = iterator.next(input); | 
|  | 5826 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
|  | 5827 //           break; | 
|  | 5828 //         case kReturn: | 
|  | 5829 //           IteratorClose(iterator, input);  // See below. | 
|  | 5830 //           break; | 
|  | 5831 //         case kThrow: | 
|  | 5832 //           let iteratorThrow = iterator.throw; | 
|  | 5833 //           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) { | 
|  | 5834 //             IteratorClose(iterator);  // See below. | 
|  | 5835 //             throw MakeTypeError(kThrowMethodMissing); | 
|  | 5836 //           } | 
|  | 5837 //           output = %_Call(iteratorThrow, iterator, input); | 
|  | 5838 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
|  | 5839 //           break; | 
|  | 5840 //       } | 
|  | 5841 //       if (output.done) break; | 
|  | 5842 // | 
|  | 5843 //       // From the generator to its user: | 
|  | 5844 //       // Forward output, receive new input, and determine resume mode. | 
|  | 5845 //       mode = kReturn; | 
|  | 5846 //       try { | 
|  | 5847 //         try { | 
|  | 5848 //           RawYield(output);  // See explanation above. | 
|  | 5849 //           mode = kNext; | 
|  | 5850 //         } catch (error) { | 
|  | 5851 //           mode = kThrow; | 
|  | 5852 //         } | 
|  | 5853 //       } finally { | 
|  | 5854 //         input = function.sent; | 
|  | 5855 //         continue; | 
|  | 5856 //       } | 
|  | 5857 //     } | 
|  | 5858 // | 
|  | 5859 //     output.value; | 
|  | 5860 //   } | 
|  | 5861 // | 
|  | 5862 // IteratorClose(iterator) expands to the following: | 
|  | 5863 // | 
|  | 5864 //   let iteratorReturn = iterator.return; | 
|  | 5865 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return; | 
|  | 5866 //   let result = %_Call(iteratorReturn, iterator); | 
|  | 5867 //   if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result); | 
|  | 5868 // | 
|  | 5869 // IteratorClose(iterator, input) expands to the following: | 
|  | 5870 // | 
|  | 5871 //   let iteratorReturn = iterator.return; | 
|  | 5872 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; | 
|  | 5873 //   let result = %_Call(iteratorReturn, iterator, input); | 
|  | 5874 //   if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result); | 
|  | 5875 | 
|  | 5876 | 
|  | 5877 Expression* ParserTraits::RewriteYieldStar( | 
|  | 5878     Expression* generator, Expression* iterable, int pos) { | 
|  | 5879 | 
|  | 5880   const int nopos = RelocInfo::kNoPosition; | 
|  | 5881 | 
|  | 5882   auto factory = parser_->factory(); | 
|  | 5883   auto avfactory = parser_->ast_value_factory(); | 
|  | 5884   auto scope = parser_->scope_; | 
|  | 5885   auto zone = parser_->zone(); | 
|  | 5886 | 
|  | 5887   Statement* skip = factory->NewEmptyStatement(nopos); | 
|  | 5888 | 
|  | 5889   enum { kNext, kReturn, kThrow }; | 
|  | 5890   // TODO(neis): Use JSGenerator::ResumeMode once extended with RETURN. | 
|  | 5891 | 
|  | 5892   // Forward definition for break/continue statements. | 
|  | 5893   WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos); | 
|  | 5894 | 
|  | 5895 | 
|  | 5896   // let input = undefined; | 
|  | 5897   Variable* var_input = scope->NewTemporary(avfactory->empty_string()); | 
|  | 5898   Statement* initialize_input; | 
|  | 5899   { | 
|  | 5900     Expression* input_proxy = factory->NewVariableProxy(var_input); | 
|  | 5901     Expression* assignment = factory->NewAssignment( | 
|  | 5902         Token::ASSIGN, input_proxy, factory->NewUndefinedLiteral(nopos), nopos); | 
|  | 5903     initialize_input = factory->NewExpressionStatement(assignment, nopos); | 
|  | 5904   } | 
|  | 5905 | 
|  | 5906 | 
|  | 5907   // let mode = kNext; | 
|  | 5908   Variable* var_mode = scope->NewTemporary(avfactory->empty_string()); | 
|  | 5909   Statement* initialize_mode; | 
|  | 5910   { | 
|  | 5911     Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 
|  | 5912     Expression* knext = factory->NewSmiLiteral(kNext, nopos); | 
|  | 5913     Expression* assignment = | 
|  | 5914         factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos); | 
|  | 5915     initialize_mode = factory->NewExpressionStatement(assignment, nopos); | 
|  | 5916   } | 
|  | 5917 | 
|  | 5918 | 
|  | 5919   // let output = undefined; | 
|  | 5920   Variable* var_output = scope->NewTemporary(avfactory->empty_string()); | 
|  | 5921   Statement* initialize_output; | 
|  | 5922   { | 
|  | 5923     Expression* output_proxy = factory->NewVariableProxy(var_output); | 
|  | 5924     Expression* assignment = factory->NewAssignment( | 
|  | 5925         Token::ASSIGN, output_proxy, factory->NewUndefinedLiteral(nopos), | 
|  | 5926         nopos); | 
|  | 5927     initialize_output = factory->NewExpressionStatement(assignment, nopos); | 
|  | 5928   } | 
|  | 5929 | 
|  | 5930 | 
|  | 5931   // let iterator = iterable[Symbol.iterator]; | 
|  | 5932   Variable* var_iterator = scope->NewTemporary(avfactory->empty_string()); | 
|  | 5933   Statement* get_iterator; | 
|  | 5934   { | 
|  | 5935     Expression* iterator = GetIterator(iterable, factory, nopos); | 
|  | 5936     Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); | 
|  | 5937     Expression* assignment = factory->NewAssignment( | 
|  | 5938         Token::ASSIGN, iterator_proxy, iterator, nopos); | 
|  | 5939     get_iterator = factory->NewExpressionStatement(assignment, nopos); | 
|  | 5940   } | 
|  | 5941 | 
|  | 5942 | 
|  | 5943   // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid); | 
|  | 5944   Statement* validate_iterator; | 
|  | 5945   { | 
|  | 5946     Expression* is_receiver_call; | 
|  | 5947     { | 
|  | 5948       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 5949       args->Add(factory->NewVariableProxy(var_iterator), zone); | 
|  | 5950       is_receiver_call = | 
|  | 5951           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 
|  | 5952     } | 
|  | 5953 | 
|  | 5954     Statement* throw_call; | 
|  | 5955     { | 
|  | 5956       Expression* call = NewThrowTypeError( | 
|  | 5957           MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(), | 
|  | 5958           nopos); | 
|  | 5959       throw_call = factory->NewExpressionStatement(call, nopos); | 
|  | 5960     } | 
|  | 5961 | 
|  | 5962     validate_iterator = | 
|  | 5963         factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 
|  | 5964   } | 
|  | 5965 | 
|  | 5966 | 
|  | 5967   // output = iterator.next(input); | 
|  | 5968   Statement* call_next; | 
|  | 5969   { | 
|  | 5970     Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); | 
|  | 5971     Expression* literal = | 
|  | 5972         factory->NewStringLiteral(avfactory->next_string(), nopos); | 
|  | 5973     Expression* next_property = | 
|  | 5974         factory->NewProperty(iterator_proxy, literal, nopos); | 
|  | 5975     Expression* input_proxy = factory->NewVariableProxy(var_input); | 
|  | 5976     auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 5977     args->Add(input_proxy, zone); | 
|  | 5978     Expression* call = factory->NewCall(next_property, args, nopos); | 
|  | 5979     Expression* output_proxy = factory->NewVariableProxy(var_output); | 
|  | 5980     Expression* assignment = | 
|  | 5981         factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 
|  | 5982     call_next = factory->NewExpressionStatement(assignment, nopos); | 
|  | 5983   } | 
|  | 5984 | 
|  | 5985 | 
|  | 5986   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
|  | 5987   Statement* validate_next_output; | 
|  | 5988   { | 
|  | 5989     Expression* is_receiver_call; | 
|  | 5990     { | 
|  | 5991       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 5992       args->Add(factory->NewVariableProxy(var_output), zone); | 
|  | 5993       is_receiver_call = | 
|  | 5994           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 
|  | 5995     } | 
|  | 5996 | 
|  | 5997     Statement* throw_call; | 
|  | 5998     { | 
|  | 5999       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 6000       args->Add(factory->NewVariableProxy(var_output), zone); | 
|  | 6001       Expression* call = factory->NewCallRuntime( | 
|  | 6002           Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 
|  | 6003       throw_call = factory->NewExpressionStatement(call, nopos); | 
|  | 6004     } | 
|  | 6005 | 
|  | 6006     validate_next_output = | 
|  | 6007         factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 
|  | 6008   } | 
|  | 6009 | 
|  | 6010 | 
|  | 6011   // let iteratorThrow = iterator.throw; | 
|  | 6012   Variable* var_throw = scope->NewTemporary(avfactory->empty_string()); | 
|  | 6013   Statement* get_throw; | 
|  | 6014   { | 
|  | 6015     Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); | 
|  | 6016     Expression* literal = | 
|  | 6017         factory->NewStringLiteral(avfactory->throw_string(), nopos); | 
|  | 6018     Expression* property = | 
|  | 6019         factory->NewProperty(iterator_proxy, literal, nopos); | 
|  | 6020     Expression* throw_proxy = factory->NewVariableProxy(var_throw); | 
|  | 6021     Expression* assignment = factory->NewAssignment( | 
|  | 6022         Token::ASSIGN, throw_proxy, property, nopos); | 
|  | 6023     get_throw = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6024   } | 
|  | 6025 | 
|  | 6026 | 
|  | 6027   // if (IS_NULL_OR_UNDEFINED(iteratorThrow) { | 
|  | 6028   //   IteratorClose(iterator); | 
|  | 6029   //   throw MakeTypeError(kThrowMethodMissing); | 
|  | 6030   // } | 
|  | 6031   Statement* check_throw; | 
|  | 6032   { | 
|  | 6033     Expression* condition = factory->NewCompareOperation( | 
|  | 6034         Token::EQ, factory->NewVariableProxy(var_throw), | 
|  | 6035         factory->NewNullLiteral(nopos), nopos); | 
|  | 6036 | 
|  | 6037     Expression* call = NewThrowTypeError( | 
|  | 6038         MessageTemplate::kThrowMethodMissing, | 
|  | 6039         avfactory->empty_string(), nopos); | 
|  | 6040     Statement* throw_call = factory->NewExpressionStatement(call, nopos); | 
|  | 6041 | 
|  | 6042     Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); | 
|  | 6043     BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>()); | 
|  | 6044     then->statements()->Add(throw_call, zone); | 
|  | 6045     check_throw = | 
|  | 6046         factory->NewIfStatement(condition, then, skip, nopos); | 
|  | 6047   } | 
|  | 6048 | 
|  | 6049 | 
|  | 6050   // output = %_Call(iteratorThrow, iterator, input); | 
|  | 6051   Statement* call_throw; | 
|  | 6052   { | 
|  | 6053     auto args = new (zone) ZoneList<Expression*>(3, zone); | 
|  | 6054     args->Add(factory->NewVariableProxy(var_throw), zone); | 
|  | 6055     args->Add(factory->NewVariableProxy(var_iterator), zone); | 
|  | 6056     args->Add(factory->NewVariableProxy(var_input), zone); | 
|  | 6057     Expression* call = | 
|  | 6058         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 
|  | 6059     Expression* assignment = factory->NewAssignment( | 
|  | 6060         Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos); | 
|  | 6061     call_throw = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6062   } | 
|  | 6063 | 
|  | 6064 | 
|  | 6065   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
|  | 6066   Statement* validate_throw_output; | 
|  | 6067   { | 
|  | 6068     Expression* is_receiver_call; | 
|  | 6069     { | 
|  | 6070       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 6071       args->Add(factory->NewVariableProxy(var_output), zone); | 
|  | 6072       is_receiver_call = | 
|  | 6073           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 
|  | 6074     } | 
|  | 6075 | 
|  | 6076     Statement* throw_call; | 
|  | 6077     { | 
|  | 6078       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 6079       args->Add(factory->NewVariableProxy(var_output), zone); | 
|  | 6080       Expression* call = factory->NewCallRuntime( | 
|  | 6081           Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 
|  | 6082       throw_call = factory->NewExpressionStatement(call, nopos); | 
|  | 6083     } | 
|  | 6084 | 
|  | 6085     validate_throw_output = | 
|  | 6086         factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 
|  | 6087   } | 
|  | 6088 | 
|  | 6089 | 
|  | 6090   // if (output.done) break; | 
|  | 6091   Statement* if_done; | 
|  | 6092   { | 
|  | 6093     Expression* output_proxy = factory->NewVariableProxy(var_output); | 
|  | 6094     Expression* literal = | 
|  | 6095         factory->NewStringLiteral(avfactory->done_string(), nopos); | 
|  | 6096     Expression* property = factory->NewProperty(output_proxy, literal, nopos); | 
|  | 6097     BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos); | 
|  | 6098     if_done = factory->NewIfStatement(property, break_loop, skip, nopos); | 
|  | 6099   } | 
|  | 6100 | 
|  | 6101 | 
|  | 6102   // mode = kReturn; | 
|  | 6103   Statement* set_mode_return; | 
|  | 6104   { | 
|  | 6105     Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 
|  | 6106     Expression* kreturn = factory->NewSmiLiteral(kReturn, nopos); | 
|  | 6107     Expression* assignment = | 
|  | 6108         factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); | 
|  | 6109     set_mode_return = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6110   } | 
|  | 6111 | 
|  | 6112 | 
|  | 6113   // RawYield(output); | 
|  | 6114   Statement* yield_output; | 
|  | 6115   { | 
|  | 6116     Expression* output_proxy = factory->NewVariableProxy(var_output); | 
|  | 6117     Yield* yield = factory->NewYield( | 
|  | 6118         generator, output_proxy, Yield::kInitial, nopos); | 
|  | 6119     yield_output = factory->NewExpressionStatement(yield, nopos); | 
|  | 6120   } | 
|  | 6121 | 
|  | 6122 | 
|  | 6123   // mode = kNext; | 
|  | 6124   Statement* set_mode_next; | 
|  | 6125   { | 
|  | 6126     Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 
|  | 6127     Expression* knext = factory->NewSmiLiteral(kNext, nopos); | 
|  | 6128     Expression* assignment = | 
|  | 6129         factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos); | 
|  | 6130     set_mode_next = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6131   } | 
|  | 6132 | 
|  | 6133 | 
|  | 6134   // mode = kThrow; | 
|  | 6135   Statement* set_mode_throw; | 
|  | 6136   { | 
|  | 6137     Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 
|  | 6138     Expression* kthrow = factory->NewSmiLiteral(kThrow, nopos); | 
|  | 6139     Expression* assignment = | 
|  | 6140         factory->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos); | 
|  | 6141     set_mode_throw = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6142   } | 
|  | 6143 | 
|  | 6144 | 
|  | 6145   // input = function.sent; | 
|  | 6146   Statement* get_input; | 
|  | 6147   { | 
|  | 6148     Expression* function_sent = FunctionSentExpression(scope, factory, nopos); | 
|  | 6149     Expression* input_proxy = factory->NewVariableProxy(var_input); | 
|  | 6150     Expression* assignment = factory->NewAssignment( | 
|  | 6151         Token::ASSIGN, input_proxy, function_sent, nopos); | 
|  | 6152     get_input = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6153   } | 
|  | 6154 | 
|  | 6155 | 
|  | 6156   // output.value; | 
|  | 6157   Statement* get_value; | 
|  | 6158   { | 
|  | 6159     Expression* output_proxy = factory->NewVariableProxy(var_output); | 
|  | 6160     Expression* literal = | 
|  | 6161         factory->NewStringLiteral(avfactory->value_string(), nopos); | 
|  | 6162     Expression* property = factory->NewProperty(output_proxy, literal, nopos); | 
|  | 6163     get_value = factory->NewExpressionStatement(property, nopos); | 
|  | 6164   } | 
|  | 6165 | 
|  | 6166 | 
|  | 6167   // Now put things together. | 
|  | 6168 | 
|  | 6169 | 
|  | 6170   // try { ... } catch(e) { ... } | 
|  | 6171   Statement* try_catch; | 
|  | 6172   { | 
|  | 6173     Block* try_block = factory->NewBlock(nullptr, 2, false, nopos); | 
|  | 6174     try_block->statements()->Add(yield_output, zone); | 
|  | 6175     try_block->statements()->Add(set_mode_next, zone); | 
|  | 6176 | 
|  | 6177     Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos); | 
|  | 6178     catch_block->statements()->Add(set_mode_throw, zone); | 
|  | 6179 | 
|  | 6180     Scope* catch_scope = NewScope(scope, CATCH_SCOPE); | 
|  | 6181     const AstRawString* name = avfactory->dot_catch_string(); | 
|  | 6182     Variable* catch_variable = | 
|  | 6183         catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, | 
|  | 6184                                                Variable::NORMAL); | 
|  | 6185 | 
|  | 6186     try_catch = factory->NewTryCatchStatement( | 
|  | 6187         try_block, catch_scope, catch_variable, catch_block, nopos); | 
|  | 6188   } | 
|  | 6189 | 
|  | 6190 | 
|  | 6191   // try { ... } finally { ... } | 
|  | 6192   Statement* try_finally; | 
|  | 6193   { | 
|  | 6194     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | 
|  | 6195     try_block->statements()->Add(try_catch, zone); | 
|  | 6196 | 
|  | 6197     Block* finally = factory->NewBlock(nullptr, 2, false, nopos); | 
|  | 6198     finally->statements()->Add(get_input, zone); | 
|  | 6199     finally->statements()->Add( | 
|  | 6200         factory->NewContinueStatement(loop, nopos), zone); | 
|  | 6201 | 
|  | 6202     try_finally = factory->NewTryFinallyStatement(try_block, finally, nopos); | 
|  | 6203   } | 
|  | 6204 | 
|  | 6205 | 
|  | 6206   // switch (mode) { ... } | 
|  | 6207   SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); | 
|  | 6208   { | 
|  | 6209     auto case_next = new (zone) ZoneList<Statement*>(3, zone); | 
|  | 6210     case_next->Add(call_next, zone); | 
|  | 6211     case_next->Add(validate_next_output, zone); | 
|  | 6212     case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 
|  | 6213 | 
|  | 6214     auto case_return = new (zone) ZoneList<Statement*>(5, zone); | 
|  | 6215     BuildIteratorClose(case_return, var_iterator, Just(var_input)); | 
|  | 6216     case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 
|  | 6217 | 
|  | 6218     auto case_throw = new (zone) ZoneList<Statement*>(5, zone); | 
|  | 6219     case_throw->Add(get_throw, zone); | 
|  | 6220     case_throw->Add(check_throw, zone); | 
|  | 6221     case_throw->Add(call_throw, zone); | 
|  | 6222     case_throw->Add(validate_throw_output, zone); | 
|  | 6223     case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 
|  | 6224 | 
|  | 6225     auto cases = new (zone) ZoneList<CaseClause*>(3, zone); | 
|  | 6226     Expression* knext = factory->NewSmiLiteral(kNext, nopos); | 
|  | 6227     Expression* kreturn = factory->NewSmiLiteral(kReturn, nopos); | 
|  | 6228     Expression* kthrow = factory->NewSmiLiteral(kThrow, nopos); | 
|  | 6229     cases->Add(factory->NewCaseClause(knext, case_next, nopos), zone); | 
|  | 6230     cases->Add(factory->NewCaseClause(kreturn, case_return, nopos), zone); | 
|  | 6231     cases->Add(factory->NewCaseClause(kthrow, case_throw, nopos), zone); | 
|  | 6232 | 
|  | 6233     switch_mode->Initialize(factory->NewVariableProxy(var_mode), cases); | 
|  | 6234   } | 
|  | 6235 | 
|  | 6236 | 
|  | 6237   // while (true) { ... } | 
|  | 6238   // Already defined earlier: WhileStatement* loop = ... | 
|  | 6239   { | 
|  | 6240     Block* loop_body = factory->NewBlock(nullptr, 4, false, nopos); | 
|  | 6241     loop_body->statements()->Add(switch_mode, zone); | 
|  | 6242     loop_body->statements()->Add(if_done, zone); | 
|  | 6243     loop_body->statements()->Add(set_mode_return, zone); | 
|  | 6244     loop_body->statements()->Add(try_finally, zone); | 
|  | 6245 | 
|  | 6246     loop->Initialize(factory->NewBooleanLiteral(true, nopos), loop_body); | 
|  | 6247   } | 
|  | 6248 | 
|  | 6249 | 
|  | 6250   // do { ... } | 
|  | 6251   DoExpression* yield_star; | 
|  | 6252   { | 
|  | 6253     // The rewriter needs to process the get_value statement only, hence we | 
|  | 6254     // put the preceding statements into an init block. | 
|  | 6255 | 
|  | 6256     Block* do_block_ = factory->NewBlock(nullptr, 6, true, nopos); | 
|  | 6257     do_block_->statements()->Add(initialize_input, zone); | 
|  | 6258     do_block_->statements()->Add(initialize_mode, zone); | 
|  | 6259     do_block_->statements()->Add(initialize_output, zone); | 
|  | 6260     do_block_->statements()->Add(get_iterator, zone); | 
|  | 6261     do_block_->statements()->Add(validate_iterator, zone); | 
|  | 6262     do_block_->statements()->Add(loop, zone); | 
|  | 6263 | 
|  | 6264     Block* do_block = factory->NewBlock(nullptr, 2, false, nopos); | 
|  | 6265     do_block->statements()->Add(do_block_, zone); | 
|  | 6266     do_block->statements()->Add(get_value, zone); | 
|  | 6267 | 
|  | 6268     Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 
|  | 6269     yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 
|  | 6270     Rewriter::Rewrite(parser_, yield_star, avfactory); | 
|  | 6271   } | 
|  | 6272 | 
|  | 6273   return yield_star; | 
|  | 6274 } | 
|  | 6275 | 
|  | 6276 | 
|  | 6277 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 
|  | 6278                                       Variable* iterator, | 
|  | 6279                                       Maybe<Variable*> input) { | 
|  | 6280   const int nopos = RelocInfo::kNoPosition; | 
|  | 6281   auto factory = parser_->factory(); | 
|  | 6282   auto avfactory = parser_->ast_value_factory(); | 
|  | 6283   auto scope = parser_->scope_; | 
|  | 6284   auto zone = parser_->zone(); | 
|  | 6285   Statement* skip = factory->NewEmptyStatement(nopos); | 
|  | 6286 | 
|  | 6287   // let iteratorReturn = iterator.return; | 
|  | 6288   Variable* var = scope->NewTemporary(avfactory->empty_string()); | 
|  | 6289   Statement* get_return; | 
|  | 6290   { | 
|  | 6291     Expression* iterator_proxy = factory->NewVariableProxy(iterator); | 
|  | 6292     Expression* literal = | 
|  | 6293         factory->NewStringLiteral(avfactory->return_string(), nopos); | 
|  | 6294     Expression* property = | 
|  | 6295         factory->NewProperty(iterator_proxy, literal, nopos); | 
|  | 6296     Expression* return_proxy = factory->NewVariableProxy(var); | 
|  | 6297     Expression* assignment = factory->NewAssignment( | 
|  | 6298         Token::ASSIGN, return_proxy, property, nopos); | 
|  | 6299     get_return = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6300   } | 
|  | 6301 | 
|  | 6302   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return;  OR | 
|  | 6303   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input; | 
|  | 6304   Statement* check_return; | 
|  | 6305   { | 
|  | 6306     Expression* condition = factory->NewCompareOperation( | 
|  | 6307         Token::EQ, factory->NewVariableProxy(var), | 
|  | 6308         factory->NewNullLiteral(nopos), nopos); | 
|  | 6309 | 
|  | 6310     Expression* value = input.IsJust() ? | 
|  | 6311         static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) : | 
|  | 6312         factory->NewUndefinedLiteral(nopos); | 
|  | 6313 | 
|  | 6314     Statement* return_undefined = factory->NewReturnStatement(value, nopos); | 
|  | 6315 | 
|  | 6316     check_return = | 
|  | 6317         factory->NewIfStatement(condition, return_undefined, skip, nopos); | 
|  | 6318   } | 
|  | 6319 | 
|  | 6320   // let result = %_Call(iteratorReturn, iterator);  OR | 
|  | 6321   // let result = %_Call(iteratorReturn, iterator, input); | 
|  | 6322   Statement* call_return; | 
|  | 6323   { | 
|  | 6324     auto args = new (zone) ZoneList<Expression*>(3, zone); | 
|  | 6325     args->Add(factory->NewVariableProxy(var), zone); | 
|  | 6326     args->Add(factory->NewVariableProxy(iterator), zone); | 
|  | 6327     if (input.IsJust()) { | 
|  | 6328       args->Add(factory->NewVariableProxy(input.FromJust()), zone); | 
|  | 6329     } | 
|  | 6330 | 
|  | 6331     Expression* call = | 
|  | 6332         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 
|  | 6333     Expression* assignment = factory->NewAssignment( | 
|  | 6334         Token::ASSIGN, factory->NewVariableProxy(var), call, nopos); | 
|  | 6335     call_return = factory->NewExpressionStatement(assignment, nopos); | 
|  | 6336   } | 
|  | 6337 | 
|  | 6338   // if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result); | 
|  | 6339   Statement* validate_result; | 
|  | 6340   { | 
|  | 6341     Expression* is_receiver_call; | 
|  | 6342     { | 
|  | 6343       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 6344       args->Add(factory->NewVariableProxy(var), zone); | 
|  | 6345       is_receiver_call = | 
|  | 6346           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 
|  | 6347     } | 
|  | 6348 | 
|  | 6349     Statement* throw_call; | 
|  | 6350     { | 
|  | 6351       auto args = new (zone) ZoneList<Expression*>(1, zone); | 
|  | 6352       args->Add(factory->NewVariableProxy(var), zone); | 
|  | 6353       Expression* call = factory->NewCallRuntime( | 
|  | 6354           Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 
|  | 6355       throw_call = factory->NewExpressionStatement(call, nopos); | 
|  | 6356     } | 
|  | 6357 | 
|  | 6358     validate_result = | 
|  | 6359         factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 
|  | 6360   } | 
|  | 6361 | 
|  | 6362   statements->Add(get_return, zone); | 
|  | 6363   statements->Add(check_return, zone); | 
|  | 6364   statements->Add(call_return, zone); | 
|  | 6365   statements->Add(validate_result, zone); | 
|  | 6366 } | 
|  | 6367 | 
|  | 6368 | 
| 5800 }  // namespace internal | 6369 }  // namespace internal | 
| 5801 }  // namespace v8 | 6370 }  // namespace v8 | 
| OLD | NEW | 
|---|