Skip to content

Commit a442179

Browse files
author
Zoltan Herczeg
committed
Implement GC opcodes
1 parent 097046d commit a442179

38 files changed

+2211
-1360
lines changed

include/wabt/binary-reader-logging.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,12 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
246246
Index memidx,
247247
Address alignment_log2,
248248
Address offset) override;
249+
Result OnStructGet(Opcode opcode,
250+
Index type_index,
251+
Index field_index) override;
252+
Result OnStructNew(Index type_index) override;
253+
Result OnStructNewDefault(Index type_index) override;
254+
Result OnStructSet(Index type_index, Index field_index) override;
249255
Result OnThrowExpr(Index tag_index) override;
250256
Result OnThrowRefExpr() override;
251257
Result OnTryExpr(Type sig_type) override;

include/wabt/binary-reader-nop.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,14 @@ class BinaryReaderNop : public BinaryReaderDelegate {
335335
Address offset) override {
336336
return Result::Ok;
337337
}
338+
Result OnStructGet(Opcode opcode,
339+
Index type_index,
340+
Index field_index) override {
341+
return Result::Ok;
342+
}
343+
Result OnStructNew(Index type_index) override { return Result::Ok; }
344+
Result OnStructNewDefault(Index type_index) override { return Result::Ok; }
345+
Result OnStructSet(Index type_index, Index field_index) override { return Result::Ok; }
338346
Result OnThrowExpr(Index depth) override { return Result::Ok; }
339347
Result OnThrowRefExpr() override { return Result::Ok; }
340348
Result OnTryExpr(Type sig_type) override { return Result::Ok; }

include/wabt/binary-reader.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ class BinaryReaderDelegate {
328328
Index memidx,
329329
Address alignment_log2,
330330
Address offset) = 0;
331+
virtual Result OnStructGet(Opcode opcode,
332+
Index type_index,
333+
Index field_index) = 0;
334+
virtual Result OnStructNew(Index type_index) = 0;
335+
virtual Result OnStructNewDefault(Index type_index) = 0;
336+
virtual Result OnStructSet(Index type_index, Index field_index) = 0;
331337
virtual Result OnThrowExpr(Index tag_index) = 0;
332338
virtual Result OnThrowRefExpr() = 0;
333339
virtual Result OnTryExpr(Type sig_type) = 0;

include/wabt/expr-visitor.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ class ExprVisitor::Delegate {
145145
virtual Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) = 0;
146146
virtual Result OnLoadSplatExpr(LoadSplatExpr*) = 0;
147147
virtual Result OnLoadZeroExpr(LoadZeroExpr*) = 0;
148+
virtual Result OnStructGetExpr(StructGetExpr*) = 0;
149+
virtual Result OnStructNewExpr(StructNewExpr*) = 0;
150+
virtual Result OnStructNewDefaultExpr(StructNewDefaultExpr*) = 0;
151+
virtual Result OnStructSetExpr(StructSetExpr*) = 0;
148152
};
149153

150154
class ExprVisitor::DelegateNop : public ExprVisitor::Delegate {
@@ -230,6 +234,12 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate {
230234
Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) override { return Result::Ok; }
231235
Result OnLoadSplatExpr(LoadSplatExpr*) override { return Result::Ok; }
232236
Result OnLoadZeroExpr(LoadZeroExpr*) override { return Result::Ok; }
237+
Result OnStructGetExpr(StructGetExpr*) override { return Result::Ok; }
238+
Result OnStructNewExpr(StructNewExpr*) override { return Result::Ok; }
239+
Result OnStructNewDefaultExpr(StructNewDefaultExpr*) override {
240+
return Result::Ok;
241+
}
242+
Result OnStructSetExpr(StructSetExpr*) override { return Result::Ok; }
233243
};
234244

235245
} // namespace wabt

include/wabt/interp/interp-inl.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,28 @@ inline const TagType& Tag::type() const {
902902
return type_;
903903
}
904904

905+
//// Struct ////
906+
// static
907+
inline bool Struct::classof(const Object* obj) {
908+
return obj->kind() == skind;
909+
}
910+
911+
inline Struct::Ptr Struct::New(Store& store, Index type_index, Module* mod) {
912+
return store.Alloc<Struct>(store, type_index, mod);
913+
}
914+
915+
inline Index Struct::Size() {
916+
return static_cast<Index>(fields_.size());
917+
}
918+
919+
inline Value Struct::GetField(Index idx) {
920+
return fields_[idx];
921+
}
922+
923+
inline void Struct::SetField(Index idx, Value value) {
924+
fields_[idx] = value;
925+
}
926+
905927
//// ElemSegment ////
906928
inline void ElemSegment::Drop() {
907929
elements_.clear();

include/wabt/interp/interp.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ enum class ObjectKind {
8989
Memory,
9090
Global,
9191
Tag,
92+
Struct,
9293
Module,
9394
Instance,
9495

@@ -999,6 +1000,29 @@ class Tag : public Extern {
9991000
TagType type_;
10001001
};
10011002

1003+
class Struct : public Object {
1004+
public:
1005+
static bool classof(const Object* obj);
1006+
static const ObjectKind skind = ObjectKind::Struct;
1007+
static const char* GetTypeName() { return "Struct"; }
1008+
using Ptr = RefPtr<Struct>;
1009+
1010+
static Struct::Ptr New(Store&, Index type_index, Module* mod);
1011+
1012+
Index Size();
1013+
Value GetField(Index idx);
1014+
void SetField(Index idx, Value value);
1015+
1016+
private:
1017+
friend Store;
1018+
explicit Struct(Store&, Index type_index, Module* mod);
1019+
void Mark(Store&) override;
1020+
1021+
Ref module_;
1022+
Index type_index_;
1023+
Values fields_;
1024+
};
1025+
10021026
class ElemSegment {
10031027
public:
10041028
explicit ElemSegment(Store& store, const ElemDesc*, RefPtr<Instance>&);

include/wabt/interp/istream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum class InstrKind {
5454
Imm_Index_Op_2, // table.set
5555
Imm_Index_Op_3, // memory.fill
5656
Imm_Index_Op_N, // call
57+
Imm_Index_Index_Op_1, // struct.get_s
5758
Imm_Index_Index_Op_3, // memory.init
5859
Imm_Index_Index_Op_N, // call_indirect
5960
Imm_Index_Offset_Op_1, // i32.load

include/wabt/ir.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ struct Const {
183183
void set_funcref() { From<uintptr_t>(Type::FuncRef, 0); }
184184
void set_externref(uintptr_t x) { From(Type::ExternRef, x); }
185185
void set_extern(uintptr_t x) { From(Type(Type::ExternRef, Type::ReferenceNonNull), x); }
186+
void set_ref_struct() { From<uintptr_t>(Type(Type::StructRef, Type::ReferenceNonNull), 0); }
186187
void set_null(Type type) { From<uintptr_t>(type, kRefNullBits); }
187188

188189
bool is_expected_nan(int lane = 0) const {
@@ -457,6 +458,10 @@ enum class ExprType {
457458
SimdLoadLane,
458459
SimdStoreLane,
459460
SimdShuffleOp,
461+
StructGet,
462+
StructNew,
463+
StructNewDefault,
464+
StructSet,
460465
LoadSplat,
461466
LoadZero,
462467
Store,
@@ -707,6 +712,8 @@ using LocalTeeExpr = VarExpr<ExprType::LocalTee>;
707712
using ReturnCallExpr = VarExpr<ExprType::ReturnCall>;
708713
using ThrowExpr = VarExpr<ExprType::Throw>;
709714
using RethrowExpr = VarExpr<ExprType::Rethrow>;
715+
using StructNewExpr = VarExpr<ExprType::StructNew>;
716+
using StructNewDefaultExpr = VarExpr<ExprType::StructNewDefault>;
710717

711718
using DataDropExpr = VarExpr<ExprType::DataDrop>;
712719
using ElemDropExpr = VarExpr<ExprType::ElemDrop>;
@@ -896,6 +903,28 @@ class AtomicFenceExpr : public ExprMixin<ExprType::AtomicFence> {
896903
uint32_t consistency_model;
897904
};
898905

906+
template <ExprType TypeEnum>
907+
class TypeVarExpr : public ExprMixin<TypeEnum> {
908+
public:
909+
TypeVarExpr(const Var& comp_type, const Var& var, const Location& loc = Location())
910+
: ExprMixin<TypeEnum>(loc), comp_type(comp_type), var(var) {}
911+
912+
Var comp_type;
913+
Var var;
914+
};
915+
916+
using StructSetExpr = TypeVarExpr<ExprType::StructSet>;
917+
918+
class StructGetExpr : public ExprMixin<ExprType::StructGet> {
919+
public:
920+
StructGetExpr(Opcode opcode, const Var& comp_type, const Var& var, const Location& loc = Location())
921+
: ExprMixin<ExprType::StructGet>(loc), opcode(opcode), comp_type(comp_type), var(var) {}
922+
923+
Opcode opcode;
924+
Var comp_type;
925+
Var var;
926+
};
927+
899928
struct Tag {
900929
explicit Tag(std::string_view name) : name(name) {}
901930

@@ -1282,6 +1311,10 @@ struct Module {
12821311
Index GetFuncTypeIndex(const FuncSignature&) const;
12831312
const FuncType* GetFuncType(const Var&) const;
12841313
FuncType* GetFuncType(const Var&);
1314+
const StructType* GetStructType(const Var&) const;
1315+
StructType* GetStructType(const Var&);
1316+
const ArrayType* GetArrayType(const Var&) const;
1317+
ArrayType* GetArrayType(const Var&);
12851318
Index GetFuncIndex(const Var&) const;
12861319
const Func* GetFunc(const Var&) const;
12871320
Func* GetFunc(const Var&);

include/wabt/opcode.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,14 @@ WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd4, RefAsNonNull, "ref.as_non_nu
272272
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd5, BrOnNull, "br_on_null", "")
273273
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd6, BrOnNonNull, "br_on_non_null", "")
274274

275+
/* Garbage collection opcodes */
276+
WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x00, StructNew, "struct.new", "")
277+
WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x01, StructNewDefault, "struct.new_default", "")
278+
WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x02, StructGet, "struct.get", "")
279+
WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x03, StructGetS, "struct.get_s", "")
280+
WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x04, StructGetU, "struct.get_u", "")
281+
WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x05, StructSet, "struct.set", "")
282+
275283
/* Simd opcodes */
276284
WABT_OPCODE(V128, I32, ___, ___, 16, 0xfd, 0x00, V128Load, "v128.load", "")
277285
WABT_OPCODE(V128, I32, ___, ___, 8, 0xfd, 0x01, V128Load8X8S, "v128.load8x8_s", "")

include/wabt/opcode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ struct Opcode {
8484
Address GetAlignment(Address alignment) const;
8585

8686
static bool IsPrefixByte(uint8_t byte) {
87-
return byte == kMathPrefix || byte == kThreadsPrefix || byte == kSimdPrefix;
87+
return byte == kMathPrefix || byte == kThreadsPrefix || byte == kGarbageCollectionPrefix || byte == kSimdPrefix;
8888
}
8989

9090
bool IsEnabled(const Features& features) const;
@@ -93,6 +93,7 @@ struct Opcode {
9393
private:
9494
static constexpr uint32_t kMathPrefix = 0xfc;
9595
static constexpr uint32_t kThreadsPrefix = 0xfe;
96+
static constexpr uint32_t kGarbageCollectionPrefix = 0xfb;
9697
static constexpr uint32_t kSimdPrefix = 0xfd;
9798

9899
struct Info {

0 commit comments

Comments
 (0)