Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: src/parsing/parser.cc

Issue 1643903003: [generators] Desugar yield*. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add CHECK to rewriter. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 // let iteratorReturn = iterator.return;
5830 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
5831 // output = %_Call(iteratorReturn, iterator, input);
5832 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5833 // break;
5834 // case kThrow:
5835 // let iteratorThrow = iterator.throw;
5836 // if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
5837 // IteratorClose(iterator);
5838 // throw MakeTypeError(kThrowMethodMissing);
5839 // }
5840 // output = %_Call(iteratorThrow, iterator, input);
5841 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5842 // break;
5843 // }
5844 // if (output.done) break;
5845 //
5846 // // From the generator to its user:
5847 // // Forward output, receive new input, and determine resume mode.
5848 // mode = kReturn;
5849 // try {
5850 // try {
5851 // RawYield(output); // See explanation above.
5852 // mode = kNext;
5853 // } catch (error) {
5854 // mode = kThrow;
5855 // }
5856 // } finally {
5857 // input = function.sent;
5858 // continue;
5859 // }
5860 // }
5861 //
5862 // output.value;
5863 // }
5864 //
5865 // IteratorClose(iterator) in the code above expands to the following:
5866 //
5867 // let iteratorReturn = iterator.return;
5868 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return;
5869 // let result = %_Call(iteratorReturn, iterator);
5870 // if (!IS_RECEIVER(result)) throw MakeTypeError(kIllegalInvocation);
5871
5872
5873 Expression* ParserTraits::RewriteYieldStar(
5874 Expression* generator, Expression* iterable, int pos) {
5875
5876 const int nopos = RelocInfo::kNoPosition;
5877
5878 auto factory = parser_->factory();
5879 auto avfactory = parser_->ast_value_factory();
5880 auto scope = parser_->scope_;
5881 auto zone = parser_->zone();
5882
5883 Statement* skip = factory->NewEmptyStatement(nopos);
5884
5885 enum { kNext, kReturn, kThrow };
Dan Ehrenberg 2016/02/04 11:40:32 This looks redundant with JSGeneratorObject::Resum
5886
5887 // Forward definition for break/continue statements.
5888 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos);
5889
5890
5891 // let input = undefined;
5892 Variable* var_input = scope->NewTemporary(avfactory->empty_string());
5893 Statement* initialize_input;
5894 {
5895 Expression* input_proxy = factory->NewVariableProxy(var_input);
5896 Expression* assignment = factory->NewAssignment(
5897 Token::ASSIGN, input_proxy, factory->NewUndefinedLiteral(nopos), nopos);
5898 initialize_input = factory->NewExpressionStatement(assignment, nopos);
5899 }
5900
5901
5902 // let mode = kNext;
5903 Variable* var_mode = scope->NewTemporary(avfactory->empty_string());
5904 Statement* initialize_mode;
5905 {
5906 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
5907 Expression* knext = factory->NewSmiLiteral(kNext, nopos);
5908 Expression* assignment =
5909 factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
5910 initialize_mode = factory->NewExpressionStatement(assignment, nopos);
5911 }
5912
5913
5914 // let output = undefined;
5915 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
5916 Statement* initialize_output;
5917 {
5918 Expression* output_proxy = factory->NewVariableProxy(var_output);
5919 Expression* assignment = factory->NewAssignment(
5920 Token::ASSIGN, output_proxy, factory->NewUndefinedLiteral(nopos),
5921 nopos);
5922 initialize_output = factory->NewExpressionStatement(assignment, nopos);
5923 }
5924
5925
5926 // let iterator = iterable[Symbol.iterator];
5927 Variable* var_iterator = scope->NewTemporary(avfactory->empty_string());
5928 Statement* get_iterator;
5929 {
5930 Expression* iterator = GetIterator(iterable, factory, nopos);
5931 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
5932 Expression* assignment = factory->NewAssignment(
5933 Token::ASSIGN, iterator_proxy, iterator, nopos);
5934 get_iterator = factory->NewExpressionStatement(assignment, nopos);
5935 }
5936
5937
5938 // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
5939 Statement* validate_iterator;
5940 {
5941 Expression* is_receiver_call;
5942 {
5943 auto args = new (zone) ZoneList<Expression*>(1, zone);
5944 args->Add(factory->NewVariableProxy(var_iterator), zone);
5945 is_receiver_call =
5946 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
5947 }
5948
5949 Statement* throw_call;
5950 {
5951 Expression* call = NewThrowTypeError(
5952 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(),
5953 nopos);
5954 throw_call = factory->NewExpressionStatement(call, nopos);
5955 }
5956
5957 validate_iterator =
5958 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos);
5959 }
5960
5961
5962 // output = iterator.next(input);
5963 Statement* call_next;
5964 {
5965 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
5966 Expression* literal =
5967 factory->NewStringLiteral(avfactory->next_string(), nopos);
5968 Expression* next_property =
5969 factory->NewProperty(iterator_proxy, literal, nopos);
5970 Expression* input_proxy = factory->NewVariableProxy(var_input);
5971 auto args = new (zone) ZoneList<Expression*>(1, zone);
5972 args->Add(input_proxy, zone);
5973 Expression* call = factory->NewCall(next_property, args, nopos);
5974 Expression* output_proxy = factory->NewVariableProxy(var_output);
5975 Expression* assignment =
5976 factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
5977 call_next = factory->NewExpressionStatement(assignment, nopos);
5978 }
5979
5980
5981 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5982 Statement* validate_next_output;
5983 {
5984 Expression* is_receiver_call;
5985 {
5986 auto args = new (zone) ZoneList<Expression*>(1, zone);
5987 args->Add(factory->NewVariableProxy(var_output), zone);
5988 is_receiver_call =
5989 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
5990 }
5991
5992 Statement* throw_call;
5993 {
5994 auto args = new (zone) ZoneList<Expression*>(1, zone);
5995 args->Add(factory->NewVariableProxy(var_output), zone);
5996 Expression* call = factory->NewCallRuntime(
5997 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
5998 throw_call = factory->NewExpressionStatement(call, nopos);
5999 }
6000
6001 validate_next_output =
6002 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos);
6003 }
6004
6005
6006 // let iteratorReturn = iterator.return;
6007 Variable* var_fun = scope->NewTemporary(avfactory->empty_string());
6008 Statement* get_return;
6009 {
6010 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6011 Expression* literal =
6012 factory->NewStringLiteral(avfactory->return_string(), nopos);
6013 Expression* property =
6014 factory->NewProperty(iterator_proxy, literal, nopos);
6015 Expression* return_proxy = factory->NewVariableProxy(var_fun);
6016 Expression* assignment = factory->NewAssignment(
6017 Token::ASSIGN, return_proxy, property, nopos);
6018 get_return = factory->NewExpressionStatement(assignment, nopos);
6019 }
6020
6021
6022 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input;
6023 Statement* check_return;
6024 {
6025 Expression* condition = factory->NewCompareOperation(
6026 Token::EQ, factory->NewVariableProxy(var_fun),
6027 factory->NewNullLiteral(nopos), nopos);
6028 Statement* return_input = factory->NewReturnStatement(
6029 factory->NewVariableProxy(var_input), nopos);
6030 check_return =
6031 factory->NewIfStatement(condition, return_input, skip, nopos);
6032 }
6033
6034
6035 // output = %_Call(iteratorReturn, iterator, input);
6036 Statement* call_return;
6037 {
6038 auto args = new (zone) ZoneList<Expression*>(3, zone);
6039 args->Add(factory->NewVariableProxy(var_fun), zone);
6040 args->Add(factory->NewVariableProxy(var_iterator), zone);
6041 args->Add(factory->NewVariableProxy(var_input), zone);
6042 Expression* call =
6043 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6044 Expression* assignment = factory->NewAssignment(
6045 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6046 call_return = factory->NewExpressionStatement(assignment, nopos);
6047 }
6048
6049
6050 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6051 Statement* validate_return_output;
6052 {
6053 Expression* is_receiver_call;
6054 {
6055 auto args = new (zone) ZoneList<Expression*>(1, zone);
6056 args->Add(factory->NewVariableProxy(var_output), zone);
6057 is_receiver_call =
6058 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6059 }
6060
6061 Statement* throw_call;
6062 {
6063 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
6064 args->Add(factory->NewVariableProxy(var_output), zone);
6065 Expression* call = factory->NewCallRuntime(
6066 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6067 throw_call = factory->NewExpressionStatement(call, nopos);
6068 }
6069
6070 validate_return_output =
6071 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos);
6072 }
6073
6074
6075 // let iteratorThrow = iterator.throw;
6076 Statement* get_throw;
6077 {
6078 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6079 Expression* literal =
6080 factory->NewStringLiteral(avfactory->throw_string(), nopos);
6081 Expression* property =
6082 factory->NewProperty(iterator_proxy, literal, nopos);
6083 Expression* throw_proxy = factory->NewVariableProxy(var_fun);
6084 Expression* assignment = factory->NewAssignment(
6085 Token::ASSIGN, throw_proxy, property, nopos);
6086 get_throw = factory->NewExpressionStatement(assignment, nopos);
6087 }
6088
6089
6090 // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
6091 // IteratorClose(iterator);
6092 // throw MakeTypeError(kThrowMethodMissing);
6093 // }
6094 Statement* check_throw;
6095 {
6096 Expression* condition = factory->NewCompareOperation(
6097 Token::EQ, factory->NewVariableProxy(var_fun),
6098 factory->NewNullLiteral(nopos), nopos);
6099
6100 Expression* call = NewThrowTypeError(
6101 MessageTemplate::kThrowMethodMissing,
6102 avfactory->empty_string(), nopos);
6103 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6104
6105 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos);
6106 BuildIteratorClose(then->statements(), var_iterator);
6107 then->statements()->Add(throw_call, zone);
6108 check_throw =
6109 factory->NewIfStatement(condition, then, skip, nopos);
6110 }
6111
6112
6113 // output = %_Call(iteratorThrow, iterator, input);
6114 Statement* call_throw;
6115 {
6116 auto args = new (zone) ZoneList<Expression*>(3, zone);
6117 args->Add(factory->NewVariableProxy(var_fun), zone);
6118 args->Add(factory->NewVariableProxy(var_iterator), zone);
6119 args->Add(factory->NewVariableProxy(var_input), zone);
6120 Expression* call =
6121 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6122 Expression* assignment = factory->NewAssignment(
6123 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6124 call_throw = factory->NewExpressionStatement(assignment, nopos);
6125 }
6126
6127
6128 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6129 Statement* validate_throw_output;
6130 {
6131 Expression* is_receiver_call;
6132 {
6133 auto args = new (zone) ZoneList<Expression*>(1, zone);
6134 args->Add(factory->NewVariableProxy(var_output), zone);
6135 is_receiver_call =
6136 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6137 }
6138
6139 Statement* throw_call;
6140 {
6141 auto args = new (zone) ZoneList<Expression*>(1, zone);
6142 args->Add(factory->NewVariableProxy(var_output), zone);
6143 Expression* call = factory->NewCallRuntime(
6144 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6145 throw_call = factory->NewExpressionStatement(call, nopos);
6146 }
6147
6148 validate_throw_output =
6149 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos);
6150 }
6151
6152
6153 // if (output.done) break;
6154 Statement* if_done;
6155 {
6156 Expression* output_proxy = factory->NewVariableProxy(var_output);
6157 Expression* literal =
6158 factory->NewStringLiteral(avfactory->done_string(), nopos);
6159 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6160 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos);
6161 if_done = factory->NewIfStatement(property, break_loop, skip, nopos);
6162 }
6163
6164
6165 // mode = kReturn;
6166 Statement* set_mode_return;
6167 {
6168 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6169 Expression* kreturn = factory->NewSmiLiteral(kReturn, nopos);
6170 Expression* assignment =
6171 factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
6172 set_mode_return = factory->NewExpressionStatement(assignment, nopos);
6173 }
6174
6175
6176 // RawYield(output);
6177 Statement* yield_output;
6178 {
6179 Expression* output_proxy = factory->NewVariableProxy(var_output);
6180 Yield* yield = factory->NewYield(
6181 generator, output_proxy, Yield::kInitial, nopos);
6182 yield_output = factory->NewExpressionStatement(yield, nopos);
6183 }
6184
6185
6186 // mode = kNext;
6187 Statement* set_mode_next;
6188 {
6189 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6190 Expression* knext = factory->NewSmiLiteral(kNext, nopos);
6191 Expression* assignment =
6192 factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
6193 set_mode_next = factory->NewExpressionStatement(assignment, nopos);
6194 }
6195
6196
6197 // mode = kThrow;
6198 Statement* set_mode_throw;
6199 {
6200 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6201 Expression* kthrow = factory->NewSmiLiteral(kThrow, nopos);
6202 Expression* assignment =
6203 factory->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
6204 set_mode_throw = factory->NewExpressionStatement(assignment, nopos);
6205 }
6206
6207
6208 // input = function.sent;
6209 Statement* get_input;
6210 {
6211 Expression* function_sent = FunctionSentExpression(scope, factory, nopos);
6212 Expression* input_proxy = factory->NewVariableProxy(var_input);
6213 Expression* assignment = factory->NewAssignment(
6214 Token::ASSIGN, input_proxy, function_sent, nopos);
6215 get_input = factory->NewExpressionStatement(assignment, nopos);
6216 }
6217
6218
6219 // output.value;
6220 Statement* get_value;
6221 {
6222 Expression* output_proxy = factory->NewVariableProxy(var_output);
6223 Expression* literal =
6224 factory->NewStringLiteral(avfactory->value_string(), nopos);
6225 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6226 get_value = factory->NewExpressionStatement(property, nopos);
6227 }
6228
6229
6230 // Now put things together.
6231
6232
6233 // try { ... } catch(e) { ... }
6234 Statement* try_catch;
6235 {
6236 Block* try_block = factory->NewBlock(nullptr, 2, false, nopos);
6237 try_block->statements()->Add(yield_output, zone);
6238 try_block->statements()->Add(set_mode_next, zone);
6239
6240 Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos);
6241 catch_block->statements()->Add(set_mode_throw, zone);
6242
6243 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6244 const AstRawString* name = avfactory->dot_catch_string();
6245 Variable* catch_variable =
6246 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
6247 Variable::NORMAL);
6248
6249 try_catch = factory->NewTryCatchStatement(
6250 try_block, catch_scope, catch_variable, catch_block, nopos);
6251 }
6252
6253
6254 // try { ... } finally { ... }
6255 Statement* try_finally;
6256 {
6257 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6258 try_block->statements()->Add(try_catch, zone);
6259
6260 Block* finally = factory->NewBlock(nullptr, 2, false, nopos);
6261 finally->statements()->Add(get_input, zone);
6262 finally->statements()->Add(
6263 factory->NewContinueStatement(loop, nopos), zone);
6264
6265 try_finally = factory->NewTryFinallyStatement(try_block, finally, nopos);
6266 }
6267
6268
6269 // switch (mode) { ... }
6270 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos);
6271 {
6272 auto case_next = new (zone) ZoneList<Statement*>(3, zone);
6273 case_next->Add(call_next, zone);
6274 case_next->Add(validate_next_output, zone);
6275 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6276
6277 auto case_return = new (zone) ZoneList<Statement*>(5, zone);
6278 case_return->Add(get_return, zone);
6279 case_return->Add(check_return, zone);
6280 case_return->Add(call_return, zone);
6281 case_return->Add(validate_return_output, zone);
6282 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6283
6284 auto case_throw = new (zone) ZoneList<Statement*>(5, zone);
6285 case_throw->Add(get_throw, zone);
6286 case_throw->Add(check_throw, zone);
6287 case_throw->Add(call_throw, zone);
6288 case_throw->Add(validate_throw_output, zone);
6289 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6290
6291 auto cases = new (zone) ZoneList<CaseClause*>(3, zone);
6292 Expression* knext = factory->NewSmiLiteral(kNext, nopos);
6293 Expression* kreturn = factory->NewSmiLiteral(kReturn, nopos);
6294 Expression* kthrow = factory->NewSmiLiteral(kThrow, nopos);
6295 cases->Add(factory->NewCaseClause(knext, case_next, nopos), zone);
6296 cases->Add(factory->NewCaseClause(kreturn, case_return, nopos), zone);
6297 cases->Add(factory->NewCaseClause(kthrow, case_throw, nopos), zone);
6298
6299 switch_mode->Initialize(factory->NewVariableProxy(var_mode), cases);
6300 }
6301
6302
6303 // while (true) { ... }
6304 // Already defined earlier: WhileStatement* loop = ...
6305 {
6306 Block* loop_body = factory->NewBlock(nullptr, 4, false, nopos);
6307 loop_body->statements()->Add(switch_mode, zone);
6308 loop_body->statements()->Add(if_done, zone);
6309 loop_body->statements()->Add(set_mode_return, zone);
6310 loop_body->statements()->Add(try_finally, zone);
6311
6312 loop->Initialize(factory->NewBooleanLiteral(true, nopos), loop_body);
6313 }
6314
6315
6316 // do { ... }
6317 DoExpression* yield_star;
6318 {
6319 // The rewriter needs to process the get_value statement only, hence we
6320 // put the preceding statements into an init block.
6321
6322 Block* do_block_ = factory->NewBlock(nullptr, 6, true, nopos);
6323 do_block_->statements()->Add(initialize_input, zone);
6324 do_block_->statements()->Add(initialize_mode, zone);
6325 do_block_->statements()->Add(initialize_output, zone);
6326 do_block_->statements()->Add(get_iterator, zone);
6327 do_block_->statements()->Add(validate_iterator, zone);
6328 do_block_->statements()->Add(loop, zone);
6329
6330 Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
6331 do_block->statements()->Add(do_block_, zone);
6332 do_block->statements()->Add(get_value, zone);
6333
6334 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string());
6335 yield_star = factory->NewDoExpression(do_block, dot_result, nopos);
6336 Rewriter::Rewrite(parser_, yield_star, avfactory);
6337 }
6338
6339 return yield_star;
6340 }
6341
6342
6343 void ParserTraits::BuildIteratorClose(
6344 ZoneList<Statement*>* statements, Variable* iterator) {
6345
6346 const int nopos = RelocInfo::kNoPosition;
6347 auto factory = parser_->factory();
6348 auto avfactory = parser_->ast_value_factory();
6349 auto scope = parser_->scope_;
6350 auto zone = parser_->zone();
6351 Statement* skip = factory->NewEmptyStatement(nopos);
6352
6353 // let iteratorReturn = iterator.return;
6354 Variable* var = scope->NewTemporary(avfactory->empty_string());
6355 Statement* get_return;
6356 {
6357 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6358 Expression* literal =
6359 factory->NewStringLiteral(avfactory->return_string(), nopos);
6360 Expression* property =
6361 factory->NewProperty(iterator_proxy, literal, nopos);
6362 Expression* return_proxy = factory->NewVariableProxy(var);
6363 Expression* assignment = factory->NewAssignment(
6364 Token::ASSIGN, return_proxy, property, nopos);
6365 get_return = factory->NewExpressionStatement(assignment, nopos);
6366 }
6367
6368 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return;
6369 Statement* check_return;
6370 {
6371 Expression* condition = factory->NewCompareOperation(
6372 Token::EQ, factory->NewVariableProxy(var),
6373 factory->NewNullLiteral(nopos), nopos);
6374
6375 Statement* return_undefined = factory->NewReturnStatement(
6376 factory->NewUndefinedLiteral(nopos), nopos);
6377
6378 check_return =
6379 factory->NewIfStatement(condition, return_undefined, skip, nopos);
6380 }
6381
6382 // let result = %_Call(iteratorReturn, iterator);
6383 Statement* call_return;
6384 {
6385 auto args = new (zone) ZoneList<Expression*>(2, zone);
6386 args->Add(factory->NewVariableProxy(var), zone);
6387 args->Add(factory->NewVariableProxy(iterator), zone);
6388 Expression* call =
6389 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6390 Expression* assignment = factory->NewAssignment(
6391 Token::ASSIGN, factory->NewVariableProxy(var), call, nopos);
6392 call_return = factory->NewExpressionStatement(assignment, nopos);
6393 }
6394
6395 // if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result);
6396 Statement* validate_result;
6397 {
6398 Expression* is_receiver_call;
6399 {
6400 auto args = new (zone) ZoneList<Expression*>(1, zone);
6401 args->Add(factory->NewVariableProxy(var), zone);
6402 is_receiver_call =
6403 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6404 }
6405
6406 Statement* throw_call;
6407 {
6408 auto args = new (zone) ZoneList<Expression*>(1, zone);
6409 args->Add(factory->NewVariableProxy(var), zone);
6410 Expression* call = factory->NewCallRuntime(
6411 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6412 throw_call = factory->NewExpressionStatement(call, nopos);
6413 }
6414
6415 validate_result =
6416 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos);
6417 }
6418
6419 statements->Add(get_return, zone);
6420 statements->Add(check_return, zone);
6421 statements->Add(call_return, zone);
6422 statements->Add(validate_result, zone);
6423 }
6424
6425
5800 } // namespace internal 6426 } // namespace internal
5801 } // namespace v8 6427 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698