Skip to content

Commit 48d11fd

Browse files
authored
[Custom Descriptors] Add effects for struct.new (#7690)
struct.new can now trap if provided a null descriptor. Update its effects accordingly and add a test that would incorrectly remove a trapping struct.new without this fix.
1 parent b12a949 commit 48d11fd

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

scripts/test/fuzzing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
'minimize-rec-groups-desc.wast',
126126
'precompute-desc.wast',
127127
'gc-desc.wast',
128+
'simplify-locals-desc.wast',
128129
# TODO: fix split_wast() on tricky escaping situations like a string ending
129130
# in \\" (the " is not escaped - there is an escaped \ before it)
130131
'string-lifting-section.wast',

src/ir/effects.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,16 @@ class EffectAnalyzer {
858858
parent.implicitTrap = true;
859859
}
860860
void visitBrOn(BrOn* curr) { parent.breakTargets.insert(curr->name); }
861-
void visitStructNew(StructNew* curr) {}
861+
void visitStructNew(StructNew* curr) {
862+
if (curr->desc) {
863+
// Traps when the descriptor is null.
864+
if (curr->desc->type.isNull()) {
865+
parent.trap = true;
866+
} else if (curr->desc->type.isNullable()) {
867+
parent.implicitTrap = true;
868+
}
869+
}
870+
}
862871
void visitStructGet(StructGet* curr) {
863872
if (curr->ref->type == Type::unreachable) {
864873
return;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
2+
3+
;; RUN: wasm-opt %s --simplify-locals -all -S -o - | filecheck %s
4+
5+
(module
6+
(rec
7+
;; CHECK: (rec
8+
;; CHECK-NEXT: (type $struct (descriptor $desc (struct)))
9+
(type $struct (descriptor $desc (struct)))
10+
;; CHECK: (type $desc (sub (describes $struct (struct))))
11+
(type $desc (sub (describes $struct (struct))))
12+
)
13+
14+
;; CHECK: (func $test (type $2)
15+
;; CHECK-NEXT: (local $l (ref null $struct))
16+
;; CHECK-NEXT: (drop
17+
;; CHECK-NEXT: (struct.new_default $struct
18+
;; CHECK-NEXT: (ref.null none)
19+
;; CHECK-NEXT: )
20+
;; CHECK-NEXT: )
21+
;; CHECK-NEXT: )
22+
(func $test (export "test")
23+
(local $l (ref null $struct))
24+
(local.set $l
25+
;; We should preserve this trap.
26+
(struct.new_default $struct
27+
(ref.null none)
28+
)
29+
)
30+
)
31+
)

0 commit comments

Comments
 (0)