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 11 #include "src/base/functional.h" 12 #include "src/base/logging.h" 13 #include "src/torque/ast.h" 14 #include "src/torque/types.h" 15 #include "src/torque/utils.h" 16 17 namespace v8 { 18 namespace internal { 19 namespace torque { 20 21 class Scope; 22 class ScopeChain; 23 class Generic; 24 25 class Declarable { 26 public: ~Declarable()27 virtual ~Declarable() {} 28 enum Kind { 29 kVariable, 30 kParameter, 31 kMacro, 32 kMacroList, 33 kBuiltin, 34 kRuntimeFunction, 35 kGeneric, 36 kGenericList, 37 kTypeAlias, 38 kLabel, 39 kExternConstant, 40 kModuleConstant 41 }; kind()42 Kind kind() const { return kind_; } IsMacro()43 bool IsMacro() const { return kind() == kMacro; } IsBuiltin()44 bool IsBuiltin() const { return kind() == kBuiltin; } IsRuntimeFunction()45 bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; } IsGeneric()46 bool IsGeneric() const { return kind() == kGeneric; } IsTypeAlias()47 bool IsTypeAlias() const { return kind() == kTypeAlias; } IsParameter()48 bool IsParameter() const { return kind() == kParameter; } IsLabel()49 bool IsLabel() const { return kind() == kLabel; } IsVariable()50 bool IsVariable() const { return kind() == kVariable; } IsMacroList()51 bool IsMacroList() const { return kind() == kMacroList; } IsGenericList()52 bool IsGenericList() const { return kind() == kGenericList; } IsExternConstant()53 bool IsExternConstant() const { return kind() == kExternConstant; } IsModuleConstant()54 bool IsModuleConstant() const { return kind() == kModuleConstant; } IsValue()55 bool IsValue() const { 56 return IsVariable() || IsExternConstant() || IsParameter() || 57 IsModuleConstant(); 58 } type_name()59 virtual const char* type_name() const { return "<<unknown>>"; } 60 61 protected: Declarable(Kind kind)62 explicit Declarable(Kind kind) : kind_(kind) {} 63 64 private: 65 const Kind kind_; 66 }; 67 68 #define DECLARE_DECLARABLE_BOILERPLATE(x, y) \ 69 static x* cast(Declarable* declarable) { \ 70 DCHECK(declarable->Is##x()); \ 71 return static_cast<x*>(declarable); \ 72 } \ 73 static const x* cast(const Declarable* declarable) { \ 74 DCHECK(declarable->Is##x()); \ 75 return static_cast<const x*>(declarable); \ 76 } \ 77 const char* type_name() const override { return #y; } \ 78 static x* DynamicCast(Declarable* declarable) { \ 79 if (!declarable) return nullptr; \ 80 if (!declarable->Is##x()) return nullptr; \ 81 return static_cast<x*>(declarable); \ 82 } \ 83 static const x* DynamicCast(const Declarable* declarable) { \ 84 if (!declarable) return nullptr; \ 85 if (!declarable->Is##x()) return nullptr; \ 86 return static_cast<const x*>(declarable); \ 87 } 88 89 class Value : public Declarable { 90 public: name()91 const std::string& name() const { return name_; } IsConst()92 virtual bool IsConst() const { return true; } 93 virtual std::string value() const = 0; RValue()94 virtual std::string RValue() const { return value(); } 95 DECLARE_DECLARABLE_BOILERPLATE(Value, value); type()96 const Type* type() const { return type_; } 97 98 protected: Value(Kind kind,const Type * type,const std::string & name)99 Value(Kind kind, const Type* type, const std::string& name) 100 : Declarable(kind), type_(type), name_(name) {} 101 102 private: 103 const Type* type_; 104 std::string name_; 105 }; 106 107 class Parameter : public Value { 108 public: 109 DECLARE_DECLARABLE_BOILERPLATE(Parameter, parameter); value()110 std::string value() const override { return var_name_; } 111 112 private: 113 friend class Declarations; Parameter(const std::string & name,const Type * type,const std::string & var_name)114 Parameter(const std::string& name, const Type* type, 115 const std::string& var_name) 116 : Value(Declarable::kParameter, type, name), var_name_(var_name) {} 117 118 std::string var_name_; 119 }; 120 121 class ModuleConstant : public Value { 122 public: 123 DECLARE_DECLARABLE_BOILERPLATE(ModuleConstant, constant); value()124 std::string value() const override { UNREACHABLE(); } RValue()125 std::string RValue() const override { return name() + "()"; } 126 127 private: 128 friend class Declarations; ModuleConstant(const std::string & name,const Type * type)129 explicit ModuleConstant(const std::string& name, const Type* type) 130 : Value(Declarable::kModuleConstant, type, name) {} 131 }; 132 133 class Variable : public Value { 134 public: 135 DECLARE_DECLARABLE_BOILERPLATE(Variable, variable); IsConst()136 bool IsConst() const override { return const_; } value()137 std::string value() const override { return value_; } 138 std::string RValue() const override; Define()139 void Define() { 140 if (defined_ && IsConst()) { 141 ReportError("Cannot re-define a const-bound variable."); 142 } 143 defined_ = true; 144 } IsDefined()145 bool IsDefined() const { return defined_; } 146 147 private: 148 friend class Declarations; Variable(const std::string & name,const std::string & value,const Type * type,bool is_const)149 Variable(const std::string& name, const std::string& value, const Type* type, 150 bool is_const) 151 : Value(Declarable::kVariable, type, name), 152 value_(value), 153 defined_(false), 154 const_(is_const) { 155 DCHECK_IMPLIES(type->IsConstexpr(), IsConst()); 156 } 157 158 std::string value_; 159 bool defined_; 160 bool const_; 161 }; 162 163 class Label : public Declarable { 164 public: AddVariable(Variable * var)165 void AddVariable(Variable* var) { parameters_.push_back(var); } name()166 std::string name() const { return name_; } generated()167 std::string generated() const { return generated_; } GetParameter(size_t i)168 Variable* GetParameter(size_t i) const { return parameters_[i]; } GetParameterCount()169 size_t GetParameterCount() const { return parameters_.size(); } GetParameters()170 const std::vector<Variable*>& GetParameters() const { return parameters_; } 171 172 DECLARE_DECLARABLE_BOILERPLATE(Label, label); MarkUsed()173 void MarkUsed() { used_ = true; } IsUsed()174 bool IsUsed() const { return used_; } 175 176 private: 177 friend class Declarations; Label(const std::string & name)178 explicit Label(const std::string& name) 179 : Declarable(Declarable::kLabel), 180 name_(name), 181 generated_("label_" + name + "_" + std::to_string(next_id_++)), 182 used_(false) {} 183 184 std::string name_; 185 std::string generated_; 186 std::vector<Variable*> parameters_; 187 static size_t next_id_; 188 bool used_; 189 }; 190 191 class ExternConstant : public Value { 192 public: 193 DECLARE_DECLARABLE_BOILERPLATE(ExternConstant, constant); value()194 std::string value() const override { return value_; } 195 196 private: 197 friend class Declarations; ExternConstant(const std::string & name,const Type * type,const std::string & value)198 explicit ExternConstant(const std::string& name, const Type* type, 199 const std::string& value) 200 : Value(Declarable::kExternConstant, type, name), value_(value) {} 201 202 std::string value_; 203 }; 204 205 class Callable : public Declarable { 206 public: cast(Declarable * declarable)207 static Callable* cast(Declarable* declarable) { 208 assert(declarable->IsMacro() || declarable->IsBuiltin() || 209 declarable->IsRuntimeFunction()); 210 return static_cast<Callable*>(declarable); 211 } cast(const Declarable * declarable)212 static const Callable* cast(const Declarable* declarable) { 213 assert(declarable->IsMacro() || declarable->IsBuiltin() || 214 declarable->IsRuntimeFunction()); 215 return static_cast<const Callable*>(declarable); 216 } name()217 const std::string& name() const { return name_; } signature()218 const Signature& signature() const { return signature_; } parameter_names()219 const NameVector& parameter_names() const { 220 return signature_.parameter_names; 221 } HasReturnValue()222 bool HasReturnValue() const { 223 return !signature_.return_type->IsVoidOrNever(); 224 } IncrementReturns()225 void IncrementReturns() { ++returns_; } HasReturns()226 bool HasReturns() const { return returns_; } generic()227 base::Optional<Generic*> generic() const { return generic_; } 228 229 protected: Callable(Declarable::Kind kind,const std::string & name,const Signature & signature,base::Optional<Generic * > generic)230 Callable(Declarable::Kind kind, const std::string& name, 231 const Signature& signature, base::Optional<Generic*> generic) 232 : Declarable(kind), 233 name_(name), 234 signature_(signature), 235 returns_(0), 236 generic_(generic) {} 237 238 private: 239 std::string name_; 240 Signature signature_; 241 size_t returns_; 242 base::Optional<Generic*> generic_; 243 }; 244 245 class Macro : public Callable { 246 public: 247 DECLARE_DECLARABLE_BOILERPLATE(Macro, macro); 248 249 private: 250 friend class Declarations; Macro(const std::string & name,const Signature & signature,base::Optional<Generic * > generic)251 Macro(const std::string& name, const Signature& signature, 252 base::Optional<Generic*> generic) 253 : Callable(Declarable::kMacro, name, signature, generic) { 254 if (signature.parameter_types.var_args) { 255 ReportError("Varargs are not supported for macros."); 256 } 257 } 258 }; 259 260 class MacroList : public Declarable { 261 public: 262 DECLARE_DECLARABLE_BOILERPLATE(MacroList, macro_list); list()263 const std::vector<Macro*>& list() { return list_; } AddMacro(Macro * macro)264 Macro* AddMacro(Macro* macro) { 265 list_.emplace_back(macro); 266 return macro; 267 } 268 269 private: 270 friend class Declarations; MacroList()271 MacroList() : Declarable(Declarable::kMacroList) {} 272 273 std::vector<Macro*> list_; 274 }; 275 276 class Builtin : public Callable { 277 public: 278 enum Kind { kStub, kFixedArgsJavaScript, kVarArgsJavaScript }; 279 DECLARE_DECLARABLE_BOILERPLATE(Builtin, builtin); kind()280 Kind kind() const { return kind_; } IsStub()281 bool IsStub() const { return kind_ == kStub; } IsVarArgsJavaScript()282 bool IsVarArgsJavaScript() const { return kind_ == kVarArgsJavaScript; } IsFixedArgsJavaScript()283 bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; } IsExternal()284 bool IsExternal() const { return external_; } 285 286 private: 287 friend class Declarations; Builtin(const std::string & name,Builtin::Kind kind,bool external,const Signature & signature,base::Optional<Generic * > generic)288 Builtin(const std::string& name, Builtin::Kind kind, bool external, 289 const Signature& signature, base::Optional<Generic*> generic) 290 : Callable(Declarable::kBuiltin, name, signature, generic), 291 kind_(kind), 292 external_(external) {} 293 294 Kind kind_; 295 bool external_; 296 }; 297 298 class RuntimeFunction : public Callable { 299 public: 300 DECLARE_DECLARABLE_BOILERPLATE(RuntimeFunction, runtime); 301 302 private: 303 friend class Declarations; RuntimeFunction(const std::string & name,const Signature & signature,base::Optional<Generic * > generic)304 RuntimeFunction(const std::string& name, const Signature& signature, 305 base::Optional<Generic*> generic) 306 : Callable(Declarable::kRuntimeFunction, name, signature, generic) {} 307 }; 308 309 class Generic : public Declarable { 310 public: 311 DECLARE_DECLARABLE_BOILERPLATE(Generic, generic); 312 declaration()313 GenericDeclaration* declaration() const { return declaration_; } name()314 const std::string& name() const { return name_; } module()315 Module* module() const { return module_; } 316 317 private: 318 friend class Declarations; Generic(const std::string & name,Module * module,GenericDeclaration * declaration)319 Generic(const std::string& name, Module* module, 320 GenericDeclaration* declaration) 321 : Declarable(Declarable::kGeneric), 322 name_(name), 323 module_(module), 324 declaration_(declaration) {} 325 326 std::string name_; 327 Module* module_; 328 GenericDeclaration* declaration_; 329 }; 330 331 class GenericList : public Declarable { 332 public: 333 DECLARE_DECLARABLE_BOILERPLATE(GenericList, generic_list); list()334 const std::vector<Generic*>& list() { return list_; } AddGeneric(Generic * generic)335 Generic* AddGeneric(Generic* generic) { 336 list_.push_back(generic); 337 return generic; 338 } 339 340 private: 341 friend class Declarations; GenericList()342 GenericList() : Declarable(Declarable::kGenericList) {} 343 344 std::vector<Generic*> list_; 345 }; 346 347 typedef std::pair<Generic*, TypeVector> SpecializationKey; 348 349 class TypeAlias : public Declarable { 350 public: 351 DECLARE_DECLARABLE_BOILERPLATE(TypeAlias, type_alias); 352 type()353 const Type* type() const { return type_; } 354 355 private: 356 friend class Declarations; TypeAlias(const Type * type)357 explicit TypeAlias(const Type* type) 358 : Declarable(Declarable::kTypeAlias), type_(type) {} 359 360 const Type* type_; 361 }; 362 363 void PrintLabel(std::ostream& os, const Label& l, bool with_names); 364 365 std::ostream& operator<<(std::ostream& os, const Callable& m); 366 std::ostream& operator<<(std::ostream& os, const Variable& v); 367 std::ostream& operator<<(std::ostream& os, const Builtin& b); 368 std::ostream& operator<<(std::ostream& os, const Label& l); 369 std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b); 370 std::ostream& operator<<(std::ostream& os, const Generic& g); 371 372 #undef DECLARE_DECLARABLE_BOILERPLATE 373 374 } // namespace torque 375 } // namespace internal 376 } // namespace v8 377 378 #endif // V8_TORQUE_DECLARABLE_H_ 379