|
1 | | -import WAT |
2 | | -import XCTest |
| 1 | +#if canImport(Testing) |
| 2 | + import WAT |
| 3 | + import Testing |
3 | 4 |
|
4 | | -@testable import WasmKit |
5 | | -@testable import WasmParser |
| 5 | + @testable import WasmKit |
| 6 | + @testable import WasmParser |
6 | 7 |
|
7 | | -final class HostModuleTests: XCTestCase { |
8 | | - func testImportMemory() throws { |
9 | | - let engine = Engine() |
10 | | - let store = Store(engine: engine) |
11 | | - let memoryType = MemoryType(min: 1, max: nil) |
12 | | - let memory = try WasmKit.Memory(store: store, type: memoryType) |
13 | | - let imports: Imports = [ |
14 | | - "env": ["memory": memory] |
15 | | - ] |
16 | | - |
17 | | - let module = try parseWasm( |
18 | | - bytes: wat2wasm( |
19 | | - """ |
20 | | - (module |
21 | | - (import "env" "memory" (memory 1)) |
22 | | - ) |
23 | | - """)) |
24 | | - XCTAssertNoThrow(try module.instantiate(store: store, imports: imports)) |
25 | | - // Ensure the allocated address is valid |
26 | | - _ = memory.data |
27 | | - } |
| 8 | + @Suite |
| 9 | + struct HostModuleTests { |
| 10 | + @Test |
| 11 | + func importMemory() throws { |
| 12 | + let engine = Engine() |
| 13 | + let store = Store(engine: engine) |
| 14 | + let memoryType = MemoryType(min: 1, max: nil) |
| 15 | + let memory = try WasmKit.Memory(store: store, type: memoryType) |
| 16 | + let imports: Imports = [ |
| 17 | + "env": ["memory": memory] |
| 18 | + ] |
28 | 19 |
|
29 | | - func testReentrancy() throws { |
30 | | - let engine = Engine() |
31 | | - let store = Store(engine: engine) |
32 | | - let voidSignature = WasmTypes.FunctionType(parameters: [], results: []) |
33 | | - let module = try parseWasm( |
34 | | - bytes: wat2wasm( |
35 | | - """ |
36 | | - (module |
37 | | - (import "env" "bar" (func $bar)) |
38 | | - (import "env" "qux" (func $qux)) |
39 | | - (func (export "foo") |
40 | | - (call $bar) |
41 | | - (call $bar) |
42 | | - (call $bar) |
| 20 | + let module = try parseWasm( |
| 21 | + bytes: wat2wasm( |
| 22 | + """ |
| 23 | + (module |
| 24 | + (import "env" "memory" (memory 1)) |
43 | 25 | ) |
44 | | - (func (export "baz") |
45 | | - (call $qux) |
| 26 | + """)) |
| 27 | + #expect(throws: Never.self) { try module.instantiate(store: store, imports: imports) } |
| 28 | + // Ensure the allocated address is valid |
| 29 | + _ = memory.data |
| 30 | + } |
| 31 | + |
| 32 | + @Test |
| 33 | + func reentrancy() throws { |
| 34 | + let engine = Engine() |
| 35 | + let store = Store(engine: engine) |
| 36 | + let voidSignature = WasmTypes.FunctionType(parameters: [], results: []) |
| 37 | + let module = try parseWasm( |
| 38 | + bytes: wat2wasm( |
| 39 | + """ |
| 40 | + (module |
| 41 | + (import "env" "bar" (func $bar)) |
| 42 | + (import "env" "qux" (func $qux)) |
| 43 | + (func (export "foo") |
| 44 | + (call $bar) |
| 45 | + (call $bar) |
| 46 | + (call $bar) |
| 47 | + ) |
| 48 | + (func (export "baz") |
| 49 | + (call $qux) |
| 50 | + ) |
46 | 51 | ) |
47 | | - ) |
48 | | - """) |
49 | | - ) |
| 52 | + """) |
| 53 | + ) |
50 | 54 |
|
51 | | - var isExecutingFoo = false |
52 | | - var isQuxCalled = false |
53 | | - let imports: Imports = [ |
54 | | - "env": [ |
55 | | - "bar": Function(store: store, type: voidSignature) { caller, _ in |
56 | | - // Ensure "invoke" executes instructions under the current call |
57 | | - XCTAssertFalse(isExecutingFoo, "bar should not be called recursively") |
58 | | - isExecutingFoo = true |
59 | | - defer { isExecutingFoo = false } |
60 | | - let foo = try XCTUnwrap(caller.instance?.exportedFunction(name: "baz")) |
61 | | - _ = try foo() |
62 | | - return [] |
63 | | - }, |
64 | | - "qux": Function(store: store, type: voidSignature) { caller, _ in |
65 | | - XCTAssertTrue(isExecutingFoo) |
66 | | - isQuxCalled = true |
67 | | - return [] |
68 | | - }, |
| 55 | + var isExecutingFoo = false |
| 56 | + var isQuxCalled = false |
| 57 | + let imports: Imports = [ |
| 58 | + "env": [ |
| 59 | + "bar": Function(store: store, type: voidSignature) { caller, _ in |
| 60 | + // Ensure "invoke" executes instructions under the current call |
| 61 | + #expect(isExecutingFoo == false, "bar should not be called recursively") |
| 62 | + isExecutingFoo = true |
| 63 | + defer { isExecutingFoo = false } |
| 64 | + let foo = try #require(caller.instance?.exportedFunction(name: "baz")) |
| 65 | + _ = try foo() |
| 66 | + return [] |
| 67 | + }, |
| 68 | + "qux": Function(store: store, type: voidSignature) { caller, _ in |
| 69 | + #expect(isExecutingFoo == true) |
| 70 | + isQuxCalled = true |
| 71 | + return [] |
| 72 | + }, |
| 73 | + ] |
69 | 74 | ] |
70 | | - ] |
71 | | - let instance = try module.instantiate(store: store, imports: imports) |
72 | | - // Check foo(wasm) -> bar(host) -> baz(wasm) -> qux(host) |
73 | | - let foo = try XCTUnwrap(instance.exports[function: "foo"]) |
74 | | - try foo() |
75 | | - XCTAssertTrue(isQuxCalled) |
| 75 | + let instance = try module.instantiate(store: store, imports: imports) |
| 76 | + // Check foo(wasm) -> bar(host) -> baz(wasm) -> qux(host) |
| 77 | + let foo = try #require(instance.exports[function: "foo"]) |
| 78 | + try foo() |
| 79 | + #expect(isQuxCalled == true) |
| 80 | + } |
76 | 81 | } |
77 | | -} |
| 82 | + |
| 83 | +#endif |
0 commit comments