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_IMPLEMENTATION_VISITOR_H_ 6 #define V8_TORQUE_IMPLEMENTATION_VISITOR_H_ 7 8 #include <string> 9 10 #include "src/base/macros.h" 11 #include "src/torque/ast.h" 12 #include "src/torque/file-visitor.h" 13 #include "src/torque/global-context.h" 14 #include "src/torque/types.h" 15 #include "src/torque/utils.h" 16 17 namespace v8 { 18 namespace internal { 19 namespace torque { 20 21 struct LocationReference { LocationReferenceLocationReference22 LocationReference(Value* value, VisitResult base, VisitResult index) 23 : value(value), base(base), index(index) {} 24 Value* value; 25 VisitResult base; 26 VisitResult index; 27 }; 28 29 class ImplementationVisitor : public FileVisitor { 30 public: ImplementationVisitor(GlobalContext & global_context)31 explicit ImplementationVisitor(GlobalContext& global_context) 32 : FileVisitor(global_context), indent_(0), next_temp_(0) {} 33 Visit(Ast * ast)34 void Visit(Ast* ast) { Visit(ast->default_module()); } 35 36 VisitResult Visit(Expression* expr); 37 const Type* Visit(Statement* stmt); 38 void Visit(Declaration* decl); 39 40 VisitResult Visit(StructExpression* decl); 41 42 LocationReference GetLocationReference(LocationExpression* location); GetLocationReference(IdentifierExpression * expr)43 LocationReference GetLocationReference(IdentifierExpression* expr) { 44 return LocationReference(declarations()->LookupValue(expr->name), {}, {}); 45 } 46 LocationReference GetLocationReference(FieldAccessExpression* expr); GetLocationReference(ElementAccessExpression * expr)47 LocationReference GetLocationReference(ElementAccessExpression* expr) { 48 return LocationReference({}, Visit(expr->array), Visit(expr->index)); 49 } 50 51 std::string RValueFlattenStructs(VisitResult result); 52 GenerateFetchFromLocation(LocationReference reference)53 VisitResult GenerateFetchFromLocation(LocationReference reference) { 54 const Value* value = reference.value; 55 return VisitResult(value->type(), value); 56 } 57 VisitResult GenerateFetchFromLocation(LocationExpression* location, 58 LocationReference reference); GenerateFetchFromLocation(IdentifierExpression * expr,LocationReference reference)59 VisitResult GenerateFetchFromLocation(IdentifierExpression* expr, 60 LocationReference reference) { 61 return GenerateFetchFromLocation(reference); 62 } 63 VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr, 64 LocationReference reference); GenerateFetchFromLocation(ElementAccessExpression * expr,LocationReference reference)65 VisitResult GenerateFetchFromLocation(ElementAccessExpression* expr, 66 LocationReference reference) { 67 Arguments arguments; 68 arguments.parameters = {reference.base, reference.index}; 69 return GenerateCall("[]", arguments); 70 } 71 72 VisitResult GetBuiltinCode(Builtin* builtin); 73 74 VisitResult Visit(IdentifierExpression* expr); Visit(FieldAccessExpression * expr)75 VisitResult Visit(FieldAccessExpression* expr) { 76 return GenerateFetchFromLocation(expr, GetLocationReference(expr)); 77 } Visit(ElementAccessExpression * expr)78 VisitResult Visit(ElementAccessExpression* expr) { 79 return GenerateFetchFromLocation(expr, GetLocationReference(expr)); 80 } 81 82 void Visit(ModuleDeclaration* decl); Visit(DefaultModuleDeclaration * decl)83 void Visit(DefaultModuleDeclaration* decl) { 84 Visit(implicit_cast<ModuleDeclaration*>(decl)); 85 } Visit(ExplicitModuleDeclaration * decl)86 void Visit(ExplicitModuleDeclaration* decl) { 87 Visit(implicit_cast<ModuleDeclaration*>(decl)); 88 } Visit(TypeDeclaration * decl)89 void Visit(TypeDeclaration* decl) {} Visit(TypeAliasDeclaration * decl)90 void Visit(TypeAliasDeclaration* decl) {} Visit(ExternConstDeclaration * decl)91 void Visit(ExternConstDeclaration* decl) {} 92 void Visit(StructDeclaration* decl); 93 void Visit(StandardDeclaration* decl); Visit(GenericDeclaration * decl)94 void Visit(GenericDeclaration* decl) {} 95 void Visit(SpecializationDeclaration* decl); 96 97 void Visit(TorqueMacroDeclaration* decl, const Signature& signature, 98 Statement* body); 99 void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature, 100 Statement* body); Visit(ExternalMacroDeclaration * decl,const Signature & signature,Statement * body)101 void Visit(ExternalMacroDeclaration* decl, const Signature& signature, 102 Statement* body) {} Visit(ExternalBuiltinDeclaration * decl,const Signature & signature,Statement * body)103 void Visit(ExternalBuiltinDeclaration* decl, const Signature& signature, 104 Statement* body) {} Visit(ExternalRuntimeDeclaration * decl,const Signature & signature,Statement * body)105 void Visit(ExternalRuntimeDeclaration* decl, const Signature& signature, 106 Statement* body) {} 107 void Visit(CallableNode* decl, const Signature& signature, Statement* body); 108 void Visit(ConstDeclaration* decl); 109 110 VisitResult Visit(CallExpression* expr, bool is_tail = false); 111 const Type* Visit(TailCallStatement* stmt); 112 113 VisitResult Visit(ConditionalExpression* expr); 114 115 VisitResult Visit(LogicalOrExpression* expr); 116 VisitResult Visit(LogicalAndExpression* expr); 117 118 VisitResult Visit(IncrementDecrementExpression* expr); 119 VisitResult Visit(AssignmentExpression* expr); 120 VisitResult Visit(StringLiteralExpression* expr); 121 VisitResult Visit(NumberLiteralExpression* expr); 122 VisitResult Visit(AssumeTypeImpossibleExpression* expr); 123 124 const Type* Visit(TryLabelStatement* stmt); 125 const Type* Visit(ReturnStatement* stmt); 126 const Type* Visit(GotoStatement* stmt); 127 const Type* Visit(IfStatement* stmt); 128 const Type* Visit(WhileStatement* stmt); 129 const Type* Visit(BreakStatement* stmt); 130 const Type* Visit(ContinueStatement* stmt); 131 const Type* Visit(ForLoopStatement* stmt); 132 const Type* Visit(VarDeclarationStatement* stmt); 133 const Type* Visit(ForOfLoopStatement* stmt); 134 const Type* Visit(BlockStatement* block); 135 const Type* Visit(ExpressionStatement* stmt); 136 const Type* Visit(DebugStatement* stmt); 137 const Type* Visit(AssertStatement* stmt); 138 139 void BeginModuleFile(Module* module); 140 void EndModuleFile(Module* module); 141 142 void GenerateImplementation(const std::string& dir, Module* module); 143 144 private: 145 std::string GetBaseAssemblerName(Module* module); 146 147 std::string GetDSLAssemblerName(Module* module); 148 149 void GenerateIndent(); 150 151 class ScopedIndent { 152 public: 153 explicit ScopedIndent(ImplementationVisitor* visitor, bool new_lines = true) new_lines_(new_lines)154 : new_lines_(new_lines), visitor_(visitor) { 155 if (new_lines) visitor->GenerateIndent(); 156 visitor->source_out() << "{"; 157 if (new_lines) visitor->source_out() << "\n"; 158 visitor->indent_++; 159 } ~ScopedIndent()160 ~ScopedIndent() { 161 visitor_->indent_--; 162 visitor_->GenerateIndent(); 163 visitor_->source_out() << "}"; 164 if (new_lines_) visitor_->source_out() << "\n"; 165 } 166 167 private: 168 bool new_lines_; 169 ImplementationVisitor* visitor_; 170 }; 171 172 Callable* LookupCall(const std::string& name, const Arguments& arguments, 173 const TypeVector& specialization_types); 174 175 bool GenerateChangedVarFromControlSplit(const Variable* v, bool first = true); 176 177 void GetFlattenedStructsVars(const Variable* base, 178 std::set<const Variable*>* vars); 179 180 void GenerateChangedVarsFromControlSplit(AstNode* node); 181 182 const Type* GetCommonType(const Type* left, const Type* right); 183 184 VisitResult GenerateCopy(const VisitResult& to_copy); 185 186 void GenerateAssignToVariable(Variable* var, VisitResult value); 187 188 void GenerateAssignToLocation(LocationExpression* location, 189 const LocationReference& reference, 190 VisitResult assignment_value); 191 192 void GenerateVariableDeclaration(const Variable* var); 193 194 Variable* GeneratePredeclaredVariableDeclaration( 195 const std::string& name, 196 const base::Optional<VisitResult>& initialization); 197 198 Variable* GenerateVariableDeclaration( 199 AstNode* node, const std::string& name, bool is_const, 200 const base::Optional<const Type*>& type, 201 const base::Optional<VisitResult>& initialization = {}); 202 203 void GenerateParameter(const std::string& parameter_name); 204 205 void GenerateParameterList(const NameVector& list, size_t first = 0); 206 207 VisitResult GenerateCall(const std::string& callable_name, 208 Arguments parameters, 209 const TypeVector& specialization_types = {}, 210 bool tail_call = false); 211 VisitResult GeneratePointerCall(Expression* callee, 212 const Arguments& parameters, bool tail_call); 213 214 bool GenerateLabeledStatementBlocks( 215 const std::vector<Statement*>& blocks, 216 const std::vector<Label*>& statement_labels, Label* merge_label); 217 218 void GenerateBranch(const VisitResult& condition, Label* true_label, 219 Label* false_label); 220 221 bool GenerateExpressionBranch(Expression* expression, 222 const std::vector<Label*>& statement_labels, 223 const std::vector<Statement*>& statement_blocks, 224 Label* merge_label); 225 226 void GenerateMacroFunctionDeclaration(std::ostream& o, 227 const std::string& macro_prefix, 228 Macro* macro); 229 void GenerateFunctionDeclaration(std::ostream& o, 230 const std::string& macro_prefix, 231 const std::string& name, 232 const Signature& signature, 233 const NameVector& parameter_names); 234 235 VisitResult GenerateImplicitConvert(const Type* destination_type, 236 VisitResult source); 237 Specialize(const SpecializationKey & key,CallableNode * callable,const CallableNodeSignature * signature,Statement * body)238 void Specialize(const SpecializationKey& key, CallableNode* callable, 239 const CallableNodeSignature* signature, 240 Statement* body) override { 241 Declarations::GenericScopeActivator scope(declarations(), key); 242 Visit(callable, MakeSignature(signature), body); 243 } 244 245 std::string NewTempVariable(); 246 247 std::string GenerateNewTempVariable(const Type* type); 248 249 void GenerateLabelDefinition(Label* label, AstNode* node = nullptr); 250 251 void GenerateLabelBind(Label* label); 252 253 void GenerateLabelGoto(Label* label); 254 255 std::vector<Label*> LabelsFromIdentifiers( 256 const std::vector<std::string>& names); 257 source_out()258 std::ostream& source_out() { return module_->source_stream(); } 259 header_out()260 std::ostream& header_out() { return module_->header_stream(); } 261 262 size_t indent_; 263 int32_t next_temp_; 264 }; 265 266 } // namespace torque 267 } // namespace internal 268 } // namespace v8 269 270 #endif // V8_TORQUE_IMPLEMENTATION_VISITOR_H_ 271