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 6221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6232 do_block->statements()->Add(get_value, zone); | 6232 do_block->statements()->Add(get_value, zone); |
6233 | 6233 |
6234 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6234 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
6235 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6235 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
6236 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6236 Rewriter::Rewrite(parser_, yield_star, avfactory); |
6237 } | 6237 } |
6238 | 6238 |
6239 return yield_star; | 6239 return yield_star; |
6240 } | 6240 } |
6241 | 6241 |
6242 // Desugaring of (lhs) instanceof (rhs) | |
6243 // ==================== | |
rossberg
2016/02/12 14:11:31
Nit: underline all of it?
mvstanton
2016/02/18 02:12:17
Done.
| |
6244 // | |
6245 // We desugar instanceof into a load of property @@hasInstance on the rhs. | |
6246 // We end up with roughly the following code (O, C): | |
6247 // | |
6248 // do { | |
6249 // let O = lhs; | |
6250 // let C = rhs; | |
6251 // let result; | |
6252 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); | |
6253 // let handler = C[Symbol.hasInstance]; | |
6254 // if (handler === undefined) { | |
6255 // result = %ordinary_has_instance(C, O); | |
mvstanton
2016/02/18 02:12:17
I had to add an IS_CALLABLE check here, because %o
| |
6256 // } else { | |
6257 // if (!%IsCallable(handler)) { | |
rossberg
2016/02/12 14:11:32
Is this actually necessary? %_Call would throw the
mvstanton
2016/02/18 02:12:17
Indeed, I was able to remove it, thanks!
| |
6258 // throw MakeTypeError(kFoundNonCallableHasInstance); | |
6259 // } | |
6260 // result = !!(%_Call(handler, C, O)); | |
6261 // } | |
6262 // } | |
rossberg
2016/02/12 14:11:31
result; as the last statement?
mvstanton
2016/02/18 02:12:17
Done.
| |
6263 // | |
6264 Expression* ParserTraits::RewriteInstanceof(Expression* lhs, Expression* rhs, | |
6265 int pos) { | |
6266 const int nopos = RelocInfo::kNoPosition; | |
6267 | |
6268 auto factory = parser_->factory(); | |
6269 auto avfactory = parser_->ast_value_factory(); | |
6270 auto scope = parser_->scope_; | |
6271 auto zone = parser_->zone(); | |
6272 | |
6273 // let O = lhs; | |
6274 Variable* var_O = scope->NewTemporary(avfactory->empty_string()); | |
6275 Statement* get_O; | |
6276 { | |
6277 Expression* O_proxy = factory->NewVariableProxy(var_O); | |
6278 Expression* assignment = | |
6279 factory->NewAssignment(Token::ASSIGN, O_proxy, lhs, nopos); | |
6280 get_O = factory->NewExpressionStatement(assignment, nopos); | |
6281 } | |
6282 | |
6283 // let C = lhs; | |
6284 Variable* var_C = scope->NewTemporary(avfactory->empty_string()); | |
6285 Statement* get_C; | |
6286 { | |
6287 Expression* C_proxy = factory->NewVariableProxy(var_C); | |
6288 Expression* assignment = | |
6289 factory->NewAssignment(Token::ASSIGN, C_proxy, rhs, nopos); | |
6290 get_C = factory->NewExpressionStatement(assignment, nopos); | |
6291 } | |
6292 | |
6293 Statement* skip = factory->NewEmptyStatement(nopos); | |
rossberg
2016/02/12 14:11:31
It looks like you are using this AST node twice. T
mvstanton
2016/02/18 02:12:17
Done.
| |
6294 | |
6295 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); | |
6296 Statement* validate_C; | |
6297 { | |
6298 Expression* is_receiver_call; | |
6299 { | |
6300 auto args = new (zone) ZoneList<Expression*>(1, zone); | |
6301 args->Add(factory->NewVariableProxy(var_C), zone); | |
6302 is_receiver_call = | |
6303 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | |
6304 } | |
6305 | |
6306 Statement* throw_call; | |
6307 { | |
6308 Expression* call = | |
6309 NewThrowTypeError(MessageTemplate::kNonObjectInInstanceOfCheck, | |
6310 avfactory->empty_string(), nopos); | |
6311 throw_call = factory->NewExpressionStatement(call, nopos); | |
6312 } | |
6313 | |
6314 validate_C = | |
6315 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | |
6316 } | |
6317 | |
6318 Variable* var_result = scope->NewTemporary(avfactory->empty_string()); | |
rossberg
2016/02/12 14:11:32
Nit: you can probably reuse the same temporary for
mvstanton
2016/02/18 02:12:17
Done.
| |
6319 | |
6320 // let handler = C[Symbol.hasInstance]; | |
6321 Variable* var_handler = scope->NewTemporary(avfactory->empty_string()); | |
6322 Statement* initialize_handler; | |
6323 { | |
6324 Expression* hasInstance_symbol_literal = | |
6325 factory->NewSymbolLiteral("hasInstance_symbol", RelocInfo::kNoPosition); | |
6326 Expression* prop = factory->NewProperty(factory->NewVariableProxy(var_C), | |
6327 hasInstance_symbol_literal, pos); | |
6328 Expression* handler_proxy = factory->NewVariableProxy(var_handler); | |
6329 Expression* assignment = | |
6330 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos); | |
6331 initialize_handler = factory->NewExpressionStatement(assignment, nopos); | |
6332 } | |
6333 | |
6334 // if (handler === undefined) { | |
6335 // result = %ordinary_has_instance(C, O); | |
6336 // } else { | |
6337 // result = !!%_Call(handler, C, O); | |
6338 // } | |
6339 Statement* call_handler; | |
6340 { | |
6341 Expression* condition = factory->NewCompareOperation( | |
6342 Token::EQ_STRICT, factory->NewVariableProxy(var_handler), | |
6343 factory->NewUndefinedLiteral(nopos), nopos); | |
6344 Statement* then_side; | |
6345 { | |
6346 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); | |
6347 args->Add(factory->NewVariableProxy(var_C), zone); | |
6348 args->Add(factory->NewVariableProxy(var_O), zone); | |
6349 CallRuntime* call = factory->NewCallRuntime( | |
6350 Context::ORDINARY_HAS_INSTANCE_INDEX, args, pos); | |
6351 Expression* result_proxy = factory->NewVariableProxy(var_result); | |
6352 Expression* assignment = | |
6353 factory->NewAssignment(Token::ASSIGN, result_proxy, call, nopos); | |
6354 then_side = factory->NewExpressionStatement(assignment, nopos); | |
6355 } | |
6356 Statement* else_side; | |
6357 { | |
6358 Block* block = factory->NewBlock(nullptr, 2, true, nopos); | |
6359 | |
6360 // if (!%IsCallable(handler)) { | |
6361 // throw MakeTypeError(kFoundNonCallableHasInstance); | |
6362 // } | |
6363 Statement* validate_handler; | |
6364 { | |
6365 Expression* is_callable_call; | |
6366 { | |
6367 auto args = new (zone) ZoneList<Expression*>(1, zone); | |
6368 args->Add(factory->NewVariableProxy(var_handler), zone); | |
6369 is_callable_call = | |
6370 factory->NewCallRuntime(Runtime::kIsCallable, args, nopos); | |
6371 } | |
6372 | |
6373 Statement* throw_call; | |
6374 { | |
6375 Expression* call = | |
6376 NewThrowTypeError(MessageTemplate::kFoundNonCallableHasInstance, | |
6377 avfactory->empty_string(), nopos); | |
6378 throw_call = factory->NewExpressionStatement(call, nopos); | |
6379 } | |
6380 | |
6381 validate_handler = | |
6382 factory->NewIfStatement(is_callable_call, skip, throw_call, nopos); | |
6383 } | |
6384 | |
6385 auto args = new (zone) ZoneList<Expression*>(3, zone); | |
6386 args->Add(factory->NewVariableProxy(var_handler), zone); | |
6387 args->Add(factory->NewVariableProxy(var_C), zone); | |
6388 args->Add(factory->NewVariableProxy(var_O), zone); | |
6389 Expression* call = | |
6390 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | |
6391 Expression* inner_not = | |
6392 factory->NewUnaryOperation(Token::NOT, call, nopos); | |
6393 Expression* outer_not = | |
6394 factory->NewUnaryOperation(Token::NOT, inner_not, nopos); | |
6395 Expression* result_proxy = factory->NewVariableProxy(var_result); | |
6396 Expression* assignment = | |
6397 factory->NewAssignment(Token::ASSIGN, result_proxy, outer_not, nopos); | |
6398 Statement* assignment_return = | |
6399 factory->NewExpressionStatement(assignment, nopos); | |
6400 | |
6401 block->statements()->Add(validate_handler, zone); | |
6402 block->statements()->Add(assignment_return, zone); | |
6403 | |
6404 else_side = block; | |
6405 } | |
6406 call_handler = | |
6407 factory->NewIfStatement(condition, then_side, else_side, nopos); | |
6408 } | |
6409 | |
6410 // do { ... } | |
6411 DoExpression* instanceof; | |
6412 { | |
6413 Block* block = factory->NewBlock(nullptr, 5, true, nopos); | |
6414 block->statements()->Add(get_O, zone); | |
6415 block->statements()->Add(get_C, zone); | |
6416 block->statements()->Add(validate_C, zone); | |
6417 block->statements()->Add(initialize_handler, zone); | |
6418 block->statements()->Add(call_handler, zone); | |
6419 | |
6420 // Here is the desugared instanceof. | |
6421 instanceof = factory->NewDoExpression(block, var_result, nopos); | |
6422 Rewriter::Rewrite(parser_, instanceof, avfactory); | |
6423 } | |
6424 | |
6425 return instanceof; | |
6426 } | |
6242 | 6427 |
6243 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6428 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, |
6244 Variable* iterator, | 6429 Variable* iterator, |
6245 Maybe<Variable*> input, | 6430 Maybe<Variable*> input, |
6246 Maybe<Variable*> output) { | 6431 Maybe<Variable*> output) { |
6247 const int nopos = RelocInfo::kNoPosition; | 6432 const int nopos = RelocInfo::kNoPosition; |
6248 auto factory = parser_->factory(); | 6433 auto factory = parser_->factory(); |
6249 auto avfactory = parser_->ast_value_factory(); | 6434 auto avfactory = parser_->ast_value_factory(); |
6250 auto scope = parser_->scope_; | 6435 auto scope = parser_->scope_; |
6251 auto zone = parser_->zone(); | 6436 auto zone = parser_->zone(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6330 | 6515 |
6331 statements->Add(get_return, zone); | 6516 statements->Add(get_return, zone); |
6332 statements->Add(check_return, zone); | 6517 statements->Add(check_return, zone); |
6333 statements->Add(call_return, zone); | 6518 statements->Add(call_return, zone); |
6334 statements->Add(validate_output, zone); | 6519 statements->Add(validate_output, zone); |
6335 } | 6520 } |
6336 | 6521 |
6337 | 6522 |
6338 } // namespace internal | 6523 } // namespace internal |
6339 } // namespace v8 | 6524 } // namespace v8 |
OLD | NEW |