| // Copyright 2017 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_TORQUE_IMPLEMENTATION_VISITOR_H_ |
| #define V8_TORQUE_IMPLEMENTATION_VISITOR_H_ |
| |
| #include <string> |
| |
| #include "src/base/macros.h" |
| #include "src/torque/ast.h" |
| #include "src/torque/file-visitor.h" |
| #include "src/torque/global-context.h" |
| #include "src/torque/types.h" |
| #include "src/torque/utils.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace torque { |
| |
| struct LocationReference { |
| LocationReference(Value* value, VisitResult base, VisitResult index) |
| : value(value), base(base), index(index) {} |
| Value* value; |
| VisitResult base; |
| VisitResult index; |
| }; |
| |
| class ImplementationVisitor : public FileVisitor { |
| public: |
| explicit ImplementationVisitor(GlobalContext& global_context) |
| : FileVisitor(global_context), indent_(0), next_temp_(0) {} |
| |
| void Visit(Ast* ast) { Visit(ast->default_module()); } |
| |
| VisitResult Visit(Expression* expr); |
| const Type* Visit(Statement* stmt); |
| void Visit(Declaration* decl); |
| |
| VisitResult Visit(StructExpression* decl); |
| |
| LocationReference GetLocationReference(LocationExpression* location); |
| LocationReference GetLocationReference(IdentifierExpression* expr) { |
| return LocationReference(declarations()->LookupValue(expr->name), {}, {}); |
| } |
| LocationReference GetLocationReference(FieldAccessExpression* expr); |
| LocationReference GetLocationReference(ElementAccessExpression* expr) { |
| return LocationReference({}, Visit(expr->array), Visit(expr->index)); |
| } |
| |
| std::string RValueFlattenStructs(VisitResult result); |
| |
| VisitResult GenerateFetchFromLocation(LocationReference reference) { |
| const Value* value = reference.value; |
| return VisitResult(value->type(), value); |
| } |
| VisitResult GenerateFetchFromLocation(LocationExpression* location, |
| LocationReference reference); |
| VisitResult GenerateFetchFromLocation(IdentifierExpression* expr, |
| LocationReference reference) { |
| return GenerateFetchFromLocation(reference); |
| } |
| VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr, |
| LocationReference reference); |
| VisitResult GenerateFetchFromLocation(ElementAccessExpression* expr, |
| LocationReference reference) { |
| Arguments arguments; |
| arguments.parameters = {reference.base, reference.index}; |
| return GenerateCall("[]", arguments); |
| } |
| |
| VisitResult GetBuiltinCode(Builtin* builtin); |
| |
| VisitResult Visit(IdentifierExpression* expr); |
| VisitResult Visit(FieldAccessExpression* expr) { |
| return GenerateFetchFromLocation(expr, GetLocationReference(expr)); |
| } |
| VisitResult Visit(ElementAccessExpression* expr) { |
| return GenerateFetchFromLocation(expr, GetLocationReference(expr)); |
| } |
| |
| void Visit(ModuleDeclaration* decl); |
| void Visit(DefaultModuleDeclaration* decl) { |
| Visit(implicit_cast<ModuleDeclaration*>(decl)); |
| } |
| void Visit(ExplicitModuleDeclaration* decl) { |
| Visit(implicit_cast<ModuleDeclaration*>(decl)); |
| } |
| void Visit(TypeDeclaration* decl) {} |
| void Visit(TypeAliasDeclaration* decl) {} |
| void Visit(ExternConstDeclaration* decl) {} |
| void Visit(StructDeclaration* decl); |
| void Visit(StandardDeclaration* decl); |
| void Visit(GenericDeclaration* decl) {} |
| void Visit(SpecializationDeclaration* decl); |
| |
| void Visit(TorqueMacroDeclaration* decl, const Signature& signature, |
| Statement* body); |
| void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature, |
| Statement* body); |
| void Visit(ExternalMacroDeclaration* decl, const Signature& signature, |
| Statement* body) {} |
| void Visit(ExternalBuiltinDeclaration* decl, const Signature& signature, |
| Statement* body) {} |
| void Visit(ExternalRuntimeDeclaration* decl, const Signature& signature, |
| Statement* body) {} |
| void Visit(CallableNode* decl, const Signature& signature, Statement* body); |
| void Visit(ConstDeclaration* decl); |
| |
| VisitResult Visit(CallExpression* expr, bool is_tail = false); |
| const Type* Visit(TailCallStatement* stmt); |
| |
| VisitResult Visit(ConditionalExpression* expr); |
| |
| VisitResult Visit(LogicalOrExpression* expr); |
| VisitResult Visit(LogicalAndExpression* expr); |
| |
| VisitResult Visit(IncrementDecrementExpression* expr); |
| VisitResult Visit(AssignmentExpression* expr); |
| VisitResult Visit(StringLiteralExpression* expr); |
| VisitResult Visit(NumberLiteralExpression* expr); |
| VisitResult Visit(AssumeTypeImpossibleExpression* expr); |
| |
| const Type* Visit(TryLabelStatement* stmt); |
| const Type* Visit(ReturnStatement* stmt); |
| const Type* Visit(GotoStatement* stmt); |
| const Type* Visit(IfStatement* stmt); |
| const Type* Visit(WhileStatement* stmt); |
| const Type* Visit(BreakStatement* stmt); |
| const Type* Visit(ContinueStatement* stmt); |
| const Type* Visit(ForLoopStatement* stmt); |
| const Type* Visit(VarDeclarationStatement* stmt); |
| const Type* Visit(ForOfLoopStatement* stmt); |
| const Type* Visit(BlockStatement* block); |
| const Type* Visit(ExpressionStatement* stmt); |
| const Type* Visit(DebugStatement* stmt); |
| const Type* Visit(AssertStatement* stmt); |
| |
| void BeginModuleFile(Module* module); |
| void EndModuleFile(Module* module); |
| |
| void GenerateImplementation(const std::string& dir, Module* module); |
| |
| private: |
| std::string GetBaseAssemblerName(Module* module); |
| |
| std::string GetDSLAssemblerName(Module* module); |
| |
| void GenerateIndent(); |
| |
| class ScopedIndent { |
| public: |
| explicit ScopedIndent(ImplementationVisitor* visitor, bool new_lines = true) |
| : new_lines_(new_lines), visitor_(visitor) { |
| if (new_lines) visitor->GenerateIndent(); |
| visitor->source_out() << "{"; |
| if (new_lines) visitor->source_out() << "\n"; |
| visitor->indent_++; |
| } |
| ~ScopedIndent() { |
| visitor_->indent_--; |
| visitor_->GenerateIndent(); |
| visitor_->source_out() << "}"; |
| if (new_lines_) visitor_->source_out() << "\n"; |
| } |
| |
| private: |
| bool new_lines_; |
| ImplementationVisitor* visitor_; |
| }; |
| |
| Callable* LookupCall(const std::string& name, const Arguments& arguments, |
| const TypeVector& specialization_types); |
| |
| bool GenerateChangedVarFromControlSplit(const Variable* v, bool first = true); |
| |
| void GetFlattenedStructsVars(const Variable* base, |
| std::set<const Variable*>* vars); |
| |
| void GenerateChangedVarsFromControlSplit(AstNode* node); |
| |
| const Type* GetCommonType(const Type* left, const Type* right); |
| |
| VisitResult GenerateCopy(const VisitResult& to_copy); |
| |
| void GenerateAssignToVariable(Variable* var, VisitResult value); |
| |
| void GenerateAssignToLocation(LocationExpression* location, |
| const LocationReference& reference, |
| VisitResult assignment_value); |
| |
| void GenerateVariableDeclaration(const Variable* var); |
| |
| Variable* GeneratePredeclaredVariableDeclaration( |
| const std::string& name, |
| const base::Optional<VisitResult>& initialization); |
| |
| Variable* GenerateVariableDeclaration( |
| AstNode* node, const std::string& name, bool is_const, |
| const base::Optional<const Type*>& type, |
| const base::Optional<VisitResult>& initialization = {}); |
| |
| void GenerateParameter(const std::string& parameter_name); |
| |
| void GenerateParameterList(const NameVector& list, size_t first = 0); |
| |
| VisitResult GenerateCall(const std::string& callable_name, |
| Arguments parameters, |
| const TypeVector& specialization_types = {}, |
| bool tail_call = false); |
| VisitResult GeneratePointerCall(Expression* callee, |
| const Arguments& parameters, bool tail_call); |
| |
| bool GenerateLabeledStatementBlocks( |
| const std::vector<Statement*>& blocks, |
| const std::vector<Label*>& statement_labels, Label* merge_label); |
| |
| void GenerateBranch(const VisitResult& condition, Label* true_label, |
| Label* false_label); |
| |
| bool GenerateExpressionBranch(Expression* expression, |
| const std::vector<Label*>& statement_labels, |
| const std::vector<Statement*>& statement_blocks, |
| Label* merge_label); |
| |
| void GenerateMacroFunctionDeclaration(std::ostream& o, |
| const std::string& macro_prefix, |
| Macro* macro); |
| void GenerateFunctionDeclaration(std::ostream& o, |
| const std::string& macro_prefix, |
| const std::string& name, |
| const Signature& signature, |
| const NameVector& parameter_names); |
| |
| VisitResult GenerateImplicitConvert(const Type* destination_type, |
| VisitResult source); |
| |
| void Specialize(const SpecializationKey& key, CallableNode* callable, |
| const CallableNodeSignature* signature, |
| Statement* body) override { |
| Declarations::GenericScopeActivator scope(declarations(), key); |
| Visit(callable, MakeSignature(signature), body); |
| } |
| |
| std::string NewTempVariable(); |
| |
| std::string GenerateNewTempVariable(const Type* type); |
| |
| void GenerateLabelDefinition(Label* label, AstNode* node = nullptr); |
| |
| void GenerateLabelBind(Label* label); |
| |
| void GenerateLabelGoto(Label* label); |
| |
| std::vector<Label*> LabelsFromIdentifiers( |
| const std::vector<std::string>& names); |
| |
| std::ostream& source_out() { return module_->source_stream(); } |
| |
| std::ostream& header_out() { return module_->header_stream(); } |
| |
| size_t indent_; |
| int32_t next_temp_; |
| }; |
| |
| } // namespace torque |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_TORQUE_IMPLEMENTATION_VISITOR_H_ |