Class: Cry::Wasmer

Inherits:
Object
  • Object
show all
Defined in:
lib/cry/wasmer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wasm_bytes = nil) ⇒ Wasmer

Returns a new instance of Wasmer.



7
8
9
# File 'lib/cry/wasmer.rb', line 7

def initialize(wasm_bytes = nil)
  load_wasm(wasm_bytes) if wasm_bytes
end

Instance Attribute Details

#instanceObject (readonly)

Returns the value of attribute instance.



5
6
7
# File 'lib/cry/wasmer.rb', line 5

def instance
  @instance
end

Instance Method Details

#function(name) ⇒ Object



31
32
33
# File 'lib/cry/wasmer.rb', line 31

def function(name)
  instance.exports.public_send(name)
end

#get_view(addr, type) ⇒ Object



84
85
86
87
88
89
90
91
92
93
# File 'lib/cry/wasmer.rb', line 84

def get_view(addr, type)
  offset = case type
           when 'int8', 'uint8' then addr / 1
           when 'int16', 'uint16' then addr / 2
           when 'int32', 'uint32' then addr / 4
           # when 'int64', 'uint64' then addr / 8
           else raise "unsupported type: #{type}"
           end
  view = memory.public_send("#{type}_view", offset)
end

#invoke(name, *args) ⇒ Object



35
36
37
# File 'lib/cry/wasmer.rb', line 35

def invoke(name, *args)
  instance.exports.public_send(name).call(*args)
end

#load_wasm(wasm_bytes) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/cry/wasmer.rb', line 11

def load_wasm(wasm_bytes)
  store = ::Wasmer::Store.new
  modul = ::Wasmer::Module.new store, wasm_bytes

  wasi_version = ::Wasmer::Wasi.get_version modul, true

  wasi_env = ::Wasmer::Wasi::StateBuilder
             .new('wasi_test_program')
             .argument('--test')
             .environment('COLOR', 'true')
             .environment('APP_SHOULD_LOG', 'false')
             .map_directory('the_host_current_dir', '.')
             .finalize

  import_object = wasi_env.generate_import_object store, wasi_version

  @instance = ::Wasmer::Instance.new modul, import_object
  self
end

#memoryObject



43
44
45
# File 'lib/cry/wasmer.rb', line 43

def memory
  instance.exports.memory
end

#read_memory(addr, t2, len) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/cry/wasmer.rb', line 67

def read_memory(addr, t2, len)
  uint8_view = memory.uint8_view(addr)
  case t2
  when 'int8'    then Array.new(len * 1) { |i| uint8_view[i] }.pack('C*').unpack('c*')
  when 'uint8'   then Array.new(len * 1) { |i| uint8_view[i] }.pack('C*').unpack('C*')
  when 'int16'   then Array.new(len * 2) { |i| uint8_view[i] }.pack('C*').unpack('s*')
  when 'uint16'  then Array.new(len * 2) { |i| uint8_view[i] }.pack('C*').unpack('S*')
  when 'int32'   then Array.new(len * 4) { |i| uint8_view[i] }.pack('C*').unpack('l*')
  when 'uint32'  then Array.new(len * 4) { |i| uint8_view[i] }.pack('C*').unpack('L*')
  when 'int64'   then Array.new(len * 8) { |i| uint8_view[i] }.pack('C*').unpack('q*')
  when 'uint64'  then Array.new(len * 8) { |i| uint8_view[i] }.pack('C*').unpack('Q*')
  when 'float32' then Array.new(len * 4) { |i| uint8_view[i] }.pack('C*').unpack('e*')
  when 'float64' then Array.new(len * 8) { |i| uint8_view[i] }.pack('C*').unpack('E*')
  else raise "unsupported type: #{t2}"
  end
end

#startObject



39
40
41
# File 'lib/cry/wasmer.rb', line 39

def start
  invoke('_start')
end

#write_memory(addr, t2, arg) ⇒ Object



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

def write_memory(addr, t2, arg)
  uint8_view = memory.uint8_view(addr)
  arg_uint8 = case t2
              when 'int8'    then arg.pack('c*')
              when 'uint8'   then arg.pack('C*')
              when 'int16'   then arg.pack('s*')
              when 'uint16'  then arg.pack('S*')
              when 'int32'   then arg.pack('l*')
              when 'uint32'  then arg.pack('L*')
              when 'int64'   then arg.pack('q*')
              when 'uint64'  then arg.pack('Q*')
              when 'float32' then arg.pack('e*')
              when 'float64' then arg.pack('E*')
              else raise "unsupported type: #{t2}"
              end.unpack('C*')
  arg_uint8.each_with_index do |a, i|
    uint8_view[i] = a
  end
end