Class: HyperUuid::Runtime::WasmInstance

Inherits:
Object
  • Object
show all
Defined in:
lib/hyperuuid/wasm_runtime.rb

Overview

One instantiated module: the exported functions, the exported memory, and the two 16-byte scratch buffers (one in, one out) the single-item doors reuse for the life of the process. Batches and v5 names get a malloc/free pair per call instead — one allocation amortized over count IDs, the same shape as the Fiddle backend's per-batch Pointer.malloc.

Constant Summary collapse

EXPORTS =
%i[
  malloc free
  uuid_new_v4 uuid_new_v5 uuid_new_v6 uuid_v6_unix_millis uuid_new_v6_batch
  uuid_new_v7 uuid_v7_unix_millis uuid_new_v7_batch
  uuid_v7_to_sql_order uuid_v7_to_rfc_order uuid_v6_to_sql_order uuid_v6_to_rfc_order
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ WasmInstance

Returns a new instance of WasmInstance.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/hyperuuid/wasm_runtime.rb', line 47

def initialize(path)
  unless File.exist?(path)
    raise LoadError,
          "hyperuuid: #{path} not found (this gem was built without its WebAssembly module)"
  end

  engine = Wasmtime::Engine.new
  mod = Wasmtime::Module.from_file(engine, path)
  linker = Wasmtime::Linker.new(engine)
  # The module imports five WASI preview1 functions (random_get is the one that
  # matters: it is the core's only entropy source; the rest are wasi-libc's startup
  # plumbing). A default WasiConfig — no stdio, no filesystem, no environment — is all
  # any of them need.
  Wasmtime::WASI::P1.add_to_linker_sync(linker)
  store = Wasmtime::Store.new(engine, wasi_p1_config: Wasmtime::WasiConfig.new)
  instance = linker.instantiate(store, mod)

  @memory = instance.export("memory").to_memory
  @fn = EXPORTS.to_h { |name| [name, instance.export(name.to_s).to_func] }
  @in = malloc(16)
  @out = malloc(16)
end

Instance Attribute Details

#in ⇒ Object (readonly)

Returns the value of attribute in.



38
39
40
# File 'lib/hyperuuid/wasm_runtime.rb', line 38

def in
  @in
end

#memory ⇒ Object (readonly)

Returns the value of attribute memory.



38
39
40
# File 'lib/hyperuuid/wasm_runtime.rb', line 38

def memory
  @memory
end

#out ⇒ Object (readonly)

Returns the value of attribute out.



38
39
40
# File 'lib/hyperuuid/wasm_runtime.rb', line 38

def out
  @out
end

Instance Method Details

#fn(name) ⇒ Object



70
71
72
# File 'lib/hyperuuid/wasm_runtime.rb', line 70

def fn(name)
  @fn.fetch(name)
end

#free(ptr) ⇒ Object



80
81
82
# File 'lib/hyperuuid/wasm_runtime.rb', line 80

def free(ptr)
  @fn[:free].call(ptr)
end

#malloc(size) ⇒ Object

Raises:

  • (NoMemoryError)


74
75
76
77
78
# File 'lib/hyperuuid/wasm_runtime.rb', line 74

def malloc(size)
  ptr = @fn[:malloc].call(size)
  raise NoMemoryError, "hyperuuid: wasm malloc(#{size}) failed" if ptr.zero?
  ptr
end

#with_buffer(size) ⇒ Object

Runs block with a size-byte guest buffer, freeing it afterwards even on error.



85
86
87
88
89
90
91
92
# File 'lib/hyperuuid/wasm_runtime.rb', line 85

def with_buffer(size)
  ptr = malloc(size)
  begin
    yield ptr
  ensure
    free(ptr)
  end
end