LCOV - code coverage report
Current view: top level - src/torque - implementation-visitor.h (source / functions) Hit Total Coverage
Test: app.info Lines: 96 98 98.0 %
Date: 2019-02-19 Functions: 29 29 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       20752 : class LocationReference {
      28             :  public:
      29             :   // An assignable stack range.
      30             :   static LocationReference VariableAccess(VisitResult variable) {
      31             :     DCHECK(variable.IsOnStack());
      32        2997 :     LocationReference result;
      33             :     result.variable_ = std::move(variable);
      34             :     return result;
      35             :   }
      36             :   // An unassignable value. {description} is only used for error messages.
      37             :   static LocationReference Temporary(VisitResult temporary,
      38             :                                      std::string description) {
      39        5025 :     LocationReference result;
      40             :     result.temporary_ = std::move(temporary);
      41             :     result.temporary_description_ = std::move(description);
      42             :     return result;
      43             :   }
      44          99 :   static LocationReference ArrayAccess(VisitResult base, VisitResult offset) {
      45          99 :     LocationReference result;
      46         198 :     result.eval_function_ = std::string{"[]"};
      47         198 :     result.assign_function_ = std::string{"[]="};
      48         297 :     result.call_arguments_ = {base, offset};
      49          99 :     return result;
      50             :   }
      51         428 :   static LocationReference FieldAccess(VisitResult object,
      52             :                                        std::string fieldname) {
      53         428 :     LocationReference result;
      54         856 :     result.eval_function_ = "." + fieldname;
      55        1284 :     result.assign_function_ = "." + fieldname + "=";
      56        1284 :     result.call_arguments_ = {object};
      57             :     result.index_field_ = base::nullopt;
      58         428 :     return result;
      59             :   }
      60         134 :   static LocationReference IndexedFieldIndexedAccess(
      61             :       const LocationReference& indexed_field, VisitResult index) {
      62         134 :     LocationReference result;
      63             :     DCHECK(indexed_field.IsIndexedFieldAccess());
      64         134 :     std::string fieldname = *indexed_field.index_field_;
      65         402 :     result.eval_function_ = "." + fieldname + "[]";
      66         402 :     result.assign_function_ = "." + fieldname + "[]=";
      67             :     result.call_arguments_ = indexed_field.call_arguments_;
      68         134 :     result.call_arguments_.push_back(index);
      69             :     result.index_field_ = fieldname;
      70         134 :     return result;
      71             :   }
      72         134 :   static LocationReference IndexedFieldAccess(VisitResult object,
      73             :                                               std::string fieldname) {
      74         134 :     LocationReference result;
      75         402 :     result.call_arguments_ = {object};
      76             :     result.index_field_ = fieldname;
      77         134 :     return result;
      78             :   }
      79             : 
      80             :   bool IsConst() const { return temporary_.has_value(); }
      81             : 
      82        5197 :   bool IsVariableAccess() const { return variable_.has_value(); }
      83             :   const VisitResult& variable() const {
      84             :     DCHECK(IsVariableAccess());
      85             :     return *variable_;
      86             :   }
      87        7573 :   bool IsTemporary() const { return temporary_.has_value(); }
      88             :   const VisitResult& temporary() const {
      89             :     DCHECK(IsTemporary());
      90             :     return *temporary_;
      91             :   }
      92             : 
      93             :   const VisitResult& GetVisitResult() const {
      94        1038 :     if (IsVariableAccess()) return variable();
      95             :     DCHECK(IsTemporary());
      96          49 :     return temporary();
      97             :   }
      98             : 
      99             :   // For error reporting.
     100             :   const std::string& temporary_description() const {
     101             :     DCHECK(IsTemporary());
     102             :     return *temporary_description_;
     103             :   }
     104             : 
     105         784 :   bool IsArrayField() const { return index_field_.has_value(); }
     106             :   bool IsIndexedFieldAccess() const {
     107         987 :     return IsArrayField() && !IsCallAccess();
     108             :   }
     109             :   bool IsIndexedFieldIndexedAccess() const {
     110             :     return IsArrayField() && IsCallAccess();
     111             :   }
     112             :   bool IsCallAccess() const {
     113        1141 :     bool is_call_access = eval_function_.has_value();
     114             :     DCHECK_EQ(is_call_access, assign_function_.has_value());
     115             :     return is_call_access;
     116             :   }
     117             :   const VisitResultVector& call_arguments() const {
     118             :     DCHECK(IsCallAccess());
     119             :     return call_arguments_;
     120             :   }
     121             :   const std::string& eval_function() const {
     122             :     DCHECK(IsCallAccess());
     123             :     return *eval_function_;
     124             :   }
     125             :   const std::string& assign_function() const {
     126             :     DCHECK(IsCallAccess());
     127             :     return *assign_function_;
     128             :   }
     129             : 
     130             :  private:
     131             :   base::Optional<VisitResult> variable_;
     132             :   base::Optional<VisitResult> temporary_;
     133             :   base::Optional<std::string> temporary_description_;
     134             :   base::Optional<std::string> eval_function_;
     135             :   base::Optional<std::string> assign_function_;
     136             :   VisitResultVector call_arguments_;
     137             :   base::Optional<std::string> index_field_;
     138             : 
     139       17634 :   LocationReference() = default;
     140             : };
     141             : 
     142             : template <class T>
     143             : class Binding;
     144             : 
     145             : template <class T>
     146        1822 : class BindingsManager {
     147             :  public:
     148       16258 :   base::Optional<Binding<T>*> TryLookup(const std::string& name) {
     149       16258 :     return current_bindings_[name];
     150             :   }
     151             : 
     152             :  private:
     153             :   friend class Binding<T>;
     154             :   std::unordered_map<std::string, base::Optional<Binding<T>*>>
     155             :       current_bindings_;
     156             : };
     157             : 
     158             : template <class T>
     159             : class Binding : public T {
     160             :  public:
     161             :   template <class... Args>
     162        6273 :   Binding(BindingsManager<T>* manager, const std::string& name, Args&&... args)
     163             :       : T(std::forward<Args>(args)...),
     164             :         manager_(manager),
     165             :         name_(name),
     166       12546 :         previous_binding_(this) {
     167       12546 :     std::swap(previous_binding_, manager_->current_bindings_[name]);
     168        6273 :   }
     169       12546 :   ~Binding() { manager_->current_bindings_[name_] = previous_binding_; }
     170             : 
     171             :   const std::string& name() const { return name_; }
     172           0 :   SourcePosition declaration_position() const { return declaration_position_; }
     173             : 
     174             :  private:
     175             :   BindingsManager<T>* manager_;
     176             :   const std::string name_;
     177             :   base::Optional<Binding*> previous_binding_;
     178             :   SourcePosition declaration_position_ = CurrentSourcePosition::Get();
     179             :   DISALLOW_COPY_AND_ASSIGN(Binding);
     180             : };
     181             : 
     182             : template <class T>
     183        2851 : class BlockBindings {
     184             :  public:
     185        3606 :   explicit BlockBindings(BindingsManager<T>* manager) : manager_(manager) {}
     186        3542 :   void Add(std::string name, T value) {
     187       11854 :     for (const auto& binding : bindings_) {
     188        4770 :       if (binding->name() == name) {
     189           0 :         ReportError(
     190             :             "redeclaration of name \"", name,
     191             :             "\" in the same block is illegal, previous declaration at: ",
     192             :             binding->declaration_position());
     193             :       }
     194             :     }
     195        7084 :     bindings_.push_back(base::make_unique<Binding<T>>(manager_, std::move(name),
     196             :                                                       std::move(value)));
     197        3542 :   }
     198             : 
     199             :   std::vector<Binding<T>*> bindings() const {
     200             :     std::vector<Binding<T>*> result;
     201             :     result.reserve(bindings_.size());
     202             :     for (auto& b : bindings_) {
     203             :       result.push_back(b.get());
     204             :     }
     205             :     return result;
     206             :   }
     207             : 
     208             :  private:
     209             :   BindingsManager<T>* manager_;
     210             :   std::vector<std::unique_ptr<Binding<T>>> bindings_;
     211             : };
     212             : 
     213        3620 : struct LocalValue {
     214             :   bool is_const;
     215             :   VisitResult value;
     216             : };
     217             : 
     218        2880 : struct LocalLabel {
     219             :   Block* block;
     220             :   std::vector<const Type*> parameter_types;
     221             : 
     222             :   explicit LocalLabel(Block* block,
     223             :                       std::vector<const Type*> parameter_types = {})
     224        2880 :       : block(block), parameter_types(std::move(parameter_types)) {}
     225             : };
     226             : 
     227       39943 : struct Arguments {
     228             :   VisitResultVector parameters;
     229             :   std::vector<Binding<LocalLabel>*> labels;
     230             : };
     231             : 
     232             : // Determine if a callable should be considered as an overload.
     233             : bool IsCompatibleSignature(const Signature& sig, const TypeVector& types,
     234             :                            size_t label_count);
     235             : 
     236           3 : class ImplementationVisitor : public FileVisitor {
     237             :  public:
     238             :   void GenerateBuiltinDefinitions(std::string& file_name);
     239             :   void GenerateClassDefinitions(std::string& file_name);
     240             : 
     241             :   VisitResult Visit(Expression* expr);
     242             :   const Type* Visit(Statement* stmt);
     243             : 
     244             :   VisitResult TemporaryUninitializedStruct(const StructType* struct_type,
     245             :                                            const std::string& reason);
     246             :   VisitResult Visit(StructExpression* decl);
     247             : 
     248             :   LocationReference GetLocationReference(Expression* location);
     249             :   LocationReference GetLocationReference(IdentifierExpression* expr);
     250             :   LocationReference GetLocationReference(FieldAccessExpression* expr);
     251             :   LocationReference GetLocationReference(ElementAccessExpression* expr);
     252             : 
     253             :   VisitResult GenerateFetchFromLocation(const LocationReference& reference);
     254             : 
     255             :   VisitResult GetBuiltinCode(Builtin* builtin);
     256             : 
     257             :   VisitResult Visit(IdentifierExpression* expr);
     258         520 :   VisitResult Visit(FieldAccessExpression* expr) {
     259             :     StackScope scope(this);
     260        1560 :     return scope.Yield(GenerateFetchFromLocation(GetLocationReference(expr)));
     261             :   }
     262         165 :   VisitResult Visit(ElementAccessExpression* expr) {
     263             :     StackScope scope(this);
     264         495 :     return scope.Yield(GenerateFetchFromLocation(GetLocationReference(expr)));
     265             :   }
     266             : 
     267             :   void VisitAllDeclarables();
     268             :   void Visit(Declarable* delarable);
     269             :   void Visit(TypeAlias* decl);
     270             :   VisitResult InlineMacro(Macro* macro,
     271             :                           base::Optional<LocationReference> this_reference,
     272             :                           const std::vector<VisitResult>& arguments,
     273             :                           const std::vector<Block*> label_blocks);
     274             :   void VisitMacroCommon(Macro* macro);
     275             :   void Visit(Macro* macro);
     276             :   void Visit(Method* macro);
     277             :   void Visit(Builtin* builtin);
     278             :   void Visit(NamespaceConstant* decl);
     279             : 
     280             :   VisitResult Visit(CallExpression* expr, bool is_tail = false);
     281             :   VisitResult Visit(CallMethodExpression* expr);
     282             :   VisitResult Visit(IntrinsicCallExpression* intrinsic);
     283             :   VisitResult Visit(LoadObjectFieldExpression* expr);
     284             :   VisitResult Visit(StoreObjectFieldExpression* expr);
     285             :   const Type* Visit(TailCallStatement* stmt);
     286             : 
     287             :   VisitResult Visit(ConditionalExpression* expr);
     288             : 
     289             :   VisitResult Visit(LogicalOrExpression* expr);
     290             :   VisitResult Visit(LogicalAndExpression* expr);
     291             : 
     292             :   VisitResult Visit(IncrementDecrementExpression* expr);
     293             :   VisitResult Visit(AssignmentExpression* expr);
     294             :   VisitResult Visit(StringLiteralExpression* expr);
     295             :   VisitResult Visit(NumberLiteralExpression* expr);
     296             :   VisitResult Visit(AssumeTypeImpossibleExpression* expr);
     297             :   VisitResult Visit(TryLabelExpression* expr);
     298             :   VisitResult Visit(StatementExpression* expr);
     299             :   VisitResult Visit(NewExpression* expr);
     300             : 
     301             :   const Type* Visit(ReturnStatement* stmt);
     302             :   const Type* Visit(GotoStatement* stmt);
     303             :   const Type* Visit(IfStatement* stmt);
     304             :   const Type* Visit(WhileStatement* stmt);
     305             :   const Type* Visit(BreakStatement* stmt);
     306             :   const Type* Visit(ContinueStatement* stmt);
     307             :   const Type* Visit(ForLoopStatement* stmt);
     308             :   const Type* Visit(VarDeclarationStatement* stmt);
     309             :   const Type* Visit(VarDeclarationStatement* stmt,
     310             :                     BlockBindings<LocalValue>* block_bindings);
     311             :   const Type* Visit(ForOfLoopStatement* stmt);
     312             :   const Type* Visit(BlockStatement* block);
     313             :   const Type* Visit(ExpressionStatement* stmt);
     314             :   const Type* Visit(DebugStatement* stmt);
     315             :   const Type* Visit(AssertStatement* stmt);
     316             : 
     317             :   void BeginNamespaceFile(Namespace* nspace);
     318             :   void EndNamespaceFile(Namespace* nspace);
     319             : 
     320             :   void GenerateImplementation(const std::string& dir, Namespace* nspace);
     321             : 
     322             :   struct ConstructorInfo {
     323             :     int super_calls;
     324             :   };
     325             : 
     326             :   DECLARE_CONTEXTUAL_VARIABLE(ValueBindingsManager,
     327             :                               BindingsManager<LocalValue>);
     328             :   DECLARE_CONTEXTUAL_VARIABLE(LabelBindingsManager,
     329             :                               BindingsManager<LocalLabel>);
     330             :   DECLARE_CONTEXTUAL_VARIABLE(CurrentCallable, Callable*);
     331             :   DECLARE_CONTEXTUAL_VARIABLE(CurrentReturnValue, base::Optional<VisitResult>);
     332             :   DECLARE_CONTEXTUAL_VARIABLE(CurrentConstructorInfo,
     333             :                               base::Optional<ConstructorInfo>);
     334             : 
     335             :   // A BindingsManagersScope has to be active for local bindings to be created.
     336             :   // Shadowing an existing BindingsManagersScope by creating a new one hides all
     337             :   // existing bindings while the additional BindingsManagersScope is active.
     338        1822 :   struct BindingsManagersScope {
     339             :     ValueBindingsManager::Scope value_bindings_manager;
     340             :     LabelBindingsManager::Scope label_bindings_manager;
     341             :   };
     342             : 
     343             :  private:
     344             :   base::Optional<Block*> GetCatchBlock();
     345             :   void GenerateCatchBlock(base::Optional<Block*> catch_block);
     346             : 
     347             :   // {StackScope} records the stack height at creation time and reconstructs it
     348             :   // when being destructed by emitting a {DeleteRangeInstruction}, except for
     349             :   // the slots protected by {StackScope::Yield}. Calling {Yield(v)} deletes all
     350             :   // slots above the initial stack height except for the slots of {v}, which are
     351             :   // moved to form the only slots above the initial height and marks them to
     352             :   // survive destruction of the {StackScope}. A typical pattern is the
     353             :   // following:
     354             :   //
     355             :   // VisitResult result;
     356             :   // {
     357             :   //   StackScope stack_scope(this);
     358             :   //   // ... create temporary slots ...
     359             :   //   result = stack_scope.Yield(surviving_slots);
     360             :   // }
     361             :   class StackScope {
     362             :    public:
     363       30016 :     explicit StackScope(ImplementationVisitor* visitor) : visitor_(visitor) {
     364       30016 :       base_ = visitor_->assembler().CurrentStack().AboveTop();
     365             :     }
     366       46680 :     VisitResult Yield(VisitResult result) {
     367             :       DCHECK(!closed_);
     368       24835 :       closed_ = true;
     369       24835 :       if (!result.IsOnStack()) {
     370        5980 :         if (!visitor_->assembler().CurrentBlockIsComplete()) {
     371        2850 :           visitor_->assembler().DropTo(base_);
     372             :         }
     373        2990 :         return result;
     374             :       }
     375             :       DCHECK_LE(base_, result.stack_range().begin());
     376             :       DCHECK_LE(result.stack_range().end(),
     377             :                 visitor_->assembler().CurrentStack().AboveTop());
     378       21845 :       visitor_->assembler().DropTo(result.stack_range().end());
     379       21845 :       visitor_->assembler().DeleteRange(
     380       21845 :           StackRange{base_, result.stack_range().begin()});
     381       43690 :       base_ = visitor_->assembler().CurrentStack().AboveTop();
     382             :       return VisitResult(result.type(), visitor_->assembler().TopRange(
     383             :                                             result.stack_range().Size()));
     384             :     }
     385             : 
     386        5181 :     void Close() {
     387             :       DCHECK(!closed_);
     388        5181 :       closed_ = true;
     389       10362 :       if (!visitor_->assembler().CurrentBlockIsComplete()) {
     390        2943 :         visitor_->assembler().DropTo(base_);
     391             :       }
     392        5181 :     }
     393             : 
     394             :     ~StackScope() {
     395       30016 :       if (closed_) {
     396             :         DCHECK_IMPLIES(
     397             :             !visitor_->assembler().CurrentBlockIsComplete(),
     398             :             base_ == visitor_->assembler().CurrentStack().AboveTop());
     399             :       } else {
     400        5181 :         Close();
     401             :       }
     402             :     }
     403             : 
     404             :    private:
     405             :     ImplementationVisitor* visitor_;
     406             :     BottomOffset base_;
     407             :     bool closed_ = false;
     408             :   };
     409             : 
     410          93 :   class BreakContinueActivator {
     411             :    public:
     412          93 :     BreakContinueActivator(Block* break_block, Block* continue_block)
     413             :         : break_binding_{&LabelBindingsManager::Get(), "_break",
     414             :                          LocalLabel{break_block}},
     415             :           continue_binding_{&LabelBindingsManager::Get(), "_continue",
     416         744 :                             LocalLabel{continue_block}} {}
     417             : 
     418             :    private:
     419             :     Binding<LocalLabel> break_binding_;
     420             :     Binding<LocalLabel> continue_binding_;
     421             :   };
     422             : 
     423             :   base::Optional<Binding<LocalValue>*> TryLookupLocalValue(
     424             :       const std::string& name);
     425             :   base::Optional<Binding<LocalLabel>*> TryLookupLabel(const std::string& name);
     426             :   Binding<LocalLabel>* LookupLabel(const std::string& name);
     427             :   Block* LookupSimpleLabel(const std::string& name);
     428             :   template <class Container>
     429             :   Callable* LookupCallable(const QualifiedName& name,
     430             :                            const Container& declaration_container,
     431             :                            const TypeVector& types,
     432             :                            const std::vector<Binding<LocalLabel>*>& labels,
     433             :                            const TypeVector& specialization_types);
     434             : 
     435             :   template <class Container>
     436             :   Callable* LookupCallable(const QualifiedName& name,
     437             :                            const Container& declaration_container,
     438             :                            const Arguments& arguments,
     439             :                            const TypeVector& specialization_types);
     440             : 
     441             :   Method* LookupMethod(const std::string& name, LocationReference target,
     442             :                        const Arguments& arguments,
     443             :                        const TypeVector& specialization_types);
     444             : 
     445         105 :   Method* LookupConstructor(LocationReference target,
     446             :                             const Arguments& arguments,
     447             :                             const TypeVector& specialization_types) {
     448             :     return LookupMethod(kConstructMethodName, target, arguments,
     449         210 :                         specialization_types);
     450             :   }
     451             : 
     452             :   const Type* GetCommonType(const Type* left, const Type* right);
     453             : 
     454             :   VisitResult GenerateCopy(const VisitResult& to_copy);
     455             : 
     456             :   void GenerateAssignToLocation(const LocationReference& reference,
     457             :                                 const VisitResult& assignment_value);
     458             : 
     459             :   void AddCallParameter(Callable* callable, VisitResult parameter,
     460             :                         const Type* parameter_type,
     461             :                         std::vector<VisitResult>* converted_arguments,
     462             :                         StackRange* argument_range,
     463             :                         std::vector<std::string>* constexpr_arguments);
     464             : 
     465             :   VisitResult GenerateCall(Callable* callable,
     466             :                            base::Optional<LocationReference> this_parameter,
     467             :                            Arguments parameters,
     468             :                            const TypeVector& specialization_types = {},
     469             :                            bool tail_call = false);
     470             :   VisitResult GenerateCall(const QualifiedName& callable_name,
     471             :                            Arguments parameters,
     472             :                            const TypeVector& specialization_types = {},
     473             :                            bool tail_call = false);
     474        2229 :   VisitResult GenerateCall(std::string callable_name, Arguments parameters,
     475             :                            const TypeVector& specialization_types = {},
     476             :                            bool tail_call = false) {
     477             :     return GenerateCall(QualifiedName(std::move(callable_name)),
     478        6687 :                         std::move(parameters), specialization_types, tail_call);
     479             :   }
     480             :   VisitResult GeneratePointerCall(Expression* callee,
     481             :                                   const Arguments& parameters, bool tail_call);
     482             : 
     483             :   void GenerateBranch(const VisitResult& condition, Block* true_block,
     484             :                       Block* false_block);
     485             : 
     486             :   void GenerateExpressionBranch(Expression* expression, Block* true_block,
     487             :                                 Block* false_block);
     488             : 
     489             :   void GenerateMacroFunctionDeclaration(std::ostream& o,
     490             :                                         const std::string& macro_prefix,
     491             :                                         Macro* macro);
     492             :   void GenerateFunctionDeclaration(std::ostream& o,
     493             :                                    const std::string& macro_prefix,
     494             :                                    const std::string& name,
     495             :                                    const Signature& signature,
     496             :                                    const NameVector& parameter_names);
     497             : 
     498             :   VisitResult GenerateImplicitConvert(const Type* destination_type,
     499             :                                       VisitResult source);
     500             : 
     501             :   StackRange GenerateLabelGoto(LocalLabel* label,
     502             :                                base::Optional<StackRange> arguments = {});
     503             : 
     504             :   std::vector<Binding<LocalLabel>*> LabelsFromIdentifiers(
     505             :       const std::vector<std::string>& names);
     506             : 
     507             :   StackRange LowerParameter(const Type* type, const std::string& parameter_name,
     508             :                             Stack<std::string>* lowered_parameters);
     509             : 
     510             :   void LowerLabelParameter(const Type* type, const std::string& parameter_name,
     511             :                            std::vector<std::string>* lowered_parameters);
     512             : 
     513             :   std::string ExternalLabelName(const std::string& label_name);
     514             :   std::string ExternalLabelParameterName(const std::string& label_name,
     515             :                                          size_t i);
     516             :   std::string ExternalParameterName(const std::string& name);
     517             : 
     518        5022 :   std::ostream& source_out() {
     519        5022 :     Callable* callable = CurrentCallable::Get();
     520        5022 :     if (!callable || callable->ShouldGenerateExternalCode()) {
     521        4835 :       return CurrentNamespace()->source_stream();
     522             :     } else {
     523         187 :       return null_stream_;
     524             :     }
     525             :   }
     526        2654 :   std::ostream& header_out() {
     527        2654 :     Callable* callable = CurrentCallable::Get();
     528        2654 :     if (!callable || callable->ShouldGenerateExternalCode()) {
     529        2525 :       return CurrentNamespace()->header_stream();
     530             :     } else {
     531         129 :       return null_stream_;
     532             :     }
     533             :   }
     534             :   CfgAssembler& assembler() { return *assembler_; }
     535             : 
     536             :   void SetReturnValue(VisitResult return_value) {
     537             :     base::Optional<VisitResult>& current_return_value =
     538             :         CurrentReturnValue::Get();
     539             :     DCHECK_IMPLIES(current_return_value, *current_return_value == return_value);
     540             :     current_return_value = std::move(return_value);
     541             :   }
     542             : 
     543             :   VisitResult GetAndClearReturnValue() {
     544         755 :     VisitResult return_value = *CurrentReturnValue::Get();
     545             :     CurrentReturnValue::Get() = base::nullopt;
     546             :     return return_value;
     547             :   }
     548             : 
     549             :   base::Optional<CfgAssembler> assembler_;
     550             :   NullOStream null_stream_;
     551             : };
     552             : 
     553             : }  // namespace torque
     554             : }  // namespace internal
     555             : }  // namespace v8
     556             : 
     557             : #endif  // V8_TORQUE_IMPLEMENTATION_VISITOR_H_

Generated by: LCOV version 1.10