mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 08:33:58 +02:00
parent
ca7297efd3
commit
05f5c545d2
12 changed files with 335 additions and 234 deletions
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
PRISM_EXPORTED_FUNCTION void
|
||||
pm_options_filepath_set(pm_options_t *options, const char *filepath) {
|
||||
options->filepath = filepath;
|
||||
pm_string_constant_init(&options->filepath, filepath, strlen(filepath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@ pm_options_filepath_set(pm_options_t *options, const char *filepath) {
|
|||
*/
|
||||
PRISM_EXPORTED_FUNCTION void
|
||||
pm_options_encoding_set(pm_options_t *options, const char *encoding) {
|
||||
options->encoding = encoding;
|
||||
pm_string_constant_init(&options->encoding, encoding, strlen(encoding));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,6 +82,9 @@ pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index) {
|
|||
*/
|
||||
PRISM_EXPORTED_FUNCTION void
|
||||
pm_options_free(pm_options_t *options) {
|
||||
pm_string_free(&options->filepath);
|
||||
pm_string_free(&options->encoding);
|
||||
|
||||
for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
|
||||
pm_options_scope_t *scope = &options->scopes[scope_index];
|
||||
|
||||
|
@ -94,3 +97,74 @@ pm_options_free(pm_options_t *options) {
|
|||
|
||||
free(options->scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a 32-bit unsigned 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 uint32_t
|
||||
pm_options_read_u32(const char *data) {
|
||||
if (((uintptr_t) data) % sizeof(uint32_t) == 0) {
|
||||
return *((uint32_t *) data);
|
||||
} else {
|
||||
uint32_t value;
|
||||
memcpy(&value, data, sizeof(uint32_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
|
||||
* options structs. Since the source of these calls will be from Ruby
|
||||
* implementation internals we assume it is from a trusted source.
|
||||
*/
|
||||
void
|
||||
pm_options_read(pm_options_t *options, const char *data) {
|
||||
uint32_t filepath_length = pm_options_read_u32(data);
|
||||
data += 4;
|
||||
|
||||
if (filepath_length > 0) {
|
||||
pm_string_constant_init(&options->filepath, data, filepath_length);
|
||||
data += filepath_length;
|
||||
}
|
||||
|
||||
options->line = pm_options_read_u32(data);
|
||||
data += 4;
|
||||
|
||||
uint32_t encoding_length = pm_options_read_u32(data);
|
||||
data += 4;
|
||||
|
||||
if (encoding_length > 0) {
|
||||
pm_string_constant_init(&options->encoding, data, encoding_length);
|
||||
data += encoding_length;
|
||||
}
|
||||
|
||||
options->frozen_string_literal = *data++;
|
||||
options->suppress_warnings = *data++;
|
||||
|
||||
uint32_t scopes_count = pm_options_read_u32(data);
|
||||
data += 4;
|
||||
|
||||
if (scopes_count > 0) {
|
||||
pm_options_scopes_init(options, scopes_count);
|
||||
|
||||
for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) {
|
||||
uint32_t locals_count = pm_options_read_u32(data);
|
||||
data += 4;
|
||||
|
||||
pm_options_scope_t *scope = &options->scopes[scope_index];
|
||||
pm_options_scope_init(scope, locals_count);
|
||||
|
||||
for (size_t local_index = 0; local_index < locals_count; local_index++) {
|
||||
uint32_t local_length = pm_options_read_u32(data);
|
||||
data += 4;
|
||||
|
||||
pm_string_constant_init(&scope->locals[local_index], data, local_length);
|
||||
data += local_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue