decouple compile.c usage of imemo_ifunc

After 5e86b005c0, 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.
This commit is contained in:
卜部昌平 2019-08-26 14:25:53 +09:00
parent 7329b3339a
commit b8fd2e83e7
7 changed files with 56 additions and 36 deletions

View File

@ -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;
}
/*

View File

@ -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);
}

10
iseq.c
View File

@ -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);

2
iseq.h
View File

@ -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,

8
proc.c
View File

@ -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

View File

@ -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);

View File

@ -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;