summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcheck.py2
-rw-r--r--src/ir/memory-utils.h8
-rw-r--r--src/passes/I64ToI32Lowering.cpp9
-rw-r--r--src/passes/RemoveNonJSOps.cpp4
-rw-r--r--src/tools/fuzzing.h5
-rw-r--r--src/wasm/wasm-validator.cpp11
-rw-r--r--test/passes/code-pushing_ignore-implicit-traps.txt1
-rw-r--r--test/passes/code-pushing_ignore-implicit-traps.wast1
-rw-r--r--test/passes/flatten_rereloop.txt1
-rw-r--r--test/passes/flatten_rereloop.wast1
-rw-r--r--test/passes/flatten_simplify-locals-nonesting_dfo_O3.wast1
-rw-r--r--test/passes/licm.txt1
-rw-r--r--test/passes/licm.wast1
-rw-r--r--test/passes/optimize-added-constants-propagate_low-memory-unused.txt1
-rw-r--r--test/passes/optimize-added-constants-propagate_low-memory-unused.wast1
-rw-r--r--test/passes/optimize-added-constants_low-memory-unused.txt1
-rw-r--r--test/passes/optimize-added-constants_low-memory-unused.wast1
-rw-r--r--test/passes/pick-load-signs.txt1
-rw-r--r--test/passes/pick-load-signs.wast1
-rw-r--r--test/passes/remove-non-js-ops.txt1
-rw-r--r--test/passes/remove-non-js-ops.wast1
-rw-r--r--test/passes/safe-heap_disable-simd.txt1
-rw-r--r--test/passes/safe-heap_disable-simd.wast4
-rw-r--r--test/passes/simplify-locals-nostructure.txt1
-rw-r--r--test/passes/simplify-locals-nostructure.wast1
-rw-r--r--test/passes/vacuum.txt1
-rw-r--r--test/passes/vacuum.wast1
-rw-r--r--test/passes/vacuum_ignore-implicit-traps.txt1
-rw-r--r--test/passes/vacuum_ignore-implicit-traps.wast1
-rw-r--r--test/simd.wast1
-rw-r--r--test/simd.wast.from-wast1
-rw-r--r--test/simd.wast.fromBinary1
-rw-r--r--test/simd.wast.fromBinary.noDebugInfo1
-rw-r--r--test/spec/memory.wast195
-rw-r--r--test/unit/test_features.py1
-rw-r--r--test/wasm2js/unaligned.wast2
36 files changed, 105 insertions, 162 deletions
diff --git a/check.py b/check.py
index a7768ad6a..bf4279ba8 100755
--- a/check.py
+++ b/check.py
@@ -298,7 +298,7 @@ def run_spec_tests():
if len(requested) == 0:
# FIXME we support old and new memory formats, for now, until 0xc, and so can't pass this old-style test.
- BLACKLIST = ['memory.wast', 'binary.wast']
+ BLACKLIST = ['binary.wast']
# FIXME to update the spec to 0xd, we need to implement (register "name") for import.wast
spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'spec'))) if t not in BLACKLIST]
else:
diff --git a/src/ir/memory-utils.h b/src/ir/memory-utils.h
index 5980a3218..c8f39a2ec 100644
--- a/src/ir/memory-utils.h
+++ b/src/ir/memory-utils.h
@@ -48,6 +48,14 @@ namespace MemoryUtils {
memory.segments[0].data.swap(data);
return true;
}
+
+ // Ensures that the memory exists (of minimal size).
+ inline void ensureExists(Memory& memory) {
+ if (!memory.exists) {
+ memory.exists = true;
+ memory.initial = memory.max = 1;
+ }
+ }
};
} // namespace wasm
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index 4575dd2f8..ae69ec19d 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -27,6 +27,7 @@
#include "emscripten-optimizer/istring.h"
#include "support/name.h"
#include "wasm-builder.h"
+#include "ir/memory-utils.h"
#include "ir/module-utils.h"
#include "ir/names.h"
#include "asmjs/shared-constants.h"
@@ -608,6 +609,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
);
setOutParam(result, std::move(highBits));
replaceCurrent(result);
+ ensureMinimalMemory();
}
void lowerReinterpretInt64(Unary* curr) {
@@ -620,6 +622,13 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
builder->makeLoad(8, true, 0, 8, builder->makeConst(Literal(int32_t(0))), f64)
);
replaceCurrent(result);
+ ensureMinimalMemory();
+ }
+
+ // Ensure memory exists with a minimal size, enough for round-tripping operations on
+ // address 0, which we need for reinterpret operations.
+ void ensureMinimalMemory() {
+ MemoryUtils::ensureExists(getModule()->memory);
}
void lowerTruncFloatToInt(Unary *curr) {
diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp
index cc9a40a1f..342f59eba 100644
--- a/src/passes/RemoveNonJSOps.cpp
+++ b/src/passes/RemoveNonJSOps.cpp
@@ -33,6 +33,7 @@
#include "asmjs/shared-constants.h"
#include "wasm-builder.h"
#include "wasm-s-parser.h"
+#include "ir/memory-utils.h"
#include "ir/module-utils.h"
#include "ir/find_all.h"
#include "passes/intrinsics-module.h"
@@ -97,6 +98,9 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> {
}
neededFunctions.clear();
}
+
+ // Intrinsics may use memory, so ensure the module has one.
+ MemoryUtils::ensureExists(module->memory);
}
void addNeededFunctions(Module &m, Name name, std::set<Name> &needed) {
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 6aa0764f1..b17be8afe 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -29,6 +29,7 @@ high chance for set at start of loop
#include <ir/find_all.h>
#include <ir/literal-utils.h>
#include <ir/manipulation.h>
+#include "ir/memory-utils.h"
#include <ir/utils.h>
namespace wasm {
@@ -254,9 +255,7 @@ private:
}
void setupMemory() {
- wasm.memory.exists = true;
- // use one page
- wasm.memory.initial = wasm.memory.max = 1;
+ MemoryUtils::ensureExists(wasm.memory);
// init some data
wasm.memory.segments.emplace_back(builder.makeConst(Literal(int32_t(0))));
auto num = upTo(USABLE_MEMORY * 2);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 6d4490982..79c1d4f9b 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -512,6 +512,7 @@ void FunctionValidator::visitSetGlobal(SetGlobal* curr) {
}
void FunctionValidator::visitLoad(Load* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
if (curr->isAtomic) {
shouldBeTrue(info.features.hasAtomics(), curr, "Atomic operation (atomics are disabled)");
shouldBeTrue(curr->type == i32 || curr->type == i64 || curr->type == unreachable, curr, "Atomic load should be i32 or i64");
@@ -528,6 +529,7 @@ void FunctionValidator::visitLoad(Load* curr) {
}
void FunctionValidator::visitStore(Store* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
if (curr->isAtomic) {
shouldBeTrue(info.features.hasAtomics(), curr, "Atomic operation (atomics are disabled)");
shouldBeTrue(curr->valueType == i32 || curr->valueType == i64 || curr->valueType == unreachable, curr, "Atomic store should be i32 or i64");
@@ -545,6 +547,7 @@ void FunctionValidator::visitStore(Store* curr) {
}
void FunctionValidator::visitAtomicRMW(AtomicRMW* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasAtomics(), curr, "Atomic operation (atomics are disabled)");
shouldBeFalse(!getModule()->memory.shared, curr, "Atomic operation with non-shared memory");
validateMemBytes(curr->bytes, curr->type, curr);
@@ -554,6 +557,7 @@ void FunctionValidator::visitAtomicRMW(AtomicRMW* curr) {
}
void FunctionValidator::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasAtomics(), curr, "Atomic operation (atomics are disabled)");
shouldBeFalse(!getModule()->memory.shared, curr, "Atomic operation with non-shared memory");
validateMemBytes(curr->bytes, curr->type, curr);
@@ -567,6 +571,7 @@ void FunctionValidator::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
}
void FunctionValidator::visitAtomicWait(AtomicWait* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasAtomics(), curr, "Atomic operation (atomics are disabled)");
shouldBeFalse(!getModule()->memory.shared, curr, "Atomic operation with non-shared memory");
shouldBeEqualOrFirstIsUnreachable(curr->type, i32, curr, "AtomicWait must have type i32");
@@ -577,6 +582,7 @@ void FunctionValidator::visitAtomicWait(AtomicWait* curr) {
}
void FunctionValidator::visitAtomicNotify(AtomicNotify* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasAtomics(), curr, "Atomic operation (atomics are disabled)");
shouldBeFalse(!getModule()->memory.shared, curr, "Atomic operation with non-shared memory");
shouldBeEqualOrFirstIsUnreachable(curr->type, i32, curr, "AtomicNotify must have type i32");
@@ -647,6 +653,7 @@ void FunctionValidator::visitSIMDShift(SIMDShift* curr) {
}
void FunctionValidator::visitMemoryInit(MemoryInit* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasBulkMemory(), curr, "Bulk memory operation (bulk memory is disabled)");
shouldBeEqualOrFirstIsUnreachable(curr->type, none, curr, "memory.init must have type none");
shouldBeEqualOrFirstIsUnreachable(curr->dest->type, i32, curr, "memory.init dest must be an i32");
@@ -656,12 +663,14 @@ void FunctionValidator::visitMemoryInit(MemoryInit* curr) {
}
void FunctionValidator::visitDataDrop(DataDrop* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasBulkMemory(), curr, "Bulk memory operation (bulk memory is disabled)");
shouldBeEqualOrFirstIsUnreachable(curr->type, none, curr, "data.drop must have type none");
shouldBeTrue(curr->segment < getModule()->memory.segments.size(), curr, "data.drop segment index out of bounds");
}
void FunctionValidator::visitMemoryCopy(MemoryCopy* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasBulkMemory(), curr, "Bulk memory operation (bulk memory is disabled)");
shouldBeEqualOrFirstIsUnreachable(curr->type, none, curr, "memory.copy must have type none");
shouldBeEqualOrFirstIsUnreachable(curr->dest->type, i32, curr, "memory.copy dest must be an i32");
@@ -670,6 +679,7 @@ void FunctionValidator::visitMemoryCopy(MemoryCopy* curr) {
}
void FunctionValidator::visitMemoryFill(MemoryFill* curr) {
+ shouldBeTrue(getModule()->memory.exists, curr, "Memory operations require a memory");
shouldBeTrue(info.features.hasBulkMemory(), curr, "Bulk memory operation (bulk memory is disabled)");
shouldBeEqualOrFirstIsUnreachable(curr->type, none, curr, "memory.fill must have type none");
shouldBeEqualOrFirstIsUnreachable(curr->dest->type, i32, curr, "memory.fill dest must be an i32");
@@ -1289,6 +1299,7 @@ static void validateGlobals(Module& module, ValidationInfo& info) {
static void validateMemory(Module& module, ValidationInfo& info) {
auto& curr = module.memory;
info.shouldBeFalse(curr.initial > curr.max, "memory", "memory max >= initial");
+ info.shouldBeTrue(curr.initial <= Memory::kMaxSize, "memory", "initial memory must be <= 4GB");
info.shouldBeTrue(!curr.hasMax() || curr.max <= Memory::kMaxSize, "memory", "max memory must be <= 4GB, or unlimited");
info.shouldBeTrue(!curr.shared || curr.hasMax(), "memory", "shared memory must have max size");
if (curr.shared) info.shouldBeTrue(info.features.hasAtomics(), "memory", "memory is shared, but atomics are disabled");
diff --git a/test/passes/code-pushing_ignore-implicit-traps.txt b/test/passes/code-pushing_ignore-implicit-traps.txt
index 95b6edb52..f21915829 100644
--- a/test/passes/code-pushing_ignore-implicit-traps.txt
+++ b/test/passes/code-pushing_ignore-implicit-traps.txt
@@ -1,6 +1,7 @@
(module
(type $0 (func))
(type $1 (func (result i32)))
+ (memory $0 1)
(func $push1 (; 0 ;) (type $0)
(local $x i32)
(block $out
diff --git a/test/passes/code-pushing_ignore-implicit-traps.wast b/test/passes/code-pushing_ignore-implicit-traps.wast
index a091608c1..3f70c24a6 100644
--- a/test/passes/code-pushing_ignore-implicit-traps.wast
+++ b/test/passes/code-pushing_ignore-implicit-traps.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(func $push1
(local $x i32)
(block $out
diff --git a/test/passes/flatten_rereloop.txt b/test/passes/flatten_rereloop.txt
index c60bbf006..162336420 100644
--- a/test/passes/flatten_rereloop.txt
+++ b/test/passes/flatten_rereloop.txt
@@ -5,6 +5,7 @@
(type $3 (func (param i32)))
(type $4 (func (param i32) (result f32)))
(type $5 (func (result f32)))
+ (memory $0 1)
(global $global (mut i32) (i32.const 0))
(func $0 (; 0 ;) (type $0) (result f64)
(local $0 f64)
diff --git a/test/passes/flatten_rereloop.wast b/test/passes/flatten_rereloop.wast
index e8259885e..5ff0e9960 100644
--- a/test/passes/flatten_rereloop.wast
+++ b/test/passes/flatten_rereloop.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(global $global (mut i32) (i32.const 0))
(func $0 (result f64)
(if
diff --git a/test/passes/flatten_simplify-locals-nonesting_dfo_O3.wast b/test/passes/flatten_simplify-locals-nonesting_dfo_O3.wast
index b301608ca..0de6200c7 100644
--- a/test/passes/flatten_simplify-locals-nonesting_dfo_O3.wast
+++ b/test/passes/flatten_simplify-locals-nonesting_dfo_O3.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(func "if-select"
(local $var$0 i32)
(nop)
diff --git a/test/passes/licm.txt b/test/passes/licm.txt
index 032b88462..2db8aac32 100644
--- a/test/passes/licm.txt
+++ b/test/passes/licm.txt
@@ -4,6 +4,7 @@
(type $2 (func (result i64)))
(type $3 (func (param i32)))
(type $4 (func (param i32) (result i32)))
+ (memory $0 1)
(global $glob (mut i32) (i32.const 1))
(func $loop1 (; 0 ;) (type $0)
(drop
diff --git a/test/passes/licm.wast b/test/passes/licm.wast
index ad88c3e92..14d97afd9 100644
--- a/test/passes/licm.wast
+++ b/test/passes/licm.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(global $glob (mut i32) (i32.const 1))
(func $loop1
(loop $loop
diff --git a/test/passes/optimize-added-constants-propagate_low-memory-unused.txt b/test/passes/optimize-added-constants-propagate_low-memory-unused.txt
index 3e2ec5b9d..3d6a644e9 100644
--- a/test/passes/optimize-added-constants-propagate_low-memory-unused.txt
+++ b/test/passes/optimize-added-constants-propagate_low-memory-unused.txt
@@ -2,6 +2,7 @@
(type $0 (func))
(type $1 (func (param i32)))
(type $2 (func (param i32) (result i32)))
+ (memory $0 1 1)
(func $consts (; 0 ;) (type $0)
(drop
(i32.load
diff --git a/test/passes/optimize-added-constants-propagate_low-memory-unused.wast b/test/passes/optimize-added-constants-propagate_low-memory-unused.wast
index 0582294c8..d62d487d2 100644
--- a/test/passes/optimize-added-constants-propagate_low-memory-unused.wast
+++ b/test/passes/optimize-added-constants-propagate_low-memory-unused.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1 1)
(func $consts
(drop
(i32.load (i32.const 0))
diff --git a/test/passes/optimize-added-constants_low-memory-unused.txt b/test/passes/optimize-added-constants_low-memory-unused.txt
index 81f2ba216..174897946 100644
--- a/test/passes/optimize-added-constants_low-memory-unused.txt
+++ b/test/passes/optimize-added-constants_low-memory-unused.txt
@@ -2,6 +2,7 @@
(type $0 (func))
(type $1 (func (param i32)))
(type $2 (func (param i32) (result i32)))
+ (memory $0 1 1)
(func $consts (; 0 ;) (type $0)
(drop
(i32.load
diff --git a/test/passes/optimize-added-constants_low-memory-unused.wast b/test/passes/optimize-added-constants_low-memory-unused.wast
index b31f80a25..ac7d77fc4 100644
--- a/test/passes/optimize-added-constants_low-memory-unused.wast
+++ b/test/passes/optimize-added-constants_low-memory-unused.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1 1)
(func $consts
(drop
(i32.load (i32.const 0))
diff --git a/test/passes/pick-load-signs.txt b/test/passes/pick-load-signs.txt
index d719f11a9..126343b79 100644
--- a/test/passes/pick-load-signs.txt
+++ b/test/passes/pick-load-signs.txt
@@ -1,6 +1,7 @@
(module
(type $0 (func))
(type $1 (func (result i32)))
+ (memory $0 1)
(func $a (; 0 ;) (type $0)
(local $y i32)
(local.set $y
diff --git a/test/passes/pick-load-signs.wast b/test/passes/pick-load-signs.wast
index 975d1ac75..3b12c02bf 100644
--- a/test/passes/pick-load-signs.wast
+++ b/test/passes/pick-load-signs.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(func $a ;; load 8s, but use is 8u, so load should be signed
(local $y i32)
(local.set $y
diff --git a/test/passes/remove-non-js-ops.txt b/test/passes/remove-non-js-ops.txt
index cedb062cf..59977b859 100644
--- a/test/passes/remove-non-js-ops.txt
+++ b/test/passes/remove-non-js-ops.txt
@@ -6,6 +6,7 @@
(type $4 (func (param f64) (result f64)))
(type $5 (func (param f32) (result f32)))
(type $6 (func (param i32) (result i32)))
+ (memory $0 1)
(func $copysign64 (; 0 ;) (type $0) (param $0 f64) (param $1 f64) (result f64)
(f64.reinterpret_i64
(i64.or
diff --git a/test/passes/remove-non-js-ops.wast b/test/passes/remove-non-js-ops.wast
index de74fe1f4..ef3229e5a 100644
--- a/test/passes/remove-non-js-ops.wast
+++ b/test/passes/remove-non-js-ops.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(func $copysign64 (param $0 f64) (param $1 f64) (result f64)
(f64.copysign (local.get $0) (local.get $1)))
(func $copysign32 (param $0 f32) (param $1 f32) (result f32)
diff --git a/test/passes/safe-heap_disable-simd.txt b/test/passes/safe-heap_disable-simd.txt
index ab7338ea6..d2a109c0d 100644
--- a/test/passes/safe-heap_disable-simd.txt
+++ b/test/passes/safe-heap_disable-simd.txt
@@ -3,6 +3,7 @@
(import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32))
(import "env" "segfault" (func $segfault))
(import "env" "alignfault" (func $alignfault))
+ (memory $0 1 1)
(func $SAFE_HEAP_LOAD_i32_1_1 (; 2 ;) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local.set $2
diff --git a/test/passes/safe-heap_disable-simd.wast b/test/passes/safe-heap_disable-simd.wast
index 3af8f2545..13f77a0bc 100644
--- a/test/passes/safe-heap_disable-simd.wast
+++ b/test/passes/safe-heap_disable-simd.wast
@@ -1 +1,3 @@
-(module)
+(module
+ (memory 1 1)
+)
diff --git a/test/passes/simplify-locals-nostructure.txt b/test/passes/simplify-locals-nostructure.txt
index 42ee14a0f..10f1544e1 100644
--- a/test/passes/simplify-locals-nostructure.txt
+++ b/test/passes/simplify-locals-nostructure.txt
@@ -2,6 +2,7 @@
(type $0 (func))
(type $1 (func (param i32 i32) (result f64)))
(type $2 (func (param i32) (result i32)))
+ (memory $0 1)
(func $contrast (; 0 ;) (type $0)
(local $x i32)
(local $y i32)
diff --git a/test/passes/simplify-locals-nostructure.wast b/test/passes/simplify-locals-nostructure.wast
index 9c04b753a..4dc6cfb82 100644
--- a/test/passes/simplify-locals-nostructure.wast
+++ b/test/passes/simplify-locals-nostructure.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(func $contrast ;; check for tee and structure sinking
(local $x i32)
(local $y i32)
diff --git a/test/passes/vacuum.txt b/test/passes/vacuum.txt
index 9f106cd89..638aa3bed 100644
--- a/test/passes/vacuum.txt
+++ b/test/passes/vacuum.txt
@@ -329,6 +329,7 @@
(module
(type $0 (func (param i32) (result i32)))
(type $1 (func (param i32 i32 i32)))
+ (memory $0 1 1)
(global $global$1 (mut i32) (i32.const 0))
(export "compress" (func $3))
(func $_deflate (; 0 ;) (type $0) (param $0 i32) (result i32)
diff --git a/test/passes/vacuum.wast b/test/passes/vacuum.wast
index 0e15c76ad..0408277d7 100644
--- a/test/passes/vacuum.wast
+++ b/test/passes/vacuum.wast
@@ -686,6 +686,7 @@
)
)
(module ;; vacuum away a drop on an if where both arms can be vacuumed
+ (memory 1 1)
(global $global$1 (mut i32) (i32.const 0))
(func $_deflate (param i32) (result i32)
(call $_deflate (local.get $0))
diff --git a/test/passes/vacuum_ignore-implicit-traps.txt b/test/passes/vacuum_ignore-implicit-traps.txt
index 46db916c8..5df38be47 100644
--- a/test/passes/vacuum_ignore-implicit-traps.txt
+++ b/test/passes/vacuum_ignore-implicit-traps.txt
@@ -1,6 +1,7 @@
(module
(type $0 (func (result i32)))
(type $1 (func))
+ (memory $0 1)
(func $load-would-normally-have-side-effects (; 0 ;) (type $0) (result i32)
(i64.ge_s
(i64.const 2912825531628789796)
diff --git a/test/passes/vacuum_ignore-implicit-traps.wast b/test/passes/vacuum_ignore-implicit-traps.wast
index 83ec69c9e..ab958cec7 100644
--- a/test/passes/vacuum_ignore-implicit-traps.wast
+++ b/test/passes/vacuum_ignore-implicit-traps.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1)
(func $load-would-normally-have-side-effects (result i32)
(i64.ge_s
(block (result i64)
diff --git a/test/simd.wast b/test/simd.wast
index 11f0c19a6..572efa0f5 100644
--- a/test/simd.wast
+++ b/test/simd.wast
@@ -1,4 +1,5 @@
(module
+ (memory 1 1)
(func $v128.load (param $0 i32) (result v128)
(v128.load offset=0 align=16
(local.get $0)
diff --git a/test/simd.wast.from-wast b/test/simd.wast.from-wast
index fe1fd241d..55e97a6f1 100644
--- a/test/simd.wast.from-wast
+++ b/test/simd.wast.from-wast
@@ -15,6 +15,7 @@
(type $13 (func (param v128 f64) (result v128)))
(type $14 (func (param v128) (result v128)))
(type $15 (func (param v128 v128 v128) (result v128)))
+ (memory $0 1 1)
(func $v128.load (; 0 ;) (type $0) (param $0 i32) (result v128)
(v128.load
(local.get $0)
diff --git a/test/simd.wast.fromBinary b/test/simd.wast.fromBinary
index f3ea3ca91..9d06742dd 100644
--- a/test/simd.wast.fromBinary
+++ b/test/simd.wast.fromBinary
@@ -15,6 +15,7 @@
(type $13 (func (param v128 f64) (result v128)))
(type $14 (func (param v128) (result v128)))
(type $15 (func (param v128 v128 v128) (result v128)))
+ (memory $0 1 1)
(func $v128.load (; 0 ;) (type $0) (param $0 i32) (result v128)
(v128.load
(local.get $0)
diff --git a/test/simd.wast.fromBinary.noDebugInfo b/test/simd.wast.fromBinary.noDebugInfo
index 75ff49595..9b8cbeef0 100644
--- a/test/simd.wast.fromBinary.noDebugInfo
+++ b/test/simd.wast.fromBinary.noDebugInfo
@@ -15,6 +15,7 @@
(type $13 (func (param v128 f64) (result v128)))
(type $14 (func (param v128) (result v128)))
(type $15 (func (param v128 v128 v128) (result v128)))
+ (memory $0 1 1)
(func $0 (; 0 ;) (type $0) (param $0 i32) (result v128)
(v128.load
(local.get $0)
diff --git a/test/spec/memory.wast b/test/spec/memory.wast
index bb0226ed2..5f926339b 100644
--- a/test/spec/memory.wast
+++ b/test/spec/memory.wast
@@ -1,66 +1,39 @@
;; Test memory section structure
+
(module (memory 0 0))
(module (memory 0 1))
(module (memory 1 256))
(module (memory 0 65536))
-(module (memory 0 0) (data (i32.const 0)))
-(module (memory 0 0) (data (i32.const 0) ""))
-(module (memory 1 1) (data (i32.const 0) "a"))
-(module (memory 1 2) (data (i32.const 0) "a") (data (i32.const 65535) "b"))
-(module (memory 1 2)
- (data (i32.const 0) "a") (data (i32.const 1) "b") (data (i32.const 2) "c")
-)
-
-(module (memory (data)) (func (export "memsize") (result i32) (current_memory)))
-(assert_return (invoke "memsize") (i32.const 0))
-(module (memory (data "")) (func (export "memsize") (result i32) (current_memory)))
-(assert_return (invoke "memsize") (i32.const 0))
-(module (memory (data "x")) (func (export "memsize") (result i32) (current_memory)))
-(assert_return (invoke "memsize") (i32.const 1))
(assert_invalid (module (data (i32.const 0))) "unknown memory")
(assert_invalid (module (data (i32.const 0) "")) "unknown memory")
(assert_invalid (module (data (i32.const 0) "x")) "unknown memory")
(assert_invalid
- (module (memory 1) (data (i64.const 0)))
- "type mismatch"
-)
-(assert_invalid
- (module (memory 1) (data (i32.ctz (i32.const 0))))
- "constant expression required"
+ (module (func (drop (f32.load (i32.const 0)))))
+ "unknown memory"
)
(assert_invalid
- (module (memory 1) (data (nop)))
- "constant expression required"
+ (module (func (f32.store (f32.const 0) (i32.const 0))))
+ "unknown memory"
)
-
(assert_invalid
- (module (memory 1 0))
- "memory size minimum must not be greater than maximum"
+ (module (func (drop (i32.load8_s (i32.const 0)))))
+ "unknown memory"
)
(assert_invalid
- (module (memory 0 0) (data (i32.const 0) "a"))
- "data segment does not fit"
+ (module (func (i32.store8 (i32.const 0) (i32.const 0))))
+ "unknown memory"
)
(assert_invalid
- (module (memory 1 2) (data (i32.const 0) "a") (data (i32.const 98304) "b"))
- "data segment does not fit"
-)
-(assert_invalid
- (module (memory 1 2) (data (i32.const 0) "abc") (data (i32.const 0) "def"))
- "data segment not disjoint and ordered"
-)
-(assert_invalid
- (module (memory 1 2) (data (i32.const 3) "ab") (data (i32.const 0) "de"))
- "data segment not disjoint and ordered"
+ (module (func (drop (memory.grow (i32.const 0)))))
+ "unknown memory"
)
+
+
(assert_invalid
- (module
- (memory 1 2)
- (data (i32.const 0) "a") (data (i32.const 2) "b") (data (i32.const 1) "c")
- )
- "data segment not disjoint and ordered"
+ (module (memory 1 0))
+ "size minimum must not be greater than maximum"
)
(assert_invalid
(module (memory 65537))
@@ -87,70 +60,6 @@
"memory size must be at most 65536 pages (4GiB)"
)
-;; Test alignment annotation rules
-(module (memory 0) (func (drop (i32.load8_u align=1 (i32.const 0)))))
-(module (memory 0) (func (drop (i32.load16_u align=2 (i32.const 0)))))
-(module (memory 0) (func (drop (i32.load align=4 (i32.const 0)))))
-(module (memory 0) (func (drop (f32.load align=4 (i32.const 0)))))
-
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=0 (i32.const 0)))))
- "alignment must be a power of two"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=3 (i32.const 0)))))
- "alignment must be a power of two"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=5 (i32.const 0)))))
- "alignment must be a power of two"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=6 (i32.const 0)))))
- "alignment must be a power of two"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=7 (i32.const 0)))))
- "alignment must be a power of two"
-)
-
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=16 (i32.const 0)))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i64.load align=32 (i32.const 0)))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i32.load align=8 (i32.const 0)))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i32.load16_u align=4 (i32.const 0)))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (drop (i32.load8_u align=2 (i32.const 0)))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (i32.store8 align=2 (i32.const 0) (i32.const 0))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (i32.load16_u align=4 (i32.const 0))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (i32.load8_u align=2 (i32.const 0))))
- "alignment must not be larger than natural"
-)
-(assert_invalid
- (module (memory 0) (func (i32.store8 align=2 (i32.const 0) (i32.const 0))))
- "alignment must not be larger than natural"
-)
-
(module
(memory 1)
(data (i32.const 0) "ABC\a7D") (data (i32.const 20) "WASM")
@@ -181,54 +90,6 @@
)
)
- ;; Aligned read/write
- (func (export "aligned") (result i32)
- (local i32 i32 i32)
- (local.set 0 (i32.const 10))
- (block
- (loop
- (if
- (i32.eq (local.get 0) (i32.const 0))
- (br 2)
- )
- (local.set 2 (i32.mul (local.get 0) (i32.const 4)))
- (i32.store (local.get 2) (local.get 0))
- (local.set 1 (i32.load (local.get 2)))
- (if
- (i32.ne (local.get 0) (local.get 1))
- (return (i32.const 0))
- )
- (local.set 0 (i32.sub (local.get 0) (i32.const 1)))
- (br 0)
- )
- )
- (i32.const 1)
- )
-
- ;; Unaligned read/write
- (func (export "unaligned") (result i32)
- (local i32 f64 f64)
- (local.set 0 (i32.const 10))
- (block
- (loop
- (if
- (i32.eq (local.get 0) (i32.const 0))
- (br 2)
- )
- (local.set 2 (f64.convert_i32_s (local.get 0)))
- (f64.store align=1 (local.get 0) (local.get 2))
- (local.set 1 (f64.load align=1 (local.get 0)))
- (if
- (f64.ne (local.get 2) (local.get 1))
- (return (i32.const 0))
- )
- (local.set 0 (i32.sub (local.get 0) (i32.const 1)))
- (br 0)
- )
- )
- (i32.const 1)
- )
-
;; Memory cast
(func (export "cast") (result f64)
(i64.store (i32.const 8) (i64.const -12345))
@@ -237,7 +98,7 @@
(f64.load (i32.const 8))
(f64.reinterpret_i64 (i64.const -12345))
)
- (return (f64.const 0))
+ (then (return (f64.const 0)))
)
(i64.store align=1 (i32.const 9) (i64.const 0))
(i32.store16 align=1 (i32.const 15) (i32.const 16453))
@@ -288,8 +149,6 @@
)
(assert_return (invoke "data") (i32.const 1))
-(assert_return (invoke "aligned") (i32.const 1))
-(assert_return (invoke "unaligned") (i32.const 1))
(assert_return (invoke "cast") (f64.const 42.0))
(assert_return (invoke "i32_load8_s" (i32.const -1)) (i32.const -1))
@@ -302,6 +161,15 @@
(assert_return (invoke "i32_load16_s" (i32.const 20000)) (i32.const 20000))
(assert_return (invoke "i32_load16_u" (i32.const 40000)) (i32.const 40000))
+(assert_return (invoke "i32_load8_s" (i32.const 0xfedc6543)) (i32.const 0x43))
+(assert_return (invoke "i32_load8_s" (i32.const 0x3456cdef)) (i32.const 0xffffffef))
+(assert_return (invoke "i32_load8_u" (i32.const 0xfedc6543)) (i32.const 0x43))
+(assert_return (invoke "i32_load8_u" (i32.const 0x3456cdef)) (i32.const 0xef))
+(assert_return (invoke "i32_load16_s" (i32.const 0xfedc6543)) (i32.const 0x6543))
+(assert_return (invoke "i32_load16_s" (i32.const 0x3456cdef)) (i32.const 0xffffcdef))
+(assert_return (invoke "i32_load16_u" (i32.const 0xfedc6543)) (i32.const 0x6543))
+(assert_return (invoke "i32_load16_u" (i32.const 0x3456cdef)) (i32.const 0xcdef))
+
(assert_return (invoke "i64_load8_s" (i64.const -1)) (i64.const -1))
(assert_return (invoke "i64_load8_u" (i64.const -1)) (i64.const 255))
(assert_return (invoke "i64_load16_s" (i64.const -1)) (i64.const -1))
@@ -315,3 +183,16 @@
(assert_return (invoke "i64_load16_u" (i64.const 40000)) (i64.const 40000))
(assert_return (invoke "i64_load32_s" (i64.const 20000)) (i64.const 20000))
(assert_return (invoke "i64_load32_u" (i64.const 40000)) (i64.const 40000))
+
+(assert_return (invoke "i64_load8_s" (i64.const 0xfedcba9856346543)) (i64.const 0x43))
+(assert_return (invoke "i64_load8_s" (i64.const 0x3456436598bacdef)) (i64.const 0xffffffffffffffef))
+(assert_return (invoke "i64_load8_u" (i64.const 0xfedcba9856346543)) (i64.const 0x43))
+(assert_return (invoke "i64_load8_u" (i64.const 0x3456436598bacdef)) (i64.const 0xef))
+(assert_return (invoke "i64_load16_s" (i64.const 0xfedcba9856346543)) (i64.const 0x6543))
+(assert_return (invoke "i64_load16_s" (i64.const 0x3456436598bacdef)) (i64.const 0xffffffffffffcdef))
+(assert_return (invoke "i64_load16_u" (i64.const 0xfedcba9856346543)) (i64.const 0x6543))
+(assert_return (invoke "i64_load16_u" (i64.const 0x3456436598bacdef)) (i64.const 0xcdef))
+(assert_return (invoke "i64_load32_s" (i64.const 0xfedcba9856346543)) (i64.const 0x56346543))
+(assert_return (invoke "i64_load32_s" (i64.const 0x3456436598bacdef)) (i64.const 0xffffffff98bacdef))
+(assert_return (invoke "i64_load32_u" (i64.const 0xfedcba9856346543)) (i64.const 0x56346543))
+(assert_return (invoke "i64_load32_u" (i64.const 0x3456436598bacdef)) (i64.const 0x98bacdef))
diff --git a/test/unit/test_features.py b/test/unit/test_features.py
index 9f9f618b0..f939025e0 100644
--- a/test/unit/test_features.py
+++ b/test/unit/test_features.py
@@ -60,6 +60,7 @@ class FeatureValidationTest(unittest.TestCase):
def test_simd_load(self):
module = """
(module
+ (memory 1 1)
(func $foo
(drop (v128.load (i32.const 0)))
)
diff --git a/test/wasm2js/unaligned.wast b/test/wasm2js/unaligned.wast
index 600d22459..c55870603 100644
--- a/test/wasm2js/unaligned.wast
+++ b/test/wasm2js/unaligned.wast
@@ -1,4 +1,6 @@
(module
+ (memory 1 1)
+
(func (export "i32.load") (result i32)
(i32.load align=1 (i32.const 0)))
(func (export "i64.load") (result i64)