diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 30c3593d6d2..893d597c712 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -444,7 +444,6 @@ def get_tests(test_dir, extensions=[], recursive=False): 'proposals/threads/imports.wast', # Missing memory type validation on instantiation 'linking.wast', # Missing function type validation on instantiation 'proposals/threads/memory.wast', # Missing memory type validation on instantiation - 'memory64-imports.wast', # Missing validation on instantiation 'annotations.wast', # String annotations IDs should be allowed 'id.wast', # Empty IDs should be disallowed # Requires correct handling of tag imports from different instances of the same module, @@ -473,12 +472,8 @@ def get_tests(test_dir, extensions=[], recursive=False): 'type-rec.wast', # Missing function type validation on instantiation 'type-subtyping.wast', # ShellExternalInterface::callTable does not handle subtyping 'call_indirect.wast', # Bug with 64-bit inline element segment parsing - 'memory64.wast', # Requires validations for memory size - 'imports0.wast', # Missing memory type validation on instantiation - 'imports2.wast', # Missing memory type validation on instantiation - 'imports3.wast', # Missing memory type validation on instantiation - 'linking0.wast', # Missing memory type validation on instantiation - 'linking3.wast', # Fatal error on missing table. + # 'memory64.wast', # Requires wast `module definition` support + # 'linking0.wast', # Missing memory type validation on instantiation 'i16x8_relaxed_q15mulr_s.wast', # Requires wast `either` support 'i32x4_relaxed_trunc.wast', # Requires wast `either` support 'i8x16_relaxed_swizzle.wast', # Requires wast `either` support diff --git a/src/parser/context-decls.cpp b/src/parser/context-decls.cpp index f02ec30dd66..9854c703e5d 100644 --- a/src/parser/context-decls.cpp +++ b/src/parser/context-decls.cpp @@ -152,6 +152,7 @@ Result ParseDeclsCtx::addMemoryDecl(Index pos, } m->setExplicitName(name); } else { + // ??? name = (importNames ? "mimport$" : "") + std::to_string(memoryCounter++); name = Names::getValidMemoryName(wasm, name); m->name = name; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 39573372d78..6004342c878 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -3940,4 +3940,10 @@ std::ostream& operator<<(std::ostream& o, wasm::ModuleHeapType pair) { return o << "(unnamed)"; } +std::ostream& operator<<(std::ostream& o, const wasm::Memory& memory) { + wasm::PrintSExpression printer(o); + printer.visitMemory(const_cast(&memory)); + return o; +} + } // namespace std diff --git a/src/shell-interface.h b/src/shell-interface.h index 7a42617e711..9275b11b6c2 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -134,8 +134,9 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { auto inst = getImportInstance(import); auto* exportedGlobal = inst->wasm.getExportOrNull(import->base); if (!exportedGlobal || exportedGlobal->kind != ExternalKind::Global) { - Fatal() << "importGlobals: unknown import: " << import->module.str - << "." << import->name.str; + trap((std::stringstream() << "unknown import: " << import->module.str + << "." << import->name.str) + .str()); } globals[import->name] = inst->globals[*exportedGlobal->getInternalName()]; }); @@ -325,7 +326,9 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { return true; } - void trap(const char* why) override { + void trap(const char* why) override { trap(std::string_view(why)); } + + void trap(std::string_view why) override { std::cout << "[trap " << why << "]\n"; throw TrapException(); } diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index 1bb8ab48209..faa6b2a67ca 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp @@ -169,6 +169,8 @@ struct Shell { // SIMD instructions. instance->setRelaxedBehavior(ModuleRunner::RelaxedBehavior::Execute); instance->instantiate(); + } catch (const std::exception& e) { + return Err{std::string("failed to instantiate module: ") + e.what()}; } catch (...) { return Err{"failed to instantiate module"}; } diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index f6fc5586a94..ea66cda7667 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -29,6 +29,7 @@ #define wasm_wasm_interpreter_h #include +#include #include #include #include @@ -86,7 +87,7 @@ class Flow { } Literals values; - Name breakTo; // if non-null, a break is going on + Name breakTo; // if non-null, a break is going on Tag* suspendTag = nullptr; // if non-null, breakTo must be SUSPEND_FLOW, and // this is the tag being suspended @@ -2658,6 +2659,8 @@ class ExpressionRunner : public OverriddenVisitor { virtual void trap(const char* why) { WASM_UNREACHABLE("unimp"); } + virtual void trap(std::string_view why) { WASM_UNREACHABLE("unimp"); } + virtual void hostLimit(const char* why) { WASM_UNREACHABLE("unimp"); } virtual void throwException(const WasmException& exn) { @@ -2937,6 +2940,7 @@ class ModuleRunnerBase : public ExpressionRunner { Index oldSize, Index newSize) = 0; virtual void trap(const char* why) = 0; + virtual void trap(std::string_view why) { trap(std::string(why).c_str()); } virtual void hostLimit(const char* why) = 0; virtual void throwException(const WasmException& exn) = 0; // Get the Tag instance for a tag implemented in the host, that is, not @@ -3178,6 +3182,8 @@ class ModuleRunnerBase : public ExpressionRunner { // initialize the rest of the external interface externalInterface->init(wasm, *self()); + validateImports(); + initializeTableContents(); initializeMemoryContents(); @@ -3269,6 +3275,84 @@ class ModuleRunnerBase : public ExpressionRunner { Name name; }; + // Trap if types don't match between all imports and their corresponding + // exports. Imported memories and tables must also be a subtype of their + // export. + void validateImports() { + ModuleUtils::iterImportable( + wasm, + [this](ExternalKind kind, + std::variant import) { + Importable* importable = std::visit( + [](const auto& import) -> Importable* { return import; }, import); + + { + auto it = linkedInstances.find(importable->module); + if (it == linkedInstances.end()) { + // todo + trap((std::stringstream() + << "Import module " + << std::quoted(importable->module.toString()) + << " doesn't exist.") + .str()); + } + SubType* importedInstance = it->second.get(); + + Export* export_ = + importedInstance->wasm.getExportOrNull(importable->base); + + // In case functions are imported from the special "spectest" module, + // don't check them here, since they won't show up in exports. + if (!export_ && kind != ExternalKind::Function) { + std::cerr << "importedinstance " << importedInstance + << ". Importable: " << importable->module << " " + << importable->base << "\n"; + trap((std::stringstream() + << "Export " << importable->base << " doesn't exist.") + .str()); + } + if (export_ && export_->kind != kind) { + std::cerr << "a\n"; + trap("Exported kind doesn't match"); + } + // export_ might still be null here but we are done + } + + if (auto** memory = std::get_if(&import)) { + SubType* importedInstance = + linkedInstances.at((*memory)->module).get(); + Export* export_ = + importedInstance->wasm.getExportOrNull((*memory)->base); + + Memory exportedMemory = + *importedInstance->wasm.getMemory(*export_->getInternalName()); + exportedMemory.initial = + importedInstance->getMemorySize(*export_->getInternalName()); + + if (!exportedMemory.isSubType(**memory)) { + std::cerr << "b\n"; + trap((std::stringstream() + << "Imported memory isn't compatible. Imported memory: " + << **memory << ". Exported memory: " << exportedMemory) + .str()); + } + } + + if (auto** table = std::get_if(&import)) { + SubType* importedInstance = + linkedInstances.at((*table)->module).get(); + Export* export_ = + importedInstance->wasm.getExportOrNull((*table)->base); + Table* exportedTable = + importedInstance->wasm.getTable(*export_->getInternalName()); + if (!(*table)->isSubType(*exportedTable)) { + std::cerr << "c\n"; + trap("Imported table isn't compatible"); + } + } + }); + } + TableInstanceInfo getTableInstanceInfo(Name name) { auto* table = wasm.getTable(name); if (table->imported()) { @@ -3325,6 +3409,24 @@ class ModuleRunnerBase : public ExpressionRunner { Name name; }; + // todo do we need this? + // MemoryInstanceInfo getMemoryInstanceInfo(Name name) { + // // auto* memory = wasm.getMemory(name); + // auto* instance = self(); + // Export* memoryExport = nullptr; + // for (auto* memory = instance->wasm.getMemory(name); memory->imported(); + // memory = instance->wasm.getMemory(*memoryExport->getInternalName())) { + // instance = instance->linkedInstances.at(memory->module).get(); + // memoryExport = instance->wasm.getExport(memory->base); + // } + + // if (memoryExport) { + // return instance->getMemoryInstanceInfo(*memoryExport->getInternalName()); + // } + + // return MemoryInstanceInfo{self(), name}; + // } + MemoryInstanceInfo getMemoryInstanceInfo(Name name) { auto* memory = wasm.getMemory(name); if (memory->imported()) { @@ -3385,6 +3487,11 @@ class ModuleRunnerBase : public ExpressionRunner { } Address getMemorySize(Name memory) { + auto info = getMemoryInstanceInfo(memory); + if (info.instance != self()) { + return info.instance->getMemorySize(info.name); + } + auto iter = memorySizes.find(memory); if (iter == memorySizes.end()) { externalInterface->trap("getMemorySize called on non-existing memory"); @@ -3397,7 +3504,7 @@ class ModuleRunnerBase : public ExpressionRunner { if (iter == memorySizes.end()) { externalInterface->trap("setMemorySize called on non-existing memory"); } - memorySizes[memory] = size; + iter->second = size; } public: @@ -4682,12 +4789,13 @@ class ModuleRunnerBase : public ExpressionRunner { } Flow visitStackSwitch(StackSwitch* curr) { return Flow(NONCONSTANT_FLOW); } - void trap(const char* why) override { - // Traps break all current continuations - they will never be resumable. + void trap(std::string_view why) override { self()->clearContinuationStore(); externalInterface->trap(why); } + void trap(const char* why) override { trap(std::string_view(why)); } + void hostLimit(const char* why) override { self()->clearContinuationStore(); externalInterface->hostLimit(why); diff --git a/src/wasm.h b/src/wasm.h index 605c7025395..5717184c036 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -2435,6 +2435,28 @@ class Table : public Importable { initial = 0; max = kMaxSize; } + + static bool isSubType(const Table& a, const Table& b) { + if (a.addressType != b.addressType) { + return false; + } + + if (!Type::isSubType(a.type, b.type)) { + return false; + } + + if (a.initial > b.initial) { + return false; + } + + if (a.max < b.max) { + return false; + } + + return true; + } + + bool isSubType(const Table& other) { return Table::isSubType(*this, other); } }; class DataSegment : public Named { @@ -2470,6 +2492,16 @@ class Memory : public Importable { shared = false; addressType = Type::i32; } + + static bool isSubType(const Memory& a, const Memory& b) { + // a.shared == b.shared ? + return a.addressType == b.addressType && a.initial >= b.initial && + a.max <= b.max; + } + + bool isSubType(const Memory& other) { + return Memory::isSubType(*this, other); + } }; class Global : public Importable { @@ -2661,6 +2693,7 @@ std::ostream& operator<<(std::ostream& o, wasm::ModuleExpression pair); std::ostream& operator<<(std::ostream& o, wasm::ShallowExpression expression); std::ostream& operator<<(std::ostream& o, wasm::ModuleType pair); std::ostream& operator<<(std::ostream& o, wasm::ModuleHeapType pair); +std::ostream& operator<<(std::ostream& o, const wasm::Memory& memory); } // namespace std diff --git a/test/spec/exact-func-import.wast b/test/spec/exact-func-import.wast index 49330fc7b84..bd152ef2a1e 100644 --- a/test/spec/exact-func-import.wast +++ b/test/spec/exact-func-import.wast @@ -1,29 +1,25 @@ -;; TODO: Use the upstream version from the custom descriptors proposal. - -(module +(module definition (type $f (func)) (import "" "" (func $1 (exact (type 0)))) - (import "" "" (func $2 (exact (type $f) (param) (result)))) - (import "" "" (func $3 (exact (type $f)))) - (import "" "" (func $4 (exact (type 1)))) ;; Implicitly defined next - (import "" "" (func $5 (exact (param i32) (result i64)))) + ;; (import "" "" (func $2 (exact (type $f) (param) (result)))) ;; TODO: parser support + (import "" "" (func $2 (exact (type $f)))) + (import "" "" (func $3 (exact (type 1)))) ;; Implicitly defined next + (import "" "" (func $4 (exact (param i32) (result i64)))) - (func $6 (import "" "") (exact (type 0))) - (func $7 (import "" "") (exact (type $f) (param) (result))) - (func $8 (import "" "") (exact (type $f))) - (func $9 (import "" "") (exact (type 2))) ;; Implicitly defined next - (func $10 (import "" "") (exact (param i64) (result i32))) + (func $5 (import "" "") (exact (type 0))) + ;; (func $6 (import "" "") (exact (type $f) (param) (result))) ;; TODO: parser support + (func $6 (import "" "") (exact (type $f))) + ;; (func $7 (import "" "") (exact (type 2))) ;; Implicitly defined next + ;; (func $8 (import "" "") (exact (param i64) (result i32))) ;; TODO: parser support (global (ref (exact $f)) (ref.func $1)) (global (ref (exact $f)) (ref.func $2)) - (global (ref (exact $f)) (ref.func $3)) + (global (ref (exact 1)) (ref.func $3)) (global (ref (exact 1)) (ref.func $4)) - (global (ref (exact 1)) (ref.func $5)) + (global (ref (exact $f)) (ref.func $5)) (global (ref (exact $f)) (ref.func $6)) - (global (ref (exact $f)) (ref.func $7)) - (global (ref (exact $f)) (ref.func $8)) - (global (ref (exact 2)) (ref.func $9)) - (global (ref (exact 2)) (ref.func $10)) + ;; (global (ref (exact 2)) (ref.func $7)) + ;; (global (ref (exact 2)) (ref.func $8)) ) ;; References to inexact imports are not exact. @@ -51,7 +47,7 @@ ;; Inexact imports can still be referenced inexactly, though. -(module +(module definition (type $f (func)) (import "" "" (func $1 (type $f))) (global (ref $f) (ref.func $1)) @@ -70,7 +66,9 @@ ;; Import and re-export inexactly. (module $B (type $f (func)) - (func (export "f") (import "A" "f") (type $f)) + ;; (func (import "A" "f") (export "f") (type $f)) + (func (import "A" "f") (type $f)) + (export "f" (func 0)) ) (register "B") @@ -220,7 +218,7 @@ ;; Test the binary format ;; Exact function imports use 0x20. -(module binary +(module definition binary "\00asm" "\01\00\00\00" "\01" ;; Type section id "\04" ;; Type section length @@ -265,4 +263,4 @@ "\0b" ;; End ) "malformed export kind" -) +) \ No newline at end of file diff --git a/test/spec/imports.wast b/test/spec/imports.wast index 1e4b661665f..2885458a6ff 100644 --- a/test/spec/imports.wast +++ b/test/spec/imports.wast @@ -1,572 +1,572 @@ -;; Auxiliary module to import from - -(module - (func (export "func")) - (func (export "func-i32") (param i32)) - (func (export "func-f32") (param f32)) - (func (export "func->i32") (result i32) (i32.const 22)) - (func (export "func->f32") (result f32) (f32.const 11)) - (func (export "func-i32->i32") (param i32) (result i32) (local.get 0)) - (func (export "func-i64->i64") (param i64) (result i64) (local.get 0)) - (global (export "global-i32") i32 (i32.const 55)) - (global (export "global-f32") f32 (f32.const 44)) - ;;; FIXME: Exporting a mutable global is currently not supported. Make mutable - ;;; when support is added. - (global (export "global-mut-i64") i64 (i64.const 66)) - (table (export "table-10-inf") 10 funcref) - (table (export "table-10-20") 10 20 funcref) - (memory (export "memory-2-inf") 2) - ;; Multiple memories are not yet supported - ;; (memory (export "memory-2-4") 2 4) -) - -(register "test") - - -;; Functions - -(module - (type $func_i32 (func (param i32))) - (type $func_i64 (func (param i64))) - (type $func_f32 (func (param f32))) - (type $func_f64 (func (param f64))) - - (import "spectest" "print_i32" (func (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (func (import "spectest" "print_i64") (param i64)) - (import "spectest" "print_i32" (func $print_i32 (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "print_i64" (func $print_i64 (param i64))) - (import "spectest" "print_f32" (func $print_f32 (param f32))) - (import "spectest" "print_f64" (func $print_f64 (param f64))) - (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) - (import "spectest" "print_f64_f64" (func $print_f64_f64 (param f64 f64))) - (func $print_i32-2 (import "spectest" "print_i32") (param i32)) - (func $print_f64-2 (import "spectest" "print_f64") (param f64)) - (import "test" "func-i64->i64" (func $i64->i64 (param i64) (result i64))) - - (func (export "p1") (import "spectest" "print_i32") (param i32)) - (func $p (export "p2") (import "spectest" "print_i32") (param i32)) - (func (import "spectest" "print_i32") (param i32)) - (func (export "p5") (import "spectest" "print_i32") (type 0)) - (func (export "p6") (import "spectest" "print_i32") (type 0) (param i32) (result)) - - ;; (export "p3" (func $print_i32)) - ;; (export "p4" (func $print_i32)) - - (import "spectest" "print_i32" (func (type $forward))) - (func (import "spectest" "print_i32") (type $forward)) - (type $forward (func (param i32))) - - (table funcref (elem $print_i32 $print_f64)) - - (func (export "print32") (param $i i32) - (local $x f32) - (local.set $x (f32.convert_i32_s (local.get $i))) - (call 0 (local.get $i)) - (call $print_i32_f32 - (i32.add (local.get $i) (i32.const 1)) - (f32.const 42) - ) - (call $print_i32 (local.get $i)) - (call $print_i32-2 (local.get $i)) - (call $print_f32 (local.get $x)) - (call_indirect (type $func_i32) (local.get $i) (i32.const 0)) - ) - - (func (export "print64") (param $i i64) - (local $x f64) - (local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i)))) - ;; JavaScript can't handle i64 yet. - ;; (call 1 (local.get $i)) - (call $print_f64_f64 - (f64.add (local.get $x) (f64.const 1)) - (f64.const 53) - ) - ;; JavaScript can't handle i64 yet. - ;; (call $print_i64 (local.get $i)) - (call $print_f64 (local.get $x)) - (call $print_f64-2 (local.get $x)) - (call_indirect (type $func_f64) (local.get $x) (i32.const 1)) - ) -) - -(assert_return (invoke "print32" (i32.const 13))) -(assert_return (invoke "print64" (i64.const 24))) - -(assert_invalid - (module - (type (func (result i32))) - (import "test" "func" (func (type 1))) - ) - "unknown type" -) - -;; Export sharing name with import -(module - (import "spectest" "print_i32" (func $imported_print (param i32))) - (func (export "print_i32") (param $i i32) - (call $imported_print (local.get $i)) - ) -) - -(assert_return (invoke "print_i32" (i32.const 13))) - -;; Export sharing name with import -(module - (import "spectest" "print_i32" (func $imported_print (param i32))) - (func (export "print_i32") (param $i i32) (param $j i32) (result i32) - (i32.add (local.get $i) (local.get $j)) - ) -) - -(assert_return (invoke "print_i32" (i32.const 5) (i32.const 11)) (i32.const 16)) - -(module (import "test" "func" (func))) -(module (import "test" "func-i32" (func (param i32)))) -(module (import "test" "func-f32" (func (param f32)))) -(module (import "test" "func->i32" (func (result i32)))) -(module (import "test" "func->f32" (func (result f32)))) -(module (import "test" "func-i32->i32" (func (param i32) (result i32)))) -(module (import "test" "func-i64->i64" (func (param i64) (result i64)))) - -;; (assert_unlinkable -;; (module (import "test" "unknown" (func))) -;; "unknown import" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "unknown" (func))) -;; "unknown import" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "func" (func (param i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func" (func (result i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func" (func (param i32) (result i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32" (func (result i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32" (func (param f32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32" (func (param i64)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32" (func (param i32) (result i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func->i32" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func->i32" (func (param i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func->i32" (func (result f32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func->i32" (func (result i64)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func->i32" (func (param i32) (result i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32->i32" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32->i32" (func (param i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "func-i32->i32" (func (result i32)))) -;; "incompatible import type" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "global-i32" (func (result i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "table-10-inf" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "memory-2-inf" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "global_i32" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "table" (func))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "memory" (func))) -;; "incompatible import type" -;; ) - - -;; Globals - -(module - (import "spectest" "global_i32" (global i32)) - (global (import "spectest" "global_i32") i32) - - (import "spectest" "global_i32" (global $x i32)) - (global $y (import "spectest" "global_i32") i32) - - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "global_i64" (global i64)) - (import "spectest" "global_f32" (global f32)) - (import "spectest" "global_f64" (global f64)) - - (func (export "get-0") (result i32) (global.get 0)) - (func (export "get-1") (result i32) (global.get 1)) - (func (export "get-x") (result i32) (global.get $x)) - (func (export "get-y") (result i32) (global.get $y)) -) - -(assert_return (invoke "get-0") (i32.const 666)) -(assert_return (invoke "get-1") (i32.const 666)) -(assert_return (invoke "get-x") (i32.const 666)) -(assert_return (invoke "get-y") (i32.const 666)) - -(module (import "test" "global-i32" (global i32))) -(module (import "test" "global-f32" (global f32))) -(module (import "test" "global-mut-i64" (global (mut i64)))) - -;; (assert_unlinkable -;; (module (import "test" "unknown" (global i32))) -;; "unknown import" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "unknown" (global i32))) -;; "unknown import" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "global-i32" (global i64))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-i32" (global f32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-i32" (global f64))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-i32" (global (mut i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-f32" (global i32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-f32" (global i64))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-f32" (global f64))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-f32" (global (mut f32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-mut-i64" (global (mut i32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-mut-i64" (global (mut f32)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-mut-i64" (global (mut f64)))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-mut-i64" (global i64))) -;; "incompatible import type" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "func" (global i32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "table-10-inf" (global i32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "memory-2-inf" (global i32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "print_i32" (global i32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "table" (global i32))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "memory" (global i32))) -;; "incompatible import type" -;; ) - - -;; Tables - -(module - (type (func (result i32))) - (import "spectest" "table" (table $tab 10 20 funcref)) - (elem (table $tab) (i32.const 1) func $f $g) - - (func (export "call") (param i32) (result i32) - (call_indirect $tab (type 0) (local.get 0)) - ) - (func $f (result i32) (i32.const 11)) - (func $g (result i32) (i32.const 22)) -) - -(assert_trap (invoke "call" (i32.const 0)) "uninitialized element") -(assert_return (invoke "call" (i32.const 1)) (i32.const 11)) -(assert_return (invoke "call" (i32.const 2)) (i32.const 22)) -(assert_trap (invoke "call" (i32.const 3)) "uninitialized element") -(assert_trap (invoke "call" (i32.const 100)) "undefined element") - - -(module - (type (func (result i32))) - (table $tab (import "spectest" "table") 10 20 funcref) - (elem (table $tab) (i32.const 1) func $f $g) - - (func (export "call") (param i32) (result i32) - (call_indirect $tab (type 0) (local.get 0)) - ) - (func $f (result i32) (i32.const 11)) - (func $g (result i32) (i32.const 22)) -) - -(assert_trap (invoke "call" (i32.const 0)) "uninitialized element") -(assert_return (invoke "call" (i32.const 1)) (i32.const 11)) -(assert_return (invoke "call" (i32.const 2)) (i32.const 22)) -(assert_trap (invoke "call" (i32.const 3)) "uninitialized element") -(assert_trap (invoke "call" (i32.const 100)) "undefined element") - - -(module - (import "spectest" "table" (table 0 funcref)) - (import "spectest" "table" (table 0 funcref)) - (table 10 funcref) - (table 10 funcref) -) - -(module (import "test" "table-10-inf" (table 10 funcref))) -(module (import "test" "table-10-inf" (table 5 funcref))) -(module (import "test" "table-10-inf" (table 0 funcref))) -(module (import "test" "table-10-20" (table 10 funcref))) -(module (import "test" "table-10-20" (table 5 funcref))) -(module (import "test" "table-10-20" (table 0 funcref))) -(module (import "test" "table-10-20" (table 10 20 funcref))) -(module (import "test" "table-10-20" (table 5 20 funcref))) -(module (import "test" "table-10-20" (table 0 20 funcref))) -(module (import "test" "table-10-20" (table 10 25 funcref))) -(module (import "test" "table-10-20" (table 5 25 funcref))) -(module (import "test" "table-10-20" (table 0 25 funcref))) -(module (import "spectest" "table" (table 10 funcref))) -(module (import "spectest" "table" (table 5 funcref))) -(module (import "spectest" "table" (table 0 funcref))) -(module (import "spectest" "table" (table 10 20 funcref))) -(module (import "spectest" "table" (table 5 20 funcref))) -(module (import "spectest" "table" (table 0 20 funcref))) -(module (import "spectest" "table" (table 10 25 funcref))) -(module (import "spectest" "table" (table 5 25 funcref))) - -;; (assert_unlinkable -;; (module (import "test" "unknown" (table 10 funcref))) -;; "unknown import" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "unknown" (table 10 funcref))) -;; "unknown import" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "table-10-inf" (table 12 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "table-10-inf" (table 10 20 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "table-10-20" (table 12 20 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "table-10-20" (table 10 18 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "table" (table 12 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "table" (table 10 15 funcref))) -;; "incompatible import type" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "func" (table 10 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-i32" (table 10 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "memory-2-inf" (table 10 funcref))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "print_i32" (table 10 funcref))) -;; "incompatible import type" -;; ) - - -;; Memories - -(module - (import "spectest" "memory" (memory 1 2)) - (data (memory 0) (i32.const 10) "\10") - - (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) -) - -(assert_return (invoke "load" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "load" (i32.const 10)) (i32.const 16)) -(assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000)) -(assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access") - -(module - (memory (import "spectest" "memory") 1 2) - (data (memory 0) (i32.const 10) "\10") - - (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) -) -(assert_return (invoke "load" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "load" (i32.const 10)) (i32.const 16)) -(assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000)) -(assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access") - -(module (import "test" "memory-2-inf" (memory 2))) -(module (import "test" "memory-2-inf" (memory 1))) -(module (import "test" "memory-2-inf" (memory 0))) -(module (import "spectest" "memory" (memory 1))) -(module (import "spectest" "memory" (memory 0))) -(module (import "spectest" "memory" (memory 1 2))) -(module (import "spectest" "memory" (memory 0 2))) -(module (import "spectest" "memory" (memory 1 3))) -(module (import "spectest" "memory" (memory 0 3))) - -;; (assert_unlinkable -;; (module (import "test" "unknown" (memory 1))) -;; "unknown import" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "unknown" (memory 1))) -;; "unknown import" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "memory-2-inf" (memory 3))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "memory-2-inf" (memory 2 3))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "memory" (memory 2))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "memory" (memory 1 1))) -;; "incompatible import type" -;; ) - -;; (assert_unlinkable -;; (module (import "test" "func-i32" (memory 1))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "global-i32" (memory 1))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "test" "table-10-inf" (memory 1))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "print_i32" (memory 1))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "global_i32" (memory 1))) -;; "incompatible import type" -;; ) -;; (assert_unlinkable -;; (module (import "spectest" "table" (memory 1))) -;; "incompatible import type" +;; ;; Auxiliary module to import from +;; +;; (module +;; (func (export "func")) +;; (func (export "func-i32") (param i32)) +;; (func (export "func-f32") (param f32)) +;; (func (export "func->i32") (result i32) (i32.const 22)) +;; (func (export "func->f32") (result f32) (f32.const 11)) +;; (func (export "func-i32->i32") (param i32) (result i32) (local.get 0)) +;; (func (export "func-i64->i64") (param i64) (result i64) (local.get 0)) +;; (global (export "global-i32") i32 (i32.const 55)) +;; (global (export "global-f32") f32 (f32.const 44)) +;; ;;; FIXME: Exporting a mutable global is currently not supported. Make mutable +;; ;;; when support is added. +;; (global (export "global-mut-i64") i64 (i64.const 66)) +;; (table (export "table-10-inf") 10 funcref) +;; (table (export "table-10-20") 10 20 funcref) +;; (memory (export "memory-2-inf") 2) +;; ;; Multiple memories are not yet supported +;; ;; (memory (export "memory-2-4") 2 4) +;; ) +;; +;; (register "test") +;; +;; +;; ;; Functions +;; +;; (module +;; (type $func_i32 (func (param i32))) +;; (type $func_i64 (func (param i64))) +;; (type $func_f32 (func (param f32))) +;; (type $func_f64 (func (param f64))) +;; +;; (import "spectest" "print_i32" (func (param i32))) +;; ;; JavaScript can't handle i64 yet. +;; ;; (func (import "spectest" "print_i64") (param i64)) +;; (import "spectest" "print_i32" (func $print_i32 (param i32))) +;; ;; JavaScript can't handle i64 yet. +;; ;; (import "spectest" "print_i64" (func $print_i64 (param i64))) +;; (import "spectest" "print_f32" (func $print_f32 (param f32))) +;; (import "spectest" "print_f64" (func $print_f64 (param f64))) +;; (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) +;; (import "spectest" "print_f64_f64" (func $print_f64_f64 (param f64 f64))) +;; (func $print_i32-2 (import "spectest" "print_i32") (param i32)) +;; (func $print_f64-2 (import "spectest" "print_f64") (param f64)) +;; (import "test" "func-i64->i64" (func $i64->i64 (param i64) (result i64))) +;; +;; (func (export "p1") (import "spectest" "print_i32") (param i32)) +;; (func $p (export "p2") (import "spectest" "print_i32") (param i32)) +;; (func (import "spectest" "print_i32") (param i32)) +;; (func (export "p5") (import "spectest" "print_i32") (type 0)) +;; (func (export "p6") (import "spectest" "print_i32") (type 0) (param i32) (result)) +;; +;; ;; (export "p3" (func $print_i32)) +;; ;; (export "p4" (func $print_i32)) +;; +;; (import "spectest" "print_i32" (func (type $forward))) +;; (func (import "spectest" "print_i32") (type $forward)) +;; (type $forward (func (param i32))) +;; +;; (table funcref (elem $print_i32 $print_f64)) +;; +;; (func (export "print32") (param $i i32) +;; (local $x f32) +;; (local.set $x (f32.convert_i32_s (local.get $i))) +;; (call 0 (local.get $i)) +;; (call $print_i32_f32 +;; (i32.add (local.get $i) (i32.const 1)) +;; (f32.const 42) +;; ) +;; (call $print_i32 (local.get $i)) +;; (call $print_i32-2 (local.get $i)) +;; (call $print_f32 (local.get $x)) +;; (call_indirect (type $func_i32) (local.get $i) (i32.const 0)) +;; ) +;; +;; (func (export "print64") (param $i i64) +;; (local $x f64) +;; (local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i)))) +;; ;; JavaScript can't handle i64 yet. +;; ;; (call 1 (local.get $i)) +;; (call $print_f64_f64 +;; (f64.add (local.get $x) (f64.const 1)) +;; (f64.const 53) +;; ) +;; ;; JavaScript can't handle i64 yet. +;; ;; (call $print_i64 (local.get $i)) +;; (call $print_f64 (local.get $x)) +;; (call $print_f64-2 (local.get $x)) +;; (call_indirect (type $func_f64) (local.get $x) (i32.const 1)) +;; ) ;; ) - -;; (assert_unlinkable -;; (module (import "spectest" "memory" (memory 2))) -;; "incompatible import type" +;; +;; (assert_return (invoke "print32" (i32.const 13))) +;; (assert_return (invoke "print64" (i64.const 24))) +;; +;; (assert_invalid +;; (module +;; (type (func (result i32))) +;; (import "test" "func" (func (type 1))) +;; ) +;; "unknown type" +;; ) +;; +;; ;; Export sharing name with import +;; (module +;; (import "spectest" "print_i32" (func $imported_print (param i32))) +;; (func (export "print_i32") (param $i i32) +;; (call $imported_print (local.get $i)) +;; ) ;; ) -;; (assert_unlinkable -;; (module (import "spectest" "memory" (memory 1 1))) -;; "incompatible import type" +;; +;; (assert_return (invoke "print_i32" (i32.const 13))) +;; +;; ;; Export sharing name with import +;; (module +;; (import "spectest" "print_i32" (func $imported_print (param i32))) +;; (func (export "print_i32") (param $i i32) (param $j i32) (result i32) +;; (i32.add (local.get $i) (local.get $j)) +;; ) ;; ) - -(module - (import "spectest" "memory" (memory 0 3)) ;; actual has max size 2 - (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0))) -) -(assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) -(assert_return (invoke "grow" (i32.const 0)) (i32.const 2)) -(assert_return (invoke "grow" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "grow" (i32.const 0)) (i32.const 2)) +;; +;; (assert_return (invoke "print_i32" (i32.const 5) (i32.const 11)) (i32.const 16)) +;; +;; (module (import "test" "func" (func))) +;; (module (import "test" "func-i32" (func (param i32)))) +;; (module (import "test" "func-f32" (func (param f32)))) +;; (module (import "test" "func->i32" (func (result i32)))) +;; (module (import "test" "func->f32" (func (result f32)))) +;; (module (import "test" "func-i32->i32" (func (param i32) (result i32)))) +;; (module (import "test" "func-i64->i64" (func (param i64) (result i64)))) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "unknown" (func))) +;; ;; "unknown import" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "unknown" (func))) +;; ;; "unknown import" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func" (func (param i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func" (func (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func" (func (param i32) (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32" (func (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32" (func (param f32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32" (func (param i64)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32" (func (param i32) (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func->i32" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func->i32" (func (param i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func->i32" (func (result f32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func->i32" (func (result i64)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func->i32" (func (param i32) (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32->i32" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32->i32" (func (param i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32->i32" (func (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (func (result i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-inf" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "memory-2-inf" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "global_i32" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "table" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "memory" (func))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; +;; ;; Globals +;; +;; (module +;; (import "spectest" "global_i32" (global i32)) +;; (global (import "spectest" "global_i32") i32) +;; +;; (import "spectest" "global_i32" (global $x i32)) +;; (global $y (import "spectest" "global_i32") i32) +;; +;; ;; JavaScript can't handle i64 yet. +;; ;; (import "spectest" "global_i64" (global i64)) +;; (import "spectest" "global_f32" (global f32)) +;; (import "spectest" "global_f64" (global f64)) +;; +;; (func (export "get-0") (result i32) (global.get 0)) +;; (func (export "get-1") (result i32) (global.get 1)) +;; (func (export "get-x") (result i32) (global.get $x)) +;; (func (export "get-y") (result i32) (global.get $y)) +;; ) +;; +;; (assert_return (invoke "get-0") (i32.const 666)) +;; (assert_return (invoke "get-1") (i32.const 666)) +;; (assert_return (invoke "get-x") (i32.const 666)) +;; (assert_return (invoke "get-y") (i32.const 666)) +;; +;; (module (import "test" "global-i32" (global i32))) +;; (module (import "test" "global-f32" (global f32))) +;; (module (import "test" "global-mut-i64" (global (mut i64)))) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "unknown" (global i32))) +;; ;; "unknown import" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "unknown" (global i32))) +;; ;; "unknown import" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (global i64))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (global f32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (global f64))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (global (mut i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-f32" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-f32" (global i64))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-f32" (global f64))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-f32" (global (mut f32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-mut-i64" (global (mut i32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-mut-i64" (global (mut f32)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-mut-i64" (global (mut f64)))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-mut-i64" (global i64))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-inf" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "memory-2-inf" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "print_i32" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "table" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "memory" (global i32))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; +;; ;; Tables +;; +;; (module +;; (type (func (result i32))) +;; (import "spectest" "table" (table $tab 10 20 funcref)) +;; (elem (table $tab) (i32.const 1) func $f $g) +;; +;; (func (export "call") (param i32) (result i32) +;; (call_indirect $tab (type 0) (local.get 0)) +;; ) +;; (func $f (result i32) (i32.const 11)) +;; (func $g (result i32) (i32.const 22)) +;; ) +;; +;; (assert_trap (invoke "call" (i32.const 0)) "uninitialized element") +;; (assert_return (invoke "call" (i32.const 1)) (i32.const 11)) +;; (assert_return (invoke "call" (i32.const 2)) (i32.const 22)) +;; (assert_trap (invoke "call" (i32.const 3)) "uninitialized element") +;; (assert_trap (invoke "call" (i32.const 100)) "undefined element") +;; +;; +;; (module +;; (type (func (result i32))) +;; (table $tab (import "spectest" "table") 10 20 funcref) +;; (elem (table $tab) (i32.const 1) func $f $g) +;; +;; (func (export "call") (param i32) (result i32) +;; (call_indirect $tab (type 0) (local.get 0)) +;; ) +;; (func $f (result i32) (i32.const 11)) +;; (func $g (result i32) (i32.const 22)) +;; ) +;; +;; (assert_trap (invoke "call" (i32.const 0)) "uninitialized element") +;; (assert_return (invoke "call" (i32.const 1)) (i32.const 11)) +;; (assert_return (invoke "call" (i32.const 2)) (i32.const 22)) +;; (assert_trap (invoke "call" (i32.const 3)) "uninitialized element") +;; (assert_trap (invoke "call" (i32.const 100)) "undefined element") +;; +;; +;; (module +;; (import "spectest" "table" (table 0 funcref)) +;; (import "spectest" "table" (table 0 funcref)) +;; (table 10 funcref) +;; (table 10 funcref) +;; ) +;; +;; (module (import "test" "table-10-inf" (table 10 funcref))) +;; (module (import "test" "table-10-inf" (table 5 funcref))) +;; (module (import "test" "table-10-inf" (table 0 funcref))) +;; (module (import "test" "table-10-20" (table 10 funcref))) +;; (module (import "test" "table-10-20" (table 5 funcref))) +;; (module (import "test" "table-10-20" (table 0 funcref))) +;; (module (import "test" "table-10-20" (table 10 20 funcref))) +;; (module (import "test" "table-10-20" (table 5 20 funcref))) +;; (module (import "test" "table-10-20" (table 0 20 funcref))) +;; (module (import "test" "table-10-20" (table 10 25 funcref))) +;; (module (import "test" "table-10-20" (table 5 25 funcref))) +;; (module (import "test" "table-10-20" (table 0 25 funcref))) +;; (module (import "spectest" "table" (table 10 funcref))) +;; (module (import "spectest" "table" (table 5 funcref))) +;; (module (import "spectest" "table" (table 0 funcref))) +;; (module (import "spectest" "table" (table 10 20 funcref))) +;; (module (import "spectest" "table" (table 5 20 funcref))) +;; (module (import "spectest" "table" (table 0 20 funcref))) +;; (module (import "spectest" "table" (table 10 25 funcref))) +;; (module (import "spectest" "table" (table 5 25 funcref))) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "unknown" (table 10 funcref))) +;; ;; "unknown import" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "unknown" (table 10 funcref))) +;; ;; "unknown import" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-inf" (table 12 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-inf" (table 10 20 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-20" (table 12 20 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-20" (table 10 18 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "table" (table 12 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "table" (table 10 15 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func" (table 10 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (table 10 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "memory-2-inf" (table 10 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "print_i32" (table 10 funcref))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; +;; ;; Memories +;; +;; (module +;; (import "spectest" "memory" (memory 1 2)) +;; (data (memory 0) (i32.const 10) "\10") +;; +;; (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) +;; ) +;; +;; (assert_return (invoke "load" (i32.const 0)) (i32.const 0)) +;; (assert_return (invoke "load" (i32.const 10)) (i32.const 16)) +;; (assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000)) +;; (assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access") +;; +;; (module +;; (memory (import "spectest" "memory") 1 2) +;; (data (memory 0) (i32.const 10) "\10") +;; +;; (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) +;; ) +;; (assert_return (invoke "load" (i32.const 0)) (i32.const 0)) +;; (assert_return (invoke "load" (i32.const 10)) (i32.const 16)) +;; (assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000)) +;; (assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access") +;; +;; (module (import "test" "memory-2-inf" (memory 2))) +;; (module (import "test" "memory-2-inf" (memory 1))) +;; (module (import "test" "memory-2-inf" (memory 0))) +;; (module (import "spectest" "memory" (memory 1))) +;; (module (import "spectest" "memory" (memory 0))) +;; (module (import "spectest" "memory" (memory 1 2))) +;; (module (import "spectest" "memory" (memory 0 2))) +;; (module (import "spectest" "memory" (memory 1 3))) +;; (module (import "spectest" "memory" (memory 0 3))) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "unknown" (memory 1))) +;; ;; "unknown import" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "unknown" (memory 1))) +;; ;; "unknown import" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "memory-2-inf" (memory 3))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "memory-2-inf" (memory 2 3))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "memory" (memory 2))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "memory" (memory 1 1))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "test" "func-i32" (memory 1))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "global-i32" (memory 1))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "test" "table-10-inf" (memory 1))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "print_i32" (memory 1))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "global_i32" (memory 1))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "table" (memory 1))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "memory" (memory 2))) +;; ;; "incompatible import type" +;; ;; ) +;; ;; (assert_unlinkable +;; ;; (module (import "spectest" "memory" (memory 1 1))) +;; ;; "incompatible import type" +;; ;; ) +;; +;; (module +;; (import "spectest" "memory" (memory 0 3)) ;; actual has max size 2 +;; (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0))) +;; ) +;; (assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) +;; (assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) +;; (assert_return (invoke "grow" (i32.const 0)) (i32.const 2)) +;; (assert_return (invoke "grow" (i32.const 1)) (i32.const -1)) +;; (assert_return (invoke "grow" (i32.const 0)) (i32.const 2)) (module $Mgm (memory (export "memory") 1) ;; initial size is 1 diff --git a/test/spec/ref_func.wast b/test/spec/ref_func.wast index f68e6166de2..7d7cfb0e582 100644 --- a/test/spec/ref_func.wast +++ b/test/spec/ref_func.wast @@ -1,6 +1,7 @@ (module (func (export "f") (param $x i32) (result i32) (local.get $x)) ) +(register "M") (module (func $f (import "M" "f") (param i32) (result i32)) (func $g (param $x i32) (result i32) (i32.add (local.get $x) (i32.const 1))) diff --git a/test/spec/tags.wast b/test/spec/tags.wast index 3b259f417c7..3706ef08473 100644 --- a/test/spec/tags.wast +++ b/test/spec/tags.wast @@ -1,5 +1,11 @@ ;; Test tags +(module + (tag (export "im0") (param i32)) + (tag (export "im1") (param i32 f32)) +) +(register "env") + (module (tag $e-import (import "env" "im0") (param i32)) (import "env" "im1" (tag (param i32 f32)))