Skip to content

Commit ddf4b2f

Browse files
Merge pull request #66 from MaxDesiatov/maxd/expose-memory
Expose a way to allocate a memory from host
2 parents 5d94eb5 + 467f8ca commit ddf4b2f

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

Sources/WasmKit/Execution/Runtime/Store.swift

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@ public typealias ExternAddress = Int
1010

1111
/// A collection of globals and functions that are exported from a host module.
1212
public struct HostModule {
13-
public init(globals: [String: GlobalInstance] = [:], functions: [String: HostFunction] = [:]) {
13+
public init(
14+
globals: [String: GlobalInstance] = [:],
15+
memories: [String: MemoryAddress] = [:],
16+
functions: [String: HostFunction] = [:]
17+
) {
1418
self.globals = globals
19+
self.memories = memories
1520
self.functions = functions
1621
}
1722

1823
/// Names of globals exported by this module mapped to corresponding global instances.
1924
public let globals: [String: GlobalInstance]
2025

26+
/// Names of memories exported by this module mapped to corresponding addresses of memory instances.
27+
public let memories: [String: MemoryAddress]
28+
2129
/// Names of functions exported by this module mapped to corresponding host functions.
2230
public let functions: [String: HostFunction]
2331
}
@@ -45,19 +53,7 @@ public final class Store {
4553

4654
init(_ hostModules: [String: HostModule]) {
4755
for (moduleName, hostModule) in hostModules {
48-
var moduleExports = ModuleInstance.Exports()
49-
50-
for (globalName, global) in hostModule.globals {
51-
moduleExports[globalName] = .global(-hostGlobals.count - 1)
52-
hostGlobals.append(global)
53-
}
54-
55-
for (functionName, function) in hostModule.functions {
56-
moduleExports[functionName] = .function(-hostFunctions.count - 1)
57-
hostFunctions.append(function)
58-
}
59-
60-
availableExports[moduleName] = moduleExports
56+
registerUniqueHostModule(hostModule, as: moduleName)
6157
}
6258
}
6359
}
@@ -121,6 +117,40 @@ extension Store {
121117
availableExports[name] = moduleInstance.exports
122118
}
123119

120+
/// Register the given host module in this store with the given name.
121+
///
122+
/// - Parameters:
123+
/// - hostModule: A host module to register.
124+
/// - name: A name to register the given host module.
125+
public func register(_ hostModule: HostModule, as name: String) throws {
126+
guard availableExports[name] == nil else {
127+
throw ImportError.moduleInstanceAlreadyRegistered(name)
128+
}
129+
130+
registerUniqueHostModule(hostModule, as: name)
131+
}
132+
133+
/// Register the given host module assuming that the given name is not registered yet.
134+
func registerUniqueHostModule(_ hostModule: HostModule, as name: String) {
135+
var moduleExports = ModuleInstance.Exports()
136+
137+
for (globalName, global) in hostModule.globals {
138+
moduleExports[globalName] = .global(-hostGlobals.count - 1)
139+
hostGlobals.append(global)
140+
}
141+
142+
for (functionName, function) in hostModule.functions {
143+
moduleExports[functionName] = .function(-hostFunctions.count - 1)
144+
hostFunctions.append(function)
145+
}
146+
147+
for (memoryName, memoryAddr) in hostModule.memories {
148+
moduleExports[memoryName] = .memory(memoryAddr)
149+
}
150+
151+
availableExports[name] = moduleExports
152+
}
153+
124154
public func memory(at address: MemoryAddress) -> MemoryInstance {
125155
return self.memories[address]
126156
}
@@ -309,7 +339,7 @@ extension Store {
309339

310340
/// > Note:
311341
/// <https://webassembly.github.io/spec/core/exec/modules.html#alloc-mem>
312-
func allocate(memoryType: MemoryType) -> MemoryAddress {
342+
public func allocate(memoryType: MemoryType) -> MemoryAddress {
313343
let address = memories.count
314344
let instance = MemoryInstance(memoryType)
315345
memories.append(instance)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import XCTest
2+
3+
@testable import WasmKit
4+
5+
final class HostModuleTests: XCTestCase {
6+
func testImportMemory() throws {
7+
let runtime = Runtime()
8+
let memoryType = MemoryType(min: 1, max: nil)
9+
let memoryAddr = runtime.store.allocate(memoryType: memoryType)
10+
try runtime.store.register(HostModule(memories: ["memory": memoryAddr]), as: "env")
11+
12+
let module = Module(
13+
imports: [
14+
Import(module: "env", name: "memory", descriptor: .memory(memoryType))
15+
]
16+
)
17+
XCTAssertNoThrow(try runtime.instantiate(module: module))
18+
// Ensure the allocated address is valid
19+
_ = runtime.store.memory(at: memoryAddr)
20+
}
21+
}

0 commit comments

Comments
 (0)