Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
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
*
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 "mozilla/Variant.h"
23
24
#include "ds/LifoAlloc.h"
25
#include "js/HashTable.h"
26
#include "js/Vector.h"
27
#include "wasm/WasmTypes.h"
28
#include "wasm/WasmUtility.h"
29
30
namespace js {
31
namespace wasm {
32
33
const uint32_t AstNoIndex = UINT32_MAX;
34
const unsigned AST_LIFO_DEFAULT_CHUNK_SIZE = 4096;
35
36
/*****************************************************************************/
37
// wasm AST
38
39
class AstExpr;
40
41
template <class T>
42
using AstVector = mozilla::Vector<T, 0, LifoAllocPolicy<Fallible>>;
43
44
template <class K, class V, class HP>
45
using AstHashMap = HashMap<K, V, HP, LifoAllocPolicy<Fallible>>;
46
47
using mozilla::Variant;
48
49
typedef AstVector<bool> AstBoolVector;
50
51
class AstName {
52
const char16_t* begin_;
53
const char16_t* end_;
54
55
public:
56
template <size_t Length>
57
explicit AstName(const char16_t (&str)[Length])
58
: begin_(str), end_(str + Length - 1) {
59
MOZ_ASSERT(str[Length - 1] == u'\0');
60
}
61
62
AstName(const char16_t* begin, size_t length)
63
: begin_(begin), end_(begin + length) {}
64
AstName() : begin_(nullptr), end_(nullptr) {}
65
const char16_t* begin() const { return begin_; }
66
const char16_t* end() const { return end_; }
67
size_t length() const { return end_ - begin_; }
68
bool empty() const { return begin_ == nullptr; }
69
70
bool operator==(AstName rhs) const {
71
if (length() != rhs.length()) {
72
return false;
73
}
74
if (begin() == rhs.begin()) {
75
return true;
76
}
77
return EqualChars(begin(), rhs.begin(), length());
78
}
79
bool operator!=(AstName rhs) const { return !(*this == rhs); }
80
};
81
82
class AstRef {
83
AstName name_;
84
uint32_t index_;
85
86
public:
87
AstRef() : index_(AstNoIndex) { MOZ_ASSERT(isInvalid()); }
88
explicit AstRef(AstName name) : name_(name), index_(AstNoIndex) {
89
MOZ_ASSERT(!isInvalid());
90
}
91
explicit AstRef(uint32_t index) : index_(index) { MOZ_ASSERT(!isInvalid()); }
92
bool isInvalid() const { return name_.empty() && index_ == AstNoIndex; }
93
AstName name() const { return name_; }
94
bool isIndex() const { return index_ != AstNoIndex; }
95
size_t index() const {
96
MOZ_ASSERT(index_ != AstNoIndex);
97
return index_;
98
}
99
void setIndex(uint32_t index) {
100
MOZ_ASSERT(index_ == AstNoIndex);
101
index_ = index;
102
}
103
bool operator==(AstRef rhs) const {
104
return name_ == rhs.name_ && index_ == rhs.index_;
105
}
106
bool operator!=(AstRef rhs) const { return !(*this == rhs); }
107
};
108
109
class AstValType {
110
// When this type is resolved, which_ becomes IsValType.
111
112
enum { IsValType, IsAstRef } which_;
113
ValType type_;
114
AstRef ref_;
115
116
public:
117
AstValType() : which_(IsValType) {} // type_ is then !isValid()
118
119
explicit AstValType(ValType type) : which_(IsValType), type_(type) {}
120
121
explicit AstValType(AstRef ref) {
122
if (ref.name().empty()) {
123
which_ = IsValType;
124
type_ = RefType::fromTypeIndex(ref.index());
125
} else {
126
which_ = IsAstRef;
127
ref_ = ref;
128
}
129
}
130
131
#ifdef ENABLE_WASM_GC
132
bool isNarrowType() const {
133
if (which_ == IsAstRef) {
134
return true;
135
}
136
return type_ == RefType::any() || type_.isRef();
137
}
138
#endif
139
140
bool isValid() const { return !(which_ == IsValType && !type_.isValid()); }
141
142
bool isResolved() const { return which_ == IsValType; }
143
144
AstRef& asRef() { return ref_; }
145
146
void resolve() {
147
MOZ_ASSERT(which_ == IsAstRef);
148
which_ = IsValType;
149
type_ = RefType::fromTypeIndex(ref_.index());
150
}
151
152
ValType::Kind code() const {
153
if (which_ == IsValType) {
154
return type_.kind();
155
}
156
return ValType::Ref;
157
}
158
159
ValType type() const {
160
MOZ_ASSERT(which_ == IsValType);
161
return type_;
162
}
163
164
bool operator==(const AstValType& that) const {
165
if (which_ != that.which_) {
166
return false;
167
}
168
if (which_ == IsValType) {
169
return type_ == that.type_;
170
}
171
return ref_ == that.ref_;
172
}
173
174
bool operator!=(const AstValType& that) const { return !(*this == that); }
175
};
176
177
struct AstBlockType {
178
enum class Which {
179
VoidToVoid, // [] -> []
180
VoidToSingle, // [] -> T
181
Func // ft: index of [T,..] -> [T,..]
182
};
183
184
private:
185
Which which_;
186
union {
187
AstValType voidToSingle_;
188
AstRef func_;
189
};
190
191
public:
192
AstBlockType() : which_(Which::VoidToVoid) {}
193
Which which() const { return which_; }
194
AstValType& voidToSingleType() {
195
MOZ_ASSERT(which_ == Which::VoidToSingle);
196
return voidToSingle_;
197
}
198
void setVoidToSingle(AstValType t) {
199
which_ = Which::VoidToSingle;
200
voidToSingle_ = t;
201
}
202
AstRef& funcType() {
203
MOZ_ASSERT(which_ == Which::Func);
204
return func_;
205
}
206
void setFunc(AstRef t) {
207
which_ = Which::Func;
208
func_ = t;
209
}
210
};
211
212
struct AstNameHasher {
213
typedef const AstName Lookup;
214
static js::HashNumber hash(Lookup l) {
215
return mozilla::HashString(l.begin(), l.length());
216
}
217
static bool match(const AstName key, Lookup lookup) { return key == lookup; }
218
};
219
220
using AstNameMap = AstHashMap<AstName, uint32_t, AstNameHasher>;
221
222
typedef AstVector<AstValType> AstValTypeVector;
223
typedef AstVector<AstExpr*> AstExprVector;
224
typedef AstVector<AstName> AstNameVector;
225
typedef AstVector<AstRef> AstRefVector;
226
227
struct AstBase {
228
void* operator new(size_t numBytes, LifoAlloc& astLifo) noexcept(true) {
229
return astLifo.alloc(numBytes);
230
}
231
};
232
233
struct AstNode {
234
void* operator new(size_t numBytes, LifoAlloc& astLifo) noexcept(true) {
235
return astLifo.alloc(numBytes);
236
}
237
};
238
239
class AstFuncType;
240
class AstStructType;
241
242
class AstTypeDef : public AstNode {
243
protected:
244
enum class Which { IsFuncType, IsStructType };
245
246
private:
247
Which which_;
248
249
public:
250
explicit AstTypeDef(Which which) : which_(which) {}
251
252
bool isFuncType() const { return which_ == Which::IsFuncType; }
253
bool isStructType() const { return which_ == Which::IsStructType; }
254
inline AstFuncType& asFuncType();
255
inline AstStructType& asStructType();
256
inline const AstFuncType& asFuncType() const;
257
inline const AstStructType& asStructType() const;
258
};
259
260
class AstFuncType : public AstTypeDef {
261
AstName name_;
262
AstValTypeVector args_;
263
AstValTypeVector results_;
264
265
public:
266
explicit AstFuncType(LifoAlloc& lifo)
267
: AstTypeDef(Which::IsFuncType), args_(lifo), results_(lifo) {}
268
AstFuncType(AstValTypeVector&& args, AstValTypeVector&& results)
269
: AstTypeDef(Which::IsFuncType),
270
args_(std::move(args)),
271
results_(std::move(results)) {}
272
AstFuncType(AstName name, AstFuncType&& rhs)
273
: AstTypeDef(Which::IsFuncType),
274
name_(name),
275
args_(std::move(rhs.args_)),
276
results_(std::move(rhs.results_)) {}
277
const AstValTypeVector& args() const { return args_; }
278
AstValTypeVector& args() { return args_; }
279
const AstValTypeVector& results() const { return results_; }
280
AstValTypeVector& results() { return results_; }
281
AstName name() const { return name_; }
282
bool operator==(const AstFuncType& rhs) const {
283
return EqualContainers(args(), rhs.args()) &&
284
EqualContainers(results(), rhs.results());
285
}
286
287
typedef const AstFuncType& Lookup;
288
static HashNumber hash(Lookup ft) {
289
HashNumber hn = 0;
290
for (const AstValType& vt : ft.args()) {
291
hn = mozilla::AddToHash(hn, uint32_t(vt.code()));
292
}
293
for (const AstValType& vt : ft.results()) {
294
hn = mozilla::AddToHash(hn, uint32_t(vt.code()));
295
}
296
return hn;
297
}
298
static bool match(const AstFuncType* lhs, Lookup rhs) { return *lhs == rhs; }
299
};
300
301
class AstStructType : public AstTypeDef {
302
AstName name_;
303
AstNameVector fieldNames_;
304
AstBoolVector fieldMutability_;
305
AstValTypeVector fieldTypes_;
306
307
public:
308
explicit AstStructType(LifoAlloc& lifo)
309
: AstTypeDef(Which::IsStructType),
310
fieldNames_(lifo),
311
fieldMutability_(lifo),
312
fieldTypes_(lifo) {}
313
AstStructType(AstNameVector&& names, AstBoolVector&& mutability,
314
AstValTypeVector&& types)
315
: AstTypeDef(Which::IsStructType),
316
fieldNames_(std::move(names)),
317
fieldMutability_(std::move(mutability)),
318
fieldTypes_(std::move(types)) {}
319
AstStructType(AstName name, AstStructType&& rhs)
320
: AstTypeDef(Which::IsStructType),
321
name_(name),
322
fieldNames_(std::move(rhs.fieldNames_)),
323
fieldMutability_(std::move(rhs.fieldMutability_)),
324
fieldTypes_(std::move(rhs.fieldTypes_)) {}
325
AstName name() const { return name_; }
326
const AstNameVector& fieldNames() const { return fieldNames_; }
327
const AstBoolVector& fieldMutability() const { return fieldMutability_; }
328
const AstValTypeVector& fieldTypes() const { return fieldTypes_; }
329
AstValTypeVector& fieldTypes() { return fieldTypes_; }
330
};
331
332
inline AstFuncType& AstTypeDef::asFuncType() {
333
MOZ_ASSERT(isFuncType());
334
return *static_cast<AstFuncType*>(this);
335
}
336
337
inline AstStructType& AstTypeDef::asStructType() {
338
MOZ_ASSERT(isStructType());
339
return *static_cast<AstStructType*>(this);
340
}
341
342
inline const AstFuncType& AstTypeDef::asFuncType() const {
343
MOZ_ASSERT(isFuncType());
344
return *static_cast<const AstFuncType*>(this);
345
}
346
347
inline const AstStructType& AstTypeDef::asStructType() const {
348
MOZ_ASSERT(isStructType());
349
return *static_cast<const AstStructType*>(this);
350
}
351
352
enum class AstExprKind {
353
AtomicCmpXchg,
354
AtomicLoad,
355
AtomicRMW,
356
AtomicStore,
357
BinaryOperator,
358
Block,
359
Branch,
360
BranchTable,
361
Call,
362
CallIndirect,
363
ComparisonOperator,
364
Const,
365
ConversionOperator,
366
DataOrElemDrop,
367
Drop,
368
ExtraConversionOperator,
369
First,
370
GetGlobal,
371
GetLocal,
372
If,
373
Load,
374
MemFill,
375
MemOrTableCopy,
376
MemOrTableInit,
377
MemoryGrow,
378
MemorySize,
379
Nop,
380
Pop,
381
RefFunc,
382
RefNull,
383
Return,
384
SetGlobal,
385
SetLocal,
386
#ifdef ENABLE_WASM_GC
387
StructNew,
388
StructGet,
389
StructSet,
390
StructNarrow,
391
#endif
392
#ifdef ENABLE_WASM_REFTYPES
393
TableFill,
394
TableGet,
395
TableGrow,
396
TableSet,
397
TableSize,
398
#endif
399
TeeLocal,
400
Store,
401
Select,
402
UnaryOperator,
403
Unreachable,
404
Wait,
405
Wake,
406
Fence
407
};
408
409
class AstExpr : public AstNode {
410
const AstExprKind kind_;
411
412
protected:
413
explicit AstExpr(AstExprKind kind) : kind_(kind) {}
414
415
public:
416
AstExprKind kind() const { return kind_; }
417
418
template <class T>
419
T& as() {
420
MOZ_ASSERT(kind() == T::Kind);
421
return static_cast<T&>(*this);
422
}
423
};
424
425
struct AstNop : AstExpr {
426
static const AstExprKind Kind = AstExprKind::Nop;
427
AstNop() : AstExpr(AstExprKind::Nop) {}
428
};
429
430
struct AstUnreachable : AstExpr {
431
static const AstExprKind Kind = AstExprKind::Unreachable;
432
AstUnreachable() : AstExpr(AstExprKind::Unreachable) {}
433
};
434
435
class AstDrop : public AstExpr {
436
AstExpr& value_;
437
438
public:
439
static const AstExprKind Kind = AstExprKind::Drop;
440
explicit AstDrop(AstExpr& value)
441
: AstExpr(AstExprKind::Drop), value_(value) {}
442
AstExpr& value() const { return value_; }
443
};
444
445
class AstSelect : public AstExpr {
446
AstExpr* condition_;
447
AstExpr* op1_;
448
AstExpr* op2_;
449
AstValTypeVector result_;
450
451
public:
452
static const AstExprKind Kind = AstExprKind::Select;
453
AstSelect(AstExpr* condition, AstExpr* op1, AstExpr* op2,
454
AstValTypeVector&& result)
455
: AstExpr(Kind),
456
condition_(condition),
457
op1_(op1),
458
op2_(op2),
459
result_(std::move(result)) {}
460
461
AstExpr* condition() const { return condition_; }
462
AstExpr* op1() const { return op1_; }
463
AstExpr* op2() const { return op2_; }
464
AstValTypeVector& result() { return result_; }
465
const AstValTypeVector& result() const { return result_; }
466
};
467
468
class AstConst : public AstExpr {
469
const LitVal val_;
470
471
public:
472
static const AstExprKind Kind = AstExprKind::Const;
473
explicit AstConst(LitVal val) : AstExpr(Kind), val_(val) {}
474
LitVal val() const { return val_; }
475
};
476
477
class AstGetLocal : public AstExpr {
478
AstRef local_;
479
480
public:
481
static const AstExprKind Kind = AstExprKind::GetLocal;
482
explicit AstGetLocal(AstRef local) : AstExpr(Kind), local_(local) {}
483
AstRef& local() { return local_; }
484
};
485
486
class AstSetLocal : public AstExpr {
487
AstRef local_;
488
AstExpr& value_;
489
490
public:
491
static const AstExprKind Kind = AstExprKind::SetLocal;
492
AstSetLocal(AstRef local, AstExpr& value)
493
: AstExpr(Kind), local_(local), value_(value) {}
494
AstRef& local() { return local_; }
495
AstExpr& value() const { return value_; }
496
};
497
498
class AstGetGlobal : public AstExpr {
499
AstRef global_;
500
501
public:
502
static const AstExprKind Kind = AstExprKind::GetGlobal;
503
explicit AstGetGlobal(AstRef global) : AstExpr(Kind), global_(global) {}
504
AstRef& global() { return global_; }
505
};
506
507
class AstSetGlobal : public AstExpr {
508
AstRef global_;
509
AstExpr& value_;
510
511
public:
512
static const AstExprKind Kind = AstExprKind::SetGlobal;
513
AstSetGlobal(AstRef global, AstExpr& value)
514
: AstExpr(Kind), global_(global), value_(value) {}
515
AstRef& global() { return global_; }
516
AstExpr& value() const { return value_; }
517
};
518
519
class AstTeeLocal : public AstExpr {
520
AstRef local_;
521
AstExpr& value_;
522
523
public:
524
static const AstExprKind Kind = AstExprKind::TeeLocal;
525
AstTeeLocal(AstRef local, AstExpr& value)
526
: AstExpr(Kind), local_(local), value_(value) {}
527
AstRef& local() { return local_; }
528
AstExpr& value() const { return value_; }
529
};
530
531
class AstBlock : public AstExpr {
532
Op op_;
533
AstName name_;
534
AstExprVector exprs_;
535
AstBlockType type_;
536
537
public:
538
static const AstExprKind Kind = AstExprKind::Block;
539
explicit AstBlock(Op op, AstBlockType type, AstName name,
540
AstExprVector&& exprs)
541
: AstExpr(Kind),
542
op_(op),
543
name_(name),
544
exprs_(std::move(exprs)),
545
type_(type) {}
546
547
Op op() const { return op_; }
548
AstName name() const { return name_; }
549
const AstExprVector& exprs() const { return exprs_; }
550
AstBlockType& type() { return type_; }
551
};
552
553
class AstBranch : public AstExpr {
554
Op op_;
555
AstRef target_;
556
AstExprVector values_; // Includes the condition, for br_if
557
558
public:
559
static const AstExprKind Kind = AstExprKind::Branch;
560
explicit AstBranch(Op op, AstRef target, AstExprVector&& values)
561
: AstExpr(Kind), op_(op), target_(target), values_(std::move(values)) {}
562
563
Op op() const { return op_; }
564
AstRef& target() { return target_; }
565
AstExprVector& values() { return values_; }
566
};
567
568
class AstCall : public AstExpr {
569
Op op_;
570
AstRef func_;
571
AstExprVector args_;
572
573
public:
574
static const AstExprKind Kind = AstExprKind::Call;
575
AstCall(Op op, AstRef func, AstExprVector&& args)
576
: AstExpr(Kind), op_(op), func_(func), args_(std::move(args)) {}
577
578
Op op() const { return op_; }
579
AstRef& func() { return func_; }
580
const AstExprVector& args() const { return args_; }
581
};
582
583
class AstCallIndirect : public AstExpr {
584
AstRef targetTable_;
585
AstRef funcType_;
586
AstExprVector args_;
587
AstExpr* index_;
588
589
public:
590
static const AstExprKind Kind = AstExprKind::CallIndirect;
591
AstCallIndirect(AstRef targetTable, AstRef funcType, AstExprVector&& args,
592
AstExpr* index)
593
: AstExpr(Kind),
594
targetTable_(targetTable),
595
funcType_(funcType),
596
args_(std::move(args)),
597
index_(index) {}
598
AstRef& targetTable() { return targetTable_; }
599
AstRef& funcType() { return funcType_; }
600
const AstExprVector& args() const { return args_; }
601
AstExpr* index() const { return index_; }
602
};
603
604
class AstReturn : public AstExpr {
605
AstExpr* maybeExpr_;
606
607
public:
608
static const AstExprKind Kind = AstExprKind::Return;
609
explicit AstReturn(AstExpr* maybeExpr)
610
: AstExpr(Kind), maybeExpr_(maybeExpr) {}
611
AstExpr* maybeExpr() const { return maybeExpr_; }
612
};
613
614
class AstIf : public AstExpr {
615
AstExpr* cond_;
616
AstName name_;
617
AstExprVector thenExprs_;
618
AstExprVector elseExprs_;
619
AstBlockType type_;
620
621
public:
622
static const AstExprKind Kind = AstExprKind::If;
623
AstIf(AstBlockType type, AstExpr* cond, AstName name,
624
AstExprVector&& thenExprs, AstExprVector&& elseExprs)
625
: AstExpr(Kind),
626
cond_(cond),
627
name_(name),
628
thenExprs_(std::move(thenExprs)),
629
elseExprs_(std::move(elseExprs)),
630
type_(type) {}
631
632
AstExpr& cond() const { return *cond_; }
633
const AstExprVector& thenExprs() const { return thenExprs_; }
634
bool hasElse() const { return elseExprs_.length(); }
635
const AstExprVector& elseExprs() const {
636
MOZ_ASSERT(hasElse());
637
return elseExprs_;
638
}
639
AstName name() const { return name_; }
640
AstBlockType& type() { return type_; }
641
};
642
643
class AstLoadStoreAddress {
644
AstExpr* base_;
645
int32_t flags_;
646
int32_t offset_;
647
648
public:
649
explicit AstLoadStoreAddress(AstExpr* base, int32_t flags, int32_t offset)
650
: base_(base), flags_(flags), offset_(offset) {}
651
652
AstExpr& base() const { return *base_; }
653
int32_t flags() const { return flags_; }
654
int32_t offset() const { return offset_; }
655
};
656
657
class AstLoad : public AstExpr {
658
Op op_;
659
AstLoadStoreAddress address_;
660
661
public:
662
static const AstExprKind Kind = AstExprKind::Load;
663
explicit AstLoad(Op op, const AstLoadStoreAddress& address)
664
: AstExpr(Kind), op_(op), address_(address) {}
665
666
Op op() const { return op_; }
667
const AstLoadStoreAddress& address() const { return address_; }
668
};
669
670
class AstStore : public AstExpr {
671
Op op_;
672
AstLoadStoreAddress address_;
673
AstExpr* value_;
674
675
public:
676
static const AstExprKind Kind = AstExprKind::Store;
677
explicit AstStore(Op op, const AstLoadStoreAddress& address, AstExpr* value)
678
: AstExpr(Kind), op_(op), address_(address), value_(value) {}
679
680
Op op() const { return op_; }
681
const AstLoadStoreAddress& address() const { return address_; }
682
AstExpr& value() const { return *value_; }
683
};
684
685
class AstAtomicCmpXchg : public AstExpr {
686
ThreadOp op_;
687
AstLoadStoreAddress address_;
688
AstExpr* expected_;
689
AstExpr* replacement_;
690
691
public:
692
static const AstExprKind Kind = AstExprKind::AtomicCmpXchg;
693
explicit AstAtomicCmpXchg(ThreadOp op, const AstLoadStoreAddress& address,
694
AstExpr* expected, AstExpr* replacement)
695
: AstExpr(Kind),
696
op_(op),
697
address_(address),
698
expected_(expected),
699
replacement_(replacement) {}
700
701
ThreadOp op() const { return op_; }
702
const AstLoadStoreAddress& address() const { return address_; }
703
AstExpr& expected() const { return *expected_; }
704
AstExpr& replacement() const { return *replacement_; }
705
};
706
707
class AstAtomicLoad : public AstExpr {
708
ThreadOp op_;
709
AstLoadStoreAddress address_;
710
711
public:
712
static const AstExprKind Kind = AstExprKind::AtomicLoad;
713
explicit AstAtomicLoad(ThreadOp op, const AstLoadStoreAddress& address)
714
: AstExpr(Kind), op_(op), address_(address) {}
715
716
ThreadOp op() const { return op_; }
717
const AstLoadStoreAddress& address() const { return address_; }
718
};
719
720
class AstAtomicRMW : public AstExpr {
721
ThreadOp op_;
722
AstLoadStoreAddress address_;
723
AstExpr* value_;
724
725
public:
726
static const AstExprKind Kind = AstExprKind::AtomicRMW;
727
explicit AstAtomicRMW(ThreadOp op, const AstLoadStoreAddress& address,
728
AstExpr* value)
729
: AstExpr(Kind), op_(op), address_(address), value_(value) {}
730
731
ThreadOp op() const { return op_; }
732
const AstLoadStoreAddress& address() const { return address_; }
733
AstExpr& value() const { return *value_; }
734
};
735
736
class AstAtomicStore : public AstExpr {
737
ThreadOp op_;
738
AstLoadStoreAddress address_;
739
AstExpr* value_;
740
741
public:
742
static const AstExprKind Kind = AstExprKind::AtomicStore;
743
explicit AstAtomicStore(ThreadOp op, const AstLoadStoreAddress& address,
744
AstExpr* value)
745
: AstExpr(Kind), op_(op), address_(address), value_(value) {}
746
747
ThreadOp op() const { return op_; }
748
const AstLoadStoreAddress& address() const { return address_; }
749
AstExpr& value() const { return *value_; }
750
};
751
752
class AstWait : public AstExpr {
753
ThreadOp op_;
754
AstLoadStoreAddress address_;
755
AstExpr* expected_;
756
AstExpr* timeout_;
757
758
public:
759
static const AstExprKind Kind = AstExprKind::Wait;
760
explicit AstWait(ThreadOp op, const AstLoadStoreAddress& address,
761
AstExpr* expected, AstExpr* timeout)
762
: AstExpr(Kind),
763
op_(op),
764
address_(address),
765
expected_(expected),
766
timeout_(timeout) {}
767
768
ThreadOp op() const { return op_; }
769
const AstLoadStoreAddress& address() const { return address_; }
770
AstExpr& expected() const { return *expected_; }
771
AstExpr& timeout() const { return *timeout_; }
772
};
773
774
class AstWake : public AstExpr {
775
AstLoadStoreAddress address_;
776
AstExpr* count_;
777
778
public:
779
static const AstExprKind Kind = AstExprKind::Wake;
780
explicit AstWake(const AstLoadStoreAddress& address, AstExpr* count)
781
: AstExpr(Kind), address_(address), count_(count) {}
782
783
const AstLoadStoreAddress& address() const { return address_; }
784
AstExpr& count() const { return *count_; }
785
};
786
787
struct AstFence : AstExpr {
788
static const AstExprKind Kind = AstExprKind::Fence;
789
AstFence() : AstExpr(AstExprKind::Fence) {}
790
};
791
792
class AstMemOrTableCopy : public AstExpr {
793
bool isMem_;
794
AstRef destTable_;
795
AstExpr* dest_;
796
AstRef srcTable_;
797
AstExpr* src_;
798
AstExpr* len_;
799
800
public:
801
static const AstExprKind Kind = AstExprKind::MemOrTableCopy;
802
explicit AstMemOrTableCopy(bool isMem, AstRef destTable, AstExpr* dest,
803
AstRef srcTable, AstExpr* src, AstExpr* len)
804
: AstExpr(Kind),
805
isMem_(isMem),
806
destTable_(destTable),
807
dest_(dest),
808
srcTable_(srcTable),
809
src_(src),
810
len_(len) {}
811
812
bool isMem() const { return isMem_; }
813
AstRef& destTable() {
814
MOZ_ASSERT(!isMem());
815
return destTable_;
816
}
817
AstExpr& dest() const { return *dest_; }
818
AstRef& srcTable() {
819
MOZ_ASSERT(!isMem());
820
return srcTable_;
821
}
822
AstExpr& src() const { return *src_; }
823
AstExpr& len() const { return *len_; }
824
};
825
826
class AstDataOrElemDrop : public AstExpr {
827
bool isData_;
828
uint32_t segIndex_;
829
830
public:
831
static const AstExprKind Kind = AstExprKind::DataOrElemDrop;
832
explicit AstDataOrElemDrop(bool isData, uint32_t segIndex)
833
: AstExpr(Kind), isData_(isData), segIndex_(segIndex) {}
834
835
bool isData() const { return isData_; }
836
uint32_t segIndex() const { return segIndex_; }
837
};
838
839
class AstMemFill : public AstExpr {
840
AstExpr* start_;
841
AstExpr* val_;
842
AstExpr* len_;
843
844
public:
845
static const AstExprKind Kind = AstExprKind::MemFill;
846
explicit AstMemFill(AstExpr* start, AstExpr* val, AstExpr* len)
847
: AstExpr(Kind), start_(start), val_(val), len_(len) {}
848
849
AstExpr& start() const { return *start_; }
850
AstExpr& val() const { return *val_; }
851
AstExpr& len() const { return *len_; }
852
};
853
854
class AstMemOrTableInit : public AstExpr {
855
bool isMem_;
856
uint32_t segIndex_;
857
AstRef target_;
858
AstExpr* dst_;
859
AstExpr* src_;
860
AstExpr* len_;
861
862
public:
863
static const AstExprKind Kind = AstExprKind::MemOrTableInit;
864
explicit AstMemOrTableInit(bool isMem, uint32_t segIndex, AstRef target,
865
AstExpr* dst, AstExpr* src, AstExpr* len)
866
: AstExpr(Kind),
867
isMem_(isMem),
868
segIndex_(segIndex),
869
target_(target),
870
dst_(dst),
871
src_(src),
872
len_(len) {}
873
874
bool isMem() const { return isMem_; }
875
uint32_t segIndex() const { return segIndex_; }
876
AstRef& target() { return target_; }
877
AstRef& targetTable() {
878
MOZ_ASSERT(!isMem());
879
return target_;
880
}
881
AstRef& targetMemory() {
882
MOZ_ASSERT(isMem());
883
return target_;
884
}
885
AstExpr& dst() const { return *dst_; }
886
AstExpr& src() const { return *src_; }
887
AstExpr& len() const { return *len_; }
888
};
889
890
#ifdef ENABLE_WASM_REFTYPES
891
class AstTableFill : public AstExpr {
892
AstRef targetTable_;
893
AstExpr* start_;
894
AstExpr* val_;
895
AstExpr* len_;
896
897
public:
898
static const AstExprKind Kind = AstExprKind::TableFill;
899
explicit AstTableFill(AstRef targetTable, AstExpr* start, AstExpr* val,
900
AstExpr* len)
901
: AstExpr(Kind),
902
targetTable_(targetTable),
903
start_(start),
904
val_(val),
905
len_(len) {}
906
907
AstRef& targetTable() { return targetTable_; }
908
AstExpr& start() const { return *start_; }
909
AstExpr& val() const { return *val_; }
910
AstExpr& len() const { return *len_; }
911
};
912
913
class AstTableGet : public AstExpr {
914
AstRef targetTable_;
915
AstExpr* index_;
916
917
public:
918
static const AstExprKind Kind = AstExprKind::TableGet;
919
explicit AstTableGet(AstRef targetTable, AstExpr* index)
920
: AstExpr(Kind), targetTable_(targetTable), index_(index) {}
921
922
AstRef& targetTable() { return targetTable_; }
923
AstExpr& index() const { return *index_; }
924
};
925
926
class AstTableGrow : public AstExpr {
927
AstRef targetTable_;
928
AstExpr* initValue_;
929
AstExpr* delta_;
930
931
public:
932
static const AstExprKind Kind = AstExprKind::TableGrow;
933
AstTableGrow(AstRef targetTable, AstExpr* initValue, AstExpr* delta)
934
: AstExpr(Kind),
935
targetTable_(targetTable),
936
initValue_(initValue),
937
delta_(delta) {}
938
939
AstRef& targetTable() { return targetTable_; }
940
AstExpr& initValue() const { return *initValue_; }
941
AstExpr& delta() const { return *delta_; }
942
};
943
944
class AstTableSet : public AstExpr {
945
AstRef targetTable_;
946
AstExpr* index_;
947
AstExpr* value_;
948
949
public:
950
static const AstExprKind Kind = AstExprKind::TableSet;
951
AstTableSet(AstRef targetTable, AstExpr* index, AstExpr* value)
952
: AstExpr(Kind),
953
targetTable_(targetTable),
954
index_(index),
955
value_(value) {}
956
957
AstRef& targetTable() { return targetTable_; }
958
AstExpr& index() const { return *index_; }
959
AstExpr& value() const { return *value_; }
960
};
961
962
class AstTableSize : public AstExpr {
963
AstRef targetTable_;
964
965
public:
966
static const AstExprKind Kind = AstExprKind::TableSize;
967
explicit AstTableSize(AstRef targetTable)
968
: AstExpr(Kind), targetTable_(targetTable) {}
969
970
AstRef& targetTable() { return targetTable_; }
971
};
972
#endif // ENABLE_WASM_REFTYPES
973
974
#ifdef ENABLE_WASM_GC
975
class AstStructNew : public AstExpr {
976
AstRef structType_;
977
AstExprVector fieldValues_;
978
979
public:
980
static const AstExprKind Kind = AstExprKind::StructNew;
981
AstStructNew(AstRef structType, AstExprVector&& fieldVals)
982
: AstExpr(Kind),
983
structType_(structType),
984
fieldValues_(std::move(fieldVals)) {}
985
AstRef& structType() { return structType_; }
986
const AstExprVector& fieldValues() const { return fieldValues_; }
987
};
988
989
class AstStructGet : public AstExpr {
990
AstRef structType_;
991
AstRef fieldName_;
992
AstExpr* ptr_;
993
994
public:
995
static const AstExprKind Kind = AstExprKind::StructGet;
996
AstStructGet(AstRef structType, AstRef fieldName, AstExpr* ptr)
997
: AstExpr(Kind),
998
structType_(structType),
999
fieldName_(fieldName),
1000
ptr_(ptr) {}
1001
AstRef& structType() { return structType_; }
1002
AstRef& fieldName() { return fieldName_; }
1003
AstExpr& ptr() const { return *ptr_; }
1004
};
1005
1006
class AstStructSet : public AstExpr {
1007
AstRef structType_;
1008
AstRef fieldName_;
1009
AstExpr* ptr_;
1010
AstExpr* value_;
1011
1012
public:
1013
static const AstExprKind Kind = AstExprKind::StructSet;
1014
AstStructSet(AstRef structType, AstRef fieldName, AstExpr* ptr,
1015
AstExpr* value)
1016
: AstExpr(Kind),
1017
structType_(structType),
1018
fieldName_(fieldName),
1019
ptr_(ptr),
1020
value_(value) {}
1021
AstRef& structType() { return structType_; }
1022
AstRef& fieldName() { return fieldName_; }
1023
AstExpr& ptr() const { return *ptr_; }
1024
AstExpr& value() const { return *value_; }
1025
};
1026
1027
class AstStructNarrow : public AstExpr {
1028
AstValType inputStruct_;
1029
AstValType outputStruct_;
1030
AstExpr* ptr_;
1031
1032
public:
1033
static const AstExprKind Kind = AstExprKind::StructNarrow;
1034
AstStructNarrow(AstValType inputStruct, AstValType outputStruct, AstExpr* ptr)
1035
: AstExpr(Kind),
1036
inputStruct_(inputStruct),
1037
outputStruct_(outputStruct),
1038
ptr_(ptr) {}
1039
AstValType& inputStruct() { return inputStruct_; }
1040
AstValType& outputStruct() { return outputStruct_; }
1041
AstExpr& ptr() const { return *ptr_; }
1042
};
1043
#endif
1044
1045
class AstMemorySize final : public AstExpr {
1046
public:
1047
static const AstExprKind Kind = AstExprKind::MemorySize;
1048
explicit AstMemorySize() : AstExpr(Kind) {}
1049
};
1050
1051
class AstMemoryGrow final : public AstExpr {
1052
AstExpr* operand_;
1053
1054
public:
1055
static const AstExprKind Kind = AstExprKind::MemoryGrow;
1056
explicit AstMemoryGrow(AstExpr* operand) : AstExpr(Kind), operand_(operand) {}
1057
1058
AstExpr* operand() const { return operand_; }
1059
};
1060
1061
class AstBranchTable : public AstExpr {
1062
AstRef default_;
1063
AstRefVector table_;
1064
AstExprVector values_;
1065
1066
public:
1067
static const AstExprKind Kind = AstExprKind::BranchTable;
1068
explicit AstBranchTable(AstRef def, AstRefVector&& table,
1069
AstExprVector&& values)
1070
: AstExpr(Kind),
1071
default_(def),
1072
table_(std::move(table)),
1073
values_(std::move(values)) {}
1074
AstRef& def() { return default_; }
1075
AstRefVector& table() { return table_; }
1076
AstExprVector& values() { return values_; }
1077
};
1078
1079
class AstFunc : public AstNode {
1080
AstName name_;
1081
AstRef funcType_;
1082
AstValTypeVector vars_;
1083
AstNameVector localNames_;
1084
AstExprVector body_;
1085
1086
public:
1087
AstFunc(AstName name, AstRef ft, AstValTypeVector&& vars,
1088
AstNameVector&& locals, AstExprVector&& body)
1089
: name_(name),
1090
funcType_(ft),
1091
vars_(std::move(vars)),
1092
localNames_(std::move(locals)),
1093
body_(std::move(body)) {}
1094
AstRef& funcType() { return funcType_; }
1095
const AstValTypeVector& vars() const { return vars_; }
1096
AstValTypeVector& vars() { return vars_; }
1097
const AstNameVector& locals() const { return localNames_; }
1098
const AstExprVector& body() const { return body_; }
1099
AstName name() const { return name_; }
1100
};
1101
1102
class AstGlobal : public AstNode {
1103
AstName name_;
1104
bool isMutable_;
1105
AstValType type_;
1106
Maybe<AstExpr*> init_;
1107
1108
public:
1109
AstGlobal() : isMutable_(false), type_(ValType()) {}
1110
1111
explicit AstGlobal(AstName name, AstValType type, bool isMutable,
1112
const Maybe<AstExpr*>& init = Maybe<AstExpr*>())
1113
: name_(name), isMutable_(isMutable), type_(type), init_(init) {}
1114
1115
AstName name() const { return name_; }
1116
bool isMutable() const { return isMutable_; }
1117
ValType type() const { return type_.type(); }
1118
AstValType& type() { return type_; }
1119
1120
bool hasInit() const { return !!init_; }
1121
AstExpr& init() const {
1122
MOZ_ASSERT(hasInit());
1123
return **init_;
1124
}
1125
};
1126
1127
typedef AstVector<AstGlobal*> AstGlobalVector;
1128
1129
class AstImport : public AstNode {
1130
AstName name_;
1131
AstName module_;
1132
AstName field_;
1133
DefinitionKind kind_;
1134
1135
AstRef funcType_;
1136
Limits limits_;
1137
TableKind tableKind_;
1138
AstGlobal global_;
1139
1140
public:
1141
AstImport(AstName name, AstName module, AstName field, AstRef funcType)
1142
: name_(name),
1143
module_(module),
1144
field_(field),
1145
kind_(DefinitionKind::Function),
1146
funcType_(funcType) {}
1147
AstImport(AstName name, AstName module, AstName field, DefinitionKind kind,
1148
const Limits& limits)
1149
: name_(name),
1150
module_(module),
1151
field_(field),
1152
kind_(kind),
1153
limits_(limits) {
1154
MOZ_ASSERT(kind != DefinitionKind::Table, "A table must have a kind");
1155
}
1156
AstImport(AstName name, AstName module, AstName field, const Limits& limits,
1157
TableKind tableKind)
1158
: name_(name),
1159
module_(module),
1160
field_(field),
1161
kind_(DefinitionKind::Table),
1162
limits_(limits),
1163
tableKind_(tableKind) {}
1164
AstImport(AstName name, AstName module, AstName field,
1165
const AstGlobal& global)
1166
: name_(name),
1167
module_(module),
1168
field_(field),
1169
kind_(DefinitionKind::Global),
1170
global_(global) {}
1171
1172
AstName name() const { return name_; }
1173
AstName module() const { return module_; }
1174
AstName field() const { return field_; }
1175
1176
DefinitionKind kind() const { return kind_; }
1177
TableKind tableKind() const {
1178
MOZ_ASSERT(kind_ == DefinitionKind::Table);
1179
return tableKind_;
1180
}
1181
AstRef& funcType() {
1182
MOZ_ASSERT(kind_ == DefinitionKind::Function);
1183
return funcType_;
1184
}
1185
Limits limits() const {
1186
MOZ_ASSERT(kind_ == DefinitionKind::Memory ||
1187
kind_ == DefinitionKind::Table);
1188
return limits_;
1189
}
1190
const AstGlobal& global() const {
1191
MOZ_ASSERT(kind_ == DefinitionKind::Global);
1192
return global_;
1193
}
1194
AstGlobal& global() {
1195
MOZ_ASSERT(kind_ == DefinitionKind::Global);
1196
return global_;
1197
}
1198
};
1199
1200
class AstExport : public AstNode {
1201
AstName name_;
1202
DefinitionKind kind_;
1203
AstRef ref_;
1204
1205
public:
1206
AstExport(AstName name, DefinitionKind kind, AstRef ref)
1207
: name_(name), kind_(kind), ref_(ref) {}
1208
explicit AstExport(AstName name, DefinitionKind kind)
1209
: name_(name), kind_(kind) {}
1210
AstName name() const { return name_; }
1211
DefinitionKind kind() const { return kind_; }
1212
AstRef& ref() { return ref_; }
1213
};
1214
1215
class AstDataSegment : public AstNode {
1216
AstExpr* offsetIfActive_;
1217
AstNameVector fragments_;
1218
1219
public:
1220
AstDataSegment(AstExpr* offsetIfActive, AstNameVector&& fragments)
1221
: offsetIfActive_(offsetIfActive), fragments_(std::move(fragments)) {}
1222
1223
AstExpr* offsetIfActive() const { return offsetIfActive_; }
1224
const AstNameVector& fragments() const { return fragments_; }
1225
};
1226
1227
typedef AstVector<AstDataSegment*> AstDataSegmentVector;
1228
1229
struct AstNullValue {};
1230
typedef Variant<AstRef, AstNullValue> AstElem;
1231
typedef AstVector<AstElem> AstElemVector;
1232
1233
enum class AstElemSegmentKind {
1234
Active,
1235
Passive,
1236
Declared,
1237
};
1238
1239
class AstElemSegment : public AstNode {
1240
AstElemSegmentKind kind_;
1241
AstRef targetTable_;
1242
AstExpr* offsetIfActive_;
1243
ValType elemType_;
1244
AstElemVector elems_;
1245
1246
public:
1247
AstElemSegment(AstElemSegmentKind kind, AstRef targetTable,
1248
AstExpr* offsetIfActive, ValType elemType,
1249
AstElemVector&& elems)
1250
: kind_(kind),
1251
targetTable_(targetTable),
1252
offsetIfActive_(offsetIfActive),
1253
elemType_(elemType),
1254
elems_(std::move(elems)) {}
1255
1256
AstElemSegmentKind kind() const { return kind_; }
1257
AstRef targetTable() const { return targetTable_; }
1258
AstRef& targetTableRef() { return targetTable_; }
1259
AstExpr* offsetIfActive() const { return offsetIfActive_; }
1260
ValType elemType() const { return elemType_; }
1261
AstElemVector& elems() { return elems_; }
1262
const AstElemVector& elems() const { return elems_; }
1263
};
1264
1265
typedef AstVector<AstElemSegment*> AstElemSegmentVector;
1266
1267
class AstStartFunc : public AstNode {
1268
AstRef func_;
1269
1270
public:
1271
explicit AstStartFunc(AstRef func) : func_(func) {}
1272
1273
AstRef& func() { return func_; }
1274
};
1275
1276
struct AstMemory {
1277
AstName name;
1278
Limits limits;
1279
bool imported;
1280
1281
AstMemory(const Limits& limits, bool imported, AstName name = AstName())
1282
: name(name), limits(limits), imported(imported) {}
1283
};
1284
1285
struct AstTable {
1286
AstName name;
1287
Limits limits;
1288
TableKind tableKind;
1289
bool imported;
1290
1291
AstTable(const Limits& limits, TableKind tableKind, bool imported,
1292
AstName name = AstName())
1293
: name(name), limits(limits), tableKind(tableKind), imported(imported) {}
1294
};
1295
1296
class AstModule : public AstNode {
1297
public:
1298
typedef AstVector<AstFunc*> FuncVector;
1299
typedef AstVector<AstImport*> ImportVector;
1300
typedef AstVector<AstExport*> ExportVector;
1301
typedef AstVector<AstTypeDef*> TypeDefVector;
1302
typedef AstVector<AstName> NameVector;
1303
typedef AstVector<AstMemory> AstMemoryVector;
1304
typedef AstVector<AstTable> AstTableVector;
1305
1306
private:
1307
typedef AstHashMap<AstFuncType*, uint32_t, AstFuncType> FuncTypeMap;
1308
1309
LifoAlloc& lifo_;
1310
TypeDefVector types_;
1311
FuncTypeMap funcTypeMap_;
1312
ImportVector imports_;
1313
NameVector funcImportNames_;
1314
AstTableVector tables_;
1315
AstMemoryVector memories_;
1316
#ifdef ENABLE_WASM_GC
1317
uint32_t gcFeatureOptIn_;
1318
#endif
1319
Maybe<uint32_t> dataCount_;
1320
ExportVector exports_;
1321
Maybe<AstStartFunc> startFunc_;
1322
FuncVector funcs_;
1323
AstDataSegmentVector dataSegments_;
1324
AstElemSegmentVector elemSegments_;
1325
AstGlobalVector globals_;
1326
1327
size_t numGlobalImports_;
1328
1329
public:
1330
explicit AstModule(LifoAlloc& lifo)
1331
: lifo_(lifo),
1332
types_(lifo),
1333
funcTypeMap_(lifo),
1334
imports_(lifo),
1335
funcImportNames_(lifo),
1336
tables_(lifo),
1337
memories_(lifo),
1338
#ifdef ENABLE_WASM_GC
1339
gcFeatureOptIn_(0),
1340
#endif
1341
exports_(lifo),
1342
funcs_(lifo),
1343
dataSegments_(lifo),
1344
elemSegments_(lifo),
1345
globals_(lifo),
1346
numGlobalImports_(0) {
1347
}
1348
bool addMemory(AstName name, const Limits& memory) {
1349
return memories_.append(AstMemory(memory, false, name));
1350
}
1351
bool hasMemory() const { return !!memories_.length(); }
1352
const AstMemoryVector& memories() const { return memories_; }
1353
#ifdef ENABLE_WASM_GC
1354
bool addGcFeatureOptIn(uint32_t version) {
1355
gcFeatureOptIn_ = version;
1356
return true;
1357
}
1358
uint32_t gcFeatureOptIn() const { return gcFeatureOptIn_; }
1359
#endif
1360
bool initDataCount(uint32_t dataCount) {
1361
MOZ_ASSERT(dataCount_.isNothing());
1362
dataCount_.emplace(dataCount);
1363
return true;
1364
}
1365
Maybe<uint32_t> dataCount() const { return dataCount_; }
1366
bool addTable(AstName name, const Limits& table, TableKind tableKind) {
1367
return tables_.append(AstTable(table, tableKind, false, name));
1368
}
1369
bool hasTable() const { return !!tables_.length(); }
1370
const AstTableVector& tables() const { return tables_; }
1371
bool append(AstDataSegment* seg) { return dataSegments_.append(seg); }
1372
const AstDataSegmentVector& dataSegments() const { return dataSegments_; }
1373
bool append(AstElemSegment* seg) { return elemSegments_.append(seg); }
1374
const AstElemSegmentVector& elemSegments() const { return elemSegments_; }
1375
bool hasStartFunc() const { return !!startFunc_; }
1376
bool setStartFunc(AstStartFunc startFunc) {
1377
if (startFunc_) {
1378
return false;
1379
}
1380
startFunc_.emplace(startFunc);
1381
return true;
1382
}
1383
AstStartFunc& startFunc() { return *startFunc_; }
1384
bool declare(AstFuncType&& funcType, uint32_t* funcTypeIndex) {
1385
FuncTypeMap::AddPtr p = funcTypeMap_.lookupForAdd(funcType);
1386
if (p) {
1387
*funcTypeIndex = p->value();
1388
return true;
1389
}
1390
*funcTypeIndex = types_.length();
1391
auto* lifoFuncType =
1392
new (lifo_) AstFuncType(AstName(), std::move(funcType));
1393
return lifoFuncType && types_.append(lifoFuncType) &&
1394
funcTypeMap_.add(p, static_cast<AstFuncType*>(types_.back()),
1395
*funcTypeIndex);
1396
}
1397
bool append(AstFuncType* funcType) {
1398
uint32_t funcTypeIndex = types_.length();
1399
if (!types_.append(funcType)) {
1400
return false;
1401
}
1402
FuncTypeMap::AddPtr p = funcTypeMap_.lookupForAdd(*funcType);
1403
return p || funcTypeMap_.add(p, funcType, funcTypeIndex);
1404
}
1405
const TypeDefVector& types() const { return types_; }
1406
bool append(AstFunc* func) { return funcs_.append(func); }
1407
const FuncVector& funcs() const { return funcs_; }
1408
bool append(AstStructType* str) { return types_.append(str); }
1409
bool append(AstTypeDef* td) {
1410
if (td->isFuncType()) {
1411
return append(&td->asFuncType());
1412
}
1413
if (td->isStructType()) {
1414
return append(&td->asStructType());
1415
}
1416
MOZ_CRASH("Bad type");
1417
}
1418
bool append(AstImport* imp) {
1419
switch (imp->kind()) {
1420
case DefinitionKind::Function:
1421
if (!funcImportNames_.append(imp->name())) {
1422
return false;
1423
}
1424
break;
1425
case DefinitionKind::Table:
1426
if (!tables_.append(AstTable(imp->limits(), imp->tableKind(), true))) {
1427
return false;
1428
}
1429
break;
1430
case DefinitionKind::Memory:
1431
if (!memories_.append(AstMemory(imp->limits(), true))) {
1432
return false;
1433
}
1434
break;
1435
case DefinitionKind::Global:
1436
numGlobalImports_++;
1437
break;
1438
}
1439
return imports_.append(imp);
1440
}
1441
const ImportVector& imports() const { return imports_; }
1442
const NameVector& funcImportNames() const { return funcImportNames_; }
1443
size_t numFuncImports() const { return funcImportNames_.length(); }
1444
bool append(AstExport* exp) { return exports_.append(exp); }
1445
const ExportVector& exports() const { return exports_; }
1446
bool append(AstGlobal* glob) { return globals_.append(glob); }
1447
const AstGlobalVector& globals() const { return globals_; }
1448
size_t numGlobalImports() const { return numGlobalImports_; }
1449
};
1450
1451
class AstUnaryOperator final : public AstExpr {
1452
Op op_;
1453
AstExpr* operand_;
1454
1455
public:
1456
static const AstExprKind Kind = AstExprKind::UnaryOperator;
1457
explicit AstUnaryOperator(Op op, AstExpr* operand)
1458
: AstExpr(Kind), op_(op), operand_(operand) {}
1459
1460
Op op() const { return op_; }
1461
AstExpr* operand() const { return operand_; }
1462
};
1463
1464
class AstBinaryOperator final : public AstExpr {
1465
Op op_;
1466
AstExpr* lhs_;
1467
AstExpr* rhs_;
1468
1469
public:
1470
static const AstExprKind Kind = AstExprKind::BinaryOperator;
1471
explicit AstBinaryOperator(Op op, AstExpr* lhs, AstExpr* rhs)
1472
: AstExpr(Kind), op_(op), lhs_(lhs), rhs_(rhs) {}
1473
1474
Op op() const { return op_; }
1475
AstExpr* lhs() const { return lhs_; }
1476
AstExpr* rhs() const { return rhs_; }
1477
};
1478
1479
class AstComparisonOperator final : public AstExpr {
1480
Op op_;
1481
AstExpr* lhs_;
1482
AstExpr* rhs_;
1483
1484
public:
1485
static const AstExprKind Kind = AstExprKind::ComparisonOperator;
1486
explicit AstComparisonOperator(Op op, AstExpr* lhs, AstExpr* rhs)
1487
: AstExpr(Kind), op_(op), lhs_(lhs), rhs_(rhs) {}
1488
1489
Op op() const { return op_; }
1490
AstExpr* lhs() const { return lhs_; }
1491
AstExpr* rhs() const { return rhs_; }
1492
};
1493
1494
class AstConversionOperator final : public AstExpr {
1495
Op op_;
1496
AstExpr* operand_;
1497
1498
public:
1499
static const AstExprKind Kind = AstExprKind::ConversionOperator;
1500
explicit AstConversionOperator(Op op, AstExpr* operand)
1501
: AstExpr(Kind), op_(op), operand_(operand) {}
1502
1503
Op op() const { return op_; }
1504
AstExpr* operand() const { return operand_; }
1505
};
1506
1507
// Like AstConversionOperator, but for opcodes encoded with the Misc prefix.
1508
class AstExtraConversionOperator final : public AstExpr {
1509
MiscOp op_;
1510
AstExpr* operand_;
1511
1512
public:
1513
static const AstExprKind Kind = AstExprKind::ExtraConversionOperator;
1514
explicit AstExtraConversionOperator(MiscOp op, AstExpr* operand)
1515
: AstExpr(Kind), op_(op), operand_(operand) {}
1516
1517
MiscOp op() const { return op_; }
1518
AstExpr* operand() const { return operand_; }
1519
};
1520
1521
class AstRefFunc final : public AstExpr {
1522
AstRef func_;
1523
1524
public:
1525
static const AstExprKind Kind = AstExprKind::RefFunc;
1526
explicit AstRefFunc(AstRef func) : AstExpr(Kind), func_(func) {}
1527
1528
AstRef& func() { return func_; }
1529
};
1530
1531
class AstRefNull final : public AstExpr {
1532
public:
1533
static const AstExprKind Kind = AstExprKind::RefNull;
1534
AstRefNull() : AstExpr(Kind) {}
1535
};
1536
1537
// This is an artificial AST node which can fill operand slots in an AST
1538
// constructed from parsing or decoding stack-machine code that doesn't have
1539
// an inherent AST structure.
1540
class AstPop final : public AstExpr {
1541
public:
1542
static const AstExprKind Kind = AstExprKind::Pop;
1543
AstPop() : AstExpr(Kind) {}
1544
};
1545
1546
// This is an artificial AST node which can be used to represent some forms
1547
// of stack-machine code in an AST form. It is similar to Block, but returns the
1548
// value of its first operand, rather than the last.
1549
class AstFirst : public AstExpr {
1550
AstExprVector exprs_;
1551
1552
public:
1553
static const AstExprKind Kind = AstExprKind::First;
1554
explicit AstFirst(AstExprVector&& exprs)
1555
: AstExpr(Kind), exprs_(std::move(exprs)) {}
1556
1557
AstExprVector& exprs() { return exprs_; }
1558
const AstExprVector& exprs() const { return exprs_; }
1559
};
1560
1561
} // namespace wasm
1562
} // namespace js
1563
1564
#endif // namespace wasmast_h