aboutsummaryrefslogtreecommitdiffstats
path: root/iseq.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-11-02 23:14:21 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-11-02 23:14:21 +0000
commit831e33c7809a92da6d14f0e518f960034c5dabd0 (patch)
treea0308f28d043d963e8e2b21d68f0633655105693 /iseq.c
parent5d1f152fa342f6bb5fa9b546e3971843ee81c6b1 (diff)
downloadruby-831e33c7809a92da6d14f0e518f960034c5dabd0.tar.gz
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48242 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c172
1 files changed, 79 insertions, 93 deletions
diff --git a/iseq.c b/iseq.c
index 4af1426a54..6f5ac8b6cd 100644
--- a/iseq.c
+++ b/iseq.c
@@ -23,7 +23,7 @@
#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)
}
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)
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,
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);
* 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);
* 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)
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)
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)
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)
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)
}
}
- /* 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)
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)
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
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, int is_proc)
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, int is_proc)
}
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(
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);