Skip to content

Commit bcbabd8

Browse files
authored
[custom-descriptors] Initial support for ref.get_desc (#7614)
Implement parsing and printing for binary and text as well as typing and validation for ref.get_desc.
1 parent dfab223 commit bcbabd8

30 files changed

+264
-21
lines changed

scripts/gen-s-parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@
610610
("i31.get_u", "makeI31Get(false)"),
611611
("ref.test", "makeRefTest()"),
612612
("ref.cast", "makeRefCast()"),
613+
("ref.get_desc", "makeRefGetDesc()"),
613614
("br_on_null", "makeBrOnNull()"),
614615
("br_on_non_null", "makeBrOnNull(true)"),
615616
("br_on_cast", "makeBrOnCast()"),

src/gen-s-parser.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4764,6 +4764,12 @@ switch (buf[0]) {
47644764
return Ok{};
47654765
}
47664766
goto parse_error;
4767+
case 'g':
4768+
if (op == "ref.get_desc"sv) {
4769+
CHECK_ERR(makeRefGetDesc(ctx, pos, annotations));
4770+
return Ok{};
4771+
}
4772+
goto parse_error;
47674773
case 'i': {
47684774
switch (buf[5]) {
47694775
case '3': {

src/interpreter/interpreter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
245245
Flow visitCallRef(CallRef* curr) { WASM_UNREACHABLE("TODO"); }
246246
Flow visitRefTest(RefTest* curr) { WASM_UNREACHABLE("TODO"); }
247247
Flow visitRefCast(RefCast* curr) { WASM_UNREACHABLE("TODO"); }
248+
Flow visitRefGetDesc(RefGetDesc* curr) { WASM_UNREACHABLE("TODO"); }
248249
Flow visitBrOn(BrOn* curr) { WASM_UNREACHABLE("TODO"); }
249250
Flow visitStructNew(StructNew* curr) { WASM_UNREACHABLE("TODO"); }
250251
Flow visitStructGet(StructGet* curr) { WASM_UNREACHABLE("TODO"); }

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ void ReFinalize::visitI31Get(I31Get* curr) { curr->finalize(); }
147147
void ReFinalize::visitCallRef(CallRef* curr) { curr->finalize(); }
148148
void ReFinalize::visitRefTest(RefTest* curr) { curr->finalize(); }
149149
void ReFinalize::visitRefCast(RefCast* curr) { curr->finalize(); }
150+
void ReFinalize::visitRefGetDesc(RefGetDesc* curr) { curr->finalize(); }
150151
void ReFinalize::visitBrOn(BrOn* curr) {
151152
curr->finalize();
152153
if (curr->type == Type::unreachable) {

src/ir/child-typer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,14 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
857857
note(&curr->ref, Type(top, Nullable));
858858
}
859859

860+
void visitRefGetDesc(RefGetDesc* curr,
861+
std::optional<HeapType> ht = std::nullopt) {
862+
if (!ht) {
863+
ht = curr->ref->type.getHeapType();
864+
}
865+
note(&curr->ref, Type(*ht, Nullable));
866+
}
867+
860868
void visitBrOn(BrOn* curr) {
861869
switch (curr->op) {
862870
case BrOnNull:

src/ir/cost.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,9 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
668668
CostType visitRefCast(RefCast* curr) {
669669
return CastCost + nullCheckCost(curr->ref) + visit(curr->ref);
670670
}
671+
CostType visitRefGetDesc(RefGetDesc* curr) {
672+
return 1 + nullCheckCost(curr->ref) + visit(curr->ref);
673+
}
671674
CostType visitBrOn(BrOn* curr) {
672675
// BrOn of a null can be fairly fast, but anything else is a cast check.
673676
CostType base =

src/ir/effects.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,11 @@ class EffectAnalyzer {
849849
}
850850
void visitRefTest(RefTest* curr) {}
851851
void visitRefCast(RefCast* curr) {
852-
// Traps if the ref is not null and the cast fails.
852+
// Traps if the cast fails.
853+
parent.implicitTrap = true;
854+
}
855+
void visitRefGetDesc(RefGetDesc* curr) {
856+
// Traps if the ref is null.
853857
parent.implicitTrap = true;
854858
}
855859
void visitBrOn(BrOn* curr) { parent.breakTargets.insert(curr->name); }

src/ir/possible-contents.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,10 @@ struct InfoCollector
703703

704704
void visitRefCast(RefCast* curr) { receiveChildValue(curr->ref, curr); }
705705
void visitRefTest(RefTest* curr) { addRoot(curr); }
706+
void visitRefGetDesc(RefGetDesc* curr) {
707+
// TODO: Do something more similar to struct.get here
708+
addRoot(curr);
709+
}
706710
void visitBrOn(BrOn* curr) {
707711
// TODO: optimize when possible
708712
handleBreakValue(curr);

src/ir/subtype-exprs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> {
299299
self()->noteCast(curr->ref, curr->castType);
300300
}
301301
void visitRefCast(RefCast* curr) { self()->noteCast(curr->ref, curr); }
302+
void visitRefGetDesc(RefGetDesc* curr) {}
302303
void visitBrOn(BrOn* curr) {
303304
if (curr->op == BrOnCast || curr->op == BrOnCastFail) {
304305
self()->noteCast(curr->ref, curr->castType);

src/parser/contexts.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,10 @@ struct NullInstrParserCtx {
736736
Result<> makeRefCast(Index, const std::vector<Annotation>&, TypeT) {
737737
return Ok{};
738738
}
739+
template<typename HeapTypeT>
740+
Result<> makeRefGetDesc(Index, const std::vector<Annotation>&, HeapTypeT) {
741+
return Ok{};
742+
}
739743

740744
Result<> makeBrOn(Index, const std::vector<Annotation>&, LabelIdxT, BrOnOp) {
741745
return Ok{};
@@ -2591,6 +2595,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
25912595
return withLoc(pos, irBuilder.makeRefCast(type));
25922596
}
25932597

2598+
Result<> makeRefGetDesc(Index pos,
2599+
const std::vector<Annotation>& annotations,
2600+
HeapType type) {
2601+
return withLoc(pos, irBuilder.makeRefGetDesc(type));
2602+
}
2603+
25942604
Result<> makeBrOn(Index pos,
25952605
const std::vector<Annotation>& annotations,
25962606
Index label,

0 commit comments

Comments
 (0)