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

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: Refer to ResumeMode 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
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // 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
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698