Skip to content

Commit 755dfd0

Browse files
Updated waitqueue support
1 parent 79d54a1 commit 755dfd0

38 files changed

Lines changed: 470 additions & 335 deletions

scripts/gen-s-parser.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@
213213
# atomic instructions
214214
("memory.atomic.notify", "makeAtomicNotify()"),
215215
("struct.wait", "makeStructWait()"),
216-
("struct.notify", "makeStructNotify()"),
216+
("waitqueue.new", "makeWaitqueueNew()"),
217+
("waitqueue.notify", "makeWaitqueueNotify()"),
217218
("memory.atomic.wait32", "makeAtomicWait(Type::i32)"),
218219
("memory.atomic.wait64", "makeAtomicWait(Type::i64)"),
219220
("atomic.fence", "makeAtomicFence()"),

src/binaryen-c.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
9292
case HeapType::exn:
9393
WASM_UNREACHABLE("invalid type");
9494
case HeapType::string:
95+
case HeapType::waitqueue:
96+
case HeapType::nowaitqueue:
9597
WASM_UNREACHABLE("TODO: string literals");
9698
case HeapType::none:
9799
case HeapType::noext:
@@ -146,6 +148,8 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
146148
case HeapType::exn:
147149
WASM_UNREACHABLE("invalid type");
148150
case HeapType::string:
151+
case HeapType::waitqueue:
152+
case HeapType::nowaitqueue:
149153
WASM_UNREACHABLE("TODO: string literals");
150154
case HeapType::none:
151155
case HeapType::noext:

src/gen-s-parser.inc

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5448,52 +5448,41 @@ switch (buf[0]) {
54485448
}
54495449
}
54505450
case 'n': {
5451-
switch (buf[8]) {
5452-
case 'e': {
5453-
switch (buf[10]) {
5454-
case '\0':
5455-
if (op == "struct.new"sv) {
5456-
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, false));
5457-
return Ok{};
5458-
}
5459-
goto parse_error;
5460-
case '_': {
5461-
switch (buf[13]) {
5462-
case 'f': {
5463-
switch (buf[18]) {
5464-
case '\0':
5465-
if (op == "struct.new_default"sv) {
5466-
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, false));
5467-
return Ok{};
5468-
}
5469-
goto parse_error;
5470-
case '_':
5471-
if (op == "struct.new_default_desc"sv) {
5472-
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, true));
5473-
return Ok{};
5474-
}
5475-
goto parse_error;
5476-
default: goto parse_error;
5451+
switch (buf[10]) {
5452+
case '\0':
5453+
if (op == "struct.new"sv) {
5454+
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, false));
5455+
return Ok{};
5456+
}
5457+
goto parse_error;
5458+
case '_': {
5459+
switch (buf[13]) {
5460+
case 'f': {
5461+
switch (buf[18]) {
5462+
case '\0':
5463+
if (op == "struct.new_default"sv) {
5464+
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, false));
5465+
return Ok{};
54775466
}
5478-
}
5479-
case 's':
5480-
if (op == "struct.new_desc"sv) {
5481-
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, true));
5467+
goto parse_error;
5468+
case '_':
5469+
if (op == "struct.new_default_desc"sv) {
5470+
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, true));
54825471
return Ok{};
54835472
}
54845473
goto parse_error;
54855474
default: goto parse_error;
54865475
}
54875476
}
5477+
case 's':
5478+
if (op == "struct.new_desc"sv) {
5479+
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, true));
5480+
return Ok{};
5481+
}
5482+
goto parse_error;
54885483
default: goto parse_error;
54895484
}
54905485
}
5491-
case 'o':
5492-
if (op == "struct.notify"sv) {
5493-
CHECK_ERR(makeStructNotify(ctx, pos, annotations));
5494-
return Ok{};
5495-
}
5496-
goto parse_error;
54975486
default: goto parse_error;
54985487
}
54995488
}
@@ -5893,6 +5882,23 @@ switch (buf[0]) {
58935882
default: goto parse_error;
58945883
}
58955884
}
5885+
case 'w': {
5886+
switch (buf[11]) {
5887+
case 'e':
5888+
if (op == "waitqueue.new"sv) {
5889+
CHECK_ERR(makeWaitqueueNew(ctx, pos, annotations));
5890+
return Ok{};
5891+
}
5892+
goto parse_error;
5893+
case 'o':
5894+
if (op == "waitqueue.notify"sv) {
5895+
CHECK_ERR(makeWaitqueueNotify(ctx, pos, annotations));
5896+
return Ok{};
5897+
}
5898+
goto parse_error;
5899+
default: goto parse_error;
5900+
}
5901+
}
58965902
default: goto parse_error;
58975903
}
58985904
parse_error:

src/interpreter/interpreter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
257257
Flow visitStructRMW(StructRMW* curr) { WASM_UNREACHABLE("TODO"); }
258258
Flow visitStructCmpxchg(StructCmpxchg* curr) { WASM_UNREACHABLE("TODO"); }
259259
Flow visitStructWait(StructWait* curr) { WASM_UNREACHABLE("TODO"); }
260-
Flow visitStructNotify(StructNotify* curr) { WASM_UNREACHABLE("TODO"); }
260+
Flow visitWaitqueueNew(WaitqueueNew* curr) { WASM_UNREACHABLE("TODO"); }
261+
Flow visitWaitqueueNotify(WaitqueueNotify* curr) { WASM_UNREACHABLE("TODO"); }
261262
Flow visitArrayNew(ArrayNew* curr) { WASM_UNREACHABLE("TODO"); }
262263
Flow visitArrayNewData(ArrayNewData* curr) { WASM_UNREACHABLE("TODO"); }
263264
Flow visitArrayNewElem(ArrayNewElem* curr) { WASM_UNREACHABLE("TODO"); }

src/ir/ReFinalize.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,10 @@ void ReFinalize::visitStructSet(StructSet* curr) { curr->finalize(); }
166166
void ReFinalize::visitStructRMW(StructRMW* curr) { curr->finalize(); }
167167
void ReFinalize::visitStructCmpxchg(StructCmpxchg* curr) { curr->finalize(); }
168168
void ReFinalize::visitStructWait(StructWait* curr) { curr->finalize(); }
169-
void ReFinalize::visitStructNotify(StructNotify* curr) { curr->finalize(); }
169+
void ReFinalize::visitWaitqueueNew(WaitqueueNew* curr) { curr->finalize(); }
170+
void ReFinalize::visitWaitqueueNotify(WaitqueueNotify* curr) {
171+
curr->finalize();
172+
}
170173
void ReFinalize::visitArrayNew(ArrayNew* curr) { curr->finalize(); }
171174
void ReFinalize::visitArrayNewData(ArrayNewData* curr) { curr->finalize(); }
172175
void ReFinalize::visitArrayNewElem(ArrayNewElem* curr) { curr->finalize(); }

src/ir/child-typer.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,21 +1037,15 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
10371037
}
10381038

10391039
note(&curr->ref, Type(*ht, Nullable));
1040+
note(&curr->waitqueue, Type(HeapType::waitqueue, Nullable));
10401041
note(&curr->expected, Type(Type::BasicType::i32));
10411042
note(&curr->timeout, Type(Type::BasicType::i64));
10421043
}
10431044

1044-
void visitStructNotify(StructNotify* curr,
1045-
std::optional<HeapType> ht = std::nullopt) {
1046-
if (!ht) {
1047-
if (!curr->ref->type.isStruct()) {
1048-
self().noteUnknown();
1049-
return;
1050-
}
1051-
ht = curr->ref->type.getHeapType();
1052-
}
1045+
void visitWaitqueueNew(WaitqueueNew* curr) {}
10531046

1054-
note(&curr->ref, Type(*ht, Nullable));
1047+
void visitWaitqueueNotify(WaitqueueNotify* curr) {
1048+
note(&curr->waitqueue, Type(HeapType::waitqueue, Nullable));
10551049
note(&curr->count, Type(Type::BasicType::i32));
10561050
}
10571051

src/ir/cost.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,13 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
120120
}
121121
CostType visitStructWait(StructWait* curr) {
122122
return AtomicCost + nullCheckCost(curr->ref) + visit(curr->ref) +
123+
nullCheckCost(curr->waitqueue) + visit(curr->waitqueue) +
123124
visit(curr->expected) + visit(curr->timeout);
124125
}
125-
CostType visitStructNotify(StructNotify* curr) {
126-
return AtomicCost + nullCheckCost(curr->ref) + visit(curr->ref) +
127-
visit(curr->count);
126+
CostType visitWaitqueueNew(WaitqueueNew* curr) { return 1; }
127+
CostType visitWaitqueueNotify(WaitqueueNotify* curr) {
128+
return AtomicCost + nullCheckCost(curr->waitqueue) +
129+
visit(curr->waitqueue) + visit(curr->count);
128130
}
129131
CostType visitAtomicNotify(AtomicNotify* curr) {
130132
return AtomicCost + visit(curr->ptr) + visit(curr->notifyCount);

src/ir/effects.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,9 @@ class EffectAnalyzer {
10981098
if (trapOnNull(curr->ref)) {
10991099
return;
11001100
}
1101+
if (trapOnNull(curr->waitqueue)) {
1102+
return;
1103+
}
11011104
// StructWait doesn't strictly write a struct, but it does modify the
11021105
// waiters list associated with the waitqueue field, which we can think
11031106
// of as a write.
@@ -1108,16 +1111,13 @@ class EffectAnalyzer {
11081111
// If the timeout is negative and no-one wakes us.
11091112
parent.mayNotReturn = true;
11101113
}
1111-
void visitStructNotify(StructNotify* curr) {
1112-
if (trapOnNull(curr->ref)) {
1113-
return;
1114-
}
1115-
// Non-shared notifies just return 0.
1116-
if (curr->ref->type.getHeapType().isShared()) {
1114+
void visitWaitqueueNew(WaitqueueNew* curr) {}
1115+
void visitWaitqueueNotify(WaitqueueNotify* curr) {
1116+
if (trapOnNull(curr->waitqueue)) {
11171117
return;
11181118
}
1119-
// AtomicNotify doesn't strictly write the struct, but it does
1120-
// modify the waiters list associated with the waitqueue field, which we
1119+
// AtomicNotify doesn't strictly write anything, but it does
1120+
// modify the waiters list associated with the waitqueue, which we
11211121
// can think of as a write.
11221122
parent.readsSharedMutableStruct = true;
11231123
parent.writesSharedStruct = true;

src/ir/module-utils.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,10 @@ struct CodeScanner : PostWalker<CodeScanner> {
443443
void visitStructGet(StructGet* curr) { info.note(curr->ref->type); }
444444
void visitStructSet(StructSet* curr) { info.note(curr->ref->type); }
445445
void visitStructWait(StructWait* curr) { info.note(curr->ref->type); }
446-
void visitStructNotify(StructNotify* curr) { info.note(curr->ref->type); }
446+
void visitWaitqueueNew(WaitqueueNew* curr) { info.note(curr->type); }
447+
void visitWaitqueueNotify(WaitqueueNotify* curr) {
448+
info.note(curr->waitqueue->type);
449+
}
447450
void visitArrayGet(ArrayGet* curr) { info.note(curr->ref->type); }
448451
void visitArraySet(ArraySet* curr) { info.note(curr->ref->type); }
449452
void visitContBind(ContBind* curr) {

src/ir/possible-constant.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,6 @@ struct PossibleConstantValues {
120120
value = val.and_(Literal(uint32_t(0xffff)));
121121
}
122122
break;
123-
case Field::WaitQueue:
124-
value = val;
125-
break;
126123
case Field::NotPacked:
127124
WASM_UNREACHABLE("unexpected packed type");
128125
break;

0 commit comments

Comments
 (0)