summaryrefslogtreecommitdiff
path: root/template
diff options
context:
space:
mode:
authorHASUMI Hitoshi <hasumikin@gmail.com>2024-04-16 18:42:42 +0900
committerYuichiro Kaneko <spiketeika@gmail.com>2024-04-26 11:21:08 +0900
commit2244c58b009c31da60ad108d6cbccf99d97a5e29 (patch)
tree8d8a6cab701722368e72479a0f8505dfbf5d9a45 /template
parent9b5bc8e6ea3e5269a5415546a33fd09035eab168 (diff)
[Universal parser] Decouple IMEMO from rb_ast_tHEADmaster
This patch removes the `VALUE flags` member from the `rb_ast_t` structure making `rb_ast_t` no longer an IMEMO object. ## Background We are trying to make the Ruby parser generated from parse.y a universal parser that can be used by other implementations such as mruby. To achieve this, it is necessary to exclude VALUE and IMEMO from parse.y, AST, and NODE. ## Summary (file by file) - `rubyparser.h` - Remove the `VALUE flags` member from `rb_ast_t` - `ruby_parser.c` and `internal/ruby_parser.h` - Use TypedData_Make_Struct VALUE which wraps `rb_ast_t` `in ast_alloc()` so that GC can manage it - You can retrieve `rb_ast_t` from the VALUE by `rb_ruby_ast_data_get()` - Change the return type of `rb_parser_compile_XXXX()` functions from `rb_ast_t *` to `VALUE` - rb_ruby_ast_new() which internally `calls ast_alloc()` is to create VALUE vast outside ruby_parser.c - `iseq.c` and `vm_core.h` - Amend the first parameter of `rb_iseq_new_XXXX()` functions from `rb_ast_body_t *` to `VALUE` - This keeps the VALUE of AST on the machine stack to prevent being removed by GC - `ast.c` - Almost all change is replacement `rb_ast_t *ast` with `VALUE vast` (sorry for the big diff) - Fix `node_memsize()` - Now it includes `rb_ast_local_table_link`, `tokens` and script_lines - `compile.c`, `load.c`, `node.c`, `parse.y`, `proc.c`, `ruby.c`, `template/prelude.c.tmpl`, `vm.c` and `vm_eval.c` - Follow-up due to the above changes - `imemo.{c|h}` - If an object with `imemo_ast` appears, considers it a bug Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Diffstat (limited to 'template')
-rw-r--r--template/prelude.c.tmpl30
1 files changed, 17 insertions, 13 deletions
diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl
index dc0a143004..386511f20c 100644
--- a/template/prelude.c.tmpl
+++ b/template/prelude.c.tmpl
@@ -141,37 +141,39 @@ COMPILER_WARNING_POP
#define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1)
#define PRELUDE_CODE(n) rb_utf8_str_new_static(prelude_code##n.L0, sizeof(prelude_code##n))
-static rb_ast_t *
-prelude_ast(VALUE name, VALUE code, int line)
+static VALUE
+prelude_vast(VALUE name, VALUE code, int line)
{
- rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line);
+ rb_ast_t *ast;
+ VALUE vast = rb_parser_compile_string_path(rb_parser_new(), name, code, line);
+ ast = rb_ruby_ast_data_get(vast);
if (!ast || !ast->body.root) {
if (ast) rb_ast_dispose(ast);
rb_exc_raise(rb_errinfo());
}
- return ast;
+ return vast;
}
% end
% if @builtin_count > 0
-#define PRELUDE_AST(n, name_str, start_line) \
+#define PRELUDE_VAST(n, name_str, start_line) \
(((sizeof(prelude_name<%='##'%><%=%>n) - prefix_len - 2) == namelen) && \
(strncmp(prelude_name<%='##'%><%=%>n + prefix_len, feature_name, namelen) == 0) ? \
- prelude_ast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : 0)
+ prelude_vast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : Qnil)
-rb_ast_t *
-rb_builtin_ast(const char *feature_name, VALUE *name_str)
+VALUE
+rb_builtin_vast(const char *feature_name, VALUE *name_str)
{
const size_t prefix_len = rb_strlen_lit("<internal:");
size_t namelen = strlen(feature_name);
- rb_ast_t *ast = 0;
+ VALUE vast = Qnil;
% @preludes.each_value do |i, prelude, lines, sub, start_line|
% if sub
- if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str, <%=start_line%>)) != 0) return ast;
+ if (!NIL_P(vast = PRELUDE_VAST(<%=i%><%=%>, *name_str, <%=start_line%>))) return vast;
% end
% end
- return ast;
+ return vast;
}
% end
@@ -196,8 +198,10 @@ prelude_eval(VALUE code, VALUE name, int line)
0, /* int debug_level; */
};
- rb_ast_t *ast = prelude_ast(name, code, line);
- rb_iseq_eval(rb_iseq_new_with_opt(&ast->body, name, name, Qnil, line,
+ rb_ast_t *ast;
+ VALUE vast = prelude_vast(name, code, line);
+ ast = rb_ruby_ast_data_get(vast);
+ rb_iseq_eval(rb_iseq_new_with_opt(vast, name, name, Qnil, line,
NULL, 0, ISEQ_TYPE_TOP, &optimization,
Qnil));
rb_ast_dispose(ast);