5 #ifndef V8_TORQUE_IMPLEMENTATION_VISITOR_H_ 6 #define V8_TORQUE_IMPLEMENTATION_VISITOR_H_ 10 #include "src/base/macros.h" 11 #include "src/torque/ast.h" 12 #include "src/torque/cfg.h" 13 #include "src/torque/file-visitor.h" 14 #include "src/torque/global-context.h" 15 #include "src/torque/types.h" 16 #include "src/torque/utils.h" 31 DCHECK(variable.IsOnStack());
33 result.variable_ = std::move(variable);
38 std::string description) {
40 result.temporary_ = std::move(temporary);
41 result.temporary_description_ = std::move(description);
46 result.eval_function_ = std::string{
"[]"};
47 result.assign_function_ = std::string{
"[]="};
48 result.call_arguments_ = {base, offset};
52 std::string fieldname) {
54 result.eval_function_ =
"." + fieldname;
55 result.assign_function_ =
"." + fieldname +
"=";
56 result.call_arguments_ = {
object};
60 bool IsConst()
const {
return temporary_.has_value(); }
62 bool IsVariableAccess()
const {
return variable_.has_value(); }
64 DCHECK(IsVariableAccess());
67 bool IsTemporary()
const {
return temporary_.has_value(); }
69 DCHECK(IsTemporary());
73 const std::string& temporary_description()
const {
74 DCHECK(IsTemporary());
75 return *temporary_description_;
78 bool IsCallAccess()
const {
79 bool is_call_access = eval_function_.has_value();
80 DCHECK_EQ(is_call_access, assign_function_.has_value());
81 return is_call_access;
84 DCHECK(IsCallAccess());
85 return call_arguments_;
87 const std::string& eval_function()
const {
88 DCHECK(IsCallAccess());
89 return *eval_function_;
91 const std::string& assign_function()
const {
92 DCHECK(IsCallAccess());
93 return *assign_function_;
114 return current_bindings_[name];
119 std::unordered_map<std::string, base::Optional<Binding<T>*>>
126 template <
class... Args>
128 : T(
std::forward<Args>(args)...),
131 previous_binding_(this) {
132 std::swap(previous_binding_, manager_->current_bindings_[name]);
134 ~Binding() { manager_->current_bindings_[name_] = previous_binding_; }
136 const std::string& name()
const {
return name_; }
137 SourcePosition declaration_position()
const {
return declaration_position_; }
140 BindingsManager<T>* manager_;
141 const std::string name_;
142 base::Optional<Binding*> previous_binding_;
143 SourcePosition declaration_position_ = CurrentSourcePosition::Get();
144 DISALLOW_COPY_AND_MOVE_AND_ASSIGN(Binding);
151 void Add(std::string name, T value) {
152 for (
const auto& binding : bindings_) {
153 if (binding->name() == name) {
155 "redeclaration of name \"", name,
156 "\" in the same block is illegal, previous declaration at: ",
157 binding->declaration_position());
160 bindings_.push_back(base::make_unique<
Binding<T>>(manager_, std::move(name),
164 std::vector<Binding<T>*> bindings()
const {
165 std::vector<Binding<T>*> result;
166 result.reserve(bindings_.size());
167 for (
auto& b : bindings_) {
168 result.push_back(b.get());
175 std::vector<std::unique_ptr<Binding<T>>> bindings_;
185 std::vector<const Type*> parameter_types;
188 std::vector<const Type*> parameter_types = {})
189 : block(block), parameter_types(std::move(parameter_types)) {}
194 std::vector<Binding<LocalLabel>*> labels;
197 bool IsCompatibleSignature(
const Signature& sig,
const TypeVector& types,
202 void GenerateBuiltinDefinitions(std::string& file_name);
220 StackScope scope(
this);
221 return scope.Yield(GenerateFetchFromLocation(GetLocationReference(expr)));
224 StackScope scope(
this);
225 return scope.Yield(GenerateFetchFromLocation(GetLocationReference(expr)));
228 void VisitAllDeclarables();
231 void Visit(
Macro* macro);
268 void BeginNamespaceFile(
Namespace* nspace);
269 void EndNamespaceFile(
Namespace* nspace);
271 void GenerateImplementation(
const std::string& dir,
Namespace* nspace);
273 DECLARE_CONTEXTUAL_VARIABLE(ValueBindingsManager,
275 DECLARE_CONTEXTUAL_VARIABLE(LabelBindingsManager,
277 DECLARE_CONTEXTUAL_VARIABLE(CurrentCallable,
Callable*);
283 ValueBindingsManager::Scope value_bindings_manager;
284 LabelBindingsManager::Scope label_bindings_manager;
308 base_ = visitor_->assembler().CurrentStack().AboveTop();
313 if (!result.IsOnStack()) {
314 if (!visitor_->assembler().CurrentBlockIsComplete()) {
315 visitor_->assembler().DropTo(base_);
319 DCHECK_LE(base_, result.stack_range().begin());
320 DCHECK_LE(result.stack_range().end(),
321 visitor_->assembler().CurrentStack().AboveTop());
322 visitor_->assembler().DropTo(result.stack_range().end());
323 visitor_->assembler().DeleteRange(
324 StackRange{base_, result.stack_range().begin()});
325 base_ = visitor_->assembler().CurrentStack().AboveTop();
326 return VisitResult(result.type(), visitor_->assembler().TopRange(
327 result.stack_range().Size()));
333 if (!visitor_->assembler().CurrentBlockIsComplete()) {
334 visitor_->assembler().DropTo(base_);
341 !visitor_->assembler().CurrentBlockIsComplete(),
342 base_ == visitor_->assembler().CurrentStack().AboveTop());
349 ImplementationVisitor* visitor_;
351 bool closed_ =
false;
354 class BreakContinueActivator {
356 BreakContinueActivator(Block* break_block, Block* continue_block)
357 : break_binding_{&LabelBindingsManager::Get(),
"_break",
358 LocalLabel{break_block}},
359 continue_binding_{&LabelBindingsManager::Get(),
"_continue",
360 LocalLabel{continue_block}} {}
363 Binding<LocalLabel> break_binding_;
364 Binding<LocalLabel> continue_binding_;
367 base::Optional<Binding<LocalValue>*> TryLookupLocalValue(
368 const std::string& name);
369 base::Optional<Binding<LocalLabel>*> TryLookupLabel(
const std::string& name);
370 Binding<LocalLabel>* LookupLabel(
const std::string& name);
371 Block* LookupSimpleLabel(
const std::string& name);
372 Callable* LookupCall(
const QualifiedName& name,
const Arguments& arguments,
373 const TypeVector& specialization_types);
375 const Type* GetCommonType(
const Type* left,
const Type* right);
377 VisitResult GenerateCopy(
const VisitResult& to_copy);
379 void GenerateAssignToLocation(
const LocationReference& reference,
380 const VisitResult& assignment_value);
382 VisitResult GenerateCall(
const QualifiedName& callable_name,
383 Arguments parameters,
384 const TypeVector& specialization_types = {},
385 bool tail_call =
false);
386 VisitResult GenerateCall(std::string callable_name, Arguments parameters,
387 const TypeVector& specialization_types = {},
388 bool tail_call =
false) {
389 return GenerateCall(QualifiedName(std::move(callable_name)),
390 std::move(parameters), specialization_types, tail_call);
392 VisitResult GeneratePointerCall(Expression* callee,
393 const Arguments& parameters,
bool tail_call);
395 void GenerateBranch(
const VisitResult& condition, Block* true_block,
398 void GenerateExpressionBranch(Expression* expression, Block* true_block,
401 void GenerateMacroFunctionDeclaration(std::ostream& o,
402 const std::string& macro_prefix,
404 void GenerateFunctionDeclaration(std::ostream& o,
405 const std::string& macro_prefix,
406 const std::string& name,
407 const Signature& signature,
408 const NameVector& parameter_names);
410 VisitResult GenerateImplicitConvert(
const Type* destination_type,
413 StackRange GenerateLabelGoto(LocalLabel* label,
414 base::Optional<StackRange> arguments = {});
416 std::vector<Binding<LocalLabel>*> LabelsFromIdentifiers(
417 const std::vector<std::string>& names);
419 StackRange LowerParameter(
const Type* type,
const std::string& parameter_name,
420 Stack<std::string>* lowered_parameters);
422 std::string ExternalLabelName(
const std::string& label_name);
423 std::string ExternalLabelParameterName(
const std::string& label_name,
425 std::string ExternalParameterName(
const std::string& name);
427 std::ostream& source_out() {
return CurrentNamespace()->source_stream(); }
429 std::ostream& header_out() {
return CurrentNamespace()->header_stream(); }
431 CfgAssembler& assembler() {
return *assembler_; }
433 void SetReturnValue(VisitResult return_value) {
434 DCHECK_IMPLIES(return_value_, *return_value_ == return_value);
435 return_value_ = std::move(return_value);
438 VisitResult GetAndClearReturnValue() {
439 VisitResult return_value = *return_value_;
440 return_value_ = base::nullopt;
444 base::Optional<CfgAssembler> assembler_;
445 base::Optional<VisitResult> return_value_;
452 #endif // V8_TORQUE_IMPLEMENTATION_VISITOR_H_