1 // Copyright 2017 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_TORQUE_GLOBAL_CONTEXT_H_ 6 #define V8_TORQUE_GLOBAL_CONTEXT_H_ 7 8 #include "src/torque/declarable.h" 9 #include "src/torque/declarations.h" 10 #include "src/torque/scope.h" 11 #include "src/torque/type-oracle.h" 12 13 namespace v8 { 14 namespace internal { 15 namespace torque { 16 17 class GlobalContext; 18 class Scope; 19 class TypeOracle; 20 class Builtin; 21 class Label; 22 23 class Module { 24 public: Module(const std::string & name,bool is_default)25 explicit Module(const std::string& name, bool is_default) 26 : name_(name), is_default_(is_default) {} name()27 const std::string& name() const { return name_; } IsDefault()28 bool IsDefault() const { return is_default_; } source_stream()29 std::ostream& source_stream() { return source_stream_; } header_stream()30 std::ostream& header_stream() { return header_stream_; } source()31 std::string source() { return source_stream_.str(); } header()32 std::string header() { return header_stream_.str(); } 33 34 private: 35 std::string name_; 36 bool is_default_; 37 std::stringstream header_stream_; 38 std::stringstream source_stream_; 39 }; 40 41 class GlobalContext { 42 public: GlobalContext(Ast ast)43 explicit GlobalContext(Ast ast) 44 : verbose_(false), 45 next_label_number_(0), 46 default_module_(GetModule("base", true)), 47 ast_(std::move(ast)) {} GetDefaultModule()48 Module* GetDefaultModule() { return default_module_; } 49 Module* GetModule(const std::string& name, bool is_default = false) { 50 auto i = modules_.find(name); 51 if (i != modules_.end()) { 52 return i->second.get(); 53 } 54 Module* module = new Module(name, is_default); 55 modules_[name] = std::unique_ptr<Module>(module); 56 return module; 57 } 58 GetNextLabelNumber()59 int GetNextLabelNumber() { return next_label_number_++; } 60 GetModules()61 const std::map<std::string, std::unique_ptr<Module>>& GetModules() const { 62 return modules_; 63 } 64 SetVerbose()65 void SetVerbose() { verbose_ = true; } verbose()66 bool verbose() const { return verbose_; } 67 AddControlSplitChangedVariables(const AstNode * node,const TypeVector & specialization_types,const std::set<const Variable * > & vars)68 void AddControlSplitChangedVariables(const AstNode* node, 69 const TypeVector& specialization_types, 70 const std::set<const Variable*>& vars) { 71 auto key = std::make_pair(node, specialization_types); 72 control_split_changed_variables_[key] = vars; 73 } 74 GetControlSplitChangedVariables(const AstNode * node,const TypeVector & specialization_types)75 const std::set<const Variable*>& GetControlSplitChangedVariables( 76 const AstNode* node, const TypeVector& specialization_types) { 77 auto key = std::make_pair(node, specialization_types); 78 assert(control_split_changed_variables_.find(key) != 79 control_split_changed_variables_.end()); 80 return control_split_changed_variables_.find(key)->second; 81 } 82 MarkVariableChanged(const AstNode * node,const TypeVector & specialization_types,Variable * var)83 void MarkVariableChanged(const AstNode* node, 84 const TypeVector& specialization_types, 85 Variable* var) { 86 auto key = std::make_pair(node, specialization_types); 87 control_split_changed_variables_[key].insert(var); 88 } 89 90 friend class CurrentCallableActivator; 91 friend class BreakContinueActivator; 92 GetCurrentCallable()93 Callable* GetCurrentCallable() const { return current_callable_; } GetCurrentBreak()94 Label* GetCurrentBreak() const { return break_continue_stack_.back().first; } GetCurrentContinue()95 Label* GetCurrentContinue() const { 96 return break_continue_stack_.back().second; 97 } 98 declarations()99 Declarations* declarations() { return &declarations_; } ast()100 Ast* ast() { return &ast_; } 101 102 private: 103 bool verbose_; 104 int next_label_number_; 105 Declarations declarations_; 106 Callable* current_callable_; 107 std::vector<std::pair<Label*, Label*>> break_continue_stack_; 108 std::map<std::string, std::unique_ptr<Module>> modules_; 109 Module* default_module_; 110 std::map<std::pair<const AstNode*, TypeVector>, std::set<const Variable*>> 111 control_split_changed_variables_; 112 Ast ast_; 113 }; 114 115 class CurrentCallableActivator { 116 public: CurrentCallableActivator(GlobalContext & context,Callable * callable,CallableNode * decl)117 CurrentCallableActivator(GlobalContext& context, Callable* callable, 118 CallableNode* decl) 119 : context_(context), scope_activator_(context.declarations(), decl) { 120 remembered_callable_ = context_.current_callable_; 121 context_.current_callable_ = callable; 122 } ~CurrentCallableActivator()123 ~CurrentCallableActivator() { 124 context_.current_callable_ = remembered_callable_; 125 } 126 127 private: 128 GlobalContext& context_; 129 Callable* remembered_callable_; 130 Declarations::NodeScopeActivator scope_activator_; 131 }; 132 133 class BreakContinueActivator { 134 public: BreakContinueActivator(GlobalContext & context,Label * break_label,Label * continue_label)135 BreakContinueActivator(GlobalContext& context, Label* break_label, 136 Label* continue_label) 137 : context_(context) { 138 context_.break_continue_stack_.push_back({break_label, continue_label}); 139 } ~BreakContinueActivator()140 ~BreakContinueActivator() { context_.break_continue_stack_.pop_back(); } 141 142 private: 143 GlobalContext& context_; 144 }; 145 146 } // namespace torque 147 } // namespace internal 148 } // namespace v8 149 150 #endif // V8_TORQUE_GLOBAL_CONTEXT_H_ 151