File: Function.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, 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 (50 lines) | stat: -rw-r--r-- 2,197 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
/// A WebAssembly guest function or host function
public struct Function: Equatable {
    internal let address: FunctionAddress

    /// Invokes a function of the given address with the given parameters.
    public func invoke(_ arguments: [Value] = [], runtime: Runtime) throws -> [Value] {
        try withExecution { execution in
            try invoke(execution: &execution, with: arguments, runtime: runtime)
            try execution.run(runtime: runtime)
            return try Array(execution.stack.popTopValues())
        }
    }

    private func invoke(execution: inout ExecutionState, with arguments: [Value], runtime: Runtime) throws {
        switch try runtime.store.function(at: address) {
        case let .host(function):
            try check(functionType: function.type, parameters: arguments)

            let parameters = execution.stack.popValues(count: function.type.parameters.count)

            let moduleInstance = runtime.store.module(address: execution.stack.currentFrame.module)
            let caller = Caller(runtime: runtime, instance: moduleInstance)
            let results = try function.implementation(caller, Array(parameters))
            try check(functionType: function.type, results: results)
            execution.stack.push(values: results)

        case let .wasm(function, _):
            try check(functionType: function.type, parameters: arguments)
            execution.stack.push(values: arguments)

            try execution.invoke(functionAddress: address, runtime: runtime)
        }
    }

    private func check(functionType: FunctionType, parameters: [Value]) throws {
        let parameterTypes = parameters.map { $0.type }

        guard parameterTypes == functionType.parameters else {
            throw Trap._raw("parameters types don't match, expected \(functionType.parameters), got \(parameterTypes)")
        }
    }

    private func check(functionType: FunctionType, results: [Value]) throws {
        let resultTypes = results.map { $0.type }

        guard resultTypes == functionType.results else {
            throw Trap._raw("result types don't match, expected \(functionType.results), got \(resultTypes)")
        }
    }
}