diff options
-rw-r--r-- | lib/prism/ffi.rb | 3 | ||||
-rw-r--r-- | lib/prism/parse_result.rb | 2 | ||||
-rw-r--r-- | prism/options.h | 16 | ||||
-rw-r--r-- | prism/prism.c | 79 | ||||
-rw-r--r-- | prism/prism.h | 4 | ||||
-rw-r--r-- | prism/templates/lib/prism/serialize.rb.erb | 9 |
6 files changed, 23 insertions, 90 deletions
diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index cc84d00f14..931e277ef5 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -231,6 +231,7 @@ module Prism loader.load_header loader.load_force_encoding + loader.load_start_line loader.load_comments end end @@ -283,7 +284,7 @@ module Prism end template << "L" - values << options.fetch(:line, 0) + values << options.fetch(:line, 1) template << "L" if (encoding = options[:encoding]) diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 92651cf766..c7f6cdcd16 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -9,7 +9,7 @@ module Prism attr_reader :source # The line number where this source starts. - attr_reader :start_line + attr_accessor :start_line # The list of newline byte offsets in the source code. attr_reader :offsets diff --git a/prism/options.h b/prism/options.h index 6faadc2c47..f1b0254fff 100644 --- a/prism/options.h +++ b/prism/options.h @@ -160,28 +160,28 @@ PRISM_EXPORTED_FUNCTION void pm_options_free(pm_options_t *options); * * | # bytes | field | * | ------- | -------------------------- | - * | 4 | the length of the filepath | + * | `4` | the length of the filepath | * | ... | the filepath bytes | - * | 4 | the line number | - * | 4 | the length the encoding | + * | `4` | the line number | + * | `4` | the length the encoding | * | ... | the encoding bytes | - * | 1 | frozen string literal | - * | 1 | suppress warnings | - * | 4 | the number of scopes | + * | `1` | frozen string literal | + * | `1` | suppress warnings | + * | `4` | the number of scopes | * | ... | the scopes | * * Each scope is layed out as follows: * * | # bytes | field | * | ------- | -------------------------- | - * | 4 | the number of locals | + * | `4` | the number of locals | * | ... | the locals | * * Each local is layed out as follows: * * | # bytes | field | * | ------- | -------------------------- | - * | 4 | the length of the local | + * | `4` | the length of the local | * | ... | the local bytes | * * Some additional things to note about this layout: diff --git a/prism/prism.c b/prism/prism.c index be8dd38ccf..a362961a1f 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -16239,82 +16239,6 @@ parse_program(pm_parser_t *parser) { return (pm_node_t *) pm_program_node_create(parser, &locals, statements); } -/** - * Read a 32-bit unsigned integer from a pointer. This function is used to read - * the metadata that is passed into the parser from the Ruby implementation. It - * handles aligned and unaligned reads. - */ -static uint32_t -pm_metadata_read_u32(const char *ptr) { - if (((uintptr_t) ptr) % sizeof(uint32_t) == 0) { - return *((uint32_t *) ptr); - } else { - uint32_t value; - memcpy(&value, ptr, sizeof(uint32_t)); - return value; - } -} - -/** - * Process any additional metadata being passed into a call to the parser via - * the pm_parse_serialize function. Since the source of these calls will be from - * Ruby implementation internals we assume it is from a trusted source. - * - * Currently, this is only passing in variable scoping surrounding an eval, but - * eventually it will be extended to hold any additional metadata. This data - * is serialized to reduce the calling complexity for a foreign function call - * vs a foreign runtime making a bindable in-memory version of a C structure. - * - * metadata is assumed to be a valid pointer pointing to well-formed data. The - * format is described below: - * - * ```text - * [ - * filepath_size: uint32_t, - * filepath: char*, - * scopes_count: uint32_t, - * [ - * locals_count: uint32_t, - * [local_size: uint32_t, local: char*]* - * ]* - * ] - * ``` - */ -void -pm_parser_metadata(pm_parser_t *parser, const char *metadata) { - uint32_t filepath_size = pm_metadata_read_u32(metadata); - metadata += 4; - - if (filepath_size) { - pm_string_t filepath_string; - pm_string_constant_init(&filepath_string, metadata, filepath_size); - - parser->filepath_string = filepath_string; - metadata += filepath_size; - } - - uint32_t scopes_count = pm_metadata_read_u32(metadata); - metadata += 4; - - for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) { - uint32_t locals_count = pm_metadata_read_u32(metadata); - metadata += 4; - - pm_parser_scope_push(parser, scope_index == 0); - - for (size_t local_index = 0; local_index < locals_count; local_index++) { - uint32_t local_size = pm_metadata_read_u32(metadata); - metadata += 4; - - uint8_t *constant = malloc(local_size); - memcpy(constant, metadata, local_size); - - pm_parser_local_add_owned(parser, constant, (size_t) local_size); - metadata += local_size; - } - } -} - /******************************************************************************/ /* External functions */ /******************************************************************************/ @@ -16561,7 +16485,7 @@ PRISM_EXPORTED_FUNCTION void pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { pm_serialize_header(buffer); pm_serialize_content(parser, node, buffer); - pm_buffer_append_string(buffer, "\0", 1); + pm_buffer_append_byte(buffer, '\0'); } /** @@ -16601,6 +16525,7 @@ pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t s pm_node_t *node = pm_parse(&parser); pm_serialize_header(buffer); pm_serialize_encoding(&parser.encoding, buffer); + pm_buffer_append_varint(buffer, parser.start_line); pm_serialize_comment_list(&parser, &parser.comment_list, buffer); pm_node_destroy(&parser, node); diff --git a/prism/prism.h b/prism/prism.h index 2f7208929b..211d2957f2 100644 --- a/prism/prism.h +++ b/prism/prism.h @@ -233,7 +233,7 @@ PRISM_EXPORTED_FUNCTION const char * pm_token_type_to_str(pm_token_type_t token_ * * `pm_buffer_t` - a small buffer object that will hold the serialized AST * * `pm_buffer_free` - free the memory associated with the buffer * * `pm_serialize` - serialize the AST into a buffer - * * `pm_parse_serialize` - parse and serialize the AST into a buffer + * * `pm_serialize_parse` - parse and serialize the AST into a buffer * * Putting all of this together would look something like: * @@ -241,7 +241,7 @@ PRISM_EXPORTED_FUNCTION const char * pm_token_type_to_str(pm_token_type_t token_ * void serialize(const uint8_t *source, size_t length) { * pm_buffer_t buffer = { 0 }; * - * pm_parse_serialize(source, length, &buffer, NULL); + * pm_serialize_parse(&buffer, source, length, NULL); * printf("SERIALIZED!\n"); * * pm_buffer_free(&buffer); diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb index a8a6a2dd47..ef8ebbbae8 100644 --- a/prism/templates/lib/prism/serialize.rb.erb +++ b/prism/templates/lib/prism/serialize.rb.erb @@ -46,6 +46,7 @@ module Prism class Loader # :nodoc: attr_reader :encoding, :input, :serialized, :io attr_reader :constant_pool_offset, :constant_pool, :source + attr_reader :start_line def initialize(source, serialized) @encoding = Encoding::UTF_8 @@ -59,7 +60,7 @@ module Prism @constant_pool = nil @source = source - define_load_node_lambdas unless RUBY_ENGINE == 'ruby' + define_load_node_lambdas unless RUBY_ENGINE == "ruby" end def load_header @@ -80,6 +81,10 @@ module Prism @input = input.force_encoding(@encoding).freeze end + def load_start_line + source.start_line = load_varint + end + def load_comments load_varint.times.map { Comment.new(Comment::TYPES.fetch(load_varint), load_location) } end @@ -108,6 +113,7 @@ module Prism def load_tokens_result tokens = load_tokens encoding = load_encoding + load_start_line comments, magic_comments, errors, warnings = load_metadata if encoding != @encoding @@ -121,6 +127,7 @@ module Prism def load_nodes load_header load_force_encoding + load_start_line comments, magic_comments, errors, warnings = load_metadata |