Ruby 4.1.0dev (2026-09-17 revision 55562be3de92cc8a8713b15c6dc6baa0d7662ae5)
prism_compile.h (55562be3de92cc8a8713b15c6dc6baa0d7662ae5)
1#include "prism/prism.h"
2#include "ruby/encoding.h"
3
12typedef struct pm_local_index_struct {
13 int index, level;
15
16// A declaration for the struct that lives in compile.c.
17struct iseq_link_anchor;
19
28typedef struct {
30 int *values;
31
34
36 bool owned;
38
40#define PM_INDEX_LOOKUP_SPECIALS 4
41
43#define PM_SPECIAL_CONSTANT_FLAG ((pm_constant_id_t) (1 << 31))
44#define PM_INDEX_LOOKUP_SPECIAL_MULT 0
45#define PM_INDEX_LOOKUP_SPECIAL_POW 1
46#define PM_INDEX_LOOKUP_SPECIAL_AND 2
47#define PM_INDEX_LOOKUP_SPECIAL_DOT3 3
48
54#define PM_CONSTANT_MULT ((pm_constant_id_t) (PM_SPECIAL_CONSTANT_FLAG | PM_INDEX_LOOKUP_SPECIAL_MULT))
55#define PM_CONSTANT_POW ((pm_constant_id_t) (PM_SPECIAL_CONSTANT_FLAG | PM_INDEX_LOOKUP_SPECIAL_POW))
56#define PM_CONSTANT_AND ((pm_constant_id_t) (PM_SPECIAL_CONSTANT_FLAG | PM_INDEX_LOOKUP_SPECIAL_AND))
57#define PM_CONSTANT_DOT3 ((pm_constant_id_t) (PM_SPECIAL_CONSTANT_FLAG | PM_INDEX_LOOKUP_SPECIAL_DOT3))
58
59static inline int
60pm_index_lookup_table_index(const pm_index_lookup_table_t *table, pm_constant_id_t key)
61{
62 if (LIKELY(!(key & PM_SPECIAL_CONSTANT_FLAG))) {
63 return (int) key - 1;
64 }
65 return table->capacity - PM_INDEX_LOOKUP_SPECIALS + (int)(key & ~PM_SPECIAL_CONSTANT_FLAG);
66}
67
68static inline void
69pm_index_lookup_table_insert(pm_index_lookup_table_t *table, pm_constant_id_t key, int value)
70{
71 int idx = pm_index_lookup_table_index(table, key);
72 RUBY_ASSERT(idx >= 0 && idx < table->capacity);
73 table->values[idx] = value;
74}
75
76static inline int
77pm_index_lookup_table_lookup(const pm_index_lookup_table_t *table, pm_constant_id_t key, int *value)
78{
79 int idx = pm_index_lookup_table_index(table, key);
80 RUBY_ASSERT(idx >= 0 && idx < table->capacity);
81 if (table->values[idx] == -1) return 0;
82 *value = table->values[idx];
83 return 1;
84}
85
86static inline void
87pm_index_lookup_table_init_heap(pm_index_lookup_table_t *table, int constants_size)
88{
89 int cap = constants_size + PM_INDEX_LOOKUP_SPECIALS;
90 table->values = (int *) ruby_xmalloc(cap * sizeof(int));
91 memset(table->values, -1, cap * sizeof(int));
92 table->capacity = cap;
93 table->owned = true;
94}
95
96// ScopeNodes are helper nodes, and will never be part of the AST. We manually
97// declare them here to avoid generating them.
98typedef struct pm_scope_node {
99 pm_node_t base;
100 struct pm_scope_node *previous;
101 pm_node_t *ast_node;
102 pm_node_t *parameters;
103 pm_node_t *body;
105
106 const pm_parser_t *parser;
107
109 uint64_t source_hash;
110 const pm_options_t *options;
111 const pm_line_offset_list_t *line_offsets;
112 int32_t start_line;
113 rb_encoding *encoding;
114
124
131
132 // The size of the local table on the iseq which includes locals and hidden
133 // variables.
134 int local_table_for_iseq_size;
135
136 ID *constants;
137
145
146 // The current coverage setting, passed down through the various scopes.
147 int coverage_enabled;
148
154
160 size_t last_line;
162
163void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous);
164void pm_scope_node_destroy(pm_scope_node_t *scope_node);
165
185
186void pm_parse_result_init(pm_parse_result_t *result);
187VALUE pm_load_file(pm_parse_result_t *result, VALUE filepath, bool load_error);
188VALUE pm_parse_file(pm_parse_result_t *result, VALUE filepath, VALUE *script_lines);
189VALUE pm_load_parse_file(pm_parse_result_t *result, VALUE filepath, VALUE *script_lines);
190VALUE pm_parse_string(pm_parse_result_t *result, VALUE source, VALUE filepath, VALUE *script_lines);
191VALUE pm_parse_stdin(pm_parse_result_t *result);
192void pm_options_version_for_current_ruby_set(pm_options_t *options);
193void pm_parse_result_free(pm_parse_result_t *result);
194bool pm_node_source_location(VALUE source, VALUE filepath, int start_line,
195 int node_id, struct rb_code_location_struct *location);
196
197rb_iseq_t *pm_iseq_new(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum rb_iseq_type, int *error_state);
198rb_iseq_t *pm_iseq_new_top(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, int *error_state);
199rb_iseq_t *pm_iseq_new_main(pm_scope_node_t *node, VALUE path, VALUE realpath, const rb_iseq_t *parent, int opt, int *error_state);
200rb_iseq_t *pm_iseq_new_eval(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth, int *error_state);
201rb_iseq_t *pm_iseq_new_with_opt(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth, enum rb_iseq_type, const rb_compile_option_t *option, int *error_state);
202rb_iseq_t *pm_iseq_build(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth, enum rb_iseq_type, const rb_compile_option_t *option);
203
204VALUE pm_iseq_compile_node(rb_iseq_t *iseq, pm_scope_node_t *node);
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
uint32_t pm_constant_id_t
A constant id is a unique identifier for a constant in the constant pool.
Encoding relates APIs.
The main header file for the prism parser.
A list of constant IDs.
A direct-indexed lookup table mapping constant IDs to local variable indices.
int capacity
Total number of slots (constants_size + PM_INDEX_LOOKUP_SPECIALS).
bool owned
Whether the values array is heap-allocated and needs explicit free.
int * values
Array of local indices, indexed by constant_id.
A list of offsets of the start of lines in a string.
the getlocal and setlocal instructions require two parameters.
This is the base structure that represents a node in the syntax tree.
Definition ast.h:1083
bool parsed
Whether or not this parse result has performed its parsing yet.
pm_parser_t * parser
The parser that will do the actual parsing.
pm_source_t * source
The source backing the parse (file, string, or stream).
pm_scope_node_t node
The resulting scope node that will hold the generated AST.
pm_options_t * options
The options that will be passed to the parser.
pm_arena_t * arena
The arena allocator for AST-lifetime memory.
uint64_t source_hash
The source hash of the parsed source, propagated to every iseq.
rb_encoding * filepath_encoding
This is the encoding of the actual filepath object that will be used when a FILE node is compiled or ...
pm_index_lookup_table_t index_lookup_table
A flat lookup table mapping constant IDs (or special IDs) to local variable indices.
size_t last_line
Cached line hint for line offset list lookups.
struct iseq_link_anchor * pre_execution_anchor
This will only be set on the top-level scope node.
VALUE * script_lines
This is a pointer to the list of script lines for the ISEQs that will be associated with this scope n...
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40