Skip to content

Commit 475a6ca

Browse files
Updated waitqueue support
1 parent 7f44054 commit 475a6ca

38 files changed

Lines changed: 469 additions & 333 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
@@ -5433,52 +5433,41 @@ switch (buf[0]) {
54335433
}
54345434
}
54355435
case 'n': {
5436-
switch (buf[8]) {
5437-
case 'e': {
5438-
switch (buf[10]) {
5439-
case '\0':
5440-
if (op == "struct.new"sv) {
5441-
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, false));
5442-
return Ok{};
5443-
}
5444-
goto parse_error;
5445-
case '_': {
5446-
switch (buf[13]) {
5447-
case 'f': {
5448-
switch (buf[18]) {
5449-
case '\0':
5450-
if (op == "struct.new_default"sv) {
5451-
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, false));
5452-
return Ok{};
5453-
}
5454-
goto parse_error;
5455-
case '_':
5456-
if (op == "struct.new_default_desc"sv) {
5457-
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, true));
5458-
return Ok{};
5459-
}
5460-
goto parse_error;
5461-
default: goto parse_error;
5436+
switch (buf[10]) {
5437+
case '\0':
5438+
if (op == "struct.new"sv) {
5439+
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, false));
5440+
return Ok{};
5441+
}
5442+
goto parse_error;
5443+
case '_': {
5444+
switch (buf[13]) {
5445+
case 'f': {
5446+
switch (buf[18]) {
5447+
case '\0':
5448+
if (op == "struct.new_default"sv) {
5449+
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, false));
5450+
return Ok{};
54625451
}
5463-
}
5464-
case 's':
5465-
if (op == "struct.new_desc"sv) {
5466-
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, true));
5452+
goto parse_error;
5453+
case '_':
5454+
if (op == "struct.new_default_desc"sv) {
5455+
CHECK_ERR(makeStructNew(ctx, pos, annotations, true, true));
54675456
return Ok{};
54685457
}
54695458
goto parse_error;
54705459
default: goto parse_error;
54715460
}
54725461
}
5462+
case 's':
5463+
if (op == "struct.new_desc"sv) {
5464+
CHECK_ERR(makeStructNew(ctx, pos, annotations, false, true));
5465+
return Ok{};
5466+
}
5467+
goto parse_error;
54735468
default: goto parse_error;
54745469
}
54755470
}
5476-
case 'o':
5477-
if (op == "struct.notify"sv) {
5478-
CHECK_ERR(makeStructNotify(ctx, pos, annotations));
5479-
return Ok{};
5480-
}
5481-
goto parse_error;
54825471
default: goto parse_error;
54835472
}
54845473
}
@@ -5878,6 +5867,23 @@ switch (buf[0]) {
58785867
default: goto parse_error;
58795868
}
58805869
}
5870+
case 'w': {
5871+
switch (buf[11]) {
5872+
case 'e':
5873+
if (op == "waitqueue.new"sv) {
5874+
CHECK_ERR(makeWaitqueueNew(ctx, pos, annotations));
5875+
return Ok{};
5876+
}
5877+
goto parse_error;
5878+
case 'o':
5879+
if (op == "waitqueue.notify"sv) {
5880+
CHECK_ERR(makeWaitqueueNotify(ctx, pos, annotations));
5881+
return Ok{};
5882+
}
5883+
goto parse_error;
5884+
default: goto parse_error;
5885+
}
5886+
}
58815887
default: goto parse_error;
58825888
}
58835889
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)