LCOV - code coverage report
Current view: top level - js/src/wasm - WasmAST.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 413 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 223 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  *
       4             :  * Copyright 2015 Mozilla Foundation
       5             :  *
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at
       9             :  *
      10             :  *     http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  */
      18             : 
      19             : #ifndef wasmast_h
      20             : #define wasmast_h
      21             : 
      22             : #include "ds/LifoAlloc.h"
      23             : #include "js/HashTable.h"
      24             : #include "js/Vector.h"
      25             : #include "wasm/WasmTypes.h"
      26             : 
      27             : namespace js {
      28             : namespace wasm {
      29             : 
      30             : const uint32_t AstNoIndex = UINT32_MAX;
      31             : const unsigned AST_LIFO_DEFAULT_CHUNK_SIZE = 4096;
      32             : 
      33             : /*****************************************************************************/
      34             : // wasm AST
      35             : 
      36             : class AstExpr;
      37             : 
      38             : template <class T>
      39             : using AstVector = mozilla::Vector<T, 0, LifoAllocPolicy<Fallible>>;
      40             : 
      41             : template <class K, class V, class HP>
      42             : using AstHashMap = HashMap<K, V, HP, LifoAllocPolicy<Fallible>>;
      43             : 
      44             : class AstName
      45             : {
      46             :     const char16_t* begin_;
      47             :     const char16_t* end_;
      48             :   public:
      49             :     template <size_t Length>
      50           0 :     explicit AstName(const char16_t (&str)[Length]) : begin_(str), end_(str + Length - 1) {
      51           0 :       MOZ_ASSERT(str[Length - 1] == u'\0');
      52           0 :     }
      53             : 
      54           0 :     AstName(const char16_t* begin, size_t length) : begin_(begin), end_(begin + length) {}
      55           0 :     AstName() : begin_(nullptr), end_(nullptr) {}
      56           0 :     const char16_t* begin() const { return begin_; }
      57           0 :     const char16_t* end() const { return end_; }
      58           0 :     size_t length() const { return end_ - begin_; }
      59           0 :     bool empty() const { return begin_ == nullptr; }
      60             : 
      61           0 :     bool operator==(AstName rhs) const {
      62           0 :         if (length() != rhs.length())
      63           0 :             return false;
      64           0 :         if (begin() == rhs.begin())
      65           0 :             return true;
      66           0 :         return EqualChars(begin(), rhs.begin(), length());
      67             :     }
      68           0 :     bool operator!=(AstName rhs) const {
      69           0 :         return !(*this == rhs);
      70             :     }
      71             : };
      72             : 
      73             : class AstRef
      74             : {
      75             :     AstName name_;
      76             :     uint32_t index_;
      77             : 
      78             :   public:
      79           0 :     AstRef() : index_(AstNoIndex) {
      80           0 :         MOZ_ASSERT(isInvalid());
      81           0 :     }
      82           0 :     explicit AstRef(AstName name) : name_(name), index_(AstNoIndex) {
      83           0 :         MOZ_ASSERT(!isInvalid());
      84           0 :     }
      85           0 :     explicit AstRef(uint32_t index) : index_(index) {
      86           0 :         MOZ_ASSERT(!isInvalid());
      87           0 :     }
      88           0 :     bool isInvalid() const {
      89           0 :         return name_.empty() && index_ == AstNoIndex;
      90             :     }
      91           0 :     AstName name() const {
      92           0 :         return name_;
      93             :     }
      94           0 :     size_t index() const {
      95           0 :         MOZ_ASSERT(index_ != AstNoIndex);
      96           0 :         return index_;
      97             :     }
      98           0 :     void setIndex(uint32_t index) {
      99           0 :         MOZ_ASSERT(index_ == AstNoIndex);
     100           0 :         index_ = index;
     101           0 :     }
     102             : };
     103             : 
     104             : struct AstNameHasher
     105             : {
     106             :     typedef const AstName Lookup;
     107           0 :     static js::HashNumber hash(Lookup l) {
     108           0 :         return mozilla::HashString(l.begin(), l.length());
     109             :     }
     110           0 :     static bool match(const AstName key, Lookup lookup) {
     111           0 :         return key == lookup;
     112             :     }
     113             : };
     114             : 
     115             : using AstNameMap = AstHashMap<AstName, uint32_t, AstNameHasher>;
     116             : 
     117             : typedef AstVector<ValType> AstValTypeVector;
     118             : typedef AstVector<AstExpr*> AstExprVector;
     119             : typedef AstVector<AstName> AstNameVector;
     120             : typedef AstVector<AstRef> AstRefVector;
     121             : 
     122           0 : struct AstBase
     123             : {
     124           0 :     void* operator new(size_t numBytes, LifoAlloc& astLifo) throw() {
     125           0 :         return astLifo.alloc(numBytes);
     126             :     }
     127             : };
     128             : 
     129           0 : class AstSig : public AstBase
     130             : {
     131             :     AstName name_;
     132             :     AstValTypeVector args_;
     133             :     ExprType ret_;
     134             : 
     135             :   public:
     136           0 :     explicit AstSig(LifoAlloc& lifo)
     137           0 :       : args_(lifo),
     138           0 :         ret_(ExprType::Void)
     139           0 :     {}
     140           0 :     AstSig(AstValTypeVector&& args, ExprType ret)
     141           0 :       : args_(Move(args)),
     142           0 :         ret_(ret)
     143           0 :     {}
     144           0 :     AstSig(AstName name, AstSig&& rhs)
     145           0 :       : name_(name),
     146           0 :         args_(Move(rhs.args_)),
     147           0 :         ret_(rhs.ret_)
     148           0 :     {}
     149           0 :     const AstValTypeVector& args() const {
     150           0 :         return args_;
     151             :     }
     152           0 :     ExprType ret() const {
     153           0 :         return ret_;
     154             :     }
     155           0 :     AstName name() const {
     156           0 :         return name_;
     157             :     }
     158           0 :     bool operator==(const AstSig& rhs) const {
     159           0 :         return ret() == rhs.ret() && EqualContainers(args(), rhs.args());
     160             :     }
     161             : 
     162             :     typedef const AstSig& Lookup;
     163           0 :     static HashNumber hash(Lookup sig) {
     164           0 :         return AddContainerToHash(sig.args(), HashNumber(sig.ret()));
     165             :     }
     166           0 :     static bool match(const AstSig* lhs, Lookup rhs) {
     167           0 :         return *lhs == rhs;
     168             :     }
     169             : };
     170             : 
     171             : const uint32_t AstNodeUnknownOffset = 0;
     172             : 
     173             : class AstNode : public AstBase
     174             : {
     175             :     uint32_t offset_; // if applicable, offset in the binary format file
     176             : 
     177             :   public:
     178           0 :     AstNode() : offset_(AstNodeUnknownOffset) {}
     179             : 
     180           0 :     uint32_t offset() const { return offset_; }
     181           0 :     void setOffset(uint32_t offset) { offset_ = offset; }
     182             : };
     183             : 
     184             : enum class AstExprKind
     185             : {
     186             :     BinaryOperator,
     187             :     Block,
     188             :     Branch,
     189             :     BranchTable,
     190             :     Call,
     191             :     CallIndirect,
     192             :     ComparisonOperator,
     193             :     Const,
     194             :     ConversionOperator,
     195             :     CurrentMemory,
     196             :     Drop,
     197             :     First,
     198             :     GetGlobal,
     199             :     GetLocal,
     200             :     GrowMemory,
     201             :     If,
     202             :     Load,
     203             :     Nop,
     204             :     Pop,
     205             :     Return,
     206             :     SetGlobal,
     207             :     SetLocal,
     208             :     TeeLocal,
     209             :     Store,
     210             :     TernaryOperator,
     211             :     UnaryOperator,
     212             :     Unreachable
     213             : };
     214             : 
     215             : class AstExpr : public AstNode
     216             : {
     217             :     const AstExprKind kind_;
     218             :     ExprType type_;
     219             : 
     220             :   protected:
     221           0 :     AstExpr(AstExprKind kind, ExprType type)
     222           0 :       : kind_(kind), type_(type)
     223           0 :     {}
     224             : 
     225             :   public:
     226           0 :     AstExprKind kind() const { return kind_; }
     227             : 
     228           0 :     bool isVoid() const { return IsVoid(type_); }
     229             : 
     230             :     // Note that for nodes other than blocks and block-like things, this
     231             :     // may return ExprType::Limit for nodes with non-void types.
     232           0 :     ExprType type() const { return type_; }
     233             : 
     234             :     template <class T>
     235           0 :     T& as() {
     236           0 :         MOZ_ASSERT(kind() == T::Kind);
     237           0 :         return static_cast<T&>(*this);
     238             :     }
     239             : };
     240             : 
     241             : struct AstNop : AstExpr
     242             : {
     243             :    static const AstExprKind Kind = AstExprKind::Nop;
     244           0 :    AstNop()
     245           0 :       : AstExpr(AstExprKind::Nop, ExprType::Void)
     246           0 :    {}
     247             : };
     248             : 
     249             : struct AstUnreachable : AstExpr
     250             : {
     251             :     static const AstExprKind Kind = AstExprKind::Unreachable;
     252           0 :     AstUnreachable()
     253           0 :       : AstExpr(AstExprKind::Unreachable, ExprType::Void)
     254           0 :     {}
     255             : };
     256             : 
     257             : class AstDrop : public AstExpr
     258             : {
     259             :     AstExpr& value_;
     260             : 
     261             :   public:
     262             :     static const AstExprKind Kind = AstExprKind::Drop;
     263           0 :     explicit AstDrop(AstExpr& value)
     264           0 :       : AstExpr(AstExprKind::Drop, ExprType::Void),
     265           0 :         value_(value)
     266           0 :     {}
     267           0 :     AstExpr& value() const {
     268           0 :         return value_;
     269             :     }
     270             : };
     271             : 
     272             : class AstConst : public AstExpr
     273             : {
     274             :     const Val val_;
     275             : 
     276             :   public:
     277             :     static const AstExprKind Kind = AstExprKind::Const;
     278           0 :     explicit AstConst(Val val)
     279           0 :       : AstExpr(Kind, ExprType::Limit),
     280           0 :         val_(val)
     281           0 :     {}
     282           0 :     Val val() const { return val_; }
     283             : };
     284             : 
     285             : class AstGetLocal : public AstExpr
     286             : {
     287             :     AstRef local_;
     288             : 
     289             :   public:
     290             :     static const AstExprKind Kind = AstExprKind::GetLocal;
     291           0 :     explicit AstGetLocal(AstRef local)
     292           0 :       : AstExpr(Kind, ExprType::Limit),
     293           0 :         local_(local)
     294           0 :     {}
     295           0 :     AstRef& local() {
     296           0 :         return local_;
     297             :     }
     298             : };
     299             : 
     300             : class AstSetLocal : public AstExpr
     301             : {
     302             :     AstRef local_;
     303             :     AstExpr& value_;
     304             : 
     305             :   public:
     306             :     static const AstExprKind Kind = AstExprKind::SetLocal;
     307           0 :     AstSetLocal(AstRef local, AstExpr& value)
     308           0 :       : AstExpr(Kind, ExprType::Void),
     309             :         local_(local),
     310           0 :         value_(value)
     311           0 :     {}
     312           0 :     AstRef& local() {
     313           0 :         return local_;
     314             :     }
     315           0 :     AstExpr& value() const {
     316           0 :         return value_;
     317             :     }
     318             : };
     319             : 
     320             : class AstGetGlobal : public AstExpr
     321             : {
     322             :     AstRef global_;
     323             : 
     324             :   public:
     325             :     static const AstExprKind Kind = AstExprKind::GetGlobal;
     326           0 :     explicit AstGetGlobal(AstRef global)
     327           0 :       : AstExpr(Kind, ExprType::Limit),
     328           0 :         global_(global)
     329           0 :     {}
     330           0 :     AstRef& global() {
     331           0 :         return global_;
     332             :     }
     333             : };
     334             : 
     335             : class AstSetGlobal : public AstExpr
     336             : {
     337             :     AstRef global_;
     338             :     AstExpr& value_;
     339             : 
     340             :   public:
     341             :     static const AstExprKind Kind = AstExprKind::SetGlobal;
     342           0 :     AstSetGlobal(AstRef global, AstExpr& value)
     343           0 :       : AstExpr(Kind, ExprType::Void),
     344             :         global_(global),
     345           0 :         value_(value)
     346           0 :     {}
     347           0 :     AstRef& global() {
     348           0 :         return global_;
     349             :     }
     350           0 :     AstExpr& value() const {
     351           0 :         return value_;
     352             :     }
     353             : };
     354             : 
     355             : class AstTeeLocal : public AstExpr
     356             : {
     357             :     AstRef local_;
     358             :     AstExpr& value_;
     359             : 
     360             :   public:
     361             :     static const AstExprKind Kind = AstExprKind::TeeLocal;
     362           0 :     AstTeeLocal(AstRef local, AstExpr& value)
     363           0 :       : AstExpr(Kind, ExprType::Limit),
     364             :         local_(local),
     365           0 :         value_(value)
     366           0 :     {}
     367           0 :     AstRef& local() {
     368           0 :         return local_;
     369             :     }
     370           0 :     AstExpr& value() const {
     371           0 :         return value_;
     372             :     }
     373             : };
     374             : 
     375             : class AstBlock : public AstExpr
     376             : {
     377             :     Op op_;
     378             :     AstName name_;
     379             :     AstExprVector exprs_;
     380             : 
     381             :   public:
     382             :     static const AstExprKind Kind = AstExprKind::Block;
     383           0 :     explicit AstBlock(Op op, ExprType type, AstName name, AstExprVector&& exprs)
     384           0 :       : AstExpr(Kind, type),
     385             :         op_(op),
     386             :         name_(name),
     387           0 :         exprs_(Move(exprs))
     388           0 :     {}
     389             : 
     390           0 :     Op op() const { return op_; }
     391           0 :     AstName name() const { return name_; }
     392           0 :     const AstExprVector& exprs() const { return exprs_; }
     393             : };
     394             : 
     395             : class AstBranch : public AstExpr
     396             : {
     397             :     Op op_;
     398             :     AstExpr* cond_;
     399             :     AstRef target_;
     400             :     AstExpr* value_;
     401             : 
     402             :   public:
     403             :     static const AstExprKind Kind = AstExprKind::Branch;
     404           0 :     explicit AstBranch(Op op, ExprType type,
     405             :                        AstExpr* cond, AstRef target, AstExpr* value)
     406           0 :       : AstExpr(Kind, type),
     407             :         op_(op),
     408             :         cond_(cond),
     409             :         target_(target),
     410           0 :         value_(value)
     411           0 :     {}
     412             : 
     413           0 :     Op op() const { return op_; }
     414           0 :     AstRef& target() { return target_; }
     415           0 :     AstExpr& cond() const { MOZ_ASSERT(cond_); return *cond_; }
     416           0 :     AstExpr* maybeValue() const { return value_; }
     417             : };
     418             : 
     419             : class AstCall : public AstExpr
     420             : {
     421             :     Op op_;
     422             :     AstRef func_;
     423             :     AstExprVector args_;
     424             : 
     425             :   public:
     426             :     static const AstExprKind Kind = AstExprKind::Call;
     427           0 :     AstCall(Op op, ExprType type, AstRef func, AstExprVector&& args)
     428           0 :       : AstExpr(Kind, type), op_(op), func_(func), args_(Move(args))
     429           0 :     {}
     430             : 
     431           0 :     Op op() const { return op_; }
     432           0 :     AstRef& func() { return func_; }
     433           0 :     const AstExprVector& args() const { return args_; }
     434             : };
     435             : 
     436             : class AstCallIndirect : public AstExpr
     437             : {
     438             :     AstRef sig_;
     439             :     AstExprVector args_;
     440             :     AstExpr* index_;
     441             : 
     442             :   public:
     443             :     static const AstExprKind Kind = AstExprKind::CallIndirect;
     444           0 :     AstCallIndirect(AstRef sig, ExprType type, AstExprVector&& args, AstExpr* index)
     445           0 :       : AstExpr(Kind, type), sig_(sig), args_(Move(args)), index_(index)
     446           0 :     {}
     447           0 :     AstRef& sig() { return sig_; }
     448           0 :     const AstExprVector& args() const { return args_; }
     449           0 :     AstExpr* index() const { return index_; }
     450             : };
     451             : 
     452             : class AstReturn : public AstExpr
     453             : {
     454             :     AstExpr* maybeExpr_;
     455             : 
     456             :   public:
     457             :     static const AstExprKind Kind = AstExprKind::Return;
     458           0 :     explicit AstReturn(AstExpr* maybeExpr)
     459           0 :       : AstExpr(Kind, ExprType::Void),
     460           0 :         maybeExpr_(maybeExpr)
     461           0 :     {}
     462           0 :     AstExpr* maybeExpr() const { return maybeExpr_; }
     463             : };
     464             : 
     465             : class AstIf : public AstExpr
     466             : {
     467             :     AstExpr* cond_;
     468             :     AstName name_;
     469             :     AstExprVector thenExprs_;
     470             :     AstExprVector elseExprs_;
     471             : 
     472             :   public:
     473             :     static const AstExprKind Kind = AstExprKind::If;
     474           0 :     AstIf(ExprType type, AstExpr* cond, AstName name,
     475             :           AstExprVector&& thenExprs, AstExprVector&& elseExprs)
     476           0 :       : AstExpr(Kind, type),
     477             :         cond_(cond),
     478             :         name_(name),
     479           0 :         thenExprs_(Move(thenExprs)),
     480           0 :         elseExprs_(Move(elseExprs))
     481           0 :     {}
     482             : 
     483           0 :     AstExpr& cond() const { return *cond_; }
     484           0 :     const AstExprVector& thenExprs() const { return thenExprs_; }
     485           0 :     bool hasElse() const { return elseExprs_.length(); }
     486           0 :     const AstExprVector& elseExprs() const { MOZ_ASSERT(hasElse()); return elseExprs_; }
     487           0 :     AstName name() const { return name_; }
     488             : };
     489             : 
     490             : class AstLoadStoreAddress
     491             : {
     492             :     AstExpr* base_;
     493             :     int32_t flags_;
     494             :     int32_t offset_;
     495             : 
     496             :   public:
     497           0 :     explicit AstLoadStoreAddress(AstExpr* base, int32_t flags, int32_t offset)
     498           0 :       : base_(base),
     499             :         flags_(flags),
     500           0 :         offset_(offset)
     501           0 :     {}
     502             : 
     503           0 :     AstExpr& base() const { return *base_; }
     504           0 :     int32_t flags() const { return flags_; }
     505           0 :     int32_t offset() const { return offset_; }
     506             : };
     507             : 
     508             : class AstLoad : public AstExpr
     509             : {
     510             :     Op op_;
     511             :     AstLoadStoreAddress address_;
     512             : 
     513             :   public:
     514             :     static const AstExprKind Kind = AstExprKind::Load;
     515           0 :     explicit AstLoad(Op op, const AstLoadStoreAddress &address)
     516           0 :       : AstExpr(Kind, ExprType::Limit),
     517             :         op_(op),
     518           0 :         address_(address)
     519           0 :     {}
     520             : 
     521           0 :     Op op() const { return op_; }
     522           0 :     const AstLoadStoreAddress& address() const { return address_; }
     523             : };
     524             : 
     525             : class AstStore : public AstExpr
     526             : {
     527             :     Op op_;
     528             :     AstLoadStoreAddress address_;
     529             :     AstExpr* value_;
     530             : 
     531             :   public:
     532             :     static const AstExprKind Kind = AstExprKind::Store;
     533           0 :     explicit AstStore(Op op, const AstLoadStoreAddress &address, AstExpr* value)
     534           0 :       : AstExpr(Kind, ExprType::Void),
     535             :         op_(op),
     536             :         address_(address),
     537           0 :         value_(value)
     538           0 :     {}
     539             : 
     540           0 :     Op op() const { return op_; }
     541           0 :     const AstLoadStoreAddress& address() const { return address_; }
     542           0 :     AstExpr& value() const { return *value_; }
     543             : };
     544             : 
     545             : class AstCurrentMemory final : public AstExpr
     546             : {
     547             :   public:
     548             :     static const AstExprKind Kind = AstExprKind::CurrentMemory;
     549           0 :     explicit AstCurrentMemory()
     550           0 :       : AstExpr(Kind, ExprType::I32)
     551           0 :     {}
     552             : };
     553             : 
     554             : class AstGrowMemory final : public AstExpr
     555             : {
     556             :     AstExpr* operand_;
     557             : 
     558             :   public:
     559             :     static const AstExprKind Kind = AstExprKind::GrowMemory;
     560           0 :     explicit AstGrowMemory(AstExpr* operand)
     561           0 :       : AstExpr(Kind, ExprType::I32), operand_(operand)
     562           0 :     {}
     563             : 
     564           0 :     AstExpr* operand() const { return operand_; }
     565             : };
     566             : 
     567             : class AstBranchTable : public AstExpr
     568             : {
     569             :     AstExpr& index_;
     570             :     AstRef default_;
     571             :     AstRefVector table_;
     572             :     AstExpr* value_;
     573             : 
     574             :   public:
     575             :     static const AstExprKind Kind = AstExprKind::BranchTable;
     576           0 :     explicit AstBranchTable(AstExpr& index, AstRef def, AstRefVector&& table,
     577             :                             AstExpr* maybeValue)
     578           0 :       : AstExpr(Kind, ExprType::Void),
     579             :         index_(index),
     580             :         default_(def),
     581           0 :         table_(Move(table)),
     582           0 :         value_(maybeValue)
     583           0 :     {}
     584           0 :     AstExpr& index() const { return index_; }
     585           0 :     AstRef& def() { return default_; }
     586           0 :     AstRefVector& table() { return table_; }
     587           0 :     AstExpr* maybeValue() { return value_; }
     588             : };
     589             : 
     590             : class AstFunc : public AstNode
     591             : {
     592             :     AstName name_;
     593             :     AstRef sig_;
     594             :     AstValTypeVector vars_;
     595             :     AstNameVector localNames_;
     596             :     AstExprVector body_;
     597             :     uint32_t endOffset_; // if applicable, offset in the binary format file
     598             : 
     599             :   public:
     600           0 :     AstFunc(AstName name, AstRef sig, AstValTypeVector&& vars,
     601             :                 AstNameVector&& locals, AstExprVector&& body)
     602           0 :       : name_(name),
     603             :         sig_(sig),
     604           0 :         vars_(Move(vars)),
     605           0 :         localNames_(Move(locals)),
     606           0 :         body_(Move(body)),
     607           0 :         endOffset_(AstNodeUnknownOffset)
     608           0 :     {}
     609           0 :     AstRef& sig() { return sig_; }
     610           0 :     const AstValTypeVector& vars() const { return vars_; }
     611           0 :     const AstNameVector& locals() const { return localNames_; }
     612           0 :     const AstExprVector& body() const { return body_; }
     613           0 :     AstName name() const { return name_; }
     614           0 :     uint32_t endOffset() const { return endOffset_; }
     615           0 :     void setEndOffset(uint32_t offset) { endOffset_ = offset; }
     616             : };
     617             : 
     618           0 : class AstGlobal : public AstNode
     619             : {
     620             :     AstName name_;
     621             :     bool isMutable_;
     622             :     ValType type_;
     623             :     Maybe<AstExpr*> init_;
     624             : 
     625             :   public:
     626           0 :     AstGlobal() : isMutable_(false), type_(ValType(TypeCode::Limit))
     627           0 :     {}
     628             : 
     629           0 :     explicit AstGlobal(AstName name, ValType type, bool isMutable,
     630             :                        const Maybe<AstExpr*>& init = Maybe<AstExpr*>())
     631           0 :       : name_(name), isMutable_(isMutable), type_(type), init_(init)
     632           0 :     {}
     633             : 
     634           0 :     AstName name() const { return name_; }
     635           0 :     bool isMutable() const { return isMutable_; }
     636           0 :     ValType type() const { return type_; }
     637             : 
     638           0 :     bool hasInit() const { return !!init_; }
     639           0 :     AstExpr& init() const { MOZ_ASSERT(hasInit()); return **init_; }
     640             : };
     641             : 
     642             : typedef AstVector<AstGlobal*> AstGlobalVector;
     643             : 
     644             : class AstImport : public AstNode
     645             : {
     646             :     AstName name_;
     647             :     AstName module_;
     648             :     AstName field_;
     649             :     DefinitionKind kind_;
     650             : 
     651             :     AstRef funcSig_;
     652             :     Limits limits_;
     653             :     AstGlobal global_;
     654             : 
     655             :   public:
     656           0 :     AstImport(AstName name, AstName module, AstName field, AstRef funcSig)
     657           0 :       : name_(name), module_(module), field_(field), kind_(DefinitionKind::Function), funcSig_(funcSig)
     658           0 :     {}
     659           0 :     AstImport(AstName name, AstName module, AstName field, DefinitionKind kind,
     660             :               const Limits& limits)
     661           0 :       : name_(name), module_(module), field_(field), kind_(kind), limits_(limits)
     662           0 :     {}
     663           0 :     AstImport(AstName name, AstName module, AstName field, const AstGlobal& global)
     664           0 :       : name_(name), module_(module), field_(field), kind_(DefinitionKind::Global), global_(global)
     665           0 :     {}
     666             : 
     667           0 :     AstName name() const { return name_; }
     668           0 :     AstName module() const { return module_; }
     669           0 :     AstName field() const { return field_; }
     670             : 
     671           0 :     DefinitionKind kind() const { return kind_; }
     672           0 :     AstRef& funcSig() {
     673           0 :         MOZ_ASSERT(kind_ == DefinitionKind::Function);
     674           0 :         return funcSig_;
     675             :     }
     676           0 :     Limits limits() const {
     677           0 :         MOZ_ASSERT(kind_ == DefinitionKind::Memory || kind_ == DefinitionKind::Table);
     678           0 :         return limits_;
     679             :     }
     680           0 :     const AstGlobal& global() const {
     681           0 :         MOZ_ASSERT(kind_ == DefinitionKind::Global);
     682           0 :         return global_;
     683             :     }
     684             : };
     685             : 
     686             : class AstExport : public AstNode
     687             : {
     688             :     AstName name_;
     689             :     DefinitionKind kind_;
     690             :     AstRef ref_;
     691             : 
     692             :   public:
     693           0 :     AstExport(AstName name, DefinitionKind kind, AstRef ref)
     694           0 :       : name_(name), kind_(kind), ref_(ref)
     695           0 :     {}
     696             :     explicit AstExport(AstName name, DefinitionKind kind)
     697             :       : name_(name), kind_(kind)
     698             :     {}
     699           0 :     AstName name() const { return name_; }
     700           0 :     DefinitionKind kind() const { return kind_; }
     701           0 :     AstRef& ref() { return ref_; }
     702             : };
     703             : 
     704             : class AstDataSegment : public AstNode
     705             : {
     706             :     AstExpr* offset_;
     707             :     AstNameVector fragments_;
     708             : 
     709             :   public:
     710           0 :     AstDataSegment(AstExpr* offset, AstNameVector&& fragments)
     711           0 :       : offset_(offset), fragments_(Move(fragments))
     712           0 :     {}
     713             : 
     714           0 :     AstExpr* offset() const { return offset_; }
     715           0 :     const AstNameVector& fragments() const { return fragments_; }
     716             : };
     717             : 
     718             : typedef AstVector<AstDataSegment*> AstDataSegmentVector;
     719             : 
     720             : class AstElemSegment : public AstNode
     721             : {
     722             :     AstExpr* offset_;
     723             :     AstRefVector elems_;
     724             : 
     725             :   public:
     726           0 :     AstElemSegment(AstExpr* offset, AstRefVector&& elems)
     727           0 :       : offset_(offset), elems_(Move(elems))
     728           0 :     {}
     729             : 
     730           0 :     AstExpr* offset() const { return offset_; }
     731           0 :     AstRefVector& elems() { return elems_; }
     732           0 :     const AstRefVector& elems() const { return elems_; }
     733             : };
     734             : 
     735             : typedef AstVector<AstElemSegment*> AstElemSegmentVector;
     736             : 
     737             : class AstStartFunc : public AstNode
     738             : {
     739             :     AstRef func_;
     740             : 
     741             :   public:
     742           0 :     explicit AstStartFunc(AstRef func)
     743           0 :       : func_(func)
     744           0 :     {}
     745             : 
     746           0 :     AstRef& func() {
     747           0 :         return func_;
     748             :     }
     749             : };
     750             : 
     751           0 : struct AstResizable
     752             : {
     753             :     AstName name;
     754             :     Limits limits;
     755             :     bool imported;
     756             : 
     757           0 :     AstResizable(const Limits& limits, bool imported, AstName name = AstName())
     758           0 :       : name(name),
     759             :         limits(limits),
     760           0 :         imported(imported)
     761           0 :     {}
     762             : };
     763             : 
     764             : class AstModule : public AstNode
     765             : {
     766             :   public:
     767             :     typedef AstVector<AstFunc*> FuncVector;
     768             :     typedef AstVector<AstImport*> ImportVector;
     769             :     typedef AstVector<AstExport*> ExportVector;
     770             :     typedef AstVector<AstSig*> SigVector;
     771             :     typedef AstVector<AstName> NameVector;
     772             :     typedef AstVector<AstResizable> AstResizableVector;
     773             : 
     774             :   private:
     775             :     typedef AstHashMap<AstSig*, uint32_t, AstSig> SigMap;
     776             : 
     777             :     LifoAlloc&           lifo_;
     778             :     SigVector            sigs_;
     779             :     SigMap               sigMap_;
     780             :     ImportVector         imports_;
     781             :     NameVector           funcImportNames_;
     782             :     AstResizableVector   tables_;
     783             :     AstResizableVector   memories_;
     784             :     ExportVector         exports_;
     785             :     Maybe<AstStartFunc>  startFunc_;
     786             :     FuncVector           funcs_;
     787             :     AstDataSegmentVector dataSegments_;
     788             :     AstElemSegmentVector elemSegments_;
     789             :     AstGlobalVector      globals_;
     790             : 
     791             :   public:
     792           0 :     explicit AstModule(LifoAlloc& lifo)
     793           0 :       : lifo_(lifo),
     794             :         sigs_(lifo),
     795             :         sigMap_(lifo),
     796             :         imports_(lifo),
     797             :         funcImportNames_(lifo),
     798             :         tables_(lifo),
     799             :         memories_(lifo),
     800             :         exports_(lifo),
     801             :         funcs_(lifo),
     802             :         dataSegments_(lifo),
     803             :         elemSegments_(lifo),
     804           0 :         globals_(lifo)
     805           0 :     {}
     806           0 :     bool init() {
     807           0 :         return sigMap_.init();
     808             :     }
     809           0 :     bool addMemory(AstName name, const Limits& memory) {
     810           0 :         return memories_.append(AstResizable(memory, false, name));
     811             :     }
     812           0 :     bool hasMemory() const {
     813           0 :         return !!memories_.length();
     814             :     }
     815           0 :     const AstResizableVector& memories() const {
     816           0 :         return memories_;
     817             :     }
     818           0 :     bool addTable(AstName name, const Limits& table) {
     819           0 :         return tables_.append(AstResizable(table, false, name));
     820             :     }
     821           0 :     bool hasTable() const {
     822           0 :         return !!tables_.length();
     823             :     }
     824           0 :     const AstResizableVector& tables() const {
     825           0 :         return tables_;
     826             :     }
     827           0 :     bool append(AstDataSegment* seg) {
     828           0 :         return dataSegments_.append(seg);
     829             :     }
     830           0 :     const AstDataSegmentVector& dataSegments() const {
     831           0 :         return dataSegments_;
     832             :     }
     833           0 :     bool append(AstElemSegment* seg) {
     834           0 :         return elemSegments_.append(seg);
     835             :     }
     836           0 :     const AstElemSegmentVector& elemSegments() const {
     837           0 :         return elemSegments_;
     838             :     }
     839           0 :     bool hasStartFunc() const {
     840           0 :         return !!startFunc_;
     841             :     }
     842           0 :     bool setStartFunc(AstStartFunc startFunc) {
     843           0 :         if (startFunc_)
     844           0 :             return false;
     845           0 :         startFunc_.emplace(startFunc);
     846           0 :         return true;
     847             :     }
     848           0 :     AstStartFunc& startFunc() {
     849           0 :         return *startFunc_;
     850             :     }
     851           0 :     bool declare(AstSig&& sig, uint32_t* sigIndex) {
     852           0 :         SigMap::AddPtr p = sigMap_.lookupForAdd(sig);
     853           0 :         if (p) {
     854           0 :             *sigIndex = p->value();
     855           0 :             return true;
     856             :         }
     857           0 :         *sigIndex = sigs_.length();
     858           0 :         auto* lifoSig = new (lifo_) AstSig(AstName(), Move(sig));
     859           0 :         return lifoSig &&
     860           0 :                sigs_.append(lifoSig) &&
     861           0 :                sigMap_.add(p, sigs_.back(), *sigIndex);
     862             :     }
     863           0 :     bool append(AstSig* sig) {
     864           0 :         uint32_t sigIndex = sigs_.length();
     865           0 :         if (!sigs_.append(sig))
     866           0 :             return false;
     867           0 :         SigMap::AddPtr p = sigMap_.lookupForAdd(*sig);
     868           0 :         return p || sigMap_.add(p, sig, sigIndex);
     869             :     }
     870           0 :     const SigVector& sigs() const {
     871           0 :         return sigs_;
     872             :     }
     873           0 :     bool append(AstFunc* func) {
     874           0 :         return funcs_.append(func);
     875             :     }
     876           0 :     const FuncVector& funcs() const {
     877           0 :         return funcs_;
     878             :     }
     879           0 :     bool append(AstImport* imp) {
     880           0 :         switch (imp->kind()) {
     881             :           case DefinitionKind::Function:
     882           0 :             if (!funcImportNames_.append(imp->name()))
     883           0 :                 return false;
     884           0 :             break;
     885             :           case DefinitionKind::Table:
     886           0 :             if (!tables_.append(AstResizable(imp->limits(), true)))
     887           0 :                 return false;
     888           0 :             break;
     889             :           case DefinitionKind::Memory:
     890           0 :             if (!memories_.append(AstResizable(imp->limits(), true)))
     891           0 :                 return false;
     892           0 :             break;
     893             :           case DefinitionKind::Global:
     894           0 :             break;
     895             :         }
     896             : 
     897           0 :         return imports_.append(imp);
     898             :     }
     899           0 :     const ImportVector& imports() const {
     900           0 :         return imports_;
     901             :     }
     902           0 :     const NameVector& funcImportNames() const {
     903           0 :         return funcImportNames_;
     904             :     }
     905           0 :     size_t numFuncImports() const {
     906           0 :         return funcImportNames_.length();
     907             :     }
     908           0 :     bool append(AstExport* exp) {
     909           0 :         return exports_.append(exp);
     910             :     }
     911           0 :     const ExportVector& exports() const {
     912           0 :         return exports_;
     913             :     }
     914           0 :     bool append(AstGlobal* glob) {
     915           0 :         return globals_.append(glob);
     916             :     }
     917           0 :     const AstGlobalVector& globals() const {
     918           0 :         return globals_;
     919             :     }
     920             : };
     921             : 
     922             : class AstUnaryOperator final : public AstExpr
     923             : {
     924             :     Op op_;
     925             :     AstExpr* operand_;
     926             : 
     927             :   public:
     928             :     static const AstExprKind Kind = AstExprKind::UnaryOperator;
     929           0 :     explicit AstUnaryOperator(Op op, AstExpr* operand)
     930           0 :       : AstExpr(Kind, ExprType::Limit),
     931           0 :         op_(op), operand_(operand)
     932           0 :     {}
     933             : 
     934           0 :     Op op() const { return op_; }
     935           0 :     AstExpr* operand() const { return operand_; }
     936             : };
     937             : 
     938             : class AstBinaryOperator final : public AstExpr
     939             : {
     940             :     Op op_;
     941             :     AstExpr* lhs_;
     942             :     AstExpr* rhs_;
     943             : 
     944             :   public:
     945             :     static const AstExprKind Kind = AstExprKind::BinaryOperator;
     946           0 :     explicit AstBinaryOperator(Op op, AstExpr* lhs, AstExpr* rhs)
     947           0 :       : AstExpr(Kind, ExprType::Limit),
     948           0 :         op_(op), lhs_(lhs), rhs_(rhs)
     949           0 :     {}
     950             : 
     951           0 :     Op op() const { return op_; }
     952           0 :     AstExpr* lhs() const { return lhs_; }
     953           0 :     AstExpr* rhs() const { return rhs_; }
     954             : };
     955             : 
     956             : class AstTernaryOperator : public AstExpr
     957             : {
     958             :     Op op_;
     959             :     AstExpr* op0_;
     960             :     AstExpr* op1_;
     961             :     AstExpr* op2_;
     962             : 
     963             :   public:
     964             :     static const AstExprKind Kind = AstExprKind::TernaryOperator;
     965           0 :     AstTernaryOperator(Op op, AstExpr* op0, AstExpr* op1, AstExpr* op2)
     966           0 :       : AstExpr(Kind, ExprType::Limit),
     967           0 :         op_(op), op0_(op0), op1_(op1), op2_(op2)
     968           0 :     {}
     969             : 
     970           0 :     Op op() const { return op_; }
     971           0 :     AstExpr* op0() const { return op0_; }
     972           0 :     AstExpr* op1() const { return op1_; }
     973           0 :     AstExpr* op2() const { return op2_; }
     974             : };
     975             : 
     976             : class AstComparisonOperator final : public AstExpr
     977             : {
     978             :     Op op_;
     979             :     AstExpr* lhs_;
     980             :     AstExpr* rhs_;
     981             : 
     982             :   public:
     983             :     static const AstExprKind Kind = AstExprKind::ComparisonOperator;
     984           0 :     explicit AstComparisonOperator(Op op, AstExpr* lhs, AstExpr* rhs)
     985           0 :       : AstExpr(Kind, ExprType::Limit),
     986           0 :         op_(op), lhs_(lhs), rhs_(rhs)
     987           0 :     {}
     988             : 
     989           0 :     Op op() const { return op_; }
     990           0 :     AstExpr* lhs() const { return lhs_; }
     991           0 :     AstExpr* rhs() const { return rhs_; }
     992             : };
     993             : 
     994             : class AstConversionOperator final : public AstExpr
     995             : {
     996             :     Op op_;
     997             :     AstExpr* operand_;
     998             : 
     999             :   public:
    1000             :     static const AstExprKind Kind = AstExprKind::ConversionOperator;
    1001           0 :     explicit AstConversionOperator(Op op, AstExpr* operand)
    1002           0 :       : AstExpr(Kind, ExprType::Limit),
    1003           0 :         op_(op), operand_(operand)
    1004           0 :     {}
    1005             : 
    1006           0 :     Op op() const { return op_; }
    1007           0 :     AstExpr* operand() const { return operand_; }
    1008             : };
    1009             : 
    1010             : // This is an artificial AST node which can fill operand slots in an AST
    1011             : // constructed from parsing or decoding stack-machine code that doesn't have
    1012             : // an inherent AST structure.
    1013             : class AstPop final : public AstExpr
    1014             : {
    1015             :   public:
    1016             :     static const AstExprKind Kind = AstExprKind::Pop;
    1017           0 :     AstPop()
    1018           0 :       : AstExpr(Kind, ExprType::Void)
    1019           0 :     {}
    1020             : };
    1021             : 
    1022             : // This is an artificial AST node which can be used to represent some forms
    1023             : // of stack-machine code in an AST form. It is similar to Block, but returns the
    1024             : // value of its first operand, rather than the last.
    1025             : class AstFirst : public AstExpr
    1026             : {
    1027             :     AstExprVector exprs_;
    1028             : 
    1029             :   public:
    1030             :     static const AstExprKind Kind = AstExprKind::First;
    1031           0 :     explicit AstFirst(AstExprVector&& exprs)
    1032           0 :       : AstExpr(Kind, ExprType::Limit),
    1033           0 :         exprs_(Move(exprs))
    1034           0 :     {}
    1035             : 
    1036           0 :     AstExprVector& exprs() { return exprs_; }
    1037             :     const AstExprVector& exprs() const { return exprs_; }
    1038             : };
    1039             : 
    1040             : } // end wasm namespace
    1041             : } // end js namespace
    1042             : 
    1043             : #endif // namespace wasmast_h

Generated by: LCOV version 1.13