Skip to content

Commit

Permalink
Merge pull request #66 from MaxDesiatov/maxd/expose-memory
Browse files Browse the repository at this point in the history
Expose a way to allocate a memory from host
  • Loading branch information
kateinoigakukun authored Nov 10, 2023
2 parents 5d94eb5 + 467f8ca commit ddf4b2f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 15 deletions.
60 changes: 45 additions & 15 deletions Sources/WasmKit/Execution/Runtime/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,22 @@ public typealias ExternAddress = Int

/// A collection of globals and functions that are exported from a host module.
public struct HostModule {
public init(globals: [String: GlobalInstance] = [:], functions: [String: HostFunction] = [:]) {
public init(
globals: [String: GlobalInstance] = [:],
memories: [String: MemoryAddress] = [:],
functions: [String: HostFunction] = [:]
) {
self.globals = globals
self.memories = memories
self.functions = functions
}

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

/// Names of memories exported by this module mapped to corresponding addresses of memory instances.
public let memories: [String: MemoryAddress]

/// Names of functions exported by this module mapped to corresponding host functions.
public let functions: [String: HostFunction]
}
Expand Down Expand Up @@ -45,19 +53,7 @@ public final class Store {

init(_ hostModules: [String: HostModule]) {
for (moduleName, hostModule) in hostModules {
var moduleExports = ModuleInstance.Exports()

for (globalName, global) in hostModule.globals {
moduleExports[globalName] = .global(-hostGlobals.count - 1)
hostGlobals.append(global)
}

for (functionName, function) in hostModule.functions {
moduleExports[functionName] = .function(-hostFunctions.count - 1)
hostFunctions.append(function)
}

availableExports[moduleName] = moduleExports
registerUniqueHostModule(hostModule, as: moduleName)
}
}
}
Expand Down Expand Up @@ -121,6 +117,40 @@ extension Store {
availableExports[name] = moduleInstance.exports
}

/// Register the given host module in this store with the given name.
///
/// - Parameters:
/// - hostModule: A host module to register.
/// - name: A name to register the given host module.
public func register(_ hostModule: HostModule, as name: String) throws {
guard availableExports[name] == nil else {
throw ImportError.moduleInstanceAlreadyRegistered(name)
}

registerUniqueHostModule(hostModule, as: name)
}

/// Register the given host module assuming that the given name is not registered yet.
func registerUniqueHostModule(_ hostModule: HostModule, as name: String) {
var moduleExports = ModuleInstance.Exports()

for (globalName, global) in hostModule.globals {
moduleExports[globalName] = .global(-hostGlobals.count - 1)
hostGlobals.append(global)
}

for (functionName, function) in hostModule.functions {
moduleExports[functionName] = .function(-hostFunctions.count - 1)
hostFunctions.append(function)
}

for (memoryName, memoryAddr) in hostModule.memories {
moduleExports[memoryName] = .memory(memoryAddr)
}

availableExports[name] = moduleExports
}

public func memory(at address: MemoryAddress) -> MemoryInstance {
return self.memories[address]
}
Expand Down Expand Up @@ -309,7 +339,7 @@ extension Store {

/// > Note:
/// <https://webassembly.github.io/spec/core/exec/modules.html#alloc-mem>
func allocate(memoryType: MemoryType) -> MemoryAddress {
public func allocate(memoryType: MemoryType) -> MemoryAddress {
let address = memories.count
let instance = MemoryInstance(memoryType)
memories.append(instance)
Expand Down
21 changes: 21 additions & 0 deletions Tests/WasmKitTests/Execution/HostModuleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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)
}
}

0 comments on commit ddf4b2f

Please sign in to comment.