// 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_
|