@@ -12,24 +12,34 @@ static VALUE rb_cPrism<%= node.name %>;
1212<%- end -%>
1313
1414static VALUE
15- pm_location_new(const pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
16- uint64_t value = ((((uint64_t) (start - parser- > start)) < < 32 ) | ((uint32_t) (end - start)));
17- return ULL2NUM(value);
15+ pm_location_new(const pm_parser_t *parser, const uint8_t *start, const uint8_t *end, VALUE source, bool freeze) {
16+ if (freeze) {
17+ VALUE location_argv[] = {
18+ source,
19+ LONG2FIX(start - parser- > start),
20+ LONG2FIX(end - start)
21+ };
22+
23+ return rb_obj_freeze(rb_class_new_instance(3, location_argv, rb_cPrismLocation));
24+ } else {
25+ uint64_t value = ((((uint64_t) (start - parser-> start)) < < 32 ) | ((uint32_t) (end - start)));
26+ return ULL2NUM(value);
27+ }
1828}
1929
2030VALUE
21- pm_token_new(const pm_parser_t *parser, const pm_token_t *token, rb_encoding *encoding, VALUE source) {
31+ pm_token_new(const pm_parser_t *parser, const pm_token_t *token, rb_encoding *encoding, VALUE source, bool freeze ) {
2232 ID type = rb_intern(pm_token_type_name(token- > type));
23- VALUE location = pm_location_new(parser, token-> start, token-> end);
33+ VALUE location = pm_location_new(parser, token-> start, token-> end, source, freeze );
2434
25- VALUE argv[] = {
26- source,
27- ID2SYM(type),
28- rb_enc_str_new((const char *) token-> start, token-> end - token-> start, encoding),
29- location
30- };
35+ VALUE slice = rb_enc_str_new((const char *) token-> start, token-> end - token-> start, encoding);
36+ if (freeze) rb_obj_freeze(slice);
3137
32- return rb_class_new_instance(4, argv, rb_cPrismToken);
38+ VALUE argv[] = { source, ID2SYM(type), slice, location };
39+ VALUE value = rb_class_new_instance(4, argv, rb_cPrismToken);
40+ if (freeze) rb_obj_freeze(value);
41+
42+ return value;
3343}
3444
3545static VALUE
@@ -68,15 +78,23 @@ pm_integer_new(const pm_integer_t *integer) {
6878
6979// Create a Prism::Source object from the given parser, after pm_parse() was called.
7080VALUE
71- pm_source_new(const pm_parser_t *parser, rb_encoding *encoding) {
81+ pm_source_new(const pm_parser_t *parser, rb_encoding *encoding, bool freeze ) {
7282 VALUE source_string = rb_enc_str_new((const char *) parser-> start, parser-> end - parser-> start, encoding);
7383
7484 VALUE offsets = rb_ary_new_capa(parser-> newline_list.size);
7585 for (size_t index = 0; index < parser- > newline_list.size; index++) {
7686 rb_ary_push(offsets, ULONG2NUM(parser-> newline_list.offsets[index]));
7787 }
7888
79- return rb_funcall(rb_cPrismSource, rb_intern("for"), 3, source_string, LONG2NUM(parser-> start_line), offsets);
89+ if (freeze) {
90+ rb_obj_freeze(source_string);
91+ rb_obj_freeze(offsets);
92+ }
93+
94+ VALUE source = rb_funcall(rb_cPrismSource, rb_intern("for"), 3, source_string, LONG2NUM(parser-> start_line), offsets);
95+ if (freeze) rb_obj_freeze(source);
96+
97+ return source;
8098}
8199
82100typedef struct pm_node_stack_node {
@@ -106,7 +124,7 @@ pm_node_stack_pop(pm_node_stack_node_t **stack) {
106124}
107125
108126VALUE
109- pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encoding, VALUE source) {
127+ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encoding, VALUE source, bool freeze ) {
110128 VALUE constants = rb_ary_new_capa(parser-> constant_pool.size);
111129
112130 for (uint32_t index = 0; index < parser- > constant_pool.size; index++) {
@@ -182,7 +200,7 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
182200 argv[1] = ULONG2NUM(node-> node_id);
183201
184202 // location
185- argv[2] = pm_location_new(parser, node-> location.start, node-> location.end);
203+ argv[2] = pm_location_new(parser, node-> location.start, node-> location.end, source, freeze );
186204
187205 // flags
188206 argv[3] = ULONG2NUM(node-> flags);
@@ -199,6 +217,7 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
199217 for (size_t index = 0; index < cast- > <%= field . name %> .size; index++) {
200218 rb_ary_push(argv[<%= index %> ], rb_ary_pop(value_stack));
201219 }
220+ if (freeze) rb_obj_freeze(argv[<%= index %> ]);
202221 <%- when Prism ::Template ::StringField -%>
203222#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File . basename ( __FILE__ ) %> "
204223 argv[<%= index %> ] = pm_string_new(&cast-> <%= field . name %> , encoding);
@@ -215,12 +234,13 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
215234 assert(cast-> <%= field . name %> .ids[index] != 0);
216235 rb_ary_push(argv[<%= index %> ], RARRAY_AREF(constants, cast-> <%= field . name %> .ids[index] - 1));
217236 }
237+ if (freeze) rb_obj_freeze(argv[<%= index %> ]);
218238 <%- when Prism ::Template ::LocationField -%>
219239#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File . basename ( __FILE__ ) %> "
220- argv[<%= index %> ] = pm_location_new(parser, cast-> <%= field . name %> .start, cast-> <%= field . name %> .end);
240+ argv[<%= index %> ] = pm_location_new(parser, cast-> <%= field . name %> .start, cast-> <%= field . name %> .end, source, freeze );
221241 <%- when Prism ::Template ::OptionalLocationField -%>
222242#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File . basename ( __FILE__ ) %> "
223- argv[<%= index %> ] = cast-> <%= field . name %> .start == NULL ? Qnil : pm_location_new(parser, cast-> <%= field . name %> .start, cast-> <%= field . name %> .end);
243+ argv[<%= index %> ] = cast-> <%= field . name %> .start == NULL ? Qnil : pm_location_new(parser, cast-> <%= field . name %> .start, cast-> <%= field . name %> .end, source, freeze );
224244 <%- when Prism ::Template ::UInt8Field -%>
225245#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File . basename ( __FILE__ ) %> "
226246 argv[<%= index %> ] = UINT2NUM(cast-> <%= field . name %> );
@@ -238,7 +258,10 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
238258 <%- end -%>
239259 <%- end -%>
240260
241- rb_ary_push(value_stack, rb_class_new_instance(<%= node . fields . length + 4 %> , argv, rb_cPrism<%= node . name %> ));
261+ VALUE value = rb_class_new_instance(<%= node . fields . length + 4 %> , argv, rb_cPrism<%= node . name %> );
262+ if (freeze) rb_obj_freeze(value);
263+
264+ rb_ary_push(value_stack, value);
242265 break;
243266 }
244267 <%- end -%>
0 commit comments