OLD | NEW |
---|---|
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 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ | 5 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ |
6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ | 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/ast.h" | 10 #include "src/ast.h" |
11 #include "src/compiler/graph-builder.h" | 11 #include "src/compiler/graph-builder.h" |
12 #include "src/compiler/js-graph.h" | 12 #include "src/compiler/js-graph.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 class ControlBuilder; | 18 class ControlBuilder; |
19 class Graph; | 19 class Graph; |
20 class LoopAssignmentAnalysis; | 20 class LoopAssignmentAnalysis; |
21 class LoopBuilder; | 21 class LoopBuilder; |
22 class TryCatchBuilder; | |
23 class TryFinallyBuilder; | |
22 | 24 |
23 // The AstGraphBuilder produces a high-level IR graph, based on an | 25 // The AstGraphBuilder produces a high-level IR graph, based on an |
24 // underlying AST. The produced graph can either be compiled into a | 26 // underlying AST. The produced graph can either be compiled into a |
25 // stand-alone function or be wired into another graph for the purposes | 27 // stand-alone function or be wired into another graph for the purposes |
26 // of function inlining. | 28 // of function inlining. |
27 class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { | 29 class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { |
28 public: | 30 public: |
29 AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, | 31 AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, |
30 LoopAssignmentAnalysis* loop_assignment = NULL); | 32 LoopAssignmentAnalysis* loop_assignment = NULL); |
31 | 33 |
32 // Creates a graph by visiting the entire AST. | 34 // Creates a graph by visiting the entire AST. |
33 bool CreateGraph(); | 35 bool CreateGraph(); |
34 | 36 |
35 protected: | 37 protected: |
36 class AstContext; | 38 class AstContext; |
37 class AstEffectContext; | 39 class AstEffectContext; |
38 class AstValueContext; | 40 class AstValueContext; |
39 class AstTestContext; | 41 class AstTestContext; |
40 class BreakableScope; | |
41 class ContextScope; | 42 class ContextScope; |
43 class ControlScope; | |
44 class ControlScopeForBreakable; | |
45 class ControlScopeForIteration; | |
46 class ControlScopeForCatch; | |
47 class ControlScopeForFinally; | |
42 class Environment; | 48 class Environment; |
43 | 49 |
44 Environment* environment() { | 50 Environment* environment() { |
45 return reinterpret_cast<Environment*>( | 51 return reinterpret_cast<Environment*>( |
46 StructuredGraphBuilder::environment()); | 52 StructuredGraphBuilder::environment()); |
47 } | 53 } |
48 | 54 |
49 AstContext* ast_context() const { return ast_context_; } | 55 AstContext* ast_context() const { return ast_context_; } |
50 BreakableScope* breakable() const { return breakable_; } | 56 ControlScope* execution_control() const { return execution_control_; } |
51 ContextScope* execution_context() const { return execution_context_; } | 57 ContextScope* execution_context() const { return execution_context_; } |
52 | 58 |
53 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } | 59 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } |
54 void set_breakable(BreakableScope* brk) { breakable_ = brk; } | 60 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } |
55 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } | 61 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } |
56 | 62 |
57 // Support for control flow builders. The concrete type of the environment | 63 // Support for control flow builders. The concrete type of the environment |
58 // depends on the graph builder, but environments themselves are not virtual. | 64 // depends on the graph builder, but environments themselves are not virtual. |
59 typedef StructuredGraphBuilder::Environment BaseEnvironment; | 65 typedef StructuredGraphBuilder::Environment BaseEnvironment; |
60 BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE; | 66 BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE; |
61 | 67 |
62 // Getters for values in the activation record. | 68 // Getters for values in the activation record. |
63 Node* GetFunctionClosure(); | 69 Node* GetFunctionClosure(); |
64 Node* GetFunctionContext(); | 70 Node* GetFunctionContext(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 | 109 |
104 // Builders for error reporting at runtime. | 110 // Builders for error reporting at runtime. |
105 Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); | 111 Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); |
106 Node* BuildThrowConstAssignError(BailoutId bailout_id); | 112 Node* BuildThrowConstAssignError(BailoutId bailout_id); |
107 | 113 |
108 // Builders for dynamic hole-checks at runtime. | 114 // Builders for dynamic hole-checks at runtime. |
109 Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole); | 115 Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole); |
110 Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole, | 116 Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole, |
111 BailoutId bailout_id); | 117 BailoutId bailout_id); |
112 | 118 |
119 // Builders for non-local control flow. | |
120 Node* BuildReturn(Node* return_value); | |
121 Node* BuildThrow(Node* exception_value); | |
122 | |
113 // Builders for binary operations. | 123 // Builders for binary operations. |
114 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); | 124 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); |
115 | 125 |
116 // Builder for stack-check guards. | 126 // Builder for stack-check guards. |
117 Node* BuildStackCheck(); | 127 Node* BuildStackCheck(); |
118 | 128 |
119 bool IsOsrLoopEntry(IterationStatement* stmt); | 129 bool IsOsrLoopEntry(IterationStatement* stmt); |
120 | 130 |
121 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; | 131 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; |
122 | 132 |
123 // Visiting functions for AST nodes make this an AstVisitor. | 133 // Visiting functions for AST nodes make this an AstVisitor. |
124 AST_NODE_LIST(DECLARE_VISIT) | 134 AST_NODE_LIST(DECLARE_VISIT) |
125 #undef DECLARE_VISIT | 135 #undef DECLARE_VISIT |
126 | 136 |
127 // Visiting function for declarations list is overridden. | 137 // Visiting function for declarations list is overridden. |
128 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE; | 138 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE; |
129 | 139 |
130 private: | 140 private: |
131 CompilationInfo* info_; | 141 CompilationInfo* info_; |
132 AstContext* ast_context_; | 142 AstContext* ast_context_; |
133 JSGraph* jsgraph_; | 143 JSGraph* jsgraph_; |
134 | 144 |
135 // List of global declarations for functions and variables. | 145 // List of global declarations for functions and variables. |
136 ZoneVector<Handle<Object>> globals_; | 146 ZoneVector<Handle<Object>> globals_; |
137 | 147 |
138 // Stack of breakable statements entered by the visitor. | 148 // Stack of control scopes currently entered by the visitor. |
139 BreakableScope* breakable_; | 149 ControlScope* execution_control_; |
140 | 150 |
141 // Stack of context objects pushed onto the chain by the visitor. | 151 // Stack of context objects pushed onto the chain by the visitor. |
142 ContextScope* execution_context_; | 152 ContextScope* execution_context_; |
143 | 153 |
144 // Nodes representing values in the activation record. | 154 // Nodes representing values in the activation record. |
145 SetOncePointer<Node> function_closure_; | 155 SetOncePointer<Node> function_closure_; |
146 SetOncePointer<Node> function_context_; | 156 SetOncePointer<Node> function_context_; |
147 | 157 |
148 // The node representing the OSR entry into the loop, if any. | 158 // The node representing the OSR entry into the loop, if any. |
149 SetOncePointer<Node> osr_loop_entry_; | 159 SetOncePointer<Node> osr_loop_entry_; |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 class AstGraphBuilder::AstTestContext FINAL : public AstContext { | 392 class AstGraphBuilder::AstTestContext FINAL : public AstContext { |
383 public: | 393 public: |
384 explicit AstTestContext(AstGraphBuilder* owner) | 394 explicit AstTestContext(AstGraphBuilder* owner) |
385 : AstContext(owner, Expression::kTest) {} | 395 : AstContext(owner, Expression::kTest) {} |
386 ~AstTestContext() FINAL; | 396 ~AstTestContext() FINAL; |
387 void ProduceValue(Node* value) FINAL; | 397 void ProduceValue(Node* value) FINAL; |
388 Node* ConsumeValue() FINAL; | 398 Node* ConsumeValue() FINAL; |
389 }; | 399 }; |
390 | 400 |
391 | 401 |
392 // Scoped class tracking breakable statements entered by the visitor. Allows to | 402 // Scoped class tracking control statements entered by the visitor. There are |
393 // properly 'break' and 'continue' iteration statements as well as to 'break' | 403 // different types of statements participating in this stack to properly track |
394 // from blocks within switch statements. | 404 // local as well as non-local control flow: |
395 class AstGraphBuilder::BreakableScope BASE_EMBEDDED { | 405 // - IterationStatement : Allows proper 'break' and 'continue' behavior. |
406 // - BreakableStatement : Allows 'break' from block and switch statements. | |
407 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. | |
408 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. | |
409 class AstGraphBuilder::ControlScope BASE_EMBEDDED { | |
396 public: | 410 public: |
397 BreakableScope(AstGraphBuilder* owner, BreakableStatement* target, | 411 ControlScope(AstGraphBuilder* builder, int stack_delta) |
398 ControlBuilder* control, int drop_extra) | 412 : builder_(builder), |
399 : owner_(owner), | 413 next_(builder->execution_control()), |
400 target_(target), | 414 stack_delta_(stack_delta) { |
401 next_(owner->breakable()), | 415 builder_->set_execution_control(this); // Push. |
402 control_(control), | |
403 drop_extra_(drop_extra) { | |
404 owner_->set_breakable(this); // Push. | |
405 } | 416 } |
406 | 417 |
407 ~BreakableScope() { | 418 virtual ~ControlScope() { |
408 owner_->set_breakable(next_); // Pop. | 419 builder_->set_execution_control(next_); // Pop. |
409 } | 420 } |
410 | 421 |
411 // Either 'break' or 'continue' the target statement. | 422 // Either 'break' or 'continue' the target statement. |
412 void BreakTarget(BreakableStatement* target); | 423 void BreakTarget(BreakableStatement* target); |
413 void ContinueTarget(BreakableStatement* target); | 424 void ContinueTarget(BreakableStatement* target); |
414 | 425 |
426 // Either 'return' or 'throw' the given value. | |
427 void ReturnValue(Node* return_value); | |
428 void ThrowValue(Node* exception_value); | |
429 | |
430 class DeferredCommands; | |
431 | |
432 protected: | |
433 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW }; | |
434 | |
435 // Performs one of the above commands on this stack of control scopes. This | |
436 // walks through the stack giving each scope a chance to execute or defer the | |
437 // given command by overriding the {Execute} method appropriately. Note that | |
438 // this also drops extra operands from the environment for each skipped scope. | |
439 void PerformCommand(Command cmd, Statement* target, Node* value); | |
440 | |
441 // Interface to execute a given command in this scope. Returning {true} here | |
442 // indicates successful execution whereas {false} requests to skip scope. | |
443 virtual bool Execute(Command cmd, Statement* target, Node* value); | |
444 | |
445 Environment* environment() { return builder_->environment(); } | |
446 AstGraphBuilder* builder() const { return builder_; } | |
447 int stack_delta() const { return stack_delta_; } | |
448 | |
415 private: | 449 private: |
416 AstGraphBuilder* owner_; | 450 AstGraphBuilder* builder_; |
417 BreakableStatement* target_; | 451 ControlScope* next_; |
418 BreakableScope* next_; | 452 int stack_delta_; |
419 ControlBuilder* control_; | |
420 int drop_extra_; | |
421 | |
422 // Find the correct scope for the target statement. Note that this also drops | |
423 // extra operands from the environment for each scope skipped along the way. | |
424 BreakableScope* FindBreakable(BreakableStatement* target); | |
425 }; | 453 }; |
426 | 454 |
427 | 455 |
456 // Control scope implementation for a BreakableStatement. | |
titzer
2015/02/03 09:01:22
Is it necessary to put these full declarations in
Michael Starzinger
2015/02/03 09:18:53
Done.
| |
457 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { | |
458 public: | |
459 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, | |
460 ControlBuilder* control) | |
461 : ControlScope(owner, 0), target_(target), control_(control) {} | |
462 | |
463 protected: | |
464 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE; | |
465 | |
466 private: | |
467 BreakableStatement* target_; | |
468 ControlBuilder* control_; | |
469 }; | |
470 | |
471 | |
472 // Control scope implementation for an IterationStatement. | |
473 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { | |
474 public: | |
475 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, | |
476 LoopBuilder* control, int stack_delta) | |
477 : ControlScope(owner, stack_delta), target_(target), control_(control) {} | |
478 | |
479 protected: | |
480 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE; | |
481 | |
482 private: | |
483 BreakableStatement* target_; | |
484 LoopBuilder* control_; | |
485 }; | |
486 | |
487 | |
488 // Control scope implementation for a TryCatchStatement. | |
489 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { | |
490 public: | |
491 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) | |
492 : ControlScope(owner, 0), control_(control) {} | |
493 | |
494 protected: | |
495 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE; | |
496 | |
497 private: | |
498 TryCatchBuilder* control_; | |
499 }; | |
500 | |
501 | |
502 // Control scope implementation for a TryFinallyStatement. | |
503 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { | |
504 public: | |
505 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, | |
506 TryFinallyBuilder* control) | |
507 : ControlScope(owner, 0), commands_(commands), control_(control) {} | |
508 | |
509 protected: | |
510 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE; | |
511 | |
512 private: | |
513 DeferredCommands* commands_; | |
514 TryFinallyBuilder* control_; | |
515 }; | |
516 | |
517 | |
428 // Scoped class tracking context objects created by the visitor. Represents | 518 // Scoped class tracking context objects created by the visitor. Represents |
429 // mutations of the context chain within the function body and allows to | 519 // mutations of the context chain within the function body and allows to |
430 // change the current {scope} and {context} during visitation. | 520 // change the current {scope} and {context} during visitation. |
431 class AstGraphBuilder::ContextScope BASE_EMBEDDED { | 521 class AstGraphBuilder::ContextScope BASE_EMBEDDED { |
432 public: | 522 public: |
433 ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context) | 523 ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context) |
434 : owner_(owner), | 524 : owner_(owner), |
435 next_(owner->execution_context()), | 525 next_(owner->execution_context()), |
436 outer_(owner->current_context()), | 526 outer_(owner->current_context()), |
437 scope_(scope) { | 527 scope_(scope) { |
(...skipping 18 matching lines...) Expand all Loading... | |
456 | 546 |
457 Scope* AstGraphBuilder::current_scope() const { | 547 Scope* AstGraphBuilder::current_scope() const { |
458 return execution_context_->scope(); | 548 return execution_context_->scope(); |
459 } | 549 } |
460 | 550 |
461 } // namespace compiler | 551 } // namespace compiler |
462 } // namespace internal | 552 } // namespace internal |
463 } // namespace v8 | 553 } // namespace v8 |
464 | 554 |
465 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ | 555 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ |
OLD | NEW |