Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions include/prism/internal/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
#define PM_LOCATION_END(location_) ((location_)->start + (location_)->length)

/*
* Slow path for pm_node_list_append: grow the list and append the node.
* Do not call directly — use pm_node_list_append instead.
* Slow path for pm_node_list_append_inline: grow the list and append the node.
* Do not call directly — use pm_node_list_append_inline instead.
*/
void pm_node_list_append_slow(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node);

/* Append a new node onto the end of the node list. */
/*
* Append a new node onto the end of the node list, handling the common case
* inline and growing the list through pm_node_list_append_slow. This is the
* version for prism's own code; others call the exported pm_node_list_append.
*/
static PRISM_FORCE_INLINE void
pm_node_list_append(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) {
pm_node_list_append_inline(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) {
if (list->size < list->capacity) {
list->nodes[list->size++] = node;
} else {
Expand Down
12 changes: 12 additions & 0 deletions include/prism/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ extern "C" {
#define PM_NODE_LIST_FOREACH(list, index, node) \
for (size_t index = 0; index < (list)->size && ((node) = (list)->nodes[index]); index++)

/**
* Append a node to the end of a node list. If the list is full, its storage is
* grown by allocating from the given arena, so the arena must live as long as
* the list does. For a list in a parsed tree, that is the arena that was passed
* to pm_parser_new.
*
* @param arena The arena to allocate the list's storage from.
* @param list The list to append to.
* @param node The node to append.
*/
PRISM_EXPORTED_FUNCTION void pm_node_list_append(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) PRISM_NONNULL(1, 2, 3);

/**
* Returns a string representation of the given node type.
*
Expand Down
18 changes: 18 additions & 0 deletions include/prism/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,24 @@ PRISM_EXPORTED_FUNCTION const pm_string_t * pm_parser_filepath(const pm_parser_t
*/
PRISM_EXPORTED_FUNCTION pm_constant_id_t pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t length) PRISM_NONNULL(1, 2);

/**
* Add a constant to the parser's constant pool, for naming a node that was not
* parsed from the source. If the constant is already in the pool, its existing
* id is returned. Otherwise the parser copies the bytes, so they only need to
* remain valid for the duration of the call.
*
* Adding a constant makes the pool larger, so a cache with one entry per
* constant built beforehand from pm_parser_constants_size and
* pm_parser_constant_at does not cover it. Build such caches after adding any
* constants.
*
* @param parser the parser whose constant pool we want to add to
* @param start a pointer to the start of the string to add
* @param length the length of the string to add
* @returns the id of the constant
*/
PRISM_EXPORTED_FUNCTION pm_constant_id_t pm_parser_constant_insert(pm_parser_t *parser, const uint8_t *start, size_t length) PRISM_NONNULL(1, 2);

/**
* Returns the frozen string literal value of the parser, as determined by the
* frozen_string_literal magic comment or the option set on the parser.
Expand Down
2 changes: 2 additions & 0 deletions rust/ruby-prism-sys/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ fn generate_bindings(ruby_include_path: &Path, clang_args: &[String], layout_tes
.allowlist_function("pm_magic_comment_key")
.allowlist_function("pm_magic_comment_next")
.allowlist_function("pm_magic_comment_value")
.allowlist_function("pm_node_list_append")
.allowlist_function("pm_options_command_line_set")
.allowlist_function("pm_options_encoding_locked_set")
.allowlist_function("pm_options_encoding_set")
Expand All @@ -220,6 +221,7 @@ fn generate_bindings(ruby_include_path: &Path, clang_args: &[String], layout_tes
.allowlist_function("pm_parser_comments_size")
.allowlist_function("pm_parser_constant")
.allowlist_function("pm_parser_constant_at")
.allowlist_function("pm_parser_constant_insert")
.allowlist_function("pm_parser_constants_size")
.allowlist_function("pm_parser_data_loc")
.allowlist_function("pm_parser_errors_first")
Expand Down
41 changes: 40 additions & 1 deletion rust/ruby-prism-sys/src/bindings.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t
return pm_constant_pool_find(&parser->constant_pool, start, length);
}

/**
* Add a constant to the parser's constant pool, copying its bytes into the
* parser's arena only if the constant is not already there.
*/
pm_constant_id_t
pm_parser_constant_insert(pm_parser_t *parser, const uint8_t *start, size_t length) {
pm_constant_id_t id = pm_constant_pool_find(&parser->constant_pool, start, length);
if (id != PM_CONSTANT_ID_UNSET) return id;

const uint8_t *copy = (const uint8_t *) pm_arena_memdup(&parser->metadata_arena, start, length, PRISM_ALIGNOF(uint8_t));
return pm_constant_pool_insert_constant(&parser->metadata_arena, &parser->constant_pool, copy, length);
}

/**
* Returns the frozen string literal value of the parser.
*/
Expand Down
Loading
Loading