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
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An implementation of the XXH3 hash function.
|
|
3
|
+
*
|
|
4
|
+
* The reason some of these names do not look quite like the style of the rest
|
|
5
|
+
* of the code in Prism is that this was adapted straight from the XXH3
|
|
6
|
+
* specification here:
|
|
7
|
+
*
|
|
8
|
+
* https://github.com/Cyan4973/xxHash/blob/release/doc/xxhash_spec.md
|
|
9
|
+
*
|
|
10
|
+
* To better understand this code it is recommended to read the XXH3
|
|
11
|
+
* specification linked above, where you should be able to follow along with
|
|
12
|
+
* this implementation more easily. Note this only implements the XXH3_64
|
|
13
|
+
* variant with the default secret and a seed of 0. Additionally it does not
|
|
14
|
+
* include a lot of the various CPU-specific optimizations that exist in the
|
|
15
|
+
* reference implementation.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "prism/internal/xxh3.h"
|
|
19
|
+
|
|
20
|
+
#include "prism/compiler/accel.h"
|
|
21
|
+
#include "prism/compiler/bswap.h"
|
|
22
|
+
#include "prism/compiler/endianness.h"
|
|
23
|
+
|
|
24
|
+
#include <string.h>
|
|
25
|
+
|
|
26
|
+
#if defined(PRISM_HAS_NEON) && defined(PRISM_LITTLE_ENDIAN_COMPTIME)
|
|
27
|
+
#include <arm_neon.h>
|
|
28
|
+
#define XXH3_NEON
|
|
29
|
+
#elif defined(PRISM_HAS_SSE2)
|
|
30
|
+
#include <emmintrin.h>
|
|
31
|
+
#define XXH3_SSE2
|
|
32
|
+
#endif
|
|
33
|
+
|
|
34
|
+
#if defined(__SIZEOF_INT128__)
|
|
35
|
+
static uint64_t
|
|
36
|
+
XXH3_mul128_fold64(uint64_t lhs, uint64_t rhs) {
|
|
37
|
+
__uint128_t x = (__uint128_t) lhs * (__uint128_t) rhs;
|
|
38
|
+
return ((uint64_t) (x & 0xFFFFFFFFFFFFFFFFULL)) ^ ((uint64_t) (x >> 64));
|
|
39
|
+
}
|
|
40
|
+
#else
|
|
41
|
+
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
|
|
42
|
+
#include <intrin.h>
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
static uint64_t
|
|
46
|
+
XXH3_mul128_fold64(uint64_t lhs, uint64_t rhs) {
|
|
47
|
+
uint64_t lo, hi;
|
|
48
|
+
#if defined(_MSC_VER) && defined(_M_X64)
|
|
49
|
+
lo = _umul128(lhs, rhs, &hi);
|
|
50
|
+
#elif defined(_MSC_VER) && defined(_M_ARM64)
|
|
51
|
+
hi = __umulh(lhs, rhs);
|
|
52
|
+
lo = lhs * rhs;
|
|
53
|
+
#else
|
|
54
|
+
uint64_t lo_lo = (lhs & 0xFFFFFFFF) * (rhs & 0xFFFFFFFF);
|
|
55
|
+
uint64_t hi_lo = (lhs >> 32) * (rhs & 0xFFFFFFFF);
|
|
56
|
+
uint64_t lo_hi = (lhs & 0xFFFFFFFF) * (rhs >> 32);
|
|
57
|
+
uint64_t hi_hi = (lhs >> 32) * (rhs >> 32);
|
|
58
|
+
|
|
59
|
+
uint64_t cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
|
|
60
|
+
hi = hi_hi + (hi_lo >> 32) + (cross >> 32);
|
|
61
|
+
lo = (cross << 32) | (lo_lo & 0xFFFFFFFF);
|
|
62
|
+
#endif
|
|
63
|
+
return lo ^ hi;
|
|
64
|
+
}
|
|
65
|
+
#endif
|
|
66
|
+
|
|
67
|
+
static uint32_t
|
|
68
|
+
read32(const void* ptr) {
|
|
69
|
+
uint32_t val;
|
|
70
|
+
memcpy(&val, ptr, sizeof(val));
|
|
71
|
+
if (!PRISM_LITTLE_ENDIAN_RUNTIME) {
|
|
72
|
+
val = pm_bswap32(val);
|
|
73
|
+
}
|
|
74
|
+
return val;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static uint64_t
|
|
78
|
+
read64(const void* ptr) {
|
|
79
|
+
uint64_t val;
|
|
80
|
+
memcpy(&val, ptr, sizeof(val));
|
|
81
|
+
if (!PRISM_LITTLE_ENDIAN_RUNTIME) {
|
|
82
|
+
val = pm_bswap64(val);
|
|
83
|
+
}
|
|
84
|
+
return val;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static const uint64_t PRIME32_1 = 0x9E3779B1U;
|
|
88
|
+
static const uint64_t PRIME32_2 = 0x85EBCA77U;
|
|
89
|
+
static const uint64_t PRIME32_3 = 0xC2B2AE3DU;
|
|
90
|
+
static const uint64_t PRIME64_1 = 0x9E3779B185EBCA87ULL;
|
|
91
|
+
static const uint64_t PRIME64_2 = 0xC2B2AE3D27D4EB4FULL;
|
|
92
|
+
static const uint64_t PRIME64_3 = 0x165667B19E3779F9ULL;
|
|
93
|
+
static const uint64_t PRIME64_4 = 0x85EBCA77C2B2AE63ULL;
|
|
94
|
+
static const uint64_t PRIME64_5 = 0x27D4EB2F165667C5ULL;
|
|
95
|
+
static const uint64_t PRIME_MX1 = 0x165667919E3779F9ULL;
|
|
96
|
+
static const uint64_t PRIME_MX2 = 0x9FB21C651E98DF25ULL;
|
|
97
|
+
|
|
98
|
+
static const uint8_t secret[192] = {
|
|
99
|
+
0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
|
|
100
|
+
0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
|
|
101
|
+
0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
|
|
102
|
+
0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
|
|
103
|
+
0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
|
|
104
|
+
0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
|
|
105
|
+
0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
|
|
106
|
+
0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
|
|
107
|
+
0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
|
|
108
|
+
0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
|
|
109
|
+
0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
|
|
110
|
+
0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
static uint64_t
|
|
114
|
+
avalanche(uint64_t x) {
|
|
115
|
+
x ^= (x >> 37);
|
|
116
|
+
x *= PRIME_MX1;
|
|
117
|
+
x ^= (x >> 32);
|
|
118
|
+
return x;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static uint64_t
|
|
122
|
+
avalanche_XXH64(uint64_t x) {
|
|
123
|
+
x ^= (x >> 33);
|
|
124
|
+
x *= PRIME64_2;
|
|
125
|
+
x ^= (x >> 29);
|
|
126
|
+
x *= PRIME64_3;
|
|
127
|
+
x ^= (x >> 32);
|
|
128
|
+
return x;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static uint64_t
|
|
132
|
+
XXH3_64_empty(void) {
|
|
133
|
+
return avalanche_XXH64(read64(secret + 56) ^ read64(secret + 64));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static uint64_t
|
|
137
|
+
XXH3_64_1to3(const uint8_t *input, size_t length) {
|
|
138
|
+
uint32_t combined = (uint32_t) input[length - 1] | ((uint32_t) length << 8) | ((uint32_t) input[0] << 16) | ((uint32_t) input[length >> 1] << 24);
|
|
139
|
+
return avalanche_XXH64((uint64_t) (read32(secret) ^ read32(secret + 4)) ^ (uint64_t) combined);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static uint64_t
|
|
143
|
+
XXH3_64_4to8(const uint8_t *input, size_t length) {
|
|
144
|
+
#define rot(x_, r_) (((x_) << (r_)) | ((x_) >> (64 - (r_))))
|
|
145
|
+
|
|
146
|
+
uint64_t combined = (uint64_t) read32(input + length - 4) | ((uint64_t) read32(input) << 32);
|
|
147
|
+
uint64_t value = (read64(secret + 8) ^ read64(secret + 16)) ^ combined;
|
|
148
|
+
value ^= rot(value, 49) ^ rot(value, 24);
|
|
149
|
+
value *= PRIME_MX2;
|
|
150
|
+
value ^= ((value >> 35) + length);
|
|
151
|
+
value *= PRIME_MX2;
|
|
152
|
+
value ^= (value >> 28);
|
|
153
|
+
return value;
|
|
154
|
+
|
|
155
|
+
#undef rot
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static uint64_t
|
|
159
|
+
XXH3_64_9to16(const uint8_t *input, size_t length) {
|
|
160
|
+
uint64_t lo = (read64(secret + 24) ^ read64(secret + 32)) ^ read64(input);
|
|
161
|
+
uint64_t hi = (read64(secret + 40) ^ read64(secret + 48)) ^ read64(input + length - 8);
|
|
162
|
+
return avalanche(length + pm_bswap64(lo) + hi + XXH3_mul128_fold64(lo, hi));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static uint64_t
|
|
166
|
+
XXH3_64_17to240(const uint8_t *input, size_t length) {
|
|
167
|
+
#define mix(data_, offset_) XXH3_mul128_fold64(read64((data_)) ^ read64(secret + (offset_)), read64((data_) + 8) ^ read64(secret + (offset_) + 8))
|
|
168
|
+
|
|
169
|
+
uint64_t acc = length * PRIME64_1;
|
|
170
|
+
|
|
171
|
+
if (length <= 128) {
|
|
172
|
+
size_t idx = (length - 1) / 32;
|
|
173
|
+
do {
|
|
174
|
+
acc += mix(input + idx * 16, idx * 32) + mix(input + length - idx * 16 - 16, idx * 32 + 16);
|
|
175
|
+
} while (idx--);
|
|
176
|
+
} else {
|
|
177
|
+
for (size_t idx = 0; idx < 8; idx++) {
|
|
178
|
+
acc += mix(input + idx * 16, idx * 16);
|
|
179
|
+
}
|
|
180
|
+
acc = avalanche(acc);
|
|
181
|
+
for (size_t idx = 8; idx < length >> 4; idx++) {
|
|
182
|
+
acc += mix(input + idx * 16, (idx - 8) * 16 + 3);
|
|
183
|
+
}
|
|
184
|
+
acc += mix(input + length - 16, 119);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return avalanche(acc);
|
|
188
|
+
|
|
189
|
+
#undef mix
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
static void
|
|
193
|
+
accumulate(uint64_t acc[8], const uint8_t *stripe, size_t secret_offset) {
|
|
194
|
+
#if defined(XXH3_NEON)
|
|
195
|
+
for (int idx = 0; idx < 8; idx += 2) {
|
|
196
|
+
uint64x2_t data = vreinterpretq_u64_u8(vld1q_u8(stripe + 8 * idx));
|
|
197
|
+
uint64x2_t value = veorq_u64(data, vreinterpretq_u64_u8(vld1q_u8(secret + secret_offset + 8 * idx)));
|
|
198
|
+
uint64x2_t product = vmull_u32(vmovn_u64(value), vshrn_n_u64(value, 32));
|
|
199
|
+
vst1q_u64(acc + idx, vaddq_u64(vld1q_u64(acc + idx), vaddq_u64(vextq_u64(data, data, 1), product)));
|
|
200
|
+
}
|
|
201
|
+
#elif defined(XXH3_SSE2)
|
|
202
|
+
for (int idx = 0; idx < 8; idx += 2) {
|
|
203
|
+
__m128i data = _mm_loadu_si128((const __m128i *) (stripe + 8 * idx));
|
|
204
|
+
__m128i value = _mm_xor_si128(data, _mm_loadu_si128((const __m128i *) (secret + secret_offset + 8 * idx)));
|
|
205
|
+
__m128i product = _mm_mul_epu32(value, _mm_shuffle_epi32(value, _MM_SHUFFLE(0, 3, 0, 1)));
|
|
206
|
+
_mm_storeu_si128((__m128i *) (acc + idx), _mm_add_epi64(_mm_loadu_si128((const __m128i *) (acc + idx)), _mm_add_epi64(_mm_shuffle_epi32(data, _MM_SHUFFLE(1, 0, 3, 2)), product)));
|
|
207
|
+
}
|
|
208
|
+
#else
|
|
209
|
+
for (int idx = 0; idx < 8; idx++) {
|
|
210
|
+
uint64_t data = read64(stripe + 8 * idx);
|
|
211
|
+
uint64_t value = data ^ read64(secret + secret_offset + 8 * idx);
|
|
212
|
+
acc[idx ^ 1] = acc[idx ^ 1] + data;
|
|
213
|
+
acc[idx] += (value & 0xFFFFFFFF) * (value >> 32);
|
|
214
|
+
}
|
|
215
|
+
#endif
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static uint64_t
|
|
219
|
+
XXH3_64_large(const uint8_t *input, size_t length) {
|
|
220
|
+
const size_t secret_length = sizeof(secret);
|
|
221
|
+
const size_t stripes_per_block = (secret_length - 64) / 8;
|
|
222
|
+
const size_t block_size = 64 * stripes_per_block;
|
|
223
|
+
const size_t block_count = (length - 1) / block_size;
|
|
224
|
+
const size_t last_offset = block_count * block_size;
|
|
225
|
+
|
|
226
|
+
uint64_t acc[8] = {
|
|
227
|
+
PRIME32_3, PRIME64_1, PRIME64_2, PRIME64_3,
|
|
228
|
+
PRIME64_4, PRIME32_2, PRIME64_5, PRIME32_1
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
for (size_t block_idx = 0; block_idx < block_count; block_idx++) {
|
|
232
|
+
const uint8_t *block = input + block_idx * block_size;
|
|
233
|
+
|
|
234
|
+
for (size_t stripe_idx = 0; stripe_idx < stripes_per_block; stripe_idx++) {
|
|
235
|
+
accumulate(acc, block + stripe_idx * 64, stripe_idx * 8);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
#if defined(XXH3_NEON)
|
|
239
|
+
const uint32x2_t prime = vdup_n_u32((uint32_t) PRIME32_1);
|
|
240
|
+
for (size_t idx = 0; idx < 8; idx += 2) {
|
|
241
|
+
uint64x2_t value = vld1q_u64(acc + idx);
|
|
242
|
+
value = veorq_u64(value, vshrq_n_u64(value, 47));
|
|
243
|
+
value = veorq_u64(value, vreinterpretq_u64_u8(vld1q_u8(secret + secret_length - 64 + idx * 8)));
|
|
244
|
+
vst1q_u64(acc + idx, vaddq_u64(vmull_u32(vmovn_u64(value), prime), vshlq_n_u64(vmull_u32(vshrn_n_u64(value, 32), prime), 32)));
|
|
245
|
+
}
|
|
246
|
+
#elif defined(XXH3_SSE2)
|
|
247
|
+
const __m128i prime = _mm_set1_epi32((int) (uint32_t) PRIME32_1);
|
|
248
|
+
for (size_t idx = 0; idx < 8; idx += 2) {
|
|
249
|
+
__m128i value = _mm_loadu_si128((const __m128i *) (acc + idx));
|
|
250
|
+
value = _mm_xor_si128(value, _mm_srli_epi64(value, 47));
|
|
251
|
+
value = _mm_xor_si128(value, _mm_loadu_si128((const __m128i *) (secret + secret_length - 64 + idx * 8)));
|
|
252
|
+
_mm_storeu_si128((__m128i *) (acc + idx), _mm_add_epi64(_mm_mul_epu32(value, prime), _mm_slli_epi64(_mm_mul_epu32(_mm_shuffle_epi32(value, _MM_SHUFFLE(0, 3, 0, 1)), prime), 32)));
|
|
253
|
+
}
|
|
254
|
+
#else
|
|
255
|
+
for (size_t idx = 0; idx < 8; idx++) {
|
|
256
|
+
acc[idx] ^= (acc[idx] >> 47);
|
|
257
|
+
acc[idx] ^= read64(secret + secret_length - 64 + idx * 8);
|
|
258
|
+
acc[idx] *= PRIME32_1;
|
|
259
|
+
}
|
|
260
|
+
#endif
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
for (size_t stripe_idx = 0; stripe_idx < (length - last_offset - 1) / 64; stripe_idx++) {
|
|
264
|
+
accumulate(acc, input + last_offset + stripe_idx * 64, stripe_idx * 8);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
accumulate(acc, input + length - 64, secret_length - 71);
|
|
268
|
+
|
|
269
|
+
uint64_t result = (uint64_t) length * PRIME64_1;
|
|
270
|
+
for (size_t idx = 0; idx < 4; idx++) {
|
|
271
|
+
result += XXH3_mul128_fold64(acc[idx * 2] ^ read64(secret + 11 + 16 * idx), acc[idx * 2 + 1] ^ read64(secret + 11 + 16 * idx + 8));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return avalanche(result);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
uint64_t
|
|
278
|
+
pm_xxh3(const uint8_t *input, size_t length) {
|
|
279
|
+
if (length == 0) {
|
|
280
|
+
return XXH3_64_empty();
|
|
281
|
+
} else if (length <= 3) {
|
|
282
|
+
return XXH3_64_1to3(input, length);
|
|
283
|
+
} else if (length <= 8) {
|
|
284
|
+
return XXH3_64_4to8(input, length);
|
|
285
|
+
} else if (length <= 16) {
|
|
286
|
+
return XXH3_64_9to16(input, length);
|
|
287
|
+
} else if (length <= 240) {
|
|
288
|
+
return XXH3_64_17to240(input, length);
|
|
289
|
+
} else {
|
|
290
|
+
return XXH3_64_large(input, length);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
|
|
2
2
|
#include "prism/extension.h"
|
|
3
|
+
#include "prism/internal/allocator.h"
|
|
4
|
+
#include "prism/internal/arena.h"
|
|
5
|
+
|
|
6
|
+
#include <assert.h>
|
|
3
7
|
|
|
4
8
|
extern VALUE rb_cPrism;
|
|
5
9
|
extern VALUE rb_cPrismNode;
|
|
@@ -12,31 +16,26 @@ static VALUE rb_cPrism<%= node.name %>;
|
|
|
12
16
|
<%- end -%>
|
|
13
17
|
|
|
14
18
|
static VALUE
|
|
15
|
-
pm_location_new(const
|
|
19
|
+
pm_location_new(const uint32_t start, const uint32_t length, VALUE source, bool freeze) {
|
|
16
20
|
if (freeze) {
|
|
17
|
-
VALUE location_argv[] = {
|
|
18
|
-
source,
|
|
19
|
-
LONG2FIX(start - parser->start),
|
|
20
|
-
LONG2FIX(end - start)
|
|
21
|
-
};
|
|
22
|
-
|
|
21
|
+
VALUE location_argv[] = { source, LONG2FIX(start), LONG2FIX(length) };
|
|
23
22
|
return rb_obj_freeze(rb_class_new_instance(3, location_argv, rb_cPrismLocation));
|
|
24
23
|
} else {
|
|
25
|
-
uint64_t value = ((((uint64_t)
|
|
24
|
+
uint64_t value = ((((uint64_t) start) << 32) | ((uint64_t) length));
|
|
26
25
|
return ULL2NUM(value);
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
VALUE
|
|
31
30
|
pm_token_new(const pm_parser_t *parser, const pm_token_t *token, rb_encoding *encoding, VALUE source, bool freeze) {
|
|
32
|
-
ID type = rb_intern(
|
|
33
|
-
VALUE location = pm_location_new(
|
|
31
|
+
ID type = rb_intern(pm_token_type(token->type));
|
|
32
|
+
VALUE location = pm_location_new((uint32_t) (token->start - pm_parser_start(parser)), (uint32_t) (token->end - token->start), source, freeze);
|
|
34
33
|
|
|
35
34
|
VALUE slice = rb_enc_str_new((const char *) token->start, token->end - token->start, encoding);
|
|
36
35
|
if (freeze) rb_obj_freeze(slice);
|
|
37
36
|
|
|
38
|
-
VALUE argv[] = { source, ID2SYM(type), slice, location };
|
|
39
|
-
VALUE value = rb_class_new_instance(
|
|
37
|
+
VALUE argv[] = { source, ID2SYM(type), slice, location, INT2FIX(pm_parser_lex_state(parser)) };
|
|
38
|
+
VALUE value = rb_class_new_instance(5, argv, rb_cPrismToken);
|
|
40
39
|
if (freeze) rb_obj_freeze(value);
|
|
41
40
|
|
|
42
41
|
return value;
|
|
@@ -78,20 +77,26 @@ pm_integer_new(const pm_integer_t *integer) {
|
|
|
78
77
|
|
|
79
78
|
// Create a Prism::Source object from the given parser, after pm_parse() was called.
|
|
80
79
|
VALUE
|
|
81
|
-
pm_source_new(const pm_parser_t *parser, rb_encoding *encoding, bool freeze) {
|
|
82
|
-
|
|
80
|
+
pm_source_new(const pm_parser_t *parser, rb_encoding *encoding, VALUE comments, VALUE comment_attachments, VALUE comment_ranges, bool freeze) {
|
|
81
|
+
const uint8_t *start = pm_parser_start(parser);
|
|
82
|
+
VALUE source_string = rb_enc_str_new((const char *) start, pm_parser_end(parser) - start, encoding);
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
rb_ary_push(offsets, ULONG2NUM(parser->newline_list.offsets[index]));
|
|
87
|
-
}
|
|
84
|
+
const pm_line_offset_list_t *line_offsets = pm_parser_line_offsets(parser);
|
|
85
|
+
VALUE offsets;
|
|
88
86
|
|
|
89
87
|
if (freeze) {
|
|
88
|
+
offsets = rb_ary_new_capa(line_offsets->size);
|
|
89
|
+
for (size_t index = 0; index < line_offsets->size; index++) {
|
|
90
|
+
rb_ary_push(offsets, ULONG2NUM(line_offsets->offsets[index]));
|
|
91
|
+
}
|
|
92
|
+
|
|
90
93
|
rb_obj_freeze(source_string);
|
|
91
94
|
rb_obj_freeze(offsets);
|
|
95
|
+
} else {
|
|
96
|
+
offsets = rb_str_new((const char *) line_offsets->offsets, line_offsets->size * sizeof(uint32_t));
|
|
92
97
|
}
|
|
93
98
|
|
|
94
|
-
VALUE source = rb_funcall(rb_cPrismSource, rb_intern("for"),
|
|
99
|
+
VALUE source = rb_funcall(rb_cPrismSource, rb_intern("for"), 7, source_string, LONG2NUM(pm_parser_start_line(parser)), offsets, comments, comment_attachments, comment_ranges, ULL2NUM(pm_parser_checksum(parser)));
|
|
95
100
|
if (freeze) rb_obj_freeze(source);
|
|
96
101
|
|
|
97
102
|
return source;
|
|
@@ -104,8 +109,8 @@ typedef struct pm_node_stack_node {
|
|
|
104
109
|
} pm_node_stack_node_t;
|
|
105
110
|
|
|
106
111
|
static void
|
|
107
|
-
pm_node_stack_push(pm_node_stack_node_t **stack, const pm_node_t *visit) {
|
|
108
|
-
pm_node_stack_node_t *node =
|
|
112
|
+
pm_node_stack_push(pm_arena_t *arena, pm_node_stack_node_t **stack, const pm_node_t *visit) {
|
|
113
|
+
pm_node_stack_node_t *node = (pm_node_stack_node_t *) pm_arena_alloc(arena, sizeof(pm_node_stack_node_t), PRISM_ALIGNOF(pm_node_stack_node_t));
|
|
109
114
|
node->prev = *stack;
|
|
110
115
|
node->visit = visit;
|
|
111
116
|
node->visited = false;
|
|
@@ -118,32 +123,40 @@ pm_node_stack_pop(pm_node_stack_node_t **stack) {
|
|
|
118
123
|
const pm_node_t *visit = current->visit;
|
|
119
124
|
|
|
120
125
|
*stack = current->prev;
|
|
121
|
-
xfree(current);
|
|
122
126
|
|
|
123
127
|
return visit;
|
|
124
128
|
}
|
|
125
129
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Build the Symbol for the given constant.
|
|
132
|
+
*/
|
|
133
|
+
static VALUE
|
|
134
|
+
pm_ast_constant(const pm_constant_t *constant, rb_encoding *encoding) {
|
|
135
|
+
int state = 0;
|
|
129
136
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
int state = 0;
|
|
137
|
+
VALUE string = rb_enc_str_new((const char *) pm_constant_start(constant), pm_constant_length(constant), encoding);
|
|
138
|
+
VALUE value = rb_protect(rb_str_intern, string, &state);
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
if (state != 0) {
|
|
141
|
+
value = ID2SYM(rb_intern_const("?"));
|
|
142
|
+
rb_set_errinfo(Qnil);
|
|
143
|
+
}
|
|
136
144
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
VALUE
|
|
149
|
+
pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encoding, VALUE source, bool freeze) {
|
|
150
|
+
size_t constants_size = pm_parser_constants_size(parser);
|
|
151
|
+
VALUE constants = rb_ary_new_capa((long) constants_size);
|
|
141
152
|
|
|
142
|
-
|
|
153
|
+
for (size_t index = 0; index < constants_size; index++) {
|
|
154
|
+
rb_ary_push(constants, pm_ast_constant(pm_parser_constant_at(parser, index), encoding));
|
|
143
155
|
}
|
|
144
156
|
|
|
157
|
+
pm_arena_t *node_arena = pm_arena_new();
|
|
145
158
|
pm_node_stack_node_t *node_stack = NULL;
|
|
146
|
-
pm_node_stack_push(&node_stack, node);
|
|
159
|
+
pm_node_stack_push(node_arena, &node_stack, node);
|
|
147
160
|
VALUE value_stack = rb_ary_new();
|
|
148
161
|
|
|
149
162
|
while (node_stack != NULL) {
|
|
@@ -166,10 +179,10 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
|
|
|
166
179
|
<%- node.fields.each do |field| -%>
|
|
167
180
|
<%- case field -%>
|
|
168
181
|
<%- when Prism::Template::NodeField, Prism::Template::OptionalNodeField -%>
|
|
169
|
-
pm_node_stack_push(&node_stack, (pm_node_t *) cast-><%= field.name %>);
|
|
182
|
+
pm_node_stack_push(node_arena, &node_stack, (pm_node_t *) cast-><%= field.name %>);
|
|
170
183
|
<%- when Prism::Template::NodeListField -%>
|
|
171
184
|
for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
|
|
172
|
-
pm_node_stack_push(&node_stack, (pm_node_t *) cast-><%= field.name %>.nodes[index]);
|
|
185
|
+
pm_node_stack_push(node_arena, &node_stack, (pm_node_t *) cast-><%= field.name %>.nodes[index]);
|
|
173
186
|
}
|
|
174
187
|
<%- end -%>
|
|
175
188
|
<%- end -%>
|
|
@@ -200,7 +213,7 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
|
|
|
200
213
|
argv[1] = ULONG2NUM(node->node_id);
|
|
201
214
|
|
|
202
215
|
// location
|
|
203
|
-
argv[2] = pm_location_new(
|
|
216
|
+
argv[2] = pm_location_new(node->location.start, node->location.length, source, freeze);
|
|
204
217
|
|
|
205
218
|
// flags
|
|
206
219
|
argv[3] = ULONG2NUM(node->flags);
|
|
@@ -224,23 +237,23 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
|
|
|
224
237
|
<%- when Prism::Template::ConstantField -%>
|
|
225
238
|
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
|
|
226
239
|
assert(cast-><%= field.name %> != 0);
|
|
227
|
-
argv[<%= index %>] = RARRAY_AREF(constants, cast-><%= field.name %>
|
|
240
|
+
argv[<%= index %>] = RARRAY_AREF(constants, pm_constant_id_index(cast-><%= field.name %>));
|
|
228
241
|
<%- when Prism::Template::OptionalConstantField -%>
|
|
229
|
-
argv[<%= index %>] = cast-><%= field.name %> == 0 ? Qnil : RARRAY_AREF(constants, cast-><%= field.name %>
|
|
242
|
+
argv[<%= index %>] = cast-><%= field.name %> == 0 ? Qnil : RARRAY_AREF(constants, pm_constant_id_index(cast-><%= field.name %>));
|
|
230
243
|
<%- when Prism::Template::ConstantListField -%>
|
|
231
244
|
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
|
|
232
245
|
argv[<%= index %>] = rb_ary_new_capa(cast-><%= field.name %>.size);
|
|
233
246
|
for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
|
|
234
247
|
assert(cast-><%= field.name %>.ids[index] != 0);
|
|
235
|
-
rb_ary_push(argv[<%= index %>], RARRAY_AREF(constants, cast-><%= field.name %>.ids[index]
|
|
248
|
+
rb_ary_push(argv[<%= index %>], RARRAY_AREF(constants, pm_constant_id_index(cast-><%= field.name %>.ids[index])));
|
|
236
249
|
}
|
|
237
250
|
if (freeze) rb_obj_freeze(argv[<%= index %>]);
|
|
238
251
|
<%- when Prism::Template::LocationField -%>
|
|
239
252
|
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
|
|
240
|
-
argv[<%= index %>] = pm_location_new(
|
|
253
|
+
argv[<%= index %>] = pm_location_new(cast-><%= field.name %>.start, cast-><%= field.name %>.length, source, freeze);
|
|
241
254
|
<%- when Prism::Template::OptionalLocationField -%>
|
|
242
255
|
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
|
|
243
|
-
argv[<%= index %>] = cast-><%= field.name %>.
|
|
256
|
+
argv[<%= index %>] = cast-><%= field.name %>.length == 0 ? Qnil : pm_location_new(cast-><%= field.name %>.start, cast-><%= field.name %>.length, source, freeze);
|
|
244
257
|
<%- when Prism::Template::UInt8Field -%>
|
|
245
258
|
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
|
|
246
259
|
argv[<%= index %>] = UINT2NUM(cast-><%= field.name %>);
|
|
@@ -271,6 +284,7 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
|
|
|
271
284
|
}
|
|
272
285
|
}
|
|
273
286
|
|
|
287
|
+
pm_arena_free(node_arena);
|
|
274
288
|
return rb_ary_pop(value_stack);
|
|
275
289
|
}
|
|
276
290
|
|
|
@@ -8,21 +8,27 @@
|
|
|
8
8
|
#ifndef PRISM_AST_H
|
|
9
9
|
#define PRISM_AST_H
|
|
10
10
|
|
|
11
|
-
#include "prism/
|
|
12
|
-
#include "prism/
|
|
13
|
-
|
|
14
|
-
#include "prism/
|
|
11
|
+
#include "prism/compiler/align.h"
|
|
12
|
+
#include "prism/compiler/exported.h"
|
|
13
|
+
|
|
14
|
+
#include "prism/arena.h"
|
|
15
|
+
#include "prism/constant_pool.h"
|
|
16
|
+
#include "prism/integer.h"
|
|
17
|
+
#include "prism/stringy.h"
|
|
15
18
|
|
|
16
|
-
#include <assert.h>
|
|
17
19
|
#include <stddef.h>
|
|
18
20
|
#include <stdint.h>
|
|
19
21
|
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
extern "C" {
|
|
24
|
+
#endif
|
|
25
|
+
|
|
20
26
|
/**
|
|
21
27
|
* This enum represents every type of token in the Ruby source.
|
|
22
28
|
*/
|
|
23
29
|
typedef enum pm_token_type {
|
|
24
30
|
<%- tokens.each do |token| -%>
|
|
25
|
-
/** <%= token.comment %> */
|
|
31
|
+
/** <%= Prism::Template::Doxygen.verbatim(token.comment) %> */
|
|
26
32
|
PM_TOKEN_<%= token.name %><%= " = #{token.value}" if token.value %>,
|
|
27
33
|
|
|
28
34
|
<%- end -%>
|
|
@@ -46,15 +52,28 @@ typedef struct {
|
|
|
46
52
|
} pm_token_t;
|
|
47
53
|
|
|
48
54
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
55
|
+
* Returns a string representation of the given token type.
|
|
56
|
+
*
|
|
57
|
+
* @param token_type The type of the token to get the string representation of.
|
|
58
|
+
* @returns A string representation of the given token type. This is meant for
|
|
59
|
+
* debugging purposes and is not guaranteed to be stable across versions.
|
|
60
|
+
*/
|
|
61
|
+
PRISM_EXPORTED_FUNCTION const char * pm_token_type(pm_token_type_t token_type);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* This struct represents a slice in the source code, defined by an offset and
|
|
65
|
+
* a length. Note that we have confirmation that we can represent all locations
|
|
66
|
+
* within Ruby source files using 32-bit integers per:
|
|
67
|
+
*
|
|
68
|
+
* https://bugs.ruby-lang.org/issues/20488#note-1
|
|
69
|
+
*
|
|
51
70
|
*/
|
|
52
71
|
typedef struct {
|
|
53
|
-
/**
|
|
54
|
-
|
|
72
|
+
/** The offset of the location from the start of the source. */
|
|
73
|
+
uint32_t start;
|
|
55
74
|
|
|
56
|
-
/**
|
|
57
|
-
|
|
75
|
+
/** The length of the location. */
|
|
76
|
+
uint32_t length;
|
|
58
77
|
} pm_location_t;
|
|
59
78
|
|
|
60
79
|
struct pm_node;
|
|
@@ -112,7 +131,7 @@ static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = 0x2;
|
|
|
112
131
|
typedef struct pm_node {
|
|
113
132
|
/**
|
|
114
133
|
* This represents the type of the node. It somewhat maps to the nodes that
|
|
115
|
-
* existed in the original grammar and ripper, but it
|
|
134
|
+
* existed in the original grammar and ripper, but it is not a 1:1 mapping.
|
|
116
135
|
*/
|
|
117
136
|
pm_node_type_t type;
|
|
118
137
|
|
|
@@ -124,12 +143,14 @@ typedef struct pm_node {
|
|
|
124
143
|
|
|
125
144
|
/**
|
|
126
145
|
* The unique identifier for this node, which is deterministic based on the
|
|
127
|
-
* source. It is used to identify unique nodes across parses.
|
|
146
|
+
* source. It is used to identify unique nodes across parses. Nodes created
|
|
147
|
+
* outside of parsing have no position in the source and can use 0, which
|
|
148
|
+
* no parsed node uses.
|
|
128
149
|
*/
|
|
129
150
|
uint32_t node_id;
|
|
130
151
|
|
|
131
152
|
/**
|
|
132
|
-
* This is the location of the node in the source. It
|
|
153
|
+
* This is the location of the node in the source. It is a range of bytes
|
|
133
154
|
* containing a start and an end.
|
|
134
155
|
*/
|
|
135
156
|
pm_location_t location;
|
|
@@ -160,6 +181,15 @@ typedef struct pm_node {
|
|
|
160
181
|
* Return true if the given flag is set on the given node.
|
|
161
182
|
*/
|
|
162
183
|
#define PM_NODE_FLAG_P(node_, flag_) ((PM_NODE_FLAGS(node_) & (flag_)) != 0)
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The alignment required for a child node within a parent node.
|
|
187
|
+
*/
|
|
188
|
+
#ifdef _MSC_VER
|
|
189
|
+
#define PM_NODE_ALIGNAS __declspec(align(8))
|
|
190
|
+
#else
|
|
191
|
+
#define PM_NODE_ALIGNAS PRISM_ALIGNAS(PRISM_ALIGNOF(void *))
|
|
192
|
+
#endif
|
|
163
193
|
<%- nodes.each do |node| -%>
|
|
164
194
|
|
|
165
195
|
/**
|
|
@@ -182,7 +212,6 @@ typedef struct pm_node {
|
|
|
182
212
|
typedef struct pm_<%= node.human %> {
|
|
183
213
|
/** The embedded base node. */
|
|
184
214
|
pm_node_t base;
|
|
185
|
-
|
|
186
215
|
<%- node.fields.each do |field| -%>
|
|
187
216
|
|
|
188
217
|
/**
|
|
@@ -195,7 +224,7 @@ typedef struct pm_<%= node.human %> {
|
|
|
195
224
|
<%- end -%>
|
|
196
225
|
*/
|
|
197
226
|
<%= case field
|
|
198
|
-
when Prism::Template::NodeField, Prism::Template::OptionalNodeField then "struct #{field.c_type} *#{field.name}"
|
|
227
|
+
when Prism::Template::NodeField, Prism::Template::OptionalNodeField then "PM_NODE_ALIGNAS struct #{field.c_type} *#{field.name}"
|
|
199
228
|
when Prism::Template::NodeListField then "struct pm_node_list #{field.name}"
|
|
200
229
|
when Prism::Template::ConstantField, Prism::Template::OptionalConstantField then "pm_constant_id_t #{field.name}"
|
|
201
230
|
when Prism::Template::ConstantListField then "pm_constant_id_list_t #{field.name}"
|
|
@@ -226,6 +255,23 @@ typedef enum pm_<%= flag.human %> {
|
|
|
226
255
|
PM_<%= flag.human.upcase %>_LAST,
|
|
227
256
|
} pm_<%= flag.human %>_t;
|
|
228
257
|
<%- end -%>
|
|
258
|
+
<%- nodes.each do |node| -%>
|
|
259
|
+
|
|
260
|
+
<%- params = node.fields.map(&:c_param) -%>
|
|
261
|
+
/**
|
|
262
|
+
* Allocate and initialize a new <%= node.name %> node.
|
|
263
|
+
*
|
|
264
|
+
* @param arena The arena to allocate from.
|
|
265
|
+
* @param node_id The unique identifier for this node.
|
|
266
|
+
* @param flags The flags for this node.
|
|
267
|
+
* @param location The location of this node in the source.
|
|
268
|
+
<%- node.fields.each do |field| -%>
|
|
269
|
+
* @param <%= field.name %> <%= field.comment ? Prism::Template::Doxygen.verbatim(field.comment.lines.first.strip) : "The #{field.name} field." %>
|
|
270
|
+
<%- end -%>
|
|
271
|
+
* @returns The newly allocated and initialized node.
|
|
272
|
+
*/
|
|
273
|
+
PRISM_EXPORTED_FUNCTION pm_<%= node.human %>_t * pm_<%= node.human %>_new(pm_arena_t *arena, uint32_t node_id, pm_node_flags_t flags, pm_location_t location<%= params.empty? ? "" : ", #{params.join(", ")}" %>);
|
|
274
|
+
<%- end -%>
|
|
229
275
|
|
|
230
276
|
/**
|
|
231
277
|
* When we're serializing to Java, we want to skip serializing the location
|
|
@@ -235,4 +281,8 @@ typedef enum pm_<%= flag.human %> {
|
|
|
235
281
|
*/
|
|
236
282
|
#define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS <%= Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS ? 1 : 0 %>
|
|
237
283
|
|
|
284
|
+
#ifdef __cplusplus
|
|
285
|
+
}
|
|
286
|
+
#endif
|
|
287
|
+
|
|
238
288
|
#endif
|