Skip to content

Commit ef86059

Browse files
committed
More location cleanup
1 parent b6de2f9 commit ef86059

File tree

6 files changed

+64
-36
lines changed

6 files changed

+64
-36
lines changed

include/prism/defines.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,24 @@
257257
#define PRISM_FALLTHROUGH
258258
#endif
259259

260+
/**
261+
* We need to align nodes in the AST to a pointer boundary so that it can be
262+
* safely cast to different node types. Use PRISM_ALIGNAS/PRISM_ALIGNOF to
263+
* specify alignment in a compiler-agnostic way.
264+
*/
265+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L /* C11 or later */
266+
#include <stdalign.h>
267+
#define PRISM_ALIGNAS(size) alignas(size)
268+
#define PRISM_ALIGNOF(type) alignof(type)
269+
#elif defined(__GNUC__) || defined(__clang__)
270+
#define PRISM_ALIGNAS(size) __attribute__((aligned(size)))
271+
#define PRISM_ALIGNOF(type) __alignof__(type)
272+
#elif defined(_MSC_VER)
273+
#define PRISM_ALIGNAS(size) __declspec(align(size))
274+
#define PRISM_ALIGNOF(type) __alignof(type)
275+
#else
276+
#define PRISM_ALIGNAS(size)
277+
#define PRISM_ALIGNOF(type) sizeof(type)
278+
#endif
279+
260280
#endif

rust/ruby-prism/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,9 @@ impl<'pr> Node<'pr> {{
605605
/// Panics if the node type cannot be read.
606606
///
607607
#[allow(clippy::not_unsafe_ptr_arg_deref)]
608+
#[allow(clippy::cast_ptr_alignment)]
608609
pub(crate) fn new(parser: NonNull<pm_parser_t>, node: *mut pm_node_t) -> Self {{
609-
match unsafe {{ (*node).type_ }} {{
610-
"
610+
match unsafe {{ (*node).type_ }} {{"
611611
)?;
612612

613613
for node in &config.nodes {

rust/ruby-prism/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::mem::MaybeUninit;
1919
use std::ptr::NonNull;
2020

2121
pub use self::bindings::*;
22-
use ruby_prism_sys::{pm_comment_t, pm_comment_type_t, pm_constant_id_list_t, pm_constant_id_t, pm_diagnostic_t, pm_integer_t, pm_magic_comment_t, pm_node_destroy, pm_node_list, pm_node_t, pm_parse, pm_parser_free, pm_parser_init, pm_parser_t, pm_location_t};
22+
use ruby_prism_sys::{pm_comment_t, pm_comment_type_t, pm_constant_id_list_t, pm_constant_id_t, pm_diagnostic_t, pm_integer_t, pm_location_t, pm_magic_comment_t, pm_node_destroy, pm_node_list, pm_node_t, pm_parse, pm_parser_free, pm_parser_init, pm_parser_t};
2323

2424
/// A range in the source file, represented as a start offset and length.
2525
pub struct Location<'pr> {
@@ -52,7 +52,7 @@ impl<'pr> Location<'pr> {
5252

5353
/// Returns the end offset from the beginning of the parsed source.
5454
#[must_use]
55-
pub fn end(&self) -> u32 {
55+
pub const fn end(&self) -> u32 {
5656
self.start + self.length
5757
}
5858

src/prism.c

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ pm_locals_order(PRISM_ATTRIBUTE_UNUSED pm_parser_t *parser, pm_locals_t *locals,
10161016
* Retrieve the constant pool id for the given location.
10171017
*/
10181018
static inline pm_constant_id_t
1019-
pm_parser_constant_id_location(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
1019+
pm_parser_constant_id_raw(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
10201020
return pm_constant_pool_insert_shared(&parser->constant_pool, start, (size_t) (end - start));
10211021
}
10221022

@@ -1041,7 +1041,7 @@ pm_parser_constant_id_constant(pm_parser_t *parser, const char *start, size_t le
10411041
*/
10421042
static inline pm_constant_id_t
10431043
pm_parser_constant_id_token(pm_parser_t *parser, const pm_token_t *token) {
1044-
return pm_parser_constant_id_location(parser, token->start, token->end);
1044+
return pm_parser_constant_id_raw(parser, token->start, token->end);
10451045
}
10461046

10471047
/**
@@ -2683,7 +2683,7 @@ pm_call_node_call_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *o
26832683
* If the final character is `@` as is the case for `foo.~@`,
26842684
* we should ignore the @ in the same way we do for symbols.
26852685
*/
2686-
node->name = pm_parser_constant_id_location(parser, message->start, parse_operator_symbol_name(message));
2686+
node->name = pm_parser_constant_id_raw(parser, message->start, parse_operator_symbol_name(message));
26872687
return node;
26882688
}
26892689

@@ -2967,7 +2967,7 @@ pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
29672967
.message_loc = target->message_loc,
29682968
.read_name = 0,
29692969
.write_name = target->name,
2970-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
2970+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1),
29712971
.binary_operator_loc = TOK2LOC(parser, operator),
29722972
.value = value
29732973
};
@@ -3000,7 +3000,7 @@ pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
30003000
.arguments = target->arguments,
30013001
.closing_loc = target->closing_loc,
30023002
.block = (pm_block_argument_node_t *) target->block,
3003-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
3003+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1),
30043004
.binary_operator_loc = TOK2LOC(parser, operator),
30053005
.value = value
30063006
};
@@ -3293,7 +3293,7 @@ pm_class_variable_operator_write_node_create(pm_parser_t *parser, pm_class_varia
32933293
.name_loc = target->base.location,
32943294
.binary_operator_loc = TOK2LOC(parser, operator),
32953295
.value = value,
3296-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
3296+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1)
32973297
};
32983298

32993299
return node;
@@ -3397,7 +3397,7 @@ pm_constant_path_operator_write_node_create(pm_parser_t *parser, pm_constant_pat
33973397
.target = target,
33983398
.binary_operator_loc = TOK2LOC(parser, operator),
33993399
.value = value,
3400-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
3400+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1)
34013401
};
34023402

34033403
return node;
@@ -3499,7 +3499,7 @@ pm_constant_operator_write_node_create(pm_parser_t *parser, pm_constant_read_nod
34993499
.name_loc = target->base.location,
35003500
.binary_operator_loc = TOK2LOC(parser, operator),
35013501
.value = value,
3502-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
3502+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1)
35033503
};
35043504

35053505
return node;
@@ -4145,7 +4145,7 @@ pm_global_variable_write_name(pm_parser_t *parser, const pm_node_t *target) {
41454145
case PM_NUMBERED_REFERENCE_READ_NODE:
41464146
// This will only ever happen in the event of a syntax error, but we
41474147
// still need to provide something for the node.
4148-
return pm_parser_constant_id_location(parser, parser->start + PM_NODE_START(target), parser->start + PM_NODE_END(target));
4148+
return pm_parser_constant_id_raw(parser, parser->start + PM_NODE_START(target), parser->start + PM_NODE_END(target));
41494149
default:
41504150
assert(false && "unreachable");
41514151
return (pm_constant_id_t) -1;
@@ -4184,7 +4184,7 @@ pm_global_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *ta
41844184
.name_loc = target->location,
41854185
.binary_operator_loc = TOK2LOC(parser, operator),
41864186
.value = value,
4187-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
4187+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1)
41884188
};
41894189

41904190
return node;
@@ -4617,7 +4617,7 @@ pm_instance_variable_operator_write_node_create(pm_parser_t *parser, pm_instance
46174617
.name_loc = target->base.location,
46184618
.binary_operator_loc = TOK2LOC(parser, operator),
46194619
.value = value,
4620-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
4620+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1)
46214621
};
46224622

46234623
return node;
@@ -5064,7 +5064,7 @@ pm_required_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t
50645064

50655065
*node = (pm_required_keyword_parameter_node_t) {
50665066
.base = PM_NODE_INIT_TOKEN(parser, PM_REQUIRED_KEYWORD_PARAMETER_NODE, 0, name),
5067-
.name = pm_parser_constant_id_location(parser, name->start, name->end - 1),
5067+
.name = pm_parser_constant_id_raw(parser, name->start, name->end - 1),
50685068
.name_loc = TOK2LOC(parser, name),
50695069
};
50705070

@@ -5080,7 +5080,7 @@ pm_optional_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t
50805080

50815081
*node = (pm_optional_keyword_parameter_node_t) {
50825082
.base = PM_NODE_INIT_TOKEN_NODE(parser, PM_OPTIONAL_KEYWORD_PARAMETER_NODE, 0, name, value),
5083-
.name = pm_parser_constant_id_location(parser, name->start, name->end - 1),
5083+
.name = pm_parser_constant_id_raw(parser, name->start, name->end - 1),
50845084
.name_loc = TOK2LOC(parser, name),
50855085
.value = value
50865086
};
@@ -5171,7 +5171,7 @@ pm_local_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *tar
51715171
.binary_operator_loc = TOK2LOC(parser, operator),
51725172
.value = value,
51735173
.name = name,
5174-
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
5174+
.binary_operator = pm_parser_constant_id_raw(parser, operator->start, operator->end - 1),
51755175
.depth = depth
51765176
};
51775177

@@ -6652,28 +6652,28 @@ pm_symbol_node_synthesized_create(pm_parser_t *parser, const char *content) {
66526652
*/
66536653
static bool
66546654
pm_symbol_node_label_p(const pm_parser_t *parser, const pm_node_t *node) {
6655-
const uint8_t *end = NULL;
6655+
const pm_location_t *location = NULL;
66566656

66576657
switch (PM_NODE_TYPE(node)) {
66586658
case PM_SYMBOL_NODE: {
66596659
const pm_symbol_node_t *cast = (pm_symbol_node_t *) node;
6660-
if (cast->closing_loc.length != 0) {
6661-
end = parser->start + cast->closing_loc.start + cast->closing_loc.length;
6660+
if (cast->closing_loc.length > 0) {
6661+
location = &cast->closing_loc;
66626662
}
66636663
break;
66646664
}
66656665
case PM_INTERPOLATED_SYMBOL_NODE: {
66666666
const pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node;
6667-
if (cast->closing_loc.length != 0) {
6668-
end = parser->start + cast->closing_loc.start + cast->closing_loc.length;
6667+
if (cast->closing_loc.length > 0) {
6668+
location = &cast->closing_loc;
66696669
}
66706670
break;
66716671
}
66726672
default:
66736673
return false;
66746674
}
66756675

6676-
return (end != NULL) && (end[-1] == ':');
6676+
return (location != NULL) && (parser->start[PM_LOCATION_END(location) - 1] == ':');
66776677
}
66786678

66796679
/**
@@ -7121,15 +7121,15 @@ pm_parser_local_add(pm_parser_t *parser, pm_constant_id_t constant_id, const uin
71217121
*/
71227122
static pm_constant_id_t
71237123
pm_parser_local_add_raw(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, uint32_t reads) {
7124-
pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, start, end);
7124+
pm_constant_id_t constant_id = pm_parser_constant_id_raw(parser, start, end);
71257125
if (constant_id != 0) pm_parser_local_add(parser, constant_id, start, end, reads);
71267126
return constant_id;
71277127
}
71287128

71297129
/**
71307130
* Add a local variable from a location to the current scope.
71317131
*/
7132-
static pm_constant_id_t
7132+
static inline pm_constant_id_t
71337133
pm_parser_local_add_location(pm_parser_t *parser, pm_location_t *location, uint32_t reads) {
71347134
return pm_parser_local_add_raw(parser, parser->start + location->start, parser->start + location->start + location->length, reads);
71357135
}
@@ -12633,7 +12633,7 @@ parse_unwriteable_target(pm_parser_t *parser, pm_node_t *target) {
1263312633
default: break;
1263412634
}
1263512635

12636-
pm_constant_id_t name = pm_parser_constant_id_location(parser, parser->start + PM_NODE_START(target), parser->start + PM_NODE_END(target));
12636+
pm_constant_id_t name = pm_parser_constant_id_raw(parser, parser->start + PM_NODE_START(target), parser->start + PM_NODE_END(target));
1263712637
pm_local_variable_target_node_t *result = pm_local_variable_target_node_create(parser, &target->location, name, 0);
1263812638

1263912639
pm_node_destroy(parser, target);
@@ -12953,7 +12953,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
1295312953
pm_parser_local_add_location(parser, &message_loc, 0);
1295412954
pm_node_destroy(parser, target);
1295512955

12956-
pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, parser->start + PM_LOCATION_START(&message_loc), parser->start + PM_LOCATION_END(&message_loc));
12956+
pm_constant_id_t constant_id = pm_parser_constant_id_raw(parser, parser->start + PM_LOCATION_START(&message_loc), parser->start + PM_LOCATION_END(&message_loc));
1295712957
target = UP(pm_local_variable_write_node_create(parser, constant_id, 0, value, &message_loc, operator));
1295812958

1295912959
return target;
@@ -13048,7 +13048,7 @@ parse_unwriteable_write(pm_parser_t *parser, pm_node_t *target, const pm_token_t
1304813048
default: break;
1304913049
}
1305013050

13051-
pm_constant_id_t name = pm_parser_local_add_raw(parser, parser->start + PM_NODE_START(target), parser->start + PM_NODE_END(target), 1);
13051+
pm_constant_id_t name = pm_parser_local_add_location(parser, &target->location, 1);
1305213052
pm_local_variable_write_node_t *result = pm_local_variable_write_node_create(parser, name, 0, value, &target->location, equals);
1305313053

1305413054
pm_node_destroy(parser, target);
@@ -16321,7 +16321,7 @@ parse_pattern_hash_implicit_value(pm_parser_t *parser, pm_constant_id_list_t *ca
1632116321
const uint8_t *start = parser->start + PM_LOCATION_START(value_loc);
1632216322
const uint8_t *end = parser->start + PM_LOCATION_END(value_loc);
1632316323

16324-
pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, start, end);
16324+
pm_constant_id_t constant_id = pm_parser_constant_id_raw(parser, start, end);
1632516325
int depth = -1;
1632616326

1632716327
if (pm_slice_is_valid_local(parser, start, end)) {
@@ -18859,7 +18859,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1885918859
* methods to override the unary operators, we should ignore
1886018860
* the @ in the same way we do for symbols.
1886118861
*/
18862-
pm_constant_id_t name_id = pm_parser_constant_id_location(parser, name.start, parse_operator_symbol_name(&name));
18862+
pm_constant_id_t name_id = pm_parser_constant_id_raw(parser, name.start, parse_operator_symbol_name(&name));
1886318863

1886418864
flush_block_exits(parser, previous_block_exits);
1886518865
pm_node_list_free(&current_block_exits);
@@ -20337,7 +20337,7 @@ parse_regular_expression_named_capture(const pm_string_t *capture, void *data) {
2033720337
// copy the names directly. The pointers will line up.
2033820338
start = source;
2033920339
end = source + length;
20340-
name = pm_parser_constant_id_location(parser, start, end);
20340+
name = pm_parser_constant_id_raw(parser, start, end);
2034120341
} else {
2034220342
// Otherwise, the name is a slice of the malloc-ed owned string,
2034320343
// in which case we need to copy it out into a new string.
@@ -20438,7 +20438,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2043820438
// variable before parsing the value, in case the value
2043920439
// references the variable.
2044020440
if (PM_NODE_TYPE_P(node, PM_IT_LOCAL_VARIABLE_READ_NODE)) {
20441-
pm_parser_local_add_raw(parser, parser->start + PM_NODE_START(node), parser->start + PM_NODE_END(node), 0);
20441+
pm_parser_local_add_location(parser, &node->location, 0);
2044220442
}
2044320443

2044420444
parser_lex(parser);

src/util/pm_char.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
8484
*/
8585
size_t
8686
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list, uint32_t start_offset) {
87-
if (length <= 0 || length > UINT32_MAX) return 0;
87+
if (length <= 0) return 0;
8888

8989
uint32_t size = 0;
9090
uint32_t maximum = (uint32_t) length;

templates/include/prism/ast.h.erb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,15 @@ typedef struct pm_node {
164164
* Return true if the given flag is set on the given node.
165165
*/
166166
#define PM_NODE_FLAG_P(node_, flag_) ((PM_NODE_FLAGS(node_) & (flag_)) != 0)
167+
168+
/**
169+
* The alignment required for a child node within a parent node.
170+
*/
171+
#ifdef _MSC_VER
172+
#define PM_NODE_ALIGNAS __declspec(align(8))
173+
#else
174+
#define PM_NODE_ALIGNAS PRISM_ALIGNAS(PRISM_ALIGNOF(void *))
175+
#endif
167176
<%- nodes.each do |node| -%>
168177

169178
/**
@@ -186,7 +195,6 @@ typedef struct pm_node {
186195
typedef struct pm_<%= node.human %> {
187196
/** The embedded base node. */
188197
pm_node_t base;
189-
190198
<%- node.fields.each do |field| -%>
191199

192200
/**
@@ -199,7 +207,7 @@ typedef struct pm_<%= node.human %> {
199207
<%- end -%>
200208
*/
201209
<%= case field
202-
when Prism::Template::NodeField, Prism::Template::OptionalNodeField then "struct #{field.c_type} *#{field.name}"
210+
when Prism::Template::NodeField, Prism::Template::OptionalNodeField then "PM_NODE_ALIGNAS struct #{field.c_type} *#{field.name}"
203211
when Prism::Template::NodeListField then "struct pm_node_list #{field.name}"
204212
when Prism::Template::ConstantField, Prism::Template::OptionalConstantField then "pm_constant_id_t #{field.name}"
205213
when Prism::Template::ConstantListField then "pm_constant_id_list_t #{field.name}"

0 commit comments

Comments
 (0)