rbs 3.9.4 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +75 -0
  3. data/.clangd +2 -0
  4. data/.dockerignore +37 -0
  5. data/.gitattributes +1 -0
  6. data/.github/dependabot.yml +16 -14
  7. data/.github/workflows/bundle-update.yml +63 -0
  8. data/.github/workflows/c-check.yml +66 -0
  9. data/.github/workflows/changelog.yml +121 -0
  10. data/.github/workflows/comments.yml +6 -4
  11. data/.github/workflows/dependabot.yml +2 -2
  12. data/.github/workflows/jruby.yml +74 -0
  13. data/.github/workflows/release-gems.yml +234 -0
  14. data/.github/workflows/ruby.yml +86 -32
  15. data/.github/workflows/rust.yml +186 -0
  16. data/.github/workflows/truffleruby.yml +54 -0
  17. data/.github/workflows/typecheck.yml +6 -3
  18. data/.github/workflows/wasm.yml +55 -0
  19. data/.github/workflows/windows.yml +10 -4
  20. data/.gitignore +16 -0
  21. data/.rubocop.yml +1 -2
  22. data/CHANGELOG.md +502 -0
  23. data/Dockerfile.jruby +53 -0
  24. data/README.md +42 -5
  25. data/Rakefile +892 -111
  26. data/Steepfile +11 -0
  27. data/config.yml +665 -62
  28. data/core/array.rbs +541 -398
  29. data/core/basic_object.rbs +9 -8
  30. data/core/binding.rbs +0 -2
  31. data/core/builtin.rbs +9 -8
  32. data/core/class.rbs +11 -8
  33. data/core/comparable.rbs +55 -34
  34. data/core/complex.rbs +104 -78
  35. data/core/dir.rbs +61 -49
  36. data/core/encoding.rbs +12 -15
  37. data/core/enumerable.rbs +297 -196
  38. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  39. data/core/enumerator/product.rbs +5 -5
  40. data/core/enumerator.rbs +91 -28
  41. data/core/errno.rbs +11 -2
  42. data/core/errors.rbs +58 -29
  43. data/core/exception.rbs +13 -13
  44. data/core/fiber.rbs +74 -54
  45. data/core/file.rbs +260 -1151
  46. data/core/file_constants.rbs +463 -0
  47. data/core/file_stat.rbs +534 -0
  48. data/core/file_test.rbs +3 -3
  49. data/core/float.rbs +257 -116
  50. data/core/gc.rbs +425 -281
  51. data/core/hash.rbs +1151 -829
  52. data/core/integer.rbs +156 -195
  53. data/core/io/buffer.rbs +53 -42
  54. data/core/io/wait.rbs +13 -35
  55. data/core/io.rbs +222 -155
  56. data/core/kernel.rbs +239 -163
  57. data/core/marshal.rbs +4 -4
  58. data/core/match_data.rbs +16 -14
  59. data/core/math.rbs +107 -66
  60. data/core/method.rbs +69 -33
  61. data/core/module.rbs +302 -150
  62. data/core/nil_class.rbs +7 -6
  63. data/core/numeric.rbs +77 -63
  64. data/core/object.rbs +9 -11
  65. data/core/object_space/weak_key_map.rbs +7 -7
  66. data/core/object_space.rbs +30 -23
  67. data/core/pathname.rbs +1312 -0
  68. data/core/proc.rbs +95 -58
  69. data/core/process.rbs +222 -202
  70. data/core/ractor.rbs +364 -518
  71. data/core/random.rbs +21 -3
  72. data/core/range.rbs +181 -79
  73. data/core/rational.rbs +60 -89
  74. data/core/rbs/ops.rbs +154 -0
  75. data/core/rbs/unnamed/argf.rbs +63 -56
  76. data/core/rbs/unnamed/env_class.rbs +19 -14
  77. data/core/rbs/unnamed/main_class.rbs +123 -0
  78. data/core/rbs/unnamed/random.rbs +11 -118
  79. data/core/regexp.rbs +258 -214
  80. data/core/ruby.rbs +53 -0
  81. data/core/ruby_vm.rbs +78 -34
  82. data/core/rubygems/config_file.rbs +5 -5
  83. data/core/rubygems/errors.rbs +6 -70
  84. data/core/rubygems/requirement.rbs +5 -15
  85. data/core/rubygems/rubygems.rbs +18 -81
  86. data/core/rubygems/specification.rbs +8 -0
  87. data/core/rubygems/version.rbs +2 -163
  88. data/core/set.rbs +493 -363
  89. data/core/signal.rbs +26 -16
  90. data/core/string.rbs +3234 -1285
  91. data/core/struct.rbs +43 -42
  92. data/core/symbol.rbs +41 -34
  93. data/core/thread.rbs +139 -83
  94. data/core/time.rbs +81 -50
  95. data/core/trace_point.rbs +41 -35
  96. data/core/true_class.rbs +2 -2
  97. data/core/unbound_method.rbs +24 -16
  98. data/core/warning.rbs +7 -7
  99. data/docs/CONTRIBUTING.md +3 -2
  100. data/docs/aliases.md +79 -0
  101. data/docs/collection.md +3 -3
  102. data/docs/config.md +171 -0
  103. data/docs/encoding.md +56 -0
  104. data/docs/gem.md +0 -1
  105. data/docs/inline.md +634 -0
  106. data/docs/rbs_by_example.md +20 -20
  107. data/docs/release.md +303 -0
  108. data/docs/rust.md +96 -0
  109. data/docs/sigs.md +3 -3
  110. data/docs/stdlib.md +8 -0
  111. data/docs/syntax.md +60 -18
  112. data/docs/type_fingerprint.md +21 -0
  113. data/docs/wasm_serialization.md +80 -0
  114. data/exe/rbs +1 -1
  115. data/ext/rbs_extension/ast_translation.c +1870 -0
  116. data/ext/rbs_extension/ast_translation.h +41 -0
  117. data/ext/rbs_extension/class_constants.c +189 -0
  118. data/{include/rbs/constants.h → ext/rbs_extension/class_constants.h} +24 -1
  119. data/ext/rbs_extension/compat.h +10 -0
  120. data/ext/rbs_extension/extconf.rb +26 -1
  121. data/ext/rbs_extension/legacy_location.c +299 -0
  122. data/ext/rbs_extension/legacy_location.h +82 -0
  123. data/ext/rbs_extension/main.c +639 -23
  124. data/ext/rbs_extension/rbs_extension.h +6 -21
  125. data/ext/rbs_extension/rbs_string_bridging.c +9 -0
  126. data/ext/rbs_extension/rbs_string_bridging.h +24 -0
  127. data/include/rbs/ast.h +1055 -0
  128. data/include/rbs/defines.h +104 -0
  129. data/include/rbs/lexer.h +208 -0
  130. data/include/rbs/location.h +40 -0
  131. data/include/rbs/parser.h +187 -0
  132. data/include/rbs/serialize.h +39 -0
  133. data/include/rbs/string.h +47 -0
  134. data/include/rbs/util/rbs_allocator.h +59 -0
  135. data/include/rbs/util/rbs_assert.h +20 -0
  136. data/include/rbs/util/rbs_buffer.h +83 -0
  137. data/include/rbs/util/rbs_constant_pool.h +6 -70
  138. data/include/rbs/util/rbs_encoding.h +282 -0
  139. data/include/rbs/util/rbs_unescape.h +24 -0
  140. data/include/rbs.h +9 -2
  141. data/lib/rbs/annotate/formatter.rb +3 -13
  142. data/lib/rbs/annotate/rdoc_annotator.rb +30 -32
  143. data/lib/rbs/annotate/rdoc_source.rb +1 -1
  144. data/lib/rbs/ast/annotation.rb +1 -1
  145. data/lib/rbs/ast/comment.rb +1 -1
  146. data/lib/rbs/ast/declarations.rb +11 -11
  147. data/lib/rbs/ast/members.rb +14 -14
  148. data/lib/rbs/ast/ruby/annotations.rb +451 -0
  149. data/lib/rbs/ast/ruby/comment_block.rb +247 -0
  150. data/lib/rbs/ast/ruby/declarations.rb +291 -0
  151. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
  152. data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  153. data/lib/rbs/ast/ruby/members.rb +762 -0
  154. data/lib/rbs/ast/type_param.rb +25 -5
  155. data/lib/rbs/buffer.rb +142 -20
  156. data/lib/rbs/cli/diff.rb +16 -15
  157. data/lib/rbs/cli/validate.rb +63 -126
  158. data/lib/rbs/cli.rb +59 -29
  159. data/lib/rbs/collection/config/lockfile_generator.rb +28 -3
  160. data/lib/rbs/collection/sources/git.rb +7 -0
  161. data/lib/rbs/definition.rb +6 -1
  162. data/lib/rbs/definition_builder/ancestor_builder.rb +129 -70
  163. data/lib/rbs/definition_builder/method_builder.rb +74 -33
  164. data/lib/rbs/definition_builder.rb +181 -21
  165. data/lib/rbs/diff.rb +7 -1
  166. data/lib/rbs/environment/class_entry.rb +81 -0
  167. data/lib/rbs/environment/module_entry.rb +91 -0
  168. data/lib/rbs/environment.rb +410 -215
  169. data/lib/rbs/environment_loader.rb +2 -8
  170. data/lib/rbs/errors.rb +31 -21
  171. data/lib/rbs/inline_parser/comment_association.rb +117 -0
  172. data/lib/rbs/inline_parser.rb +568 -0
  173. data/lib/rbs/location_aux.rb +36 -4
  174. data/lib/rbs/locator.rb +5 -1
  175. data/lib/rbs/method_type.rb +5 -3
  176. data/lib/rbs/namespace.rb +47 -18
  177. data/lib/rbs/parser_aux.rb +37 -7
  178. data/lib/rbs/prototype/helpers.rb +24 -0
  179. data/lib/rbs/prototype/rb.rb +3 -28
  180. data/lib/rbs/prototype/rbi.rb +196 -45
  181. data/lib/rbs/prototype/runtime/value_object_generator.rb +0 -1
  182. data/lib/rbs/prototype/runtime.rb +13 -3
  183. data/lib/rbs/resolver/constant_resolver.rb +2 -2
  184. data/lib/rbs/resolver/type_name_resolver.rb +120 -44
  185. data/lib/rbs/rewriter.rb +70 -0
  186. data/lib/rbs/source.rb +99 -0
  187. data/lib/rbs/subtractor.rb +7 -4
  188. data/lib/rbs/test/type_check.rb +25 -3
  189. data/lib/rbs/type_name.rb +34 -21
  190. data/lib/rbs/types.rb +135 -81
  191. data/lib/rbs/unit_test/convertibles.rb +1 -0
  192. data/lib/rbs/unit_test/type_assertions.rb +47 -11
  193. data/lib/rbs/validator.rb +2 -2
  194. data/lib/rbs/version.rb +1 -1
  195. data/lib/rbs/wasm/deserializer.rb +213 -0
  196. data/lib/rbs/wasm/location.rb +61 -0
  197. data/lib/rbs/wasm/parser.rb +174 -0
  198. data/lib/rbs/wasm/runtime.rb +211 -0
  199. data/lib/rbs/wasm/serialization_schema.rb +111 -0
  200. data/lib/rbs.rb +25 -2
  201. data/lib/rbs_jars.rb +39 -0
  202. data/lib/rdoc/discover.rb +1 -1
  203. data/lib/rdoc_plugin/parser.rb +8 -3
  204. data/rbs.gemspec +34 -6
  205. data/schema/function.json +12 -1
  206. data/schema/typeParam.json +17 -1
  207. data/sig/ancestor_builder.rbs +1 -1
  208. data/sig/annotate/formatter.rbs +2 -2
  209. data/sig/annotate/rdoc_annotater.rbs +13 -10
  210. data/sig/ast/ruby/annotations.rbs +470 -0
  211. data/sig/ast/ruby/comment_block.rbs +127 -0
  212. data/sig/ast/ruby/declarations.rbs +158 -0
  213. data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  214. data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  215. data/sig/ast/ruby/members.rbs +198 -0
  216. data/sig/buffer.rbs +81 -5
  217. data/sig/cli/diff.rbs +5 -11
  218. data/sig/cli/validate.rbs +12 -8
  219. data/sig/cli.rbs +18 -18
  220. data/sig/collection/config/lockfile_generator.rbs +2 -0
  221. data/sig/definition.rbs +6 -0
  222. data/sig/definition_builder.rbs +3 -1
  223. data/sig/environment/class_entry.rbs +56 -0
  224. data/sig/environment/module_entry.rbs +65 -0
  225. data/sig/environment.rbs +94 -87
  226. data/sig/errors.rbs +26 -20
  227. data/sig/inline_parser/comment_association.rbs +71 -0
  228. data/sig/inline_parser.rbs +126 -0
  229. data/sig/location.rbs +32 -7
  230. data/sig/locator.rbs +0 -2
  231. data/sig/manifest.yaml +0 -2
  232. data/sig/method_builder.rbs +9 -4
  233. data/sig/namespace.rbs +20 -5
  234. data/sig/parser.rbs +79 -15
  235. data/sig/prototype/helpers.rbs +2 -0
  236. data/sig/prototype/rbi.rbs +33 -4
  237. data/sig/resolver/type_name_resolver.rbs +36 -10
  238. data/sig/rewriter.rbs +45 -0
  239. data/sig/source.rbs +48 -0
  240. data/sig/type_param.rbs +13 -8
  241. data/sig/typename.rbs +15 -5
  242. data/sig/types.rbs +21 -9
  243. data/sig/unit_test/spy.rbs +0 -8
  244. data/sig/unit_test/type_assertions.rbs +17 -2
  245. data/sig/wasm/deserializer.rbs +66 -0
  246. data/sig/wasm/serialization_schema.rbs +13 -0
  247. data/src/ast.c +1644 -0
  248. data/src/lexer.c +3223 -0
  249. data/src/lexer.re +187 -0
  250. data/src/lexstate.c +222 -0
  251. data/src/location.c +31 -0
  252. data/src/parser.c +4318 -0
  253. data/src/serialize.c +965 -0
  254. data/src/string.c +41 -0
  255. data/src/util/rbs_allocator.c +171 -0
  256. data/src/util/rbs_assert.c +19 -0
  257. data/src/util/rbs_buffer.c +54 -0
  258. data/src/util/rbs_constant_pool.c +18 -92
  259. data/src/util/rbs_encoding.c +21454 -0
  260. data/src/util/rbs_unescape.c +167 -0
  261. data/stdlib/abbrev/0/array.rbs +1 -1
  262. data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
  263. data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
  264. data/stdlib/cgi/0/core.rbs +9 -393
  265. data/stdlib/cgi/0/manifest.yaml +1 -0
  266. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  267. data/stdlib/coverage/0/coverage.rbs +7 -4
  268. data/stdlib/csv/0/csv.rbs +5 -5
  269. data/stdlib/date/0/date.rbs +92 -79
  270. data/stdlib/date/0/date_time.rbs +25 -24
  271. data/stdlib/delegate/0/delegator.rbs +11 -7
  272. data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
  273. data/stdlib/digest/0/digest.rbs +117 -1
  274. data/stdlib/erb/0/erb.rbs +754 -353
  275. data/stdlib/etc/0/etc.rbs +73 -54
  276. data/stdlib/fileutils/0/fileutils.rbs +179 -160
  277. data/stdlib/forwardable/0/forwardable.rbs +13 -10
  278. data/stdlib/io-console/0/io-console.rbs +2 -2
  279. data/stdlib/ipaddr/0/ipaddr.rbs +0 -5
  280. data/stdlib/json/0/json.rbs +232 -185
  281. data/stdlib/monitor/0/monitor.rbs +9 -9
  282. data/stdlib/net-http/0/net-http.rbs +162 -134
  283. data/stdlib/objspace/0/objspace.rbs +17 -34
  284. data/stdlib/open-uri/0/open-uri.rbs +48 -8
  285. data/stdlib/open3/0/open3.rbs +469 -10
  286. data/stdlib/openssl/0/openssl.rbs +521 -397
  287. data/stdlib/optparse/0/optparse.rbs +26 -17
  288. data/stdlib/pathname/0/pathname.rbs +11 -1381
  289. data/stdlib/pp/0/pp.rbs +9 -8
  290. data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
  291. data/stdlib/pstore/0/pstore.rbs +35 -30
  292. data/stdlib/psych/0/psych.rbs +65 -12
  293. data/stdlib/psych/0/store.rbs +2 -4
  294. data/stdlib/pty/0/pty.rbs +9 -6
  295. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  296. data/stdlib/rdoc/0/code_object.rbs +4 -3
  297. data/stdlib/rdoc/0/comment.rbs +2 -0
  298. data/stdlib/rdoc/0/options.rbs +76 -0
  299. data/stdlib/rdoc/0/parser.rbs +1 -1
  300. data/stdlib/rdoc/0/rdoc.rbs +7 -5
  301. data/stdlib/rdoc/0/store.rbs +2 -2
  302. data/stdlib/resolv/0/resolv.rbs +26 -69
  303. data/stdlib/ripper/0/ripper.rbs +25 -19
  304. data/stdlib/securerandom/0/manifest.yaml +2 -0
  305. data/stdlib/securerandom/0/securerandom.rbs +7 -20
  306. data/stdlib/shellwords/0/shellwords.rbs +3 -3
  307. data/stdlib/singleton/0/singleton.rbs +6 -0
  308. data/stdlib/socket/0/addrinfo.rbs +9 -9
  309. data/stdlib/socket/0/basic_socket.rbs +3 -3
  310. data/stdlib/socket/0/ip_socket.rbs +10 -8
  311. data/stdlib/socket/0/socket.rbs +23 -10
  312. data/stdlib/socket/0/tcp_server.rbs +1 -1
  313. data/stdlib/socket/0/tcp_socket.rbs +11 -3
  314. data/stdlib/socket/0/udp_socket.rbs +1 -1
  315. data/stdlib/socket/0/unix_server.rbs +1 -1
  316. data/stdlib/stringio/0/stringio.rbs +1211 -96
  317. data/stdlib/strscan/0/string_scanner.rbs +101 -80
  318. data/stdlib/tempfile/0/manifest.yaml +3 -0
  319. data/stdlib/tempfile/0/tempfile.rbs +25 -21
  320. data/stdlib/time/0/time.rbs +8 -6
  321. data/stdlib/timeout/0/timeout.rbs +58 -7
  322. data/stdlib/tsort/0/cyclic.rbs +4 -1
  323. data/stdlib/tsort/0/interfaces.rbs +8 -8
  324. data/stdlib/tsort/0/tsort.rbs +16 -15
  325. data/stdlib/uri/0/common.rbs +42 -20
  326. data/stdlib/uri/0/file.rbs +3 -3
  327. data/stdlib/uri/0/generic.rbs +21 -18
  328. data/stdlib/uri/0/http.rbs +2 -2
  329. data/stdlib/uri/0/ldap.rbs +2 -2
  330. data/stdlib/uri/0/mailto.rbs +3 -3
  331. data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
  332. data/stdlib/zlib/0/deflate.rbs +4 -3
  333. data/stdlib/zlib/0/gzip_file.rbs +1 -1
  334. data/stdlib/zlib/0/gzip_reader.rbs +8 -8
  335. data/stdlib/zlib/0/gzip_writer.rbs +16 -13
  336. data/stdlib/zlib/0/inflate.rbs +1 -1
  337. data/stdlib/zlib/0/need_dict.rbs +1 -1
  338. data/wasm/README.md +109 -0
  339. data/wasm/rbs_wasm.c +479 -0
  340. metadata +133 -19
  341. data/ext/rbs_extension/lexer.c +0 -2728
  342. data/ext/rbs_extension/lexer.h +0 -179
  343. data/ext/rbs_extension/lexer.re +0 -147
  344. data/ext/rbs_extension/lexstate.c +0 -175
  345. data/ext/rbs_extension/location.c +0 -325
  346. data/ext/rbs_extension/location.h +0 -85
  347. data/ext/rbs_extension/parser.c +0 -2982
  348. data/ext/rbs_extension/parser.h +0 -18
  349. data/ext/rbs_extension/parserstate.c +0 -411
  350. data/ext/rbs_extension/parserstate.h +0 -163
  351. data/ext/rbs_extension/unescape.c +0 -32
  352. data/include/rbs/ruby_objs.h +0 -72
  353. data/src/constants.c +0 -153
  354. data/src/ruby_objs.c +0 -799
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "serialization_schema"
4
+
5
+ module RBS
6
+ module WASM
7
+ # Rebuilds RBS::AST objects from the binary buffer produced by
8
+ # `rbs_serialize_node` (src/serialize.c), driven by the generated
9
+ # SerializationSchema. This is the pure-Ruby counterpart of the C extension's
10
+ # ast_translation.c, used when the parser runs inside WebAssembly (JRuby).
11
+ #
12
+ # All locations are reconstructed through the public RBS::Location API, so the
13
+ # same code works whether RBS::Location is backed by the C extension (CRuby)
14
+ # or by a pure-Ruby implementation (JRuby).
15
+ class Deserializer
16
+ # Deserialize a buffer produced for a whole signature, returning
17
+ # `[directives, declarations]` to match RBS::Parser._parse_signature.
18
+ def self.deserialize(bytes, buffer)
19
+ new(bytes, buffer).read_node
20
+ end
21
+
22
+ # Deserialize a bare node list (rbs_serialize_node_list), e.g. the result
23
+ # of RBS::Parser._parse_type_params.
24
+ def self.deserialize_node_list(bytes, buffer)
25
+ new(bytes, buffer).read_node_list
26
+ end
27
+
28
+ # Deserialize the token stream produced by rbs_wasm_lex into the
29
+ # [type, location] pairs RBS::Parser._lex returns.
30
+ def self.deserialize_tokens(bytes, buffer)
31
+ new(bytes, buffer).read_tokens
32
+ end
33
+
34
+ def initialize(bytes, buffer)
35
+ @bytes = bytes
36
+ @buffer = buffer
37
+ # Symbols and rbs_string fields (comments, annotations) inherit the
38
+ # source encoding, matching ast_translation.c. String/Integer literal
39
+ # nodes are always UTF-8 (see read_node).
40
+ @encoding = buffer.content.encoding
41
+ @pos = 0
42
+ @class_cache = {} #: Hash[String, untyped]
43
+ end
44
+
45
+ def read_node
46
+ tag = read_u8
47
+ return nil if tag == 0
48
+ return read_string(@encoding).to_sym if tag == SerializationSchema::SYMBOL_TAG
49
+
50
+ entry = SerializationSchema::SCHEMA[tag] or raise "Unknown node tag: #{tag}"
51
+
52
+ case entry[0]
53
+ when :node then read_struct(entry)
54
+ when :bool then read_u8 != 0
55
+ when :integer then read_string(Encoding::UTF_8).to_i
56
+ when :string_value then read_string(Encoding::UTF_8)
57
+ when :record_field then [read_node, read_u8 != 0]
58
+ when :signature then [read_node_list, read_node_list]
59
+ when :namespace then RBS::Namespace[read_node_list, read_u8 != 0]
60
+ when :type_name then RBS::TypeName[read_node, read_node]
61
+ else raise "Unknown schema entry kind: #{entry[0].inspect}"
62
+ end
63
+ end
64
+
65
+ def read_node_list
66
+ Array.new(read_count) { read_node }
67
+ end
68
+
69
+ # The lex stream has no leading count: read records until the buffer is
70
+ # exhausted. Each is a token type name followed by its character range.
71
+ def read_tokens
72
+ tokens = [] #: Array[[ Symbol, Location ]]
73
+ until @pos >= @bytes.bytesize
74
+ type = read_string(Encoding::UTF_8).to_sym
75
+ start_char = read_i32
76
+ end_char = read_i32
77
+ tokens << [type, RBS::Location.new(@buffer, start_char, end_char)]
78
+ end
79
+ tokens
80
+ end
81
+
82
+ private
83
+
84
+ def read_struct(entry)
85
+ _, class_name, expose_location, loc_children, fields, resolve_type_params = entry
86
+
87
+ location = read_location(loc_children) if expose_location
88
+
89
+ kwargs = {} #: Hash[Symbol, untyped]
90
+ (fields || []).each do |name, reader|
91
+ kwargs[name] = read_field(reader)
92
+ end
93
+
94
+ RBS::AST::TypeParam.resolve_variables(kwargs[:type_params]) if resolve_type_params
95
+
96
+ klass = class_for(class_name)
97
+ if expose_location
98
+ klass.new(location: location, **kwargs)
99
+ else
100
+ klass.new(**kwargs)
101
+ end
102
+ end
103
+
104
+ def read_field(reader)
105
+ case reader
106
+ when :node then read_node
107
+ when :node_list then read_node_list
108
+ when :hash then read_hash
109
+ when :string then read_string(@encoding)
110
+ when :bool then read_u8 != 0
111
+ when :location_range then read_location_value
112
+ when :location_range_list then read_location_value_list
113
+ when :attr_ivar_name then read_attr_ivar_name
114
+ else # [:enum, [value_or_nil, ...]]
115
+ reader[1][read_u8]
116
+ end
117
+ end
118
+
119
+ def read_hash
120
+ hash = {} #: Hash[untyped, untyped]
121
+ read_count.times do
122
+ key = read_node
123
+ hash[key] = read_node
124
+ end
125
+ hash
126
+ end
127
+
128
+ # A count of nested items. Each item is at least one byte, so a count that
129
+ # exceeds the bytes remaining signals the cursor has drifted out of sync.
130
+ def read_count
131
+ count = read_u32
132
+ if count > @bytes.bytesize - @pos
133
+ raise "Corrupt buffer: count #{count} exceeds #{@bytes.bytesize - @pos} remaining bytes at offset #{@pos}"
134
+ end
135
+ count
136
+ end
137
+
138
+ # The base location of a node, followed by its named child ranges.
139
+ def read_location(loc_children)
140
+ base = read_range
141
+ children = (loc_children || []).map { |name, required| [name, required, read_range] }
142
+
143
+ return nil unless base
144
+
145
+ location = RBS::Location.new(@buffer, base[0], base[1])
146
+ children.each do |name, required, range|
147
+ if required
148
+ location.add_required_child(name, range[0]...range[1]) if range
149
+ else
150
+ location.add_optional_child(name, range ? (range[0]...range[1]) : nil)
151
+ end
152
+ end
153
+ location
154
+ end
155
+
156
+ # A standalone location range field: nil or an RBS::Location without children.
157
+ def read_location_value
158
+ range = read_range
159
+ range && RBS::Location.new(@buffer, range[0], range[1])
160
+ end
161
+
162
+ def read_location_value_list
163
+ Array.new(read_count) { read_location_value }
164
+ end
165
+
166
+ def read_attr_ivar_name
167
+ case read_u8
168
+ when 0 then nil # inferred instance variable
169
+ when 1 then false # no instance variable
170
+ else read_string(@encoding).to_sym
171
+ end
172
+ end
173
+
174
+ # Reads a presence byte and, when present, the start/end character positions.
175
+ def read_range
176
+ return nil if read_u8 == 0
177
+
178
+ start_char = read_i32
179
+ end_char = read_i32
180
+ [start_char, end_char]
181
+ end
182
+
183
+ def read_u8
184
+ byte = @bytes.getbyte(@pos) or raise "Unexpected end of buffer"
185
+ @pos += 1
186
+ byte
187
+ end
188
+
189
+ def read_u32
190
+ value = @bytes.unpack1("L<", offset: @pos) #: Integer
191
+ @pos += 4
192
+ value
193
+ end
194
+
195
+ def read_i32
196
+ value = @bytes.unpack1("l<", offset: @pos) #: Integer
197
+ @pos += 4
198
+ value
199
+ end
200
+
201
+ def read_string(encoding)
202
+ length = read_u32
203
+ string = @bytes.byteslice(@pos, length) or raise "Unexpected end of buffer"
204
+ @pos += length
205
+ string.force_encoding(encoding)
206
+ end
207
+
208
+ def class_for(name)
209
+ @class_cache[name] ||= Object.const_get(name)
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ # Pure-Ruby implementation of the primitives that back RBS::Location.
5
+ #
6
+ # On CRuby these come from the C extension (ext/rbs_extension/legacy_location.c).
7
+ # JRuby loads this instead, before rbs/location_aux.rb layers the public API on
8
+ # top, so RBS::Location behaves identically without the native extension.
9
+ class Location
10
+ attr_reader :buffer
11
+
12
+ def initialize(buffer, start_pos, end_pos)
13
+ @buffer = buffer
14
+ @start_pos = start_pos
15
+ @end_pos = end_pos
16
+ @required_children = {} #: Hash[Symbol, [ Integer, Integer ]]
17
+ @optional_children = {} #: Hash[Symbol, [ Integer, Integer ]?]
18
+ end
19
+
20
+ def _start_pos
21
+ @start_pos
22
+ end
23
+
24
+ def _end_pos
25
+ @end_pos
26
+ end
27
+
28
+ def _add_required_child(name, start_pos, end_pos)
29
+ @required_children[name] = [start_pos, end_pos]
30
+ end
31
+
32
+ def _add_optional_child(name, start_pos, end_pos)
33
+ @optional_children[name] = [start_pos, end_pos]
34
+ end
35
+
36
+ def _add_optional_no_child(name)
37
+ @optional_children[name] = nil
38
+ end
39
+
40
+ def _required_keys
41
+ @required_children.keys
42
+ end
43
+
44
+ def _optional_keys
45
+ @optional_children.keys
46
+ end
47
+
48
+ def [](name)
49
+ if (range = @required_children[name])
50
+ return Location.new(@buffer, range[0], range[1])
51
+ end
52
+
53
+ if @optional_children.key?(name)
54
+ range = @optional_children[name]
55
+ return range && Location.new(@buffer, range[0], range[1])
56
+ end
57
+
58
+ raise "Unknown child name given: #{name}"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "runtime"
4
+ require_relative "deserializer"
5
+
6
+ module RBS
7
+ # WebAssembly-backed implementation of the parser primitives.
8
+ #
9
+ # On CRuby these come from the C extension (ext/rbs_extension/main.c). JRuby
10
+ # loads this instead: it runs the parser inside WebAssembly, then rebuilds the
11
+ # AST with RBS::WASM::Deserializer. rbs/parser_aux.rb layers the public
12
+ # RBS::Parser API on top, exactly as it does for the C extension.
13
+ class Parser
14
+ class << self
15
+ def _parse_signature(buffer, start_pos, end_pos, enable_forwarding_params)
16
+ validate_position_range(buffer, start_pos, end_pos)
17
+ validate_parser_options(enable_forwarding_params)
18
+ encoding = buffer.content.encoding.name
19
+ status, bytes = WASM::Runtime.instance.parse_signature(buffer.content, encoding, start_pos, end_pos)
20
+ raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
21
+
22
+ WASM::Deserializer.deserialize(bytes, buffer)
23
+ end
24
+
25
+ def _parse_type(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
26
+ validate_position_range(buffer, start_pos, end_pos)
27
+ validate_variables(variables)
28
+ encoding = buffer.content.encoding.name
29
+ status, bytes = WASM::Runtime.instance.parse_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
30
+ raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
31
+
32
+ deserialize_or_nil(bytes, buffer)
33
+ end
34
+
35
+ def _parse_method_type(buffer, start_pos, end_pos, variables, require_eof, enable_forwarding_params)
36
+ validate_position_range(buffer, start_pos, end_pos)
37
+ validate_variables(variables)
38
+ validate_parser_options(enable_forwarding_params)
39
+ encoding = buffer.content.encoding.name
40
+ status, bytes = WASM::Runtime.instance.parse_method_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof)
41
+ raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
42
+
43
+ deserialize_or_nil(bytes, buffer)
44
+ end
45
+
46
+ def _parse_type_params(buffer, start_pos, end_pos, module_type_params)
47
+ validate_position_range(buffer, start_pos, end_pos)
48
+ encoding = buffer.content.encoding.name
49
+ status, bytes = WASM::Runtime.instance.parse_type_params(buffer.content, encoding, start_pos, end_pos, module_type_params)
50
+ raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
51
+
52
+ bytes.empty? ? nil : WASM::Deserializer.deserialize_node_list(bytes, buffer)
53
+ end
54
+
55
+ def _lex(buffer, end_pos)
56
+ encoding = buffer.content.encoding.name
57
+ _status, bytes = WASM::Runtime.instance.lex(buffer.content, encoding, end_pos)
58
+
59
+ WASM::Deserializer.deserialize_tokens(bytes, buffer)
60
+ end
61
+
62
+ def _parse_inline_leading_annotation(buffer, start_pos, end_pos, variables)
63
+ validate_position_range(buffer, start_pos, end_pos)
64
+ validate_variables(variables)
65
+ encoding = buffer.content.encoding.name
66
+ status, bytes = WASM::Runtime.instance.parse_inline_leading_annotation(buffer.content, encoding, start_pos, end_pos, variables)
67
+ raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
68
+
69
+ deserialize_or_nil(bytes, buffer)
70
+ end
71
+
72
+ def _parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables)
73
+ validate_position_range(buffer, start_pos, end_pos)
74
+ validate_variables(variables)
75
+ encoding = buffer.content.encoding.name
76
+ status, bytes = WASM::Runtime.instance.parse_inline_trailing_annotation(buffer.content, encoding, start_pos, end_pos, variables)
77
+ raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
78
+
79
+ deserialize_or_nil(bytes, buffer)
80
+ end
81
+
82
+ private
83
+
84
+ # Reject the position ranges the parser cannot take, matching
85
+ # validate_position_range in the C extension (main.c).
86
+ #
87
+ # `end_pos` past the end of the buffer is fine: clamping with a large
88
+ # number instead of measuring the buffer is ordinary, and the lexer stops
89
+ # at the end of the input on its own.
90
+ def validate_position_range(buffer, start_pos, end_pos)
91
+ if start_pos < 0 || end_pos < 0
92
+ raise ArgumentError, "negative position range: #{start_pos}...#{end_pos}"
93
+ end
94
+ if start_pos > end_pos
95
+ raise ArgumentError, "invalid position range: #{start_pos}...#{end_pos}"
96
+ end
97
+
98
+ size = buffer.content.bytesize
99
+ if start_pos > size
100
+ raise ArgumentError, "position range starts past the end of the buffer: #{start_pos}...#{end_pos}, buffer is #{size} bytes"
101
+ end
102
+ end
103
+
104
+ # The WebAssembly entry points (rbs_wasm.c) build their parsers with the
105
+ # default options, so the optional syntax the C extension can enable is
106
+ # not reachable here. The public RBS::Parser API never enables it.
107
+ def validate_parser_options(enable_forwarding_params)
108
+ if enable_forwarding_params
109
+ raise NotImplementedError, "forwarding parameter syntax is not supported by the WebAssembly parser"
110
+ end
111
+ end
112
+
113
+ # Reject anything that is not nil or an Array of Symbols, matching
114
+ # declare_type_variables in the C extension (main.c).
115
+ def validate_variables(variables)
116
+ return if variables.nil?
117
+
118
+ unless variables.is_a?(Array)
119
+ raise TypeError, "wrong argument type #{variables.class} (must be an Array of Symbols or nil)"
120
+ end
121
+
122
+ variables.each do |variable|
123
+ unless variable.is_a?(Symbol)
124
+ raise TypeError, "Type variables Array contains invalid value #{variable.inspect} of type #{variable.class} (must be an Array of Symbols or nil)"
125
+ end
126
+ end
127
+ end
128
+
129
+ # An empty result means the parser reached EOF immediately (`nil`).
130
+ def deserialize_or_nil(bytes, buffer)
131
+ bytes.empty? ? nil : WASM::Deserializer.deserialize(bytes, buffer)
132
+ end
133
+
134
+ # Raise for a status other than OK (see rbs_wasm.c).
135
+ #
136
+ # A negative status is about the range rather than the source text, so it
137
+ # comes with an empty result and an ArgumentError, as in the C extension
138
+ # (main.c). Starting past the end of the buffer is plain from the
139
+ # buffer's size and rejected above, so a start position that comes back
140
+ # rejected can only be one inside a character.
141
+ def raise_parse_failure(buffer, status, bytes, start_pos, end_pos)
142
+ case status
143
+ when WASM::Runtime::INVALID_START_POS
144
+ raise ArgumentError, "position range starts inside a character: #{start_pos}...#{end_pos}"
145
+ when WASM::Runtime::INVALID_RANGE
146
+ raise ArgumentError, "invalid position range: #{start_pos}...#{end_pos}"
147
+ else
148
+ raise_parsing_error(buffer, bytes)
149
+ end
150
+ end
151
+
152
+ # Decodes the error blob written by set_error_result (rbs_wasm.c) and raises
153
+ # the same error the C extension would (see raise_error in main.c).
154
+ def raise_parsing_error(buffer, blob)
155
+ start_char, end_char, syntax_error = blob.unpack("l<l<C")
156
+
157
+ raise "Unexpected error" if syntax_error.zero?
158
+
159
+ offset = 9
160
+ token_type_length = blob.unpack1("L<", offset: offset)
161
+ offset += 4
162
+ token_type = blob.byteslice(offset, token_type_length).to_s.force_encoding(Encoding::UTF_8)
163
+ offset += token_type_length
164
+
165
+ message_length = blob.unpack1("L<", offset: offset)
166
+ offset += 4
167
+ message = blob.byteslice(offset, message_length).to_s.force_encoding(Encoding::UTF_8)
168
+
169
+ location = Location.new(buffer, start_char, end_char)
170
+ raise ParsingError.new(location, message, token_type)
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "java"
4
+ require "monitor"
5
+
6
+ module RBS
7
+ module WASM
8
+ # Loads rbs_parser.wasm into a JVM WebAssembly runtime (Chicory) and drives
9
+ # it. This is the JRuby counterpart of the C extension's main.c: it copies a
10
+ # source string into the module's linear memory, runs the parser, and returns
11
+ # the serialized result for RBS::WASM::Deserializer to rebuild.
12
+ #
13
+ # Chicory is a pure-Java runtime, so there is no native dependency. The
14
+ # `.wasm` ships in the gem; the Chicory jars are fetched from Maven by
15
+ # jar-dependencies (see lib/rbs_jars.rb and rbs.gemspec).
16
+ class Runtime
17
+ include MonitorMixin
18
+
19
+ # Statuses the parse entry points return (see rbs_wasm.c). A negative one
20
+ # is about the range the caller asked for rather than the source text,
21
+ # and comes with an empty result.
22
+ INVALID_START_POS = -2
23
+ INVALID_RANGE = -1
24
+ PARSE_ERROR = 0
25
+ OK = 1
26
+
27
+ class << self
28
+ def instance
29
+ @instance ||= new
30
+ end
31
+
32
+ def wasm_path
33
+ ENV["RBS_WASM_PARSER"] || File.expand_path("rbs_parser.wasm", __dir__)
34
+ end
35
+ end
36
+
37
+ def initialize
38
+ super()
39
+ # rbs_jars.rb require_jars the Chicory/ASM jars from the local Maven
40
+ # repository (~/.m2), where jar-dependencies puts them at gem install (or
41
+ # `rake wasm:install_jars` when running from source).
42
+ require "rbs_jars"
43
+ @wasm = build_instance
44
+ @memory = @wasm.memory
45
+ @alloc = @wasm.export("rbs_wasm_alloc")
46
+ @free = @wasm.export("rbs_wasm_free")
47
+ @result_ptr = @wasm.export("rbs_wasm_result_ptr")
48
+ @result_len = @wasm.export("rbs_wasm_result_len")
49
+ @parse_signature = @wasm.export("rbs_wasm_parse_signature")
50
+ @parse_type = @wasm.export("rbs_wasm_parse_type")
51
+ @parse_method_type = @wasm.export("rbs_wasm_parse_method_type")
52
+ @parse_type_params = @wasm.export("rbs_wasm_parse_type_params")
53
+ @parse_inline_leading_annotation = @wasm.export("rbs_wasm_parse_inline_leading_annotation")
54
+ @parse_inline_trailing_annotation = @wasm.export("rbs_wasm_parse_inline_trailing_annotation")
55
+ @lex = @wasm.export("rbs_wasm_lex")
56
+ end
57
+
58
+ # `content` is the whole buffer; `start_pos`/`end_pos` are the character
59
+ # range within it to parse. Each method returns [status, bytes]: with OK
60
+ # `bytes` is the serialized AST, with PARSE_ERROR it is the error blob (see
61
+ # set_error_result in rbs_wasm.c), and with a negative status it is empty.
62
+
63
+ def parse_signature(content, encoding, start_pos, end_pos)
64
+ run(content, encoding) { |ptr, len, enc_ptr, enc_len| @parse_signature.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos)[0] }
65
+ end
66
+
67
+ def parse_type(content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
68
+ with_variables(variables) do |vars_ptr, vars_len|
69
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
70
+ @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]
71
+ end
72
+ end
73
+ end
74
+
75
+ def parse_method_type(content, encoding, start_pos, end_pos, variables, require_eof)
76
+ with_variables(variables) do |vars_ptr, vars_len|
77
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
78
+ @parse_method_type.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len, bool(require_eof))[0]
79
+ end
80
+ end
81
+ end
82
+
83
+ def parse_type_params(content, encoding, start_pos, end_pos, module_type_params)
84
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
85
+ @parse_type_params.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, bool(module_type_params))[0]
86
+ end
87
+ end
88
+
89
+ def parse_inline_leading_annotation(content, encoding, start_pos, end_pos, variables)
90
+ with_variables(variables) do |vars_ptr, vars_len|
91
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
92
+ @parse_inline_leading_annotation.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len)[0]
93
+ end
94
+ end
95
+ end
96
+
97
+ def parse_inline_trailing_annotation(content, encoding, start_pos, end_pos, variables)
98
+ with_variables(variables) do |vars_ptr, vars_len|
99
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
100
+ @parse_inline_trailing_annotation.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len)[0]
101
+ end
102
+ end
103
+ end
104
+
105
+ def lex(content, encoding, end_pos)
106
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
107
+ @lex.apply(ptr, len, enc_ptr, enc_len, end_pos)[0]
108
+ end
109
+ end
110
+
111
+ private
112
+
113
+ # Copies `source` and its encoding name into linear memory, yields their
114
+ # pointers/lengths to the block (which invokes the parser and returns its
115
+ # status), then reads the result back out. Serialized through the monitor
116
+ # because the module keeps its result in a single shared location.
117
+ def run(source, encoding)
118
+ synchronize do
119
+ bytes = source.b
120
+ length = bytes.bytesize
121
+ name = encoding.to_s.b
122
+ name_length = name.bytesize
123
+ source_ptr = @alloc.apply(length)[0]
124
+ name_ptr = @alloc.apply(name_length)[0]
125
+ begin
126
+ @memory.write(source_ptr, bytes.to_java_bytes)
127
+ @memory.write(name_ptr, name.to_java_bytes) unless name_length.zero?
128
+ status = yield(source_ptr, length, name_ptr, name_length)
129
+ [i32(status), read_result]
130
+ ensure
131
+ @free.apply(source_ptr)
132
+ @free.apply(name_ptr)
133
+ end
134
+ end
135
+ end
136
+
137
+ def read_result
138
+ pointer = @result_ptr.apply[0]
139
+ length = @result_len.apply[0]
140
+ return "".b if length.zero?
141
+
142
+ String.from_java_bytes(@memory.read_bytes(pointer, length)).b
143
+ end
144
+
145
+ # Allocates a buffer of newline-separated variable names and yields its
146
+ # pointer/length. A nil `variables` is passed as length -1 ("no variables").
147
+ def with_variables(variables)
148
+ names = variables&.map(&:to_s)&.join("\n")
149
+
150
+ if names.nil? || names.empty?
151
+ return yield(0, variables.nil? ? -1 : 0)
152
+ end
153
+
154
+ bytes = names.b
155
+ length = bytes.bytesize
156
+ synchronize do
157
+ pointer = @alloc.apply(length)[0]
158
+ begin
159
+ @memory.write(pointer, bytes.to_java_bytes)
160
+ yield(pointer, length)
161
+ ensure
162
+ @free.apply(pointer)
163
+ end
164
+ end
165
+ end
166
+
167
+ # A WebAssembly i32 comes back in a JVM long, so read the low 32 bits as
168
+ # signed: the negative statuses have to stay negative on this side.
169
+ def i32(value)
170
+ value &= 0xFFFF_FFFF
171
+ value >= 0x8000_0000 ? value - 0x1_0000_0000 : value
172
+ end
173
+
174
+ def bool(value)
175
+ value ? 1 : 0
176
+ end
177
+
178
+ def build_instance
179
+ parser = Java::ComDylibsoChicoryWasm::Parser
180
+ instance_class = Java::ComDylibsoChicoryRuntime::Instance
181
+ import_values = Java::ComDylibsoChicoryRuntime::ImportValues
182
+ wasi_preview1 = Java::ComDylibsoChicoryWasi::WasiPreview1
183
+ wasi_options = Java::ComDylibsoChicoryWasi::WasiOptions
184
+
185
+ wasm_module = parser.parse(java.io.File.new(self.class.wasm_path))
186
+ wasi = wasi_preview1.builder.with_options(wasi_options.builder.build).build
187
+ imports = import_values.builder.add_function(wasi.to_host_functions).build
188
+
189
+ builder = instance_class.builder(wasm_module).with_import_values(imports)
190
+ if (factory = machine_factory(wasm_module))
191
+ builder = builder.with_machine_factory(factory)
192
+ end
193
+
194
+ wasm = builder.build
195
+ wasm.export("_initialize").apply
196
+ wasm
197
+ end
198
+
199
+ # Chicory's AOT compiler when its jars are present and usable, otherwise nil
200
+ # (the builder then uses the interpreter). NameError covers a missing
201
+ # compiler class; LinkageError covers an incompatible/missing ASM (so a bad
202
+ # jar set degrades to the interpreter instead of crashing).
203
+ def machine_factory(wasm_module)
204
+ Java::ComDylibsoChicoryCompiler::MachineFactoryCompiler.compile(wasm_module)
205
+ rescue NameError, Java::JavaLang::LinkageError
206
+ nil
207
+ end
208
+
209
+ end
210
+ end
211
+ end