summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-01-29 16:03:31 -0800
committerGitHub <noreply@github.com>2024-01-29 16:03:31 -0800
commitc0046ad0e44d39f7ef33fa6a401a0d9d5a34a578 (patch)
tree29437ef5ff67a2a51b8a2566cad228f2e3c7ade7
parent9a31d7e351910191af2c00a9834bcb2e81a28d12 (diff)
downloadbinaryen-c0046ad0e44d39f7ef33fa6a401a0d9d5a34a578.tar.gz
binaryen-c0046ad0e44d39f7ef33fa6a401a0d9d5a34a578.tar.bz2
binaryen-c0046ad0e44d39f7ef33fa6a401a0d9d5a34a578.zip
[Parser] Parse local.set and global.set of tuple values correctly (#6250)
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.
-rw-r--r--src/wasm-ir-builder.h2
-rw-r--r--src/wasm/wasm-ir-builder.cpp18
-rw-r--r--test/lit/wat-kitchen-sink.wast57
3 files changed, 70 insertions, 7 deletions
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h
index 77ad2490e..fce8bd431 100644
--- a/src/wasm-ir-builder.h
+++ b/src/wasm-ir-builder.h
@@ -223,6 +223,8 @@ public:
[[nodiscard]] Result<> visitCall(Call*);
[[nodiscard]] Result<> visitCallIndirect(CallIndirect*);
[[nodiscard]] Result<> visitCallRef(CallRef*);
+ [[nodiscard]] Result<> visitLocalSet(LocalSet*);
+ [[nodiscard]] Result<> visitGlobalSet(GlobalSet*);
[[nodiscard]] Result<> visitThrow(Throw*);
[[nodiscard]] Result<> visitStringNew(StringNew*);
[[nodiscard]] Result<> visitStringEncode(StringEncode*);
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index aace2b1ac..1eea777e0 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -492,6 +492,21 @@ Result<> IRBuilder::visitCallRef(CallRef* curr) {
return Ok{};
}
+Result<> IRBuilder::visitLocalSet(LocalSet* curr) {
+ auto type = func->getLocalType(curr->index);
+ auto val = pop(type.size());
+ CHECK_ERR(val);
+ curr->value = *val;
+ return Ok{};
+}
+
+Result<> IRBuilder::visitGlobalSet(GlobalSet* curr) {
+ auto type = wasm.getGlobal(curr->name)->type;
+ auto val = pop(type.size());
+ CHECK_ERR(val);
+ curr->value = *val;
+ return Ok{};
+}
Result<> IRBuilder::visitThrow(Throw* curr) {
auto numArgs = wasm.getTag(curr->tag)->sig.params.size();
curr->operands.resize(numArgs);
@@ -1032,6 +1047,7 @@ Result<> IRBuilder::makeLocalGet(Index local) {
Result<> IRBuilder::makeLocalSet(Index local) {
LocalSet curr;
+ curr.index = local;
CHECK_ERR(visitLocalSet(&curr));
push(builder.makeLocalSet(local, curr.value));
return Ok{};
@@ -1039,6 +1055,7 @@ Result<> IRBuilder::makeLocalSet(Index local) {
Result<> IRBuilder::makeLocalTee(Index local) {
LocalSet curr;
+ curr.index = local;
CHECK_ERR(visitLocalSet(&curr));
push(builder.makeLocalTee(local, curr.value, func->getLocalType(local)));
return Ok{};
@@ -1051,6 +1068,7 @@ Result<> IRBuilder::makeGlobalGet(Name global) {
Result<> IRBuilder::makeGlobalSet(Name global) {
GlobalSet curr;
+ curr.name = global;
CHECK_ERR(visitGlobalSet(&curr));
push(builder.makeGlobalSet(global, curr.value));
return Ok{};
diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast
index bbb8146db..eff635237 100644
--- a/test/lit/wat-kitchen-sink.wast
+++ b/test/lit/wat-kitchen-sink.wast
@@ -296,6 +296,12 @@
;; CHECK: (global $i32 i32 (i32.const 42))
(global $i32 i32 i32.const 42)
+ ;; CHECK: (global $pair (mut (tuple i32 i64)) (tuple.make 2
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i64.const 1)
+ ;; CHECK-NEXT: ))
+ (global $pair (mut (tuple i32 i64)) (tuple.make 2 (i32.const 0) (i64.const 1)))
+
;; memories
;; CHECK: (memory $mem 1 1 shared)
(memory $mem 1 1 shared)
@@ -457,12 +463,6 @@
;; CHECK-NEXT: )
(func $f4 (type 18) (local i32 i64) (local $l f32))
- ;; CHECK: (func $tuple-locals (type $void)
- ;; CHECK-NEXT: (local $0 (tuple i32 i32))
- ;; CHECK-NEXT: (nop)
- ;; CHECK-NEXT: )
- (func $tuple-locals (local (tuple i32 i32)))
-
;; CHECK: (func $nop-skate (type $void)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (nop)
@@ -930,6 +930,30 @@
drop
)
+ ;; CHECK: (func $tuple-locals (type $void)
+ ;; CHECK-NEXT: (local $0 (tuple i32 i64))
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (local.tee $0
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (tuple.make 2
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (i64.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $tuple-locals
+ (local (tuple i32 i64))
+ local.get 0
+ local.tee 0
+ local.set 0
+ i32.const 1
+ i64.const 2
+ local.set 0
+ )
+
;; CHECK: (func $block (type $void)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (block $l
@@ -3064,6 +3088,25 @@
global.set 4
)
+ ;; CHECK: (func $tuple-globals (type $void)
+ ;; CHECK-NEXT: (global.set $pair
+ ;; CHECK-NEXT: (global.get $pair)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (global.set $pair
+ ;; CHECK-NEXT: (tuple.make 2
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (i64.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $tuple-globals
+ global.get $pair
+ global.set $pair
+ i32.const 1
+ i64.const 2
+ global.set $pair
+ )
+
;; CHECK: (func $load (type $4) (param $0 i32) (param $1 i64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.load $mimport$0 offset=42
@@ -3525,7 +3568,7 @@
(func $ref-func
ref.func $ref-func
drop
- ref.func 152
+ ref.func 153
drop
)