diff options
author | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-08-26 14:25:53 +0900 |
---|---|---|
committer | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-08-27 15:52:26 +0900 |
commit | b8fd2e83e7b18fe3c70fc342388b1cb054b22e42 (patch) | |
tree | ede1f096b9a970a831f036323915b1b76f40aa17 | |
parent | 7329b3339adab12092056bd8159513645d4f9e8a (diff) |
decouple compile.c usage of imemo_ifunc
After 5e86b005c0f2ef30df2f9906c7e2f3abefe286a2, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
struct vm_ifunc, but in doing so we also have to decouple the usage
of this struct in compile.c, which (I think) is an abuse of ANYARGS.
-rw-r--r-- | compile.c | 45 | ||||
-rw-r--r-- | internal.h | 6 | ||||
-rw-r--r-- | iseq.c | 10 | ||||
-rw-r--r-- | iseq.h | 2 | ||||
-rw-r--r-- | proc.c | 8 | ||||
-rw-r--r-- | vm_core.h | 19 | ||||
-rw-r--r-- | vm_insnhelper.c | 2 |
7 files changed, 56 insertions, 36 deletions
@@ -615,7 +615,7 @@ validate_labels(rb_iseq_t *iseq, st_table *labels_table) } VALUE -rb_iseq_compile_ifunc(rb_iseq_t *iseq, const struct vm_ifunc *ifunc) +rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc) { DECL_ANCHOR(ret); INIT_ANCHOR(ret); @@ -1206,16 +1206,16 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node, } static rb_iseq_t * -new_child_iseq_ifunc(rb_iseq_t *iseq, const struct vm_ifunc *ifunc, +new_child_iseq_with_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func *ifunc, VALUE name, const rb_iseq_t *parent, enum iseq_type type, int line_no) { rb_iseq_t *ret_iseq; - debugs("[new_child_iseq_ifunc]> ---------------------------------------\n"); - ret_iseq = rb_iseq_new_ifunc(ifunc, name, + debugs("[new_child_iseq_with_callback]> ---------------------------------------\n"); + ret_iseq = rb_iseq_new_with_callback(ifunc, name, rb_iseq_path(iseq), rb_iseq_realpath(iseq), INT2FIX(line_no), parent, type, ISEQ_COMPILE_DATA(iseq)->option); - debugs("[new_child_iseq_ifunc]< ---------------------------------------\n"); + debugs("[new_child_iseq_with_callback]< ---------------------------------------\n"); iseq_add_mark_object_compile_time(iseq, (VALUE)ret_iseq); return ret_iseq; } @@ -4629,12 +4629,11 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, } } -static VALUE -build_defined_rescue_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *unused) +static void +build_defined_rescue_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const void *unused) { ADD_INSN(ret, 0, putnil); iseq_set_exception_local_table(iseq); - return Qnil; } static void @@ -4648,7 +4647,9 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, LABEL *lstart = NEW_LABEL(line); LABEL *lend = NEW_LABEL(line); const rb_iseq_t *rescue; - rescue = new_child_iseq_ifunc(iseq, IFUNC_NEW(build_defined_rescue_iseq, 0, 0), + struct rb_iseq_new_with_callback_callback_func *ifunc = + rb_iseq_new_with_callback_new_callback(build_defined_rescue_iseq, NULL); + rescue = new_child_iseq_with_callback(iseq, ifunc, rb_str_concat(rb_str_new2("defined guard in "), iseq->body->location.label), iseq, ISEQ_TYPE_RESCUE, 0); @@ -4871,9 +4872,10 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, return ret; } -static VALUE -build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *body) +static void +build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *ptr) { + const NODE *body = ptr; int line = nd_line(body); VALUE argc = INT2FIX(0); const rb_iseq_t *block = NEW_CHILD_ISEQ(body, make_name_for_block(iseq->body->parent_iseq), ISEQ_TYPE_BLOCK, line); @@ -4881,7 +4883,6 @@ build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *body) ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); ADD_CALL_WITH_BLOCK(ret, line, id_core_set_postexe, argc, block); iseq_set_local_table(iseq, 0); - return Qnil; } static void @@ -8008,8 +8009,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in * ONCE{ rb_mRubyVMFrozenCore::core#set_postexe{ ... } } */ int is_index = body->is_size++; + struct rb_iseq_new_with_callback_callback_func *ifunc = + rb_iseq_new_with_callback_new_callback(build_postexe_iseq, node->nd_body); const rb_iseq_t *once_iseq = - new_child_iseq_ifunc(iseq, IFUNC_NEW(build_postexe_iseq, node->nd_body, 0), + new_child_iseq_with_callback(iseq, ifunc, rb_fstring(make_name_for_block(iseq)), iseq, ISEQ_TYPE_BLOCK, line); ADD_INSN2(ret, line, once, once_iseq, INT2FIX(is_index)); @@ -8978,7 +8981,7 @@ typedef struct { static const rb_iseq_t * method_for_self(VALUE name, VALUE arg, rb_insn_func_t func, - VALUE (*build)(rb_iseq_t *, LINK_ANCHOR *const, VALUE)) + void (*build)(rb_iseq_t *, LINK_ANCHOR *, const void *)) { VALUE path, realpath; accessor_args acc; @@ -8986,13 +8989,15 @@ method_for_self(VALUE name, VALUE arg, rb_insn_func_t func, acc.arg = arg; acc.func = func; acc.line = caller_location(&path, &realpath); - return rb_iseq_new_ifunc(IFUNC_NEW(build, (VALUE)&acc, 0), + struct rb_iseq_new_with_callback_callback_func *ifunc = + rb_iseq_new_with_callback_new_callback(build, &acc); + return rb_iseq_new_with_callback(ifunc, rb_sym2str(name), path, realpath, INT2FIX(acc.line), 0, ISEQ_TYPE_METHOD, 0); } -static VALUE -for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a) +static void +for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *a) { const accessor_args *const args = (void *)a; const int line = args->line; @@ -9004,11 +9009,10 @@ for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a) ADD_INSN1(ret, line, putobject, args->arg); ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func); - return Qnil; } -static VALUE -for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a) +static void +for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *a) { const accessor_args *const args = (void *)a; const int line = args->line; @@ -9023,7 +9027,6 @@ for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a) ADD_INSN1(ret, line, putobject, args->arg); ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func); ADD_INSN(ret, line, pop); - return Qnil; } /* diff --git a/internal.h b/internal.h index d6b762aeeb..01009b616a 100644 --- a/internal.h +++ b/internal.h @@ -1181,15 +1181,15 @@ struct vm_ifunc_argc { struct vm_ifunc { VALUE flags; VALUE reserved; - VALUE (*func)(ANYARGS); + rb_block_call_func_t func; const void *data; struct vm_ifunc_argc argc; }; #define IFUNC_NEW(a, b, c) ((struct vm_ifunc *)rb_imemo_new(imemo_ifunc, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0)) -struct vm_ifunc *rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_argc); +struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc); static inline struct vm_ifunc * -rb_vm_ifunc_proc_new(VALUE (*func)(ANYARGS), const void *data) +rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data) { return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS); } @@ -809,9 +809,11 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea } rb_iseq_t * -rb_iseq_new_ifunc(const struct vm_ifunc *ifunc, VALUE name, VALUE path, VALUE realpath, - VALUE first_lineno, const rb_iseq_t *parent, - enum iseq_type type, const rb_compile_option_t *option) +rb_iseq_new_with_callback( + const struct rb_iseq_new_with_callback_callback_func * ifunc, + VALUE name, VALUE path, VALUE realpath, + VALUE first_lineno, const rb_iseq_t *parent, + enum iseq_type type, const rb_compile_option_t *option) { /* TODO: argument check */ rb_iseq_t *iseq = iseq_alloc(); @@ -819,7 +821,7 @@ rb_iseq_new_ifunc(const struct vm_ifunc *ifunc, VALUE name, VALUE path, VALUE re if (!option) option = &COMPILE_OPTION_DEFAULT; prepare_iseq_build(iseq, name, path, realpath, first_lineno, NULL, -1, parent, type, option); - rb_iseq_compile_ifunc(iseq, ifunc); + rb_iseq_compile_callback(iseq, ifunc); finish_iseq_build(iseq); return iseq_translate(iseq); @@ -162,7 +162,7 @@ RUBY_SYMBOL_EXPORT_BEGIN /* compile.c */ VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node); -VALUE rb_iseq_compile_ifunc(rb_iseq_t *iseq, const struct vm_ifunc *ifunc); +VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc); int rb_iseq_translate_threaded_code(rb_iseq_t *iseq); VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq); void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, @@ -43,7 +43,7 @@ VALUE rb_cMethod; VALUE rb_cBinding; VALUE rb_cProc; -static VALUE bmcall(VALUE, VALUE, int, VALUE *, VALUE); +static rb_block_call_func bmcall; static int method_arity(VALUE); static int method_min_max_arity(VALUE, int *max); @@ -696,7 +696,7 @@ sym_proc_new(VALUE klass, VALUE sym) } struct vm_ifunc * -rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_argc) +rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc) { union { struct vm_ifunc_argc argc; @@ -2783,9 +2783,9 @@ mlambda(VALUE method) } static VALUE -bmcall(VALUE args, VALUE method, int argc, VALUE *argv, VALUE passed_proc) +bmcall(RB_BLOCK_CALL_FUNC_ARGLIST(args, method)) { - return rb_method_call_with_block(argc, argv, method, passed_proc); + return rb_method_call_with_block(argc, argv, method, blockarg); } VALUE @@ -1022,8 +1022,23 @@ rb_iseq_t *rb_iseq_new_top (const rb_ast_body_t *ast, VALUE name, VALUE path rb_iseq_t *rb_iseq_new_main (const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent); rb_iseq_t *rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*); -rb_iseq_t *rb_iseq_new_ifunc(const struct vm_ifunc *ifunc, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, - const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*); +struct iseq_link_anchor; +struct rb_iseq_new_with_callback_callback_func { + VALUE flags; + VALUE reserved; + void (*func)(rb_iseq_t *, struct iseq_link_anchor *, const void *); + const void *data; +}; +static inline struct rb_iseq_new_with_callback_callback_func * +rb_iseq_new_with_callback_new_callback( + void (*func)(rb_iseq_t *, struct iseq_link_anchor *, const void *), const void *ptr) +{ + VALUE memo = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)ptr, Qundef, Qfalse); + return (struct rb_iseq_new_with_callback_callback_func *)memo; +} +rb_iseq_t *rb_iseq_new_with_callback(const struct rb_iseq_new_with_callback_callback_func * ifunc, + VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, + const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*); /* src -> iseq */ rb_iseq_t *rb_iseq_compile(VALUE src, VALUE file, VALUE line); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index cc89398b90..e80a036e06 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2858,7 +2858,7 @@ vm_yield_with_cfunc(rb_execution_context_t *ec, VM_GUARDED_PREV_EP(captured->ep), (VALUE)me, 0, ec->cfp->sp, 0, 0); - val = (*ifunc->func)(arg, ifunc->data, argc, argv, blockarg); + val = (*ifunc->func)(arg, (VALUE)ifunc->data, argc, argv, blockarg); rb_vm_pop_frame(ec); return val; |