herb 0.11.0-x86-linux-gnu → 0.11.2-x86-linux-gnu

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 (273) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -2
  3. data/config.yml +9 -0
  4. data/ext/herb/extconf.rb +8 -31
  5. data/ext/herb/nodes.c +90 -73
  6. data/ext/herb/parser_options_helpers.c +26 -0
  7. data/lib/herb/3.2/herb.so +0 -0
  8. data/lib/herb/3.3/herb.so +0 -0
  9. data/lib/herb/3.4/herb.so +0 -0
  10. data/lib/herb/4.0/herb.so +0 -0
  11. data/lib/herb/analysis/partial_index.rb +1 -1
  12. data/lib/herb/analysis/partial_resolution.rb +27 -0
  13. data/lib/herb/ast/helpers.rb +1 -1
  14. data/lib/herb/ast/nodes.rb +32 -6
  15. data/lib/herb/bootstrap.rb +6 -2
  16. data/lib/herb/configuration.rb +11 -1
  17. data/lib/herb/dev/classifier.rb +1 -1
  18. data/lib/herb/dev/runner.rb +6 -1
  19. data/lib/herb/engine/compiler.rb +52 -19
  20. data/lib/herb/engine/slots/dynamics_compiler.rb +63 -14
  21. data/lib/herb/engine/slots/markers.rb +24 -0
  22. data/lib/herb/engine/slots/state_compiler.rb +1 -2
  23. data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
  24. data/lib/herb/engine/slots/visitor.rb +71 -32
  25. data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
  26. data/lib/herb/engine.rb +0 -2
  27. data/lib/herb/parser_options.rb +6 -3
  28. data/lib/herb/project.rb +19 -8
  29. data/lib/herb/version.rb +1 -1
  30. data/lib/herb.rb +1 -1
  31. data/sig/herb/analysis/partial_resolution.rbs +8 -0
  32. data/sig/herb/ast/nodes.rbs +10 -4
  33. data/sig/herb/bootstrap.rbs +2 -0
  34. data/sig/herb/configuration.rbs +3 -0
  35. data/sig/herb/dev/runner.rbs +3 -0
  36. data/sig/herb/engine/compiler.rbs +14 -3
  37. data/sig/herb/engine/slots/dynamics_compiler.rbs +27 -7
  38. data/sig/herb/engine/slots/markers.rbs +14 -0
  39. data/sig/herb/engine/slots/visitor.rbs +31 -13
  40. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
  41. data/sig/herb/parser_options.rbs +6 -4
  42. data/sig/herb.rbs +2 -2
  43. data/sig/serialized_ast_nodes.rbs +1 -0
  44. data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
  45. data/src/analyze/action_view/generated_handlers.c +36 -36
  46. data/src/analyze/action_view/image_tag.c +7 -3
  47. data/src/analyze/action_view/javascript_include_tag.c +6 -3
  48. data/src/analyze/action_view/link_to.c +23 -23
  49. data/src/analyze/action_view/registry.c +7 -3
  50. data/src/analyze/action_view/tag_helper_node_builders.c +12 -16
  51. data/src/analyze/action_view/tag_helpers.c +215 -110
  52. data/src/analyze/action_view/turbo_frame_tag.c +5 -4
  53. data/src/analyze/analyze.c +41 -45
  54. data/src/analyze/analyze_helpers.c +240 -405
  55. data/src/analyze/analyzed_ruby.c +10 -7
  56. data/src/analyze/builders.c +1 -0
  57. data/src/analyze/control_type.c +46 -29
  58. data/src/analyze/herb_directives.c +16 -20
  59. data/src/analyze/iteration_nodes.c +69 -24
  60. data/src/analyze/parse_errors.c +32 -22
  61. data/src/analyze/postfix_conditionals.c +23 -13
  62. data/src/analyze/prism_annotate.c +56 -32
  63. data/src/analyze/render_nodes.c +51 -41
  64. data/src/analyze/strict_locals.c +14 -15
  65. data/src/analyze/ternary_conditionals.c +14 -10
  66. data/src/ast/ast_nodes.c +3 -1
  67. data/src/ast/ast_pretty_print.c +5 -1
  68. data/src/extract.c +204 -143
  69. data/src/herb.c +10 -8
  70. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  71. data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
  72. data/src/include/analyze/action_view/tag_helpers.h +1 -1
  73. data/src/include/analyze/analyze.h +3 -24
  74. data/src/include/analyze/analyzed_ruby.h +29 -2
  75. data/src/include/analyze/helpers.h +7 -27
  76. data/src/include/ast/ast_nodes.h +2 -1
  77. data/src/include/herb.h +3 -2
  78. data/src/include/lexer/lexer.h +1 -0
  79. data/src/include/parser/parser_options.h +5 -0
  80. data/src/include/prism/herb_prism_node.h +6 -1
  81. data/src/include/prism/prism_context.h +12 -12
  82. data/src/include/prism/prism_helpers.h +30 -0
  83. data/src/include/prism_version.h +11 -0
  84. data/src/include/version.h +1 -1
  85. data/src/lexer.c +32 -0
  86. data/src/parser/parser_helpers.c +1 -2
  87. data/src/parser.c +6 -7
  88. data/src/parser_options_defaults.c +1 -0
  89. data/src/prism/prism_helpers.c +167 -42
  90. data/src/prism/ruby_parser.c +20 -20
  91. data/templates/ext/herb/nodes.c.erb +5 -5
  92. data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
  93. data/templates/java/nodes.c.erb +6 -6
  94. data/templates/java/parser_options_helpers.c.erb +41 -2
  95. data/templates/java/parser_options_helpers.h.erb +2 -1
  96. data/templates/javascript/packages/core/src/nodes.ts.erb +21 -1
  97. data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
  98. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
  99. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
  100. data/templates/lib/herb/parser_options.rb.erb +1 -1
  101. data/templates/rust/src/ast/nodes.rs.erb +1 -4
  102. data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
  103. data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
  104. data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
  105. data/templates/src/include/parser/parser_options.h.erb +10 -0
  106. data/templates/src/include/prism_version.h.erb +17 -0
  107. data/templates/src/parser_options_defaults.c.erb +1 -1
  108. data/templates/template.rb +17 -2
  109. data/templates/wasm/nodes.cpp.erb +8 -18
  110. data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
  111. data/vendor/prism/Rakefile +76 -7
  112. data/vendor/prism/config.yml +174 -161
  113. data/vendor/prism/include/prism/arena.h +45 -0
  114. data/vendor/prism/include/prism/arena.hpp +42 -0
  115. data/vendor/prism/include/prism/ast.h +2738 -611
  116. data/vendor/prism/include/prism/ast.hpp +641 -0
  117. data/vendor/prism/include/prism/buffer.h +60 -0
  118. data/vendor/prism/include/prism/buffer.hpp +55 -0
  119. data/vendor/prism/include/prism/comments.h +72 -0
  120. data/vendor/prism/include/prism/compiler/accel.h +26 -0
  121. data/vendor/prism/include/prism/compiler/align.h +36 -0
  122. data/vendor/prism/include/prism/compiler/assume.h +25 -0
  123. data/vendor/prism/include/prism/compiler/branch.h +26 -0
  124. data/vendor/prism/include/prism/compiler/bswap.h +46 -0
  125. data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
  126. data/vendor/prism/include/prism/compiler/endianness.h +34 -0
  127. data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
  128. data/vendor/prism/include/prism/compiler/exported.h +24 -0
  129. data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
  130. data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
  131. data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
  132. data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
  133. data/vendor/prism/include/prism/compiler/format.h +27 -0
  134. data/vendor/prism/include/prism/compiler/inline.h +17 -0
  135. data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
  136. data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
  137. data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
  138. data/vendor/prism/include/prism/compiler/unused.h +18 -0
  139. data/vendor/prism/include/prism/constant_pool.h +106 -0
  140. data/vendor/prism/include/prism/diagnostic.h +55 -402
  141. data/vendor/prism/include/prism/errors_format.h +61 -0
  142. data/vendor/prism/include/prism/excludes.h +29 -0
  143. data/vendor/prism/include/prism/integer.h +41 -0
  144. data/vendor/prism/include/prism/internal/allocator.h +68 -0
  145. data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
  146. data/vendor/prism/include/prism/internal/arena.h +108 -0
  147. data/vendor/prism/include/prism/internal/bit.h +42 -0
  148. data/vendor/prism/include/prism/internal/buffer.h +94 -0
  149. data/vendor/prism/include/prism/internal/char.h +145 -0
  150. data/vendor/prism/include/prism/internal/comments.h +54 -0
  151. data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
  152. data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
  153. data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
  154. data/vendor/prism/include/prism/internal/integer.h +68 -0
  155. data/vendor/prism/include/prism/internal/isinf.h +16 -0
  156. data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
  157. data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  158. data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
  159. data/vendor/prism/include/prism/internal/memchr.h +15 -0
  160. data/vendor/prism/include/prism/internal/node.h +42 -0
  161. data/vendor/prism/include/prism/internal/options.h +232 -0
  162. data/vendor/prism/include/prism/internal/parser.h +1015 -0
  163. data/vendor/prism/include/prism/internal/regexp.h +26 -0
  164. data/vendor/prism/include/prism/internal/serialize.h +39 -0
  165. data/vendor/prism/include/prism/internal/source.h +72 -0
  166. data/vendor/prism/include/prism/internal/static_literals.h +60 -0
  167. data/vendor/prism/include/prism/internal/stringy.h +30 -0
  168. data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  169. data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  170. data/vendor/prism/include/prism/internal/tokens.h +11 -0
  171. data/vendor/prism/include/prism/internal/xxh3.h +16 -0
  172. data/vendor/prism/include/prism/json.h +40 -0
  173. data/vendor/prism/include/prism/line_offset_list.h +69 -0
  174. data/vendor/prism/include/prism/magic_comments.h +53 -0
  175. data/vendor/prism/include/prism/node.h +59 -49
  176. data/vendor/prism/include/prism/node.hpp +272 -0
  177. data/vendor/prism/include/prism/node_type.hpp +38 -0
  178. data/vendor/prism/include/prism/options.h +154 -279
  179. data/vendor/prism/include/prism/options.hpp +43 -0
  180. data/vendor/prism/include/prism/parser.h +367 -870
  181. data/vendor/prism/include/prism/parser.hpp +274 -0
  182. data/vendor/prism/include/prism/prettyprint.h +14 -9
  183. data/vendor/prism/include/prism/serialize.h +123 -0
  184. data/vendor/prism/include/prism/source.h +163 -0
  185. data/vendor/prism/include/prism/stream.h +36 -0
  186. data/vendor/prism/include/prism/string_query.h +82 -0
  187. data/vendor/prism/include/prism/stringy.h +61 -0
  188. data/vendor/prism/include/prism/stringy.hpp +31 -0
  189. data/vendor/prism/include/prism/version.h +20 -3
  190. data/vendor/prism/include/prism.h +35 -320
  191. data/vendor/prism/include/prism.hpp +24 -0
  192. data/vendor/prism/src/arena.c +122 -0
  193. data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
  194. data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
  195. data/vendor/prism/src/comments.c +455 -0
  196. data/vendor/prism/src/constant_pool.c +406 -0
  197. data/vendor/prism/src/diagnostic.c +120 -68
  198. data/vendor/prism/src/encoding.c +8 -3
  199. data/vendor/prism/src/errors_format.c +519 -0
  200. data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
  201. data/vendor/prism/src/json.c +5733 -0
  202. data/vendor/prism/src/line_offset_list.c +100 -0
  203. data/vendor/prism/src/list.c +24 -0
  204. data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
  205. data/vendor/prism/src/node.c +3465 -7787
  206. data/vendor/prism/src/options.c +161 -54
  207. data/vendor/prism/src/parser.c +371 -0
  208. data/vendor/prism/src/prettyprint.c +421 -354
  209. data/vendor/prism/src/prism.c +8522 -7280
  210. data/vendor/prism/src/regexp.c +960 -45
  211. data/vendor/prism/src/serialize.c +2434 -2048
  212. data/vendor/prism/src/source.c +524 -0
  213. data/vendor/prism/src/static_literals.c +303 -360
  214. data/vendor/prism/src/string_query.c +180 -0
  215. data/vendor/prism/src/stringy.c +61 -0
  216. data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  217. data/vendor/prism/src/strpbrk.c +447 -0
  218. data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
  219. data/vendor/prism/src/xxh3.c +292 -0
  220. data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
  221. data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
  222. data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
  223. data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
  224. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
  225. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
  226. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
  227. data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
  228. data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
  229. data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
  230. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
  231. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
  232. data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
  233. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
  234. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
  235. data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
  236. data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
  237. data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
  238. data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
  239. data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
  240. data/vendor/prism/templates/src/json.c.erb +130 -0
  241. data/vendor/prism/templates/src/node.c.erb +79 -236
  242. data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
  243. data/vendor/prism/templates/src/serialize.c.erb +369 -183
  244. data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
  245. data/vendor/prism/templates/template.rb +193 -91
  246. metadata +100 -42
  247. data/vendor/prism/include/prism/defines.h +0 -260
  248. data/vendor/prism/include/prism/pack.h +0 -163
  249. data/vendor/prism/include/prism/regexp.h +0 -43
  250. data/vendor/prism/include/prism/static_literals.h +0 -121
  251. data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
  252. data/vendor/prism/include/prism/util/pm_char.h +0 -204
  253. data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
  254. data/vendor/prism/include/prism/util/pm_integer.h +0 -130
  255. data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
  256. data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
  257. data/vendor/prism/include/prism/util/pm_string.h +0 -200
  258. data/vendor/prism/src/pack.c +0 -509
  259. data/vendor/prism/src/util/pm_constant_pool.c +0 -342
  260. data/vendor/prism/src/util/pm_list.c +0 -49
  261. data/vendor/prism/src/util/pm_newline_list.c +0 -125
  262. data/vendor/prism/src/util/pm_string.c +0 -381
  263. data/vendor/prism/src/util/pm_strpbrk.c +0 -206
  264. data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
  265. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
  266. data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
  267. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
  268. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
  269. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
  270. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
  271. data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
  272. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
  273. data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
@@ -1,10 +1,13 @@
1
1
  #include "parser_options_helpers.h"
2
2
 
3
- void herb_extract_parser_options(napi_env env, napi_value options, parser_options_T* parser_options) {
3
+ #include <cstring>
4
+ #include <string>
5
+
6
+ bool herb_extract_parser_options(napi_env env, napi_value options, parser_options_T* parser_options) {
4
7
  napi_valuetype valuetype;
5
8
  napi_typeof(env, options, &valuetype);
6
9
 
7
- if (valuetype != napi_object) { return; }
10
+ if (valuetype != napi_object) { return true; }
8
11
  <%- parser_options.extractable_fields_for(:javascript).each do |field| -%>
9
12
 
10
13
  {
@@ -19,6 +22,33 @@ void herb_extract_parser_options(napi_env env, napi_value options, parser_option
19
22
  bool value = false;
20
23
  napi_get_value_bool(env, property, &value);
21
24
  parser_options-><%= field.c_name %> = value;
25
+ <%- elsif field.string? -%>
26
+ napi_valuetype property_type;
27
+ napi_typeof(env, property, &property_type);
28
+
29
+ if (property_type == napi_string) {
30
+ size_t length = 0;
31
+ napi_get_value_string_utf8(env, property, nullptr, 0, &length);
32
+
33
+ std::string value(length, '\0');
34
+ napi_get_value_string_utf8(env, property, &value[0], length + 1, &length);
35
+ value.resize(length);
36
+
37
+ <%- if field.validator -%>
38
+ if (!<%= field.validator %>(value.c_str(), value.length())) {
39
+ std::string message = "<%= field.snake_case %> \"" + value + "\" is not supported";
40
+ napi_throw_error(env, nullptr, message.c_str());
41
+ return false;
42
+ }
43
+ <%- else -%>
44
+ if (value.length() >= HERB_PARSER_OPTIONS_STRING_CAPACITY) {
45
+ napi_throw_error(env, nullptr, "<%= field.snake_case %> is too long");
46
+ return false;
47
+ }
48
+ <%- end -%>
49
+
50
+ memcpy(parser_options-><%= field.c_name %>, value.c_str(), value.length() + 1);
51
+ }
22
52
  <%- elsif field.nullable? -%>
23
53
  napi_valuetype property_type;
24
54
  napi_typeof(env, property, &property_type);
@@ -38,4 +68,6 @@ void herb_extract_parser_options(napi_env env, napi_value options, parser_option
38
68
  }
39
69
  }
40
70
  <%- end -%>
71
+
72
+ return true;
41
73
  }
@@ -7,6 +7,6 @@ extern "C" {
7
7
  #include "../extension/libherb/include/parser/parser_options.h"
8
8
  }
9
9
 
10
- void herb_extract_parser_options(napi_env env, napi_value options, parser_options_T* parser_options);
10
+ bool herb_extract_parser_options(napi_env env, napi_value options, parser_options_T* parser_options);
11
11
 
12
12
  #endif
@@ -15,7 +15,7 @@ module Herb
15
15
  <%- end -%>
16
16
  end
17
17
 
18
- #: () -> Hash[Symbol, (bool | Numeric | Array[String] | nil)]
18
+ #: () -> Hash[Symbol, (bool | Numeric | String | Array[String] | nil)]
19
19
  def to_h
20
20
  {
21
21
  <%- parser_options.fields_for(:ruby).each do |field| -%>
@@ -233,10 +233,7 @@ pub(crate) unsafe fn convert_node(node_pointer: *const c_void, source: &std::syn
233
233
  Some(std::slice::from_raw_parts((*c_node_pointer).<%= field.name %>.data, (*c_node_pointer).<%= field.name %>.length).to_vec())
234
234
  },
235
235
  <%- when Herb::Template::PrismNodeField -%>
236
- <%= field.name %>: crate::prism::serialize(
237
- (*c_node_pointer).<%= field.name %>.node,
238
- (*c_node_pointer).<%= field.name %>.parser,
239
- ),
236
+ <%= field.name %>: crate::prism::serialize((*c_node_pointer).<%= field.name %>),
240
237
  source: Some(std::sync::Arc::clone(source)),
241
238
  #[cfg(feature = "prism")]
242
239
  prism_cache: std::sync::OnceLock::new(),
@@ -1,55 +1,21 @@
1
- fn read_node_body(buffer: &mut SerializationBuffer, type_id: u8, pool: usize, node: &mut PrismNode) {
1
+ fn read_node_body(
2
+ buffer: &mut SerializationBuffer,
3
+ type_id: u8,
4
+ pool: usize,
5
+ node: &mut PrismNode,
6
+ stack: &mut Vec<Option<PrismNode>>,
7
+ ) {
2
8
  match type_id {
3
9
  <%- prism_nodes.each do |prism_node| -%>
4
10
  <%= prism_node.type_id %> => {
5
- <%- if prism_node.name == "DefNode" -%>
6
- buffer.read_uint32();
7
- <%- end -%>
8
-
9
11
  let flags = buffer.read_var_int() as u32;
10
12
  node.flags = flags;
11
13
 
12
14
  <%- prism_node.fields.each do |field| -%>
13
15
  <%- case field.type -%>
14
- <%- when "node" -%>
15
- {
16
- let child = read_node(buffer, pool);
17
- node.children.push(child);
18
- }
19
-
20
- <%- if field.name == "receiver" -%>
21
- node.receiver_index = Some(node.children.len() - 1);
22
- <%- elsif prism_node.name == "AssocNode" && field.name == "key" -%>
23
- node.key = Some(Box::new(node.children[node.children.len() - 1].clone()));
24
- <%- end -%>
25
-
26
- <%- when "node?" -%>
27
- if buffer.peek_byte() != 0 {
28
- let child = read_node(buffer, pool);
29
- node.children.push(child);
30
- <%- if field.name == "block" -%>
31
- node.has_block = true;
32
- <%- end -%>
33
-
34
- <%- if field.name == "receiver" -%>
35
- node.receiver_index = Some(node.children.len() - 1);
36
- <%- elsif prism_node.name == "AssocNode" && field.name == "key" -%>
37
- node.key = Some(Box::new(node.children[node.children.len() - 1].clone()));
38
- <%- end -%>
39
-
40
- } else {
41
- buffer.read_byte();
42
- }
43
- <%- when "node[]" -%>
44
- {
45
- let count = buffer.read_var_int();
46
-
47
- for _ in 0..count {
48
- let child = read_node(buffer, pool);
49
- node.children.push(child);
50
- }
51
- }
52
-
16
+ <%- when "node", "node?" -%>
17
+ <%- when "node[]" -%>
18
+ let <%= field.name %>_count = buffer.read_var_int();
53
19
  <%- when "string" -%>
54
20
  <%- if field.name == "unescaped" -%>
55
21
  node.unescaped = Some(buffer.read_string_field(flags));
@@ -93,12 +59,92 @@ fn read_node_body(buffer: &mut SerializationBuffer, type_id: u8, pool: usize, no
93
59
  <%- raise "unhandled prism field type: #{field.type}" -%>
94
60
  <%- end -%>
95
61
  <%- end -%>
62
+
63
+ <%- prism_node.fields.reverse.each do |field| -%>
64
+ <%- case field.type -%>
65
+ <%- when "node", "node?" -%>
66
+ let <%= field.name %>_child = stack.pop().flatten();
67
+ <%- when "node[]" -%>
68
+ let <%= field.name %>_children = stack.split_off(stack.len().saturating_sub(<%= field.name %>_count));
69
+ <%- end -%>
70
+ <%- end -%>
71
+
72
+ <%- prism_node.fields.each do |field| -%>
73
+ <%- case field.type -%>
74
+ <%- when "node", "node?" -%>
75
+ if let Some(child) = <%= field.name %>_child {
76
+ node.children.push(child);
77
+ <%- if field.name == "block" && field.type == "node?" -%>
78
+ node.has_block = true;
79
+ <%- end -%>
80
+ <%- if field.name == "receiver" -%>
81
+ node.receiver_index = Some(node.children.len() - 1);
82
+ <%- elsif prism_node.name == "AssocNode" && field.name == "key" -%>
83
+ node.key = Some(Box::new(node.children[node.children.len() - 1].clone()));
84
+ <%- end -%>
85
+ }
86
+
87
+ <%- when "node[]" -%>
88
+ node.children.extend(<%= field.name %>_children.into_iter().flatten());
89
+
90
+ <%- end -%>
91
+ <%- end -%>
96
92
  }
97
93
  <%- end -%>
98
94
  _ => {}
99
95
  }
100
96
  }
101
97
 
98
+ fn record_child_count(buffer: &mut SerializationBuffer, type_id: u8, pool: usize) -> usize {
99
+ #[allow(unused_mut)]
100
+ let mut count = 0;
101
+
102
+ match type_id {
103
+ <%- prism_nodes.each do |prism_node| -%>
104
+ <%= prism_node.type_id %> => {
105
+ buffer.read_var_int();
106
+
107
+ <%- prism_node.fields.each do |field| -%>
108
+ <%- case field.type -%>
109
+ <%- when "node", "node?" -%>
110
+ count += 1;
111
+ <%- when "node[]" -%>
112
+ count += buffer.read_var_int();
113
+ <%- when "string" -%>
114
+ buffer.read_string_field(0);
115
+ <%- when "constant" -%>
116
+ buffer.read_required_constant(pool);
117
+ <%- when "constant?" -%>
118
+ buffer.read_optional_constant(pool);
119
+ <%- when "constant[]" -%>
120
+ for _ in 0..buffer.read_var_int() {
121
+ buffer.read_required_constant(pool);
122
+ }
123
+ <%- when "location" -%>
124
+ buffer.read_location();
125
+ <%- when "location?" -%>
126
+ buffer.read_optional_location();
127
+ <%- when "uint8" -%>
128
+ buffer.read_byte();
129
+ <%- when "uint32" -%>
130
+ buffer.read_var_int();
131
+ <%- when "integer" -%>
132
+ buffer.read_integer();
133
+ <%- when "double" -%>
134
+ buffer.read_double();
135
+ <%- when "flags" -%>
136
+ <%- else -%>
137
+ <%- raise "unhandled prism field type: #{field.type}" -%>
138
+ <%- end -%>
139
+ <%- end -%>
140
+ }
141
+ <%- end -%>
142
+ _ => {}
143
+ }
144
+
145
+ count
146
+ }
147
+
102
148
  fn node_type_name_for(type_id: u8) -> String {
103
149
  match type_id {
104
150
  <%- prism_nodes.each do |prism_node| -%>
@@ -8,14 +8,12 @@ fn prettyprint_body(
8
8
  start_offset: usize,
9
9
  end_offset: usize,
10
10
  newlines: &[usize],
11
+ children: &mut std::vec::IntoIter<Option<PrismRecord>>,
11
12
  ) {
12
13
  match type_id {
13
14
  <%- prism_nodes.each do |prism_node| -%>
14
15
  <%- entries = prism_node.entries -%>
15
16
  <%= prism_node.type_id %> => {
16
- <%- if prism_node.name == "DefNode" -%>
17
- buffer.read_uint32();
18
- <%- end -%>
19
17
  #[allow(unused_variables)]
20
18
  let flags = buffer.read_var_int() as u32;
21
19
  output.push_str(&format!("@ <%= prism_node.name %> (location: {})\n", location_string(start_offset, end_offset, newlines)));
@@ -45,29 +43,18 @@ fn prettyprint_body(
45
43
 
46
44
  output.push('\n');
47
45
  }
48
- <%- when "node" -%>
49
- output.push('\n');
50
-
51
- {
52
- let saved = prefix.len();
53
- prefix.push_str("<%= preadd %>");
54
- let copy = prefix.clone();
55
- output.push_str(&copy);
56
- prettyprint_node(buffer, pool, output, prefix, newlines);
57
- prefix.truncate(saved);
58
- }
59
- <%- when "node?" -%>
60
- if buffer.peek_byte() == 0 {
61
- buffer.read_byte();
62
- output.push_str(" nil\n");
63
- } else {
64
- output.push('\n');
65
- let saved = prefix.len();
66
- prefix.push_str("<%= preadd %>");
67
- let copy = prefix.clone();
68
- output.push_str(&copy);
69
- prettyprint_node(buffer, pool, output, prefix, newlines);
70
- prefix.truncate(saved);
46
+ <%- when "node", "node?" -%>
47
+ match children.next().flatten() {
48
+ None => output.push_str(" nil\n"),
49
+ Some(child) => {
50
+ output.push('\n');
51
+ let saved = prefix.len();
52
+ prefix.push_str("<%= preadd %>");
53
+ let copy = prefix.clone();
54
+ output.push_str(&copy);
55
+ prettyprint_record(child, buffer, pool, output, prefix, newlines);
56
+ prefix.truncate(saved);
57
+ }
71
58
  }
72
59
  <%- when "node[]" -%>
73
60
  {
@@ -81,7 +68,11 @@ fn prettyprint_body(
81
68
  output.push_str(&copy);
82
69
  output.push_str("+-- ");
83
70
  prefix.push_str(if index == count - 1 { " " } else { "| " });
84
- prettyprint_node(buffer, pool, output, prefix, newlines);
71
+
72
+ if let Some(child) = children.next().flatten() {
73
+ prettyprint_record(child, buffer, pool, output, prefix, newlines);
74
+ }
75
+
85
76
  prefix.truncate(saved);
86
77
  }
87
78
  }
@@ -16,9 +16,9 @@
16
16
  bool detect_<%= helper.safe_name %>(pm_call_node_t* call_node, pm_parser_t* parser) {
17
17
  if (!call_node || !call_node->name) { return false; }
18
18
 
19
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
19
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
20
20
 
21
- return constant && constant->length == <%= helper.name.length %> && strncmp((const char*) constant->start, "<%= helper.name %>", <%= helper.name.length %>) == 0;
21
+ return constant && pm_constant_length(constant) == <%= helper.name.length %> && strncmp((const char*) pm_constant_start(constant), "<%= helper.name %>", <%= helper.name.length %>) == 0;
22
22
  }
23
23
  <%- elsif helper.receiver_call_detect? -%>
24
24
 
@@ -29,9 +29,9 @@ bool detect_<%= helper.safe_name %>(pm_call_node_t* call_node, pm_parser_t* pars
29
29
  pm_call_node_t* receiver_node = (pm_call_node_t*) call_node->receiver;
30
30
  if (!receiver_node->name) { return false; }
31
31
 
32
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, receiver_node->name);
32
+ const pm_constant_t* constant = pm_parser_constant(parser, receiver_node->name);
33
33
 
34
- return constant && constant->length == 3 && strncmp((const char*) constant->start, "tag", 3) == 0;
34
+ return constant && pm_constant_length(constant) == 3 && strncmp((const char*) pm_constant_start(constant), "tag", 3) == 0;
35
35
  }
36
36
  <%- end -%>
37
37
  <%- end -%>
@@ -79,14 +79,17 @@ extern bool is_ruby_introspection_method(hb_string_T method_name);
79
79
  static char* extract_<%= helper.safe_name %>_tag_name(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
80
80
  if (!call_node || !call_node->name) { return NULL; }
81
81
 
82
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
82
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
83
83
  if (!constant) { return NULL; }
84
84
 
85
- if (is_ruby_introspection_method(hb_string_from_data((const char*) constant->start, constant->length))) { return NULL; }
85
+ const char* constant_start = (const char*) pm_constant_start(constant);
86
+ size_t constant_length = pm_constant_length(constant);
86
87
 
87
- char* name = hb_allocator_strndup(allocator, (const char*) constant->start, constant->length);
88
+ if (is_ruby_introspection_method(hb_string_from_data(constant_start, constant_length))) { return NULL; }
88
89
 
89
- for (size_t i = 0; i < constant->length && name[i] != '\0'; i++) {
90
+ char* name = hb_allocator_strndup(allocator, constant_start, constant_length);
91
+
92
+ for (size_t i = 0; i < constant_length && name[i] != '\0'; i++) {
90
93
  if (name[i] == '_') { name[i] = '-'; }
91
94
  }
92
95
 
@@ -111,9 +114,7 @@ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* _call_node,
111
114
  }
112
115
  <%- elsif content.first_arg? -%>
113
116
 
114
- static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node, pm_parser_t* _parser, hb_allocator_T* allocator) {
115
- (void) _parser;
116
-
117
+ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
117
118
  if (!call_node || !call_node->arguments) { return NULL; }
118
119
 
119
120
  pm_arguments_node_t* arguments = call_node->arguments;
@@ -131,27 +132,26 @@ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node,
131
132
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
132
133
  }
133
134
 
134
- size_t source_length = first_argument->location.end - first_argument->location.start;
135
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
135
+ const uint8_t* source = pm_parser_start(parser);
136
+ size_t source_length = first_argument->location.length;
137
+ return hb_allocator_strndup(allocator, (const char*) (source + first_argument->location.start), source_length);
136
138
  }
137
139
  <%- elsif content.block_or_arg? -%>
138
140
 
139
- static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node, pm_parser_t* <%= helper.receiver_call_detect? ? "parser" : "_parser" %>, hb_allocator_T* allocator) {
140
- (void) <%= helper.receiver_call_detect? ? "parser" : "_parser" %>;
141
-
141
+ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
142
142
  if (!call_node) { return NULL; }
143
143
 
144
144
  <%- if helper.receiver_call_detect? -%>
145
145
  if (call_node->name) {
146
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
146
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
147
147
 
148
- if (constant && is_ruby_introspection_method(hb_string_from_data((const char*) constant->start, constant->length))) {
148
+ if (constant && is_ruby_introspection_method(hb_string_from_data((const char*) pm_constant_start(constant), pm_constant_length(constant)))) {
149
149
  return NULL;
150
150
  }
151
151
  }
152
152
  <%- end -%>
153
153
 
154
- char* block_content = extract_inline_block_content(call_node, allocator);
154
+ char* block_content = extract_inline_block_content(call_node, parser, allocator);
155
155
  if (block_content) { return block_content; }
156
156
 
157
157
  <%- arg_index = (content.arg_position || 1) - 1 -%>
@@ -173,7 +173,8 @@ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node,
173
173
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
174
174
  }
175
175
 
176
- size_t source_length = argument->location.end - argument->location.start;
176
+ const uint8_t* source = pm_parser_start(parser);
177
+ size_t source_length = argument->location.length;
177
178
 
178
179
  <%- if content.to_s_suffix_when_single -%>
179
180
  if (arguments->arguments.size == 1 && argument->type != PM_NIL_NODE) {
@@ -182,7 +183,7 @@ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node,
182
183
  size_t total_length = source_length + suffix_length;
183
184
  char* ruby_expression = hb_allocator_alloc(allocator, total_length + 1);
184
185
 
185
- memcpy(ruby_expression, (const char*) argument->location.start, source_length);
186
+ memcpy(ruby_expression, (const char*) (source + argument->location.start), source_length);
186
187
  memcpy(ruby_expression + source_length, suffix, suffix_length);
187
188
  ruby_expression[total_length] = '\0';
188
189
 
@@ -190,7 +191,7 @@ static char* extract_<%= helper.safe_name %>_content(pm_call_node_t* call_node,
190
191
  }
191
192
  <%- end -%>
192
193
 
193
- return hb_allocator_strndup(allocator, (const char*) argument->location.start, source_length);
194
+ return hb_allocator_strndup(allocator, (const char*) (source + argument->location.start), source_length);
194
195
 
195
196
  <%- if content.skip_if_hash -%>
196
197
  }
@@ -7,9 +7,15 @@
7
7
  #include <stddef.h>
8
8
  #include <stdint.h>
9
9
 
10
+ #define HERB_PARSER_OPTIONS_STRING_CAPACITY 16
11
+
10
12
  typedef struct PARSER_OPTIONS_STRUCT {
11
13
  <%- parser_options.all_c_fields.each do |field| -%>
14
+ <%- if field.string? -%>
15
+ char <%= field.c_name %>[HERB_PARSER_OPTIONS_STRING_CAPACITY];
16
+ <%- else -%>
12
17
  <%= field.c_type %> <%= field.c_name %>;
18
+ <%- end -%>
13
19
  <%- if field.string_array? -%>
14
20
  size_t <%= field.count_name %>;
15
21
  <%- end -%>
@@ -17,5 +23,9 @@ typedef struct PARSER_OPTIONS_STRUCT {
17
23
  } parser_options_T;
18
24
 
19
25
  extern const parser_options_T HERB_DEFAULT_PARSER_OPTIONS;
26
+ <%- parser_options.all_c_fields.select(&:validator).each do |field| -%>
27
+
28
+ bool <%= field.validator %>(const char* value, size_t length);
29
+ <%- end -%>
20
30
 
21
31
  #endif
@@ -0,0 +1,17 @@
1
+ <%-
2
+ lockfile = File.expand_path("../../../Gemfile.lock", __dir__)
3
+ prism_git = File.exist?(lockfile) ? File.read(lockfile).split(/\n\n+/).find { |block| block.start_with?("GIT") && block.match?(/^\s+prism \(/) } : nil
4
+ prism_revision = prism_git && !prism_git.match?(/^\s+tag:/) ? prism_git[/^\s+revision: (\h{7})/, 1] : nil
5
+ -%>
6
+ #ifndef HERB_PRISM_VERSION_H
7
+ #define HERB_PRISM_VERSION_H
8
+
9
+ #include <prism/version.h>
10
+
11
+ <%- if prism_revision -%>
12
+ #define HERB_PRISM_VERSION PRISM_VERSION "+<%= prism_revision %>"
13
+ <%- else -%>
14
+ #define HERB_PRISM_VERSION PRISM_VERSION
15
+ <%- end -%>
16
+
17
+ #endif
@@ -2,7 +2,7 @@
2
2
 
3
3
  #include <stddef.h>
4
4
 
5
- <%- entries = parser_options.all_c_fields.flat_map { |field| field.string_array? ? [[field.c_name, "NULL"], [field.count_name, "0"]] : [[field.c_name, field.pointer? ? "NULL" : field.c_default.to_s]] } -%>
5
+ <%- entries = parser_options.all_c_fields.flat_map { |field| field.string_array? ? [[field.c_name, "NULL"], [field.count_name, "0"]] : field.string? ? [[field.c_name, field.default ? field.default.inspect : "{ 0 }"]] : [[field.c_name, field.pointer? ? "NULL" : field.c_default.to_s]] } -%>
6
6
  <%- prefix = "const parser_options_T HERB_DEFAULT_PARSER_OPTIONS = { " -%>
7
7
  <%- entries.each_with_index do |(name, value), index| -%>
8
8
  <%= index.zero? ? prefix : " " * prefix.length %>.<%= name %> = <%= value %><%= index < entries.length - 1 ? "," : " };" %>
@@ -1176,7 +1176,8 @@ module Herb
1176
1176
  end
1177
1177
 
1178
1178
  class ParserOptionField
1179
- attr_reader :name, :type, :default, :description, :c_name, :nullable, :null_sentinel, :ruby_unit, :default_ms, :count_name
1179
+ attr_reader :name, :type, :default, :description, :c_name, :nullable, :null_sentinel, :ruby_unit, :default_ms, :count_name,
1180
+ :validator
1180
1181
 
1181
1182
  def initialize(config)
1182
1183
  @name = config.fetch("name")
@@ -1193,6 +1194,7 @@ module Herb
1193
1194
  @only = config["only"]
1194
1195
  @skip = config.fetch("skip", [])
1195
1196
  @lex = config.fetch("lex", false)
1197
+ @validator = config["validator"]
1196
1198
  end
1197
1199
 
1198
1200
  def for?(language)
@@ -1217,6 +1219,10 @@ module Herb
1217
1219
  @type == "string_array"
1218
1220
  end
1219
1221
 
1222
+ def string?
1223
+ @type == "string"
1224
+ end
1225
+
1220
1226
  def uint64?
1221
1227
  @type == "uint64"
1222
1228
  end
@@ -1253,17 +1259,19 @@ module Herb
1253
1259
 
1254
1260
  def java_jni_signature
1255
1261
  return "()Z" if boolean?
1262
+ return "()Ljava/lang/String;" if string?
1256
1263
  return "()Ljava/lang/Integer;" if nullable?
1257
1264
 
1258
1265
  "()I"
1259
1266
  end
1260
1267
 
1261
1268
  def ruby_constant?
1262
- !string_array?
1269
+ !string_array? && !string?
1263
1270
  end
1264
1271
 
1265
1272
  def ruby_default
1266
1273
  return "[]" if string_array?
1274
+ return @default.nil? ? "nil" : @default.inspect if string?
1267
1275
  return "nil" if nullable? && @default.nil?
1268
1276
 
1269
1277
  if @ruby_unit == "seconds" && @default_ms
@@ -1290,12 +1298,14 @@ module Herb
1290
1298
 
1291
1299
  def js_default
1292
1300
  return "[]" if string_array?
1301
+ return @default.nil? ? "null" : @default.inspect if string?
1293
1302
  return "null" if nullable? && @default.nil?
1294
1303
 
1295
1304
  @default_ms || @default
1296
1305
  end
1297
1306
 
1298
1307
  def java_default
1308
+ return @default.nil? ? "null" : @default.inspect if string?
1299
1309
  return "null" if nullable? && @default.nil?
1300
1310
 
1301
1311
  @default_ms || @default
@@ -1303,6 +1313,7 @@ module Herb
1303
1313
 
1304
1314
  def rust_default
1305
1315
  return "None" if string_array?
1316
+ return @default.nil? ? "None" : "Some(#{@default.inspect}.to_string())" if string?
1306
1317
  return "None" if nullable? && @default.nil?
1307
1318
 
1308
1319
  value = @default_ms || @default
@@ -1322,6 +1333,7 @@ module Herb
1322
1333
  def ruby_type
1323
1334
  return "bool" if boolean?
1324
1335
  return "Array[String]" if string_array?
1336
+ return "String?" if string?
1325
1337
  return "Numeric" if @ruby_unit == "seconds"
1326
1338
 
1327
1339
  nullable? ? "Integer?" : "Integer"
@@ -1330,12 +1342,14 @@ module Herb
1330
1342
  def typescript_type
1331
1343
  return "boolean" if boolean?
1332
1344
  return "string[]" if string_array?
1345
+ return "string | null" if string?
1333
1346
 
1334
1347
  nullable? ? "number | null" : "number"
1335
1348
  end
1336
1349
 
1337
1350
  def java_type
1338
1351
  return "boolean" if boolean?
1352
+ return "String" if string?
1339
1353
 
1340
1354
  nullable? ? "Integer" : "int"
1341
1355
  end
@@ -1343,6 +1357,7 @@ module Herb
1343
1357
  def rust_type
1344
1358
  return "bool" if boolean?
1345
1359
  return "Option<Vec<String>>" if string_array?
1360
+ return "Option<String>" if string?
1346
1361
 
1347
1362
  nullable? ? "Option<u32>" : "u32"
1348
1363
  end
@@ -47,34 +47,24 @@ val <%= node.name %>FromCStruct(<%= node.struct_type %>* <%= node.human %>, cons
47
47
  }
48
48
  <%- when Herb::Template::PrismSerializedField -%>
49
49
  if (<%= node.human %>-><%= field.name %>.data != NULL && <%= node.human %>-><%= field.name %>.length > 0) {
50
- val jsArray = val::array();
51
-
52
- for (size_t i = 0; i < <%= node.human %>-><%= field.name %>.length; i++) {
53
- jsArray.call<void>("push", (int)<%= node.human %>-><%= field.name %>.data[i]);
54
- }
55
-
56
- result.set("<%= field.name %>", jsArray);
50
+ val view = val(typed_memory_view(<%= node.human %>-><%= field.name %>.length, (const uint8_t*) <%= node.human %>-><%= field.name %>.data));
51
+ result.set("<%= field.name %>", val::global("Uint8Array").new_(view));
57
52
  } else {
58
53
  result.set("<%= field.name %>", val::null());
59
54
  }
60
55
  <%- when Herb::Template::PrismNodeField -%>
61
56
  if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
62
- pm_buffer_t pm_buffer = { 0 };
63
- pm_serialize(<%= node.human %>-><%= field.name %>.parser, <%= node.human %>-><%= field.name %>.node, &pm_buffer);
64
-
65
- if (pm_buffer.length > 0) {
66
- val jsArray = val::array();
67
-
68
- for (size_t i = 0; i < pm_buffer.length; i++) {
69
- jsArray.call<void>("push", (int)((uint8_t*)pm_buffer.value)[i]);
70
- }
57
+ pm_buffer_t* pm_buffer = pm_buffer_new();
58
+ herb_prism_node_serialize(<%= node.human %>-><%= field.name %>, pm_buffer);
71
59
 
72
- result.set("<%= field.name %>", jsArray);
60
+ if (pm_buffer_length(pm_buffer) > 0) {
61
+ val view = val(typed_memory_view(pm_buffer_length(pm_buffer), (const uint8_t*) pm_buffer_value(pm_buffer)));
62
+ result.set("<%= field.name %>", val::global("Uint8Array").new_(view));
73
63
  } else {
74
64
  result.set("<%= field.name %>", val::null());
75
65
  }
76
66
 
77
- pm_buffer_free(&pm_buffer);
67
+ pm_buffer_free(pm_buffer);
78
68
  } else {
79
69
  result.set("<%= field.name %>", val::null());
80
70
  }