diff options
Diffstat (limited to 'mini_builtin.c')
| -rw-r--r-- | mini_builtin.c | 131 |
1 files changed, 76 insertions, 55 deletions
diff --git a/mini_builtin.c b/mini_builtin.c index c263d1ee71..75ea94d37d 100644 --- a/mini_builtin.c +++ b/mini_builtin.c @@ -1,55 +1,98 @@ #include "internal.h" #include "internal/array.h" +#include "internal/eval.h" #include "iseq.h" #include "vm_core.h" #include "builtin.h" #include "miniprelude.c" -// included from miniinit.c +static VALUE +prelude_ast_value(VALUE name, VALUE code, int line) +{ + rb_ast_t *ast; + VALUE ast_value = rb_parser_compile_string_path(rb_parser_new(), name, code, line); + ast = rb_ruby_ast_data_get(ast_value); + if (!ast || !ast->body.root) { + if (ast) rb_ast_dispose(ast); + rb_exc_raise(rb_errinfo()); + } + return ast_value; +} -#ifndef INCLUDED_BY_BUILTIN_C -static struct st_table *loaded_builtin_table; -#endif +static void +pm_prelude_load(pm_parse_result_t *result, VALUE name, VALUE code, int line) +{ + pm_parse_result_init(result); + pm_options_line_set(result->options, line); + VALUE error = pm_parse_string(result, code, name, NULL); -rb_ast_t *rb_builtin_ast(const char *feature_name, VALUE *name_str); + if (!NIL_P(error)) { + pm_parse_result_free(result); + rb_exc_raise(error); + } +} static const rb_iseq_t * builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *table) { VALUE name_str = 0; - rb_ast_t *ast = rb_builtin_ast(feature_name, &name_str); - rb_vm_t *vm = GET_VM(); + int start_line; + const rb_iseq_t *iseq; + VALUE code = rb_builtin_find(feature_name, &name_str, &start_line); + if (NIL_P(code)) { + rb_fatal("builtin_iseq_load: can not find %s; " + "probably miniprelude.c is out of date", + feature_name); + } - vm->builtin_function_table = table; - vm->builtin_inline_index = 0; + rb_vm_t *vm = GET_VM(); static const rb_compile_option_t optimization = { - TRUE, /* int inline_const_cache; */ - TRUE, /* int peephole_optimization; */ - FALSE,/* int tailcall_optimization; */ - TRUE, /* int specialized_instruction; */ - TRUE, /* int operands_unification; */ - TRUE, /* int instructions_unification; */ - TRUE, /* int stack_caching; */ - TRUE, /* int frozen_string_literal; */ - FALSE, /* int debug_frozen_string_literal; */ - FALSE, /* unsigned int coverage_enabled; */ - 0, /* int debug_level; */ + .inline_const_cache = TRUE, + .peephole_optimization = TRUE, + .tailcall_optimization = FALSE, + .specialized_instruction = TRUE, + .operands_unification = TRUE, + .instructions_unification = TRUE, + .frozen_string_literal = TRUE, + .debug_frozen_string_literal = FALSE, + .coverage_enabled = FALSE, + .debug_level = 0, }; - const rb_iseq_t *iseq = rb_iseq_new_with_opt(&ast->body, name_str, name_str, Qnil, 0, NULL, 0, ISEQ_TYPE_TOP, &optimization); - GET_VM()->builtin_function_table = NULL; - rb_ast_dispose(ast); + if (rb_ruby_prism_p()) { + pm_parse_result_t result; + pm_prelude_load(&result, name_str, code, start_line); + + vm->builtin_function_table = table; + int error_state; + iseq = pm_iseq_new_with_opt(&result.node, name_str, name_str, Qnil, 0, NULL, 0, ISEQ_TYPE_TOP, &optimization, &error_state); + + vm->builtin_function_table = NULL; + pm_parse_result_free(&result); + + if (error_state) { + RUBY_ASSERT(iseq == NULL); + rb_jump_tag(error_state); + } + } + else { + VALUE ast_value = prelude_ast_value(name_str, code, start_line); + rb_ast_t *ast = rb_ruby_ast_data_get(ast_value); + + vm->builtin_function_table = table; + iseq = rb_iseq_new_with_opt(ast_value, name_str, name_str, Qnil, 0, NULL, 0, ISEQ_TYPE_TOP, &optimization, Qnil); + + vm->builtin_function_table = NULL; + rb_ast_dispose(ast); + } // for debug if (0 && strcmp("prelude", feature_name) == 0) { rb_io_write(rb_stdout, rb_iseq_disasm((const rb_iseq_t *)iseq)); } -#ifndef INCLUDED_BY_BUILTIN_C - st_insert(loaded_builtin_table, (st_data_t)feature_name, (st_data_t)iseq); - rb_gc_register_mark_object((VALUE)iseq); -#endif + BUILTIN_LOADED(feature_name, iseq); return iseq; } @@ -58,40 +101,18 @@ void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table) { const rb_iseq_t *iseq = builtin_iseq_load(feature_name, table); - rb_iseq_eval(iseq); -} - -#ifndef INCLUDED_BY_BUILTIN_C - -static int -each_builtin_i(st_data_t key, st_data_t val, st_data_t dmy) -{ - const char *feature = (const char *)key; - const rb_iseq_t *iseq = (const rb_iseq_t *)val; - - rb_yield_values(2, rb_str_new2(feature), rb_iseqw_new(iseq)); - - return ST_CONTINUE; + rb_iseq_eval(iseq, rb_root_box()); } -static VALUE -each_builtin(VALUE self) +VALUE +rb_define_gem_modules(VALUE _a, VALUE _b) { - st_foreach(loaded_builtin_table, each_builtin_i, 0); + // do nothing - moniruby doesn't load gem_prelude.rb. return Qnil; } void -Init_builtin(void) -{ - rb_define_singleton_method(rb_cRubyVM, "each_builtin", each_builtin, 0); - loaded_builtin_table = st_init_strtable(); -} - -void -Init_builtin_features(void) +rb_load_gem_prelude(VALUE _) { - // register for ruby - builtin_iseq_load("gem_prelude", NULL); + // do nothing - miniruby doesn't support loading RubyGems. } -#endif |
