diff options
author | Jean Boussier <[email protected]> | 2023-11-29 11:46:33 +0100 |
---|---|---|
committer | git <[email protected]> | 2023-11-29 13:56:19 +0000 |
commit | 2af82e23165180f20ca2af374aedb7a45dedcc20 (patch) | |
tree | 1bd829f6f15140c645496167a208d38736ac8d81 /prism/options.c | |
parent | 2653404840952d25bbdd7deaf599fbfb1f5287f0 (diff) |
[ruby/prism] Convert start line to signed integers
Ruby allows for 0 or negative line start, this is often used
with `eval` calls to get a correct offset when prefixing a snippet.
e.g.
```ruby
caller = caller_locations(1, 1).first
class_eval <<~RUBY, caller.path, caller.line - 2
# frozen_string_literal: true
def some_method
#{caller_provided_code_snippet}
end
RUBY
```
https://github.com/ruby/prism/commit/0d14ed1452
Diffstat (limited to 'prism/options.c')
-rw-r--r-- | prism/options.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/prism/options.c b/prism/options.c index 84c1fcbb39..85d04d6272 100644 --- a/prism/options.c +++ b/prism/options.c @@ -20,7 +20,7 @@ pm_options_encoding_set(pm_options_t *options, const char *encoding) { * Set the line option on the given options struct. */ PRISM_EXPORTED_FUNCTION void -pm_options_line_set(pm_options_t *options, uint32_t line) { +pm_options_line_set(pm_options_t *options, int32_t line) { options->line = line; } @@ -115,6 +115,22 @@ pm_options_read_u32(const char *data) { } /** + * Read a 32-bit signed integer from a pointer. This function is used to read + * the options that are passed into the parser from the Ruby implementation. It + * handles aligned and unaligned reads. + */ +static int32_t +pm_options_read_s32(const char *data) { + if (((uintptr_t) data) % sizeof(int32_t) == 0) { + return *((int32_t *) data); + } else { + int32_t value; + memcpy(&value, data, sizeof(int32_t)); + return value; + } +} + +/** * Deserialize an options struct from the given binary string. This is used to * pass options to the parser from an FFI call so that consumers of the library * from an FFI perspective don't have to worry about the structure of our @@ -123,6 +139,9 @@ pm_options_read_u32(const char *data) { */ void pm_options_read(pm_options_t *options, const char *data) { + options->line = 1; // default + if (data == NULL) return; + uint32_t filepath_length = pm_options_read_u32(data); data += 4; @@ -131,7 +150,7 @@ pm_options_read(pm_options_t *options, const char *data) { data += filepath_length; } - options->line = pm_options_read_u32(data); + options->line = pm_options_read_s32(data); data += 4; uint32_t encoding_length = pm_options_read_u32(data); |