Class: RBS::WASM::Runtime

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/rbs/wasm/runtime.rb

Overview

Loads rbs_parser.wasm into a JVM WebAssembly runtime (Chicory) and drives it. This is the JRuby counterpart of the C extension’s main.c: it copies a source string into the module’s linear memory, runs the parser, and returns the serialized result for RBS::WASM::Deserializer to rebuild.

Chicory is a pure-Java runtime, so there is no native dependency: only the ‘.wasm` and the Chicory jars need to ship with the gem.

Constant Summary collapse

JARS =

The Chicory jars the runtime needs at load time. Jars Chicory needs to load and run the module.

%w[wasm runtime log wasi].freeze
OPTIONAL_JARS =

Jars for Chicory’s ahead-of-time compiler (wasm -> JVM bytecode), which runs the parser ~8x faster than the interpreter. Optional: the runtime falls back to the interpreter when they are absent. asm* are the ow2 ASM libraries the compiler depends on.

%w[compiler asm asm-tree asm-util asm-commons asm-analysis].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRuntime

Returns a new instance of Runtime.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rbs/wasm/runtime.rb', line 42

def initialize
  super()
  load_jars
  @wasm = build_instance
  @memory = @wasm.memory
  @alloc = @wasm.export("rbs_wasm_alloc")
  @free = @wasm.export("rbs_wasm_free")
  @result_ptr = @wasm.export("rbs_wasm_result_ptr")
  @result_len = @wasm.export("rbs_wasm_result_len")
  @parse_signature = @wasm.export("rbs_wasm_parse_signature")
  @parse_type = @wasm.export("rbs_wasm_parse_type")
  @parse_method_type = @wasm.export("rbs_wasm_parse_method_type")
  @parse_type_params = @wasm.export("rbs_wasm_parse_type_params")
  @parse_inline_leading_annotation = @wasm.export("rbs_wasm_parse_inline_leading_annotation")
  @parse_inline_trailing_annotation = @wasm.export("rbs_wasm_parse_inline_trailing_annotation")
  @lex = @wasm.export("rbs_wasm_lex")
end

Class Method Details

.instanceObject



29
30
31
# File 'lib/rbs/wasm/runtime.rb', line 29

def instance
  @instance ||= new
end

.jars_dirObject



37
38
39
# File 'lib/rbs/wasm/runtime.rb', line 37

def jars_dir
  ENV["RBS_WASM_JARS"] || File.expand_path("jars", __dir__)
end

.wasm_pathObject



33
34
35
# File 'lib/rbs/wasm/runtime.rb', line 33

def wasm_path
  ENV["RBS_WASM_PARSER"] || File.expand_path("rbs_parser.wasm", __dir__)
end

Instance Method Details

#lex(content, encoding, end_pos) ⇒ Object



107
108
109
110
111
# File 'lib/rbs/wasm/runtime.rb', line 107

def lex(content, encoding, end_pos)
  run(content, encoding) do |ptr, len, enc_ptr, enc_len|
    @lex.apply(ptr, len, enc_ptr, enc_len, end_pos)[0]
  end
end

#parse_inline_leading_annotation(content, encoding, start_pos, end_pos, variables) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/rbs/wasm/runtime.rb', line 91

def parse_inline_leading_annotation(content, encoding, start_pos, end_pos, variables)
  with_variables(variables) do |vars_ptr, vars_len|
    run(content, encoding) do |ptr, len, enc_ptr, enc_len|
      @parse_inline_leading_annotation.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len)[0]
    end
  end
end

#parse_inline_trailing_annotation(content, encoding, start_pos, end_pos, variables) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/rbs/wasm/runtime.rb', line 99

def parse_inline_trailing_annotation(content, encoding, start_pos, end_pos, variables)
  with_variables(variables) do |vars_ptr, vars_len|
    run(content, encoding) do |ptr, len, enc_ptr, enc_len|
      @parse_inline_trailing_annotation.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len)[0]
    end
  end
end

#parse_method_type(content, encoding, start_pos, end_pos, variables, require_eof) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/rbs/wasm/runtime.rb', line 77

def parse_method_type(content, encoding, start_pos, end_pos, variables, require_eof)
  with_variables(variables) do |vars_ptr, vars_len|
    run(content, encoding) do |ptr, len, enc_ptr, enc_len|
      @parse_method_type.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len, bool(require_eof))[0]
    end
  end
end

#parse_signature(content, encoding, start_pos, end_pos) ⇒ Object

‘content` is the whole buffer; `start_pos`/`end_pos` are the character range within it to parse. Each method returns [success, bytes]: on success `bytes` is the serialized AST, otherwise it is the error blob (see set_error_result in rbs_wasm.c).



65
66
67
# File 'lib/rbs/wasm/runtime.rb', line 65

def parse_signature(content, encoding, start_pos, end_pos)
  run(content, encoding) { |ptr, len, enc_ptr, enc_len| @parse_signature.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos)[0] }
end

#parse_type(content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) ⇒ Object



69
70
71
72
73
74
75
# File 'lib/rbs/wasm/runtime.rb', line 69

def parse_type(content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
  with_variables(variables) do |vars_ptr, vars_len|
    run(content, encoding) do |ptr, len, enc_ptr, enc_len|
      @parse_type.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len, bool(require_eof), bool(void_allowed), bool(self_allowed), bool(classish_allowed))[0]
    end
  end
end

#parse_type_params(content, encoding, start_pos, end_pos, module_type_params) ⇒ Object



85
86
87
88
89
# File 'lib/rbs/wasm/runtime.rb', line 85

def parse_type_params(content, encoding, start_pos, end_pos, module_type_params)
  run(content, encoding) do |ptr, len, enc_ptr, enc_len|
    @parse_type_params.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, bool(module_type_params))[0]
  end
end