Skip to content

Commit df3d896

Browse files
authored
[Custom Descriptors] Add struct.new_desc (#8057)
and struct.new_default_desc instructions that take descriptor operands. These will replace the overload of struct.new and struct.new_default for types that have descriptors. It will be invalid to use the new instructions on types that do not have descriptors and to use the old instructions on types that do have descriptors. For now, to allow for a graceful transition, accept the old overloaded uses of struct.new and struct.new_default where the new instructions will eventually be required.
1 parent 2f79888 commit df3d896

35 files changed

+392
-328
lines changed

scripts/gen-s-parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,8 +620,10 @@
620620
("br_on_cast_fail", "makeBrOnCast(BrOnCastFail)"),
621621
("br_on_cast_desc", "makeBrOnCast(BrOnCastDesc)"),
622622
("br_on_cast_desc_fail", "makeBrOnCast(BrOnCastDescFail)"),
623-
("struct.new", "makeStructNew(false)"),
624-
("struct.new_default", "makeStructNew(true)"),
623+
("struct.new", "makeStructNew(false, false)"),
624+
("struct.new_default", "makeStructNew(true, false)"),
625+
("struct.new_desc", "makeStructNew(false, true)"),
626+
("struct.new_default_desc", "makeStructNew(true, true)"),
625627
("struct.get", "makeStructGet()"),
626628
("struct.get_s", "makeStructGet(true)"),
627629
("struct.get_u", "makeStructGet(false)"),

src/gen-s-parser.inc

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5315,16 +5315,38 @@ switch (buf[0]) {
53155315
switch (buf[10]) {
53165316
case '\0':
53175317
if (op == "struct.new"sv) {
5318-
CHECK_ERR(makeStructNew(ctx, pos, annotations, false));
5318+
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, false));
53195319
return Ok{};
53205320
}
53215321
goto parse_error;
5322-
case '_':
5323-
if (op == "struct.new_default"sv) {
5324-
CHECK_ERR(makeStructNew(ctx, pos, annotations, true));
5325-
return Ok{};
5322+
case '_': {
5323+
switch (buf[13]) {
5324+
case 'f': {
5325+
switch (buf[18]) {
5326+
case '\0':
5327+
if (op == "struct.new_default"sv) {
5328+
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, false));
5329+
return Ok{};
5330+
}
5331+
goto parse_error;
5332+
case '_':
5333+
if (op == "struct.new_default_desc"sv) {
5334+
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, true));
5335+
return Ok{};
5336+
}
5337+
goto parse_error;
5338+
default: goto parse_error;
5339+
}
5340+
}
5341+
case 's':
5342+
if (op == "struct.new_desc"sv) {
5343+
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, true));
5344+
return Ok{};
5345+
}
5346+
goto parse_error;
5347+
default: goto parse_error;
53265348
}
5327-
goto parse_error;
5349+
}
53285350
default: goto parse_error;
53295351
}
53305352
}

src/parser/contexts.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -756,12 +756,13 @@ struct NullInstrParserCtx {
756756
}
757757

758758
template<typename HeapTypeT>
759-
Result<> makeStructNew(Index, const std::vector<Annotation>&, HeapTypeT) {
759+
Result<>
760+
makeStructNew(Index, const std::vector<Annotation>&, HeapTypeT, bool) {
760761
return Ok{};
761762
}
762763
template<typename HeapTypeT>
763764
Result<>
764-
makeStructNewDefault(Index, const std::vector<Annotation>&, HeapTypeT) {
765+
makeStructNewDefault(Index, const std::vector<Annotation>&, HeapTypeT, bool) {
765766
return Ok{};
766767
}
767768
template<typename HeapTypeT>
@@ -2650,14 +2651,16 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
26502651

26512652
Result<> makeStructNew(Index pos,
26522653
const std::vector<Annotation>& annotations,
2653-
HeapType type) {
2654-
return withLoc(pos, irBuilder.makeStructNew(type));
2654+
HeapType type,
2655+
bool isDesc) {
2656+
return withLoc(pos, irBuilder.makeStructNew(type, isDesc));
26552657
}
26562658

26572659
Result<> makeStructNewDefault(Index pos,
26582660
const std::vector<Annotation>& annotations,
2659-
HeapType type) {
2660-
return withLoc(pos, irBuilder.makeStructNewDefault(type));
2661+
HeapType type,
2662+
bool isDesc) {
2663+
return withLoc(pos, irBuilder.makeStructNewDefault(type, isDesc));
26612664
}
26622665

26632666
Result<> makeStructGet(Index pos,

src/parser/parsers.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ makeBrOnNull(Ctx&, Index, const std::vector<Annotation>&, bool onFail = false);
244244
template<typename Ctx>
245245
Result<> makeBrOnCast(Ctx&, Index, const std::vector<Annotation>&, BrOnOp op);
246246
template<typename Ctx>
247-
Result<>
248-
makeStructNew(Ctx&, Index, const std::vector<Annotation>&, bool default_);
247+
Result<> makeStructNew(
248+
Ctx&, Index, const std::vector<Annotation>&, bool default_, bool isDesc);
249249
template<typename Ctx>
250250
Result<> makeStructGet(Ctx&,
251251
Index,
@@ -2315,13 +2315,14 @@ template<typename Ctx>
23152315
Result<> makeStructNew(Ctx& ctx,
23162316
Index pos,
23172317
const std::vector<Annotation>& annotations,
2318-
bool default_) {
2318+
bool default_,
2319+
bool isDesc) {
23192320
auto type = typeidx(ctx);
23202321
CHECK_ERR(type);
23212322
if (default_) {
2322-
return ctx.makeStructNewDefault(pos, annotations, *type);
2323+
return ctx.makeStructNewDefault(pos, annotations, *type, isDesc);
23232324
}
2324-
return ctx.makeStructNew(pos, annotations, *type);
2325+
return ctx.makeStructNew(pos, annotations, *type, isDesc);
23252326
}
23262327

23272328
template<typename Ctx>

src/passes/Print.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,6 +2309,9 @@ struct PrintExpressionContents
23092309
if (curr->isWithDefault()) {
23102310
printMedium(o, "_default");
23112311
}
2312+
if (curr->desc) {
2313+
printMedium(o, "_desc");
2314+
}
23122315
o << ' ';
23132316
printHeapTypeName(curr->type.getHeapType());
23142317
}

src/wasm-binary.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,8 @@ enum ASTNodes {
11551155

11561156
StructNew = 0x00,
11571157
StructNewDefault = 0x01,
1158+
StructNewDesc = 0x20,
1159+
StructNewDefaultDesc = 0x21,
11581160
StructGet = 0x02,
11591161
StructGetS = 0x03,
11601162
StructGetU = 0x04,

src/wasm-ir-builder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
229229
Type in = Type::none,
230230
Type out = Type::none,
231231
std::optional<bool> likely = std::nullopt);
232-
Result<> makeStructNew(HeapType type);
233-
Result<> makeStructNewDefault(HeapType type);
232+
Result<> makeStructNew(HeapType type, bool isDesc);
233+
Result<> makeStructNewDefault(HeapType type, bool isDesc);
234234
Result<>
235235
makeStructGet(HeapType type, Index field, bool signed_, MemoryOrder order);
236236
Result<> makeStructSet(HeapType type, Index field, MemoryOrder order);

src/wasm/wasm-binary.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4579,9 +4579,15 @@ Result<> WasmBinaryReader::readInst() {
45794579
return builder.makeBrOn(label, kind, in, cast);
45804580
}
45814581
case BinaryConsts::StructNew:
4582-
return builder.makeStructNew(getIndexedHeapType());
4582+
case BinaryConsts::StructNewDesc: {
4583+
bool isDesc = op == BinaryConsts::StructNewDesc;
4584+
return builder.makeStructNew(getIndexedHeapType(), isDesc);
4585+
}
45834586
case BinaryConsts::StructNewDefault:
4584-
return builder.makeStructNewDefault(getIndexedHeapType());
4587+
case BinaryConsts::StructNewDefaultDesc: {
4588+
bool isDesc = op == BinaryConsts::StructNewDefaultDesc;
4589+
return builder.makeStructNewDefault(getIndexedHeapType(), isDesc);
4590+
}
45854591
case BinaryConsts::StructGet:
45864592
case BinaryConsts::StructGetS:
45874593
case BinaryConsts::StructGetU: {

src/wasm/wasm-ir-builder.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,10 +2121,17 @@ Result<> IRBuilder::makeBrOn(
21212121
return Ok{};
21222122
}
21232123

2124-
Result<> IRBuilder::makeStructNew(HeapType type) {
2124+
Result<> IRBuilder::makeStructNew(HeapType type, bool isDesc) {
21252125
if (!type.isStruct()) {
21262126
return Err{"expected struct type annotation on struct.new"};
21272127
}
2128+
if (isDesc && !type.getDescriptorType()) {
2129+
return Err{"struct.new_desc of type without descriptor"};
2130+
}
2131+
// TODO: Uncomment this after a transition period.
2132+
// if (!isDesc && type.getDescriptorType()) {
2133+
// return Err{"type with descriptor requires struct.new_desc"};
2134+
// }
21282135
StructNew curr(wasm.allocator);
21292136
curr.type = Type(type, NonNullable, Exact);
21302137
curr.operands.resize(type.getStruct().fields.size());
@@ -2133,7 +2140,14 @@ Result<> IRBuilder::makeStructNew(HeapType type) {
21332140
return Ok{};
21342141
}
21352142

2136-
Result<> IRBuilder::makeStructNewDefault(HeapType type) {
2143+
Result<> IRBuilder::makeStructNewDefault(HeapType type, bool isDesc) {
2144+
if (isDesc && !type.getDescriptorType()) {
2145+
return Err{"struct.new_default_desc of type without descriptor"};
2146+
}
2147+
// TODO: Uncomment this after a transition period.
2148+
// if (!isDesc && type.getDescriptorType()) {
2149+
// return Err{"type with descriptor requires struct.new_default_desc"};
2150+
// }
21372151
StructNew curr(wasm.allocator);
21382152
curr.type = Type(type, NonNullable, Exact);
21392153
CHECK_ERR(visitStructNew(&curr));

src/wasm/wasm-stack.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,9 +2387,21 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
23872387
void BinaryInstWriter::visitStructNew(StructNew* curr) {
23882388
o << int8_t(BinaryConsts::GCPrefix);
23892389
if (curr->isWithDefault()) {
2390-
o << U32LEB(BinaryConsts::StructNewDefault);
2390+
if (curr->desc) {
2391+
// TODO: Start emitting the new opcode once V8 supports it.
2392+
// o << U32LEB(BinaryConsts::StructNewDefaultDesc);
2393+
o << U32LEB(BinaryConsts::StructNewDefault);
2394+
} else {
2395+
o << U32LEB(BinaryConsts::StructNewDefault);
2396+
}
23912397
} else {
2392-
o << U32LEB(BinaryConsts::StructNew);
2398+
if (curr->desc) {
2399+
// TODO: Start emitting the new opcode once V8 supports it.
2400+
// o << U32LEB(BinaryConsts::StructNewDesc);
2401+
o << U32LEB(BinaryConsts::StructNew);
2402+
} else {
2403+
o << U32LEB(BinaryConsts::StructNew);
2404+
}
23932405
}
23942406
parent.writeIndexedHeapType(curr->type.getHeapType());
23952407
}

0 commit comments

Comments
 (0)