summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-08-23 12:39:33 -0700
committerGitHub <noreply@github.com>2022-08-23 12:39:33 -0700
commit0ee15961e43e0282b014e4328458e065b6976ba7 (patch)
tree5b9f62084e2af1bbfcfc1d27f76a1e826a03a3b0 /src
parent4b635ecc3ef9ab56afab8061faba69c07eb38740 (diff)
downloadbinaryen-0ee15961e43e0282b014e4328458e065b6976ba7.tar.gz
binaryen-0ee15961e43e0282b014e4328458e065b6976ba7.tar.bz2
binaryen-0ee15961e43e0282b014e4328458e065b6976ba7.zip
Fix multi-memory + C API for MemoryGrow and MemorySize (#4953)
Those instructions need to know if the memory is 64-bit or not. We looked that up on the module globally, which is convenient, but in the C API this was actually a breaking change, it turns out. To keep things working, provide that information when creating a MemoryGrow or MemorySize, as another parameter in the C API. In the C++ API (wasm-builder), support both modes, and default to the automatic lookup. We already require a bunch of other explicit info when creating expressions, like making a Call requires the return type (we don't look it up globally), and even a LocalGet requires the local type (we don't look it up on the function), so this is consistent with those. Fixes #4946
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp24
-rw-r--r--src/binaryen-c.h6
-rw-r--r--src/js/binaryen.js-post.js9
-rw-r--r--src/wasm-builder.h24
4 files changed, 44 insertions, 19 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 3d58debc8..7d11689b0 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -1162,18 +1162,28 @@ BinaryenExpressionRef BinaryenReturn(BinaryenModuleRef module,
auto* ret = Builder(*(Module*)module).makeReturn((Expression*)value);
return static_cast<Expression*>(ret);
}
+
+static Builder::MemoryInfo getMemoryInfo(bool memoryIs64) {
+ return memoryIs64 ? Builder::MemoryInfo::Memory64
+ : Builder::MemoryInfo::Memory32;
+}
+
BinaryenExpressionRef BinaryenMemorySize(BinaryenModuleRef module,
- const char* memoryName) {
- auto* ret =
- Builder(*(Module*)module).makeMemorySize(getMemoryName(module, memoryName));
+ const char* memoryName,
+ bool memoryIs64) {
+ auto* ret = Builder(*(Module*)module)
+ .makeMemorySize(getMemoryName(module, memoryName),
+ getMemoryInfo(memoryIs64));
return static_cast<Expression*>(ret);
}
BinaryenExpressionRef BinaryenMemoryGrow(BinaryenModuleRef module,
BinaryenExpressionRef delta,
- const char* memoryName) {
- auto* ret =
- Builder(*(Module*)module)
- .makeMemoryGrow((Expression*)delta, getMemoryName(module, memoryName));
+ const char* memoryName,
+ bool memoryIs64) {
+ auto* ret = Builder(*(Module*)module)
+ .makeMemoryGrow((Expression*)delta,
+ getMemoryName(module, memoryName),
+ getMemoryInfo(memoryIs64));
return static_cast<Expression*>(ret);
}
BinaryenExpressionRef BinaryenNop(BinaryenModuleRef module) {
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 0a79e7d3d..a21c0966a 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -780,11 +780,13 @@ BINARYEN_API BinaryenExpressionRef BinaryenDrop(BinaryenModuleRef module,
BINARYEN_API BinaryenExpressionRef BinaryenReturn(BinaryenModuleRef module,
BinaryenExpressionRef value);
BINARYEN_API BinaryenExpressionRef BinaryenMemorySize(BinaryenModuleRef module,
- const char* memoryName);
+ const char* memoryName,
+ bool memoryIs64);
BINARYEN_API BinaryenExpressionRef
BinaryenMemoryGrow(BinaryenModuleRef module,
BinaryenExpressionRef delta,
- const char* memoryName);
+ const char* memoryName,
+ bool memoryIs64);
BINARYEN_API BinaryenExpressionRef BinaryenNop(BinaryenModuleRef module);
BINARYEN_API BinaryenExpressionRef
BinaryenUnreachable(BinaryenModuleRef module);
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 53930e16c..c684553a5 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -687,11 +687,12 @@ function wrapModule(module, self = {}) {
}
self['memory'] = {
- 'size'(name) {
- return Module['_BinaryenMemorySize'](module, strToStack(name));
+ // memory64 defaults to undefined/false.
+ 'size'(name, memory64) {
+ return Module['_BinaryenMemorySize'](module, strToStack(name), memory64);
},
- 'grow'(value, name) {
- return Module['_BinaryenMemoryGrow'](module, value, strToStack(name));
+ 'grow'(value, name, memory64) {
+ return Module['_BinaryenMemoryGrow'](module, value, strToStack(name), memory64);
},
'init'(segment, dest, offset, size, name) {
return Module['_BinaryenMemoryInit'](module, segment, dest, offset, size, strToStack(name));
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 69e7a7c6a..cc3b99138 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -664,20 +664,32 @@ public:
ret->value = value;
return ret;
}
- MemorySize* makeMemorySize(Name memoryName) {
- auto memory = wasm.getMemory(memoryName);
+
+ // Some APIs can be told if the memory is 32 or 64-bit. If they are not
+ // informed of that, then the memory they refer to is looked up and that
+ // information fetched from there.
+ enum MemoryInfo { Memory32, Memory64, Unspecified };
+
+ bool isMemory64(Name memoryName, MemoryInfo info) {
+ return info == MemoryInfo::Memory64 || (info == MemoryInfo::Unspecified &&
+ wasm.getMemory(memoryName)->is64());
+ }
+
+ MemorySize* makeMemorySize(Name memoryName,
+ MemoryInfo info = MemoryInfo::Unspecified) {
auto* ret = wasm.allocator.alloc<MemorySize>();
- if (memory->is64()) {
+ if (isMemory64(memoryName, info)) {
ret->make64();
}
ret->memory = memoryName;
ret->finalize();
return ret;
}
- MemoryGrow* makeMemoryGrow(Expression* delta, Name memoryName) {
- auto memory = wasm.getMemory(memoryName);
+ MemoryGrow* makeMemoryGrow(Expression* delta,
+ Name memoryName,
+ MemoryInfo info = MemoryInfo::Unspecified) {
auto* ret = wasm.allocator.alloc<MemoryGrow>();
- if (memory->is64()) {
+ if (isMemory64(memoryName, info)) {
ret->make64();
}
ret->delta = delta;