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