ruby-changes:36161
From: ko1 <ko1@a...>
Date: Mon, 3 Nov 2014 08:14:39 +0900 (JST)
Subject: [ruby-changes:36161] ko1:r48242 (trunk): * vm_core.h: change iseq parameter data structure.
ko1 2014-11-03 08:14:21 +0900 (Mon, 03 Nov 2014) New Revision: 48242 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48242 Log: * vm_core.h: change iseq parameter data structure. https://bugs.ruby-lang.org/issues/10440#change-49694 * change terminology `arg' to `param'. * move rb_iseq_t::arg_* to rb_iseq_t::param. * move rb_iseq_t::arg_size to rb_iseq_t::param::size. * move rb_iseq_t::argc to rb_iseq_t::param::lead_num. * move rb_iseq_t::arg_opts to rb_iseq_t::param::opt_num. * move rb_iseq_t::arg_rest to rb_iseq_t::param::rest_start. * move rb_iseq_t::arg_post_num to rb_iseq_t::param::post_num. * move rb_iseq_t::arg_post_start to rb_iseq_t::param::post_start. * move rb_iseq_t::arg_block to rb_iseq_t::param::block_start. * move rb_iseq_t::arg_keyword* to rb_iseq_t::param::keyword. rb_iseq_t::param::keyword is allocated only when keyword parameters are available. * introduce rb_iseq_t::param::flags to represent parameter availability. For example, rb_iseq_t::param::flags::has_kw represents that this iseq has keyword parameters and rb_iseq_t::param::keyword is allocated. We don't need to compare with -1 to check availability. * remove rb_iseq_t::arg_simple. * compile.c: catch up this change. * iseq.c: ditto. * proc.c: ditto. * vm.c, vm_args.c, vm_dump.c, vm_insnhelper.c: ditto. * iseq.c (iseq_data_to_ary): support keyword argument. Modified files: trunk/ChangeLog trunk/compile.c trunk/iseq.c trunk/proc.c trunk/vm.c trunk/vm_args.c trunk/vm_core.h trunk/vm_dump.c trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 48241) +++ ChangeLog (revision 48242) @@ -1,4 +1,38 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 -Mon Nov 3 03:39:04 2014 Koichi Sasada <ko1@a...> +Mon Nov 3 07:49:34 2014 Koichi Sasada <ko1@a...> + + * vm_core.h: change iseq parameter data structure. + https://bugs.ruby-lang.org/issues/10440#change-49694 + + * change terminology `arg' to `param'. + * move rb_iseq_t::arg_* to rb_iseq_t::param. + * move rb_iseq_t::arg_size to rb_iseq_t::param::size. + * move rb_iseq_t::argc to rb_iseq_t::param::lead_num. + * move rb_iseq_t::arg_opts to rb_iseq_t::param::opt_num. + * move rb_iseq_t::arg_rest to rb_iseq_t::param::rest_start. + * move rb_iseq_t::arg_post_num to rb_iseq_t::param::post_num. + * move rb_iseq_t::arg_post_start to rb_iseq_t::param::post_start. + * move rb_iseq_t::arg_block to rb_iseq_t::param::block_start. + * move rb_iseq_t::arg_keyword* to rb_iseq_t::param::keyword. + rb_iseq_t::param::keyword is allocated only when keyword + parameters are available. + * introduce rb_iseq_t::param::flags to represent parameter + availability. For example, rb_iseq_t::param::flags::has_kw + represents that this iseq has keyword parameters and + rb_iseq_t::param::keyword is allocated. + We don't need to compare with -1 to check availability. + * remove rb_iseq_t::arg_simple. + + * compile.c: catch up this change. + + * iseq.c: ditto. + + * proc.c: ditto. + + * vm.c, vm_args.c, vm_dump.c, vm_insnhelper.c: ditto. + + * iseq.c (iseq_data_to_ary): support keyword argument. + +xMon Nov 3 03:39:04 2014 Koichi Sasada <ko1@a...> * test/ruby/test_method.rb: r48239 makes this test green. Index: vm_core.h =================================================================== --- vm_core.h (revision 48241) +++ vm_core.h (revision 48242) @@ -240,7 +240,7 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L240 rb_call_info_t *callinfo_entries; /** - * argument information + * parameter information * * def m(a1, a2, ..., aM, # mandatory * b1=(...), b2=(...), ..., bN=(...), # optional @@ -251,36 +251,50 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L251 * &g) # block * => * - * argc = M // or 0 if no mandatory arg - * arg_opts = N+1 // or 0 if no optional arg - * arg_rest = M+N // or -1 if no rest arg - * arg_opt_table = [ (arg_opts entries) ] - * arg_post_start = M+N+(*1) // or 0 if no post arguments - * arg_post_num = O // or 0 if no post arguments - * arg_keyword_num = K // or 0 if no keyword arg - * arg_block = M+N+(*1)+O+K // or -1 if no block arg - * arg_keyword_bits = M+N+(*1)+O+K+(&1) // or -1 if no keyword arg/rest - * arg_simple = 0 if not simple arguments. - * = 1 if no opt, rest, post, block. - * = 2 if ambiguous block parameter ({|a|}). - * arg_size = M+N+O+(*1)+K+(&1)+(**1) argument size. + * lead_num = M + * opt_num = N+1 + * rest_start = M+N + * post_start = M+N+(*1) + * post_num = O + * keyword_num = K + * block_start = M+N+(*1)+O+K + * keyword_bits = M+N+(*1)+O+K+(&1) + * size = M+N+O+(*1)+K+(&1)+(**1) // parameter size. */ - int argc; - int arg_simple; - int arg_rest; - int arg_block; - int arg_opts; - int arg_post_num; - int arg_post_start; - int arg_size; - VALUE *arg_opt_table; - int arg_keyword_num; - int arg_keyword_bits; - int arg_keyword_rest; - int arg_keyword_required; - ID *arg_keyword_table; - VALUE *arg_keyword_default_values; + struct { + struct { + unsigned int has_lead : 1; + unsigned int has_opt : 1; + unsigned int has_rest : 1; + unsigned int has_post : 1; + unsigned int has_kw : 1; + unsigned int has_kwrest : 1; + unsigned int has_block : 1; + + unsigned int ambiguous_param0 : 1; /* {|a|} */ + } flags; + + int size; + + int lead_num; + int opt_num; + int rest_start; + int post_start; + int post_num; + int block_start; + + VALUE *opt_table; + + struct rb_iseq_param_keyword { + int num; + int required_num; + int bits_start; + int rest_start; + ID *table; + VALUE *default_values; + } *keyword; + } param; /* catch table */ struct iseq_catch_table *catch_table; Index: iseq.c =================================================================== --- iseq.c (revision 48241) +++ iseq.c (revision 48242) @@ -23,7 +23,7 @@ https://github.com/ruby/ruby/blob/trunk/iseq.c#L23 #include "insns_info.inc" #define ISEQ_MAJOR_VERSION 2 -#define ISEQ_MINOR_VERSION 1 +#define ISEQ_MINOR_VERSION 2 VALUE rb_cISeq; @@ -87,7 +87,8 @@ iseq_free(void *ptr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L87 } RUBY_FREE_UNLESS_NULL(iseq->callinfo_entries); RUBY_FREE_UNLESS_NULL(iseq->catch_table); - RUBY_FREE_UNLESS_NULL(iseq->arg_opt_table); + RUBY_FREE_UNLESS_NULL(iseq->param.opt_table); + RUBY_FREE_UNLESS_NULL(iseq->param.keyword); compile_data_free(iseq->compile_data); RUBY_FREE_UNLESS_NULL(iseq->iseq); } @@ -142,7 +143,7 @@ iseq_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L143 if (iseq->catch_table) { size += iseq_catch_table_bytes(iseq->catch_table->size); } - size += iseq->arg_opts * sizeof(VALUE); + size += iseq->param.opt_num * sizeof(VALUE); size += iseq->is_size * sizeof(union iseq_inline_storage_entry); size += iseq->callinfo_size * sizeof(rb_call_info_t); @@ -262,32 +263,19 @@ prepare_iseq_build(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/iseq.c#L263 const rb_compile_option_t *option) { iseq->type = type; - iseq->arg_rest = -1; - iseq->arg_block = -1; - iseq->arg_keyword_bits = -1; - iseq->arg_keyword_rest = -1; RB_OBJ_WRITE(iseq->self, &iseq->klass, 0); set_relation(iseq, parent); name = rb_fstring(name); path = rb_fstring(path); - if (RTEST(absolute_path)) - absolute_path = rb_fstring(absolute_path); - + if (RTEST(absolute_path)) absolute_path = rb_fstring(absolute_path); iseq_location_setup(iseq, path, absolute_path, name, first_lineno); if (iseq != iseq->local_iseq) { RB_OBJ_WRITE(iseq->self, &iseq->location.base_label, iseq->local_iseq->location.label); } - iseq->defined_method_id = 0; RB_OBJ_WRITE(iseq->self, &iseq->mark_ary, 0); - /* - * iseq->special_block_builder = GC_GUARDED_PTR_REF(block_opt); - * iseq->cached_special_block_builder = 0; - * iseq->cached_special_block = 0; - */ - iseq->compile_data = ZALLOC(struct iseq_compile_data); RB_OBJ_WRITE(iseq->self, &iseq->compile_data->err_info, Qnil); RB_OBJ_WRITE(iseq->self, &iseq->compile_data->mark_ary, rb_ary_tmp_new(3)); @@ -1056,14 +1044,8 @@ VALUE iseq_data_to_ary(rb_iseq_t *iseq); https://github.com/ruby/ruby/blob/trunk/iseq.c#L1044 * An array containing the names of all arguments and local variables as * symbols. * - * [args] - * The arity if the method or block only has required arguments. - * - * Otherwise an array of: - * - * [required_argc, [optional_arg_labels, ...], - * splat_index, post_splat_argc, post_splat_index, - * block_index, simple] + * [params] + * An Hash object containing parameter information. * * More info about these values can be found in +vm_core.h+. * @@ -1075,6 +1057,8 @@ VALUE iseq_data_to_ary(rb_iseq_t *iseq); https://github.com/ruby/ruby/blob/trunk/iseq.c#L1057 * An array of arrays containing the instruction names and operands that * make up the body of the instruction sequence. * + * Note that this format is MRI specific and version dependent. + * */ static VALUE iseq_to_a(VALUE self) @@ -1384,7 +1368,7 @@ catch_type(int type) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1368 VALUE rb_iseq_disasm(VALUE self) { - rb_iseq_t *iseqdat = iseq_check(self); + rb_iseq_t *iseqdat = iseq_check(self); /* TODO: rename to iseq */ VALUE *iseq; VALUE str = rb_str_new(0, 0); VALUE child = rb_ary_new(); @@ -1433,13 +1417,16 @@ rb_iseq_disasm(VALUE self) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1417 if (tbl) { rb_str_catf(str, "local table (size: %d, argc: %d " - "[opts: %d, rest: %d, post: %d, block: %d, kw: %d@%d, kwrest: %d] s%d)\n", - iseqdat->local_size, iseqdat->argc, - iseqdat->arg_opts, iseqdat->arg_rest, - iseqdat->arg_post_num, iseqdat->arg_block, - iseqdat->arg_keyword_num, iseqdat->local_size - iseqdat->arg_keyword_bits, - iseqdat->arg_keyword_rest, - iseqdat->arg_simple); + "[opts: %d, rest: %d, post: %d, block: %d, kw: %d@%d, kwrest: %d])\n", + iseqdat->local_size, + iseqdat->param.lead_num, + iseqdat->param.opt_num - (iseqdat->param.flags.has_opt == TRUE), + iseqdat->param.flags.has_rest ? iseqdat->param.rest_start : -1, + iseqdat->param.post_num, + iseqdat->param.flags.has_block ? iseqdat->param.block_start : -1, + iseqdat->param.flags.has_kw ? iseqdat->param.keyword->num : -1, + iseqdat->param.flags.has_kw ? iseqdat->param.keyword->required_num : -1, + iseqdat->param.flags.has_kwrest ? iseqdat->param.keyword->rest_start : -1); for (i = 0; i < iseqdat->local_table_size; i++) { long width; @@ -1447,22 +1434,21 @@ rb_iseq_disasm(VALUE self) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1434 char argi[0x100] = ""; char opti[0x100] = ""; - if (iseqdat->arg_opts) { - int argc = iseqdat->argc; - int opts = iseqdat->arg_opts; + if (iseqdat->param.flags.has_opt) { + int argc = iseqdat->param.lead_num; + int opts = iseqdat->param.opt_num; if (i >= argc && i < argc + opts - 1) { snprintf(opti, sizeof(opti), "Opt=%"PRIdVALUE, - iseqdat->arg_opt_table[i - argc]); + iseqdat->param.opt_table[i - argc]); } } snprintf(argi, sizeof(argi), "%s%s%s%s%s", /* arg, opts, rest, post block */ - iseqdat->argc > i ? "Arg" : "", + iseqdat->param.lead_num > i ? "Arg" : "", opti, - iseqdat->arg_rest == i ? "Rest" : "", - (iseqdat->arg_post_start <= i && - i < iseqdat->arg_post_start + iseqdat->arg_post_num) ? "Post" : "", - iseqdat->arg_block == i ? "Block" : ""); + (iseqdat->param.flags.has_rest && iseqdat->param.rest_start == i) ? "Rest" : "", + (iseqdat->param.flags.has_post && iseqdat->param.post_start <= i && i < iseqdat->param.post_start + iseqdat->param.post_num) ? "Post" : "", + (iseqdat->param.flags.has_block && iseqdat->param.block_start == i) ? "Block" : ""); rb_str_catf(str, "[%2d] ", iseqdat->local_size - i); width = RSTRING_LEN(str) + 11; @@ -1669,7 +1655,7 @@ iseq_data_to_ary(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1655 VALUE val = rb_ary_new(); VALUE type; /* Symbol */ VALUE locals = rb_ary_new(); - VALUE args = rb_ary_new(); + VALUE params = rb_hash_new(); VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */ VALUE nbody; VALUE exception = rb_ary_new(); /* [[....]] */ @@ -1729,39 +1715,39 @@ iseq_data_to_ary(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1715 } } - /* args */ + /* params */ { - /* - * [argc, # argc - * [label1, label2, ...] # opts - * rest index, - * post_len - * post_start - * block index, - * simple, - * ] - */ VALUE arg_opt_labels = rb_ary_new(); int j; - for (j=0; j<iseq->arg_opts; j++) { - rb_ary_push(arg_opt_labels, - register_label(labels_table, iseq->arg_opt_table[j])); + for (j=0; j<iseq->param.opt_num; j++) { + rb_ary_push(arg_opt_labels, register_label(labels_table, iseq->param.opt_table[j])); } /* commit */ - if (iseq->arg_simple == 1) { - args = INT2FIX(iseq->argc); - } - else { - rb_ary_push(args, INT2FIX(iseq->argc)); - rb_ary_push(args, arg_opt_labels); - rb_ary_push(args, INT2FIX(iseq->arg_post_num)); - rb_ary_push(args, INT2FIX(iseq->arg_post_start)); - rb_ary_push(args, INT2FIX(iseq->arg_rest)); - rb_ary_push(args, INT2FIX(iseq->arg_block)); - rb_ary_push(args, INT2FIX(iseq->arg_simple)); + if (iseq->param.flags.has_lead) rb_hash_aset(params, ID2SYM(rb_intern("lead_num")), INT2FIX(iseq->param.lead_num)); + if (iseq->param.flags.has_opt) rb_hash_aset(params, ID2SYM(rb_intern("opt")), arg_opt_labels); + if (iseq->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_num")), INT2FIX(iseq->param.post_num)); + if (iseq->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_start")), INT2FIX(iseq->param.post_start)); + if (iseq->param.flags.has_rest) rb_hash_aset(params, ID2SYM(rb_intern("rest_start")), INT2FIX(iseq->param.rest_start)); + if (iseq->param.flags.has_block) rb_hash_aset(params, ID2SYM(rb_intern("block_start")), INT2FIX(iseq->param.block_start)); + if (iseq->param.flags.has_kw) { + VALUE keywords = rb_ary_new(); + int i, j; + for (i=0; i<iseq->param.keyword->required_num; i++) { + rb_ary_push(keywords, ID2SYM(iseq->param.keyword->table[i])); + } + for (j=0; i<iseq->param.keyword->num; i++, j++) { + VALUE key = rb_ary_new_from_args(1, ID2SYM(iseq->param.keyword->table[i])); + if (iseq->param.keyword->default_values[j] != Qundef) { + rb_ary_push(key, iseq->param.keyword->default_values[j]); + } + rb_ary_push(keywords, key); + } + rb_hash_aset(params, ID2SYM(rb_intern("keyword")), keywords); } + if (iseq->param.flags.has_kwrest) rb_hash_aset(params, ID2SYM(rb_intern("kwrest")), INT2FIX(iseq->param.keyword->rest_start)); + if (iseq->param.flags.ambiguous_param0) rb_hash_aset(params, ID2SYM(rb_intern("ambiguous_param0")), Qtrue); } /* body */ @@ -1897,7 +1883,7 @@ iseq_data_to_ary(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1883 st_free_table(labels_table); - rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->arg_size)); + rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->param.size)); rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->local_size)); rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->stack_max)); @@ -1918,7 +1904,7 @@ iseq_data_to_ary(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1904 rb_ary_push(val, iseq->location.first_lineno); rb_ary_push(val, type); rb_ary_push(val, locals); - rb_ary_push(val, args); + rb_ary_push(val, params); rb_ary_push(val, exception); rb_ary_push(val, body); return val; @@ -1959,7 +1945,7 @@ VALUE https://github.com/ruby/ruby/blob/trunk/iseq.c#L1945 rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc) { int i, r; - VALUE a, args = rb_ary_new2(iseq->arg_size); + VALUE a, args = rb_ary_new2(iseq->param.size); ID req, opt, rest, block, key, keyrest; #define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type)) #define PARAM_ID(i) iseq->local_table[(i)] @@ -1972,18 +1958,18 @@ rb_iseq_parameters(const rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/iseq.c#L1958 CONST_ID(req, "req"); CONST_ID(opt, "opt"); if (is_proc) { - for (i = 0; i < iseq->argc; i++) { + for (i = 0; i < iseq->param.lead_num; i++) { PARAM_TYPE(opt); rb_ary_push(a, rb_id2str(PARAM_ID(i)) ? ID2SYM(PARAM_ID(i)) : Qnil); rb_ary_push(args, a); } } else { - for (i = 0; i < iseq->argc; i++) { + for (i = 0; i < iseq->param.lead_num; i++) { rb_ary_push(args, PARAM(i, req)); } } - r = iseq->argc + iseq->arg_opts - 1; + r = iseq->param.lead_num + iseq->param.opt_num - 1; for (; i < r; i++) { PARAM_TYPE(opt); if (rb_id2str(PARAM_ID(i))) { @@ -1991,52 +1977,52 @@ rb_iseq_parameters(const rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/iseq.c#L1977 } rb_ary_push(args, a); } - if (iseq->arg_rest != -1) { + if (iseq->param.flags.has_rest) { CONST_ID(rest, "rest"); - rb_ary_push(args, PARAM(iseq->arg_rest, rest)); + rb_ary_push(args, PARAM(iseq->param.rest_start, rest)); } - r = iseq->arg_post_start + iseq->arg_post_num; + r = iseq->param.post_start + iseq->param.post_num; if (is_proc) { - for (i = iseq->arg_post_start; i < r; i++) { + for (i = iseq->param.post_start; i < r; i++) { PARAM_TYPE(opt); rb_ary_push(a, rb_id2str(PARAM_ID(i)) ? ID2SYM(PARAM_ID(i)) : Qnil); rb_ary_push(args, a); } } else { - for (i = iseq->arg_post_start; i < r; i++) { + for (i = iseq->param.post_start; i < r; i++) { rb_ary_push(args, PARAM(i, req)); } } - if (iseq->arg_keyword_bits != -1) { + if (iseq->param.flags.has_kw) { i = 0; - if (iseq->arg_keyword_required) { + if (iseq->param.keyword->required_num > 0) { ID keyreq; CONST_ID(keyreq, "keyreq"); - for (; i < iseq->arg_keyword_required; i++) { + for (; i < iseq->param.keyword->required_num; i++) { PARAM_TYPE(keyreq); - if (rb_id2str(iseq->arg_keyword_table[i])) { - rb_ary_push(a, ID2SYM(iseq->arg_keyword_table[i])); + if (rb_id2str(iseq->param.keyword->table[i])) { + rb_ary_push(a, ID2SYM(iseq->param.keyword->table[i])); } rb_ary_push(args, a); } } CONST_ID(key, "key"); - for (; i < iseq->arg_keyword_num; i++) { + for (; i < iseq->param.keyword->num; i++) { PARAM_TYPE(key); - if (rb_id2str(iseq->arg_keyword_table[i])) { - rb_ary_push(a, ID2SYM(iseq->arg_keyword_table[i])); + if (rb_id2str(iseq->param.keyword->table[i])) { + rb_ary_push(a, ID2SYM(iseq->param.keyword->table[i])); } rb_ary_push(args, a); } } - if (iseq->arg_keyword_rest >= 0) { + if (iseq->param.flags.has_kwrest) { CONST_ID(keyrest, "keyrest"); - rb_ary_push(args, PARAM(iseq->arg_keyword_rest, keyrest)); + rb_ary_push(args, PARAM(iseq->param.keyword->rest_start, keyrest)); } - if (iseq->arg_block != -1) { + if (iseq->param.flags.has_block) { CONST_ID(block, "block"); - rb_ary_push(args, PARAM(iseq->arg_block, block)); + rb_ary_push(args, PARAM(iseq->param.block_start, block)); } return args; } @@ -2136,8 +2122,8 @@ rb_iseq_build_for_ruby2cext( https://github.com/ruby/ruby/blob/trunk/iseq.c#L2122 struct iseq_catch_table_entry, iseq->catch_table->size); } - ALLOC_AND_COPY(iseq->arg_opt_table, arg_opt_table, - VALUE, iseq->arg_opts); + ALLOC_AND_COPY(iseq->param.opt_table, arg_opt_table, + VALUE, iseq->param.opt_num); set_relation(iseq, 0); Index: compile.c =================================================================== --- compile.c (revision 48241) +++ compile.c (revision 48242) @@ -1076,8 +1076,9 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L1076 } - iseq->argc = (int)args->pre_args_num; - debugs(" - argc: %d\n", iseq->argc); + iseq->param.lead_num = (int)args->pre_args_num; + if (iseq->param.lead_num > 0) iseq->param.flags.has_lead = TRUE; + debugs(" - argc: %d\n", iseq->param.lead_num); rest_id = args->rest_arg; if (rest_id == 1) { @@ -1087,8 +1088,9 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L1088 block_id = args->block_arg; if (args->first_post_arg) { - iseq->arg_post_start = get_dyna_var_idx_at_raw(iseq, args->first_post_arg); - iseq->arg_post_num = args->post_args_num; + iseq->param.post_start = get (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/