summaryrefslogtreecommitdiff
path: root/prism/options.c
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2023-11-29 11:46:33 +0100
committergit <[email protected]>2023-11-29 13:56:19 +0000
commit2af82e23165180f20ca2af374aedb7a45dedcc20 (patch)
tree1bd829f6f15140c645496167a208d38736ac8d81 /prism/options.c
parent2653404840952d25bbdd7deaf599fbfb1f5287f0 (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.c23
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);