Skip to content

Commit 76afc4c

Browse files
committed
[Parser] Parse local.set and global.set of tuple values correctly
These instructions always pop a single value, except when tuples are involved, in which case they need special handling to know how many values to pop.
1 parent 4a4c934 commit 76afc4c

File tree

3 files changed

+69
-7
lines changed

3 files changed

+69
-7
lines changed

src/wasm-ir-builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
223223
[[nodiscard]] Result<> visitCall(Call*);
224224
[[nodiscard]] Result<> visitCallIndirect(CallIndirect*);
225225
[[nodiscard]] Result<> visitCallRef(CallRef*);
226+
[[nodiscard]] Result<> visitLocalSet(LocalSet*);
227+
[[nodiscard]] Result<> visitGlobalSet(GlobalSet*);
226228
[[nodiscard]] Result<> visitThrow(Throw*);
227229
[[nodiscard]] Result<> visitStringNew(StringNew*);
228230
[[nodiscard]] Result<> visitStringEncode(StringEncode*);

src/wasm/wasm-ir-builder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,21 @@ Result<> IRBuilder::visitCallRef(CallRef* curr) {
492492
return Ok{};
493493
}
494494

495+
Result<> IRBuilder::visitLocalSet(LocalSet* curr) {
496+
auto type = func->getLocalType(curr->index);
497+
auto val = pop(type.size());
498+
CHECK_ERR(val);
499+
curr->value = *val;
500+
return Ok{};
501+
}
502+
503+
Result<> IRBuilder::visitGlobalSet(GlobalSet* curr) {
504+
auto type = wasm.getGlobal(curr->name)->type;
505+
auto val = pop(type.size());
506+
CHECK_ERR(val);
507+
curr->value = *val;
508+
return Ok{};
509+
}
495510
Result<> IRBuilder::visitThrow(Throw* curr) {
496511
auto numArgs = wasm.getTag(curr->tag)->sig.params.size();
497512
curr->operands.resize(numArgs);
@@ -1032,6 +1047,7 @@ Result<> IRBuilder::makeLocalGet(Index local) {
10321047

10331048
Result<> IRBuilder::makeLocalSet(Index local) {
10341049
LocalSet curr;
1050+
curr.index = local;
10351051
CHECK_ERR(visitLocalSet(&curr));
10361052
push(builder.makeLocalSet(local, curr.value));
10371053
return Ok{};
@@ -1051,6 +1067,7 @@ Result<> IRBuilder::makeGlobalGet(Name global) {
10511067

10521068
Result<> IRBuilder::makeGlobalSet(Name global) {
10531069
GlobalSet curr;
1070+
curr.name = global;
10541071
CHECK_ERR(visitGlobalSet(&curr));
10551072
push(builder.makeGlobalSet(global, curr.value));
10561073
return Ok{};

test/lit/wat-kitchen-sink.wast

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@
296296
;; CHECK: (global $i32 i32 (i32.const 42))
297297
(global $i32 i32 i32.const 42)
298298

299+
;; CHECK: (global $pair (mut (tuple i32 i64)) (tuple.make 2
300+
;; CHECK-NEXT: (i32.const 0)
301+
;; CHECK-NEXT: (i64.const 1)
302+
;; CHECK-NEXT: ))
303+
(global $pair (mut (tuple i32 i64)) (tuple.make 2 (i32.const 0) (i64.const 1)))
304+
299305
;; memories
300306
;; CHECK: (memory $mem 1 1 shared)
301307
(memory $mem 1 1 shared)
@@ -457,12 +463,6 @@
457463
;; CHECK-NEXT: )
458464
(func $f4 (type 18) (local i32 i64) (local $l f32))
459465

460-
;; CHECK: (func $tuple-locals (type $void)
461-
;; CHECK-NEXT: (local $0 (tuple i32 i32))
462-
;; CHECK-NEXT: (nop)
463-
;; CHECK-NEXT: )
464-
(func $tuple-locals (local (tuple i32 i32)))
465-
466466
;; CHECK: (func $nop-skate (type $void)
467467
;; CHECK-NEXT: (nop)
468468
;; CHECK-NEXT: (nop)
@@ -930,6 +930,30 @@
930930
drop
931931
)
932932

933+
;; CHECK: (func $tuple-locals (type $void)
934+
;; CHECK-NEXT: (local $0 (tuple i32 i64))
935+
;; CHECK-NEXT: (local.set $0
936+
;; CHECK-NEXT: (local.tee $0
937+
;; CHECK-NEXT: (local.get $0)
938+
;; CHECK-NEXT: )
939+
;; CHECK-NEXT: )
940+
;; CHECK-NEXT: (local.set $0
941+
;; CHECK-NEXT: (tuple.make 2
942+
;; CHECK-NEXT: (i32.const 1)
943+
;; CHECK-NEXT: (i64.const 2)
944+
;; CHECK-NEXT: )
945+
;; CHECK-NEXT: )
946+
;; CHECK-NEXT: )
947+
(func $tuple-locals
948+
(local (tuple i32 i64))
949+
local.get 0
950+
local.tee 0
951+
local.set 0
952+
i32.const 1
953+
i64.const 2
954+
local.set 0
955+
)
956+
933957
;; CHECK: (func $block (type $void)
934958
;; CHECK-NEXT: (nop)
935959
;; CHECK-NEXT: (block $l
@@ -3064,6 +3088,25 @@
30643088
global.set 4
30653089
)
30663090

3091+
;; CHECK: (func $tuple-globals (type $void)
3092+
;; CHECK-NEXT: (global.set $pair
3093+
;; CHECK-NEXT: (global.get $pair)
3094+
;; CHECK-NEXT: )
3095+
;; CHECK-NEXT: (global.set $pair
3096+
;; CHECK-NEXT: (tuple.make 2
3097+
;; CHECK-NEXT: (i32.const 1)
3098+
;; CHECK-NEXT: (i64.const 2)
3099+
;; CHECK-NEXT: )
3100+
;; CHECK-NEXT: )
3101+
;; CHECK-NEXT: )
3102+
(func $tuple-globals
3103+
global.get $pair
3104+
global.set $pair
3105+
i32.const 1
3106+
i64.const 2
3107+
global.set $pair
3108+
)
3109+
30673110
;; CHECK: (func $load (type $4) (param $0 i32) (param $1 i64)
30683111
;; CHECK-NEXT: (drop
30693112
;; CHECK-NEXT: (i32.load $mimport$0 offset=42
@@ -3525,7 +3568,7 @@
35253568
(func $ref-func
35263569
ref.func $ref-func
35273570
drop
3528-
ref.func 152
3571+
ref.func 153
35293572
drop
35303573
)
35313574

0 commit comments

Comments
 (0)