LCOV - code coverage report
Current view: top level - src/torque - implementation-visitor.h (source / functions) Hit Total Coverage
Test: app.info Lines: 93 94 98.9 %
Date: 2019-04-17 Functions: 32 32 100.0 %

          Line data    Source code
       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/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"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : namespace torque {
      21             : 
      22             : // LocationReference is the representation of an l-value, so a value that might
      23             : // allow for assignment. For uniformity, this class can also represent
      24             : // unassignable temporaries. Assignable values fall in two categories:
      25             : //   - stack ranges that represent mutable variables, including structs.
      26             : //   - field or element access expressions that generate operator calls.
      27       22578 : class LocationReference {
      28             :  public:
      29             :   // An assignable stack range.
      30             :   static LocationReference VariableAccess(VisitResult variable) {
      31             :     DCHECK(variable.IsOnStack());
      32             :     LocationReference result;
      33             :     result.variable_ = std::move(variable);
      34             :     return result;
      35             :   }
      36             :   // An unassignable value. {description} is only used for error messages.
      37        6417 :   static LocationReference Temporary(VisitResult temporary,
      38             :                                      std::string description) {
      39             :     LocationReference result;
      40             :     result.temporary_ = std::move(temporary);
      41             :     result.temporary_description_ = std::move(description);
      42        6417 :     return result;
      43             :   }
      44             :   // A heap reference, that is, a tagged value and an offset to encode an inner
      45             :   // pointer.
      46             :   static LocationReference HeapReference(VisitResult heap_reference) {
      47             :     LocationReference result;
      48             :     DCHECK(heap_reference.type()->IsReferenceType());
      49             :     result.heap_reference_ = std::move(heap_reference);
      50             :     return result;
      51             :   }
      52         155 :   static LocationReference ArrayAccess(VisitResult base, VisitResult offset) {
      53             :     LocationReference result;
      54         310 :     result.eval_function_ = std::string{"[]"};
      55         310 :     result.assign_function_ = std::string{"[]="};
      56         310 :     result.call_arguments_ = {base, offset};
      57         155 :     return result;
      58             :   }
      59         100 :   static LocationReference FieldAccess(VisitResult object,
      60             :                                        std::string fieldname) {
      61             :     LocationReference result;
      62         200 :     result.eval_function_ = "." + fieldname;
      63         300 :     result.assign_function_ = "." + fieldname + "=";
      64         200 :     result.call_arguments_ = {object};
      65             :     result.index_field_ = base::nullopt;
      66         100 :     return result;
      67             :   }
      68         128 :   static LocationReference IndexedFieldIndexedAccess(
      69             :       const LocationReference& indexed_field, VisitResult index) {
      70             :     LocationReference result;
      71             :     DCHECK(indexed_field.IsIndexedFieldAccess());
      72             :     std::string fieldname = *indexed_field.index_field_;
      73         384 :     result.eval_function_ = "." + fieldname + "[]";
      74         384 :     result.assign_function_ = "." + fieldname + "[]=";
      75             :     result.call_arguments_ = indexed_field.call_arguments_;
      76         128 :     result.call_arguments_.push_back(index);
      77             :     result.index_field_ = fieldname;
      78         128 :     return result;
      79             :   }
      80         128 :   static LocationReference IndexedFieldAccess(VisitResult object,
      81             :                                               std::string fieldname) {
      82             :     LocationReference result;
      83         256 :     result.call_arguments_ = {object};
      84             :     result.index_field_ = fieldname;
      85         128 :     return result;
      86             :   }
      87             : 
      88             :   bool IsConst() const { return temporary_.has_value(); }
      89             : 
      90             :   bool IsVariableAccess() const { return variable_.has_value(); }
      91             :   const VisitResult& variable() const {
      92             :     DCHECK(IsVariableAccess());
      93             :     return *variable_;
      94             :   }
      95             :   bool IsTemporary() const { return temporary_.has_value(); }
      96             :   const VisitResult& temporary() const {
      97             :     DCHECK(IsTemporary());
      98             :     return *temporary_;
      99             :   }
     100             :   bool IsHeapReference() const { return heap_reference_.has_value(); }
     101             :   const VisitResult& heap_reference() const {
     102             :     DCHECK(IsHeapReference());
     103             :     return *heap_reference_;
     104             :   }
     105             : 
     106             :   const Type* ReferencedType() const {
     107        1905 :     if (IsHeapReference()) {
     108             :       return ReferenceType::cast(heap_reference().type())->referenced_type();
     109             :     }
     110             :     return GetVisitResult().type();
     111             :   }
     112             : 
     113             :   const VisitResult& GetVisitResult() const {
     114         669 :     if (IsVariableAccess()) return variable();
     115             :     DCHECK(IsTemporary());
     116             :     return temporary();
     117             :   }
     118             : 
     119             :   // For error reporting.
     120             :   const std::string& temporary_description() const {
     121             :     DCHECK(IsTemporary());
     122             :     return *temporary_description_;
     123             :   }
     124             : 
     125             :   bool IsArrayField() const { return index_field_.has_value(); }
     126             :   bool IsIndexedFieldAccess() const {
     127        1019 :     return IsArrayField() && !IsCallAccess();
     128             :   }
     129             :   bool IsIndexedFieldIndexedAccess() const {
     130             :     return IsArrayField() && IsCallAccess();
     131             :   }
     132             :   bool IsCallAccess() const {
     133             :     bool is_call_access = eval_function_.has_value();
     134             :     DCHECK_EQ(is_call_access, assign_function_.has_value());
     135             :     return is_call_access;
     136             :   }
     137             :   const VisitResultVector& call_arguments() const {
     138             :     DCHECK(IsCallAccess());
     139             :     return call_arguments_;
     140             :   }
     141             :   const std::string& eval_function() const {
     142             :     DCHECK(IsCallAccess());
     143             :     return *eval_function_;
     144             :   }
     145             :   const std::string& assign_function() const {
     146             :     DCHECK(IsCallAccess());
     147             :     return *assign_function_;
     148             :   }
     149             : 
     150             :  private:
     151             :   base::Optional<VisitResult> variable_;
     152             :   base::Optional<VisitResult> temporary_;
     153             :   base::Optional<std::string> temporary_description_;
     154             :   base::Optional<VisitResult> heap_reference_;
     155             :   base::Optional<std::string> eval_function_;
     156             :   base::Optional<std::string> assign_function_;
     157             :   VisitResultVector call_arguments_;
     158             :   base::Optional<std::string> index_field_;
     159             : 
     160             :   LocationReference() = default;
     161             : };
     162             : 
     163          66 : struct InitializerResults {
     164             :   std::vector<Identifier*> names;
     165             :   NameValueMap field_value_map;
     166             : };
     167             : 
     168             : template <class T>
     169             : class Binding;
     170             : 
     171             : template <class T>
     172        2892 : class BindingsManager {
     173             :  public:
     174             :   base::Optional<Binding<T>*> TryLookup(const std::string& name) {
     175       18849 :     return current_bindings_[name];
     176             :   }
     177             : 
     178             :  private:
     179             :   friend class Binding<T>;
     180             :   std::unordered_map<std::string, base::Optional<Binding<T>*>>
     181             :       current_bindings_;
     182             : };
     183             : 
     184             : template <class T>
     185             : class Binding : public T {
     186             :  public:
     187             :   template <class... Args>
     188        8068 :   Binding(BindingsManager<T>* manager, const std::string& name, Args&&... args)
     189             :       : T(std::forward<Args>(args)...),
     190             :         manager_(manager),
     191             :         name_(name),
     192       16136 :         previous_binding_(this) {
     193       16136 :     std::swap(previous_binding_, manager_->current_bindings_[name]);
     194        8068 :   }
     195             :   template <class... Args>
     196             :   Binding(BindingsManager<T>* manager, const Identifier* name, Args&&... args)
     197        4121 :       : Binding(manager, name->value, std::forward<Args>(args)...) {
     198        4121 :     declaration_position_ = name->pos;
     199             :   }
     200       16136 :   ~Binding() { manager_->current_bindings_[name_] = previous_binding_; }
     201             : 
     202        5028 :   const std::string& name() const { return name_; }
     203           1 :   SourcePosition declaration_position() const { return declaration_position_; }
     204             : 
     205             :  private:
     206             :   BindingsManager<T>* manager_;
     207             :   const std::string name_;
     208             :   base::Optional<Binding*> previous_binding_;
     209             :   SourcePosition declaration_position_ = CurrentSourcePosition::Get();
     210             :   DISALLOW_COPY_AND_ASSIGN(Binding);
     211             : };
     212             : 
     213             : template <class T>
     214        3634 : class BlockBindings {
     215             :  public:
     216        4863 :   explicit BlockBindings(BindingsManager<T>* manager) : manager_(manager) {}
     217         401 :   void Add(std::string name, T value) {
     218         401 :     ReportErrorIfAlreadyBound(name);
     219         802 :     bindings_.push_back(base::make_unique<Binding<T>>(manager_, std::move(name),
     220             :                                                       std::move(value)));
     221         401 :   }
     222             : 
     223        4121 :   void Add(const Identifier* name, T value) {
     224        4121 :     ReportErrorIfAlreadyBound(name->value);
     225        8242 :     bindings_.push_back(
     226             :         base::make_unique<Binding<T>>(manager_, name, std::move(value)));
     227        4121 :   }
     228             : 
     229             :   std::vector<Binding<T>*> bindings() const {
     230             :     std::vector<Binding<T>*> result;
     231             :     result.reserve(bindings_.size());
     232             :     for (auto& b : bindings_) {
     233             :       result.push_back(b.get());
     234             :     }
     235             :     return result;
     236             :   }
     237             : 
     238             :  private:
     239        4522 :   void ReportErrorIfAlreadyBound(const std::string& name) {
     240        9550 :     for (const auto& binding : bindings_) {
     241        5028 :       if (binding->name() == name) {
     242           0 :         ReportError(
     243             :             "redeclaration of name \"", name,
     244             :             "\" in the same block is illegal, previous declaration at: ",
     245             :             binding->declaration_position());
     246             :       }
     247             :     }
     248        4522 :   }
     249             : 
     250             :   BindingsManager<T>* manager_;
     251             :   std::vector<std::unique_ptr<Binding<T>>> bindings_;
     252             : };
     253             : 
     254       13329 : struct LocalValue {
     255             :   bool is_const;
     256             :   VisitResult value;
     257             : };
     258             : 
     259       11169 : struct LocalLabel {
     260             :   Block* block;
     261             :   std::vector<const Type*> parameter_types;
     262             : 
     263             :   explicit LocalLabel(Block* block,
     264             :                       std::vector<const Type*> parameter_types = {})
     265        3723 :       : block(block), parameter_types(std::move(parameter_types)) {}
     266             : };
     267             : 
     268       51922 : struct Arguments {
     269             :   VisitResultVector parameters;
     270             :   std::vector<Binding<LocalLabel>*> labels;
     271             : };
     272             : 
     273             : // Determine if a callable should be considered as an overload.
     274             : bool IsCompatibleSignature(const Signature& sig, const TypeVector& types,
     275             :                            size_t label_count);
     276             : 
     277          12 : class ImplementationVisitor : public FileVisitor {
     278             :  public:
     279             :   void GenerateBuiltinDefinitions(std::string& file_name);
     280             :   void GenerateClassDefinitions(std::string& file_name);
     281             :   void GeneratePrintDefinitions(std::string& file_name);
     282             : 
     283             :   VisitResult Visit(Expression* expr);
     284             :   const Type* Visit(Statement* stmt);
     285             : 
     286             :   InitializerResults VisitInitializerResults(
     287             :       const AggregateType* aggregate,
     288             :       const std::vector<NameAndExpression>& expressions);
     289             : 
     290             :   void InitializeFieldFromSpread(VisitResult object, const Field& field,
     291             :                                  const InitializerResults& initializer_results);
     292             : 
     293             :   size_t InitializeAggregateHelper(
     294             :       const AggregateType* aggregate_type, VisitResult allocate_result,
     295             :       const InitializerResults& initializer_results);
     296             : 
     297             :   VisitResult AddVariableObjectSize(
     298             :       VisitResult object_size, const ClassType* current_class,
     299             :       const InitializerResults& initializer_results);
     300             : 
     301             :   void InitializeAggregate(const AggregateType* aggregate_type,
     302             :                            VisitResult allocate_result,
     303             :                            const InitializerResults& initializer_results);
     304             : 
     305             :   VisitResult TemporaryUninitializedStruct(const StructType* struct_type,
     306             :                                            const std::string& reason);
     307             :   VisitResult Visit(StructExpression* decl);
     308             : 
     309             :   LocationReference GetLocationReference(Expression* location);
     310             :   LocationReference GetLocationReference(IdentifierExpression* expr);
     311             :   LocationReference GetLocationReference(DereferenceExpression* expr);
     312             :   LocationReference GetLocationReference(FieldAccessExpression* expr);
     313             :   LocationReference GetLocationReference(ElementAccessExpression* expr);
     314             : 
     315             :   VisitResult GenerateFetchFromLocation(const LocationReference& reference);
     316             : 
     317             :   VisitResult GetBuiltinCode(Builtin* builtin);
     318             : 
     319             :   VisitResult Visit(LocationExpression* expr);
     320             : 
     321             :   void VisitAllDeclarables();
     322             :   void Visit(Declarable* delarable);
     323             :   void Visit(TypeAlias* decl);
     324             :   VisitResult InlineMacro(Macro* macro,
     325             :                           base::Optional<LocationReference> this_reference,
     326             :                           const std::vector<VisitResult>& arguments,
     327             :                           const std::vector<Block*> label_blocks);
     328             :   void VisitMacroCommon(Macro* macro);
     329             :   void Visit(Macro* macro);
     330             :   void Visit(Method* macro);
     331             :   void Visit(Builtin* builtin);
     332             :   void Visit(NamespaceConstant* decl);
     333             : 
     334             :   VisitResult Visit(CallExpression* expr, bool is_tail = false);
     335             :   VisitResult Visit(CallMethodExpression* expr);
     336             :   VisitResult Visit(IntrinsicCallExpression* intrinsic);
     337             :   const Type* Visit(TailCallStatement* stmt);
     338             : 
     339             :   VisitResult Visit(ConditionalExpression* expr);
     340             : 
     341             :   VisitResult Visit(LogicalOrExpression* expr);
     342             :   VisitResult Visit(LogicalAndExpression* expr);
     343             : 
     344             :   VisitResult Visit(IncrementDecrementExpression* expr);
     345             :   VisitResult Visit(AssignmentExpression* expr);
     346             :   VisitResult Visit(StringLiteralExpression* expr);
     347             :   VisitResult Visit(NumberLiteralExpression* expr);
     348             :   VisitResult Visit(AssumeTypeImpossibleExpression* expr);
     349             :   VisitResult Visit(TryLabelExpression* expr);
     350             :   VisitResult Visit(StatementExpression* expr);
     351             :   VisitResult Visit(NewExpression* expr);
     352             :   VisitResult Visit(SpreadExpression* expr);
     353             : 
     354             :   const Type* Visit(ReturnStatement* stmt);
     355             :   const Type* Visit(GotoStatement* stmt);
     356             :   const Type* Visit(IfStatement* stmt);
     357             :   const Type* Visit(WhileStatement* stmt);
     358             :   const Type* Visit(BreakStatement* stmt);
     359             :   const Type* Visit(ContinueStatement* stmt);
     360             :   const Type* Visit(ForLoopStatement* stmt);
     361             :   const Type* Visit(VarDeclarationStatement* stmt);
     362             :   const Type* Visit(VarDeclarationStatement* stmt,
     363             :                     BlockBindings<LocalValue>* block_bindings);
     364             :   const Type* Visit(ForOfLoopStatement* stmt);
     365             :   const Type* Visit(BlockStatement* block);
     366             :   const Type* Visit(ExpressionStatement* stmt);
     367             :   const Type* Visit(DebugStatement* stmt);
     368             :   const Type* Visit(AssertStatement* stmt);
     369             : 
     370             :   void BeginNamespaceFile(Namespace* nspace);
     371             :   void EndNamespaceFile(Namespace* nspace);
     372             : 
     373             :   void GenerateImplementation(const std::string& dir, Namespace* nspace);
     374             : 
     375             :   DECLARE_CONTEXTUAL_VARIABLE(ValueBindingsManager,
     376             :                               BindingsManager<LocalValue>);
     377             :   DECLARE_CONTEXTUAL_VARIABLE(LabelBindingsManager,
     378             :                               BindingsManager<LocalLabel>);
     379             :   DECLARE_CONTEXTUAL_VARIABLE(CurrentCallable, Callable*);
     380             :   DECLARE_CONTEXTUAL_VARIABLE(CurrentReturnValue, base::Optional<VisitResult>);
     381             : 
     382             :   // A BindingsManagersScope has to be active for local bindings to be created.
     383             :   // Shadowing an existing BindingsManagersScope by creating a new one hides all
     384             :   // existing bindings while the additional BindingsManagersScope is active.
     385        5784 :   struct BindingsManagersScope {
     386             :     ValueBindingsManager::Scope value_bindings_manager;
     387             :     LabelBindingsManager::Scope label_bindings_manager;
     388             :   };
     389             : 
     390             :  private:
     391             :   base::Optional<Block*> GetCatchBlock();
     392             :   void GenerateCatchBlock(base::Optional<Block*> catch_block);
     393             : 
     394             :   // {StackScope} records the stack height at creation time and reconstructs it
     395             :   // when being destructed by emitting a {DeleteRangeInstruction}, except for
     396             :   // the slots protected by {StackScope::Yield}. Calling {Yield(v)} deletes all
     397             :   // slots above the initial stack height except for the slots of {v}, which are
     398             :   // moved to form the only slots above the initial height and marks them to
     399             :   // survive destruction of the {StackScope}. A typical pattern is the
     400             :   // following:
     401             :   //
     402             :   // VisitResult result;
     403             :   // {
     404             :   //   StackScope stack_scope(this);
     405             :   //   // ... create temporary slots ...
     406             :   //   result = stack_scope.Yield(surviving_slots);
     407             :   // }
     408             :   class StackScope {
     409             :    public:
     410       34641 :     explicit StackScope(ImplementationVisitor* visitor) : visitor_(visitor) {
     411       34641 :       base_ = visitor_->assembler().CurrentStack().AboveTop();
     412             :     }
     413       28571 :     VisitResult Yield(VisitResult result) {
     414             :       DCHECK(!closed_);
     415       28571 :       closed_ = true;
     416       28571 :       if (!result.IsOnStack()) {
     417        6490 :         if (!visitor_->assembler().CurrentBlockIsComplete()) {
     418        6092 :           visitor_->assembler().DropTo(base_);
     419             :         }
     420        3245 :         return result;
     421             :       }
     422             :       DCHECK_LE(base_, result.stack_range().begin());
     423             :       DCHECK_LE(result.stack_range().end(),
     424             :                 visitor_->assembler().CurrentStack().AboveTop());
     425       50652 :       visitor_->assembler().DropTo(result.stack_range().end());
     426       50652 :       visitor_->assembler().DeleteRange(
     427       25326 :           StackRange{base_, result.stack_range().begin()});
     428       50652 :       base_ = visitor_->assembler().CurrentStack().AboveTop();
     429             :       return VisitResult(result.type(), visitor_->assembler().TopRange(
     430             :                                             result.stack_range().Size()));
     431             :     }
     432             : 
     433        6070 :     void Close() {
     434             :       DCHECK(!closed_);
     435        6070 :       closed_ = true;
     436       12140 :       if (!visitor_->assembler().CurrentBlockIsComplete()) {
     437        5740 :         visitor_->assembler().DropTo(base_);
     438             :       }
     439        6070 :     }
     440             : 
     441       34641 :     ~StackScope() {
     442       34641 :       if (closed_) {
     443             :         DCHECK_IMPLIES(
     444             :             !visitor_->assembler().CurrentBlockIsComplete(),
     445             :             base_ == visitor_->assembler().CurrentStack().AboveTop());
     446             :       } else {
     447        6070 :         Close();
     448             :       }
     449             :     }
     450             : 
     451             :    private:
     452             :     ImplementationVisitor* visitor_;
     453             :     BottomOffset base_;
     454             :     bool closed_ = false;
     455             :   };
     456             : 
     457         104 :   class BreakContinueActivator {
     458             :    public:
     459         104 :     BreakContinueActivator(Block* break_block, Block* continue_block)
     460             :         : break_binding_{&LabelBindingsManager::Get(), "_break",
     461             :                          LocalLabel{break_block}},
     462             :           continue_binding_{&LabelBindingsManager::Get(), "_continue",
     463         832 :                             LocalLabel{continue_block}} {}
     464             : 
     465             :    private:
     466             :     Binding<LocalLabel> break_binding_;
     467             :     Binding<LocalLabel> continue_binding_;
     468             :   };
     469             : 
     470             :   base::Optional<Binding<LocalValue>*> TryLookupLocalValue(
     471             :       const std::string& name);
     472             :   base::Optional<Binding<LocalLabel>*> TryLookupLabel(const std::string& name);
     473             :   Binding<LocalLabel>* LookupLabel(const std::string& name);
     474             :   Block* LookupSimpleLabel(const std::string& name);
     475             :   template <class Container>
     476             :   Callable* LookupCallable(const QualifiedName& name,
     477             :                            const Container& declaration_container,
     478             :                            const TypeVector& types,
     479             :                            const std::vector<Binding<LocalLabel>*>& labels,
     480             :                            const TypeVector& specialization_types,
     481             :                            bool silence_errors = false);
     482             :   bool TestLookupCallable(const QualifiedName& name,
     483             :                           const TypeVector& parameter_types);
     484             : 
     485             :   template <class Container>
     486             :   Callable* LookupCallable(const QualifiedName& name,
     487             :                            const Container& declaration_container,
     488             :                            const Arguments& arguments,
     489             :                            const TypeVector& specialization_types);
     490             : 
     491             :   Method* LookupMethod(const std::string& name, LocationReference target,
     492             :                        const Arguments& arguments,
     493             :                        const TypeVector& specialization_types);
     494             : 
     495             :   const Type* GetCommonType(const Type* left, const Type* right);
     496             : 
     497             :   VisitResult GenerateCopy(const VisitResult& to_copy);
     498             : 
     499             :   void GenerateAssignToLocation(const LocationReference& reference,
     500             :                                 const VisitResult& assignment_value);
     501             : 
     502             :   void AddCallParameter(Callable* callable, VisitResult parameter,
     503             :                         const Type* parameter_type,
     504             :                         std::vector<VisitResult>* converted_arguments,
     505             :                         StackRange* argument_range,
     506             :                         std::vector<std::string>* constexpr_arguments);
     507             : 
     508             :   VisitResult GenerateCall(Callable* callable,
     509             :                            base::Optional<LocationReference> this_parameter,
     510             :                            Arguments parameters,
     511             :                            const TypeVector& specialization_types = {},
     512             :                            bool tail_call = false);
     513             :   VisitResult GenerateCall(const QualifiedName& callable_name,
     514             :                            Arguments parameters,
     515             :                            const TypeVector& specialization_types = {},
     516             :                            bool tail_call = false);
     517        2133 :   VisitResult GenerateCall(std::string callable_name, Arguments parameters,
     518             :                            const TypeVector& specialization_types = {},
     519             :                            bool tail_call = false) {
     520             :     return GenerateCall(QualifiedName(std::move(callable_name)),
     521        6399 :                         std::move(parameters), specialization_types, tail_call);
     522             :   }
     523             :   VisitResult GeneratePointerCall(Expression* callee,
     524             :                                   const Arguments& parameters, bool tail_call);
     525             : 
     526             :   void GenerateBranch(const VisitResult& condition, Block* true_block,
     527             :                       Block* false_block);
     528             : 
     529             :   typedef std::function<VisitResult()> VisitResultGenerator;
     530             :   void GenerateExpressionBranch(VisitResultGenerator, Block* true_block,
     531             :                                 Block* false_block);
     532             :   void GenerateExpressionBranch(Expression* expression, Block* true_block,
     533             :                                 Block* false_block);
     534             : 
     535             :   void GenerateMacroFunctionDeclaration(std::ostream& o,
     536             :                                         const std::string& macro_prefix,
     537             :                                         Macro* macro);
     538             :   void GenerateFunctionDeclaration(std::ostream& o,
     539             :                                    const std::string& macro_prefix,
     540             :                                    const std::string& name,
     541             :                                    const Signature& signature,
     542             :                                    const NameVector& parameter_names);
     543             : 
     544             :   VisitResult GenerateImplicitConvert(const Type* destination_type,
     545             :                                       VisitResult source);
     546             : 
     547             :   StackRange GenerateLabelGoto(LocalLabel* label,
     548             :                                base::Optional<StackRange> arguments = {});
     549             : 
     550             :   std::vector<Binding<LocalLabel>*> LabelsFromIdentifiers(
     551             :       const std::vector<std::string>& names);
     552             : 
     553             :   StackRange LowerParameter(const Type* type, const std::string& parameter_name,
     554             :                             Stack<std::string>* lowered_parameters);
     555             : 
     556             :   void LowerLabelParameter(const Type* type, const std::string& parameter_name,
     557             :                            std::vector<std::string>* lowered_parameters);
     558             : 
     559             :   std::string ExternalLabelName(const std::string& label_name);
     560             :   std::string ExternalLabelParameterName(const std::string& label_name,
     561             :                                          size_t i);
     562             :   std::string ExternalParameterName(const std::string& name);
     563             : 
     564        8946 :   std::ostream& source_out() {
     565        8946 :     Callable* callable = CurrentCallable::Get();
     566        8946 :     if (!callable || callable->ShouldGenerateExternalCode()) {
     567       17542 :       return CurrentNamespace()->source_stream();
     568             :     } else {
     569         175 :       return null_stream_;
     570             :     }
     571             :   }
     572        3839 :   std::ostream& header_out() {
     573        3839 :     Callable* callable = CurrentCallable::Get();
     574        3839 :     if (!callable || callable->ShouldGenerateExternalCode()) {
     575        7492 :       return CurrentNamespace()->header_stream();
     576             :     } else {
     577          93 :       return null_stream_;
     578             :     }
     579             :   }
     580             :   CfgAssembler& assembler() { return *assembler_; }
     581             : 
     582             :   void SetReturnValue(VisitResult return_value) {
     583             :     base::Optional<VisitResult>& current_return_value =
     584             :         CurrentReturnValue::Get();
     585             :     DCHECK_IMPLIES(current_return_value, *current_return_value == return_value);
     586             :     current_return_value = std::move(return_value);
     587             :   }
     588             : 
     589        1229 :   VisitResult GetAndClearReturnValue() {
     590             :     VisitResult return_value = *CurrentReturnValue::Get();
     591             :     CurrentReturnValue::Get() = base::nullopt;
     592        1229 :     return return_value;
     593             :   }
     594             : 
     595             :   base::Optional<CfgAssembler> assembler_;
     596             :   NullOStream null_stream_;
     597             : };
     598             : 
     599             : }  // namespace torque
     600             : }  // namespace internal
     601             : }  // namespace v8
     602             : 
     603             : #endif  // V8_TORQUE_IMPLEMENTATION_VISITOR_H_

Generated by: LCOV version 1.10