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. The .wasm ships in the gem; the Chicory jars are fetched from Maven by jar-dependencies (see lib/rbs_jars.rb and rbs.gemspec).

Constant Summary collapse

INVALID_START_POS =

Statuses the parse entry points return (see rbs_wasm.c). A negative one is about the range the caller asked for rather than the source text, and comes with an empty result.

-2
INVALID_RANGE =
-1
PARSE_ERROR =
0
OK =
1

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRuntime

Returns a new instance of Runtime.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rbs/wasm/runtime.rb', line 37

def initialize
  super()
  # rbs_jars.rb require_jars the Chicory/ASM jars from the local Maven
  # repository (~/.m2), where jar-dependencies puts them at gem install (or
  # `rake wasm:install_jars` when running from source).
  require "rbs_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



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

def instance
  @instance ||= new
end

.wasm_pathObject



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

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

Instance Method Details

#lex(content, encoding, end_pos) ⇒ Object



105
106
107
108
109
# File 'lib/rbs/wasm/runtime.rb', line 105

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



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

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



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

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



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

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 [status, bytes]: with OK bytes is the serialized AST, with PARSE_ERROR it is the error blob (see set_error_result in rbs_wasm.c), and with a negative status it is empty.



63
64
65
# File 'lib/rbs/wasm/runtime.rb', line 63

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



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

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



83
84
85
86
87
# File 'lib/rbs/wasm/runtime.rb', line 83

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