diff options
author | HASUMI Hitoshi <hasumikin@gmail.com> | 2024-04-16 18:42:42 +0900 |
---|---|---|
committer | Yuichiro Kaneko <spiketeika@gmail.com> | 2024-04-26 11:21:08 +0900 |
commit | 2244c58b009c31da60ad108d6cbccf99d97a5e29 (patch) | |
tree | 8d8a6cab701722368e72479a0f8505dfbf5d9a45 /template | |
parent | 9b5bc8e6ea3e5269a5415546a33fd09035eab168 (diff) |
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.tmpl | 30 |
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); |