herb 0.7.2-x86-linux-musl → 0.7.4-x86-linux-musl
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.
- checksums.yaml +4 -4
- data/Makefile +2 -0
- data/README.md +1 -1
- data/Rakefile +46 -1
- data/config.yml +714 -0
- data/ext/herb/extconf.rb +2 -1
- data/ext/herb/nodes.c +1 -1
- data/herb.gemspec +3 -0
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/engine.rb +8 -1
- data/lib/herb/version.rb +1 -1
- data/src/analyze.c +5 -9
- data/src/analyze_helpers.c +17 -6
- data/src/herb.c +2 -2
- data/src/include/parser.h +2 -2
- data/src/include/pretty_print.h +1 -1
- data/src/include/version.h +1 -1
- data/src/parser.c +3 -2
- data/src/pretty_print.c +1 -1
- data/templates/ext/herb/error_helpers.c.erb +85 -0
- data/templates/ext/herb/error_helpers.h.erb +12 -0
- data/templates/ext/herb/nodes.c.erb +90 -0
- data/templates/ext/herb/nodes.h.erb +9 -0
- data/templates/javascript/packages/core/src/errors.ts.erb +193 -0
- data/templates/javascript/packages/core/src/node-type-guards.ts.erb +325 -0
- data/templates/javascript/packages/core/src/nodes.ts.erb +414 -0
- data/templates/javascript/packages/core/src/visitor.ts.erb +29 -0
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +113 -0
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +17 -0
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +111 -0
- data/templates/javascript/packages/node/extension/nodes.h.erb +17 -0
- data/templates/lib/herb/ast/nodes.rb.erb +117 -0
- data/templates/lib/herb/errors.rb.erb +106 -0
- data/templates/lib/herb/visitor.rb.erb +28 -0
- data/templates/sig/serialized_ast_errors.rbs.erb +10 -0
- data/templates/sig/serialized_ast_nodes.rbs.erb +10 -0
- data/templates/src/ast_nodes.c.erb +145 -0
- data/templates/src/ast_pretty_print.c.erb +97 -0
- data/templates/src/errors.c.erb +245 -0
- data/templates/src/include/ast_nodes.h.erb +46 -0
- data/templates/src/include/ast_pretty_print.h.erb +14 -0
- data/templates/src/include/errors.h.erb +58 -0
- data/templates/src/visitor.c.erb +47 -0
- data/templates/template.rb +406 -0
- data/templates/wasm/error_helpers.cpp.erb +93 -0
- data/templates/wasm/error_helpers.h.erb +15 -0
- data/templates/wasm/nodes.cpp.erb +79 -0
- data/templates/wasm/nodes.h.erb +15 -0
- data/vendor/prism/Rakefile +75 -0
- data/vendor/prism/config.yml +4713 -0
- data/vendor/prism/include/prism/ast.h +8190 -0
- data/vendor/prism/include/prism/defines.h +260 -0
- data/vendor/prism/include/prism/diagnostic.h +455 -0
- data/vendor/prism/include/prism/encoding.h +283 -0
- data/vendor/prism/include/prism/node.h +129 -0
- data/vendor/prism/include/prism/options.h +482 -0
- data/vendor/prism/include/prism/pack.h +163 -0
- data/vendor/prism/include/prism/parser.h +933 -0
- data/vendor/prism/include/prism/prettyprint.h +34 -0
- data/vendor/prism/include/prism/regexp.h +43 -0
- data/vendor/prism/include/prism/static_literals.h +121 -0
- data/vendor/prism/include/prism/util/pm_buffer.h +236 -0
- data/vendor/prism/include/prism/util/pm_char.h +204 -0
- data/vendor/prism/include/prism/util/pm_constant_pool.h +218 -0
- data/vendor/prism/include/prism/util/pm_integer.h +130 -0
- data/vendor/prism/include/prism/util/pm_list.h +103 -0
- data/vendor/prism/include/prism/util/pm_memchr.h +29 -0
- data/vendor/prism/include/prism/util/pm_newline_list.h +113 -0
- data/vendor/prism/include/prism/util/pm_string.h +200 -0
- data/vendor/prism/include/prism/util/pm_strncasecmp.h +32 -0
- data/vendor/prism/include/prism/util/pm_strpbrk.h +46 -0
- data/vendor/prism/include/prism/version.h +29 -0
- data/vendor/prism/include/prism.h +408 -0
- data/vendor/prism/src/diagnostic.c +848 -0
- data/vendor/prism/src/encoding.c +5235 -0
- data/vendor/prism/src/node.c +8676 -0
- data/vendor/prism/src/options.c +328 -0
- data/vendor/prism/src/pack.c +509 -0
- data/vendor/prism/src/prettyprint.c +8941 -0
- data/vendor/prism/src/prism.c +23302 -0
- data/vendor/prism/src/regexp.c +790 -0
- data/vendor/prism/src/serialize.c +2268 -0
- data/vendor/prism/src/static_literals.c +617 -0
- data/vendor/prism/src/token_type.c +703 -0
- data/vendor/prism/src/util/pm_buffer.c +357 -0
- data/vendor/prism/src/util/pm_char.c +318 -0
- data/vendor/prism/src/util/pm_constant_pool.c +342 -0
- data/vendor/prism/src/util/pm_integer.c +670 -0
- data/vendor/prism/src/util/pm_list.c +49 -0
- data/vendor/prism/src/util/pm_memchr.c +35 -0
- data/vendor/prism/src/util/pm_newline_list.c +125 -0
- data/vendor/prism/src/util/pm_string.c +383 -0
- data/vendor/prism/src/util/pm_strncasecmp.c +36 -0
- data/vendor/prism/src/util/pm_strpbrk.c +206 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +282 -0
- data/vendor/prism/templates/include/prism/ast.h.erb +226 -0
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +130 -0
- data/vendor/prism/templates/java/org/prism/AbstractNodeVisitor.java.erb +22 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +434 -0
- data/vendor/prism/templates/java/org/prism/Nodes.java.erb +403 -0
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +448 -0
- data/vendor/prism/templates/javascript/src/nodes.js.erb +197 -0
- data/vendor/prism/templates/javascript/src/visitor.js.erb +78 -0
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +43 -0
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +103 -0
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +189 -0
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +133 -0
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +131 -0
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +19 -0
- data/vendor/prism/templates/lib/prism/node.rb.erb +515 -0
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +136 -0
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +602 -0
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +55 -0
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +68 -0
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +164 -0
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +18 -0
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +45 -0
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +31 -0
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +7 -0
- data/vendor/prism/templates/sig/prism/node.rbs.erb +132 -0
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +17 -0
- data/vendor/prism/templates/sig/prism.rbs.erb +89 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +523 -0
- data/vendor/prism/templates/src/node.c.erb +333 -0
- data/vendor/prism/templates/src/prettyprint.c.erb +166 -0
- data/vendor/prism/templates/src/serialize.c.erb +406 -0
- data/vendor/prism/templates/src/token_type.c.erb +369 -0
- data/vendor/prism/templates/template.rb +689 -0
- metadata +112 -2
@@ -0,0 +1,406 @@
|
|
1
|
+
#include "prism.h"
|
2
|
+
|
3
|
+
// We optionally support serializing to a binary string. For systems that don't
|
4
|
+
// want or need this functionality, it can be turned off with the
|
5
|
+
// PRISM_EXCLUDE_SERIALIZATION define.
|
6
|
+
#ifndef PRISM_EXCLUDE_SERIALIZATION
|
7
|
+
|
8
|
+
#include <stdio.h>
|
9
|
+
|
10
|
+
static inline uint32_t
|
11
|
+
pm_ptrdifft_to_u32(ptrdiff_t value) {
|
12
|
+
assert(value >= 0 && ((unsigned long) value) < UINT32_MAX);
|
13
|
+
return (uint32_t) value;
|
14
|
+
}
|
15
|
+
|
16
|
+
static inline uint32_t
|
17
|
+
pm_sizet_to_u32(size_t value) {
|
18
|
+
assert(value < UINT32_MAX);
|
19
|
+
return (uint32_t) value;
|
20
|
+
}
|
21
|
+
|
22
|
+
static void
|
23
|
+
pm_serialize_location(const pm_parser_t *parser, const pm_location_t *location, pm_buffer_t *buffer) {
|
24
|
+
assert(location->start);
|
25
|
+
assert(location->end);
|
26
|
+
assert(location->start <= location->end);
|
27
|
+
|
28
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->start - parser->start));
|
29
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->end - location->start));
|
30
|
+
}
|
31
|
+
|
32
|
+
static void
|
33
|
+
pm_serialize_string(const pm_parser_t *parser, const pm_string_t *string, pm_buffer_t *buffer) {
|
34
|
+
switch (string->type) {
|
35
|
+
case PM_STRING_SHARED: {
|
36
|
+
pm_buffer_append_byte(buffer, 1);
|
37
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(pm_string_source(string) - parser->start));
|
38
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_string_length(string)));
|
39
|
+
break;
|
40
|
+
}
|
41
|
+
case PM_STRING_OWNED:
|
42
|
+
case PM_STRING_CONSTANT: {
|
43
|
+
uint32_t length = pm_sizet_to_u32(pm_string_length(string));
|
44
|
+
pm_buffer_append_byte(buffer, 2);
|
45
|
+
pm_buffer_append_varuint(buffer, length);
|
46
|
+
pm_buffer_append_bytes(buffer, pm_string_source(string), length);
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
#ifdef PRISM_HAS_MMAP
|
50
|
+
case PM_STRING_MAPPED:
|
51
|
+
assert(false && "Cannot serialize mapped strings.");
|
52
|
+
break;
|
53
|
+
#endif
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
static void
|
58
|
+
pm_serialize_integer(const pm_integer_t *integer, pm_buffer_t *buffer) {
|
59
|
+
pm_buffer_append_byte(buffer, integer->negative ? 1 : 0);
|
60
|
+
if (integer->values == NULL) {
|
61
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(1));
|
62
|
+
pm_buffer_append_varuint(buffer, integer->value);
|
63
|
+
} else {
|
64
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(integer->length));
|
65
|
+
for (size_t i = 0; i < integer->length; i++) {
|
66
|
+
pm_buffer_append_varuint(buffer, integer->values[i]);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
static void
|
72
|
+
pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
73
|
+
pm_buffer_append_byte(buffer, (uint8_t) PM_NODE_TYPE(node));
|
74
|
+
|
75
|
+
size_t offset = buffer->length;
|
76
|
+
|
77
|
+
<%- if Prism::Template::INCLUDE_NODE_ID -%>
|
78
|
+
pm_buffer_append_varuint(buffer, node->node_id);
|
79
|
+
<%- end -%>
|
80
|
+
pm_serialize_location(parser, &node->location, buffer);
|
81
|
+
|
82
|
+
switch (PM_NODE_TYPE(node)) {
|
83
|
+
// We do not need to serialize a ScopeNode ever as
|
84
|
+
// it is not part of the AST
|
85
|
+
case PM_SCOPE_NODE:
|
86
|
+
return;
|
87
|
+
<%- nodes.each do |node| -%>
|
88
|
+
case <%= node.type %>: {
|
89
|
+
<%- if node.needs_serialized_length? -%>
|
90
|
+
// serialize length
|
91
|
+
// encoding of location u32s make us need to save this offset.
|
92
|
+
size_t length_offset = buffer->length;
|
93
|
+
pm_buffer_append_string(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */
|
94
|
+
<%- end -%>
|
95
|
+
<%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS && !node.flags -%>
|
96
|
+
pm_buffer_append_varuint(buffer, (uint32_t) node->flags);
|
97
|
+
<%- end -%>
|
98
|
+
<%- node.fields.each do |field| -%>
|
99
|
+
<%- case field -%>
|
100
|
+
<%- when Prism::Template::NodeField -%>
|
101
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
|
102
|
+
<%- when Prism::Template::OptionalNodeField -%>
|
103
|
+
if (((pm_<%= node.human %>_t *)node)-><%= field.name %> == NULL) {
|
104
|
+
pm_buffer_append_byte(buffer, 0);
|
105
|
+
} else {
|
106
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
|
107
|
+
}
|
108
|
+
<%- when Prism::Template::StringField -%>
|
109
|
+
pm_serialize_string(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
|
110
|
+
<%- when Prism::Template::NodeListField -%>
|
111
|
+
uint32_t <%= field.name %>_size = pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.size);
|
112
|
+
pm_buffer_append_varuint(buffer, <%= field.name %>_size);
|
113
|
+
for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
|
114
|
+
pm_serialize_node(parser, (pm_node_t *) ((pm_<%= node.human %>_t *)node)-><%= field.name %>.nodes[index], buffer);
|
115
|
+
}
|
116
|
+
<%- when Prism::Template::ConstantField, Prism::Template::OptionalConstantField -%>
|
117
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>));
|
118
|
+
<%- when Prism::Template::ConstantListField -%>
|
119
|
+
uint32_t <%= field.name %>_size = pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.size);
|
120
|
+
pm_buffer_append_varuint(buffer, <%= field.name %>_size);
|
121
|
+
for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
|
122
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.ids[index]));
|
123
|
+
}
|
124
|
+
<%- when Prism::Template::LocationField -%>
|
125
|
+
<%- if field.should_be_serialized? -%>
|
126
|
+
pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
|
127
|
+
<%- end -%>
|
128
|
+
<%- when Prism::Template::OptionalLocationField -%>
|
129
|
+
<%- if field.should_be_serialized? -%>
|
130
|
+
if (((pm_<%= node.human %>_t *)node)-><%= field.name %>.start == NULL) {
|
131
|
+
pm_buffer_append_byte(buffer, 0);
|
132
|
+
} else {
|
133
|
+
pm_buffer_append_byte(buffer, 1);
|
134
|
+
pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
|
135
|
+
}
|
136
|
+
<%- end -%>
|
137
|
+
<%- when Prism::Template::UInt8Field -%>
|
138
|
+
pm_buffer_append_byte(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
|
139
|
+
<%- when Prism::Template::UInt32Field -%>
|
140
|
+
pm_buffer_append_varuint(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
|
141
|
+
<%- when Prism::Template::IntegerField -%>
|
142
|
+
pm_serialize_integer(&((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
|
143
|
+
<%- when Prism::Template::DoubleField -%>
|
144
|
+
pm_buffer_append_double(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
|
145
|
+
<%- else -%>
|
146
|
+
<%- raise -%>
|
147
|
+
<%- end -%>
|
148
|
+
<%- end -%>
|
149
|
+
<%- if node.needs_serialized_length? -%>
|
150
|
+
// serialize length
|
151
|
+
uint32_t length = pm_sizet_to_u32(buffer->length - offset - sizeof(uint32_t));
|
152
|
+
memcpy(buffer->value + length_offset, &length, sizeof(uint32_t));
|
153
|
+
<%- end -%>
|
154
|
+
break;
|
155
|
+
}
|
156
|
+
<%- end -%>
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
static void
|
161
|
+
pm_serialize_newline_list(pm_newline_list_t *list, pm_buffer_t *buffer) {
|
162
|
+
uint32_t size = pm_sizet_to_u32(list->size);
|
163
|
+
pm_buffer_append_varuint(buffer, size);
|
164
|
+
|
165
|
+
for (uint32_t i = 0; i < size; i++) {
|
166
|
+
uint32_t offset = pm_sizet_to_u32(list->offsets[i]);
|
167
|
+
pm_buffer_append_varuint(buffer, offset);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
static void
|
172
|
+
pm_serialize_comment(pm_parser_t *parser, pm_comment_t *comment, pm_buffer_t *buffer) {
|
173
|
+
// serialize type
|
174
|
+
pm_buffer_append_byte(buffer, (uint8_t) comment->type);
|
175
|
+
|
176
|
+
// serialize location
|
177
|
+
pm_serialize_location(parser, &comment->location, buffer);
|
178
|
+
}
|
179
|
+
|
180
|
+
/**
|
181
|
+
* Serialize the given list of comments to the given buffer.
|
182
|
+
*/
|
183
|
+
void
|
184
|
+
pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
|
185
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
186
|
+
|
187
|
+
pm_comment_t *comment;
|
188
|
+
for (comment = (pm_comment_t *) list->head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
|
189
|
+
pm_serialize_comment(parser, comment, buffer);
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
static void
|
194
|
+
pm_serialize_magic_comment(pm_parser_t *parser, pm_magic_comment_t *magic_comment, pm_buffer_t *buffer) {
|
195
|
+
// serialize key location
|
196
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->key_start - parser->start));
|
197
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->key_length));
|
198
|
+
|
199
|
+
// serialize value location
|
200
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->value_start - parser->start));
|
201
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->value_length));
|
202
|
+
}
|
203
|
+
|
204
|
+
static void
|
205
|
+
pm_serialize_magic_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
|
206
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
207
|
+
|
208
|
+
pm_magic_comment_t *magic_comment;
|
209
|
+
for (magic_comment = (pm_magic_comment_t *) list->head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
|
210
|
+
pm_serialize_magic_comment(parser, magic_comment, buffer);
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
static void
|
215
|
+
pm_serialize_data_loc(const pm_parser_t *parser, pm_buffer_t *buffer) {
|
216
|
+
if (parser->data_loc.end == NULL) {
|
217
|
+
pm_buffer_append_byte(buffer, 0);
|
218
|
+
} else {
|
219
|
+
pm_buffer_append_byte(buffer, 1);
|
220
|
+
pm_serialize_location(parser, &parser->data_loc, buffer);
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
static void
|
225
|
+
pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
|
226
|
+
// serialize the type
|
227
|
+
pm_buffer_append_varuint(buffer, (uint32_t) diagnostic->diag_id);
|
228
|
+
|
229
|
+
// serialize message
|
230
|
+
size_t message_length = strlen(diagnostic->message);
|
231
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(message_length));
|
232
|
+
pm_buffer_append_string(buffer, diagnostic->message, message_length);
|
233
|
+
|
234
|
+
// serialize location
|
235
|
+
pm_serialize_location(parser, &diagnostic->location, buffer);
|
236
|
+
|
237
|
+
pm_buffer_append_byte(buffer, diagnostic->level);
|
238
|
+
}
|
239
|
+
|
240
|
+
static void
|
241
|
+
pm_serialize_diagnostic_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
|
242
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
243
|
+
|
244
|
+
pm_diagnostic_t *diagnostic;
|
245
|
+
for (diagnostic = (pm_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) {
|
246
|
+
pm_serialize_diagnostic(parser, diagnostic, buffer);
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
/**
|
251
|
+
* Serialize the name of the encoding to the buffer.
|
252
|
+
*/
|
253
|
+
void
|
254
|
+
pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer) {
|
255
|
+
size_t encoding_length = strlen(encoding->name);
|
256
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(encoding_length));
|
257
|
+
pm_buffer_append_string(buffer, encoding->name, encoding_length);
|
258
|
+
}
|
259
|
+
|
260
|
+
static void
|
261
|
+
pm_serialize_metadata(pm_parser_t *parser, pm_buffer_t *buffer) {
|
262
|
+
pm_serialize_encoding(parser->encoding, buffer);
|
263
|
+
pm_buffer_append_varsint(buffer, parser->start_line);
|
264
|
+
pm_serialize_newline_list(&parser->newline_list, buffer);
|
265
|
+
<%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS -%>
|
266
|
+
pm_serialize_comment_list(parser, &parser->comment_list, buffer);
|
267
|
+
<%- end -%>
|
268
|
+
pm_serialize_magic_comment_list(parser, &parser->magic_comment_list, buffer);
|
269
|
+
pm_serialize_data_loc(parser, buffer);
|
270
|
+
pm_serialize_diagnostic_list(parser, &parser->error_list, buffer);
|
271
|
+
pm_serialize_diagnostic_list(parser, &parser->warning_list, buffer);
|
272
|
+
}
|
273
|
+
|
274
|
+
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
275
|
+
/**
|
276
|
+
* Serialize the metadata, nodes, and constant pool.
|
277
|
+
*/
|
278
|
+
void
|
279
|
+
pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
280
|
+
pm_serialize_metadata(parser, buffer);
|
281
|
+
|
282
|
+
// Here we're going to leave space for the offset of the constant pool in
|
283
|
+
// the buffer.
|
284
|
+
size_t offset = buffer->length;
|
285
|
+
pm_buffer_append_zeroes(buffer, 4);
|
286
|
+
|
287
|
+
// Next, encode the length of the constant pool.
|
288
|
+
pm_buffer_append_varuint(buffer, parser->constant_pool.size);
|
289
|
+
|
290
|
+
// Now we're going to serialize the content of the node.
|
291
|
+
pm_serialize_node(parser, node, buffer);
|
292
|
+
|
293
|
+
// Now we're going to serialize the offset of the constant pool back where
|
294
|
+
// we left space for it.
|
295
|
+
uint32_t length = pm_sizet_to_u32(buffer->length);
|
296
|
+
memcpy(buffer->value + offset, &length, sizeof(uint32_t));
|
297
|
+
|
298
|
+
// Now we're going to serialize the constant pool.
|
299
|
+
offset = buffer->length;
|
300
|
+
pm_buffer_append_zeroes(buffer, parser->constant_pool.size * 8);
|
301
|
+
|
302
|
+
for (uint32_t index = 0; index < parser->constant_pool.capacity; index++) {
|
303
|
+
pm_constant_pool_bucket_t *bucket = &parser->constant_pool.buckets[index];
|
304
|
+
|
305
|
+
// If we find a constant at this index, serialize it at the correct
|
306
|
+
// index in the buffer.
|
307
|
+
if (bucket->id != 0) {
|
308
|
+
pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
|
309
|
+
size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
|
310
|
+
|
311
|
+
if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED || bucket->type == PM_CONSTANT_POOL_BUCKET_CONSTANT) {
|
312
|
+
// Since this is an owned or constant constant, we are going to
|
313
|
+
// write its contents into the buffer after the constant pool.
|
314
|
+
// So effectively in place of the source offset, we have a
|
315
|
+
// buffer offset. We will add a leading 1 to indicate that this
|
316
|
+
// is a buffer offset.
|
317
|
+
uint32_t content_offset = pm_sizet_to_u32(buffer->length);
|
318
|
+
uint32_t owned_mask = (uint32_t) (1 << 31);
|
319
|
+
|
320
|
+
assert(content_offset < owned_mask);
|
321
|
+
content_offset |= owned_mask;
|
322
|
+
|
323
|
+
memcpy(buffer->value + buffer_offset, &content_offset, 4);
|
324
|
+
pm_buffer_append_bytes(buffer, constant->start, constant->length);
|
325
|
+
} else {
|
326
|
+
// Since this is a shared constant, we are going to write its
|
327
|
+
// source offset directly into the buffer.
|
328
|
+
uint32_t source_offset = pm_ptrdifft_to_u32(constant->start - parser->start);
|
329
|
+
memcpy(buffer->value + buffer_offset, &source_offset, 4);
|
330
|
+
}
|
331
|
+
|
332
|
+
// Now we can write the length of the constant into the buffer.
|
333
|
+
uint32_t constant_length = pm_sizet_to_u32(constant->length);
|
334
|
+
memcpy(buffer->value + buffer_offset + 4, &constant_length, 4);
|
335
|
+
}
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
static void
|
340
|
+
serialize_token(void *data, pm_parser_t *parser, pm_token_t *token) {
|
341
|
+
pm_buffer_t *buffer = (pm_buffer_t *) data;
|
342
|
+
|
343
|
+
pm_buffer_append_varuint(buffer, token->type);
|
344
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->start - parser->start));
|
345
|
+
pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->end - token->start));
|
346
|
+
pm_buffer_append_varuint(buffer, parser->lex_state);
|
347
|
+
}
|
348
|
+
|
349
|
+
/**
|
350
|
+
* Lex the given source and serialize to the given buffer.
|
351
|
+
*/
|
352
|
+
PRISM_EXPORTED_FUNCTION void
|
353
|
+
pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
|
354
|
+
pm_options_t options = { 0 };
|
355
|
+
pm_options_read(&options, data);
|
356
|
+
|
357
|
+
pm_parser_t parser;
|
358
|
+
pm_parser_init(&parser, source, size, &options);
|
359
|
+
|
360
|
+
pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
|
361
|
+
.data = (void *) buffer,
|
362
|
+
.callback = serialize_token,
|
363
|
+
};
|
364
|
+
|
365
|
+
parser.lex_callback = &lex_callback;
|
366
|
+
pm_node_t *node = pm_parse(&parser);
|
367
|
+
|
368
|
+
// Append 0 to mark end of tokens.
|
369
|
+
pm_buffer_append_byte(buffer, 0);
|
370
|
+
|
371
|
+
pm_serialize_metadata(&parser, buffer);
|
372
|
+
|
373
|
+
pm_node_destroy(&parser, node);
|
374
|
+
pm_parser_free(&parser);
|
375
|
+
pm_options_free(&options);
|
376
|
+
}
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Parse and serialize both the AST and the tokens represented by the given
|
380
|
+
* source to the given buffer.
|
381
|
+
*/
|
382
|
+
PRISM_EXPORTED_FUNCTION void
|
383
|
+
pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
|
384
|
+
pm_options_t options = { 0 };
|
385
|
+
pm_options_read(&options, data);
|
386
|
+
|
387
|
+
pm_parser_t parser;
|
388
|
+
pm_parser_init(&parser, source, size, &options);
|
389
|
+
|
390
|
+
pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
|
391
|
+
.data = (void *) buffer,
|
392
|
+
.callback = serialize_token,
|
393
|
+
};
|
394
|
+
|
395
|
+
parser.lex_callback = &lex_callback;
|
396
|
+
pm_node_t *node = pm_parse(&parser);
|
397
|
+
|
398
|
+
pm_buffer_append_byte(buffer, 0);
|
399
|
+
pm_serialize(&parser, node, buffer);
|
400
|
+
|
401
|
+
pm_node_destroy(&parser, node);
|
402
|
+
pm_parser_free(&parser);
|
403
|
+
pm_options_free(&options);
|
404
|
+
}
|
405
|
+
|
406
|
+
#endif
|