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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 873423004: First stab at try-catch and try-finally in TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/machine-operator.h" 10 #include "src/compiler/machine-operator.h"
11 #include "src/compiler/node-matchers.h" 11 #include "src/compiler/node-matchers.h"
12 #include "src/compiler/node-properties.h" 12 #include "src/compiler/node-properties.h"
13 #include "src/compiler/operator-properties.h" 13 #include "src/compiler/operator-properties.h"
14 #include "src/full-codegen.h" 14 #include "src/full-codegen.h"
15 #include "src/parser.h" 15 #include "src/parser.h"
16 #include "src/scopes.h" 16 #include "src/scopes.h"
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 namespace compiler { 20 namespace compiler {
21 21
22 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, 22 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
23 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) 23 JSGraph* jsgraph, LoopAssignmentAnalysis* loop)
24 : StructuredGraphBuilder(jsgraph->isolate(), local_zone, jsgraph->graph(), 24 : StructuredGraphBuilder(jsgraph->isolate(), local_zone, jsgraph->graph(),
25 jsgraph->common()), 25 jsgraph->common()),
26 info_(info), 26 info_(info),
27 jsgraph_(jsgraph), 27 jsgraph_(jsgraph),
28 globals_(0, local_zone), 28 globals_(0, local_zone),
29 breakable_(NULL), 29 execution_control_(NULL),
30 execution_context_(NULL), 30 execution_context_(NULL),
31 loop_assignment_analysis_(loop) { 31 loop_assignment_analysis_(loop) {
32 InitializeAstVisitor(info->isolate(), local_zone); 32 InitializeAstVisitor(info->isolate(), local_zone);
33 } 33 }
34 34
35 35
36 Node* AstGraphBuilder::GetFunctionClosure() { 36 Node* AstGraphBuilder::GetFunctionClosure() {
37 if (!function_closure_.is_set()) { 37 if (!function_closure_.is_set()) {
38 // Parameter -1 is special for the function closure 38 // Parameter -1 is special for the function closure
39 const Operator* op = common()->Parameter(-1); 39 const Operator* op = common()->Parameter(-1);
(...skipping 16 matching lines...) Expand all
56 56
57 57
58 bool AstGraphBuilder::CreateGraph() { 58 bool AstGraphBuilder::CreateGraph() {
59 Scope* scope = info()->scope(); 59 Scope* scope = info()->scope();
60 DCHECK(graph() != NULL); 60 DCHECK(graph() != NULL);
61 61
62 // Set up the basic structure of the graph. 62 // Set up the basic structure of the graph.
63 int parameter_count = info()->num_parameters(); 63 int parameter_count = info()->num_parameters();
64 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); 64 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
65 65
66 Node* start = graph()->start(); 66 // Initialize control scope.
67 ControlScope control(this, 0);
68
67 // Initialize the top-level environment. 69 // Initialize the top-level environment.
68 Environment env(this, scope, start); 70 Environment env(this, scope, graph()->start());
69 set_environment(&env); 71 set_environment(&env);
70 72
71 if (info()->is_osr()) { 73 if (info()->is_osr()) {
72 // Use OSR normal entry as the start of the top-level environment. 74 // Use OSR normal entry as the start of the top-level environment.
73 // It will be replaced with {Dead} after typing and optimizations. 75 // It will be replaced with {Dead} after typing and optimizations.
74 NewNode(common()->OsrNormalEntry()); 76 NewNode(common()->OsrNormalEntry());
75 } 77 }
76 78
77 // Initialize the incoming context. 79 // Initialize the incoming context.
78 Node* outer_context = GetFunctionContext(); 80 Node* outer_context = GetFunctionContext();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 if (HasStackOverflow()) return false; 118 if (HasStackOverflow()) return false;
117 119
118 // Emit tracing call if requested to do so. 120 // Emit tracing call if requested to do so.
119 if (FLAG_trace) { 121 if (FLAG_trace) {
120 // TODO(mstarzinger): Only traces implicit return. 122 // TODO(mstarzinger): Only traces implicit return.
121 Node* return_value = jsgraph()->UndefinedConstant(); 123 Node* return_value = jsgraph()->UndefinedConstant();
122 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); 124 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
123 } 125 }
124 126
125 // Return 'undefined' in case we can fall off the end. 127 // Return 'undefined' in case we can fall off the end.
126 Node* control = NewNode(common()->Return(), jsgraph()->UndefinedConstant()); 128 BuildReturn(jsgraph()->UndefinedConstant());
127 UpdateControlDependencyToLeaveFunction(control);
128 129
129 // Finish the basic structure of the graph. 130 // Finish the basic structure of the graph.
130 environment()->UpdateControlDependency(exit_control()); 131 environment()->UpdateControlDependency(exit_control());
131 graph()->SetEnd(NewNode(common()->End())); 132 graph()->SetEnd(NewNode(common()->End()));
132 133
133 return true; 134 return true;
134 } 135 }
135 136
136 137
137 // Left-hand side can only be a property, a global or a variable slot. 138 // Left-hand side can only be a property, a global or a variable slot.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { 285 Node* AstGraphBuilder::AstValueContext::ConsumeValue() {
285 return environment()->Pop(); 286 return environment()->Pop();
286 } 287 }
287 288
288 289
289 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { 290 Node* AstGraphBuilder::AstTestContext::ConsumeValue() {
290 return environment()->Pop(); 291 return environment()->Pop();
291 } 292 }
292 293
293 294
294 AstGraphBuilder::BreakableScope* AstGraphBuilder::BreakableScope::FindBreakable( 295 // Helper class for a try-finally control scope. It can record intercepted
295 BreakableStatement* target) { 296 // control-flow commands that cause entry into a finally-block, and re-apply
296 BreakableScope* current = this; 297 // them after again leaving that block. Special tokens are used to identify
297 while (current != NULL && current->target_ != target) { 298 // paths going through the finally-block to dispatch after leaving the block.
298 owner_->environment()->Drop(current->drop_extra_); 299 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
299 current = current->next_; 300 public:
301 explicit DeferredCommands(AstGraphBuilder* owner)
302 : owner_(owner), deferred_(owner->zone()) {}
303
304 // One recorded control-flow command.
305 struct Entry {
306 Command command; // The command type being applied on this path.
307 Statement* statement; // The target statement for the command or {NULL}.
308 Node* value; // The passed value node for the command or {NULL}.
309 Node* token; // A token identifying this particular path.
310 };
311
312 // Records a control-flow command while entering the finally-block. This also
313 // generates a new dispatch token that identifies one particular path.
314 Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
315 Node* token = NewPathTokenForDeferredCommand();
316 deferred_.push_back({cmd, stmt, value, token});
317 return token;
300 } 318 }
301 DCHECK(current != NULL); // Always found (unless stack is malformed). 319
302 return current; 320 // Returns the dispatch token to be used to identify the implicit fall-through
321 // path at the end of a try-block into the corresponding finally-block.
322 Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); }
323
324 // Applies all recorded control-flow commands after the finally-block again.
325 // This generates a dynamic dispatch on the token from the entry point.
326 void ApplyDeferredCommands(Node* token) {
327 SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size()));
328 dispatch.BeginSwitch();
329 for (size_t i = 0; i < deferred_.size(); ++i) {
330 Node* condition = NewPathDispatchCondition(token, deferred_[i].token);
331 dispatch.BeginLabel(static_cast<int>(i), condition);
332 dispatch.EndLabel();
333 }
334 for (size_t i = 0; i < deferred_.size(); ++i) {
335 dispatch.BeginCase(static_cast<int>(i));
336 owner_->execution_control()->PerformCommand(
337 deferred_[i].command, deferred_[i].statement, deferred_[i].value);
338 dispatch.EndCase();
339 }
340 dispatch.EndSwitch();
341 }
342
343 protected:
344 Node* NewPathTokenForDeferredCommand() {
345 return owner_->jsgraph()->IntPtrConstant(deferred_.size());
346 }
347 Node* NewPathTokenForImplicitFallThrough() {
348 return owner_->jsgraph()->IntPtrConstant(-1);
349 }
350 Node* NewPathDispatchCondition(Node* t1, Node* t2) {
351 return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2);
titzer 2015/02/02 09:47:29 I think you want pointer/integer equality here. JS
Michael Starzinger 2015/02/02 14:47:41 Done.
Michael Starzinger 2015/02/02 17:08:41 Yeah, well, ain't gonna happen as long as our Phi'
352 }
353
354 private:
355 AstGraphBuilder* owner_;
356 ZoneVector<Entry> deferred_;
357 };
358
359
360 bool AstGraphBuilder::ControlScope::Execute(Command command, Statement* target,
361 Node* value) {
362 // For function-level control.
363 switch (command) {
364 case CMD_THROW:
365 owner()->BuildThrow(value);
366 return true;
367 case CMD_RETURN:
368 owner()->BuildReturn(value);
369 return true;
370 case CMD_BREAK:
371 case CMD_CONTINUE:
372 break;
373 }
374 return false;
303 } 375 }
304 376
305 377
306 void AstGraphBuilder::BreakableScope::BreakTarget(BreakableStatement* stmt) { 378 bool AstGraphBuilder::ControlScopeForBreakable::Execute(Command command,
307 FindBreakable(stmt)->control_->Break(); 379 Statement* target,
380 Node* value) {
381 if (target != target_) return false; // We are not the command target.
382 switch (command) {
383 case CMD_BREAK:
384 control_->Break();
385 return true;
386 case CMD_CONTINUE:
387 case CMD_THROW:
388 case CMD_RETURN:
389 break;
390 }
391 return false;
308 } 392 }
309 393
310 394
311 void AstGraphBuilder::BreakableScope::ContinueTarget(BreakableStatement* stmt) { 395 bool AstGraphBuilder::ControlScopeForIteration::Execute(Command command,
312 FindBreakable(stmt)->control_->Continue(); 396 Statement* target,
397 Node* value) {
398 if (target != target_) return false; // We are not the command target.
399 switch (command) {
400 case CMD_BREAK:
401 control_->Break();
402 return true;
403 case CMD_CONTINUE:
404 control_->Continue();
405 return true;
406 case CMD_THROW:
407 case CMD_RETURN:
408 break;
409 }
410 return false;
313 } 411 }
314 412
315 413
414 bool AstGraphBuilder::ControlScopeForCatch::Execute(Command command,
415 Statement* target,
416 Node* value) {
417 switch (command) {
418 case CMD_THROW:
419 control_->Throw(value);
420 return true;
421 case CMD_BREAK:
422 case CMD_CONTINUE:
423 case CMD_RETURN:
424 break;
425 }
426 return false;
427 }
428
429
430 bool AstGraphBuilder::ControlScopeForFinally::Execute(Command cmd,
431 Statement* target,
432 Node* value) {
433 Node* token = commands_->RecordCommand(cmd, target, value);
434 control_->LeaveTry(token);
435 return true;
436 }
437
438
439 void AstGraphBuilder::ControlScope::PerformCommand(Command command,
440 Statement* target,
441 Node* value) {
442 StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable();
443 ControlScope* current = this;
444 while (current != NULL) {
445 if (current->Execute(command, target, value)) break;
446 environment()->Drop(current->drop_extra());
447 current = current->next_;
448 }
449 // TODO(mstarzinger): Unconditionally kill environment once throw is control.
450 if (command != CMD_THROW) owner()->set_environment(env);
451 DCHECK(current != NULL); // Always handled (unless stack is malformed).
452 }
453
454
455 void AstGraphBuilder::ControlScope::BreakTarget(BreakableStatement* stmt) {
456 PerformCommand(CMD_BREAK, stmt, nullptr);
457 }
458
459
460 void AstGraphBuilder::ControlScope::ContinueTarget(BreakableStatement* stmt) {
461 PerformCommand(CMD_CONTINUE, stmt, nullptr);
462 }
463
464
465 void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) {
466 PerformCommand(CMD_RETURN, nullptr, return_value);
467 }
468
469
470 void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) {
471 PerformCommand(CMD_THROW, nullptr, exception_value);
472 }
473
474
316 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) { 475 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) {
317 if (expr == NULL) { 476 if (expr == NULL) {
318 return environment()->Push(jsgraph()->NullConstant()); 477 return environment()->Push(jsgraph()->NullConstant());
319 } 478 }
320 VisitForValue(expr); 479 VisitForValue(expr);
321 } 480 }
322 481
323 482
324 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) { 483 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) {
325 if (expr == NULL) { 484 if (expr == NULL) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 624
466 625
467 void AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); } 626 void AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); }
468 627
469 628
470 void AstGraphBuilder::VisitModuleUrl(ModuleUrl* modl) { UNREACHABLE(); } 629 void AstGraphBuilder::VisitModuleUrl(ModuleUrl* modl) { UNREACHABLE(); }
471 630
472 631
473 void AstGraphBuilder::VisitBlock(Block* stmt) { 632 void AstGraphBuilder::VisitBlock(Block* stmt) {
474 BlockBuilder block(this); 633 BlockBuilder block(this);
475 BreakableScope scope(this, stmt, &block, 0); 634 ControlScopeForBreakable scope(this, stmt, &block);
476 if (stmt->labels() != NULL) block.BeginBlock(); 635 if (stmt->labels() != NULL) block.BeginBlock();
477 if (stmt->scope() == NULL) { 636 if (stmt->scope() == NULL) {
478 // Visit statements in the same scope, no declarations. 637 // Visit statements in the same scope, no declarations.
479 VisitStatements(stmt->statements()); 638 VisitStatements(stmt->statements());
480 } else { 639 } else {
481 // Visit declarations and statements in a block scope. 640 // Visit declarations and statements in a block scope.
482 Node* context = BuildLocalBlockContext(stmt->scope()); 641 Node* context = BuildLocalBlockContext(stmt->scope());
483 ContextScope scope(this, stmt->scope(), context); 642 ContextScope scope(this, stmt->scope(), context);
484 VisitDeclarations(stmt->scope()->declarations()); 643 VisitDeclarations(stmt->scope()->declarations());
485 VisitStatements(stmt->statements()); 644 VisitStatements(stmt->statements());
(...skipping 24 matching lines...) Expand all
510 compare_if.If(condition); 669 compare_if.If(condition);
511 compare_if.Then(); 670 compare_if.Then();
512 Visit(stmt->then_statement()); 671 Visit(stmt->then_statement());
513 compare_if.Else(); 672 compare_if.Else();
514 Visit(stmt->else_statement()); 673 Visit(stmt->else_statement());
515 compare_if.End(); 674 compare_if.End();
516 } 675 }
517 676
518 677
519 void AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 678 void AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
520 StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable(); 679 execution_control()->ContinueTarget(stmt->target());
521 breakable()->ContinueTarget(stmt->target());
522 set_environment(env);
523 } 680 }
524 681
525 682
526 void AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 683 void AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
527 StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable(); 684 execution_control()->BreakTarget(stmt->target());
528 breakable()->BreakTarget(stmt->target());
529 set_environment(env);
530 } 685 }
531 686
532 687
533 void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 688 void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
534 VisitForValue(stmt->expression()); 689 VisitForValue(stmt->expression());
535 Node* result = environment()->Pop(); 690 Node* result = environment()->Pop();
536 Node* control = NewNode(common()->Return(), result); 691 execution_control()->ReturnValue(result);
537 UpdateControlDependencyToLeaveFunction(control);
538 } 692 }
539 693
540 694
541 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) { 695 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
542 VisitForValue(stmt->expression()); 696 VisitForValue(stmt->expression());
543 Node* value = environment()->Pop(); 697 Node* value = environment()->Pop();
544 const Operator* op = javascript()->CreateWithContext(); 698 const Operator* op = javascript()->CreateWithContext();
545 Node* context = NewNode(op, value, GetFunctionClosure()); 699 Node* context = NewNode(op, value, GetFunctionClosure());
546 PrepareFrameState(context, stmt->EntryId()); 700 PrepareFrameState(context, stmt->EntryId());
547 ContextScope scope(this, stmt->scope(), context); 701 ContextScope scope(this, stmt->scope(), context);
548 Visit(stmt->statement()); 702 Visit(stmt->statement());
549 } 703 }
550 704
551 705
552 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 706 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
553 ZoneList<CaseClause*>* clauses = stmt->cases(); 707 ZoneList<CaseClause*>* clauses = stmt->cases();
554 SwitchBuilder compare_switch(this, clauses->length()); 708 SwitchBuilder compare_switch(this, clauses->length());
555 BreakableScope scope(this, stmt, &compare_switch, 0); 709 ControlScopeForBreakable scope(this, stmt, &compare_switch);
556 compare_switch.BeginSwitch(); 710 compare_switch.BeginSwitch();
557 int default_index = -1; 711 int default_index = -1;
558 712
559 // Keep the switch value on the stack until a case matches. 713 // Keep the switch value on the stack until a case matches.
560 VisitForValue(stmt->tag()); 714 VisitForValue(stmt->tag());
561 Node* tag = environment()->Top(); 715 Node* tag = environment()->Top();
562 716
563 // Iterate over all cases and create nodes for label comparison. 717 // Iterate over all cases and create nodes for label comparison.
564 for (int i = 0; i < clauses->length(); i++) { 718 for (int i = 0; i < clauses->length(); i++) {
565 CaseClause* clause = clauses->at(i); 719 CaseClause* clause = clauses->at(i);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 Node* condition = environment()->Pop(); 952 Node* condition = environment()->Pop();
799 for_loop.BreakWhen(condition); 953 for_loop.BreakWhen(condition);
800 VisitForEffect(stmt->assign_each()); 954 VisitForEffect(stmt->assign_each());
801 VisitIterationBody(stmt, &for_loop, 0); 955 VisitIterationBody(stmt, &for_loop, 0);
802 for_loop.EndBody(); 956 for_loop.EndBody();
803 for_loop.EndLoop(); 957 for_loop.EndLoop();
804 } 958 }
805 959
806 960
807 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 961 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
808 // TODO(turbofan): Implement try-catch here. 962 TryCatchBuilder try_control(this);
809 SetStackOverflow(); 963
964 // Evaluate the try-block inside a control scope. This simulates a handler
965 // that is intercepting 'throw' control commands.
966 try_control.BeginTry();
967 {
968 ControlScopeForCatch scope(this, &try_control);
969 Visit(stmt->try_block());
970 }
971 try_control.EndTry();
972
973 // Create a catch scope that binds the exception.
974 Node* exception = try_control.GetExceptionNode();
975 if (exception == NULL) exception = jsgraph()->NullConstant();
976 Unique<String> name = MakeUnique(stmt->variable()->name());
977 const Operator* op = javascript()->CreateCatchContext(name);
978 Node* context = NewNode(op, exception, GetFunctionClosure());
979 PrepareFrameState(context, BailoutId::None());
980 ContextScope scope(this, stmt->scope(), context);
981 DCHECK(stmt->scope()->declarations()->is_empty());
982
983 // Evaluate the catch-block.
984 Visit(stmt->catch_block());
985 try_control.EndCatch();
986
987 // TODO(mstarzinger): Remove bailout once everything works.
988 if (!FLAG_turbo_exceptions) SetStackOverflow();
810 } 989 }
811 990
812 991
813 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 992 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
814 // TODO(turbofan): Implement try-catch here. 993 TryFinallyBuilder try_control(this);
815 SetStackOverflow(); 994
995 // We keep a record of all paths that enter the finally-block to be able to
996 // dispatch to the correct continuation point after the statements in the
997 // finally-block have been evaluated.
998 //
999 // The try-finally construct can enter the finally-block in three ways:
1000 // 1. By exiting the try-block normally, falling through at the end.
1001 // 2. By exiting the try-block with a function-local control flow transfer
1002 // (i.e. through break/continue/return statements).
1003 // 3. By exiting the try-block with a thrown exception.
1004 ControlScope::DeferredCommands* commands =
1005 new (zone()) ControlScope::DeferredCommands(this);
1006
1007 // Evaluate the try-block inside a control scope. This simulates a handler
1008 // that is intercepting all control commands.
1009 try_control.BeginTry();
1010 {
1011 ControlScopeForFinally scope(this, commands, &try_control);
1012 Visit(stmt->try_block());
1013 }
1014 try_control.EndTry(commands->GetFallThroughToken());
1015
1016 // Evaluate the finally-block.
1017 Visit(stmt->finally_block());
1018 try_control.EndFinally();
1019
1020 // Dynamic dispatch after the finally-block.
1021 Node* token = try_control.GetDispatchTokenNode();
1022 commands->ApplyDeferredCommands(token);
1023
1024 // TODO(mstarzinger): Remove bailout once everything works.
1025 if (!FLAG_turbo_exceptions) SetStackOverflow();
816 } 1026 }
817 1027
818 1028
819 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 1029 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
820 // TODO(turbofan): Do we really need a separate reloc-info for this? 1030 // TODO(turbofan): Do we really need a separate reloc-info for this?
821 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0)); 1031 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0));
822 PrepareFrameState(node, stmt->DebugBreakId()); 1032 PrepareFrameState(node, stmt->DebugBreakId());
823 } 1033 }
824 1034
825 1035
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 void AstGraphBuilder::VisitYield(Yield* expr) { 1579 void AstGraphBuilder::VisitYield(Yield* expr) {
1370 // TODO(turbofan): Implement yield here. 1580 // TODO(turbofan): Implement yield here.
1371 SetStackOverflow(); 1581 SetStackOverflow();
1372 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); 1582 ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
1373 } 1583 }
1374 1584
1375 1585
1376 void AstGraphBuilder::VisitThrow(Throw* expr) { 1586 void AstGraphBuilder::VisitThrow(Throw* expr) {
1377 VisitForValue(expr->exception()); 1587 VisitForValue(expr->exception());
1378 Node* exception = environment()->Pop(); 1588 Node* exception = environment()->Pop();
1379 const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1); 1589 execution_control()->ThrowValue(exception);
1380 Node* value = NewNode(op, exception); 1590 ast_context()->ProduceValue(exception);
1381 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1382 ast_context()->ProduceValue(value);
1383 } 1591 }
1384 1592
1385 1593
1386 void AstGraphBuilder::VisitProperty(Property* expr) { 1594 void AstGraphBuilder::VisitProperty(Property* expr) {
1387 Node* value; 1595 Node* value;
1388 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); 1596 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
1389 if (expr->key()->IsPropertyName()) { 1597 if (expr->key()->IsPropertyName()) {
1390 VisitForValue(expr->obj()); 1598 VisitForValue(expr->obj());
1391 Node* object = environment()->Pop(); 1599 Node* object = environment()->Pop();
1392 Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); 1600 Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 2023
1816 2024
1817 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { 2025 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
1818 if (stmt == NULL) return; 2026 if (stmt == NULL) return;
1819 Visit(stmt); 2027 Visit(stmt);
1820 } 2028 }
1821 2029
1822 2030
1823 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt, 2031 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
1824 LoopBuilder* loop, int drop_extra) { 2032 LoopBuilder* loop, int drop_extra) {
1825 BreakableScope scope(this, stmt, loop, drop_extra); 2033 ControlScopeForIteration scope(this, stmt, loop, drop_extra);
1826 Visit(stmt->body()); 2034 Visit(stmt->body());
1827 } 2035 }
1828 2036
1829 2037
1830 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { 2038 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
1831 Node* value; 2039 Node* value;
1832 if (expr->expression()->IsVariableProxy()) { 2040 if (expr->expression()->IsVariableProxy()) {
1833 // Delete of an unqualified identifier is only allowed in classic mode but 2041 // Delete of an unqualified identifier is only allowed in classic mode but
1834 // deleting "this" is allowed in all language modes. 2042 // deleting "this" is allowed in all language modes.
1835 Variable* variable = expr->expression()->AsVariableProxy()->var(); 2043 Variable* variable = expr->expression()->AsVariableProxy()->var();
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) { 2550 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
2343 // TODO(mstarzinger): Should be unified with the VisitThrow implementation. 2551 // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
2344 const Operator* op = 2552 const Operator* op =
2345 javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0); 2553 javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0);
2346 Node* call = NewNode(op); 2554 Node* call = NewNode(op);
2347 PrepareFrameState(call, bailout_id); 2555 PrepareFrameState(call, bailout_id);
2348 return call; 2556 return call;
2349 } 2557 }
2350 2558
2351 2559
2560 Node* AstGraphBuilder::BuildReturn(Node* return_value) {
2561 Node* control = NewNode(common()->Return(), return_value);
2562 UpdateControlDependencyToLeaveFunction(control);
2563 return control;
2564 }
2565
2566
2567 Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
2568 const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
2569 Node* control = NewNode(op, exception_value);
2570 // TODO(mstarzinger): Thread through the correct bailout id to this point.
Michael Starzinger 2015/01/30 14:30:27 This is the TODO I still need to address.
Michael Starzinger 2015/02/02 15:08:02 I added a workaround that only uses the ControlSco
2571 // PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2572 PrepareFrameState(control, BailoutId::None());
2573 return control;
2574 }
2575
2576
2352 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { 2577 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
2353 const Operator* js_op; 2578 const Operator* js_op;
2354 switch (op) { 2579 switch (op) {
2355 case Token::BIT_OR: 2580 case Token::BIT_OR:
2356 js_op = javascript()->BitwiseOr(); 2581 js_op = javascript()->BitwiseOr();
2357 break; 2582 break;
2358 case Token::BIT_AND: 2583 case Token::BIT_AND:
2359 js_op = javascript()->BitwiseAnd(); 2584 js_op = javascript()->BitwiseAnd();
2360 break; 2585 break;
2361 case Token::BIT_XOR: 2586 case Token::BIT_XOR:
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 2654
2430 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( 2655 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
2431 IterationStatement* stmt) { 2656 IterationStatement* stmt) {
2432 if (loop_assignment_analysis_ == NULL) return NULL; 2657 if (loop_assignment_analysis_ == NULL) return NULL;
2433 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); 2658 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
2434 } 2659 }
2435 2660
2436 } // namespace compiler 2661 } // namespace compiler
2437 } // namespace internal 2662 } // namespace internal
2438 } // namespace v8 2663 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698