File: HostModuleTests.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (85 lines) | stat: -rw-r--r-- 3,240 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import XCTest

@testable import WasmKit

final class HostModuleTests: XCTestCase {
    func testImportMemory() throws {
        let runtime = Runtime()
        let memoryType = MemoryType(min: 1, max: nil)
        let memoryAddr = runtime.store.allocate(memoryType: memoryType)
        try runtime.store.register(HostModule(memories: ["memory": memoryAddr]), as: "env")

        let module = Module(
            imports: [
                Import(module: "env", name: "memory", descriptor: .memory(memoryType))
            ]
        )
        XCTAssertNoThrow(try runtime.instantiate(module: module))
        // Ensure the allocated address is valid
        _ = runtime.store.memory(at: memoryAddr)
    }

    func testReentrancy() throws {
        let runtime = Runtime()
        let voidSignature = FunctionType(parameters: [], results: [])
        let module = Module(
            types: [voidSignature],
            functions: [
                // [0] (import "env" "bar" func)
                // [1] (import "env" "qux" func)
                // [2] "foo"
                GuestFunction(
                    type: 0, locals: [],
                    body: {
                        [
                            .call(functionIndex: 0),
                            .call(functionIndex: 0),
                            .call(functionIndex: 0),
                        ]
                    }),
                // [3] "bar"
                GuestFunction(
                    type: 0, locals: [],
                    body: {
                        [
                            .control(.call(functionIndex: 1))
                        ]
                    }),
            ],
            imports: [
                Import(module: "env", name: "bar", descriptor: .function(0)),
                Import(module: "env", name: "qux", descriptor: .function(0)),
            ],
            exports: [
                Export(name: "foo", descriptor: .function(2)),
                Export(name: "baz", descriptor: .function(3)),
            ]
        )

        var isExecutingFoo = false
        var isQuxCalled = false
        let hostModule = HostModule(
            functions: [
                "bar": HostFunction(type: voidSignature) { caller, _ in
                    // Ensure "invoke" executes instructions under the current call
                    XCTAssertFalse(isExecutingFoo, "bar should not be called recursively")
                    isExecutingFoo = true
                    defer { isExecutingFoo = false }
                    let foo = try XCTUnwrap(caller.instance.exportedFunction(name: "baz"))
                    _ = try foo.invoke([], runtime: caller.runtime)
                    return []
                },
                "qux": HostFunction(type: voidSignature) { _, _ in
                    XCTAssertTrue(isExecutingFoo)
                    isQuxCalled = true
                    return []
                },
            ]
        )
        try runtime.store.register(hostModule, as: "env")
        let instance = try runtime.instantiate(module: module)
        // Check foo(wasm) -> bar(host) -> baz(wasm) -> qux(host)
        _ = try runtime.invoke(instance, function: "foo")
        XCTAssertTrue(isQuxCalled)
    }
}