LCOV - code coverage report
Current view: top level - src/torque - declarable.h (source / functions) Hit Total Coverage
Test: app.info Lines: 121 127 95.3 %
Date: 2019-02-19 Functions: 46 73 63.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_DECLARABLE_H_
       6             : #define V8_TORQUE_DECLARABLE_H_
       7             : 
       8             : #include <cassert>
       9             : #include <string>
      10             : #include <unordered_map>
      11             : 
      12             : #include "src/base/functional.h"
      13             : #include "src/base/logging.h"
      14             : #include "src/torque/ast.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             : class Scope;
      23             : class Namespace;
      24             : 
      25             : DECLARE_CONTEXTUAL_VARIABLE(CurrentScope, Scope*);
      26             : 
      27      288390 : struct QualifiedName {
      28             :   std::vector<std::string> namespace_qualification;
      29             :   std::string name;
      30             : 
      31             :   QualifiedName(std::vector<std::string> namespace_qualification,
      32             :                 std::string name)
      33             :       : namespace_qualification(std::move(namespace_qualification)),
      34             :         name(std::move(name)) {}
      35      127971 :   explicit QualifiedName(std::string name)
      36      255942 :       : QualifiedName({}, std::move(name)) {}
      37             : 
      38             :   friend std::ostream& operator<<(std::ostream& os, const QualifiedName& name);
      39             : };
      40             : 
      41             : class Declarable {
      42             :  public:
      43        8917 :   virtual ~Declarable() = default;
      44             :   enum Kind {
      45             :     kNamespace,
      46             :     kMacro,
      47             :     kMethod,
      48             :     kBuiltin,
      49             :     kRuntimeFunction,
      50             :     kIntrinsic,
      51             :     kGeneric,
      52             :     kTypeAlias,
      53             :     kExternConstant,
      54             :     kNamespaceConstant
      55             :   };
      56             :   Kind kind() const { return kind_; }
      57       54878 :   bool IsNamespace() const { return kind() == kNamespace; }
      58       22290 :   bool IsMacro() const { return kind() == kMacro || kind() == kMethod; }
      59         568 :   bool IsMethod() const { return kind() == kMethod; }
      60          99 :   bool IsIntrinsic() const { return kind() == kIntrinsic; }
      61       33481 :   bool IsBuiltin() const { return kind() == kBuiltin; }
      62         130 :   bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; }
      63       39849 :   bool IsGeneric() const { return kind() == kGeneric; }
      64      114739 :   bool IsTypeAlias() const { return kind() == kTypeAlias; }
      65        1125 :   bool IsExternConstant() const { return kind() == kExternConstant; }
      66         889 :   bool IsNamespaceConstant() const { return kind() == kNamespaceConstant; }
      67        1125 :   bool IsValue() const { return IsExternConstant() || IsNamespaceConstant(); }
      68          95 :   bool IsScope() const { return IsNamespace() || IsCallable(); }
      69       15218 :   bool IsCallable() const {
      70       15218 :     return IsMacro() || IsBuiltin() || IsRuntimeFunction() || IsIntrinsic() ||
      71       15218 :            IsMethod();
      72             :   }
      73           0 :   virtual const char* type_name() const { return "<<unknown>>"; }
      74             :   Scope* ParentScope() const { return parent_scope_; }
      75             :   const SourcePosition& pos() const { return pos_; }
      76             : 
      77             :  protected:
      78       26751 :   explicit Declarable(Kind kind) : kind_(kind) {}
      79             : 
      80             :  private:
      81             :   const Kind kind_;
      82             :   Scope* const parent_scope_ = CurrentScope::Get();
      83             :   SourcePosition pos_ = CurrentSourcePosition::Get();
      84             : };
      85             : 
      86             : #define DECLARE_DECLARABLE_BOILERPLATE(x, y)                  \
      87             :   static x* cast(Declarable* declarable) {                    \
      88             :     DCHECK(declarable->Is##x());                              \
      89             :     return static_cast<x*>(declarable);                       \
      90             :   }                                                           \
      91             :   static const x* cast(const Declarable* declarable) {        \
      92             :     DCHECK(declarable->Is##x());                              \
      93             :     return static_cast<const x*>(declarable);                 \
      94             :   }                                                           \
      95             :   const char* type_name() const override { return #y; }       \
      96             :   static x* DynamicCast(Declarable* declarable) {             \
      97             :     if (!declarable) return nullptr;                          \
      98             :     if (!declarable->Is##x()) return nullptr;                 \
      99             :     return static_cast<x*>(declarable);                       \
     100             :   }                                                           \
     101             :   static const x* DynamicCast(const Declarable* declarable) { \
     102             :     if (!declarable) return nullptr;                          \
     103             :     if (!declarable->Is##x()) return nullptr;                 \
     104             :     return static_cast<const x*>(declarable);                 \
     105             :   }
     106             : 
     107        7858 : class Scope : public Declarable {
     108             :  public:
     109         190 :   DECLARE_DECLARABLE_BOILERPLATE(Scope, scope)
     110        7858 :   explicit Scope(Declarable::Kind kind) : Declarable(kind) {}
     111             : 
     112      207351 :   std::vector<Declarable*> LookupShallow(const QualifiedName& name) {
     113      414539 :     if (name.namespace_qualification.empty()) return declarations_[name.name];
     114             :     Scope* child = nullptr;
     115         611 :     for (Declarable* declarable :
     116          95 :          declarations_[name.namespace_qualification.front()]) {
     117          95 :       if (Scope* scope = Scope::DynamicCast(declarable)) {
     118          95 :         if (child != nullptr) {
     119             :           ReportError("ambiguous reference to scope ",
     120           0 :                       name.namespace_qualification.front());
     121             :         }
     122             :         child = scope;
     123             :       }
     124             :     }
     125         258 :     if (child == nullptr) return {};
     126             :     return child->LookupShallow(
     127             :         QualifiedName({name.namespace_qualification.begin() + 1,
     128             :                        name.namespace_qualification.end()},
     129         285 :                       name.name));
     130             :   }
     131             : 
     132      202155 :   std::vector<Declarable*> Lookup(const QualifiedName& name) {
     133             :     std::vector<Declarable*> result;
     134      202155 :     if (ParentScope()) {
     135      125094 :       result = ParentScope()->Lookup(name);
     136             :     }
     137      758554 :     for (Declarable* declarable : LookupShallow(name)) {
     138      152089 :       result.push_back(declarable);
     139             :     }
     140      202155 :     return result;
     141             :   }
     142             :   template <class T>
     143        1072 :   T* AddDeclarable(const std::string& name, T* declarable) {
     144       12059 :     declarations_[name].push_back(declarable);
     145        1177 :     return declarable;
     146             :   }
     147             : 
     148             :  private:
     149             :   std::unordered_map<std::string, std::vector<Declarable*>> declarations_;
     150             : };
     151             : 
     152        5499 : class Namespace : public Scope {
     153             :  public:
     154      109566 :   DECLARE_DECLARABLE_BOILERPLATE(Namespace, namespace)
     155        2738 :   explicit Namespace(const std::string& name)
     156        2738 :       : Scope(Declarable::kNamespace), name_(name) {}
     157             :   const std::string& name() const { return name_; }
     158        1932 :   std::string ExternalName() const {
     159        3864 :     return CamelifyString(name()) + "BuiltinsFromDSLAssembler";
     160             :   }
     161             :   bool IsDefaultNamespace() const;
     162             :   bool IsTestNamespace() const;
     163             :   std::ostream& source_stream() { return source_stream_; }
     164             :   std::ostream& header_stream() { return header_stream_; }
     165             :   std::string source() { return source_stream_.str(); }
     166             :   std::string header() { return header_stream_.str(); }
     167             : 
     168             :  private:
     169             :   std::string name_;
     170             :   std::stringstream header_stream_;
     171             :   std::stringstream source_stream_;
     172             : };
     173             : 
     174        8571 : inline Namespace* CurrentNamespace() {
     175        8571 :   Scope* scope = CurrentScope::Get();
     176             :   while (true) {
     177       10079 :     if (Namespace* n = Namespace::DynamicCast(scope)) {
     178        8571 :       return n;
     179             :     }
     180        1508 :     scope = scope->ParentScope();
     181        1508 :   }
     182             : }
     183             : 
     184         210 : class Value : public Declarable {
     185             :  public:
     186        2250 :   DECLARE_DECLARABLE_BOILERPLATE(Value, value)
     187             :   const std::string& name() const { return name_; }
     188           0 :   virtual bool IsConst() const { return true; }
     189         560 :   VisitResult value() const { return *value_; }
     190             :   const Type* type() const { return type_; }
     191             : 
     192             :   void set_value(VisitResult value) {
     193             :     DCHECK(!value_);
     194             :     value_ = value;
     195             :   }
     196             : 
     197             :  protected:
     198         105 :   Value(Kind kind, const Type* type, const std::string& name)
     199         105 :       : Declarable(kind), type_(type), name_(name) {}
     200             : 
     201             :  private:
     202             :   const Type* type_;
     203             :   std::string name_;
     204             :   base::Optional<VisitResult> value_;
     205             : };
     206             : 
     207          72 : class NamespaceConstant : public Value {
     208             :  public:
     209        1778 :   DECLARE_DECLARABLE_BOILERPLATE(NamespaceConstant, constant)
     210             : 
     211             :   const std::string& constant_name() const { return constant_name_; }
     212             :   Expression* body() { return body_; }
     213             :   std::string ExternalAssemblerName() const {
     214         329 :     return Namespace::cast(ParentScope())->ExternalName();
     215             :   }
     216             : 
     217             :  private:
     218             :   friend class Declarations;
     219             :   explicit NamespaceConstant(std::string constant_name, const Type* type,
     220             :                              Expression* body)
     221             :       : Value(Declarable::kNamespaceConstant, type, constant_name),
     222             :         constant_name_(std::move(constant_name)),
     223          48 :         body_(body) {}
     224             : 
     225             :   std::string constant_name_;
     226             :   Expression* body_;
     227             : };
     228             : 
     229          81 : class ExternConstant : public Value {
     230             :  public:
     231           0 :   DECLARE_DECLARABLE_BOILERPLATE(ExternConstant, constant)
     232             : 
     233             :  private:
     234             :   friend class Declarations;
     235          81 :   explicit ExternConstant(std::string name, const Type* type, std::string value)
     236          81 :       : Value(Declarable::kExternConstant, type, std::move(name)) {
     237          81 :     set_value(VisitResult(type, std::move(value)));
     238          81 :   }
     239             : };
     240             : 
     241        2382 : class Callable : public Scope {
     242             :  public:
     243       15218 :   DECLARE_DECLARABLE_BOILERPLATE(Callable, callable)
     244             :   const std::string& ExternalName() const { return external_name_; }
     245             :   const std::string& ReadableName() const { return readable_name_; }
     246             :   const Signature& signature() const { return signature_; }
     247             :   const NameVector& parameter_names() const {
     248             :     return signature_.parameter_names;
     249             :   }
     250             :   bool HasReturnValue() const {
     251         691 :     return !signature_.return_type->IsVoidOrNever();
     252             :   }
     253         691 :   void IncrementReturns() { ++returns_; }
     254             :   bool HasReturns() const { return returns_; }
     255             :   bool IsTransitioning() const { return transitioning_; }
     256             :   base::Optional<Statement*> body() const { return body_; }
     257        2301 :   bool IsExternal() const { return !body_.has_value(); }
     258        2028 :   virtual bool ShouldBeInlined() const { return false; }
     259        6426 :   virtual bool ShouldGenerateExternalCode() const { return !ShouldBeInlined(); }
     260         755 :   bool IsConstructor() const { return readable_name_ == kConstructMethodName; }
     261             : 
     262             :  protected:
     263        1191 :   Callable(Declarable::Kind kind, std::string external_name,
     264             :            std::string readable_name, Signature signature, bool transitioning,
     265             :            base::Optional<Statement*> body)
     266             :       : Scope(kind),
     267             :         external_name_(std::move(external_name)),
     268             : 
     269             :         readable_name_(std::move(readable_name)),
     270             :         signature_(std::move(signature)),
     271             :         transitioning_(transitioning),
     272             :         returns_(0),
     273        2382 :         body_(body) {
     274             :     DCHECK(!body || *body);
     275        1191 :   }
     276             : 
     277             :  private:
     278             :   std::string external_name_;
     279             :   std::string readable_name_;
     280             :   Signature signature_;
     281             :   bool transitioning_;
     282             :   size_t returns_;
     283             :   base::Optional<Statement*> body_;
     284             : };
     285             : 
     286        2839 : class Macro : public Callable {
     287             :  public:
     288       11402 :   DECLARE_DECLARABLE_BOILERPLATE(Macro, macro)
     289       17441 :   bool ShouldBeInlined() const override {
     290       39554 :     for (const LabelDeclaration& label : signature().labels) {
     291        5707 :       for (const Type* type : label.types) {
     292         465 :         if (type->IsStructType()) return true;
     293             :       }
     294             :     }
     295             :     return Callable::ShouldBeInlined();
     296             :   }
     297             : 
     298             :   const std::string& external_assembler_name() const {
     299             :     return external_assembler_name_;
     300             :   }
     301             : 
     302             :  protected:
     303         961 :   Macro(Declarable::Kind kind, std::string external_name,
     304             :         std::string readable_name, std::string external_assembler_name,
     305             :         const Signature& signature, bool transitioning,
     306             :         base::Optional<Statement*> body)
     307             :       : Callable(kind, std::move(external_name), std::move(readable_name),
     308             :                  signature, transitioning, body),
     309        3844 :         external_assembler_name_(std::move(external_assembler_name)) {
     310         961 :     if (signature.parameter_types.var_args) {
     311           0 :       ReportError("Varargs are not supported for macros.");
     312             :     }
     313         961 :   }
     314             : 
     315             :  private:
     316             :   friend class Declarations;
     317         917 :   Macro(std::string external_name, std::string readable_name,
     318             :         std::string external_assembler_name, const Signature& signature,
     319             :         bool transitioning, base::Optional<Statement*> body)
     320             :       : Macro(Declarable::kMacro, std::move(external_name),
     321             :               std::move(readable_name), external_assembler_name, signature,
     322        4585 :               transitioning, body) {}
     323             : 
     324             :   std::string external_assembler_name_;
     325             : };
     326             : 
     327          44 : class Method : public Macro {
     328             :  public:
     329        1136 :   DECLARE_DECLARABLE_BOILERPLATE(Method, Method)
     330        1038 :   bool ShouldBeInlined() const override {
     331        2076 :     return Macro::ShouldBeInlined() ||
     332             :            signature()
     333        1038 :                .parameter_types.types[signature().implicit_count]
     334        2076 :                ->IsStructType();
     335             :   }
     336             :   AggregateType* aggregate_type() const { return aggregate_type_; }
     337             : 
     338             :  private:
     339             :   friend class Declarations;
     340          44 :   Method(AggregateType* aggregate_type, std::string external_name,
     341             :          std::string readable_name, std::string external_assembler_name,
     342             :          const Signature& signature, bool transitioning, Statement* body)
     343             :       : Macro(Declarable::kMethod, std::move(external_name),
     344             :               std::move(readable_name), std::move(external_assembler_name),
     345             :               signature, transitioning, body),
     346         220 :         aggregate_type_(aggregate_type) {}
     347             :   AggregateType* aggregate_type_;
     348             : };
     349             : 
     350         150 : class Builtin : public Callable {
     351             :  public:
     352             :   enum Kind { kStub, kFixedArgsJavaScript, kVarArgsJavaScript };
     353       66962 :   DECLARE_DECLARABLE_BOILERPLATE(Builtin, builtin)
     354             :   Kind kind() const { return kind_; }
     355             :   bool IsStub() const { return kind_ == kStub; }
     356             :   bool IsVarArgsJavaScript() const { return kind_ == kVarArgsJavaScript; }
     357             :   bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; }
     358             : 
     359             :  private:
     360             :   friend class Declarations;
     361         150 :   Builtin(std::string external_name, std::string readable_name,
     362             :           Builtin::Kind kind, const Signature& signature, bool transitioning,
     363             :           base::Optional<Statement*> body)
     364             :       : Callable(Declarable::kBuiltin, std::move(external_name),
     365             :                  std::move(readable_name), signature, transitioning, body),
     366         600 :         kind_(kind) {}
     367             : 
     368             :   Kind kind_;
     369             : };
     370             : 
     371          14 : class RuntimeFunction : public Callable {
     372             :  public:
     373         260 :   DECLARE_DECLARABLE_BOILERPLATE(RuntimeFunction, runtime)
     374             : 
     375             :  private:
     376             :   friend class Declarations;
     377          14 :   RuntimeFunction(const std::string& name, const Signature& signature,
     378             :                   bool transitioning)
     379             :       : Callable(Declarable::kRuntimeFunction, name, name, signature,
     380          42 :                  transitioning, base::nullopt) {}
     381             : };
     382             : 
     383          66 : class Intrinsic : public Callable {
     384             :  public:
     385         198 :   DECLARE_DECLARABLE_BOILERPLATE(Intrinsic, intrinsic)
     386             : 
     387             :  private:
     388             :   friend class Declarations;
     389          66 :   Intrinsic(std::string name, const Signature& signature)
     390             :       : Callable(Declarable::kIntrinsic, name, name, signature, false,
     391         198 :                  base::nullopt) {
     392          66 :     if (signature.parameter_types.var_args) {
     393           0 :       ReportError("Varargs are not supported for intrinsics.");
     394             :     }
     395          66 :   }
     396             : };
     397             : 
     398         150 : class Generic : public Declarable {
     399             :  public:
     400       79698 :   DECLARE_DECLARABLE_BOILERPLATE(Generic, generic)
     401             : 
     402             :   GenericDeclaration* declaration() const { return declaration_; }
     403             :   const std::vector<std::string> generic_parameters() const {
     404             :     return declaration()->generic_parameters;
     405             :   }
     406             :   const std::string& name() const { return name_; }
     407             :   void AddSpecialization(const TypeVector& type_arguments,
     408             :                          Callable* specialization) {
     409             :     DCHECK_EQ(0, specializations_.count(type_arguments));
     410         326 :     specializations_[type_arguments] = specialization;
     411             :   }
     412       19187 :   base::Optional<Callable*> GetSpecialization(
     413             :       const TypeVector& type_arguments) const {
     414             :     auto it = specializations_.find(type_arguments);
     415       19187 :     if (it != specializations_.end()) return it->second;
     416             :     return base::nullopt;
     417             :   }
     418             :   base::Optional<TypeVector> InferSpecializationTypes(
     419             :       const TypeVector& explicit_specialization_types,
     420             :       const TypeVector& arguments);
     421             : 
     422             :  private:
     423             :   friend class Declarations;
     424          50 :   Generic(const std::string& name, GenericDeclaration* declaration)
     425             :       : Declarable(Declarable::kGeneric),
     426             :         name_(name),
     427         100 :         declaration_(declaration) {}
     428             :   base::Optional<const Type*> InferTypeArgument(size_t i,
     429             :                                                 const TypeVector& arguments);
     430             : 
     431             :   std::string name_;
     432             :   std::unordered_map<TypeVector, Callable*, base::hash<TypeVector>>
     433             :       specializations_;
     434             :   GenericDeclaration* declaration_;
     435             : };
     436             : 
     437             : struct SpecializationKey {
     438             :   Generic* generic;
     439             :   TypeVector specialized_types;
     440             : };
     441             : 
     442        9666 : class TypeAlias : public Declarable {
     443             :  public:
     444      229478 :   DECLARE_DECLARABLE_BOILERPLATE(TypeAlias, type_alias)
     445             : 
     446             :   const Type* type() const { return type_; }
     447             :   bool IsRedeclaration() const { return redeclaration_; }
     448             : 
     449             :  private:
     450             :   friend class Declarations;
     451             :   explicit TypeAlias(const Type* type, bool redeclaration)
     452             :       : Declarable(Declarable::kTypeAlias),
     453             :         type_(type),
     454        4833 :         redeclaration_(redeclaration) {}
     455             : 
     456             :   const Type* type_;
     457             :   bool redeclaration_;
     458             : };
     459             : 
     460             : std::ostream& operator<<(std::ostream& os, const Callable& m);
     461             : std::ostream& operator<<(std::ostream& os, const Builtin& b);
     462             : std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b);
     463             : std::ostream& operator<<(std::ostream& os, const Generic& g);
     464             : 
     465             : #undef DECLARE_DECLARABLE_BOILERPLATE
     466             : 
     467             : }  // namespace torque
     468             : }  // namespace internal
     469             : }  // namespace v8
     470             : 
     471             : #endif  // V8_TORQUE_DECLARABLE_H_

Generated by: LCOV version 1.10