diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-12-03 22:16:58 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-12-03 22:16:58 +0000 |
commit | 9581954a964c6b20bafd133a19da3e27aa135dce (patch) | |
tree | 606bf98bc1047ff5df8773e65ef3e3ee7d599a80 /iseq.c | |
parent | 0c662b34313699223f08df54c5dcd8c481ff8a95 (diff) |
mostly fix rb_iseq_load
This allows reporters commenters of [Feature #8543] to load
instruction sequences directly. Some test cases are still failing
but documented in test/-ext-/iseq_load/test_iseq_load.rb.
* compile.c (rb_iseq_build_from_exception): entry->sp is unsigned
(iseq_build_callinfo_from_hash): account for kw_arg
(iseq_build_from_ary_body): update for r35459
(CHECK_STRING, CHECK_INTEGER): remove unused checks
(int_param): new function for checking new `params' hash
(iseq_build_kw): new function for loading rb_iseq_param_keyword
(rb_iseq_build_from_ary): account for `misc' entry and general
structure changes
[Feature #8543]
* iseq.c (CHECK_HASH): new macro (for `misc' and `param' entries)
(iseq_load): account for `misc' and `params' hashes
(iseq_data_to_ary): add final opt to arg_opt_labels,
fix kw support, account for unsigned entry->sp
* ext/-test-/iseq_load/iseq_load.c: new ext for test
* ext/-test-/iseq_load/extconf.rb: ditto
* test/-ext-/iseq_load/test_iseq_load.rb: new test
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48705 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'iseq.c')
-rw-r--r-- | iseq.c | 56 |
1 files changed, 38 insertions, 18 deletions
@@ -468,6 +468,7 @@ rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE path, VALUE absolute_path, V } #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary") +#define CHECK_HASH(v) rb_convert_type((v), T_HASH, "Hash", "to_hash") #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str") #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym") static inline VALUE CHECK_INTEGER(VALUE v) {(void)NUM2LONG(v); return v;} @@ -506,7 +507,7 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) VALUE magic, version1, version2, format_type, misc; VALUE name, path, absolute_path, first_lineno; - VALUE type, body, locals, args, exception; + VALUE type, body, locals, params, exception; st_data_t iseq_type; rb_iseq_t *iseq; @@ -524,8 +525,8 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) version1 = CHECK_INTEGER(rb_ary_entry(data, i++)); version2 = CHECK_INTEGER(rb_ary_entry(data, i++)); format_type = CHECK_INTEGER(rb_ary_entry(data, i++)); - misc = rb_ary_entry(data, i++); /* TODO */ - ((void)magic, (void)version1, (void)version2, (void)format_type, (void)misc); + misc = CHECK_HASH(rb_ary_entry(data, i++)); + ((void)magic, (void)version1, (void)version2, (void)format_type); name = CHECK_STRING(rb_ary_entry(data, i++)); path = CHECK_STRING(rb_ary_entry(data, i++)); @@ -535,12 +536,7 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) type = CHECK_SYMBOL(rb_ary_entry(data, i++)); locals = CHECK_ARRAY(rb_ary_entry(data, i++)); - - args = rb_ary_entry(data, i++); - if (FIXNUM_P(args) || (args = CHECK_ARRAY(args))) { - /* */ - } - + params = CHECK_HASH(rb_ary_entry(data, i++)); exception = CHECK_ARRAY(rb_ary_entry(data, i++)); body = CHECK_ARRAY(rb_ary_entry(data, i++)); @@ -558,10 +554,11 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) } make_compile_option(&option, opt); + prepare_iseq_build(iseq, name, path, absolute_path, first_lineno, parent, (enum iseq_type)iseq_type, 0, &option); - rb_iseq_build_from_ary(iseq, locals, args, exception, body); + rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body); cleanup_iseq_build(iseq); return iseqval; @@ -1733,16 +1730,21 @@ iseq_data_to_ary(rb_iseq_t *iseq) /* params */ { - VALUE arg_opt_labels = rb_ary_new(); int 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])); - } + if (iseq->param.flags.has_opt) { + int len = iseq->param.opt_num + 1; + VALUE arg_opt_labels = rb_ary_new2(len); + + for (j = 0; j < len; j++) { + VALUE l = register_label(labels_table, iseq->param.opt_table[j]); + rb_ary_push(arg_opt_labels, l); + } + rb_hash_aset(params, ID2SYM(rb_intern("opt")), arg_opt_labels); + } /* commit */ 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)); @@ -1760,6 +1762,9 @@ iseq_data_to_ary(rb_iseq_t *iseq) } rb_ary_push(keywords, key); } + + rb_hash_aset(params, ID2SYM(rb_intern("kwbits")), + INT2FIX(iseq->param.keyword->bits_start)); 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)); @@ -1818,10 +1823,25 @@ iseq_data_to_ary(rb_iseq_t *iseq) { rb_call_info_t *ci = (rb_call_info_t *)*seq; VALUE e = rb_hash_new(); + int orig_argc = ci->orig_argc; + rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil); - rb_hash_aset(e, ID2SYM(rb_intern("flag")), ULONG2NUM(ci->flag)); - rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")), INT2FIX(ci->orig_argc)); + rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag)); rb_hash_aset(e, ID2SYM(rb_intern("blockptr")), ci->blockiseq ? iseq_data_to_ary(ci->blockiseq) : Qnil); + + if (ci->kw_arg) { + int i; + VALUE kw = rb_ary_new2((long)ci->kw_arg->keyword_len); + + orig_argc -= ci->kw_arg->keyword_len; + for (i = 0; i < ci->kw_arg->keyword_len; i++) { + rb_ary_push(kw, ID2SYM(ci->kw_arg->keywords[i])); + } + rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw); + } + + rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")), + INT2FIX(orig_argc)); rb_ary_push(ary, e); } break; @@ -1871,7 +1891,7 @@ iseq_data_to_ary(rb_iseq_t *iseq) rb_ary_push(ary, register_label(labels_table, entry->start)); rb_ary_push(ary, register_label(labels_table, entry->end)); rb_ary_push(ary, register_label(labels_table, entry->cont)); - rb_ary_push(ary, INT2FIX(entry->sp)); + rb_ary_push(ary, UINT2NUM(entry->sp)); rb_ary_push(exception, ary); } |