herb 0.11.1 → 0.11.2
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/Rakefile +4 -2
- data/config.yml +6 -0
- data/ext/herb/extconf.rb +8 -31
- data/ext/herb/nodes.c +75 -75
- data/ext/herb/parser_options_helpers.c +26 -0
- data/lib/herb/analysis/partial_index.rb +1 -1
- data/lib/herb/analysis/partial_resolution.rb +27 -0
- data/lib/herb/ast/helpers.rb +1 -1
- data/lib/herb/configuration.rb +11 -1
- data/lib/herb/dev/classifier.rb +1 -1
- data/lib/herb/engine/compiler.rb +5 -8
- data/lib/herb/engine/slots/dynamics_compiler.rb +53 -14
- data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
- data/lib/herb/engine/slots/visitor.rb +32 -4
- data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
- data/lib/herb/parser_options.rb +6 -3
- data/lib/herb/project.rb +19 -8
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +1 -1
- data/sig/herb/analysis/partial_resolution.rbs +8 -0
- data/sig/herb/configuration.rbs +3 -0
- data/sig/herb/engine/slots/dynamics_compiler.rbs +24 -7
- data/sig/herb/engine/slots/visitor.rbs +14 -0
- data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
- data/sig/herb/parser_options.rbs +6 -4
- data/sig/herb.rbs +2 -2
- data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
- data/src/analyze/action_view/generated_handlers.c +36 -36
- data/src/analyze/action_view/image_tag.c +7 -3
- data/src/analyze/action_view/javascript_include_tag.c +6 -3
- data/src/analyze/action_view/link_to.c +23 -23
- data/src/analyze/action_view/registry.c +7 -3
- data/src/analyze/action_view/tag_helper_node_builders.c +6 -13
- data/src/analyze/action_view/tag_helpers.c +139 -90
- data/src/analyze/action_view/turbo_frame_tag.c +5 -4
- data/src/analyze/analyze.c +35 -19
- data/src/analyze/analyze_helpers.c +161 -188
- data/src/analyze/analyzed_ruby.c +8 -7
- data/src/analyze/control_type.c +29 -22
- data/src/analyze/herb_directives.c +16 -20
- data/src/analyze/iteration_nodes.c +69 -24
- data/src/analyze/parse_errors.c +32 -22
- data/src/analyze/postfix_conditionals.c +23 -13
- data/src/analyze/prism_annotate.c +29 -28
- data/src/analyze/render_nodes.c +51 -41
- data/src/analyze/strict_locals.c +14 -15
- data/src/analyze/ternary_conditionals.c +14 -10
- data/src/herb.c +10 -8
- data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
- data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
- data/src/include/analyze/action_view/tag_helpers.h +1 -1
- data/src/include/analyze/analyze.h +3 -2
- data/src/include/analyze/analyzed_ruby.h +4 -2
- data/src/include/analyze/helpers.h +6 -6
- data/src/include/herb.h +3 -2
- data/src/include/parser/parser_options.h +5 -0
- data/src/include/prism/prism_context.h +12 -12
- data/src/include/prism/prism_helpers.h +30 -0
- data/src/include/prism_version.h +11 -0
- data/src/include/version.h +1 -1
- data/src/parser/parser_helpers.c +1 -2
- data/src/parser.c +6 -7
- data/src/parser_options_defaults.c +1 -0
- data/src/prism/prism_helpers.c +84 -50
- data/src/prism/ruby_parser.c +20 -20
- data/templates/ext/herb/nodes.c.erb +5 -5
- data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
- data/templates/java/nodes.c.erb +6 -6
- data/templates/java/parser_options_helpers.c.erb +41 -2
- data/templates/java/parser_options_helpers.h.erb +2 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
- data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
- data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
- data/templates/lib/herb/parser_options.rb.erb +1 -1
- data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
- data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
- data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
- data/templates/src/include/parser/parser_options.h.erb +10 -0
- data/templates/src/include/prism_version.h.erb +17 -0
- data/templates/src/parser_options_defaults.c.erb +1 -1
- data/templates/template.rb +17 -2
- data/templates/wasm/nodes.cpp.erb +5 -5
- data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
- data/vendor/prism/Rakefile +76 -7
- data/vendor/prism/config.yml +174 -161
- data/vendor/prism/include/prism/arena.h +45 -0
- data/vendor/prism/include/prism/arena.hpp +42 -0
- data/vendor/prism/include/prism/ast.h +2738 -611
- data/vendor/prism/include/prism/ast.hpp +641 -0
- data/vendor/prism/include/prism/buffer.h +60 -0
- data/vendor/prism/include/prism/buffer.hpp +55 -0
- data/vendor/prism/include/prism/comments.h +72 -0
- data/vendor/prism/include/prism/compiler/accel.h +26 -0
- data/vendor/prism/include/prism/compiler/align.h +36 -0
- data/vendor/prism/include/prism/compiler/assume.h +25 -0
- data/vendor/prism/include/prism/compiler/branch.h +26 -0
- data/vendor/prism/include/prism/compiler/bswap.h +46 -0
- data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
- data/vendor/prism/include/prism/compiler/endianness.h +34 -0
- data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
- data/vendor/prism/include/prism/compiler/exported.h +24 -0
- data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
- data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
- data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
- data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
- data/vendor/prism/include/prism/compiler/format.h +27 -0
- data/vendor/prism/include/prism/compiler/inline.h +17 -0
- data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
- data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
- data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
- data/vendor/prism/include/prism/compiler/unused.h +18 -0
- data/vendor/prism/include/prism/constant_pool.h +106 -0
- data/vendor/prism/include/prism/diagnostic.h +55 -402
- data/vendor/prism/include/prism/errors_format.h +61 -0
- data/vendor/prism/include/prism/excludes.h +29 -0
- data/vendor/prism/include/prism/integer.h +41 -0
- data/vendor/prism/include/prism/internal/allocator.h +68 -0
- data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
- data/vendor/prism/include/prism/internal/arena.h +108 -0
- data/vendor/prism/include/prism/internal/bit.h +42 -0
- data/vendor/prism/include/prism/internal/buffer.h +94 -0
- data/vendor/prism/include/prism/internal/char.h +145 -0
- data/vendor/prism/include/prism/internal/comments.h +54 -0
- data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
- data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
- data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
- data/vendor/prism/include/prism/internal/integer.h +68 -0
- data/vendor/prism/include/prism/internal/isinf.h +16 -0
- data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
- data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
- data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
- data/vendor/prism/include/prism/internal/memchr.h +15 -0
- data/vendor/prism/include/prism/internal/node.h +42 -0
- data/vendor/prism/include/prism/internal/options.h +232 -0
- data/vendor/prism/include/prism/internal/parser.h +1015 -0
- data/vendor/prism/include/prism/internal/regexp.h +26 -0
- data/vendor/prism/include/prism/internal/serialize.h +39 -0
- data/vendor/prism/include/prism/internal/source.h +72 -0
- data/vendor/prism/include/prism/internal/static_literals.h +60 -0
- data/vendor/prism/include/prism/internal/stringy.h +30 -0
- data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
- data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
- data/vendor/prism/include/prism/internal/tokens.h +11 -0
- data/vendor/prism/include/prism/internal/xxh3.h +16 -0
- data/vendor/prism/include/prism/json.h +40 -0
- data/vendor/prism/include/prism/line_offset_list.h +69 -0
- data/vendor/prism/include/prism/magic_comments.h +53 -0
- data/vendor/prism/include/prism/node.h +59 -49
- data/vendor/prism/include/prism/node.hpp +272 -0
- data/vendor/prism/include/prism/node_type.hpp +38 -0
- data/vendor/prism/include/prism/options.h +154 -279
- data/vendor/prism/include/prism/options.hpp +43 -0
- data/vendor/prism/include/prism/parser.h +367 -870
- data/vendor/prism/include/prism/parser.hpp +274 -0
- data/vendor/prism/include/prism/prettyprint.h +14 -9
- data/vendor/prism/include/prism/serialize.h +123 -0
- data/vendor/prism/include/prism/source.h +163 -0
- data/vendor/prism/include/prism/stream.h +36 -0
- data/vendor/prism/include/prism/string_query.h +82 -0
- data/vendor/prism/include/prism/stringy.h +61 -0
- data/vendor/prism/include/prism/stringy.hpp +31 -0
- data/vendor/prism/include/prism/version.h +20 -3
- data/vendor/prism/include/prism.h +35 -320
- data/vendor/prism/include/prism.hpp +24 -0
- data/vendor/prism/src/arena.c +122 -0
- data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
- data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
- data/vendor/prism/src/comments.c +455 -0
- data/vendor/prism/src/constant_pool.c +406 -0
- data/vendor/prism/src/diagnostic.c +120 -68
- data/vendor/prism/src/encoding.c +8 -3
- data/vendor/prism/src/errors_format.c +519 -0
- data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
- data/vendor/prism/src/json.c +5733 -0
- data/vendor/prism/src/line_offset_list.c +100 -0
- data/vendor/prism/src/list.c +24 -0
- data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
- data/vendor/prism/src/node.c +3465 -7787
- data/vendor/prism/src/options.c +161 -54
- data/vendor/prism/src/parser.c +371 -0
- data/vendor/prism/src/prettyprint.c +421 -354
- data/vendor/prism/src/prism.c +8522 -7280
- data/vendor/prism/src/regexp.c +960 -45
- data/vendor/prism/src/serialize.c +2434 -2048
- data/vendor/prism/src/source.c +524 -0
- data/vendor/prism/src/static_literals.c +303 -360
- data/vendor/prism/src/string_query.c +180 -0
- data/vendor/prism/src/stringy.c +61 -0
- data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
- data/vendor/prism/src/strpbrk.c +447 -0
- data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
- data/vendor/prism/src/xxh3.c +292 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
- data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
- data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
- data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
- data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
- data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
- data/vendor/prism/templates/src/json.c.erb +130 -0
- data/vendor/prism/templates/src/node.c.erb +79 -236
- data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
- data/vendor/prism/templates/src/serialize.c.erb +369 -183
- data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
- data/vendor/prism/templates/template.rb +193 -91
- metadata +100 -42
- data/vendor/prism/include/prism/defines.h +0 -260
- data/vendor/prism/include/prism/pack.h +0 -163
- data/vendor/prism/include/prism/regexp.h +0 -43
- data/vendor/prism/include/prism/static_literals.h +0 -121
- data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
- data/vendor/prism/include/prism/util/pm_char.h +0 -204
- data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
- data/vendor/prism/include/prism/util/pm_integer.h +0 -130
- data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
- data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
- data/vendor/prism/include/prism/util/pm_string.h +0 -200
- data/vendor/prism/src/pack.c +0 -509
- data/vendor/prism/src/util/pm_constant_pool.c +0 -342
- data/vendor/prism/src/util/pm_list.c +0 -49
- data/vendor/prism/src/util/pm_newline_list.c +0 -125
- data/vendor/prism/src/util/pm_string.c +0 -381
- data/vendor/prism/src/util/pm_strpbrk.c +0 -206
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
- data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
- data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
|
@@ -1,57 +1,62 @@
|
|
|
1
|
-
#include "prism.h"
|
|
1
|
+
#include "prism/excludes.h"
|
|
2
|
+
|
|
3
|
+
/* We optionally support serializing to a binary string. For systems that do not
|
|
4
|
+
* want or need this functionality, it can be turned off with the
|
|
5
|
+
* PRISM_EXCLUDE_SERIALIZATION define. */
|
|
6
|
+
#ifdef PRISM_EXCLUDE_SERIALIZATION
|
|
7
|
+
|
|
8
|
+
/* Ensure this translation unit is never empty, even when serialization is
|
|
9
|
+
* excluded. */
|
|
10
|
+
typedef int pm_serialize_unused_t;
|
|
11
|
+
|
|
12
|
+
#else
|
|
13
|
+
|
|
14
|
+
#include "prism/compiler/branch.h"
|
|
15
|
+
#include "prism/compiler/inline.h"
|
|
16
|
+
|
|
17
|
+
#include "prism/internal/allocator.h"
|
|
18
|
+
#include "prism/internal/buffer.h"
|
|
19
|
+
#include "prism/internal/comments.h"
|
|
20
|
+
#include "prism/internal/diagnostic.h"
|
|
21
|
+
#include "prism/internal/encoding.h"
|
|
22
|
+
#include "prism/internal/list.h"
|
|
23
|
+
#include "prism/internal/magic_comments.h"
|
|
24
|
+
#include "prism/internal/options.h"
|
|
25
|
+
#include "prism/internal/parser.h"
|
|
2
26
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
#ifndef PRISM_EXCLUDE_SERIALIZATION
|
|
27
|
+
#include "prism.h"
|
|
28
|
+
#include "prism/ast.h"
|
|
29
|
+
#include "prism/line_offset_list.h"
|
|
7
30
|
|
|
31
|
+
#include <assert.h>
|
|
32
|
+
#include <stdbool.h>
|
|
8
33
|
#include <stdio.h>
|
|
34
|
+
#include <stdlib.h>
|
|
35
|
+
#include <string.h>
|
|
9
36
|
|
|
10
|
-
static
|
|
37
|
+
static PRISM_INLINE uint32_t
|
|
11
38
|
pm_ptrdifft_to_u32(ptrdiff_t value) {
|
|
12
39
|
assert(value >= 0 && ((unsigned long) value) < UINT32_MAX);
|
|
13
40
|
return (uint32_t) value;
|
|
14
41
|
}
|
|
15
42
|
|
|
16
|
-
static
|
|
43
|
+
static PRISM_INLINE uint32_t
|
|
17
44
|
pm_sizet_to_u32(size_t value) {
|
|
18
45
|
assert(value < UINT32_MAX);
|
|
19
46
|
return (uint32_t) value;
|
|
20
47
|
}
|
|
21
48
|
|
|
22
49
|
static void
|
|
23
|
-
pm_serialize_location(const
|
|
24
|
-
|
|
25
|
-
|
|
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));
|
|
50
|
+
pm_serialize_location(const pm_location_t *location, pm_buffer_t *buffer) {
|
|
51
|
+
pm_buffer_append_varuint(buffer, location->start);
|
|
52
|
+
pm_buffer_append_varuint(buffer, location->length);
|
|
30
53
|
}
|
|
31
54
|
|
|
32
55
|
static void
|
|
33
|
-
pm_serialize_string(const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
}
|
|
56
|
+
pm_serialize_string(const pm_string_t *string, pm_buffer_t *buffer) {
|
|
57
|
+
uint32_t length = pm_sizet_to_u32(pm_string_length(string));
|
|
58
|
+
pm_buffer_append_varuint(buffer, length);
|
|
59
|
+
pm_buffer_append_bytes(buffer, pm_string_source(string), length);
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
static void
|
|
@@ -68,97 +73,247 @@ pm_serialize_integer(const pm_integer_t *integer, pm_buffer_t *buffer) {
|
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
/**
|
|
77
|
+
* The kinds of entries on the serialization stack.
|
|
78
|
+
*/
|
|
79
|
+
typedef enum {
|
|
80
|
+
/** A node to serialize, or NULL for an absent optional node. */
|
|
81
|
+
PM_SERIALIZE_ENTRY_NODE,
|
|
82
|
+
|
|
83
|
+
/** Write the lazy marker and placeholders for its skip and length. */
|
|
84
|
+
PM_SERIALIZE_ENTRY_LAZY_HEADER,
|
|
85
|
+
|
|
86
|
+
/** Patch the skip, now that the lazy subtree is about to be written. */
|
|
87
|
+
PM_SERIALIZE_ENTRY_LAZY_START,
|
|
88
|
+
|
|
89
|
+
/** Patch the length, now that the lazy subtree has been written. */
|
|
90
|
+
PM_SERIALIZE_ENTRY_LAZY_END
|
|
91
|
+
} pm_serialize_entry_kind_t;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* An entry on the serialization stack.
|
|
95
|
+
*/
|
|
96
|
+
typedef struct {
|
|
97
|
+
/** The node to serialize, for NODE entries. */
|
|
98
|
+
const pm_node_t *node;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* For NODE entries, the offset of the placeholders that follow the node's
|
|
102
|
+
* lazy marker. For LAZY_* entries, the index of the NODE entry that owns
|
|
103
|
+
* them, which stays valid because that entry is beneath them.
|
|
104
|
+
*/
|
|
105
|
+
size_t offset;
|
|
106
|
+
|
|
107
|
+
/** The kind of this entry. */
|
|
108
|
+
pm_serialize_entry_kind_t kind;
|
|
109
|
+
|
|
110
|
+
/** Whether the children of this node have already been pushed. */
|
|
111
|
+
bool visited;
|
|
112
|
+
} pm_serialize_entry_t;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The explicit stack used to walk the tree, so that serializing deeply nested
|
|
116
|
+
* trees does not depend on the size of the C stack.
|
|
117
|
+
*/
|
|
118
|
+
typedef struct {
|
|
119
|
+
/** The entries on the stack. */
|
|
120
|
+
pm_serialize_entry_t *entries;
|
|
121
|
+
|
|
122
|
+
/** The number of entries on the stack. */
|
|
123
|
+
size_t size;
|
|
124
|
+
|
|
125
|
+
/** The number of entries that fit in the allocated memory. */
|
|
126
|
+
size_t capacity;
|
|
127
|
+
} pm_serialize_stack_t;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Push an entry onto the serialization stack. This may reallocate the stack,
|
|
131
|
+
* which invalidates any pointers into it.
|
|
132
|
+
*/
|
|
71
133
|
static void
|
|
72
|
-
|
|
73
|
-
|
|
134
|
+
pm_serialize_stack_push(pm_serialize_stack_t *stack, pm_serialize_entry_kind_t kind, const pm_node_t *node, size_t offset) {
|
|
135
|
+
if (PRISM_UNLIKELY(stack->size == stack->capacity)) {
|
|
136
|
+
size_t capacity = stack->capacity == 0 ? 64 : stack->capacity * 2;
|
|
137
|
+
pm_serialize_entry_t *entries = (pm_serialize_entry_t *) xrealloc_sized(stack->entries, capacity * sizeof(pm_serialize_entry_t), stack->capacity * sizeof(pm_serialize_entry_t));
|
|
138
|
+
|
|
139
|
+
if (PRISM_UNLIKELY(entries == NULL)) {
|
|
140
|
+
fprintf(stderr, "prism: out of memory; aborting\n");
|
|
141
|
+
abort();
|
|
142
|
+
}
|
|
74
143
|
|
|
75
|
-
|
|
144
|
+
stack->entries = entries;
|
|
145
|
+
stack->capacity = capacity;
|
|
146
|
+
}
|
|
76
147
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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);
|
|
148
|
+
stack->entries[stack->size++] = (pm_serialize_entry_t) { .node = node, .offset = offset, .kind = kind, .visited = false };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Serialize the tree rooted at the given node in post-order: the subtrees of a
|
|
153
|
+
* node's child fields are written in field order, followed by the node's own
|
|
154
|
+
* record. A loader can therefore build every node from a stack of already
|
|
155
|
+
* built children without recursing.
|
|
156
|
+
*
|
|
157
|
+
* The child subtrees of a node with a lazy field are preceded by the lazy
|
|
158
|
+
* marker, the byte length of the subtrees before the lazy field's subtree, and
|
|
159
|
+
* the byte length of the lazy field's subtree, so that a loader can skip it.
|
|
160
|
+
*/
|
|
161
|
+
static void
|
|
162
|
+
pm_serialize_node(pm_node_t *root, pm_buffer_t *buffer) {
|
|
163
|
+
pm_serialize_stack_t stack = { 0 };
|
|
164
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_NODE, root, 0);
|
|
165
|
+
|
|
166
|
+
while (stack.size > 0) {
|
|
167
|
+
pm_serialize_entry_t *entry = &stack.entries[--stack.size];
|
|
168
|
+
|
|
169
|
+
switch (entry->kind) {
|
|
170
|
+
case PM_SERIALIZE_ENTRY_LAZY_HEADER: {
|
|
171
|
+
pm_buffer_append_byte(buffer, <%= Prism::Template::LAZY_MARKER %>);
|
|
172
|
+
stack.entries[entry->offset].offset = buffer->length;
|
|
173
|
+
pm_buffer_append_zeroes(buffer, 8);
|
|
174
|
+
continue;
|
|
107
175
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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);
|
|
176
|
+
case PM_SERIALIZE_ENTRY_LAZY_START: {
|
|
177
|
+
size_t offset = stack.entries[entry->offset].offset;
|
|
178
|
+
uint32_t skip = pm_sizet_to_u32(buffer->length - offset - 8);
|
|
179
|
+
memcpy(buffer->value + offset, &skip, sizeof(uint32_t));
|
|
180
|
+
continue;
|
|
115
181
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
182
|
+
case PM_SERIALIZE_ENTRY_LAZY_END: {
|
|
183
|
+
size_t offset = stack.entries[entry->offset].offset;
|
|
184
|
+
uint32_t skip;
|
|
185
|
+
memcpy(&skip, buffer->value + offset, sizeof(uint32_t));
|
|
186
|
+
|
|
187
|
+
uint32_t length = pm_sizet_to_u32(buffer->length - offset - 8 - skip);
|
|
188
|
+
memcpy(buffer->value + offset + 4, &length, sizeof(uint32_t));
|
|
189
|
+
continue;
|
|
123
190
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
191
|
+
case PM_SERIALIZE_ENTRY_NODE:
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const pm_node_t *node = entry->node;
|
|
196
|
+
|
|
197
|
+
if (node == NULL) {
|
|
198
|
+
pm_buffer_append_byte(buffer, 0);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (!entry->visited) {
|
|
203
|
+
/* Leave the node on the stack beneath its children, which are
|
|
204
|
+
* pushed in reverse field order so that they are popped, and
|
|
205
|
+
* therefore written, in field order. A node without children is
|
|
206
|
+
* written straight away instead. */
|
|
207
|
+
entry->visited = true;
|
|
208
|
+
size_t index = stack.size++;
|
|
209
|
+
|
|
210
|
+
switch (PM_NODE_TYPE(node)) {
|
|
211
|
+
<%- nodes.each do |node| -%>
|
|
212
|
+
<%- next if node.child_fields.empty? -%>
|
|
213
|
+
case <%= node.type %>: {
|
|
214
|
+
const pm_<%= node.human %>_t *cast = (const pm_<%= node.human %>_t *) node;
|
|
215
|
+
<%- node.child_fields.reverse_each do |field| -%>
|
|
216
|
+
<%- case field -%>
|
|
217
|
+
<%- when Prism::Template::NodeListField -%>
|
|
218
|
+
for (size_t list_index = cast-><%= field.name %>.size; list_index > 0; list_index--) {
|
|
219
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_NODE, cast-><%= field.name %>.nodes[list_index - 1], 0);
|
|
220
|
+
}
|
|
221
|
+
<%- else -%>
|
|
222
|
+
<%- if field == node.lazy_field -%>
|
|
223
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_LAZY_END, NULL, index);
|
|
224
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_NODE, (const pm_node_t *) cast-><%= field.name %>, 0);
|
|
225
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_LAZY_START, NULL, index);
|
|
226
|
+
<%- else -%>
|
|
227
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_NODE, (const pm_node_t *) cast-><%= field.name %>, 0);
|
|
228
|
+
<%- end -%>
|
|
229
|
+
<%- end -%>
|
|
230
|
+
<%- end -%>
|
|
231
|
+
<%- if node.lazy_field -%>
|
|
232
|
+
pm_serialize_stack_push(&stack, PM_SERIALIZE_ENTRY_LAZY_HEADER, NULL, index);
|
|
233
|
+
<%- end -%>
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
<%- end -%>
|
|
237
|
+
default:
|
|
238
|
+
break;
|
|
135
239
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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;
|
|
240
|
+
|
|
241
|
+
if (stack.size != index + 1) continue;
|
|
242
|
+
stack.size--;
|
|
155
243
|
}
|
|
244
|
+
|
|
245
|
+
pm_buffer_append_byte(buffer, (uint8_t) PM_NODE_TYPE(node));
|
|
246
|
+
<%- if Prism::Template::INCLUDE_NODE_ID -%>
|
|
247
|
+
pm_buffer_append_varuint(buffer, node->node_id);
|
|
156
248
|
<%- end -%>
|
|
249
|
+
pm_serialize_location(&node->location, buffer);
|
|
250
|
+
|
|
251
|
+
switch (PM_NODE_TYPE(node)) {
|
|
252
|
+
/* A ScopeNode is never part of the tree, so it has no fields to
|
|
253
|
+
* serialize. */
|
|
254
|
+
case PM_SCOPE_NODE:
|
|
255
|
+
break;
|
|
256
|
+
<%- nodes.each do |node| -%>
|
|
257
|
+
case <%= node.type %>: {
|
|
258
|
+
<%- if node.fields.any? { |field| !field.is_a?(Prism::Template::NodeField) && !field.is_a?(Prism::Template::OptionalNodeField) && field.should_be_serialized? } -%>
|
|
259
|
+
const pm_<%= node.human %>_t *cast = (const pm_<%= node.human %>_t *) node;
|
|
260
|
+
<%- end -%>
|
|
261
|
+
<%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS && !node.flags -%>
|
|
262
|
+
pm_buffer_append_varuint(buffer, (uint32_t) node->flags);
|
|
263
|
+
<%- end -%>
|
|
264
|
+
<%- node.fields.each do |field| -%>
|
|
265
|
+
<%- case field -%>
|
|
266
|
+
<%- when Prism::Template::NodeField, Prism::Template::OptionalNodeField -%>
|
|
267
|
+
<%- when Prism::Template::NodeListField -%>
|
|
268
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(cast-><%= field.name %>.size));
|
|
269
|
+
<%- when Prism::Template::StringField -%>
|
|
270
|
+
pm_serialize_string(&cast-><%= field.name %>, buffer);
|
|
271
|
+
<%- when Prism::Template::ConstantField, Prism::Template::OptionalConstantField -%>
|
|
272
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(cast-><%= field.name %>));
|
|
273
|
+
<%- when Prism::Template::ConstantListField -%>
|
|
274
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(cast-><%= field.name %>.size));
|
|
275
|
+
for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
|
|
276
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(cast-><%= field.name %>.ids[index]));
|
|
277
|
+
}
|
|
278
|
+
<%- when Prism::Template::LocationField -%>
|
|
279
|
+
<%- if field.should_be_serialized? -%>
|
|
280
|
+
pm_serialize_location(&cast-><%= field.name %>, buffer);
|
|
281
|
+
<%- end -%>
|
|
282
|
+
<%- when Prism::Template::OptionalLocationField -%>
|
|
283
|
+
<%- if field.should_be_serialized? -%>
|
|
284
|
+
if (cast-><%= field.name %>.length == 0) {
|
|
285
|
+
pm_buffer_append_byte(buffer, 0);
|
|
286
|
+
} else {
|
|
287
|
+
pm_buffer_append_byte(buffer, 1);
|
|
288
|
+
pm_serialize_location(&cast-><%= field.name %>, buffer);
|
|
289
|
+
}
|
|
290
|
+
<%- end -%>
|
|
291
|
+
<%- when Prism::Template::UInt8Field -%>
|
|
292
|
+
pm_buffer_append_byte(buffer, cast-><%= field.name %>);
|
|
293
|
+
<%- when Prism::Template::UInt32Field -%>
|
|
294
|
+
pm_buffer_append_varuint(buffer, cast-><%= field.name %>);
|
|
295
|
+
<%- when Prism::Template::IntegerField -%>
|
|
296
|
+
pm_serialize_integer(&cast-><%= field.name %>, buffer);
|
|
297
|
+
<%- when Prism::Template::DoubleField -%>
|
|
298
|
+
pm_buffer_append_double(buffer, cast-><%= field.name %>);
|
|
299
|
+
<%- else -%>
|
|
300
|
+
<%- raise -%>
|
|
301
|
+
<%- end -%>
|
|
302
|
+
<%- end -%>
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
<%- end -%>
|
|
306
|
+
}
|
|
157
307
|
}
|
|
308
|
+
|
|
309
|
+
xfree_sized(stack.entries, stack.capacity * sizeof(pm_serialize_entry_t));
|
|
158
310
|
}
|
|
159
311
|
|
|
160
|
-
|
|
161
|
-
|
|
312
|
+
/*
|
|
313
|
+
* Serialize the given list of offsets to the given buffer.
|
|
314
|
+
*/
|
|
315
|
+
void
|
|
316
|
+
pm_serialize_line_offset_list(pm_line_offset_list_t *list, pm_buffer_t *buffer) {
|
|
162
317
|
uint32_t size = pm_sizet_to_u32(list->size);
|
|
163
318
|
pm_buffer_append_varuint(buffer, size);
|
|
164
319
|
|
|
@@ -169,60 +324,90 @@ pm_serialize_newline_list(pm_newline_list_t *list, pm_buffer_t *buffer) {
|
|
|
169
324
|
}
|
|
170
325
|
|
|
171
326
|
static void
|
|
172
|
-
pm_serialize_comment(
|
|
327
|
+
pm_serialize_comment(pm_comment_t *comment, pm_buffer_t *buffer) {
|
|
173
328
|
// serialize type
|
|
174
329
|
pm_buffer_append_byte(buffer, (uint8_t) comment->type);
|
|
175
330
|
|
|
176
331
|
// serialize location
|
|
177
|
-
pm_serialize_location(
|
|
332
|
+
pm_serialize_location(&comment->location, buffer);
|
|
178
333
|
}
|
|
179
334
|
|
|
180
335
|
/**
|
|
181
336
|
* Serialize the given list of comments to the given buffer.
|
|
182
337
|
*/
|
|
183
338
|
void
|
|
184
|
-
pm_serialize_comment_list(
|
|
339
|
+
pm_serialize_comment_list(pm_list_t *list, pm_buffer_t *buffer) {
|
|
185
340
|
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
|
186
341
|
|
|
187
342
|
pm_comment_t *comment;
|
|
188
343
|
for (comment = (pm_comment_t *) list->head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
|
|
189
|
-
pm_serialize_comment(
|
|
344
|
+
pm_serialize_comment(comment, buffer);
|
|
190
345
|
}
|
|
191
346
|
}
|
|
192
347
|
|
|
348
|
+
<%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS -%>
|
|
349
|
+
/**
|
|
350
|
+
* Serialize the comments attached to each node. This is the number of nodes
|
|
351
|
+
* that own comments, followed by each of those nodes' id, the number of
|
|
352
|
+
* comments it owns, and the index of each of those comments in the comment
|
|
353
|
+
* list.
|
|
354
|
+
*/
|
|
193
355
|
static void
|
|
194
|
-
|
|
356
|
+
pm_serialize_comment_attachments(const pm_comment_attachments_t *attachments, pm_buffer_t *buffer) {
|
|
357
|
+
uint32_t count = 0;
|
|
358
|
+
for (uint32_t node_id = 0; node_id < attachments->ranges_size; node_id++) {
|
|
359
|
+
if (attachments->ranges[node_id].length > 0) count++;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
pm_buffer_append_varuint(buffer, count);
|
|
363
|
+
|
|
364
|
+
for (uint32_t node_id = 0; node_id < attachments->ranges_size; node_id++) {
|
|
365
|
+
pm_comment_range_t range = attachments->ranges[node_id];
|
|
366
|
+
if (range.length == 0) continue;
|
|
367
|
+
|
|
368
|
+
pm_buffer_append_varuint(buffer, node_id);
|
|
369
|
+
pm_buffer_append_varuint(buffer, range.length);
|
|
370
|
+
|
|
371
|
+
for (uint32_t index = 0; index < range.length; index++) {
|
|
372
|
+
pm_buffer_append_varuint(buffer, attachments->attachments[range.index + index]);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
<%- end -%>
|
|
377
|
+
|
|
378
|
+
static void
|
|
379
|
+
pm_serialize_magic_comment(pm_magic_comment_t *magic_comment, pm_buffer_t *buffer) {
|
|
195
380
|
// serialize key location
|
|
196
|
-
pm_buffer_append_varuint(buffer,
|
|
197
|
-
pm_buffer_append_varuint(buffer,
|
|
381
|
+
pm_buffer_append_varuint(buffer, magic_comment->key.start);
|
|
382
|
+
pm_buffer_append_varuint(buffer, magic_comment->key.length);
|
|
198
383
|
|
|
199
384
|
// serialize value location
|
|
200
|
-
pm_buffer_append_varuint(buffer,
|
|
201
|
-
pm_buffer_append_varuint(buffer,
|
|
385
|
+
pm_buffer_append_varuint(buffer, magic_comment->value.start);
|
|
386
|
+
pm_buffer_append_varuint(buffer, magic_comment->value.length);
|
|
202
387
|
}
|
|
203
388
|
|
|
204
389
|
static void
|
|
205
|
-
pm_serialize_magic_comment_list(
|
|
390
|
+
pm_serialize_magic_comment_list(pm_list_t *list, pm_buffer_t *buffer) {
|
|
206
391
|
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
|
207
392
|
|
|
208
393
|
pm_magic_comment_t *magic_comment;
|
|
209
394
|
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(
|
|
395
|
+
pm_serialize_magic_comment(magic_comment, buffer);
|
|
211
396
|
}
|
|
212
397
|
}
|
|
213
398
|
|
|
214
399
|
static void
|
|
215
400
|
pm_serialize_data_loc(const pm_parser_t *parser, pm_buffer_t *buffer) {
|
|
216
|
-
if (parser->data_loc.
|
|
401
|
+
if (parser->data_loc.length == 0) {
|
|
217
402
|
pm_buffer_append_byte(buffer, 0);
|
|
218
403
|
} else {
|
|
219
404
|
pm_buffer_append_byte(buffer, 1);
|
|
220
|
-
pm_serialize_location(
|
|
405
|
+
pm_serialize_location(&parser->data_loc, buffer);
|
|
221
406
|
}
|
|
222
407
|
}
|
|
223
408
|
|
|
224
409
|
static void
|
|
225
|
-
pm_serialize_diagnostic(
|
|
410
|
+
pm_serialize_diagnostic(pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
|
|
226
411
|
// serialize the type
|
|
227
412
|
pm_buffer_append_varuint(buffer, (uint32_t) diagnostic->diag_id);
|
|
228
413
|
|
|
@@ -232,18 +417,18 @@ pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buf
|
|
|
232
417
|
pm_buffer_append_string(buffer, diagnostic->message, message_length);
|
|
233
418
|
|
|
234
419
|
// serialize location
|
|
235
|
-
pm_serialize_location(
|
|
420
|
+
pm_serialize_location(&diagnostic->location, buffer);
|
|
236
421
|
|
|
237
422
|
pm_buffer_append_byte(buffer, diagnostic->level);
|
|
238
423
|
}
|
|
239
424
|
|
|
240
425
|
static void
|
|
241
|
-
pm_serialize_diagnostic_list(
|
|
426
|
+
pm_serialize_diagnostic_list(pm_list_t *list, pm_buffer_t *buffer) {
|
|
242
427
|
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
|
243
428
|
|
|
244
429
|
pm_diagnostic_t *diagnostic;
|
|
245
430
|
for (diagnostic = (pm_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) {
|
|
246
|
-
pm_serialize_diagnostic(
|
|
431
|
+
pm_serialize_diagnostic(diagnostic, buffer);
|
|
247
432
|
}
|
|
248
433
|
}
|
|
249
434
|
|
|
@@ -261,14 +446,17 @@ static void
|
|
|
261
446
|
pm_serialize_metadata(pm_parser_t *parser, pm_buffer_t *buffer) {
|
|
262
447
|
pm_serialize_encoding(parser->encoding, buffer);
|
|
263
448
|
pm_buffer_append_varsint(buffer, parser->start_line);
|
|
264
|
-
|
|
449
|
+
pm_buffer_append_uint64(buffer, pm_parser_checksum(parser));
|
|
450
|
+
pm_serialize_line_offset_list(&parser->line_offsets, buffer);
|
|
265
451
|
<%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS -%>
|
|
266
|
-
pm_serialize_comment_list(
|
|
452
|
+
pm_serialize_comment_list(&parser->comment_list, buffer);
|
|
453
|
+
pm_serialize_comment_attachments(&parser->comment_attachments, buffer);
|
|
267
454
|
<%- end -%>
|
|
268
|
-
pm_serialize_magic_comment_list(
|
|
455
|
+
pm_serialize_magic_comment_list(&parser->magic_comment_list, buffer);
|
|
269
456
|
pm_serialize_data_loc(parser, buffer);
|
|
270
|
-
pm_serialize_diagnostic_list(
|
|
271
|
-
pm_serialize_diagnostic_list(
|
|
457
|
+
pm_serialize_diagnostic_list(&parser->error_list, buffer);
|
|
458
|
+
pm_serialize_diagnostic_list(&parser->warning_list, buffer);
|
|
459
|
+
pm_buffer_append_byte(buffer, (uint8_t) parser->continuable);
|
|
272
460
|
}
|
|
273
461
|
|
|
274
462
|
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
|
@@ -288,7 +476,7 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer)
|
|
|
288
476
|
pm_buffer_append_varuint(buffer, parser->constant_pool.size);
|
|
289
477
|
|
|
290
478
|
// Now we're going to serialize the content of the node.
|
|
291
|
-
pm_serialize_node(
|
|
479
|
+
pm_serialize_node(node, buffer);
|
|
292
480
|
|
|
293
481
|
// Now we're going to serialize the offset of the constant pool back where
|
|
294
482
|
// we left space for it.
|
|
@@ -308,28 +496,12 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer)
|
|
|
308
496
|
pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
|
|
309
497
|
size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
|
|
310
498
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
// is a buffer offset.
|
|
317
|
-
uint32_t content_offset = pm_sizet_to_u32(buffer->length);
|
|
318
|
-
uint32_t owned_mask = 1U << 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
|
-
}
|
|
499
|
+
// Write the constant contents into the buffer after the constant
|
|
500
|
+
// pool. In place of the source offset, we store a buffer offset.
|
|
501
|
+
uint32_t content_offset = pm_sizet_to_u32(buffer->length);
|
|
502
|
+
memcpy(buffer->value + buffer_offset, &content_offset, 4);
|
|
503
|
+
pm_buffer_append_bytes(buffer, constant->start, constant->length);
|
|
331
504
|
|
|
332
|
-
// Now we can write the length of the constant into the buffer.
|
|
333
505
|
uint32_t constant_length = pm_sizet_to_u32(constant->length);
|
|
334
506
|
memcpy(buffer->value + buffer_offset + 4, &constant_length, 4);
|
|
335
507
|
}
|
|
@@ -337,7 +509,7 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer)
|
|
|
337
509
|
}
|
|
338
510
|
|
|
339
511
|
static void
|
|
340
|
-
serialize_token(
|
|
512
|
+
serialize_token(pm_parser_t *parser, pm_token_t *token, void *data) {
|
|
341
513
|
pm_buffer_t *buffer = (pm_buffer_t *) data;
|
|
342
514
|
|
|
343
515
|
pm_buffer_append_varuint(buffer, token->type);
|
|
@@ -349,58 +521,72 @@ serialize_token(void *data, pm_parser_t *parser, pm_token_t *token) {
|
|
|
349
521
|
/**
|
|
350
522
|
* Lex the given source and serialize to the given buffer.
|
|
351
523
|
*/
|
|
352
|
-
|
|
524
|
+
void
|
|
353
525
|
pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
|
|
354
526
|
pm_options_t options = { 0 };
|
|
355
527
|
pm_options_read(&options, data);
|
|
356
528
|
|
|
529
|
+
pm_arena_t arena = { 0 };
|
|
357
530
|
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
|
-
};
|
|
531
|
+
pm_parser_init(&arena, &parser, source, size, &options);
|
|
364
532
|
|
|
365
|
-
parser
|
|
366
|
-
|
|
533
|
+
pm_parser_lex_callback_set(&parser, serialize_token, buffer);
|
|
534
|
+
pm_parse(&parser);
|
|
367
535
|
|
|
368
536
|
// Append 0 to mark end of tokens.
|
|
369
537
|
pm_buffer_append_byte(buffer, 0);
|
|
370
538
|
|
|
371
539
|
pm_serialize_metadata(&parser, buffer);
|
|
372
540
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
541
|
+
pm_parser_cleanup(&parser);
|
|
542
|
+
pm_arena_cleanup(&arena);
|
|
543
|
+
pm_options_cleanup(&options);
|
|
376
544
|
}
|
|
377
545
|
|
|
378
546
|
/**
|
|
379
547
|
* Parse and serialize both the AST and the tokens represented by the given
|
|
380
548
|
* source to the given buffer.
|
|
381
549
|
*/
|
|
382
|
-
|
|
550
|
+
void
|
|
383
551
|
pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
|
|
384
552
|
pm_options_t options = { 0 };
|
|
385
553
|
pm_options_read(&options, data);
|
|
386
554
|
|
|
555
|
+
pm_arena_t arena = { 0 };
|
|
387
556
|
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
|
-
};
|
|
557
|
+
pm_parser_init(&arena, &parser, source, size, &options);
|
|
394
558
|
|
|
395
|
-
parser
|
|
559
|
+
pm_parser_lex_callback_set(&parser, serialize_token, buffer);
|
|
396
560
|
pm_node_t *node = pm_parse(&parser);
|
|
397
561
|
|
|
398
562
|
pm_buffer_append_byte(buffer, 0);
|
|
399
563
|
pm_serialize(&parser, node, buffer);
|
|
400
564
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
565
|
+
pm_parser_cleanup(&parser);
|
|
566
|
+
pm_arena_cleanup(&arena);
|
|
567
|
+
pm_options_cleanup(&options);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Parse the source and return true if it parses without errors or warnings.
|
|
572
|
+
*/
|
|
573
|
+
bool
|
|
574
|
+
pm_serialize_parse_success_p(const uint8_t *source, size_t size, const char *data) {
|
|
575
|
+
pm_options_t options = { 0 };
|
|
576
|
+
pm_options_read(&options, data);
|
|
577
|
+
|
|
578
|
+
pm_arena_t arena = { 0 };
|
|
579
|
+
pm_parser_t parser;
|
|
580
|
+
pm_parser_init(&arena, &parser, source, size, &options);
|
|
581
|
+
|
|
582
|
+
pm_parse(&parser);
|
|
583
|
+
|
|
584
|
+
bool result = parser.error_list.size == 0;
|
|
585
|
+
pm_parser_cleanup(&parser);
|
|
586
|
+
pm_arena_cleanup(&arena);
|
|
587
|
+
pm_options_cleanup(&options);
|
|
588
|
+
|
|
589
|
+
return result;
|
|
404
590
|
}
|
|
405
591
|
|
|
406
592
|
#endif
|