Skip to content

Commit d30f043

Browse files
zherczegZoltan Herczeg
and
Zoltan Herczeg
authored
Add Type comparison methods (#2580)
Code is based on the work of SoniEx2. Co-authored-by: Zoltan Herczeg <[email protected]>
1 parent 02d7300 commit d30f043

File tree

4 files changed

+154
-15
lines changed

4 files changed

+154
-15
lines changed

include/wabt/type.h

+33-5
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,40 @@ class Type {
6060

6161
Type() = default; // Provided so Type can be member of a union.
6262
Type(int32_t code)
63-
: enum_(static_cast<Enum>(code)), type_index_(kInvalidIndex) {}
64-
Type(Enum e) : enum_(e), type_index_(kInvalidIndex) {}
63+
: enum_(static_cast<Enum>(code)), type_index_(0) {
64+
assert(!EnumIsReferenceWithIndex(enum_));
65+
}
66+
Type(Enum e) : enum_(e), type_index_(0) {
67+
assert(!EnumIsReferenceWithIndex(enum_));
68+
}
6569
Type(Enum e, Index type_index) : enum_(e), type_index_(type_index) {
66-
assert(e == Enum::Reference);
70+
assert(EnumIsReferenceWithIndex(e));
6771
}
6872
constexpr operator Enum() const { return enum_; }
6973

74+
friend constexpr bool operator==(const Type a, const Type b) {
75+
return a.enum_ == b.enum_ && a.type_index_ == b.type_index_;
76+
}
77+
friend constexpr bool operator!=(const Type a, const Type b) {
78+
return !(a == b);
79+
}
80+
friend constexpr bool operator==(const Type ty, const Enum code) {
81+
return ty.enum_ == code;
82+
}
83+
friend constexpr bool operator!=(const Type ty, const Enum code) {
84+
return !(ty == code);
85+
}
86+
friend constexpr bool operator<(const Type a, const Type b) {
87+
return a.enum_ == b.enum_ ? a.type_index_ < b.type_index_
88+
: a.enum_ < b.enum_;
89+
}
90+
7091
bool IsRef() const {
7192
return enum_ == Type::ExternRef || enum_ == Type::FuncRef ||
7293
enum_ == Type::Reference || enum_ == Type::ExnRef;
7394
}
7495

75-
bool IsReferenceWithIndex() const { return enum_ == Type::Reference; }
96+
bool IsReferenceWithIndex() const { return EnumIsReferenceWithIndex(enum_); }
7697

7798
bool IsNullableRef() const {
7899
// Currently all reftypes are nullable
@@ -159,8 +180,15 @@ class Type {
159180
}
160181

161182
private:
183+
static bool EnumIsReferenceWithIndex(Enum value) {
184+
return value == Type::Reference;
185+
}
186+
162187
Enum enum_;
163-
Index type_index_; // Only used for for Type::Reference
188+
// This index is 0 for non-references, so a zeroed
189+
// memory area represents a valid Type::Any type.
190+
// It contains an index for references with type index.
191+
Index type_index_;
164192
};
165193

166194
} // namespace wabt

src/binary-reader.cc

+1-3
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,7 @@ Result BinaryReader::ReadType(Type* out_value, const char* desc) {
376376
}
377377

378378
Result BinaryReader::ReadRefType(Type* out_value, const char* desc) {
379-
uint32_t type = 0;
380-
CHECK_RESULT(ReadS32Leb128(&type, desc));
381-
*out_value = static_cast<Type>(type);
379+
CHECK_RESULT(ReadType(out_value, desc));
382380
ERROR_UNLESS(out_value->IsRef(), "%s must be a reference type", desc);
383381
return Result::Ok;
384382
}

src/type-checker.cc

+2-7
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,6 @@ Result TypeChecker::CheckType(Type actual, Type expected) {
233233
return Result::Ok;
234234
}
235235

236-
if (expected == Type::Reference && actual == Type::Reference) {
237-
return expected.GetReferenceIndex() == actual.GetReferenceIndex()
238-
? Result::Ok
239-
: Result::Error;
240-
}
241236
if (actual != expected) {
242237
return Result::Error;
243238
}
@@ -524,7 +519,7 @@ Result TypeChecker::OnIndexedFuncRef(Index* out_index) {
524519
Type type;
525520
Result result = PeekType(0, &type);
526521
if (!type.IsReferenceWithIndex()) {
527-
type = Type::Reference;
522+
type = Type(Type::Reference, kInvalidIndex);
528523
}
529524
result |= PopAndCheck1Type(type, "call_ref");
530525
if (Succeeded(result)) {
@@ -814,7 +809,7 @@ Result TypeChecker::OnRefIsNullExpr() {
814809
Type type;
815810
Result result = PeekType(0, &type);
816811
if (!type.IsRef()) {
817-
type = Type::Reference;
812+
type = Type(Type::Reference, kInvalidIndex);
818813
}
819814
result |= PopAndCheck1Type(type, "ref.is_null");
820815
PushType(Type::I32);
+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
;;; TOOL: run-objdump
2+
;;; ARGS0: -v --enable-function-references
3+
(module
4+
(type $t1 (func))
5+
(type $t2 (func))
6+
(type $t3 (func))
7+
8+
(func $f1 (param (ref $t1)) )
9+
(func $f2 (param (ref $t2)) )
10+
(func $f3 (param (ref $t3)) )
11+
(func $f4 (param (ref $t3)) )
12+
(func $f5 (param (ref $t2)) )
13+
(func $f6 (param (ref $t1)) )
14+
)
15+
(;; STDERR ;;;
16+
0000000: 0061 736d ; WASM_BINARY_MAGIC
17+
0000004: 0100 0000 ; WASM_BINARY_VERSION
18+
; section "Type" (1)
19+
0000008: 01 ; section code
20+
0000009: 00 ; section size (guess)
21+
000000a: 06 ; num types
22+
; func type 0
23+
000000b: 60 ; func
24+
000000c: 00 ; num params
25+
000000d: 00 ; num results
26+
; func type 1
27+
000000e: 60 ; func
28+
000000f: 00 ; num params
29+
0000010: 00 ; num results
30+
; func type 2
31+
0000011: 60 ; func
32+
0000012: 00 ; num params
33+
0000013: 00 ; num results
34+
; func type 3
35+
0000014: 60 ; func
36+
0000015: 01 ; num params
37+
0000016: 6b ; (ref 0)
38+
0000017: 00 ; (ref 0)
39+
0000018: 00 ; num results
40+
; func type 4
41+
0000019: 60 ; func
42+
000001a: 01 ; num params
43+
000001b: 6b ; (ref 1)
44+
000001c: 01 ; (ref 1)
45+
000001d: 00 ; num results
46+
; func type 5
47+
000001e: 60 ; func
48+
000001f: 01 ; num params
49+
0000020: 6b ; (ref 2)
50+
0000021: 02 ; (ref 2)
51+
0000022: 00 ; num results
52+
0000009: 19 ; FIXUP section size
53+
; section "Function" (3)
54+
0000023: 03 ; section code
55+
0000024: 00 ; section size (guess)
56+
0000025: 06 ; num functions
57+
0000026: 03 ; function 0 signature index
58+
0000027: 04 ; function 1 signature index
59+
0000028: 05 ; function 2 signature index
60+
0000029: 05 ; function 3 signature index
61+
000002a: 04 ; function 4 signature index
62+
000002b: 03 ; function 5 signature index
63+
0000024: 07 ; FIXUP section size
64+
; section "Code" (10)
65+
000002c: 0a ; section code
66+
000002d: 00 ; section size (guess)
67+
000002e: 06 ; num functions
68+
; function body 0
69+
000002f: 00 ; func body size (guess)
70+
0000030: 00 ; local decl count
71+
0000031: 0b ; end
72+
000002f: 02 ; FIXUP func body size
73+
; function body 1
74+
0000032: 00 ; func body size (guess)
75+
0000033: 00 ; local decl count
76+
0000034: 0b ; end
77+
0000032: 02 ; FIXUP func body size
78+
; function body 2
79+
0000035: 00 ; func body size (guess)
80+
0000036: 00 ; local decl count
81+
0000037: 0b ; end
82+
0000035: 02 ; FIXUP func body size
83+
; function body 3
84+
0000038: 00 ; func body size (guess)
85+
0000039: 00 ; local decl count
86+
000003a: 0b ; end
87+
0000038: 02 ; FIXUP func body size
88+
; function body 4
89+
000003b: 00 ; func body size (guess)
90+
000003c: 00 ; local decl count
91+
000003d: 0b ; end
92+
000003b: 02 ; FIXUP func body size
93+
; function body 5
94+
000003e: 00 ; func body size (guess)
95+
000003f: 00 ; local decl count
96+
0000040: 0b ; end
97+
000003e: 02 ; FIXUP func body size
98+
000002d: 13 ; FIXUP section size
99+
;;; STDERR ;;)
100+
(;; STDOUT ;;;
101+
102+
typed-func-ref-signature.wasm: file format wasm 0x1
103+
104+
Code Disassembly:
105+
106+
000030 func[0]:
107+
000031: 0b | end
108+
000033 func[1]:
109+
000034: 0b | end
110+
000036 func[2]:
111+
000037: 0b | end
112+
000039 func[3]:
113+
00003a: 0b | end
114+
00003c func[4]:
115+
00003d: 0b | end
116+
00003f func[5]:
117+
000040: 0b | end
118+
;;; STDOUT ;;)

0 commit comments

Comments
 (0)