aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-21 22:52:59 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-21 22:52:59 +0000
commit62fecbe8c54d8e59f45e06bb021ae3639efb0e5f (patch)
treee77fa8d9817f9ff7c53864e373784f902b4368c1
parent7960a911db40229ae51a49454d458f960ccfdcff (diff)
downloadruby-62fecbe8c54d8e59f45e06bb021ae3639efb0e5f.tar.gz
* make rb_iseq_t T_IMEMO object (type is imemo_iseq).
All contents of previous rb_iseq_t is in rb_iseq_t::body. Remove rb_iseq_t::self because rb_iseq_t is an object. RubyVM::InstructionSequence is wrapper object points T_IMEMO/iseq. So RubyVM::ISeq.of(something) method returns different wrapper objects but they point the same T_IMEMO/iseq object. This patch is big, but most of difference is replacement of iseq->xxx to iseq->body->xxx. (previous) rb_iseq_t::compile_data is also located to rb_iseq_t::compile_data. It was moved from rb_iseq_body::compile_data. Now rb_iseq_t has empty two pointers. I will split rb_iseq_body data into static data and dynamic data. * compile.c: rename some functions/macros. Now, we don't need to separate iseq and iseqval (only VALUE). * eval.c (ruby_exec_internal): `n' is rb_iseq_t (T_IMEMO/iseq). * ext/objspace/objspace.c (count_imemo_objects): count T_IMEMO/iseq. * gc.c: check T_IMEMO/iseq. * internal.h: add imemo_type::imemo_iseq. * iseq.c: define RubyVM::InstructionSequnce as T_OBJECT. Methods are implemented by functions named iseqw_.... * load.c (rb_load_internal0): rb_iseq_new_top() returns rb_iseq_t (T_IMEMO/iesq). * method.h (rb_add_method_iseq): accept rb_iseq_t (T_IMEMO/iseq). * vm_core.h (GetISeqPtr): removed because it is not T_DATA now. * vm_core.h (struct rb_iseq_body): remove padding for [Bug #10037][ruby-core:63721]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51327 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog45
-rw-r--r--class.c2
-rw-r--r--compile.c742
-rw-r--r--eval.c6
-rw-r--r--ext/objspace/objspace.c3
-rw-r--r--gc.c60
-rw-r--r--insns.def6
-rw-r--r--internal.h9
-rw-r--r--iseq.c828
-rw-r--r--iseq.h29
-rw-r--r--load.c4
-rw-r--r--method.h4
-rw-r--r--proc.c30
-rw-r--r--ruby.c6
-rw-r--r--struct.c12
-rw-r--r--thread.c2
-rw-r--r--vm.c153
-rw-r--r--vm_args.c68
-rw-r--r--vm_backtrace.c87
-rw-r--r--vm_core.h51
-rw-r--r--vm_dump.c22
-rw-r--r--vm_eval.c20
-rw-r--r--vm_insnhelper.c85
-rw-r--r--vm_method.c17
-rw-r--r--vm_trace.c2
25 files changed, 1155 insertions, 1138 deletions
diff --git a/ChangeLog b/ChangeLog
index a7064590a9..4ae130706d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+Wed Jul 22 07:24:18 2015 Koichi Sasada <ko1@atdot.net>
+
+ * make rb_iseq_t T_IMEMO object (type is imemo_iseq).
+
+ All contents of previous rb_iseq_t is in rb_iseq_t::body.
+ Remove rb_iseq_t::self because rb_iseq_t is an object.
+
+ RubyVM::InstructionSequence is wrapper object points T_IMEMO/iseq.
+ So RubyVM::ISeq.of(something) method returns different wrapper
+ objects but they point the same T_IMEMO/iseq object.
+
+ This patch is big, but most of difference is replacement of
+ iseq->xxx to iseq->body->xxx.
+
+ (previous) rb_iseq_t::compile_data is also located to
+ rb_iseq_t::compile_data.
+ It was moved from rb_iseq_body::compile_data.
+
+ Now rb_iseq_t has empty two pointers.
+ I will split rb_iseq_body data into static data and dynamic data.
+
+ * compile.c: rename some functions/macros.
+ Now, we don't need to separate iseq and iseqval (only VALUE).
+
+ * eval.c (ruby_exec_internal): `n' is rb_iseq_t (T_IMEMO/iseq).
+
+ * ext/objspace/objspace.c (count_imemo_objects): count T_IMEMO/iseq.
+
+ * gc.c: check T_IMEMO/iseq.
+
+ * internal.h: add imemo_type::imemo_iseq.
+
+ * iseq.c: define RubyVM::InstructionSequnce as T_OBJECT.
+ Methods are implemented by functions named iseqw_....
+
+ * load.c (rb_load_internal0): rb_iseq_new_top() returns
+ rb_iseq_t (T_IMEMO/iesq).
+
+ * method.h (rb_add_method_iseq): accept rb_iseq_t (T_IMEMO/iseq).
+
+ * vm_core.h (GetISeqPtr): removed because it is not T_DATA now.
+
+ * vm_core.h (struct rb_iseq_body): remove padding for
+ [Bug #10037][ruby-core:63721].
+
Wed Jul 22 07:15:33 2015 Koichi Sasada <ko1@atdot.net>
* ext/objspace/objspace.c (total_i): no need to skip singleton classes.
diff --git a/class.c b/class.c
index 46a0d617ad..15f5592204 100644
--- a/class.c
+++ b/class.c
@@ -246,7 +246,7 @@ clone_method(VALUE old_klass, VALUE new_klass, ID mid, const rb_method_entry_t *
if (me->def->type == VM_METHOD_TYPE_ISEQ) {
rb_cref_t *new_cref;
rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass, &new_cref);
- rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr->self, new_cref, METHOD_ENTRY_VISI(me));
+ rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
}
else {
rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me));
diff --git a/compile.c b/compile.c
index e6b00e55bb..1011e54486 100644
--- a/compile.c
+++ b/compile.c
@@ -168,17 +168,14 @@ r_value(VALUE value)
/* create new label */
#define NEW_LABEL(l) new_label_body(iseq, (l))
-#define iseq_path(iseq) \
- (((rb_iseq_t*)DATA_PTR(iseq))->location.path)
+#define iseq_path(iseq) ((iseq)->body->location.path)
+#define iseq_absolute_path(iseq) ((iseq)->body->location.absolute_path)
-#define iseq_absolute_path(iseq) \
- (((rb_iseq_t*)DATA_PTR(iseq))->location.absolute_path)
-
-#define NEW_ISEQVAL(node, name, type, line_no) \
+#define NEW_ISEQ(node, name, type, line_no) \
new_child_iseq(iseq, (node), rb_fstring(name), 0, (type), (line_no))
-#define NEW_CHILD_ISEQVAL(node, name, type, line_no) \
- new_child_iseq(iseq, (node), rb_fstring(name), iseq->self, (type), (line_no))
+#define NEW_CHILD_ISEQ(node, name, type, line_no) \
+ new_child_iseq(iseq, (node), rb_fstring(name), iseq, (type), (line_no))
/* add instructions */
#define ADD_SEQ(seq1, seq2) \
@@ -206,31 +203,31 @@ r_value(VALUE value)
/* Specific Insn factory */
#define ADD_SEND(seq, line, id, argc) \
- ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)INT2FIX(0), NULL)
+ ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(0), NULL)
#define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag) \
- ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)(flag), NULL)
+ ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)(flag), NULL)
#define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block) \
- ADD_SEND_R((seq), (line), (id), (argc), (VALUE)(block), (VALUE)INT2FIX(0), NULL)
+ ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(0), NULL)
#define ADD_CALL_RECEIVER(seq, line) \
ADD_INSN((seq), (line), putself)
#define ADD_CALL(seq, line, id, argc) \
- ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
+ ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
#define ADD_SEND_R(seq, line, id, argc, block, flag, keywords) \
- ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line), (id), (VALUE)(argc), (VALUE)(block), (VALUE)(flag), (keywords)))
+ ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords)))
#define ADD_TRACE(seq, line, event) \
do { \
- if ((event) == RUBY_EVENT_LINE && iseq->coverage && \
+ if ((event) == RUBY_EVENT_LINE && iseq->body->coverage && \
(line) != iseq->compile_data->last_coverable_line) { \
- RARRAY_ASET(iseq->coverage, (line) - 1, INT2FIX(0)); \
+ RARRAY_ASET(iseq->body->coverage, (line) - 1, INT2FIX(0)); \
iseq->compile_data->last_coverable_line = (line); \
ADD_INSN1((seq), (line), trace, INT2FIX(RUBY_EVENT_COVERAGE)); \
} \
@@ -252,11 +249,12 @@ r_value(VALUE value)
#define ADD_ADJUST_RESTORE(seq, label) \
ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1))
-#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
- (rb_ary_push(iseq->compile_data->catch_table_ary, \
- rb_ary_new3(5, (type), \
- (VALUE)(ls) | 1, (VALUE)(le) | 1, \
- (VALUE)(iseqv), (VALUE)(lc) | 1)))
+#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) do { \
+ VALUE _e = rb_ary_new3(5, (type), \
+ (VALUE)(ls) | 1, (VALUE)(le) | 1, \
+ (VALUE)(iseqv), (VALUE)(lc) | 1); \
+ rb_ary_push(iseq->compile_data->catch_table_ary, freeze_hide_obj(_e)); \
+} while (0)
/* compile node */
#define COMPILE(anchor, desc, node) \
@@ -292,7 +290,7 @@ r_value(VALUE value)
if (compile_debug) rb_compile_bug strs; \
th->errinfo = iseq->compile_data->err_info; \
rb_compile_error strs; \
- RB_OBJ_WRITE(iseq->self, &iseq->compile_data->err_info, th->errinfo); \
+ RB_OBJ_WRITE(iseq, &iseq->compile_data->err_info, th->errinfo); \
th->errinfo = tmp; \
ret = 0; \
break; \
@@ -312,7 +310,13 @@ r_value(VALUE value)
#define INIT_ANCHOR(name) \
(name##_body__.last = &name##_body__.anchor, name = &name##_body__)
-#define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC_CLEAR_CLASS(obj);} while (0)
+static inline VALUE
+freeze_hide_obj(VALUE obj)
+{
+ OBJ_FREEZE(obj);
+ RBASIC_CLEAR_CLASS(obj);
+ return obj;
+}
#include "optinsn.inc"
#if OPT_INSTRUCTIONS_UNIFICATION
@@ -430,7 +434,7 @@ iseq_add_mark_object(const rb_iseq_t *iseq, VALUE v)
return COMPILE_OK;
}
-#define ruby_sourcefile RSTRING_PTR(iseq->location.path)
+#define ruby_sourcefile RSTRING_PTR(iseq->body->location.path)
static int
iseq_add_mark_object_compile_time(const rb_iseq_t *iseq, VALUE v)
@@ -468,12 +472,10 @@ validate_labels(rb_iseq_t *iseq, st_table *labels_table)
}
VALUE
-rb_iseq_compile_node(VALUE self, NODE *node)
+rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
{
DECL_ANCHOR(ret);
- rb_iseq_t *iseq;
INIT_ANCHOR(ret);
- GetISeqPtr(self, iseq);
if (node == 0) {
COMPILE(ret, "nil", node);
@@ -484,13 +486,13 @@ rb_iseq_compile_node(VALUE self, NODE *node)
iseq_set_local_table(iseq, node->nd_tbl);
iseq_set_arguments(iseq, ret, node->nd_args);
- switch (iseq->type) {
+ switch (iseq->body->type) {
case ISEQ_TYPE_BLOCK:
{
LABEL *start = iseq->compile_data->start_label = NEW_LABEL(0);
LABEL *end = iseq->compile_data->end_label = NEW_LABEL(0);
- ADD_TRACE(ret, FIX2INT(iseq->location.first_lineno), RUBY_EVENT_B_CALL);
+ ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_B_CALL);
ADD_LABEL(ret, start);
COMPILE(ret, "block body", node->nd_body);
ADD_LABEL(ret, end);
@@ -503,14 +505,14 @@ rb_iseq_compile_node(VALUE self, NODE *node)
}
case ISEQ_TYPE_CLASS:
{
- ADD_TRACE(ret, FIX2INT(iseq->location.first_lineno), RUBY_EVENT_CLASS);
+ ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CLASS);
COMPILE(ret, "scoped node", node->nd_body);
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END);
break;
}
case ISEQ_TYPE_METHOD:
{
- ADD_TRACE(ret, FIX2INT(iseq->location.first_lineno), RUBY_EVENT_CALL);
+ ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CALL);
COMPILE(ret, "scoped node", node->nd_body);
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
break;
@@ -527,7 +529,7 @@ rb_iseq_compile_node(VALUE self, NODE *node)
(*ifunc->func)(iseq, ret, ifunc->data);
}
else {
- switch (iseq->type) {
+ switch (iseq->body->type) {
case ISEQ_TYPE_METHOD:
case ISEQ_TYPE_CLASS:
case ISEQ_TYPE_BLOCK:
@@ -554,7 +556,7 @@ rb_iseq_compile_node(VALUE self, NODE *node)
}
}
- if (iseq->type == ISEQ_TYPE_RESCUE || iseq->type == ISEQ_TYPE_ENSURE) {
+ if (iseq->body->type == ISEQ_TYPE_RESCUE || iseq->body->type == ISEQ_TYPE_ENSURE) {
ADD_INSN2(ret, 0, getlocal, INT2FIX(2), INT2FIX(0));
ADD_INSN1(ret, 0, throw, INT2FIX(0) /* continue throw */ );
}
@@ -577,10 +579,10 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
const void * const *table = rb_vm_get_insns_address_table();
unsigned int i;
- for (i = 0; i < iseq->iseq_size; /* */ ) {
- int insn = (int)iseq->iseq_encoded[i];
+ for (i = 0; i < iseq->body->iseq_size; /* */ ) {
+ int insn = (int)iseq->body->iseq_encoded[i];
int len = insn_len(insn);
- iseq->iseq_encoded[i] = (VALUE)table[insn];
+ iseq->body->iseq_encoded[i] = (VALUE)table[insn];
i += len;
}
#endif
@@ -604,28 +606,28 @@ rb_vm_insn_addr2insn(const void *addr) /* cold path */
#endif
VALUE *
-rb_iseq_original_iseq(rb_iseq_t *iseq) /* cold path */
+rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
{
- if (iseq->iseq) return iseq->iseq;
+ if (iseq->body->iseq) return iseq->body->iseq;
- iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);
+ iseq->body->iseq = ALLOC_N(VALUE, iseq->body->iseq_size);
- MEMCPY(iseq->iseq, iseq->iseq_encoded, VALUE, iseq->iseq_size);
+ MEMCPY(iseq->body->iseq, iseq->body->iseq_encoded, VALUE, iseq->body->iseq_size);
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
{
unsigned int i;
- for (i = 0; i < iseq->iseq_size; /* */ ) {
- const void *addr = (const void *)iseq->iseq[i];
+ for (i = 0; i < iseq->body->iseq_size; /* */ ) {
+ const void *addr = (const void *)iseq->body->iseq[i];
const int insn = rb_vm_insn_addr2insn(addr);
- iseq->iseq[i] = insn;
+ iseq->body->iseq[i] = insn;
i += insn_len(insn);
}
}
#endif
- return iseq->iseq;
+ return iseq->body->iseq;
}
/*********************************************/
@@ -942,7 +944,7 @@ new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int a
}
static rb_call_info_t *
-new_callinfo(rb_iseq_t *iseq, ID mid, int argc, VALUE block, unsigned int flag, rb_call_info_kw_arg_t *kw_arg)
+new_callinfo(rb_iseq_t *iseq, ID mid, int argc, const rb_iseq_t *blockiseq, unsigned int flag, rb_call_info_kw_arg_t *kw_arg)
{
rb_call_info_t *ci = (rb_call_info_t *)compile_data_alloc(iseq, sizeof(rb_call_info_t));
@@ -957,12 +959,7 @@ new_callinfo(rb_iseq_t *iseq, ID mid, int argc, VALUE block, unsigned int flag,
ci->orig_argc += kw_arg->keyword_len;
}
- if (block) {
- GetISeqPtr(block, ci->blockiseq);
- }
- else {
- ci->blockiseq = 0;
- }
+ ci->blockiseq = blockiseq;
if (!(ci->flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG)) &&
ci->blockiseq == NULL && ci->kw_arg == NULL) {
@@ -975,32 +972,32 @@ new_callinfo(rb_iseq_t *iseq, ID mid, int argc, VALUE block, unsigned int flag,
ci->recv = Qundef;
ci->call = 0; /* TODO: should set default function? */
- ci->aux.index = iseq->callinfo_size++;
+ ci->aux.index = iseq->body->callinfo_size++;
return ci;
}
static INSN *
-new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, VALUE block, VALUE flag, rb_call_info_kw_arg_t *keywords)
+new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *block, VALUE flag, rb_call_info_kw_arg_t *keywords)
{
VALUE *operands = (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 1);
operands[0] = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), block, FIX2INT(flag), keywords);
return new_insn_core(iseq, line_no, BIN(send), 1, operands);
}
-static VALUE
+static rb_iseq_t *
new_child_iseq(rb_iseq_t *iseq, NODE *node,
- VALUE name, VALUE parent, enum iseq_type type, int line_no)
+ VALUE name, const rb_iseq_t *parent, enum iseq_type type, int line_no)
{
- VALUE ret;
+ rb_iseq_t *ret_iseq;
debugs("[new_child_iseq]> ---------------------------------------\n");
- ret = rb_iseq_new_with_opt(node, name,
- iseq_path(iseq->self), iseq_absolute_path(iseq->self),
- INT2FIX(line_no), parent, type, iseq->compile_data->option);
+ ret_iseq = rb_iseq_new_with_opt(node, name,
+ iseq_path(iseq), iseq_absolute_path(iseq),
+ INT2FIX(line_no), parent, type, iseq->compile_data->option);
debugs("[new_child_iseq]< ---------------------------------------\n");
- iseq_add_mark_object(iseq, ret);
- return ret;
+ iseq_add_mark_object(iseq, (VALUE)ret_iseq);
+ return ret_iseq;
}
static int
@@ -1046,7 +1043,7 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
rb_iseq_translate_threaded_code(iseq);
if (compile_debug > 1) {
- VALUE str = rb_iseq_disasm(iseq->self);
+ VALUE str = rb_iseq_disasm(iseq);
printf("%s\n", StringValueCStr(str));
}
debugs("[compile step: finish]\n");
@@ -1060,10 +1057,10 @@ iseq_set_exception_local_table(rb_iseq_t *iseq)
ID id_dollar_bang;
CONST_ID(id_dollar_bang, "#$!");
- iseq->local_table = (ID *)ALLOC_N(ID, 1);
- iseq->local_table_size = 1;
- iseq->local_size = iseq->local_table_size + 1;
- iseq->local_table[0] = id_dollar_bang;
+ iseq->body->local_table = (ID *)ALLOC_N(ID, 1);
+ iseq->body->local_table_size = 1;
+ iseq->body->local_size = iseq->body->local_table_size + 1;
+ iseq->body->local_table[0] = id_dollar_bang;
return COMPILE_OK;
}
@@ -1071,9 +1068,9 @@ static int
get_lvar_level(const rb_iseq_t *iseq)
{
int lev = 0;
- while (iseq != iseq->local_iseq) {
+ while (iseq != iseq->body->local_iseq) {
lev++;
- iseq = iseq->parent_iseq;
+ iseq = iseq->body->parent_iseq;
}
return lev;
}
@@ -1083,8 +1080,8 @@ get_dyna_var_idx_at_raw(const rb_iseq_t *iseq, ID id)
{
int i;
- for (i = 0; i < iseq->local_table_size; i++) {
- if (iseq->local_table[i] == id) {
+ for (i = 0; i < iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == id) {
return i;
}
}
@@ -1094,7 +1091,7 @@ get_dyna_var_idx_at_raw(const rb_iseq_t *iseq, ID id)
static int
get_local_var_idx(const rb_iseq_t *iseq, ID id)
{
- int idx = get_dyna_var_idx_at_raw(iseq->local_iseq, id);
+ int idx = get_dyna_var_idx_at_raw(iseq->body->local_iseq, id);
if (idx < 0) {
rb_bug("get_local_var_idx: %d", idx);
@@ -1113,7 +1110,7 @@ get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
if (idx >= 0) {
break;
}
- iseq = iseq->parent_iseq;
+ iseq = iseq->body->parent_iseq;
lv++;
}
@@ -1122,44 +1119,44 @@ get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
}
*level = lv;
- *ls = iseq->local_size;
+ *ls = iseq->body->local_size;
return idx;
}
static void
iseq_calc_param_size(rb_iseq_t *iseq)
{
- if (iseq->param.flags.has_opt ||
- iseq->param.flags.has_post ||
- iseq->param.flags.has_rest ||
- iseq->param.flags.has_block ||
- iseq->param.flags.has_kw ||
- iseq->param.flags.has_kwrest) {
+ if (iseq->body->param.flags.has_opt ||
+ iseq->body->param.flags.has_post ||
+ iseq->body->param.flags.has_rest ||
+ iseq->body->param.flags.has_block ||
+ iseq->body->param.flags.has_kw ||
+ iseq->body->param.flags.has_kwrest) {
- if (iseq->param.flags.has_block) {
- iseq->param.size = iseq->param.block_start + 1;
+ if (iseq->body->param.flags.has_block) {
+ iseq->body->param.size = iseq->body->param.block_start + 1;
}
- else if (iseq->param.flags.has_kwrest) {
- iseq->param.size = iseq->param.keyword->rest_start + 1;
+ else if (iseq->body->param.flags.has_kwrest) {
+ iseq->body->param.size = iseq->body->param.keyword->rest_start + 1;
}
- else if (iseq->param.flags.has_kw) {
- iseq->param.size = iseq->param.keyword->bits_start + 1;
+ else if (iseq->body->param.flags.has_kw) {
+ iseq->body->param.size = iseq->body->param.keyword->bits_start + 1;
}
- else if (iseq->param.flags.has_post) {
- iseq->param.size = iseq->param.post_start + iseq->param.post_num;
+ else if (iseq->body->param.flags.has_post) {
+ iseq->body->param.size = iseq->body->param.post_start + iseq->body->param.post_num;
}
- else if (iseq->param.flags.has_rest) {
- iseq->param.size = iseq->param.rest_start + 1;
+ else if (iseq->body->param.flags.has_rest) {
+ iseq->body->param.size = iseq->body->param.rest_start + 1;
}
- else if (iseq->param.flags.has_opt) {
- iseq->param.size = iseq->param.lead_num + iseq->param.opt_num;
+ else if (iseq->body->param.flags.has_opt) {
+ iseq->body->param.size = iseq->body->param.lead_num + iseq->body->param.opt_num;
}
else {
rb_bug("unreachable");
}
}
else {
- iseq->param.size = iseq->param.lead_num;
+ iseq->body->param.size = iseq->body->param.lead_num;
}
}
@@ -1180,9 +1177,9 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
}
- 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);
+ iseq->body->param.lead_num = (int)args->pre_args_num;
+ if (iseq->body->param.lead_num > 0) iseq->body->param.flags.has_lead = TRUE;
+ debugs(" - argc: %d\n", iseq->body->param.lead_num);
rest_id = args->rest_arg;
if (rest_id == 1) {
@@ -1192,9 +1189,9 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
block_id = args->block_arg;
if (args->first_post_arg) {
- iseq->param.post_start = get_dyna_var_idx_at_raw(iseq, args->first_post_arg);
- iseq->param.post_num = args->post_args_num;
- iseq->param.flags.has_post = TRUE;
+ iseq->body->param.post_start = get_dyna_var_idx_at_raw(iseq, args->first_post_arg);
+ iseq->body->param.post_num = args->post_args_num;
+ iseq->body->param.flags.has_post = TRUE;
}
if (args->opt_args) {
@@ -1217,15 +1214,15 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
rb_ary_push(labels, (VALUE)label | 1);
ADD_LABEL(optargs, label);
- iseq->param.opt_num = i;
- iseq->param.opt_table = ALLOC_N(VALUE, i+1);
- MEMCPY(iseq->param.opt_table, RARRAY_CONST_PTR(labels), VALUE, i+1);
+ iseq->body->param.opt_num = i;
+ iseq->body->param.opt_table = ALLOC_N(VALUE, i+1);
+ MEMCPY(iseq->body->param.opt_table, RARRAY_CONST_PTR(labels), VALUE, i+1);
for (j = 0; j < i+1; j++) {
- iseq->param.opt_table[j] &= ~1;
+ iseq->body->param.opt_table[j] &= ~1;
}
rb_ary_clear(labels);
- iseq->param.flags.has_opt = TRUE;
+ iseq->body->param.flags.has_opt = TRUE;
}
if (args->kw_args) {
@@ -1234,9 +1231,9 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
const VALUE complex_mark = rb_str_tmp_new(0);
int kw = 0, rkw = 0, di = 0, i;
- iseq->param.flags.has_kw = TRUE;
- iseq->param.keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
- iseq->param.keyword->bits_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
+ iseq->body->param.flags.has_kw = TRUE;
+ iseq->body->param.keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
+ iseq->body->param.keyword->bits_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
while (node) {
NODE *val_node = node->nd_body->nd_value;
@@ -1265,7 +1262,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
dv = complex_mark;
}
- iseq->param.keyword->num = ++di;
+ iseq->body->param.keyword->num = ++di;
rb_ary_push(default_values, dv);
}
@@ -1273,26 +1270,26 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
node = node->nd_next;
}
- iseq->param.keyword->num = kw;
+ iseq->body->param.keyword->num = kw;
if (args->kw_rest_arg->nd_cflag != 0) {
- iseq->param.keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_cflag);
- iseq->param.flags.has_kwrest = TRUE;
+ iseq->body->param.keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_cflag);
+ iseq->body->param.flags.has_kwrest = TRUE;
}
- iseq->param.keyword->required_num = rkw;
- iseq->param.keyword->table = &iseq->local_table[iseq->param.keyword->bits_start - iseq->param.keyword->num];
- iseq->param.keyword->default_values = ALLOC_N(VALUE, RARRAY_LEN(default_values));
+ iseq->body->param.keyword->required_num = rkw;
+ iseq->body->param.keyword->table = &iseq->body->local_table[iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num];
+ iseq->body->param.keyword->default_values = ALLOC_N(VALUE, RARRAY_LEN(default_values));
for (i = 0; i < RARRAY_LEN(default_values); i++) {
VALUE dv = RARRAY_AREF(default_values, i);
if (dv == complex_mark) dv = Qundef;
- iseq->param.keyword->default_values[i] = dv;
+ iseq->body->param.keyword->default_values[i] = dv;
}
}
else if (args->kw_rest_arg) {
- iseq->param.flags.has_kwrest = TRUE;
- iseq->param.keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
- iseq->param.keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
+ iseq->body->param.flags.has_kwrest = TRUE;
+ iseq->body->param.keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
+ iseq->body->param.keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
}
if (args->pre_init) { /* m_init */
@@ -1303,32 +1300,32 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
}
if (rest_id) {
- iseq->param.rest_start = get_dyna_var_idx_at_raw(iseq, rest_id);
- iseq->param.flags.has_rest = TRUE;
- assert(iseq->param.rest_start != -1);
+ iseq->body->param.rest_start = get_dyna_var_idx_at_raw(iseq, rest_id);
+ iseq->body->param.flags.has_rest = TRUE;
+ assert(iseq->body->param.rest_start != -1);
- if (iseq->param.post_start == 0) { /* TODO: why that? */
- iseq->param.post_start = iseq->param.rest_start + 1;
+ if (iseq->body->param.post_start == 0) { /* TODO: why that? */
+ iseq->body->param.post_start = iseq->body->param.rest_start + 1;
}
}
if (block_id) {
- iseq->param.block_start = get_dyna_var_idx_at_raw(iseq, block_id);
- iseq->param.flags.has_block = TRUE;
+ iseq->body->param.block_start = get_dyna_var_idx_at_raw(iseq, block_id);
+ iseq->body->param.flags.has_block = TRUE;
}
iseq_calc_param_size(iseq);
- if (iseq->type == ISEQ_TYPE_BLOCK) {
- if (iseq->param.flags.has_opt == FALSE &&
- iseq->param.flags.has_post == FALSE &&
- iseq->param.flags.has_rest == FALSE &&
- iseq->param.flags.has_kw == FALSE &&
- iseq->param.flags.has_kwrest == FALSE) {
+ if (iseq->body->type == ISEQ_TYPE_BLOCK) {
+ if (iseq->body->param.flags.has_opt == FALSE &&
+ iseq->body->param.flags.has_post == FALSE &&
+ iseq->body->param.flags.has_rest == FALSE &&
+ iseq->body->param.flags.has_kw == FALSE &&
+ iseq->body->param.flags.has_kwrest == FALSE) {
- if (iseq->param.lead_num == 1 && last_comma == 0) {
+ if (iseq->body->param.lead_num == 1 && last_comma == 0) {
/* {|a|} */
- iseq->param.flags.ambiguous_param0 = TRUE;
+ iseq->body->param.flags.ambiguous_param0 = TRUE;
}
}
}
@@ -1351,12 +1348,12 @@ iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl)
}
if (size > 0) {
- iseq->local_table = (ID *)ALLOC_N(ID, size);
- MEMCPY(iseq->local_table, tbl, ID, size);
+ iseq->body->local_table = (ID *)ALLOC_N(ID, size);
+ MEMCPY(iseq->body->local_table, tbl, ID, size);
}
- iseq->local_size = iseq->local_table_size = size;
- iseq->local_size += 1;
+ iseq->body->local_size = iseq->body->local_table_size = size;
+ iseq->body->local_size += 1;
/*
if (lfp == dfp ) { // top, class, method
dfp[-1]: svar
@@ -1365,7 +1362,7 @@ iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl)
}
*/
- debugs("iseq_set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size);
+ debugs("iseq_set_local_table: %d, %d\n", iseq->body->local_size, iseq->body->local_table_size);
return COMPILE_OK;
}
@@ -1468,7 +1465,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
default:
dump_disasm_list(FIRST_ELEMENT(anchor));
dump_disasm_list(list);
- rb_compile_error(RSTRING_PTR(iseq->location.path), line,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), line,
"error: set_sequence");
break;
}
@@ -1478,9 +1475,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* make instruction sequence */
generated_iseq = ALLOC_N(VALUE, pos);
line_info_table = ALLOC_N(struct iseq_line_info_entry, k);
- iseq->is_entries = ZALLOC_N(union iseq_inline_storage_entry, iseq->is_size);
- iseq->callinfo_entries = ALLOC_N(rb_call_info_t, iseq->callinfo_size);
- /* MEMZERO(iseq->callinfo_entries, rb_call_info_t, iseq->callinfo_size); */
+ iseq->body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, iseq->body->is_size);
+ iseq->body->callinfo_entries = ALLOC_N(rb_call_info_t, iseq->body->callinfo_size);
+ /* MEMZERO(iseq->body->callinfo_entries, rb_call_info_t, iseq->body->callinfo_size); */
list = FIRST_ELEMENT(anchor);
k = pos = sp = 0;
@@ -1512,7 +1509,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
if (iobj->operand_size != len - 1) {
/* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */
dump_disasm_list(list);
- rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), iobj->line_no,
"operand size miss! (%d for %d)",
iobj->operand_size, len - 1);
xfree(generated_iseq);
@@ -1529,7 +1526,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* label(destination position) */
lobj = (LABEL *)operands[j];
if (!lobj->set) {
- rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), iobj->line_no,
"unknown label");
}
if (lobj->sp == -1) {
@@ -1547,7 +1544,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
data.len = len;
rb_hash_foreach(map, cdhash_set_label_i, (VALUE)&data);
- hide_obj(map);
+ freeze_hide_obj(map);
generated_iseq[pos + 1 + j] = map;
break;
}
@@ -1558,11 +1555,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
case TS_ISEQ: /* iseq */
{
VALUE v = operands[j];
- rb_iseq_t *block = 0;
- if (v) {
- GetISeqPtr(v, block);
- }
- generated_iseq[pos + 1 + j] = (VALUE)block;
+ generated_iseq[pos + 1 + j] = v;
break;
}
case TS_VALUE: /* VALUE */
@@ -1576,9 +1569,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
case TS_IC: /* inline cache */
{
int ic_index = FIX2INT(operands[j]);
- IC ic = (IC)&iseq->is_entries[ic_index];
- if (UNLIKELY(ic_index >= iseq->is_size)) {
- rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->is_size);
+ IC ic = (IC)&iseq->body->is_entries[ic_index];
+ if (UNLIKELY(ic_index >= iseq->body->is_size)) {
+ rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->body->is_size);
}
generated_iseq[pos + 1 + j] = (VALUE)ic;
break;
@@ -1586,11 +1579,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
case TS_CALLINFO: /* call info */
{
rb_call_info_t *base_ci = (rb_call_info_t *)operands[j];
- rb_call_info_t *ci = &iseq->callinfo_entries[base_ci->aux.index];
+ rb_call_info_t *ci = &iseq->body->callinfo_entries[base_ci->aux.index];
*ci = *base_ci;
- if (UNLIKELY(base_ci->aux.index >= iseq->callinfo_size)) {
- rb_bug("iseq_set_sequence: ci_index overflow: index: %d, size: %d", base_ci->argc, iseq->callinfo_size);
+ if (UNLIKELY(base_ci->aux.index >= iseq->body->callinfo_size)) {
+ rb_bug("iseq_set_sequence: ci_index overflow: index: %d, size: %d", base_ci->argc, iseq->body->callinfo_size);
}
generated_iseq[pos + 1 + j] = (VALUE)ci;
break;
@@ -1609,7 +1602,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
generated_iseq[pos + 1 + j] = operands[j];
break;
default:
- rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), iobj->line_no,
"unknown operand type: %c", type);
xfree(generated_iseq);
xfree(line_info_table);
@@ -1680,13 +1673,13 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
list = list->next;
}
- iseq->iseq_encoded = (void *)generated_iseq;
- iseq->iseq_size = pos;
- iseq->stack_max = stack_max;
+ iseq->body->iseq_encoded = (void *)generated_iseq;
+ iseq->body->iseq_size = pos;
+ iseq->body->stack_max = stack_max;
REALLOC_N(line_info_table, struct iseq_line_info_entry, k);
- iseq->line_info_table = line_info_table;
- iseq->line_info_size = k;
+ iseq->body->line_info_table = line_info_table;
+ iseq->body->line_info_size = k;
return COMPILE_OK;
}
@@ -1713,23 +1706,23 @@ iseq_set_exception_table(rb_iseq_t *iseq)
tlen = (int)RARRAY_LEN(iseq->compile_data->catch_table_ary);
tptr = RARRAY_CONST_PTR(iseq->compile_data->catch_table_ary);
- iseq->catch_table = 0;
+ iseq->body->catch_table = 0;
if (tlen > 0) {
- iseq->catch_table = xmalloc(iseq_catch_table_bytes(tlen));
- iseq->catch_table->size = tlen;
+ iseq->body->catch_table = xmalloc(iseq_catch_table_bytes(tlen));
+ iseq->body->catch_table->size = tlen;
}
- if (iseq->catch_table) for (i = 0; i < iseq->catch_table->size; i++) {
+ if (iseq->body->catch_table) for (i = 0; i < iseq->body->catch_table->size; i++) {
ptr = RARRAY_CONST_PTR(tptr[i]);
- entry = &iseq->catch_table->entries[i];
+ entry = &iseq->body->catch_table->entries[i];
entry->type = (enum catch_type)(ptr[0] & 0xffff);
entry->start = label_get_position((LABEL *)(ptr[1] & ~1));
entry->end = label_get_position((LABEL *)(ptr[2] & ~1));
- entry->iseq = ptr[3];
+ entry->iseq = (rb_iseq_t *)ptr[3];
/* register iseq as mark object */
if (entry->iseq != 0) {
- iseq_add_mark_object(iseq, entry->iseq);
+ iseq_add_mark_object(iseq, (VALUE)entry->iseq);
}
/* stack depth */
@@ -1750,7 +1743,7 @@ iseq_set_exception_table(rb_iseq_t *iseq)
}
}
- RB_OBJ_WRITE(iseq->self, &iseq->compile_data->catch_table_ary, 0); /* free */
+ RB_OBJ_WRITE(iseq, &iseq->compile_data->catch_table_ary, 0); /* free */
return COMPILE_OK;
}
@@ -1768,9 +1761,9 @@ iseq_set_optargs_table(rb_iseq_t *iseq)
{
int i;
- if (iseq->param.flags.has_opt) {
- for (i = 0; i < iseq->param.opt_num + 1; i++) {
- iseq->param.opt_table[i] = label_get_position((LABEL *)iseq->param.opt_table[i]);
+ if (iseq->body->param.flags.has_opt) {
+ for (i = 0; i < iseq->body->param.opt_num + 1; i++) {
+ iseq->body->param.opt_table[i] = label_get_position((LABEL *)iseq->body->param.opt_table[i]);
}
}
return COMPILE_OK;
@@ -2156,7 +2149,7 @@ insn_set_sc_state(rb_iseq_t *iseq, INSN *iobj, int state)
dump_disasm_list((LINK_ELEMENT *)iobj);
dump_disasm_list((LINK_ELEMENT *)lobj);
printf("\n-- %d, %d\n", lobj->sc_state, nstate);
- rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), iobj->line_no,
"insn_set_sc_state error\n");
return 0;
}
@@ -2258,7 +2251,7 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
case SCS_XX:
goto normal_insn;
default:
- rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), iobj->line_no,
"unreachable");
}
/* remove useless pop */
@@ -2632,7 +2625,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, int onl
}
else {
if (rb_hash_lookup(literals, lit) != Qnil) {
- rb_compile_warning(RSTRING_PTR(iseq->location.path), nd_line(val), "duplicated when clause is ignored");
+ rb_compile_warning(RSTRING_PTR(iseq->body->location.path), nd_line(val), "duplicated when clause is ignored");
}
else {
rb_hash_aset(literals, lit, (VALUE)(l1) | 1);
@@ -3111,11 +3104,11 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
int line = nd_line(node);
LABEL *lstart = NEW_LABEL(line);
LABEL *lend = NEW_LABEL(line);
- VALUE rescue = NEW_CHILD_ISEQVAL(NEW_NIL(),
- rb_str_concat(rb_str_new2
- ("defined guard in "),
- iseq->location.label),
- ISEQ_TYPE_DEFINED_GUARD, 0);
+ const rb_iseq_t *rescue = NEW_CHILD_ISEQ(NEW_NIL(),
+ rb_str_concat(rb_str_new2
+ ("defined guard in "),
+ iseq->body->location.label),
+ ISEQ_TYPE_DEFINED_GUARD, 0);
APPEND_LABEL(ret, lcur, lstart);
ADD_LABEL(ret, lend);
ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]);
@@ -3124,25 +3117,25 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
}
static VALUE
-make_name_for_block(const rb_iseq_t *iseq)
+make_name_for_block(const rb_iseq_t *orig_iseq)
{
int level = 1;
- const rb_iseq_t *ip = iseq;
+ const rb_iseq_t *iseq = orig_iseq;
- if (iseq->parent_iseq != 0) {
- while (ip->local_iseq != ip) {
- if (ip->type == ISEQ_TYPE_BLOCK) {
+ if (orig_iseq->body->parent_iseq != 0) {
+ while (orig_iseq->body->local_iseq != iseq) {
+ if (iseq->body->type == ISEQ_TYPE_BLOCK) {
level++;
}
- ip = ip->parent_iseq;
+ iseq = iseq->body->parent_iseq;
}
}
if (level == 1) {
- return rb_sprintf("block in %"PRIsVALUE, ip->location.label);
+ return rb_sprintf("block in %"PRIsVALUE, iseq->body->location.label);
}
else {
- return rb_sprintf("block (%d levels) in %"PRIsVALUE, level, ip->location.label);
+ return rb_sprintf("block (%d levels) in %"PRIsVALUE, level, iseq->body->location.label);
}
}
@@ -3296,7 +3289,8 @@ build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *body)
{
int line = nd_line(body);
VALUE argc = INT2FIX(0);
- VALUE block = NEW_CHILD_ISEQVAL(body, make_name_for_block(iseq->parent_iseq), ISEQ_TYPE_BLOCK, line);
+ const rb_iseq_t *block = NEW_CHILD_ISEQ(body, make_name_for_block(iseq->body->parent_iseq), ISEQ_TYPE_BLOCK, line);
+
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);
@@ -3653,7 +3647,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_ITER:{
- VALUE prevblock = iseq->compile_data->current_block;
+ const rb_iseq_t *prevblock = iseq->compile_data->current_block;
LABEL *retry_label = NEW_LABEL(line);
LABEL *retry_end_l = NEW_LABEL(line);
@@ -3661,16 +3655,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (nd_type(node) == NODE_FOR) {
COMPILE(ret, "iter caller (for)", node->nd_iter);
- iseq->compile_data->current_block =
- NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK, line);
-
+ iseq->compile_data->current_block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
+ ISEQ_TYPE_BLOCK, line);
ADD_SEND_WITH_BLOCK(ret, line, idEach, INT2FIX(0), iseq->compile_data->current_block);
}
else {
- iseq->compile_data->current_block =
- NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK, line);
+ iseq->compile_data->current_block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
+ ISEQ_TYPE_BLOCK, line);
COMPILE(ret, "iter caller", node->nd_iter);
}
ADD_LABEL(ret, retry_end_l);
@@ -3702,7 +3693,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN(ret, line, putnil);
}
}
- else if (iseq->type == ISEQ_TYPE_BLOCK) {
+ else if (iseq->body->type == ISEQ_TYPE_BLOCK) {
break_by_insn:
/* escape from block */
COMPILE(ret, "break val (block)", node->nd_stts);
@@ -3711,12 +3702,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN(ret, line, pop);
}
}
- else if (iseq->type == ISEQ_TYPE_EVAL) {
+ else if (iseq->body->type == ISEQ_TYPE_EVAL) {
break_in_eval:
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with break"));
}
else {
- const rb_iseq_t *ip = iseq->parent_iseq;
+ const rb_iseq_t *ip = iseq->body->parent_iseq;
+
while (ip) {
if (!ip->compile_data) {
ip = 0;
@@ -3728,15 +3720,15 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
level = VM_THROW_NO_ESCAPE_FLAG;
goto break_by_insn;
}
- else if (ip->type == ISEQ_TYPE_BLOCK) {
+ else if (ip->body->type == ISEQ_TYPE_BLOCK) {
level <<= VM_THROW_LEVEL_SHIFT;
goto break_by_insn;
}
- else if (ip->type == ISEQ_TYPE_EVAL) {
+ else if (ip->body->type == ISEQ_TYPE_EVAL) {
goto break_in_eval;
}
- ip = ip->parent_iseq;
+ ip = ip->body->parent_iseq;
}
COMPILE_ERROR((ERROR_ARGS "Invalid break"));
}
@@ -3772,7 +3764,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN(ret, line, putnil);
}
}
- else if (iseq->type == ISEQ_TYPE_EVAL) {
+ else if (iseq->body->type == ISEQ_TYPE_EVAL) {
next_in_eval:
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with next"));
}
@@ -3790,14 +3782,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
/* while loop */
break;
}
- else if (ip->type == ISEQ_TYPE_BLOCK) {
+ else if (ip->body->type == ISEQ_TYPE_BLOCK) {
break;
}
- else if (ip->type == ISEQ_TYPE_EVAL) {
+ else if (ip->body->type == ISEQ_TYPE_EVAL) {
goto next_in_eval;
}
- ip = ip->parent_iseq;
+ ip = ip->body->parent_iseq;
}
if (ip != 0) {
COMPILE(ret, "next val", node->nd_stts);
@@ -3826,7 +3818,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN(ret, line, putnil);
}
}
- else if (iseq->type == ISEQ_TYPE_EVAL) {
+ else if (iseq->body->type == ISEQ_TYPE_EVAL) {
redo_in_eval:
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
}
@@ -3857,14 +3849,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (ip->compile_data->redo_label != 0) {
break;
}
- else if (ip->type == ISEQ_TYPE_BLOCK) {
+ else if (ip->body->type == ISEQ_TYPE_BLOCK) {
break;
}
- else if (ip->type == ISEQ_TYPE_EVAL) {
+ else if (ip->body->type == ISEQ_TYPE_EVAL) {
goto redo_in_eval;
}
- ip = ip->parent_iseq;
+ ip = ip->body->parent_iseq;
}
if (ip != 0) {
ADD_INSN(ret, line, putnil);
@@ -3881,7 +3873,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_RETRY:{
- if (iseq->type == ISEQ_TYPE_RESCUE) {
+ if (iseq->body->type == ISEQ_TYPE_RESCUE) {
ADD_INSN(ret, line, putnil);
ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETRY));
@@ -3902,10 +3894,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
LABEL *lstart = NEW_LABEL(line);
LABEL *lend = NEW_LABEL(line);
LABEL *lcont = NEW_LABEL(line);
- VALUE rescue = NEW_CHILD_ISEQVAL(
- node->nd_resq,
- rb_str_concat(rb_str_new2("rescue in "), iseq->location.label),
- ISEQ_TYPE_RESCUE, line);
+ const rb_iseq_t *rescue = NEW_CHILD_ISEQ(node->nd_resq,
+ rb_str_concat(rb_str_new2("rescue in "), iseq->body->location.label),
+ ISEQ_TYPE_RESCUE, line);
ADD_LABEL(ret, lstart);
COMPILE(ret, "rescue head", node->nd_head);
@@ -3980,11 +3971,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_ENSURE:{
DECL_ANCHOR(ensr);
- VALUE ensure = NEW_CHILD_ISEQVAL(node->nd_ensr,
- rb_str_concat(rb_str_new2
- ("ensure in "),
- iseq->location.label),
- ISEQ_TYPE_ENSURE, line);
+ const rb_iseq_t *ensure = NEW_CHILD_ISEQ(node->nd_ensr,
+ rb_str_concat(rb_str_new2 ("ensure in "), iseq->body->location.label),
+ ISEQ_TYPE_ENSURE, line);
LABEL *lstart = NEW_LABEL(line);
LABEL *lend = NEW_LABEL(line);
LABEL *lcont = NEW_LABEL(line);
@@ -4050,7 +4039,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_LASGN:{
ID id = node->nd_vid;
- int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id);
+ int idx = iseq->body->local_iseq->body->local_size - get_local_var_idx(iseq, id);
debugs("lvar: %"PRIsVALUE" idx: %d\n", rb_id2str(id), idx);
COMPILE(ret, "rvalue", node->nd_value);
@@ -4098,7 +4087,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN(ret, line, dup);
}
ADD_INSN2(ret, line, setinstancevariable,
- ID2SYM(node->nd_vid), INT2FIX(iseq->is_size++));
+ ID2SYM(node->nd_vid), INT2FIX(iseq->body->is_size++));
break;
}
case NODE_CDECL:{
@@ -4470,7 +4459,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
*/
if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR &&
node->nd_mid == idFreeze && node->nd_args == NULL &&
- iseq->compile_data->current_block == Qfalse &&
+ iseq->compile_data->current_block == NULL &&
iseq->compile_data->option->specialized_instruction) {
VALUE str = rb_fstring(node->nd_recv->nd_lit);
iseq_add_mark_object(iseq, str);
@@ -4486,7 +4475,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args &&
nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 1 &&
nd_type(node->nd_args->nd_head) == NODE_STR &&
- iseq->compile_data->current_block == Qfalse &&
+ iseq->compile_data->current_block == NULL &&
iseq->compile_data->option->specialized_instruction) {
VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
node->nd_args->nd_head->nd_lit = str;
@@ -4511,8 +4500,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
VALUE argc;
unsigned int flag = 0;
rb_call_info_kw_arg_t *keywords = NULL;
- VALUE parent_block = iseq->compile_data->current_block;
- iseq->compile_data->current_block = Qfalse;
+ const rb_iseq_t *parent_block = iseq->compile_data->current_block;
+ iseq->compile_data->current_block = NULL;
INIT_ANCHOR(recv);
INIT_ANCHOR(args);
@@ -4623,10 +4612,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
int argc;
unsigned int flag = 0;
rb_call_info_kw_arg_t *keywords = NULL;
- VALUE parent_block = iseq->compile_data->current_block;
+ const rb_iseq_t *parent_block = iseq->compile_data->current_block;
INIT_ANCHOR(args);
- iseq->compile_data->current_block = Qfalse;
+ iseq->compile_data->current_block = NULL;
if (nd_type(node) == NODE_SUPER) {
VALUE vargc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
argc = FIX2INT(vargc);
@@ -4634,43 +4623,43 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
else {
/* NODE_ZSUPER */
int i;
- const rb_iseq_t *liseq = iseq->local_iseq;
+ const rb_iseq_t *liseq = iseq->body->local_iseq;
int lvar_level = get_lvar_level(iseq);
- argc = liseq->param.lead_num;
+ argc = liseq->body->param.lead_num;
/* normal arguments */
- for (i = 0; i < liseq->param.lead_num; i++) {
- int idx = liseq->local_size - i;
+ for (i = 0; i < liseq->body->param.lead_num; i++) {
+ int idx = liseq->body->local_size - i;
ADD_INSN2(args, line, getlocal, INT2FIX(idx), INT2FIX(lvar_level));
}
- if (liseq->param.flags.has_opt) {
+ if (liseq->body->param.flags.has_opt) {
/* optional arguments */
int j;
- for (j = 0; j < liseq->param.opt_num; j++) {
- int idx = liseq->local_size - (i + j);
+ for (j = 0; j < liseq->body->param.opt_num; j++) {
+ int idx = liseq->body->local_size - (i + j);
ADD_INSN2(args, line, getlocal, INT2FIX(idx), INT2FIX(lvar_level));
}
i += j;
argc = i;
}
- if (liseq->param.flags.has_rest) {
+ if (liseq->body->param.flags.has_rest) {
/* rest argument */
- int idx = liseq->local_size - liseq->param.rest_start;
+ int idx = liseq->body->local_size - liseq->body->param.rest_start;
ADD_INSN2(args, line, getlocal, INT2FIX(idx), INT2FIX(lvar_level));
- argc = liseq->param.rest_start + 1;
+ argc = liseq->body->param.rest_start + 1;
flag |= VM_CALL_ARGS_SPLAT;
}
- if (liseq->param.flags.has_post) {
+ if (liseq->body->param.flags.has_post) {
/* post arguments */
- int post_len = liseq->param.post_num;
- int post_start = liseq->param.post_start;
+ int post_len = liseq->body->param.post_num;
+ int post_start = liseq->body->param.post_start;
- if (liseq->param.flags.has_rest) {
+ if (liseq->body->param.flags.has_rest) {
int j;
for (j=0; j<post_len; j++) {
- int idx = liseq->local_size - (post_start + j);
+ int idx = liseq->body->local_size - (post_start + j);
ADD_INSN2(args, line, getlocal, INT2FIX(idx), INT2FIX(lvar_level));
}
ADD_INSN1(args, line, newarray, INT2FIX(j));
@@ -4680,43 +4669,43 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
else {
int j;
for (j=0; j<post_len; j++) {
- int idx = liseq->local_size - (post_start + j);
+ int idx = liseq->body->local_size - (post_start + j);
ADD_INSN2(args, line, getlocal, INT2FIX(idx), INT2FIX(lvar_level));
}
argc = post_len + post_start;
}
}
- if (liseq->param.flags.has_kw) { /* TODO: support keywords */
- int local_size = liseq->local_size;
+ if (liseq->body->param.flags.has_kw) { /* TODO: support keywords */
+ int local_size = liseq->body->local_size;
argc++;
ADD_INSN1(args, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- if (liseq->param.flags.has_kwrest) {
- ADD_INSN2(args, line, getlocal, INT2FIX(liseq->local_size - liseq->param.keyword->rest_start), INT2FIX(lvar_level));
+ if (liseq->body->param.flags.has_kwrest) {
+ ADD_INSN2(args, line, getlocal, INT2FIX(liseq->body->local_size - liseq->body->param.keyword->rest_start), INT2FIX(lvar_level));
ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
}
else {
ADD_INSN1(args, line, newhash, INT2FIX(0));
}
- for (i = 0; i < liseq->param.keyword->num; ++i) {
- ID id = liseq->param.keyword->table[i];
+ for (i = 0; i < liseq->body->param.keyword->num; ++i) {
+ ID id = liseq->body->param.keyword->table[i];
int idx = local_size - get_local_var_idx(liseq, id);
ADD_INSN1(args, line, putobject, ID2SYM(id));
ADD_INSN2(args, line, getlocal, INT2FIX(idx), INT2FIX(lvar_level));
}
ADD_SEND(args, line, id_core_hash_merge_ptr, INT2FIX(i * 2 + 1));
- if (liseq->param.flags.has_rest) {
+ if (liseq->body->param.flags.has_rest) {
ADD_INSN1(args, line, newarray, INT2FIX(1));
ADD_INSN (args, line, concatarray);
--argc;
}
}
- else if (liseq->param.flags.has_kwrest) {
- ADD_INSN2(args, line, getlocal, INT2FIX(liseq->local_size - liseq->param.keyword->rest_start), INT2FIX(lvar_level));
+ else if (liseq->body->param.flags.has_kwrest) {
+ ADD_INSN2(args, line, getlocal, INT2FIX(liseq->body->local_size - liseq->body->param.keyword->rest_start), INT2FIX(lvar_level));
ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
- if (liseq->param.flags.has_rest) {
+ if (liseq->body->param.flags.has_rest) {
ADD_INSN1(args, line, newarray, INT2FIX(1));
ADD_INSN (args, line, concatarray);
}
@@ -4787,13 +4776,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
rb_iseq_t *is = iseq;
if (is) {
- if (is->type == ISEQ_TYPE_TOP) {
+ if (is->body->type == ISEQ_TYPE_TOP) {
COMPILE_ERROR((ERROR_ARGS "Invalid return"));
}
else {
LABEL *splabel = 0;
- if (is->type == ISEQ_TYPE_METHOD) {
+ if (is->body->type == ISEQ_TYPE_METHOD) {
splabel = NEW_LABEL(0);
ADD_LABEL(ret, splabel);
ADD_ADJUST(ret, line, 0);
@@ -4801,7 +4790,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
COMPILE(ret, "return nd_stts (return val)", node->nd_stts);
- if (is->type == ISEQ_TYPE_METHOD) {
+ if (is->body->type == ISEQ_TYPE_METHOD) {
add_ensure_iseq(ret, iseq, 1);
ADD_TRACE(ret, line, RUBY_EVENT_RETURN);
ADD_INSN(ret, line, leave);
@@ -4828,7 +4817,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
rb_call_info_kw_arg_t *keywords = NULL;
INIT_ANCHOR(args);
- if (iseq->type == ISEQ_TYPE_TOP) {
+ if (iseq->body->type == ISEQ_TYPE_TOP) {
COMPILE_ERROR((ERROR_ARGS "Invalid yield"));
}
@@ -4850,7 +4839,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_LVAR:{
if (!poped) {
ID id = node->nd_vid;
- int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id);
+ int idx = iseq->body->local_iseq->body->local_size - get_local_var_idx(iseq, id);
debugs("id: %"PRIsVALUE" idx: %d\n", rb_id2str(id), idx);
ADD_INSN2(ret, line, getlocal, INT2FIX(idx), INT2FIX(get_lvar_level(iseq)));
@@ -4881,7 +4870,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
debugi("nd_vid", node->nd_vid);
if (!poped) {
ADD_INSN2(ret, line, getinstancevariable,
- ID2SYM(node->nd_vid), INT2FIX(iseq->is_size++));
+ ID2SYM(node->nd_vid), INT2FIX(iseq->body->is_size++));
}
break;
}
@@ -4890,7 +4879,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (iseq->compile_data->option->inline_const_cache) {
LABEL *lend = NEW_LABEL(line);
- int ic_index = iseq->is_size++;
+ int ic_index = iseq->body->is_size++;
ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
@@ -5046,10 +5035,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_DREGX_ONCE:{
- int ic_index = iseq->is_size++;
+ int ic_index = iseq->body->is_size++;
NODE *dregx_node = NEW_NODE(NODE_DREGX, node->u1.value, node->u2.value, node->u3.value);
NODE *block_node = NEW_NODE(NODE_SCOPE, 0, dregx_node, 0);
- VALUE block_iseq = NEW_CHILD_ISEQVAL(block_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+ const rb_iseq_t * block_iseq = NEW_CHILD_ISEQ(block_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
ADD_INSN2(ret, line, once, block_iseq, INT2FIX(ic_index));
@@ -5099,36 +5088,35 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_DEFN:{
- VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
- rb_id2str(node->nd_mid),
- ISEQ_TYPE_METHOD, line);
+ const rb_iseq_t *method_iseq = NEW_ISEQ(node->nd_defn,
+ rb_id2str(node->nd_mid),
+ ISEQ_TYPE_METHOD, line);
- debugp_param("defn/iseq", iseqval);
+ debugp_param("defn/iseq", (VALUE)method_iseq);
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_mid));
- ADD_INSN1(ret, line, putiseq, iseqval);
+ ADD_INSN1(ret, line, putiseq, method_iseq);
ADD_SEND (ret, line, id_core_define_method, INT2FIX(3));
if (poped) {
ADD_INSN(ret, line, pop);
}
- debugp_param("defn", iseqval);
break;
}
case NODE_DEFS:{
- VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
- rb_id2str(node->nd_mid),
- ISEQ_TYPE_METHOD, line);
+ const rb_iseq_t * singleton_method = NEW_ISEQ(node->nd_defn,
+ rb_id2str(node->nd_mid),
+ ISEQ_TYPE_METHOD, line);
- debugp_param("defs/iseq", iseqval);
+ debugp_param("defs/iseq", (VALUE)singleton_method);
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
COMPILE(ret, "defs: recv", node->nd_recv);
ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_mid));
- ADD_INSN1(ret, line, putiseq, iseqval);
+ ADD_INSN1(ret, line, putiseq, singleton_method);
ADD_SEND (ret, line, id_core_define_singleton_method, INT2FIX(3));
if (poped) {
@@ -5171,18 +5159,16 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_CLASS:{
- VALUE iseqval =
- NEW_CHILD_ISEQVAL(
- node->nd_body,
- rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid)),
- ISEQ_TYPE_CLASS, line);
+ const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(node->nd_body,
+ rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid)),
+ ISEQ_TYPE_CLASS, line);
VALUE noscope = compile_cpath(ret, iseq, node->nd_cpath);
int flags = VM_DEFINECLASS_TYPE_CLASS;
+
if (!noscope) flags |= VM_DEFINECLASS_FLAG_SCOPED;
if (node->nd_super) flags |= VM_DEFINECLASS_FLAG_HAS_SUPERCLASS;
COMPILE(ret, "super", node->nd_super);
- ADD_INSN3(ret, line, defineclass,
- ID2SYM(node->nd_cpath->nd_mid), iseqval, INT2FIX(flags));
+ ADD_INSN3(ret, line, defineclass, ID2SYM(node->nd_cpath->nd_mid), class_iseq, INT2FIX(flags));
if (poped) {
ADD_INSN(ret, line, pop);
@@ -5190,17 +5176,16 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_MODULE:{
- VALUE iseqval = NEW_CHILD_ISEQVAL(
- node->nd_body,
- rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid)),
- ISEQ_TYPE_CLASS, line);
-
+ const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(node->nd_body,
+ rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid)),
+ ISEQ_TYPE_CLASS, line);
VALUE noscope = compile_cpath(ret, iseq, node->nd_cpath);
int flags = VM_DEFINECLASS_TYPE_MODULE;
+
if (!noscope) flags |= VM_DEFINECLASS_FLAG_SCOPED;
ADD_INSN (ret, line, putnil); /* dummy */
- ADD_INSN3(ret, line, defineclass,
- ID2SYM(node->nd_cpath->nd_mid), iseqval, INT2FIX(flags));
+ ADD_INSN3(ret, line, defineclass, ID2SYM(node->nd_cpath->nd_mid), module_iseq, INT2FIX(flags));
+
if (poped) {
ADD_INSN(ret, line, pop);
}
@@ -5208,15 +5193,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_SCLASS:{
ID singletonclass;
- VALUE iseqval =
- NEW_ISEQVAL(node->nd_body, rb_str_new2("singleton class"),
- ISEQ_TYPE_CLASS, line);
+ const rb_iseq_t *singleton_class = NEW_ISEQ(node->nd_body, rb_str_new2("singleton class"),
+ ISEQ_TYPE_CLASS, line);
COMPILE(ret, "sclass#recv", node->nd_recv);
ADD_INSN (ret, line, putnil);
CONST_ID(singletonclass, "singletonclass");
ADD_INSN3(ret, line, defineclass,
- ID2SYM(singletonclass), iseqval,
+ ID2SYM(singletonclass), singleton_class,
INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS));
if (poped) {
@@ -5228,7 +5212,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (rb_is_const_id(node->nd_mid)) {
/* constant */
LABEL *lend = NEW_LABEL(line);
- int ic_index = iseq->is_size++;
+ int ic_index = iseq->body->is_size++;
DECL_ANCHOR(pref);
DECL_ANCHOR(body);
@@ -5269,7 +5253,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_COLON3:{
LABEL *lend = NEW_LABEL(line);
- int ic_index = iseq->is_size++;
+ int ic_index = iseq->body->is_size++;
debugi("colon3#nd_mid", node->nd_mid);
@@ -5311,11 +5295,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
LABEL *lend = NEW_LABEL(line);
LABEL *lfin = NEW_LABEL(line);
LABEL *ltrue = NEW_LABEL(line);
- rb_iseq_t *local_iseq = iseq->local_iseq;
+ rb_iseq_t *local_iseq = iseq->body->local_iseq;
rb_num_t cnt;
VALUE key;
- cnt = local_iseq->flip_cnt++ + VM_SVAR_FLIPFLOP_START;
+ cnt = local_iseq->body->flip_cnt++ + VM_SVAR_FLIPFLOP_START;
key = INT2FIX(cnt);
ADD_INSN2(ret, line, getspecial, key, INT2FIX(0));
@@ -5373,17 +5357,17 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_ERRINFO:{
if (!poped) {
- if (iseq->type == ISEQ_TYPE_RESCUE) {
+ if (iseq->body->type == ISEQ_TYPE_RESCUE) {
ADD_INSN2(ret, line, getlocal, INT2FIX(2), INT2FIX(0));
}
else {
const rb_iseq_t *ip = iseq;
int level = 0;
while (ip) {
- if (ip->type == ISEQ_TYPE_RESCUE) {
+ if (ip->body->type == ISEQ_TYPE_RESCUE) {
break;
}
- ip = ip->parent_iseq;
+ ip = ip->body->parent_iseq;
level++;
}
if (ip) {
@@ -5421,10 +5405,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
/* compiled to:
* ONCE{ rb_mRubyVMFrozenCore::core#set_postexe{ ... } }
*/
- int is_index = iseq->is_size++;
- VALUE once_iseq = NEW_CHILD_ISEQVAL(
- (NODE *)IFUNC_NEW(build_postexe_iseq, node->nd_body, 0),
- make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+ int is_index = iseq->body->is_size++;
+ const rb_iseq_t *once_iseq = NEW_CHILD_ISEQ((NODE *)IFUNC_NEW(build_postexe_iseq, node->nd_body, 0),
+ make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
ADD_INSN2(ret, line, once, once_iseq, INT2FIX(is_index));
@@ -5453,8 +5436,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
* kw = default_value
* end
*/
- int kw_bits_idx = iseq->local_size - iseq->param.keyword->bits_start;
- int keyword_idx = iseq->param.keyword->num;
+ int kw_bits_idx = iseq->body->local_size - iseq->body->param.keyword->bits_start;
+ int keyword_idx = iseq->body->param.keyword->num;
ADD_INSN2(ret, line, checkkeyword, INT2FIX(kw_bits_idx), INT2FIX(keyword_idx));
ADD_INSNL(ret, line, branchif, end_label);
@@ -5486,7 +5469,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (node->nd_mid == idASET && !private_recv_p(node) && node->nd_args &&
nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 2 &&
nd_type(node->nd_args->nd_head) == NODE_STR &&
- iseq->compile_data->current_block == Qfalse &&
+ iseq->compile_data->current_block == NULL &&
iseq->compile_data->option->specialized_instruction)
{
VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
@@ -5554,8 +5537,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_LAMBDA:{
/* compile same as lambda{...} */
- VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+ const rb_iseq_t *block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
VALUE argc = INT2FIX(0);
+
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_CALL_WITH_BLOCK(ret, line, idLambda, argc, block);
@@ -5640,7 +5624,7 @@ insn_data_to_s_detail(INSN *iobj)
rb_iseq_t *iseq = (rb_iseq_t *)OPERAND_AT(iobj, j);
VALUE val = Qnil;
if (0 && iseq) { /* TODO: invalidate now */
- val = iseq->self;
+ val = (VALUE)iseq;
}
rb_str_concat(str, opobj_inspect(val));
}
@@ -5817,7 +5801,8 @@ iseq_build_from_ary_exception(rb_iseq_t *iseq, struct st_table *labels_table,
int i;
for (i=0; i<RARRAY_LEN(exception); i++) {
- VALUE v, type, eiseqval;
+ const rb_iseq_t *eiseq;
+ VALUE v, type;
const VALUE *ptr;
LABEL *lstart, *lend, *lcont;
unsigned int sp;
@@ -5830,10 +5815,10 @@ iseq_build_from_ary_exception(rb_iseq_t *iseq, struct st_table *labels_table,
ptr = RARRAY_CONST_PTR(v);
type = get_exception_sym2type(ptr[0]);
if (ptr[1] == Qnil) {
- eiseqval = 0;
+ eiseq = NULL;
}
else {
- eiseqval = rb_iseq_load(ptr[1], iseq->self, Qnil);
+ eiseq = rb_iseqw_to_iseq(rb_iseq_load(ptr[1], (VALUE)iseq, Qnil));
}
lstart = register_label(iseq, labels_table, ptr[2]);
@@ -5843,7 +5828,7 @@ iseq_build_from_ary_exception(rb_iseq_t *iseq, struct st_table *labels_table,
(void)sp;
- ADD_CATCH_ENTRY(type, lstart, lend, eiseqval, lcont);
+ ADD_CATCH_ENTRY(type, lstart, lend, eiseq, lcont);
RB_GC_GUARD(v);
}
@@ -5864,21 +5849,25 @@ insn_make_insn_table(void)
return table;
}
-static VALUE
-iseq_build_load_iseq(rb_iseq_t *iseq, VALUE op)
+static const rb_iseq_t *
+iseq_build_load_iseq(const rb_iseq_t *iseq, VALUE op)
{
- VALUE iseqval;
+ VALUE iseqw;
+ const rb_iseq_t *loaded_iseq;
+
if (RB_TYPE_P(op, T_ARRAY)) {
- iseqval = rb_iseq_load(op, iseq->self, Qnil);
+ iseqw = rb_iseq_load(op, (VALUE)iseq, Qnil);
}
else if (CLASS_OF(op) == rb_cISeq) {
- iseqval = op;
+ iseqw = op;
}
else {
rb_raise(rb_eSyntaxError, "ISEQ is required");
}
- iseq_add_mark_object(iseq, iseqval);
- return iseqval;
+
+ loaded_iseq = rb_iseqw_to_iseq(iseqw);
+ iseq_add_mark_object(iseq, (VALUE)loaded_iseq);
+ return loaded_iseq;
}
static VALUE
@@ -5886,7 +5875,7 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op)
{
ID mid = 0;
int orig_argc = 0;
- VALUE block = 0;
+ const rb_iseq_t *block = NULL;
unsigned int flag = 0;
rb_call_info_kw_arg_t *kw_arg = 0;
@@ -5957,12 +5946,12 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
insn = (argc < 0) ? Qnil : RARRAY_AREF(obj, 0);
if (st_lookup(insn_table, (st_data_t)insn, &insn_id) == 0) {
/* TODO: exception */
- rb_compile_error(RSTRING_PTR(iseq->location.path), line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), line_no,
"unknown instruction: %+"PRIsVALUE, insn);
}
if (argc != insn_len((VALUE)insn_id)-1) {
- rb_compile_error(RSTRING_PTR(iseq->location.path), line_no,
+ rb_compile_error(RSTRING_PTR(iseq->body->location.path), line_no,
"operand size mismatch");
}
@@ -5988,7 +5977,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
case TS_ISEQ:
{
if (op != Qnil) {
- argv[j] = iseq_build_load_iseq(iseq, op);
+ argv[j] = (VALUE)iseq_build_load_iseq(iseq, op);
}
else {
argv[j] = 0;
@@ -6001,8 +5990,8 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
break;
case TS_IC:
argv[j] = op;
- if (NUM2INT(op) >= iseq->is_size) {
- iseq->is_size = NUM2INT(op) + 1;
+ if (NUM2INT(op) >= iseq->body->is_size) {
+ iseq->body->is_size = NUM2INT(op) + 1;
}
break;
case TS_CALLINFO:
@@ -6089,14 +6078,14 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
int default_len;
VALUE key, sym, default_val;
- iseq->param.flags.has_kw = TRUE;
+ iseq->body->param.flags.has_kw = TRUE;
- iseq->param.keyword = ZALLOC(struct rb_iseq_param_keyword);
- iseq->param.keyword->num = len;
+ iseq->body->param.keyword = ZALLOC(struct rb_iseq_param_keyword);
+ iseq->body->param.keyword->num = len;
#define SYM(s) ID2SYM(rb_intern(#s))
- (void)int_param(&iseq->param.keyword->bits_start, params, SYM(kwbits));
- i = iseq->param.keyword->bits_start - iseq->param.keyword->num;
- iseq->param.keyword->table = &iseq->local_table[i];
+ (void)int_param(&iseq->body->param.keyword->bits_start, params, SYM(kwbits));
+ i = iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num;
+ iseq->body->param.keyword->table = &iseq->body->local_table[i];
#undef SYM
/* required args */
@@ -6106,8 +6095,8 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
if (!SYMBOL_P(val)) {
goto default_values;
}
- iseq->param.keyword->table[i] = SYM2ID(val);
- iseq->param.keyword->required_num++;
+ iseq->body->param.keyword->table[i] = SYM2ID(val);
+ iseq->body->param.keyword->required_num++;
}
default_values: /* note: we intentionally preserve `i' from previous loop */
@@ -6116,7 +6105,7 @@ default_values: /* note: we intentionally preserve `i' from previous loop */
return;
}
- iseq->param.keyword->default_values = ALLOC_N(VALUE, default_len);
+ iseq->body->param.keyword->default_values = ALLOC_N(VALUE, default_len);
for (j = 0; i < len; i++, j++) {
key = RARRAY_AREF(keywords, i);
@@ -6136,12 +6125,12 @@ default_values: /* note: we intentionally preserve `i' from previous loop */
"keyword default has unsupported len %+"PRIsVALUE,
key);
}
- iseq->param.keyword->table[i] = SYM2ID(sym);
- iseq->param.keyword->default_values[j] = default_val;
+ iseq->body->param.keyword->table[i] = SYM2ID(sym);
+ iseq->body->param.keyword->default_values[j] = default_val;
}
}
-VALUE
+void
rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
VALUE exception, VALUE body)
{
@@ -6156,9 +6145,9 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
INIT_ANCHOR(anchor);
len = RARRAY_LENINT(locals);
- iseq->local_table_size = len;
- iseq->local_table = tbl = (ID *)ALLOC_N(ID, iseq->local_table_size);
- iseq->local_size = iseq->local_table_size + 1;
+ iseq->body->local_table_size = len;
+ iseq->body->local_table = tbl = (ID *)ALLOC_N(ID, iseq->body->local_table_size);
+ iseq->body->local_size = iseq->body->local_table_size + 1;
for (i = 0; i < len; i++) {
VALUE lv = RARRAY_AREF(locals, i);
@@ -6176,30 +6165,30 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
* local_size, stack_size and param.size are all calculated
*/
-#define INT_PARAM(F) int_param(&iseq->param.F, params, SYM(F))
+#define INT_PARAM(F) int_param(&iseq->body->param.F, params, SYM(F))
if (INT_PARAM(lead_num)) {
- iseq->param.flags.has_lead = TRUE;
+ iseq->body->param.flags.has_lead = TRUE;
}
- if (INT_PARAM(post_num)) iseq->param.flags.has_post = TRUE;
- if (INT_PARAM(post_start)) iseq->param.flags.has_post = TRUE;
- if (INT_PARAM(rest_start)) iseq->param.flags.has_rest = TRUE;
- if (INT_PARAM(block_start)) iseq->param.flags.has_block = TRUE;
+ if (INT_PARAM(post_num)) iseq->body->param.flags.has_post = TRUE;
+ if (INT_PARAM(post_start)) iseq->body->param.flags.has_post = TRUE;
+ if (INT_PARAM(rest_start)) iseq->body->param.flags.has_rest = TRUE;
+ if (INT_PARAM(block_start)) iseq->body->param.flags.has_block = TRUE;
#undef INT_PARAM
switch (TYPE(arg_opt_labels)) {
case T_ARRAY:
len = RARRAY_LENINT(arg_opt_labels);
- iseq->param.flags.has_opt = !!(len - 1 >= 0);
+ iseq->body->param.flags.has_opt = !!(len - 1 >= 0);
- if (iseq->param.flags.has_opt) {
- iseq->param.opt_num = len - 1;
- iseq->param.opt_table = (VALUE *)ALLOC_N(VALUE, len);
+ if (iseq->body->param.flags.has_opt) {
+ iseq->body->param.opt_num = len - 1;
+ iseq->body->param.opt_table = (VALUE *)ALLOC_N(VALUE, len);
for (i = 0; i < len; i++) {
VALUE ent = RARRAY_AREF(arg_opt_labels, i);
LABEL *label = register_label(iseq, labels_table, ent);
- iseq->param.opt_table[i] = (VALUE)label;
+ iseq->body->param.opt_table[i] = (VALUE)label;
}
}
case T_NIL:
@@ -6220,15 +6209,15 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
}
if (Qtrue == rb_hash_aref(params, SYM(ambiguous_param0))) {
- iseq->param.flags.ambiguous_param0 = TRUE;
+ iseq->body->param.flags.ambiguous_param0 = TRUE;
}
if (int_param(&i, params, SYM(kwrest))) {
- if (!iseq->param.keyword) {
- iseq->param.keyword = ZALLOC(struct rb_iseq_param_keyword);
+ if (!iseq->body->param.keyword) {
+ iseq->body->param.keyword = ZALLOC(struct rb_iseq_param_keyword);
}
- iseq->param.keyword->rest_start = i;
- iseq->param.flags.has_kwrest = TRUE;
+ iseq->body->param.keyword->rest_start = i;
+ iseq->body->param.flags.has_kwrest = TRUE;
}
#undef SYM
@@ -6239,7 +6228,6 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
/* body */
iseq_build_from_ary_body(iseq, anchor, body, labels_table);
- return iseq->self;
}
/* for parser */
@@ -6251,20 +6239,20 @@ rb_dvar_defined(ID id)
const rb_iseq_t *iseq;
if (th->base_block && (iseq = th->base_block->iseq)) {
- while (iseq->type == ISEQ_TYPE_BLOCK ||
- iseq->type == ISEQ_TYPE_RESCUE ||
- iseq->type == ISEQ_TYPE_ENSURE ||
- iseq->type == ISEQ_TYPE_EVAL ||
- iseq->type == ISEQ_TYPE_MAIN
+ while (iseq->body->type == ISEQ_TYPE_BLOCK ||
+ iseq->body->type == ISEQ_TYPE_RESCUE ||
+ iseq->body->type == ISEQ_TYPE_ENSURE ||
+ iseq->body->type == ISEQ_TYPE_EVAL ||
+ iseq->body->type == ISEQ_TYPE_MAIN
) {
int i;
- for (i = 0; i < iseq->local_table_size; i++) {
- if (iseq->local_table[i] == id) {
+ for (i = 0; i < iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == id) {
return 1;
}
}
- iseq = iseq->parent_iseq;
+ iseq = iseq->body->parent_iseq;
}
}
return 0;
@@ -6278,10 +6266,10 @@ rb_local_defined(ID id)
if (th->base_block && th->base_block->iseq) {
int i;
- iseq = th->base_block->iseq->local_iseq;
+ iseq = th->base_block->iseq->body->local_iseq;
- for (i=0; i<iseq->local_table_size; i++) {
- if (iseq->local_table[i] == id) {
+ for (i=0; i<iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == id) {
return 1;
}
}
@@ -6310,8 +6298,8 @@ caller_location(VALUE *path, VALUE *absolute_path)
if (cfp) {
int line = rb_vm_get_sourceline(cfp);
- *path = cfp->iseq->location.path;
- *absolute_path = cfp->iseq->location.absolute_path;
+ *path = cfp->iseq->body->location.path;
+ *absolute_path = cfp->iseq->body->location.absolute_path;
return line;
}
else {
@@ -6327,7 +6315,7 @@ typedef struct {
int line;
} accessor_args;
-static VALUE
+static const rb_iseq_t *
method_for_self(VALUE name, VALUE arg, rb_insn_func_t func,
VALUE (*build)(rb_iseq_t *, LINK_ANCHOR *, VALUE))
{
@@ -6349,8 +6337,8 @@ for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a)
const int line = args->line;
iseq_set_local_table(iseq, 0);
- iseq->param.lead_num = 0;
- iseq->param.size = 0;
+ iseq->body->param.lead_num = 0;
+ iseq->body->param.size = 0;
ADD_INSN1(ret, line, putobject, args->arg);
ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
@@ -6365,8 +6353,8 @@ for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a)
static const ID vars[] = {1, idUScore};
iseq_set_local_table(iseq, vars);
- iseq->param.lead_num = 1;
- iseq->param.size = 1;
+ iseq->body->param.lead_num = 1;
+ iseq->body->param.size = 1;
ADD_INSN2(ret, line, getlocal, INT2FIX(numberof(vars)-0), INT2FIX(0));
ADD_INSN1(ret, line, putobject, args->arg);
@@ -6378,7 +6366,7 @@ for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a)
/*
* func (index) -> (value)
*/
-VALUE
+const rb_iseq_t *
rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
{
return method_for_self(name, arg, func, for_self_aref);
@@ -6387,7 +6375,7 @@ rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
/*
* func (index, value) -> (index, value)
*/
-VALUE
+const rb_iseq_t *
rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
{
return method_for_self(name, arg, func, for_self_aset);
diff --git a/eval.c b/eval.c
index 69a15d9985..287a7406d9 100644
--- a/eval.c
+++ b/eval.c
@@ -237,7 +237,7 @@ static int
ruby_exec_internal(void *n)
{
volatile int state;
- VALUE iseq = (VALUE)n;
+ rb_iseq_t *iseq = (rb_iseq_t *)n;
rb_thread_t *th = GET_THREAD();
if (!n) return 0;
@@ -1448,10 +1448,10 @@ errinfo_place(rb_thread_t *th)
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
+ if (cfp->iseq->body->type == ISEQ_TYPE_RESCUE) {
return &cfp->ep[-2];
}
- else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
+ else if (cfp->iseq->body->type == ISEQ_TYPE_ENSURE &&
!THROW_DATA_P(cfp->ep[-2]) &&
!FIXNUM_P(cfp->ep[-2])) {
return &cfp->ep[-2];
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 352380d89b..a268be8f76 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -497,7 +497,7 @@ count_tdata_objects(int argc, VALUE *argv, VALUE self)
return hash;
}
-static ID imemo_type_ids[imemo_mask];
+static ID imemo_type_ids[imemo_mask+1];
static int
count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
@@ -567,6 +567,7 @@ count_imemo_objects(int argc, VALUE *argv, VALUE self)
imemo_type_ids[4] = rb_intern("imemo_ifunc");
imemo_type_ids[5] = rb_intern("imemo_memo");
imemo_type_ids[6] = rb_intern("imemo_ment");
+ imemo_type_ids[7] = rb_intern("imemo_iseq");
}
rb_objspace_each_objects(count_imemo_objects_i, (void *)hash);
diff --git a/gc.c b/gc.c
index 36c4e01320..3cb5a61324 100644
--- a/gc.c
+++ b/gc.c
@@ -404,6 +404,7 @@ typedef struct RVALUE {
struct vm_ifunc ifunc;
struct MEMO memo;
struct rb_method_entry_struct ment;
+ const rb_iseq_t iseq;
} imemo;
struct {
struct RBasic basic;
@@ -699,6 +700,7 @@ static rb_objspace_t rb_objspace = {{GC_MALLOC_LIMIT_MIN}};
#endif
#define ruby_initial_gc_stress gc_params.gc_stress
+
VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
#define malloc_limit objspace->malloc_params.limit
@@ -778,6 +780,9 @@ int ruby_gc_debug_indent = 0;
VALUE rb_mGC;
int ruby_disable_gc = 0;
+void rb_iseq_mark(const rb_iseq_t *iseq);
+void rb_iseq_free(const rb_iseq_t *iseq);
+
void rb_gcdebug_print_obj_condition(VALUE obj);
static void rb_objspace_call_finalizer(rb_objspace_t *objspace);
@@ -2140,11 +2145,18 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
case T_IMEMO:
{
- if (imemo_type(obj) == imemo_ment) {
+ switch (imemo_type(obj)) {
+ case imemo_ment:
rb_free_method_entry(&RANY(obj)->as.imemo.ment);
+ break;
+ case imemo_iseq:
+ rb_iseq_free(&RANY(obj)->as.imemo.iseq);
+ break;
+ default:
+ break;
}
}
- break;
+ return 0;
default:
rb_bug("gc_sweep(): unknown data type 0x%x(%p) 0x%"PRIxVALUE,
@@ -3924,7 +3936,7 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
if (def) {
switch (def->type) {
case VM_METHOD_TYPE_ISEQ:
- if (def->body.iseq.iseqptr) gc_mark(objspace, def->body.iseq.iseqptr->self);
+ if (def->body.iseq.iseqptr) gc_mark(objspace, (VALUE)def->body.iseq.iseqptr);
gc_mark(objspace, (VALUE)def->body.iseq.cref);
break;
case VM_METHOD_TYPE_ATTRSET:
@@ -4272,6 +4284,9 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case T_IMEMO:
switch (imemo_type(obj)) {
+ case imemo_none:
+ rb_bug("unreachable");
+ return;
case imemo_cref:
gc_mark(objspace, RANY(obj)->as.imemo.cref.klass);
gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next);
@@ -4297,9 +4312,11 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case imemo_ment:
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
return;
- default:
- rb_bug("T_IMEMO: unreachable");
+ case imemo_iseq:
+ rb_iseq_mark((rb_iseq_t *)obj);
+ return;
}
+ rb_bug("T_IMEMO: unreachable");
}
gc_mark(objspace, any->as.basic.klass);
@@ -8917,15 +8934,7 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
}
case T_DATA: {
const char * const type_name = rb_objspace_data_type_name(obj);
- if (type_name && strcmp(type_name, "iseq") == 0) {
- rb_iseq_t *iseq;
- GetISeqPtr(obj, iseq);
- if (iseq->location.label) {
- snprintf(buff, buff_size, "%s %s@%s:%d", buff,
- RSTRING_PTR(iseq->location.label), RSTRING_PTR(iseq->location.path), (int)iseq->location.first_lineno);
- }
- }
- else if (type_name) {
+ if (type_name) {
snprintf(buff, buff_size, "%s %s", buff, type_name);
}
break;
@@ -8945,10 +8954,25 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
#undef IMEMO_NAME
}
snprintf(buff, buff_size, "%s %s", buff, imemo_name);
- if (imemo_type(obj) == imemo_ment) {
- const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment;
- snprintf(buff, buff_size, "%s (called_id: %s, type: %s, alias: %d, class: %s)", buff,
- rb_id2name(me->called_id), method_type_name(me->def->type), me->def->alias_count, obj_info(me->defined_class));
+
+ switch (imemo_type(obj)) {
+ case imemo_ment: {
+ const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment;
+ snprintf(buff, buff_size, "%s (called_id: %s, type: %s, alias: %d, class: %s)", buff,
+ rb_id2name(me->called_id), method_type_name(me->def->type), me->def->alias_count, obj_info(me->defined_class));
+ break;
+ }
+ case imemo_iseq: {
+ const rb_iseq_t *iseq = (const rb_iseq_t *)obj;
+
+ if (iseq->body->location.label) {
+ snprintf(buff, buff_size, "%s %s@%s:%d", buff,
+ RSTRING_PTR(iseq->body->location.label), RSTRING_PTR(iseq->body->location.path), (int)iseq->body->location.first_lineno);
+ }
+ break;
+ }
+ default:
+ break;
}
}
default:
diff --git a/insns.def b/insns.def
index c2697c60d5..ed02b6edba 100644
--- a/insns.def
+++ b/insns.def
@@ -337,7 +337,7 @@ putiseq
()
(VALUE ret)
{
- ret = iseq->self;
+ ret = (VALUE)iseq;
}
/**
@@ -917,8 +917,8 @@ defineclass
vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, klass,
VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
(VALUE)vm_cref_push(th, klass, NULL),
- class_iseq->iseq_encoded, GET_SP(),
- class_iseq->local_size, class_iseq->stack_max);
+ class_iseq->body->iseq_encoded, GET_SP(),
+ class_iseq->body->local_size, class_iseq->body->stack_max);
RESTORE_REGS();
NEXT_INSN();
diff --git a/internal.h b/internal.h
index c91d8caba0..5ba73847fa 100644
--- a/internal.h
+++ b/internal.h
@@ -546,6 +546,7 @@ enum imemo_type {
imemo_ifunc = 4,
imemo_memo = 5,
imemo_ment = 6,
+ imemo_iseq = 7,
imemo_mask = 0x07
};
@@ -854,14 +855,6 @@ void rb_write_error_str(VALUE mesg);
VALUE rb_io_flush_raw(VALUE, int);
size_t rb_io_memsize(const rb_io_t *);
-/* iseq.c */
-VALUE rb_iseq_path(VALUE iseqval);
-VALUE rb_iseq_absolute_path(VALUE iseqval);
-VALUE rb_iseq_label(VALUE iseqval);
-VALUE rb_iseq_base_label(VALUE iseqval);
-VALUE rb_iseq_first_lineno(VALUE iseqval);
-VALUE rb_iseq_method_name(VALUE self);
-
/* load.c */
VALUE rb_get_load_path(void);
VALUE rb_get_expanded_load_path(void);
diff --git a/iseq.c b/iseq.c
index 0161dea259..e4790e290a 100644
--- a/iseq.c
+++ b/iseq.c
@@ -29,6 +29,7 @@
#define ISEQ_MINOR_VERSION 2
VALUE rb_cISeq;
+ID iseqw_iseq_key;
#define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
@@ -63,60 +64,61 @@ compile_data_free(struct iseq_compile_data *compile_data)
}
}
-static void
-iseq_free(void *ptr)
+void
+rb_iseq_free(const rb_iseq_t *iseq)
{
RUBY_FREE_ENTER("iseq");
- if (ptr) {
+ if (iseq) {
int i;
- rb_iseq_t *iseq = ptr;
- ruby_xfree(iseq->iseq_encoded);
- ruby_xfree(iseq->line_info_table);
- ruby_xfree(iseq->local_table);
- ruby_xfree(iseq->is_entries);
+ ruby_xfree(iseq->body->iseq_encoded);
+ ruby_xfree(iseq->body->line_info_table);
+ ruby_xfree(iseq->body->local_table);
+ ruby_xfree(iseq->body->is_entries);
- if (iseq->callinfo_entries) {
- for (i=0; i<iseq->callinfo_size; i++) {
+ if (iseq->body->callinfo_entries) {
+ for (i=0; i<iseq->body->callinfo_size; i++) {
/* TODO: revisit callinfo data structure */
- const rb_call_info_kw_arg_t *kw_arg = iseq->callinfo_entries[i].kw_arg;
+ const rb_call_info_kw_arg_t *kw_arg = iseq->body->callinfo_entries[i].kw_arg;
ruby_xfree((void *)kw_arg);
}
- ruby_xfree(iseq->callinfo_entries);
+ ruby_xfree(iseq->body->callinfo_entries);
}
- ruby_xfree(iseq->catch_table);
- ruby_xfree(iseq->param.opt_table);
- if (iseq->param.keyword != NULL) {
- ruby_xfree(iseq->param.keyword->default_values);
- ruby_xfree(iseq->param.keyword);
+ ruby_xfree(iseq->body->catch_table);
+ ruby_xfree(iseq->body->param.opt_table);
+ if (iseq->body->param.keyword != NULL) {
+ ruby_xfree(iseq->body->param.keyword->default_values);
+ ruby_xfree(iseq->body->param.keyword);
}
compile_data_free(iseq->compile_data);
- ruby_xfree(iseq->iseq);
-
- ruby_xfree(ptr);
+ ruby_xfree(iseq->body->iseq);
+ ruby_xfree(iseq->body);
}
RUBY_FREE_LEAVE("iseq");
}
-static void
-iseq_mark(void *ptr)
+void
+rb_iseq_mark(const rb_iseq_t *iseq)
{
- const rb_iseq_t *iseq = ptr;
-
RUBY_MARK_ENTER("iseq");
- RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->location.label), RSTRING_PTR(iseq->location.path));
+ RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->body->location.label), RSTRING_PTR(iseq->body->location.path));
+
+ if (iseq->body) {
+ const struct rb_iseq_body *body = iseq->body;
- RUBY_MARK_UNLESS_NULL(iseq->mark_ary);
- RUBY_MARK_UNLESS_NULL(iseq->location.label);
- RUBY_MARK_UNLESS_NULL(iseq->location.base_label);
- RUBY_MARK_UNLESS_NULL(iseq->location.path);
- RUBY_MARK_UNLESS_NULL(iseq->location.absolute_path);
- RUBY_MARK_UNLESS_NULL(iseq->coverage);
+ RUBY_MARK_UNLESS_NULL(body->mark_ary);
+ RUBY_MARK_UNLESS_NULL(body->location.label);
+ RUBY_MARK_UNLESS_NULL(body->location.base_label);
+ RUBY_MARK_UNLESS_NULL(body->location.path);
+ RUBY_MARK_UNLESS_NULL(body->location.absolute_path);
+ RUBY_MARK_UNLESS_NULL(body->coverage);
+ }
if (iseq->compile_data != 0) {
- struct iseq_compile_data *const compile_data = iseq->compile_data;
+ const struct iseq_compile_data *const compile_data = iseq->compile_data;
+
RUBY_MARK_UNLESS_NULL(compile_data->mark_ary);
RUBY_MARK_UNLESS_NULL(compile_data->err_info);
RUBY_MARK_UNLESS_NULL(compile_data->catch_table_ary);
@@ -125,6 +127,7 @@ iseq_mark(void *ptr)
RUBY_MARK_LEAVE("iseq");
}
+#if 0 /* TODO */
static size_t
iseq_memsize(const void *ptr)
{
@@ -133,19 +136,19 @@ iseq_memsize(const void *ptr)
if (ptr) {
const rb_iseq_t *iseq = ptr;
- size += iseq->iseq_size * sizeof(VALUE);
- size += iseq->line_info_size * sizeof(struct iseq_line_info_entry);
- size += iseq->local_table_size * sizeof(ID);
- if (iseq->catch_table) {
- size += iseq_catch_table_bytes(iseq->catch_table->size);
+ size += iseq->body->iseq_size * sizeof(VALUE);
+ size += iseq->body->line_info_size * sizeof(struct iseq_line_info_entry);
+ size += iseq->body->local_table_size * sizeof(ID);
+ if (iseq->body->catch_table) {
+ size += iseq_catch_table_bytes(iseq->body->catch_table->size);
}
- size += (iseq->param.opt_num + 1) * sizeof(VALUE);
- if (iseq->param.keyword != NULL) {
+ size += (iseq->body->param.opt_num + 1) * sizeof(VALUE);
+ if (iseq->body->param.keyword != NULL) {
size += sizeof(struct rb_iseq_param_keyword);
- size += sizeof(VALUE) * (iseq->param.keyword->num - iseq->param.keyword->required_num);
+ size += sizeof(VALUE) * (iseq->body->param.keyword->num - iseq->body->param.keyword->required_num);
}
- size += iseq->is_size * sizeof(union iseq_inline_storage_entry);
- size += iseq->callinfo_size * sizeof(rb_call_info_t);
+ size += iseq->body->is_size * sizeof(union iseq_inline_storage_entry);
+ size += iseq->body->callinfo_size * sizeof(rb_call_info_t);
if (iseq->compile_data) {
struct iseq_compile_data_storage *cur;
@@ -157,115 +160,103 @@ iseq_memsize(const void *ptr)
}
size += sizeof(struct iseq_compile_data);
}
- if (iseq->iseq) {
- size += iseq->iseq_size * sizeof(VALUE);
+ if (iseq->body->iseq) {
+ size += iseq->body->iseq_size * sizeof(VALUE);
}
}
return size;
}
+#endif
-static const rb_data_type_t iseq_data_type = {
- "iseq",
- {
- iseq_mark,
- iseq_free,
- iseq_memsize,
- }, /* functions */
- 0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_PROMOTED1 /* start from age == 2 */ | RUBY_TYPED_WB_PROTECTED
-};
-
-static VALUE
-iseq_alloc(VALUE klass)
+static rb_iseq_t *
+iseq_alloc(void)
{
- rb_iseq_t *iseq;
- return TypedData_Make_Struct(klass, rb_iseq_t, &iseq_data_type, iseq);
+ rb_iseq_t *iseq = (rb_iseq_t *)rb_imemo_new(imemo_iseq, 0, 0, 0, 0);
+ iseq->body = ZALLOC(struct rb_iseq_body);
+ return iseq;
}
static rb_iseq_location_t *
iseq_location_setup(rb_iseq_t *iseq, VALUE path, VALUE absolute_path, VALUE name, VALUE first_lineno)
{
- rb_iseq_location_t *loc = &iseq->location;
- RB_OBJ_WRITE(iseq->self, &loc->path, path);
+ rb_iseq_location_t *loc = &iseq->body->location;
+ RB_OBJ_WRITE(iseq, &loc->path, path);
if (RTEST(absolute_path) && rb_str_cmp(path, absolute_path) == 0) {
- RB_OBJ_WRITE(iseq->self, &loc->absolute_path, path);
+ RB_OBJ_WRITE(iseq, &loc->absolute_path, path);
}
else {
- RB_OBJ_WRITE(iseq->self, &loc->absolute_path, absolute_path);
+ RB_OBJ_WRITE(iseq, &loc->absolute_path, absolute_path);
}
- RB_OBJ_WRITE(iseq->self, &loc->label, name);
- RB_OBJ_WRITE(iseq->self, &loc->base_label, name);
+ RB_OBJ_WRITE(iseq, &loc->label, name);
+ RB_OBJ_WRITE(iseq, &loc->base_label, name);
loc->first_lineno = first_lineno;
return loc;
}
static void
-set_relation(rb_iseq_t *iseq, const VALUE parent)
+set_relation(rb_iseq_t *iseq, const rb_iseq_t *piseq)
{
- const VALUE type = iseq->type;
- rb_iseq_t *piseq;
+ const VALUE type = iseq->body->type;
/* set class nest stack */
if (type == ISEQ_TYPE_TOP) {
- iseq->local_iseq = iseq;
+ iseq->body->local_iseq = iseq;
}
else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
- iseq->local_iseq = iseq;
+ iseq->body->local_iseq = iseq;
}
- else if (RTEST(parent)) {
- GetISeqPtr(parent, piseq);
- iseq->local_iseq = piseq->local_iseq;
+ else if (piseq) {
+ iseq->body->local_iseq = piseq->body->local_iseq;
}
- if (RTEST(parent)) {
- GetISeqPtr(parent, piseq);
- iseq->parent_iseq = piseq;
+ if (piseq) {
+ iseq->body->parent_iseq = piseq;
}
if (type == ISEQ_TYPE_MAIN) {
- iseq->local_iseq = iseq;
+ iseq->body->local_iseq = iseq;
}
}
void
rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj)
{
- if (!RTEST(iseq->mark_ary)) {
- RB_OBJ_WRITE(iseq->self, &iseq->mark_ary, rb_ary_tmp_new(3));
- RBASIC_CLEAR_CLASS(iseq->mark_ary);
+ if (!RTEST(iseq->body->mark_ary)) {
+ RB_OBJ_WRITE(iseq, &iseq->body->mark_ary, rb_ary_tmp_new(3));
+ RBASIC_CLEAR_CLASS(iseq->body->mark_ary);
}
- rb_ary_push(iseq->mark_ary, obj);
+ rb_ary_push(iseq->body->mark_ary, obj);
}
static VALUE
prepare_iseq_build(rb_iseq_t *iseq,
VALUE name, VALUE path, VALUE absolute_path, VALUE first_lineno,
- VALUE parent, enum iseq_type type,
+ const rb_iseq_t *parent, enum iseq_type type,
const rb_compile_option_t *option)
{
- iseq->type = type;
+ iseq->body->type = type;
set_relation(iseq, parent);
name = rb_fstring(name);
path = rb_fstring(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);
+ if (iseq != iseq->body->local_iseq) {
+ RB_OBJ_WRITE(iseq, &iseq->body->location.base_label, iseq->body->local_iseq->body->location.label);
}
- RB_OBJ_WRITE(iseq->self, &iseq->mark_ary, 0);
+ RB_OBJ_WRITE(iseq, &iseq->body->mark_ary, 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));
+ RB_OBJ_WRITE(iseq, &iseq->compile_data->err_info, Qnil);
+ RB_OBJ_WRITE(iseq, &iseq->compile_data->mark_ary, rb_ary_tmp_new(3));
iseq->compile_data->storage_head = iseq->compile_data->storage_current =
(struct iseq_compile_data_storage *)
ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE +
SIZEOF_ISEQ_COMPILE_DATA_STORAGE);
- RB_OBJ_WRITE(iseq->self, &iseq->compile_data->catch_table_ary, rb_ary_new());
+ RB_OBJ_WRITE(iseq, &iseq->compile_data->catch_table_ary, rb_ary_tmp_new(3));
iseq->compile_data->storage_head->pos = 0;
iseq->compile_data->storage_head->next = 0;
iseq->compile_data->storage_head->size =
@@ -273,12 +264,13 @@ prepare_iseq_build(rb_iseq_t *iseq,
iseq->compile_data->option = option;
iseq->compile_data->last_coverable_line = -1;
- RB_OBJ_WRITE(iseq->self, &iseq->coverage, Qfalse);
+ RB_OBJ_WRITE(iseq, &iseq->body->coverage, Qfalse);
+
if (!GET_THREAD()->parse_in_eval) {
VALUE coverages = rb_get_coverages();
if (RTEST(coverages)) {
- RB_OBJ_WRITE(iseq->self, &iseq->coverage, rb_hash_lookup(coverages, path));
- if (NIL_P(iseq->coverage)) RB_OBJ_WRITE(iseq->self, &iseq->coverage, Qfalse);
+ RB_OBJ_WRITE(iseq, &iseq->body->coverage, rb_hash_lookup(coverages, path));
+ if (NIL_P(iseq->body->coverage)) RB_OBJ_WRITE(iseq, &iseq->body->coverage, Qfalse);
}
}
@@ -294,7 +286,7 @@ cleanup_iseq_build(rb_iseq_t *iseq)
compile_data_free(data);
if (RTEST(err)) {
- rb_funcall2(err, rb_intern("set_backtrace"), 1, &iseq->location.path);
+ rb_funcall2(err, rb_intern("set_backtrace"), 1, &iseq->body->location.path);
rb_exc_raise(err);
}
return Qtrue;
@@ -379,49 +371,45 @@ make_compile_option_value(rb_compile_option_t *option)
return opt;
}
-VALUE
+rb_iseq_t *
rb_iseq_new(NODE *node, VALUE name, VALUE path, VALUE absolute_path,
- VALUE parent, enum iseq_type type)
+ const rb_iseq_t *parent, enum iseq_type type)
{
return rb_iseq_new_with_opt(node, name, path, absolute_path, INT2FIX(0), parent, type,
&COMPILE_OPTION_DEFAULT);
}
-VALUE
-rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE parent)
+rb_iseq_t *
+rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, const rb_iseq_t *parent)
{
return rb_iseq_new_with_opt(node, name, path, absolute_path, INT2FIX(0), parent, ISEQ_TYPE_TOP,
&COMPILE_OPTION_DEFAULT);
}
-VALUE
+rb_iseq_t *
rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path)
{
rb_thread_t *th = GET_THREAD();
- VALUE parent = th->base_block->iseq->self;
+ const rb_iseq_t *parent = th->base_block->iseq;
return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), path, absolute_path, INT2FIX(0),
parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
}
-VALUE
+rb_iseq_t *
rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE path, VALUE absolute_path,
- VALUE first_lineno, VALUE parent, enum iseq_type type,
- const rb_compile_option_t *option)
+ 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;
- VALUE self = iseq_alloc(rb_cISeq);
-
- GetISeqPtr(self, iseq);
- iseq->self = self;
+ rb_iseq_t *iseq = iseq_alloc();
if (!option) option = &COMPILE_OPTION_DEFAULT;
- prepare_iseq_build(iseq, name, path, absolute_path, first_lineno, parent,
- type, option);
+ prepare_iseq_build(iseq, name, path, absolute_path, first_lineno, parent, type, option);
- rb_iseq_compile_node(self, node);
+ rb_iseq_compile_node(iseq, node);
cleanup_iseq_build(iseq);
- return self;
+
+ return iseq;
}
#define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
@@ -457,17 +445,18 @@ iseq_type_from_sym(VALUE type)
return (enum iseq_type)-1;
}
+static VALUE iseqw_new(const rb_iseq_t *iseq);
+
static VALUE
-iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
+iseq_load(VALUE data, const rb_iseq_t *parent, VALUE opt)
{
- VALUE iseqval = iseq_alloc(self);
+ rb_iseq_t *iseq = iseq_alloc();
VALUE magic, version1, version2, format_type, misc;
VALUE name, path, absolute_path, first_lineno;
VALUE type, body, locals, params, exception;
st_data_t iseq_type;
- rb_iseq_t *iseq;
rb_compile_option_t option;
int i = 0;
@@ -497,28 +486,22 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
exception = CHECK_ARRAY(rb_ary_entry(data, i++));
body = CHECK_ARRAY(rb_ary_entry(data, i++));
- GetISeqPtr(iseqval, iseq);
- iseq->self = iseqval;
- iseq->local_iseq = iseq;
+ iseq->body->local_iseq = iseq;
iseq_type = iseq_type_from_sym(type);
if (iseq_type == (enum iseq_type)-1) {
rb_raise(rb_eTypeError, "unsupport type: :%"PRIsVALUE, rb_sym2str(type));
}
- if (parent == Qnil) {
- parent = 0;
- }
-
make_compile_option(&option, opt);
-
prepare_iseq_build(iseq, name, path, absolute_path, first_lineno,
parent, (enum iseq_type)iseq_type, &option);
rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body);
cleanup_iseq_build(iseq);
- return iseqval;
+
+ return iseqw_new(iseq);
}
/*
@@ -530,22 +513,22 @@ iseq_s_load(int argc, VALUE *argv, VALUE self)
VALUE data, opt=Qnil;
rb_scan_args(argc, argv, "11", &data, &opt);
- return iseq_load(self, data, 0, opt);
+ return iseq_load(data, NULL, opt);
}
VALUE
rb_iseq_load(VALUE data, VALUE parent, VALUE opt)
{
- return iseq_load(rb_cISeq, data, parent, opt);
+ return iseq_load(data, RTEST(parent) ? (rb_iseq_t *)parent : NULL, opt);
}
-VALUE
+rb_iseq_t *
rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt)
{
int state;
rb_thread_t *th = GET_THREAD();
rb_block_t *prev_base_block = th->base_block;
- VALUE iseqval = Qundef;
+ rb_iseq_t *iseq = NULL;
th->base_block = base_block;
@@ -573,13 +556,13 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE li
}
if (base_block && base_block->iseq) {
- iseqval = rb_iseq_new_with_opt(node, base_block->iseq->location.label,
- file, absolute_path, line, base_block->iseq->self,
- ISEQ_TYPE_EVAL, &option);
+ iseq = rb_iseq_new_with_opt(node, base_block->iseq->body->location.label,
+ file, absolute_path, line, base_block->iseq,
+ ISEQ_TYPE_EVAL, &option);
}
else {
- iseqval = rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, absolute_path, line, Qfalse,
- ISEQ_TYPE_TOP, &option);
+ iseq = rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, absolute_path, line,
+ NULL, ISEQ_TYPE_TOP, &option);
}
}
TH_POP_TAG();
@@ -590,21 +573,82 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE li
JUMP_TAG(state);
}
- return iseqval;
+ return iseq;
}
-VALUE
+rb_iseq_t *
rb_iseq_compile(VALUE src, VALUE file, VALUE line)
{
return rb_iseq_compile_with_option(src, file, Qnil, line, 0, Qnil);
}
-VALUE
+rb_iseq_t *
rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_block)
{
return rb_iseq_compile_with_option(src, file, Qnil, line, base_block, Qnil);
}
+VALUE
+rb_iseq_path(const rb_iseq_t *iseq)
+{
+ return iseq->body->location.path;
+}
+
+VALUE
+rb_iseq_absolute_path(const rb_iseq_t *iseq)
+{
+ return iseq->body->location.absolute_path;
+}
+
+VALUE
+rb_iseq_label(const rb_iseq_t *iseq)
+{
+ return iseq->body->location.label;
+}
+
+VALUE
+rb_iseq_base_label(const rb_iseq_t *iseq)
+{
+ return iseq->body->location.base_label;
+}
+
+VALUE
+rb_iseq_first_lineno(const rb_iseq_t *iseq)
+{
+ return iseq->body->location.first_lineno;
+}
+
+VALUE
+rb_iseq_method_name(const rb_iseq_t *iseq)
+{
+ const rb_iseq_t *local_iseq;
+
+ local_iseq = iseq->body->local_iseq;
+
+ if (local_iseq->body->type == ISEQ_TYPE_METHOD) {
+ return local_iseq->body->location.base_label;
+ }
+ else {
+ return Qnil;
+ }
+}
+
+/* define wrapper class methods (RubyVM::InstructionSequence) */
+
+static VALUE
+iseqw_new(const rb_iseq_t *iseq)
+{
+ VALUE iseqw = rb_obj_alloc(rb_cISeq);
+ rb_ivar_set(iseqw, iseqw_iseq_key, (VALUE)iseq);
+ return iseqw;
+}
+
+VALUE
+rb_iseqw_new(const rb_iseq_t *iseq)
+{
+ return iseqw_new(iseq);
+}
+
/*
* call-seq:
* InstructionSequence.compile(source[, file[, path[, line[, options]]]]) -> iseq
@@ -627,17 +671,16 @@ rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_bloc
*
*/
static VALUE
-iseq_s_compile(int argc, VALUE *argv, VALUE self)
+iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
-
rb_secure(1);
rb_scan_args(argc, argv, "14", &src, &file, &path, &line, &opt);
if (NIL_P(file)) file = rb_str_new2("<compiled>");
if (NIL_P(line)) line = INT2FIX(1);
- return rb_iseq_compile_with_option(src, file, path, line, 0, opt);
+ return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, 0, opt));
}
/*
@@ -661,7 +704,7 @@ iseq_s_compile(int argc, VALUE *argv, VALUE self)
* #=> <RubyVM::InstructionSequence:<main>@/tmp/hello.rb>
*/
static VALUE
-iseq_s_compile_file(int argc, VALUE *argv, VALUE self)
+iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
{
VALUE file, line = INT2FIX(1), opt = Qnil;
VALUE parser;
@@ -683,9 +726,10 @@ iseq_s_compile_file(int argc, VALUE *argv, VALUE self)
rb_io_close(f);
make_compile_option(&option, opt);
- return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file,
- rb_realpath_internal(Qnil, file, 1), line, Qfalse,
- ISEQ_TYPE_TOP, &option);
+
+ return iseqw_new(rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file,
+ rb_realpath_internal(Qnil, file, 1), line, NULL,
+ ISEQ_TYPE_TOP, &option));
}
/*
@@ -721,7 +765,7 @@ iseq_s_compile_file(int argc, VALUE *argv, VALUE self)
* ::new, ::compile and ::compile_file.
*/
static VALUE
-iseq_s_compile_option_set(VALUE self, VALUE opt)
+iseqw_s_compile_option_set(VALUE self, VALUE opt)
{
rb_compile_option_t option;
rb_secure(1);
@@ -739,22 +783,28 @@ iseq_s_compile_option_set(VALUE self, VALUE opt)
* For details, see InstructionSequence.compile_option=.
*/
static VALUE
-iseq_s_compile_option_get(VALUE self)
+iseqw_s_compile_option_get(VALUE self)
{
return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
}
-static rb_iseq_t *
-iseq_check(VALUE val)
+static const rb_iseq_t *
+iseqw_check(VALUE iseqw)
{
- rb_iseq_t *iseq;
- GetISeqPtr(val, iseq);
- if (!iseq->location.label) {
+ const rb_iseq_t *iseq = (rb_iseq_t *)rb_ivar_get(iseqw, iseqw_iseq_key);
+
+ if (!iseq->body->location.label) {
rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
}
return iseq;
}
+const rb_iseq_t *
+rb_iseqw_to_iseq(VALUE iseqw)
+{
+ return iseqw_check(iseqw);
+}
+
/*
* call-seq:
* iseq.eval -> obj
@@ -764,10 +814,10 @@ iseq_check(VALUE val)
* RubyVM::InstructionSequence.compile("1 + 2").eval #=> 3
*/
static VALUE
-iseq_eval(VALUE self)
+iseqw_eval(VALUE self)
{
rb_secure(1);
- return rb_iseq_eval(self);
+ return rb_iseq_eval(iseqw_check(self));
}
/*
@@ -775,17 +825,18 @@ iseq_eval(VALUE self)
* sequence, including the #label and #path.
*/
static VALUE
-iseq_inspect(VALUE self)
+iseqw_inspect(VALUE self)
{
- rb_iseq_t *iseq;
- GetISeqPtr(self, iseq);
- if (!iseq->location.label) {
+ const rb_iseq_t *iseq = iseqw_check(self);
+
+ if (!iseq->body->location.label) {
return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
}
-
- return rb_sprintf("<%s:%s@%s>",
- rb_obj_classname(self),
- RSTRING_PTR(iseq->location.label), RSTRING_PTR(iseq->location.path));
+ else {
+ return rb_sprintf("<%s:%s@%s>",
+ rb_obj_classname(self),
+ RSTRING_PTR(iseq->body->location.label), RSTRING_PTR(iseq->body->location.path));
+ }
}
/*
@@ -811,12 +862,10 @@ iseq_inspect(VALUE self)
* > iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
* > iseq.path #=> /tmp/method.rb
*/
-VALUE
-rb_iseq_path(VALUE self)
+static VALUE
+iseqw_path(VALUE self)
{
- rb_iseq_t *iseq;
- GetISeqPtr(self, iseq);
- return iseq->location.path;
+ return rb_iseq_path(iseqw_check(self));
}
/*
@@ -835,12 +884,10 @@ rb_iseq_path(VALUE self)
* > iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
* > iseq.absolute_path #=> /tmp/method.rb
*/
-VALUE
-rb_iseq_absolute_path(VALUE self)
+static VALUE
+iseqw_absolute_path(VALUE self)
{
- rb_iseq_t *iseq;
- GetISeqPtr(self, iseq);
- return iseq->location.absolute_path;
+ return rb_iseq_absolute_path(iseqw_check(self));
}
/* Returns the label of this instruction sequence.
@@ -867,11 +914,9 @@ rb_iseq_absolute_path(VALUE self)
* > iseq.label #=> <main>
*/
VALUE
-rb_iseq_label(VALUE self)
+iseqw_label(VALUE self)
{
- rb_iseq_t *iseq;
- GetISeqPtr(self, iseq);
- return iseq->location.label;
+ return rb_iseq_label(iseqw_check(self));
}
/* Returns the base label of this instruction sequence.
@@ -894,12 +939,10 @@ rb_iseq_label(VALUE self)
* > iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
* > iseq.base_label #=> <main>
*/
-VALUE
-rb_iseq_base_label(VALUE self)
+static VALUE
+iseqw_base_label(VALUE self)
{
- rb_iseq_t *iseq;
- GetISeqPtr(self, iseq);
- return iseq->location.base_label;
+ return rb_iseq_base_label(iseqw_check(self));
}
/* Returns the number of the first source line where the instruction sequence
@@ -913,25 +956,9 @@ rb_iseq_base_label(VALUE self)
* #=> 1
*/
VALUE
-rb_iseq_first_lineno(VALUE self)
+iseqw_first_lineno(VALUE self)
{
- const rb_iseq_t *iseq;
- GetISeqPtr(self, iseq);
- return iseq->location.first_lineno;
-}
-
-VALUE
-rb_iseq_method_name(VALUE self)
-{
- const rb_iseq_t *iseq, *local_iseq;
- GetISeqPtr(self, iseq);
- local_iseq = iseq->local_iseq;
- if (local_iseq->type == ISEQ_TYPE_METHOD) {
- return local_iseq->location.base_label;
- }
- else {
- return Qnil;
- }
+ return rb_iseq_first_lineno(iseqw_check(self));
}
static VALUE iseq_data_to_ary(const rb_iseq_t *iseq);
@@ -1018,9 +1045,9 @@ static VALUE iseq_data_to_ary(const rb_iseq_t *iseq);
*
*/
static VALUE
-iseq_to_a(VALUE self)
+iseqw_to_a(VALUE self)
{
- rb_iseq_t *iseq = iseq_check(self);
+ const rb_iseq_t *iseq = iseqw_check(self);
rb_secure(1);
return iseq_data_to_ary(iseq);
}
@@ -1031,8 +1058,8 @@ iseq_to_a(VALUE self)
static struct iseq_line_info_entry *
get_line_info(const rb_iseq_t *iseq, size_t pos)
{
- size_t i = 0, size = iseq->line_info_size;
- struct iseq_line_info_entry *table = iseq->line_info_table;
+ size_t i = 0, size = iseq->body->line_info_size;
+ struct iseq_line_info_entry *table = iseq->body->line_info_table;
const int debug = 0;
if (debug) {
@@ -1124,9 +1151,9 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
VALUE level = *pnop, i;
for (i = 0; i < level; i++) {
- diseq = diseq->parent_iseq;
+ diseq = diseq->body->parent_iseq;
}
- ret = id_to_name(diseq->local_table[diseq->local_size - op], INT2FIX('*'));
+ ret = id_to_name(diseq->body->local_table[diseq->body->local_size - op], INT2FIX('*'));
}
else {
ret = rb_sprintf("%"PRIuVALUE, op);
@@ -1154,9 +1181,9 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
{
rb_iseq_t *iseq = (rb_iseq_t *)op;
if (iseq) {
- ret = iseq->location.label;
+ ret = iseq->body->location.label;
if (child) {
- rb_ary_push(child, iseq->self);
+ rb_ary_push(child, (VALUE)iseq);
}
}
else {
@@ -1172,7 +1199,7 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
break;
case TS_IC:
- ret = rb_sprintf("<is:%"PRIdPTRDIFF">", (union iseq_inline_storage_entry *)op - iseq->is_entries);
+ ret = rb_sprintf("<is:%"PRIdPTRDIFF">", (union iseq_inline_storage_entry *)op - iseq->body->is_entries);
break;
case TS_CALLINFO:
@@ -1191,9 +1218,9 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
}
if (ci->blockiseq) {
if (child) {
- rb_ary_push(child, ci->blockiseq->self);
+ rb_ary_push(child, (VALUE)ci->blockiseq);
}
- rb_ary_push(ary, rb_sprintf("block:%"PRIsVALUE, ci->blockiseq->location.label));
+ rb_ary_push(ary, rb_sprintf("block:%"PRIsVALUE, ci->blockiseq->body->location.label));
}
if (ci->flag) {
@@ -1313,31 +1340,23 @@ catch_type(int type)
}
}
-/*
- * call-seq:
- * iseq.disasm -> str
- * iseq.disassemble -> str
- *
- * Returns the instruction sequence as a +String+ in human readable form.
- *
- * puts RubyVM::InstructionSequence.compile('1 + 2').disasm
- *
- * Produces:
- *
- * == disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
- * 0000 trace 1 ( 1)
- * 0002 putobject 1
- * 0004 putobject 2
- * 0006 opt_plus <ic:1>
- * 0008 leave
- */
+static VALUE
+iseq_inspect(const rb_iseq_t *iseq)
+{
+ if (!iseq->body->location.label) {
+ return rb_sprintf("#<ISeq: uninitialized>");
+ }
+ else {
+ return rb_sprintf("#<ISeq:%s@%s>", RSTRING_PTR(iseq->body->location.label), RSTRING_PTR(iseq->body->location.path));
+ }
+}
+
VALUE
-rb_iseq_disasm(VALUE self)
+rb_iseq_disasm(const rb_iseq_t *iseq)
{
- rb_iseq_t *iseq = iseq_check(self); /* TODO: rename to iseq */
VALUE *code;
VALUE str = rb_str_new(0, 0);
- VALUE child = rb_ary_new();
+ VALUE child = rb_ary_tmp_new(3);
unsigned int size;
int i;
long l;
@@ -1347,11 +1366,11 @@ rb_iseq_disasm(VALUE self)
rb_secure(1);
- size = iseq->iseq_size;
+ size = iseq->body->iseq_size;
rb_str_cat2(str, "== disasm: ");
- rb_str_concat(str, iseq_inspect(iseq->self));
+ rb_str_concat(str, iseq_inspect(iseq));
if ((l = RSTRING_LEN(str)) < header_minlen) {
rb_str_resize(str, header_minlen);
memset(RSTRING_PTR(str) + l, '=', header_minlen - l);
@@ -1359,11 +1378,11 @@ rb_iseq_disasm(VALUE self)
rb_str_cat2(str, "\n");
/* show catch table information */
- if (iseq->catch_table) {
+ if (iseq->body->catch_table) {
rb_str_cat2(str, "== catch table\n");
}
- if (iseq->catch_table) for (i = 0; i < iseq->catch_table->size; i++) {
- struct iseq_catch_table_entry *entry = &iseq->catch_table->entries[i];
+ if (iseq->body->catch_table) for (i = 0; i < iseq->body->catch_table->size; i++) {
+ struct iseq_catch_table_entry *entry = &iseq->body->catch_table->entries[i];
rb_str_catf(str,
"| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
catch_type((int)entry->type), (int)entry->start,
@@ -1372,51 +1391,51 @@ rb_iseq_disasm(VALUE self)
rb_str_concat(str, rb_iseq_disasm(entry->iseq));
}
}
- if (iseq->catch_table) {
+ if (iseq->body->catch_table) {
rb_str_cat2(str, "|-------------------------------------"
"-----------------------------------\n");
}
/* show local table information */
- tbl = iseq->local_table;
+ tbl = iseq->body->local_table;
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])\n",
- iseq->local_size,
- iseq->param.lead_num,
- iseq->param.opt_num,
- iseq->param.flags.has_rest ? iseq->param.rest_start : -1,
- iseq->param.post_num,
- iseq->param.flags.has_block ? iseq->param.block_start : -1,
- iseq->param.flags.has_kw ? iseq->param.keyword->num : -1,
- iseq->param.flags.has_kw ? iseq->param.keyword->required_num : -1,
- iseq->param.flags.has_kwrest ? iseq->param.keyword->rest_start : -1);
-
- for (i = 0; i < iseq->local_table_size; i++) {
+ iseq->body->local_size,
+ iseq->body->param.lead_num,
+ iseq->body->param.opt_num,
+ iseq->body->param.flags.has_rest ? iseq->body->param.rest_start : -1,
+ iseq->body->param.post_num,
+ iseq->body->param.flags.has_block ? iseq->body->param.block_start : -1,
+ iseq->body->param.flags.has_kw ? iseq->body->param.keyword->num : -1,
+ iseq->body->param.flags.has_kw ? iseq->body->param.keyword->required_num : -1,
+ iseq->body->param.flags.has_kwrest ? iseq->body->param.keyword->rest_start : -1);
+
+ for (i = 0; i < iseq->body->local_table_size; i++) {
long width;
VALUE name = id_to_name(tbl[i], 0);
char argi[0x100] = "";
char opti[0x100] = "";
- if (iseq->param.flags.has_opt) {
- int argc = iseq->param.lead_num;
- int opts = iseq->param.opt_num;
+ if (iseq->body->param.flags.has_opt) {
+ int argc = iseq->body->param.lead_num;
+ int opts = iseq->body->param.opt_num;
if (i >= argc && i < argc + opts) {
snprintf(opti, sizeof(opti), "Opt=%"PRIdVALUE,
- iseq->param.opt_table[i - argc]);
+ iseq->body->param.opt_table[i - argc]);
}
}
snprintf(argi, sizeof(argi), "%s%s%s%s%s", /* arg, opts, rest, post block */
- iseq->param.lead_num > i ? "Arg" : "",
+ iseq->body->param.lead_num > i ? "Arg" : "",
opti,
- (iseq->param.flags.has_rest && iseq->param.rest_start == i) ? "Rest" : "",
- (iseq->param.flags.has_post && iseq->param.post_start <= i && i < iseq->param.post_start + iseq->param.post_num) ? "Post" : "",
- (iseq->param.flags.has_block && iseq->param.block_start == i) ? "Block" : "");
+ (iseq->body->param.flags.has_rest && iseq->body->param.rest_start == i) ? "Rest" : "",
+ (iseq->body->param.flags.has_post && iseq->body->param.post_start <= i && i < iseq->body->param.post_start + iseq->body->param.post_num) ? "Post" : "",
+ (iseq->body->param.flags.has_block && iseq->body->param.block_start == i) ? "Block" : "");
- rb_str_catf(str, "[%2d] ", iseq->local_size - i);
+ rb_str_catf(str, "[%2d] ", iseq->body->local_size - i);
width = RSTRING_LEN(str) + 11;
if (name)
rb_str_append(str, name);
@@ -1436,13 +1455,37 @@ rb_iseq_disasm(VALUE self)
for (i = 0; i < RARRAY_LEN(child); i++) {
VALUE isv = rb_ary_entry(child, i);
- rb_str_concat(str, rb_iseq_disasm(isv));
+ rb_str_concat(str, rb_iseq_disasm((rb_iseq_t *)isv));
}
return str;
}
/*
+ * call-seq:
+ * iseq.disasm -> str
+ * iseq.disassemble -> str
+ *
+ * Returns the instruction sequence as a +String+ in human readable form.
+ *
+ * puts RubyVM::InstructionSequence.compile('1 + 2').disasm
+ *
+ * Produces:
+ *
+ * == disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
+ * 0000 trace 1 ( 1)
+ * 0002 putobject 1
+ * 0004 putobject 2
+ * 0006 opt_plus <ic:1>
+ * 0008 leave
+ */
+static VALUE
+iseqw_disasm(VALUE self)
+{
+ return rb_iseq_disasm(iseqw_check(self));
+}
+
+/*
* Returns the instruction sequence containing the given proc or method.
*
* For example, using irb:
@@ -1478,10 +1521,9 @@ rb_iseq_disasm(VALUE self)
* > #=> #<RubyVM::InstructionSequence:0x007fb73d7caf78>
*/
static VALUE
-iseq_s_of(VALUE klass, VALUE body)
+iseqw_s_of(VALUE klass, VALUE body)
{
- VALUE ret = Qnil;
- const rb_iseq_t *iseq;
+ const rb_iseq_t *iseq = NULL;
rb_secure(1);
@@ -1489,14 +1531,16 @@ iseq_s_of(VALUE klass, VALUE body)
rb_proc_t *proc;
GetProcPtr(body, proc);
iseq = proc->block.iseq;
- if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
- ret = iseq->self;
+
+ if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) {
+ iseq = NULL;
}
}
- else if ((iseq = rb_method_iseq(body)) != 0) {
- ret = iseq->self;
+ else {
+ iseq = rb_method_iseq(body);
}
- return ret;
+
+ return iseq ? iseqw_new(iseq) : Qnil;
}
/*
@@ -1551,12 +1595,11 @@ iseq_s_of(VALUE klass, VALUE body)
* 0012 leave
*
*/
-
static VALUE
-iseq_s_disasm(VALUE klass, VALUE body)
+iseqw_s_disasm(VALUE klass, VALUE body)
{
- VALUE iseqval = iseq_s_of(klass, body);
- return NIL_P(iseqval) ? Qnil : rb_iseq_disasm(iseqval);
+ VALUE iseqw = iseqw_s_of(klass, body);
+ return NIL_P(iseqw) ? Qnil : rb_iseq_disasm(iseqw_check(iseqw));
}
const char *
@@ -1657,7 +1700,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
}
/* type */
- switch (iseq->type) {
+ switch (iseq->body->type) {
case ISEQ_TYPE_TOP: type = sym_top; break;
case ISEQ_TYPE_METHOD: type = sym_method; break;
case ISEQ_TYPE_BLOCK: type = sym_block; break;
@@ -1671,14 +1714,14 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
};
/* locals */
- for (i=0; i<iseq->local_table_size; i++) {
- ID lid = iseq->local_table[i];
+ for (i=0; i<iseq->body->local_table_size; i++) {
+ ID lid = iseq->body->local_table[i];
if (lid) {
if (rb_id2str(lid)) {
rb_ary_push(locals, ID2SYM(lid));
}
else { /* hidden variable from id_internal() */
- rb_ary_push(locals, ULONG2NUM(iseq->local_table_size-i+1));
+ rb_ary_push(locals, ULONG2NUM(iseq->body->local_table_size-i+1));
}
}
else {
@@ -1690,49 +1733,49 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
{
int j;
- if (iseq->param.flags.has_opt) {
- int len = iseq->param.opt_num + 1;
+ if (iseq->body->param.flags.has_opt) {
+ int len = iseq->body->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]);
+ VALUE l = register_label(labels_table, iseq->body->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_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) {
+ if (iseq->body->param.flags.has_lead) rb_hash_aset(params, ID2SYM(rb_intern("lead_num")), INT2FIX(iseq->body->param.lead_num));
+ if (iseq->body->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_num")), INT2FIX(iseq->body->param.post_num));
+ if (iseq->body->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_start")), INT2FIX(iseq->body->param.post_start));
+ if (iseq->body->param.flags.has_rest) rb_hash_aset(params, ID2SYM(rb_intern("rest_start")), INT2FIX(iseq->body->param.rest_start));
+ if (iseq->body->param.flags.has_block) rb_hash_aset(params, ID2SYM(rb_intern("block_start")), INT2FIX(iseq->body->param.block_start));
+ if (iseq->body->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 (i=0; i<iseq->body->param.keyword->required_num; i++) {
+ rb_ary_push(keywords, ID2SYM(iseq->body->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]);
+ for (j=0; i<iseq->body->param.keyword->num; i++, j++) {
+ VALUE key = rb_ary_new_from_args(1, ID2SYM(iseq->body->param.keyword->table[i]));
+ if (iseq->body->param.keyword->default_values[j] != Qundef) {
+ rb_ary_push(key, iseq->body->param.keyword->default_values[j]);
}
rb_ary_push(keywords, key);
}
rb_hash_aset(params, ID2SYM(rb_intern("kwbits")),
- INT2FIX(iseq->param.keyword->bits_start));
+ INT2FIX(iseq->body->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));
- if (iseq->param.flags.ambiguous_param0) rb_hash_aset(params, ID2SYM(rb_intern("ambiguous_param0")), Qtrue);
+ if (iseq->body->param.flags.has_kwrest) rb_hash_aset(params, ID2SYM(rb_intern("kwrest")), INT2FIX(iseq->body->param.keyword->rest_start));
+ if (iseq->body->param.flags.ambiguous_param0) rb_hash_aset(params, ID2SYM(rb_intern("ambiguous_param0")), Qtrue);
}
/* body */
iseq_original = rb_iseq_original_iseq((rb_iseq_t *)iseq);
- for (seq = iseq_original; seq < iseq_original + iseq->iseq_size; ) {
+ for (seq = iseq_original; seq < iseq_original + iseq->body->iseq_size; ) {
VALUE insn = *seq++;
int j, len = insn_len(insn);
VALUE *nseq = seq + len - 1;
@@ -1774,7 +1817,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
case TS_IC:
{
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
- rb_ary_push(ary, INT2FIX(is - iseq->is_entries));
+ rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));
}
break;
case TS_CALLINFO:
@@ -1844,14 +1887,12 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
nbody = body;
/* exception */
- if (iseq->catch_table) for (i=0; i<iseq->catch_table->size; i++) {
+ if (iseq->body->catch_table) for (i=0; i<iseq->body->catch_table->size; i++) {
VALUE ary = rb_ary_new();
- struct iseq_catch_table_entry *entry = &iseq->catch_table->entries[i];
+ struct iseq_catch_table_entry *entry = &iseq->body->catch_table->entries[i];
rb_ary_push(ary, exception_type2symbol(entry->type));
if (entry->iseq) {
- rb_iseq_t *eiseq;
- GetISeqPtr(entry->iseq, eiseq);
- rb_ary_push(ary, iseq_data_to_ary(eiseq));
+ rb_ary_push(ary, iseq_data_to_ary(entry->iseq));
}
else {
rb_ary_push(ary, Qnil);
@@ -1875,8 +1916,8 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(body, (VALUE)label);
}
- if (ti < iseq->line_info_size && iseq->line_info_table[ti].position == pos) {
- line = iseq->line_info_table[ti].line_no;
+ if (ti < iseq->body->line_info_size && iseq->body->line_info_table[ti].position == pos) {
+ line = iseq->body->line_info_table[ti].line_no;
rb_ary_push(body, INT2FIX(line));
ti++;
}
@@ -1888,9 +1929,9 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
st_free_table(labels_table);
- 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));
+ rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->body->param.size));
+ rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->body->local_size));
+ rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->body->stack_max));
/* TODO: compatibility issue */
/*
@@ -1903,10 +1944,10 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(val, INT2FIX(ISEQ_MINOR_VERSION)); /* minor */
rb_ary_push(val, INT2FIX(1));
rb_ary_push(val, misc);
- rb_ary_push(val, iseq->location.label);
- rb_ary_push(val, iseq->location.path);
- rb_ary_push(val, iseq->location.absolute_path);
- rb_ary_push(val, iseq->location.first_lineno);
+ rb_ary_push(val, iseq->body->location.label);
+ rb_ary_push(val, iseq->body->location.path);
+ rb_ary_push(val, iseq->body->location.absolute_path);
+ rb_ary_push(val, iseq->body->location.first_lineno);
rb_ary_push(val, type);
rb_ary_push(val, locals);
rb_ary_push(val, params);
@@ -1919,10 +1960,10 @@ VALUE
rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
{
int i, r;
- VALUE a, args = rb_ary_new2(iseq->param.size);
+ VALUE a, args = rb_ary_new2(iseq->body->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)]
+#define PARAM_ID(i) iseq->body->local_table[(i)]
#define PARAM(i, type) ( \
PARAM_TYPE(type), \
rb_id2str(PARAM_ID(i)) ? \
@@ -1932,18 +1973,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->param.lead_num; i++) {
+ for (i = 0; i < iseq->body->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->param.lead_num; i++) {
+ for (i = 0; i < iseq->body->param.lead_num; i++) {
rb_ary_push(args, PARAM(i, req));
}
}
- r = iseq->param.lead_num + iseq->param.opt_num;
+ r = iseq->body->param.lead_num + iseq->body->param.opt_num;
for (; i < r; i++) {
PARAM_TYPE(opt);
if (rb_id2str(PARAM_ID(i))) {
@@ -1951,52 +1992,52 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
}
rb_ary_push(args, a);
}
- if (iseq->param.flags.has_rest) {
+ if (iseq->body->param.flags.has_rest) {
CONST_ID(rest, "rest");
- rb_ary_push(args, PARAM(iseq->param.rest_start, rest));
+ rb_ary_push(args, PARAM(iseq->body->param.rest_start, rest));
}
- r = iseq->param.post_start + iseq->param.post_num;
+ r = iseq->body->param.post_start + iseq->body->param.post_num;
if (is_proc) {
- for (i = iseq->param.post_start; i < r; i++) {
+ for (i = iseq->body->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->param.post_start; i < r; i++) {
+ for (i = iseq->body->param.post_start; i < r; i++) {
rb_ary_push(args, PARAM(i, req));
}
}
- if (iseq->param.flags.has_kw) {
+ if (iseq->body->param.flags.has_kw) {
i = 0;
- if (iseq->param.keyword->required_num > 0) {
+ if (iseq->body->param.keyword->required_num > 0) {
ID keyreq;
CONST_ID(keyreq, "keyreq");
- for (; i < iseq->param.keyword->required_num; i++) {
+ for (; i < iseq->body->param.keyword->required_num; i++) {
PARAM_TYPE(keyreq);
- if (rb_id2str(iseq->param.keyword->table[i])) {
- rb_ary_push(a, ID2SYM(iseq->param.keyword->table[i]));
+ if (rb_id2str(iseq->body->param.keyword->table[i])) {
+ rb_ary_push(a, ID2SYM(iseq->body->param.keyword->table[i]));
}
rb_ary_push(args, a);
}
}
CONST_ID(key, "key");
- for (; i < iseq->param.keyword->num; i++) {
+ for (; i < iseq->body->param.keyword->num; i++) {
PARAM_TYPE(key);
- if (rb_id2str(iseq->param.keyword->table[i])) {
- rb_ary_push(a, ID2SYM(iseq->param.keyword->table[i]));
+ if (rb_id2str(iseq->body->param.keyword->table[i])) {
+ rb_ary_push(a, ID2SYM(iseq->body->param.keyword->table[i]));
}
rb_ary_push(args, a);
}
}
- if (iseq->param.flags.has_kwrest) {
+ if (iseq->body->param.flags.has_kwrest) {
CONST_ID(keyrest, "keyrest");
- rb_ary_push(args, PARAM(iseq->param.keyword->rest_start, keyrest));
+ rb_ary_push(args, PARAM(iseq->body->param.keyword->rest_start, keyrest));
}
- if (iseq->param.flags.has_block) {
+ if (iseq->body->param.flags.has_block) {
CONST_ID(block, "block");
- rb_ary_push(args, PARAM(iseq->param.block_start, block));
+ rb_ary_push(args, PARAM(iseq->body->param.block_start, block));
}
return args;
}
@@ -2041,85 +2082,22 @@ rb_iseq_defined_string(enum defined_type type)
return str;
}
-/* ruby2cext */
-
-VALUE
-rb_iseq_build_for_ruby2cext(
- const rb_iseq_t *iseq_template,
- const rb_insn_func_t *func,
- const struct iseq_line_info_entry *line_info_table,
- const char **local_table,
- const VALUE *arg_opt_table,
- const struct iseq_catch_table_entry *catch_table,
- const char *name,
- const char *path,
- const unsigned short first_lineno)
-{
- unsigned long i;
- VALUE iseqval = iseq_alloc(rb_cISeq);
- rb_iseq_t *iseq;
- GetISeqPtr(iseqval, iseq);
-
- /* copy iseq */
- MEMCPY(iseq, iseq_template, rb_iseq_t, 1); /* TODO: write barrier, *iseq = *iseq_template; */
- RB_OBJ_WRITE(iseq->self, &iseq->location.label, rb_str_new2(name));
- RB_OBJ_WRITE(iseq->self, &iseq->location.path, rb_str_new2(path));
- iseq->location.first_lineno = UINT2NUM(first_lineno);
- RB_OBJ_WRITE(iseq->self, &iseq->mark_ary, 0);
- iseq->self = iseqval;
-
- iseq->iseq_encoded = ALLOC_N(VALUE, iseq->iseq_size);
-
- for (i=0; i<iseq->iseq_size; i+=2) {
- iseq->iseq_encoded[i] = BIN(opt_call_c_function);
- iseq->iseq_encoded[i+1] = (VALUE)func;
- }
-
- rb_iseq_translate_threaded_code(iseq);
-
-#define ALLOC_AND_COPY(dst, src, type, size) do { \
- if (size) { \
- (dst) = ALLOC_N(type, (size)); \
- MEMCPY((dst), (src), type, (size)); \
- } \
-} while (0)
-
- ALLOC_AND_COPY(iseq->line_info_table, line_info_table,
- struct iseq_line_info_entry, iseq->line_info_size);
-
- /*
- * FIXME: probably broken, but this function is probably unused
- * and should be removed
- */
- if (iseq->catch_table) {
- MEMCPY(&iseq->catch_table->entries, catch_table,
- struct iseq_catch_table_entry, iseq->catch_table->size);
- }
-
- ALLOC_AND_COPY(iseq->param.opt_table, arg_opt_table, VALUE, iseq->param.opt_num + 1);
-
- set_relation(iseq, 0);
-
- return iseqval;
-}
-
/* Experimental tracing support: trace(line) -> trace(specified_line)
* MRI Specific.
*/
int
-rb_iseq_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data)
+rb_iseqw_line_trace_each(VALUE iseqw, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data)
{
int trace_num = 0;
unsigned int pos;
size_t insn;
- rb_iseq_t *iseq;
+ const rb_iseq_t *iseq = iseqw_check(iseqw);
int cont = 1;
VALUE *iseq_original;
- GetISeqPtr(iseqval, iseq);
iseq_original = rb_iseq_original_iseq(iseq);
- for (pos = 0; cont && pos < iseq->iseq_size; pos += insn_len(insn)) {
+ for (pos = 0; cont && pos < iseq->body->iseq_size; pos += insn_len(insn)) {
insn = iseq_original[pos];
if (insn == BIN(trace)) {
@@ -2136,7 +2114,7 @@ rb_iseq_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *ev
/* printf("line: %d\n", line); */
cont = (*func)(line, &events, data);
if (current_events != events) {
- iseq_original[pos+1] = iseq->iseq_encoded[pos+1] =
+ iseq_original[pos+1] = iseq->body->iseq_encoded[pos+1] =
(VALUE)(current_events | (events & RUBY_EVENT_SPECIFIED_LINE));
}
}
@@ -2160,10 +2138,10 @@ collect_trace(int line, rb_event_flag_t *events_ptr, void *ptr)
* Returns all +specified_line+ events.
*/
VALUE
-rb_iseq_line_trace_all(VALUE iseqval)
+rb_iseqw_line_trace_all(VALUE iseqw)
{
VALUE result = rb_ary_new();
- rb_iseq_line_trace_each(iseqval, collect_trace, (void *)result);
+ rb_iseqw_line_trace_each(iseqw, collect_trace, (void *)result);
return result;
}
@@ -2207,7 +2185,7 @@ line_trace_specify(int line, rb_event_flag_t *events_ptr, void *ptr)
* If +pos+ is a negative integer a TypeError exception is raised.
*/
VALUE
-rb_iseq_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set)
+rb_iseqw_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set)
{
struct set_specifc_data data;
@@ -2222,7 +2200,7 @@ rb_iseq_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set)
rb_raise(rb_eTypeError, "`set' should be true/false");
}
- rb_iseq_line_trace_each(iseqval, line_trace_specify, (void *)&data);
+ rb_iseqw_line_trace_each(iseqval, line_trace_specify, (void *)&data);
if (data.prev == 0) {
rb_raise(rb_eTypeError, "`pos' is out of range.");
@@ -2255,45 +2233,45 @@ Init_ISeq(void)
{
/* declare ::RubyVM::InstructionSequence */
rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject);
- rb_define_alloc_func(rb_cISeq, iseq_alloc);
- rb_define_method(rb_cISeq, "inspect", iseq_inspect, 0);
- rb_define_method(rb_cISeq, "disasm", rb_iseq_disasm, 0);
- rb_define_method(rb_cISeq, "disassemble", rb_iseq_disasm, 0);
- rb_define_method(rb_cISeq, "to_a", iseq_to_a, 0);
- rb_define_method(rb_cISeq, "eval", iseq_eval, 0);
+ rb_define_method(rb_cISeq, "inspect", iseqw_inspect, 0);
+ rb_define_method(rb_cISeq, "disasm", iseqw_disasm, 0);
+ rb_define_method(rb_cISeq, "disassemble", iseqw_disasm, 0);
+ rb_define_method(rb_cISeq, "to_a", iseqw_to_a, 0);
+ rb_define_method(rb_cISeq, "eval", iseqw_eval, 0);
/* location APIs */
- rb_define_method(rb_cISeq, "path", rb_iseq_path, 0);
- rb_define_method(rb_cISeq, "absolute_path", rb_iseq_absolute_path, 0);
- rb_define_method(rb_cISeq, "label", rb_iseq_label, 0);
- rb_define_method(rb_cISeq, "base_label", rb_iseq_base_label, 0);
- rb_define_method(rb_cISeq, "first_lineno", rb_iseq_first_lineno, 0);
+ rb_define_method(rb_cISeq, "path", iseqw_path, 0);
+ rb_define_method(rb_cISeq, "absolute_path", iseqw_absolute_path, 0);
+ rb_define_method(rb_cISeq, "label", iseqw_label, 0);
+ rb_define_method(rb_cISeq, "base_label", iseqw_base_label, 0);
+ rb_define_method(rb_cISeq, "first_lineno", iseqw_first_lineno, 0);
#if 0
/* Now, it is experimental. No discussions, no tests. */
/* They can be used from C level. Please give us feedback. */
- rb_define_method(rb_cISeq, "line_trace_all", rb_iseq_line_trace_all, 0);
- rb_define_method(rb_cISeq, "line_trace_specify", rb_iseq_line_trace_specify, 2);
+ rb_define_method(rb_cISeq, "line_trace_all", rb_iseqw_line_trace_all, 0);
+ rb_define_method(rb_cISeq, "line_trace_specify", rb_iseqw_line_trace_specify, 2);
#else
- (void)rb_iseq_line_trace_all;
- (void)rb_iseq_line_trace_specify;
+ (void)rb_iseqw_line_trace_all;
+ (void)rb_iseqw_line_trace_specify;
#endif
#if 0 /* TBD */
- rb_define_private_method(rb_cISeq, "marshal_dump", iseq_marshal_dump, 0);
- rb_define_private_method(rb_cISeq, "marshal_load", iseq_marshal_load, 1);
+ rb_define_private_method(rb_cISeq, "marshal_dump", iseqw_marshal_dump, 0);
+ rb_define_private_method(rb_cISeq, "marshal_load", iseqw_marshal_load, 1);
#endif
-
/* disable this feature because there is no verifier. */
/* rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); */
(void)iseq_s_load;
- rb_define_singleton_method(rb_cISeq, "compile", iseq_s_compile, -1);
- rb_define_singleton_method(rb_cISeq, "new", iseq_s_compile, -1);
- rb_define_singleton_method(rb_cISeq, "compile_file", iseq_s_compile_file, -1);
- rb_define_singleton_method(rb_cISeq, "compile_option", iseq_s_compile_option_get, 0);
- rb_define_singleton_method(rb_cISeq, "compile_option=", iseq_s_compile_option_set, 1);
- rb_define_singleton_method(rb_cISeq, "disasm", iseq_s_disasm, 1);
- rb_define_singleton_method(rb_cISeq, "disassemble", iseq_s_disasm, 1);
- rb_define_singleton_method(rb_cISeq, "of", iseq_s_of, 1);
+ rb_define_singleton_method(rb_cISeq, "compile", iseqw_s_compile, -1);
+ rb_define_singleton_method(rb_cISeq, "new", iseqw_s_compile, -1);
+ rb_define_singleton_method(rb_cISeq, "compile_file", iseqw_s_compile_file, -1);
+ rb_define_singleton_method(rb_cISeq, "compile_option", iseqw_s_compile_option_get, 0);
+ rb_define_singleton_method(rb_cISeq, "compile_option=", iseqw_s_compile_option_set, 1);
+ rb_define_singleton_method(rb_cISeq, "disasm", iseqw_s_disasm, 1);
+ rb_define_singleton_method(rb_cISeq, "disassemble", iseqw_s_disasm, 1);
+ rb_define_singleton_method(rb_cISeq, "of", iseqw_s_of, 1);
+
+ iseqw_iseq_key = rb_intern("T_IMEMO/iseq");
}
diff --git a/iseq.h b/iseq.h
index 487b703c80..2db95e2983 100644
--- a/iseq.h
+++ b/iseq.h
@@ -15,12 +15,12 @@
RUBY_SYMBOL_EXPORT_BEGIN
/* compile.c */
-VALUE rb_iseq_compile_node(VALUE self, NODE *node);
+VALUE rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node);
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
-VALUE *rb_iseq_original_iseq(rb_iseq_t *iseq);
-VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
- VALUE locals, VALUE args,
- VALUE exception, VALUE body);
+VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
+void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
+ VALUE locals, VALUE args,
+ VALUE exception, VALUE body);
/* iseq.c */
void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj);
@@ -29,9 +29,18 @@ VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
struct st_table *ruby_insn_make_insn_table(void);
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos);
-int rb_iseq_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data);
-VALUE rb_iseq_line_trace_all(VALUE iseqval);
-VALUE rb_iseq_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set);
+int rb_iseqw_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data);
+VALUE rb_iseqw_line_trace_all(VALUE iseqval);
+VALUE rb_iseqw_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set);
+VALUE rb_iseqw_new(const rb_iseq_t *iseq);
+const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw);
+
+VALUE rb_iseq_path(const rb_iseq_t *iseq);
+VALUE rb_iseq_absolute_path(const rb_iseq_t *iseq);
+VALUE rb_iseq_label(const rb_iseq_t *iseq);
+VALUE rb_iseq_base_label(const rb_iseq_t *iseq);
+VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq);
+VALUE rb_iseq_method_name(const rb_iseq_t *iseq);
/* proc.c */
const rb_iseq_t *rb_method_iseq(VALUE body);
@@ -63,7 +72,7 @@ struct iseq_catch_table_entry {
CATCH_TYPE_REDO = INT2FIX(5),
CATCH_TYPE_NEXT = INT2FIX(6)
} type;
- VALUE iseq;
+ const rb_iseq_t *iseq;
unsigned int start;
unsigned int end;
unsigned int cont;
@@ -109,7 +118,7 @@ struct iseq_compile_data {
struct iseq_label_data *start_label;
struct iseq_label_data *end_label;
struct iseq_label_data *redo_label;
- VALUE current_block;
+ const rb_iseq_t *current_block;
VALUE ensure_node;
VALUE for_iseq;
struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
diff --git a/load.c b/load.c
index e1c6fe1530..9dc2229db2 100644
--- a/load.c
+++ b/load.c
@@ -602,12 +602,12 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
state = EXEC_TAG();
if (state == 0) {
NODE *node;
- VALUE iseq;
+ rb_iseq_t *iseq;
th->mild_compile_error++;
node = (NODE *)rb_load_file_str(fname);
loaded = TRUE;
- iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
+ iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), NULL);
th->mild_compile_error--;
rb_iseq_eval(iseq);
}
diff --git a/method.h b/method.h
index c421d48e3a..e46ba551a2 100644
--- a/method.h
+++ b/method.h
@@ -121,7 +121,7 @@ typedef enum {
typedef struct rb_iseq_struct rb_iseq_t;
typedef struct rb_method_iseq_struct {
- const rb_iseq_t * const iseqptr; /* should be separated from iseqval */
+ const rb_iseq_t * const iseqptr; /* should be separated from iseqval */
rb_cref_t * const cref; /* shoudl be marked */
} rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */
@@ -174,7 +174,7 @@ typedef struct rb_method_definition_struct {
UNDEFINED_METHOD_ENTRY_P((def)->body.refined.orig_me))
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi);
-void rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi);
+void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi);
void rb_add_refined_method_entry(VALUE refined_class, ID mid);
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
diff --git a/proc.c b/proc.c
index 8cf652b191..82f785114d 100644
--- a/proc.c
+++ b/proc.c
@@ -369,8 +369,8 @@ get_local_variable_ptr(VALUE envval, ID lid)
iseq = env->block.iseq;
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
- for (i=0; i<iseq->local_table_size; i++) {
- if (iseq->local_table[i] == lid) {
+ for (i=0; i<iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == lid) {
return &env->env[i];
}
}
@@ -735,7 +735,7 @@ proc_call(int argc, VALUE *argv, VALUE procval)
GetProcPtr(procval, proc);
iseq = proc->block.iseq;
- if (RUBY_VM_IFUNC_P(iseq) || iseq->param.flags.has_block) {
+ if (RUBY_VM_IFUNC_P(iseq) || iseq->body->param.flags.has_block) {
if (rb_block_given_p()) {
rb_proc_t *passed_proc;
RB_GC_GUARD(passed_procval) = rb_block_proc();
@@ -847,11 +847,11 @@ proc_arity(VALUE self)
static inline int
rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max)
{
- *max = iseq->param.flags.has_rest == FALSE ?
- iseq->param.lead_num + iseq->param.opt_num + iseq->param.post_num +
- (iseq->param.flags.has_kw == TRUE || iseq->param.flags.has_kwrest == TRUE)
+ *max = iseq->body->param.flags.has_rest == FALSE ?
+ iseq->body->param.lead_num + iseq->body->param.opt_num + iseq->body->param.post_num +
+ (iseq->body->param.flags.has_kw == TRUE || iseq->body->param.flags.has_kwrest == TRUE)
: UNLIMITED_ARGUMENTS;
- return iseq->param.lead_num + iseq->param.post_num + (iseq->param.flags.has_kw && iseq->param.keyword->required_num > 0);
+ return iseq->body->param.lead_num + iseq->body->param.post_num + (iseq->body->param.flags.has_kw && iseq->body->param.keyword->required_num > 0);
}
static int
@@ -950,9 +950,9 @@ iseq_location(const rb_iseq_t *iseq)
VALUE loc[2];
if (!iseq) return Qnil;
- loc[0] = iseq->location.path;
- if (iseq->line_info_table) {
- loc[1] = rb_iseq_first_lineno(iseq->self);
+ loc[0] = iseq->body->location.path;
+ if (iseq->body->line_info_table) {
+ loc[1] = rb_iseq_first_lineno(iseq);
}
else {
loc[1] = Qnil;
@@ -1066,11 +1066,11 @@ proc_to_s(VALUE self)
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
int first_lineno = 0;
- if (iseq->line_info_table) {
- first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
+ if (iseq->body->line_info_table) {
+ first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
}
str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self,
- iseq->location.path, first_lineno, is_lambda);
+ iseq->body->location.path, first_lineno, is_lambda);
}
else {
str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
@@ -2558,8 +2558,8 @@ proc_binding(VALUE self)
}
if (iseq) {
- bind->path = iseq->location.path;
- bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
+ bind->path = iseq->body->location.path;
+ bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
}
else {
bind->path = Qnil;
diff --git a/ruby.c b/ruby.c
index 9167b6837b..d74451ff62 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1305,7 +1305,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
{
NODE *tree = 0;
VALUE parser;
- VALUE iseq;
+ const rb_iseq_t *iseq;
rb_encoding *enc, *lenc;
const char *s;
char fbuf[MAXPATHLEN];
@@ -1544,7 +1544,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
});
if (opt->dump & DUMP_BIT(insns)) {
- rb_io_write(rb_stdout, rb_iseq_disasm(iseq));
+ rb_io_write(rb_stdout, rb_iseq_disasm((const rb_iseq_t *)iseq));
rb_io_flush(rb_stdout);
return Qtrue;
}
@@ -1555,7 +1555,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
rb_set_safe_level(opt->safe_level);
- return iseq;
+ return (VALUE)iseq;
}
struct load_file_arg {
diff --git a/struct.c b/struct.c
index 729b7c2685..0d979c8aac 100644
--- a/struct.c
+++ b/struct.c
@@ -19,8 +19,8 @@ enum {
AREF_HASH_THRESHOLD = 10
};
-VALUE rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func);
-VALUE rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func);
+const rb_iseq_t *rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func);
+const rb_iseq_t *rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func);
VALUE rb_cStruct;
static ID id_members, id_back_members;
@@ -287,18 +287,18 @@ static void
define_aref_method(VALUE nstr, VALUE name, VALUE off)
{
rb_control_frame_t *FUNC_FASTCALL(rb_vm_opt_struct_aref)(rb_thread_t *, rb_control_frame_t *);
- VALUE iseqval = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref);
+ const rb_iseq_t *iseq = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref);
- rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, METHOD_VISI_PUBLIC);
+ rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, METHOD_VISI_PUBLIC);
}
static void
define_aset_method(VALUE nstr, VALUE name, VALUE off)
{
rb_control_frame_t *FUNC_FASTCALL(rb_vm_opt_struct_aset)(rb_thread_t *, rb_control_frame_t *);
- VALUE iseqval = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset);
+ const rb_iseq_t *iseq = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset);
- rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, METHOD_VISI_PUBLIC);
+ rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, METHOD_VISI_PUBLIC);
}
static VALUE
diff --git a/thread.c b/thread.c
index c516d5fa72..45f0fa7355 100644
--- a/thread.c
+++ b/thread.c
@@ -5226,7 +5226,7 @@ rb_check_deadlock(rb_vm_t *vm)
static void
update_coverage(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass)
{
- VALUE coverage = GET_THREAD()->cfp->iseq->coverage;
+ VALUE coverage = GET_THREAD()->cfp->iseq->body->coverage;
if (coverage && RBASIC(coverage)->klass == 0) {
long line = rb_sourceline() - 1;
long count;
diff --git a/vm.c b/vm.c
index 9aaf5f6180..e1f5212deb 100644
--- a/vm.c
+++ b/vm.c
@@ -247,12 +247,9 @@ vm_stat(int argc, VALUE *argv, VALUE self)
/* control stack frame */
static void
-vm_set_top_stack(rb_thread_t *th, VALUE iseqval)
+vm_set_top_stack(rb_thread_t *th, const rb_iseq_t *iseq)
{
- rb_iseq_t *iseq;
- GetISeqPtr(iseqval, iseq);
-
- if (iseq->type != ISEQ_TYPE_TOP) {
+ if (iseq->body->type != ISEQ_TYPE_TOP) {
rb_raise(rb_eTypeError, "Not a toplevel InstructionSequence");
}
@@ -260,37 +257,33 @@ vm_set_top_stack(rb_thread_t *th, VALUE iseqval)
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH, th->top_self,
VM_ENVVAL_BLOCK_PTR(0),
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
- iseq->iseq_encoded, th->cfp->sp, iseq->local_size, iseq->stack_max);
+ iseq->body->iseq_encoded, th->cfp->sp, iseq->body->local_size, iseq->body->stack_max);
}
static void
-vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const rb_cref_t *cref, rb_block_t *base_block)
+vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, rb_block_t *base_block)
{
- rb_iseq_t *iseq;
- GetISeqPtr(iseqval, iseq);
-
vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL | VM_FRAME_FLAG_FINISH,
base_block->self, VM_ENVVAL_PREV_EP_PTR(base_block->ep),
(VALUE)cref, /* cref or me */
- iseq->iseq_encoded,
- th->cfp->sp, iseq->local_size, iseq->stack_max);
+ iseq->body->iseq_encoded,
+ th->cfp->sp, iseq->body->local_size, iseq->body->stack_max);
}
static void
-vm_set_main_stack(rb_thread_t *th, VALUE iseqval)
+vm_set_main_stack(rb_thread_t *th, const rb_iseq_t *iseq)
{
VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING"));
rb_binding_t *bind;
- rb_iseq_t *iseq;
rb_env_t *env;
GetBindingPtr(toplevel_binding, bind);
GetEnvPtr(bind->env, env);
- vm_set_eval_stack(th, iseqval, 0, &env->block);
+
+ vm_set_eval_stack(th, iseq, 0, &env->block);
/* save binding */
- GetISeqPtr(iseqval, iseq);
- if (bind && iseq->local_size > 0) {
+ if (bind && iseq->body->local_size > 0) {
bind->env = vm_make_env_object(th, th->cfp);
}
}
@@ -425,7 +418,7 @@ env_mark(void * const ptr)
rb_gc_mark((VALUE)env->block.iseq);
}
else {
- RUBY_MARK_UNLESS_NULL(env->block.iseq->self);
+ RUBY_MARK_UNLESS_NULL((VALUE)env->block.iseq);
}
}
RUBY_MARK_LEAVE("env");
@@ -536,7 +529,7 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
local_size = 1 /* cref/me */;
}
else {
- local_size = cfp->iseq->local_size;
+ local_size = cfp->iseq->body->local_size;
}
/*
@@ -638,8 +631,8 @@ collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_li
{
int i;
if (!iseq) return 0;
- for (i = 0; i < iseq->local_table_size; i++) {
- local_var_list_add(vars, iseq->local_table[i]);
+ for (i = 0; i < iseq->body->local_table_size; i++) {
+ local_var_list_add(vars, iseq->body->local_table[i]);
}
return 1;
}
@@ -756,7 +749,7 @@ rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
bindval = rb_binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind);
bind->env = envval;
- bind->path = ruby_level_cfp->iseq->location.path;
+ bind->path = ruby_level_cfp->iseq->body->location.path;
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
return bindval;
@@ -765,11 +758,11 @@ rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
VALUE *
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
{
- VALUE envval = bind->env, path = bind->path, iseqval;
+ VALUE envval = bind->env, path = bind->path;
rb_env_t *env;
rb_block_t *base_block;
rb_thread_t *th = GET_THREAD();
- const rb_iseq_t *base_iseq;
+ const rb_iseq_t *base_iseq, *iseq;
NODE *node = 0;
ID minibuf[4], *dyns = minibuf;
VALUE idtmp = 0;
@@ -788,17 +781,16 @@ rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
node = NEW_NODE(NODE_SCOPE, dyns, 0, 0);
if (base_iseq) {
- iseqval = rb_iseq_new(node, base_iseq->location.label, path, path,
- base_iseq->self, ISEQ_TYPE_EVAL);
+ iseq = rb_iseq_new(node, base_iseq->body->location.label, path, path, base_iseq, ISEQ_TYPE_EVAL);
}
else {
VALUE tempstr = rb_str_new2("<temp>");
- iseqval = rb_iseq_new_top(node, tempstr, tempstr, tempstr, Qfalse);
+ iseq = rb_iseq_new_top(node, tempstr, tempstr, tempstr, NULL);
}
node->u1.tbl = 0; /* reset table */
ALLOCV_END(idtmp);
- vm_set_eval_stack(th, iseqval, 0, base_block);
+ vm_set_eval_stack(th, iseq, 0, base_block);
bind->env = vm_make_env_object(th, th->cfp);
vm_pop_frame(th);
GetEnvPtr(bind->env, env);
@@ -821,7 +813,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
VALUE ret;
const rb_iseq_t *iseq = block->iseq;
const rb_control_frame_t *cfp;
- int i, opt_pc, arg_size = iseq->param.size;
+ int i, opt_pc, arg_size = iseq->body->param.size;
int type = block_proc_is_lambda(block->proc) ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
th->passed_bmethod_me = NULL;
@@ -839,9 +831,9 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self,
VM_ENVVAL_PREV_EP_PTR(block->ep),
(VALUE)me, /* cref or method (TODO: can we ignore cref?) */
- iseq->iseq_encoded + opt_pc,
- cfp->sp + arg_size, iseq->local_size - arg_size,
- iseq->stack_max);
+ iseq->body->iseq_encoded + opt_pc,
+ cfp->sp + arg_size, iseq->body->local_size - arg_size,
+ iseq->body->stack_max);
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->called_id);
EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->called_id, me->owner, Qnil);
@@ -850,9 +842,9 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH, self,
VM_ENVVAL_PREV_EP_PTR(block->ep),
(VALUE)cref, /* cref or method */
- iseq->iseq_encoded + opt_pc,
- cfp->sp + arg_size, iseq->local_size - arg_size,
- iseq->stack_max);
+ iseq->body->iseq_encoded + opt_pc,
+ cfp->sp + arg_size, iseq->body->local_size - arg_size,
+ iseq->body->stack_max);
}
ret = vm_exec(th);
@@ -1021,7 +1013,7 @@ rb_sourcefilename(void)
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
- return cfp->iseq->location.path;
+ return cfp->iseq->body->location.path;
}
else {
return Qnil;
@@ -1035,7 +1027,7 @@ rb_sourcefile(void)
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
- return RSTRING_PTR(cfp->iseq->location.path);
+ return RSTRING_PTR(cfp->iseq->body->location.path);
}
else {
return 0;
@@ -1489,7 +1481,7 @@ vm_exec(rb_thread_t *th)
struct iseq_catch_table_entry *entry;
struct iseq_catch_table *ct;
unsigned long epc, cont_pc, cont_sp;
- VALUE catch_iseqval;
+ const rb_iseq_t *catch_iseq;
rb_control_frame_t *cfp;
VALUE type;
const rb_control_frame_t *escape_cfp;
@@ -1497,7 +1489,8 @@ vm_exec(rb_thread_t *th)
err = (struct vm_throw_data *)th->errinfo;
exception_handler:
- cont_pc = cont_sp = catch_iseqval = 0;
+ cont_pc = cont_sp = 0;
+ catch_iseq = NULL;
while (th->cfp->pc == 0 || th->cfp->iseq == 0) {
if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
@@ -1512,7 +1505,7 @@ vm_exec(rb_thread_t *th)
}
cfp = th->cfp;
- epc = cfp->pc - cfp->iseq->iseq_encoded;
+ epc = cfp->pc - cfp->iseq->body->iseq_encoded;
escape_cfp = NULL;
if (state == TAG_BREAK || state == TAG_RETURN) {
@@ -1525,19 +1518,19 @@ vm_exec(rb_thread_t *th)
THROW_DATA_STATE_SET(err, state = TAG_BREAK);
}
else {
- ct = cfp->iseq->catch_table;
+ ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) {
- catch_iseqval = entry->iseq;
+ catch_iseq = entry->iseq;
cont_pc = entry->cont;
cont_sp = entry->sp;
break;
}
}
}
- if (!catch_iseqval) {
+ if (!catch_iseq) {
th->errinfo = Qnil;
result = THROW_DATA_VAL(err);
hook_before_rewind(th, th->cfp);
@@ -1561,14 +1554,14 @@ vm_exec(rb_thread_t *th)
}
if (state == TAG_RAISE) {
- ct = cfp->iseq->catch_table;
+ ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_RESCUE ||
entry->type == CATCH_TYPE_ENSURE) {
- catch_iseqval = entry->iseq;
+ catch_iseq = entry->iseq;
cont_pc = entry->cont;
cont_sp = entry->sp;
break;
@@ -1577,13 +1570,13 @@ vm_exec(rb_thread_t *th)
}
}
else if (state == TAG_RETRY) {
- ct = cfp->iseq->catch_table;
+ ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) {
- catch_iseqval = entry->iseq;
+ catch_iseq = entry->iseq;
cont_pc = entry->cont;
cont_sp = entry->sp;
break;
@@ -1592,7 +1585,7 @@ vm_exec(rb_thread_t *th)
const rb_control_frame_t *escape_cfp;
escape_cfp = THROW_DATA_CATCH_FRAME(err);
if (cfp == escape_cfp) {
- cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
+ cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
th->errinfo = Qnil;
goto vm_loop_start;
}
@@ -1604,19 +1597,19 @@ vm_exec(rb_thread_t *th)
type = CATCH_TYPE_BREAK;
search_restart_point:
- ct = cfp->iseq->catch_table;
+ ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) {
- catch_iseqval = entry->iseq;
+ catch_iseq = entry->iseq;
cont_pc = entry->cont;
cont_sp = entry->sp;
break;
}
else if (entry->type == type) {
- cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
+ cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
cfp->sp = vm_base_ptr(cfp) + entry->sp;
if (state != TAG_REDO) {
@@ -1642,13 +1635,13 @@ vm_exec(rb_thread_t *th)
goto search_restart_point;
}
else {
- ct = cfp->iseq->catch_table;
+ ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) {
- catch_iseqval = entry->iseq;
+ catch_iseq = entry->iseq;
cont_pc = entry->cont;
cont_sp = entry->sp;
break;
@@ -1657,14 +1650,10 @@ vm_exec(rb_thread_t *th)
}
}
- if (catch_iseqval != 0) {
- /* found catch table */
- rb_iseq_t *catch_iseq;
-
+ if (catch_iseq != 0) { /* found catch table */
/* enter catch scope */
- GetISeqPtr(catch_iseqval, catch_iseq);
cfp->sp = vm_base_ptr(cfp) + cont_sp;
- cfp->pc = cfp->iseq->iseq_encoded + cont_pc;
+ cfp->pc = cfp->iseq->body->iseq_encoded + cont_pc;
/* push block frame */
cfp->sp[0] = (VALUE)err;
@@ -1672,10 +1661,10 @@ vm_exec(rb_thread_t *th)
cfp->self,
VM_ENVVAL_PREV_EP_PTR(cfp->ep),
0, /* cref or me */
- catch_iseq->iseq_encoded,
+ catch_iseq->body->iseq_encoded,
cfp->sp + 1 /* push value */,
- catch_iseq->local_size - 1,
- catch_iseq->stack_max);
+ catch_iseq->body->local_size - 1,
+ catch_iseq->body->stack_max);
state = 0;
th->state = 0;
@@ -1706,28 +1695,23 @@ vm_exec(rb_thread_t *th)
/* misc */
VALUE
-rb_iseq_eval(VALUE iseqval)
+rb_iseq_eval(const rb_iseq_t *iseq)
{
rb_thread_t *th = GET_THREAD();
VALUE val;
-
- vm_set_top_stack(th, iseqval);
-
+ vm_set_top_stack(th, iseq);
val = vm_exec(th);
- RB_GC_GUARD(iseqval); /* prohibit tail call optimization */
return val;
}
VALUE
-rb_iseq_eval_main(VALUE iseqval)
+rb_iseq_eval_main(const rb_iseq_t *iseq)
{
rb_thread_t *th = GET_THREAD();
VALUE val;
- vm_set_main_stack(th, iseqval);
-
+ vm_set_main_stack(th, iseq);
val = vm_exec(th);
- RB_GC_GUARD(iseqval); /* prohibit tail call optimization */
return val;
}
@@ -1770,7 +1754,7 @@ rb_thread_current_status(const rb_thread_t *th)
const rb_iseq_t *iseq = cfp->iseq;
int line_no = rb_vm_get_sourceline(cfp);
str = rb_sprintf("%"PRIsVALUE":%d:in `%"PRIsVALUE"'",
- iseq->location.path, line_no, iseq->location.label);
+ iseq->body->location.path, line_no, iseq->body->location.label);
}
}
else if ((me = rb_vm_frame_method_entry(cfp)) && me->def->original_id) {
@@ -1788,10 +1772,10 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
{
rb_thread_t *th = GET_THREAD();
const rb_control_frame_t *reg_cfp = th->cfp;
- volatile VALUE iseqval = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
+ const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
VALUE val;
- vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
+ vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
recv, VM_ENVVAL_BLOCK_PTR(blockptr),
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
0, reg_cfp->sp, 1, 0);
@@ -2065,12 +2049,9 @@ rb_thread_mark(void *ptr)
rb_gc_mark_values((long)(sp - p), p);
while (cfp != limit_cfp) {
- const rb_iseq_t *iseq = cfp->iseq;
rb_gc_mark(cfp->proc);
rb_gc_mark(cfp->self);
- if (iseq) {
- rb_gc_mark(RUBY_VM_NORMAL_ISEQ_P(iseq) ? iseq->self : (VALUE)iseq);
- }
+ rb_gc_mark((VALUE)cfp->iseq);
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
}
@@ -2287,11 +2268,11 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
visi = METHOD_VISI_PUBLIC;
}
- rb_add_method_iseq(klass, id, iseqval, cref, visi);
+ rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
if (!is_singleton && scope_visi->module_func) {
klass = rb_singleton_class(klass);
- rb_add_method_iseq(klass, id, iseqval, cref, METHOD_VISI_PUBLIC);
+ rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
}
}
@@ -2755,9 +2736,8 @@ Init_VM(void)
rb_vm_t *vm = ruby_current_vm;
rb_thread_t *th = GET_THREAD();
VALUE filename = rb_str_new2("<main>");
- volatile VALUE iseqval = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
+ const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
volatile VALUE th_self;
- rb_iseq_t *iseq;
/* create vm object */
vm->self = TypedData_Wrap_Struct(rb_cRubyVM, &vm_data_type, vm);
@@ -2774,10 +2754,9 @@ Init_VM(void)
rb_vm_living_threads_insert(vm, th);
- rb_gc_register_mark_object(iseqval);
- GetISeqPtr(iseqval, iseq);
+ rb_gc_register_mark_object((VALUE)iseq);
th->cfp->iseq = iseq;
- th->cfp->pc = iseq->iseq_encoded;
+ th->cfp->pc = iseq->body->iseq_encoded;
th->cfp->self = th->top_self;
th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, NULL);
@@ -2800,7 +2779,7 @@ rb_vm_set_progname(VALUE filename)
rb_thread_t *th = GET_VM()->main_thread;
rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size);
--cfp;
- RB_OBJ_WRITE(cfp->iseq->self, &cfp->iseq->location.path, filename);
+ RB_OBJ_WRITE(cfp->iseq, &cfp->iseq->body->location.path, filename);
}
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
@@ -2893,7 +2872,7 @@ rb_ruby_debug_ptr(void)
}
/* iseq.c */
-VALUE rb_insn_operand_intern(rb_iseq_t *iseq,
+VALUE rb_insn_operand_intern(const rb_iseq_t *iseq,
VALUE insn, int op_no, VALUE op,
int len, size_t pos, VALUE *pnop, VALUE child);
diff --git a/vm_args.c b/vm_args.c
index bea9d59b7a..c7a1299792 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -384,10 +384,10 @@ static void
args_setup_kw_parameters(VALUE* const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords,
const rb_iseq_t * const iseq, VALUE * const locals)
{
- const ID *acceptable_keywords = iseq->param.keyword->table;
- const int req_key_num = iseq->param.keyword->required_num;
- const int key_num = iseq->param.keyword->num;
- const VALUE * const default_values = iseq->param.keyword->default_values;
+ const ID *acceptable_keywords = iseq->body->param.keyword->table;
+ const int req_key_num = iseq->body->param.keyword->required_num;
+ const int key_num = iseq->body->param.keyword->num;
+ const VALUE * const default_values = iseq->body->param.keyword->default_values;
VALUE missing = 0;
int i, di, found = 0;
int unspecified_bits = 0;
@@ -438,7 +438,7 @@ args_setup_kw_parameters(VALUE* const passed_values, const int passed_keyword_le
}
}
- if (iseq->param.flags.has_kwrest) {
+ if (iseq->body->param.flags.has_kwrest) {
const int rest_hash_index = key_num + 1;
locals[rest_hash_index] = make_unused_kw_hash(passed_keywords, passed_keyword_len, passed_values, FALSE);
}
@@ -502,8 +502,8 @@ static int
setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, rb_call_info_t * const ci,
VALUE * const locals, const enum arg_setup_type arg_setup_type)
{
- const int min_argc = iseq->param.lead_num + iseq->param.post_num;
- const int max_argc = (iseq->param.flags.has_rest == FALSE) ? min_argc + iseq->param.opt_num : UNLIMITED_ARGUMENTS;
+ const int min_argc = iseq->body->param.lead_num + iseq->body->param.post_num;
+ const int max_argc = (iseq->body->param.flags.has_rest == FALSE) ? min_argc + iseq->body->param.opt_num : UNLIMITED_ARGUMENTS;
int opt_pc = 0;
int given_argc;
struct args_info args_body, *args;
@@ -516,16 +516,16 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
*
* [pushed values] [uninitialized values]
* <- ci->argc -->
- * <- iseq->param.size------------------>
+ * <- iseq->body->param.size------------>
* ^ locals ^ sp
*
* =>
* [pushed values] [initialized values ]
* <- ci->argc -->
- * <- iseq->param.size------------------>
+ * <- iseq->body->param.size------------>
* ^ locals ^ sp
*/
- for (i=ci->argc; i<iseq->param.size; i++) {
+ for (i=ci->argc; i<iseq->body->param.size; i++) {
locals[i] = Qnil;
}
th->cfp->sp = &locals[i];
@@ -537,7 +537,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
args->argv = locals;
if (ci->kw_arg) {
- if (iseq->param.flags.has_kw) {
+ if (iseq->body->param.flags.has_kw) {
int kw_len = ci->kw_arg->keyword_len;
/* copy kw_argv */
args->kw_argv = ALLOCA_N(VALUE, kw_len);
@@ -568,17 +568,17 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
break; /* do nothing special */
case arg_setup_block:
if (given_argc == 1 &&
- (min_argc > 0 || iseq->param.opt_num > 1 ||
- iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) &&
- !iseq->param.flags.ambiguous_param0 &&
+ (min_argc > 0 || iseq->body->param.opt_num > 1 ||
+ iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
+ !iseq->body->param.flags.ambiguous_param0 &&
args_check_block_arg0(args, th)) {
given_argc = RARRAY_LENINT(args->rest);
}
break;
case arg_setup_lambda:
if (given_argc == 1 &&
- given_argc != iseq->param.lead_num &&
- !iseq->param.flags.has_rest &&
+ given_argc != iseq->body->param.lead_num &&
+ !iseq->body->param.flags.has_rest &&
args_check_block_arg0(args, th)) {
given_argc = RARRAY_LENINT(args->rest);
}
@@ -603,7 +603,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
}
if (given_argc > min_argc &&
- (iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) &&
+ (iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
args->kw_argv == NULL) {
if (args_pop_keyword_hash(args, &keyword_hash, th)) {
given_argc--;
@@ -621,25 +621,25 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
}
}
- if (iseq->param.flags.has_lead) {
- args_setup_lead_parameters(args, iseq->param.lead_num, locals + 0);
+ if (iseq->body->param.flags.has_lead) {
+ args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0);
}
- if (iseq->param.flags.has_post) {
- args_setup_post_parameters(args, iseq->param.post_num, locals + iseq->param.post_start);
+ if (iseq->body->param.flags.has_post) {
+ args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start);
}
- if (iseq->param.flags.has_opt) {
- int opt = args_setup_opt_parameters(args, iseq->param.opt_num, locals + iseq->param.lead_num);
- opt_pc = (int)iseq->param.opt_table[opt];
+ if (iseq->body->param.flags.has_opt) {
+ int opt = args_setup_opt_parameters(args, iseq->body->param.opt_num, locals + iseq->body->param.lead_num);
+ opt_pc = (int)iseq->body->param.opt_table[opt];
}
- if (iseq->param.flags.has_rest) {
- args_setup_rest_parameter(args, locals + iseq->param.rest_start);
+ if (iseq->body->param.flags.has_rest) {
+ args_setup_rest_parameter(args, locals + iseq->body->param.rest_start);
}
- if (iseq->param.flags.has_kw) {
- VALUE * const klocals = locals + iseq->param.keyword->bits_start - iseq->param.keyword->num;
+ if (iseq->body->param.flags.has_kw) {
+ VALUE * const klocals = locals + iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num;
if (args->kw_argv != NULL) {
args_setup_kw_parameters(args->kw_argv, args->ci->kw_arg->keyword_len, args->ci->kw_arg->keywords, iseq, klocals);
@@ -660,18 +660,18 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
args_setup_kw_parameters(NULL, 0, NULL, iseq, klocals);
}
}
- else if (iseq->param.flags.has_kwrest) {
- args_setup_kw_rest_parameter(keyword_hash, locals + iseq->param.keyword->rest_start);
+ else if (iseq->body->param.flags.has_kwrest) {
+ args_setup_kw_rest_parameter(keyword_hash, locals + iseq->body->param.keyword->rest_start);
}
- if (iseq->param.flags.has_block) {
- args_setup_block_parameter(th, ci, locals + iseq->param.block_start);
+ if (iseq->body->param.flags.has_block) {
+ args_setup_block_parameter(th, ci, locals + iseq->body->param.block_start);
}
#if 0
{
int i;
- for (i=0; i<iseq->param.size; i++) {
+ for (i=0; i<iseq->body->param.size; i++) {
fprintf(stderr, "local[%d] = %p\n", i, (void *)locals[i]);
}
}
@@ -691,7 +691,7 @@ raise_argument_error(rb_thread_t *th, const rb_iseq_t *iseq, const VALUE exc)
if (iseq) {
vm_push_frame(th, iseq, VM_FRAME_MAGIC_DUMMY, Qnil /* self */,
VM_ENVVAL_BLOCK_PTR(0) /* specval*/, Qfalse /* me or cref */,
- iseq->iseq_encoded, th->cfp->sp, 1 /* local_size (cref/me) */, 0 /* stack_max */);
+ iseq->body->iseq_encoded, th->cfp->sp, 1 /* local_size (cref/me) */, 0 /* stack_max */);
at = rb_vm_backtrace_object();
vm_pop_frame(th);
}
diff --git a/vm_backtrace.c b/vm_backtrace.c
index aabc949f64..077ed5049f 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -31,7 +31,7 @@ id2str(ID id)
inline static int
calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
{
- return rb_iseq_line_no(iseq, pc - iseq->iseq_encoded);
+ return rb_iseq_line_no(iseq, pc - iseq->body->iseq_encoded);
}
int
@@ -87,7 +87,7 @@ location_mark_entry(rb_backtrace_location_t *fi)
switch (fi->type) {
case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED:
- rb_gc_mark(fi->body.iseq.iseq->self);
+ rb_gc_mark((VALUE)fi->body.iseq.iseq);
break;
case LOCATION_TYPE_CFUNC:
case LOCATION_TYPE_IFUNC:
@@ -157,7 +157,7 @@ location_label(rb_backtrace_location_t *loc)
switch (loc->type) {
case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED:
- return loc->body.iseq.iseq->location.label;
+ return loc->body.iseq.iseq->body->location.label;
case LOCATION_TYPE_CFUNC:
return rb_id2str(loc->body.cfunc.mid);
case LOCATION_TYPE_IFUNC:
@@ -206,7 +206,7 @@ location_base_label(rb_backtrace_location_t *loc)
switch (loc->type) {
case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED:
- return loc->body.iseq.iseq->location.base_label;
+ return loc->body.iseq.iseq->body->location.base_label;
case LOCATION_TYPE_CFUNC:
return rb_id2str(loc->body.cfunc.mid);
case LOCATION_TYPE_IFUNC:
@@ -233,7 +233,7 @@ location_path(rb_backtrace_location_t *loc)
switch (loc->type) {
case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED:
- return loc->body.iseq.iseq->location.path;
+ return loc->body.iseq.iseq->body->location.path;
case LOCATION_TYPE_CFUNC:
if (loc->body.cfunc.prev_loc) {
return location_path(loc->body.cfunc.prev_loc);
@@ -266,7 +266,7 @@ location_absolute_path(rb_backtrace_location_t *loc)
switch (loc->type) {
case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED:
- return loc->body.iseq.iseq->location.absolute_path;
+ return loc->body.iseq.iseq->body->location.absolute_path;
case LOCATION_TYPE_CFUNC:
if (loc->body.cfunc.prev_loc) {
return location_absolute_path(loc->body.cfunc.prev_loc);
@@ -315,20 +315,20 @@ location_to_str(rb_backtrace_location_t *loc)
switch (loc->type) {
case LOCATION_TYPE_ISEQ:
- file = loc->body.iseq.iseq->location.path;
- name = loc->body.iseq.iseq->location.label;
+ file = loc->body.iseq.iseq->body->location.path;
+ name = loc->body.iseq.iseq->body->location.label;
lineno = loc->body.iseq.lineno.lineno = calc_lineno(loc->body.iseq.iseq, loc->body.iseq.lineno.pc);
loc->type = LOCATION_TYPE_ISEQ_CALCED;
break;
case LOCATION_TYPE_ISEQ_CALCED:
- file = loc->body.iseq.iseq->location.path;
+ file = loc->body.iseq.iseq->body->location.path;
lineno = loc->body.iseq.lineno.lineno;
- name = loc->body.iseq.iseq->location.label;
+ name = loc->body.iseq.iseq->body->location.label;
break;
case LOCATION_TYPE_CFUNC:
if (loc->body.cfunc.prev_loc) {
- file = loc->body.cfunc.prev_loc->body.iseq.iseq->location.path;
+ file = loc->body.cfunc.prev_loc->body.iseq.iseq->body->location.path;
lineno = location_lineno(loc->body.cfunc.prev_loc);
}
else {
@@ -693,8 +693,8 @@ oldbt_iter_iseq(void *ptr, const rb_control_frame_t *cfp)
const rb_iseq_t *iseq = cfp->iseq;
const VALUE *pc = cfp->pc;
struct oldbt_arg *arg = (struct oldbt_arg *)ptr;
- VALUE file = arg->filename = iseq->location.path;
- VALUE name = iseq->location.label;
+ VALUE file = arg->filename = iseq->body->location.path;
+ VALUE name = iseq->body->location.label;
int lineno = arg->lineno = calc_lineno(iseq, pc);
(arg->func)(arg->data, file, lineno, name);
@@ -1111,7 +1111,7 @@ collect_caller_bindings_iseq(void *arg, const rb_control_frame_t *cfp)
rb_ary_store(frame, CALLER_BINDING_SELF, cfp->self);
rb_ary_store(frame, CALLER_BINDING_CLASS, get_klass(cfp));
rb_ary_store(frame, CALLER_BINDING_BINDING, GC_GUARDED_PTR(cfp)); /* create later */
- rb_ary_store(frame, CALLER_BINDING_ISEQ, cfp->iseq ? cfp->iseq->self : Qnil);
+ rb_ary_store(frame, CALLER_BINDING_ISEQ, cfp->iseq ? (VALUE)cfp->iseq : Qnil);
rb_ary_store(frame, CALLER_BINDING_CFP, GC_GUARDED_PTR(cfp));
rb_ary_push(data->ary, frame);
@@ -1231,7 +1231,9 @@ VALUE
rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index)
{
VALUE frame = frame_get(dc, index);
- return rb_ary_entry(frame, CALLER_BINDING_ISEQ);
+ VALUE iseq = rb_ary_entry(frame, CALLER_BINDING_ISEQ);
+
+ return RTEST(iseq) ? rb_iseqw_new((rb_iseq_t *)iseq) : Qnil;
}
VALUE
@@ -1261,7 +1263,7 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
buff[i] = (VALUE)cme;
}
else {
- buff[i] = cfp->iseq->self;
+ buff[i] = (VALUE)cfp->iseq;
}
if (cfp->iseq && lines) lines[i] = calc_lineno(cfp->iseq, cfp->pc);
@@ -1274,24 +1276,27 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
return i;
}
-static VALUE
+static const rb_iseq_t *
frame2iseq(VALUE frame)
{
- if (frame == Qnil) return Qnil;
-
- if (RB_TYPE_P(frame, T_DATA)) {
- VM_ASSERT(strcmp(rb_objspace_data_type_name(frame), "iseq") == 0);
- return frame;
- }
+ if (frame == Qnil) return NULL;
if (RB_TYPE_P(frame, T_IMEMO)) {
- const rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)frame;
- VM_ASSERT(imemo_type(frame) == imemo_ment);
- switch (cme->def->type) {
- case VM_METHOD_TYPE_ISEQ:
- return cme->def->body.iseq.iseqptr->self;
+ switch (imemo_type(frame)) {
+ case imemo_iseq:
+ return (const rb_iseq_t *)frame;
+ case imemo_ment:
+ {
+ const rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)frame;
+ switch (cme->def->type) {
+ case VM_METHOD_TYPE_ISEQ:
+ return cme->def->body.iseq.iseqptr;
+ default:
+ return NULL;
+ }
+ }
default:
- return Qnil;
+ break;
}
}
rb_bug("frame2iseq: unreachable");
@@ -1300,36 +1305,36 @@ frame2iseq(VALUE frame)
VALUE
rb_profile_frame_path(VALUE frame)
{
- VALUE iseqv = frame2iseq(frame);
- return NIL_P(iseqv) ? Qnil : rb_iseq_path(iseqv);
+ const rb_iseq_t *iseq = frame2iseq(frame);
+ return iseq ? rb_iseq_path(iseq) : Qnil;
}
VALUE
rb_profile_frame_absolute_path(VALUE frame)
{
- VALUE iseqv = frame2iseq(frame);
- return NIL_P(iseqv) ? Qnil : rb_iseq_absolute_path(iseqv);
+ const rb_iseq_t *iseq = frame2iseq(frame);
+ return iseq ? rb_iseq_absolute_path(iseq) : Qnil;
}
VALUE
rb_profile_frame_label(VALUE frame)
{
- VALUE iseqv = frame2iseq(frame);
- return NIL_P(iseqv) ? Qnil : rb_iseq_label(iseqv);
+ const rb_iseq_t *iseq = frame2iseq(frame);
+ return iseq ? rb_iseq_label(iseq) : Qnil;
}
VALUE
rb_profile_frame_base_label(VALUE frame)
{
- VALUE iseqv = frame2iseq(frame);
- return NIL_P(iseqv) ? Qnil : rb_iseq_base_label(iseqv);
+ const rb_iseq_t *iseq = frame2iseq(frame);
+ return iseq ? rb_iseq_base_label(iseq) : Qnil;
}
VALUE
rb_profile_frame_first_lineno(VALUE frame)
{
- VALUE iseqv = frame2iseq(frame);
- return NIL_P(iseqv) ? Qnil : rb_iseq_first_lineno(iseqv);
+ const rb_iseq_t *iseq = frame2iseq(frame);
+ return iseq ? rb_iseq_first_lineno(iseq) : Qnil;
}
static VALUE
@@ -1384,8 +1389,8 @@ rb_profile_frame_singleton_method_p(VALUE frame)
VALUE
rb_profile_frame_method_name(VALUE frame)
{
- VALUE iseqv = frame2iseq(frame);
- return NIL_P(iseqv) ? Qnil : rb_iseq_method_name(iseqv);
+ const rb_iseq_t *iseq = frame2iseq(frame);
+ return iseq ? rb_iseq_method_name(iseq) : Qnil;
}
VALUE
diff --git a/vm_core.h b/vm_core.h
index c0c119ac2a..f4c81fce3a 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -233,9 +233,6 @@ typedef struct rb_call_info_struct {
#define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct((obj), type, (ptr))
#endif
-#define GetISeqPtr(obj, ptr) \
- GetCoreDataFromValue((obj), rb_iseq_t, (ptr))
-
typedef struct rb_iseq_location_struct {
const VALUE path;
const VALUE absolute_path;
@@ -244,7 +241,7 @@ typedef struct rb_iseq_location_struct {
VALUE first_lineno; /* TODO: may be unsigned short */
} rb_iseq_location_t;
-struct rb_iseq_struct {
+struct rb_iseq_body {
/***************/
/* static data */
/***************/
@@ -260,9 +257,7 @@ struct rb_iseq_struct {
ISEQ_TYPE_MAIN,
ISEQ_TYPE_DEFINED_GUARD
} type; /* instruction sequence type */
-#if defined(WORDS_BIGENDIAN) && (SIZEOF_VALUE > SIZEOF_INT)
- char dummy[SIZEOF_VALUE - SIZEOF_INT]; /* [Bug #10037][ruby-core:63721] */
-#endif
+
int stack_max; /* for stack overflow check */
rb_iseq_location_t location;
@@ -370,19 +365,24 @@ struct rb_iseq_struct {
/* dynamic data */
/****************/
- VALUE self;
-
/* misc */
rb_num_t flip_cnt;
- /* used at compile time */
- struct iseq_compile_data *compile_data;
-
/* original iseq, before encoding
* used for debug/dump (TODO: union with compile_data) */
VALUE *iseq;
};
+/* T_IMEMO/iseq */
+/* typedef rb_iseq_t is in method.h */
+struct rb_iseq_struct {
+ VALUE flags;
+ struct iseq_compile_data *compile_data; /* used at compile time */
+ struct rb_iseq_body *body;
+ VALUE dummy1;
+ VALUE dummy2;
+};
+
enum ruby_special_exceptions {
ruby_error_reenter,
ruby_error_nomemory,
@@ -785,18 +785,18 @@ typedef enum {
RUBY_SYMBOL_EXPORT_BEGIN
/* node -> iseq */
-VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, enum iseq_type);
-VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE parent);
-VALUE rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path);
-VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE);
-VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, const rb_compile_option_t*);
+rb_iseq_t *rb_iseq_new(NODE*, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type);
+rb_iseq_t *rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, const rb_iseq_t *parent);
+rb_iseq_t *rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path);
+rb_iseq_t *rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE);
+rb_iseq_t *rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*);
/* src -> iseq */
-VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
-VALUE rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_block);
-VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt);
+rb_iseq_t *rb_iseq_compile(VALUE src, VALUE file, VALUE line);
+rb_iseq_t *rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_block);
+rb_iseq_t *rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt);
-VALUE rb_iseq_disasm(VALUE self);
+VALUE rb_iseq_disasm(const rb_iseq_t *iseq);
int rb_iseq_disasm_insn(VALUE str, const VALUE *iseqval, size_t pos, const rb_iseq_t *iseq, VALUE child);
const char *ruby_node_name(int node);
@@ -946,9 +946,8 @@ rb_block_t *rb_vm_control_frame_block_ptr(const rb_control_frame_t *cfp);
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
(!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th)))
-#define RUBY_VM_IFUNC_P(ptr) RB_TYPE_P((VALUE)(ptr), T_IMEMO)
-#define RUBY_VM_NORMAL_ISEQ_P(ptr) \
- ((ptr) && !RUBY_VM_IFUNC_P(ptr))
+#define RUBY_VM_IFUNC_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_ifunc)
+#define RUBY_VM_NORMAL_ISEQ_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_iseq)
#define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self))
#define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \
@@ -972,8 +971,8 @@ NORETURN(void rb_bug_context(const void *, const char *fmt, ...));
/* functions about thread/vm execution */
RUBY_SYMBOL_EXPORT_BEGIN
-VALUE rb_iseq_eval(VALUE iseqval);
-VALUE rb_iseq_eval_main(VALUE iseqval);
+VALUE rb_iseq_eval(const rb_iseq_t *iseq);
+VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
RUBY_SYMBOL_EXPORT_END
int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
diff --git a/vm_dump.c b/vm_dump.c
index dc27dd4c4a..553acf2800 100644
--- a/vm_dump.c
+++ b/vm_dump.c
@@ -39,7 +39,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
const rb_callable_method_entry_t *me;
if (cfp->block_iseq != 0 && !RUBY_VM_IFUNC_P(cfp->block_iseq)) {
- biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */
+ biseq_name = ""; /* RSTRING(cfp->block_iseq->body->location.label)->ptr; */
}
if (ep < 0 || (size_t)ep > th->stack_size) {
@@ -99,11 +99,11 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
iseq_name = "<ifunc>";
}
else {
- pc = cfp->pc - cfp->iseq->iseq_encoded;
- iseq_name = RSTRING_PTR(cfp->iseq->location.label);
+ pc = cfp->pc - cfp->iseq->body->iseq_encoded;
+ iseq_name = RSTRING_PTR(cfp->iseq->body->location.label);
line = rb_vm_get_sourceline(cfp);
if (line) {
- snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->location.path), line);
+ snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->body->location.path), line);
}
}
}
@@ -233,9 +233,9 @@ static VALUE *
vm_base_ptr(rb_control_frame_t *cfp)
{
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1;
+ VALUE *bp = prev_cfp->sp + cfp->iseq->body->local_size + 1;
- if (cfp->iseq->type == ISEQ_TYPE_METHOD) {
+ if (cfp->iseq->body->type == ISEQ_TYPE_METHOD) {
bp += 1;
}
return bp;
@@ -266,9 +266,9 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
name = "<ifunc>";
}
else {
- argc = iseq->param.lead_num;
- local_size = iseq->local_size;
- name = RSTRING_PTR(iseq->location.label);
+ argc = iseq->body->param.lead_num;
+ local_size = iseq->body->local_size;
+ name = RSTRING_PTR(iseq->body->location.label);
}
/* stack trace header */
@@ -335,7 +335,7 @@ rb_vmdebug_debug_print_register(rb_thread_t *th)
ptrdiff_t cfpi;
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- pc = cfp->pc - cfp->iseq->iseq_encoded;
+ pc = cfp->pc - cfp->iseq->body->iseq_encoded;
}
if (ep < 0 || (size_t)ep > th->stack_size) {
@@ -361,7 +361,7 @@ rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp,VALUE *_pc)
const rb_iseq_t *iseq = cfp->iseq;
if (iseq != 0) {
- ptrdiff_t pc = _pc - iseq->iseq_encoded;
+ ptrdiff_t pc = _pc - iseq->body->iseq_encoded;
int i;
for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) {
diff --git a/vm_eval.c b/vm_eval.c
index ff4abf53ed..a3ed8fa644 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -20,7 +20,7 @@ static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *a
static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
static inline VALUE vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, const rb_block_t *blockargptr);
static VALUE vm_exec(rb_thread_t *th);
-static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const rb_cref_t *cref, rb_block_t *base_block);
+static void vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, rb_block_t *base_block);
static int vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *dfp, const struct local_var_list *vars);
static VALUE rb_eUncaughtThrow;
@@ -1234,8 +1234,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
if ((state = TH_EXEC_TAG()) == 0) {
rb_cref_t *cref = cref_arg;
rb_binding_t *bind = 0;
- rb_iseq_t *iseq;
- volatile VALUE iseqval;
+ const rb_iseq_t *iseq;
VALUE absolute_path = Qnil;
VALUE fname;
@@ -1282,7 +1281,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
/* make eval iseq */
th->parse_in_eval++;
th->mild_compile_error++;
- iseqval = rb_iseq_compile_with_option(src, fname, absolute_path, INT2FIX(line), base_block, Qnil);
+ iseq = rb_iseq_compile_with_option(src, fname, absolute_path, INT2FIX(line), base_block, Qnil);
th->mild_compile_error--;
th->parse_in_eval--;
@@ -1297,17 +1296,16 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
cref = rb_vm_get_cref(base_block->ep);
}
}
- vm_set_eval_stack(th, iseqval, cref, base_block);
+ vm_set_eval_stack(th, iseq, cref, base_block);
RB_GC_GUARD(crefval);
if (0) { /* for debug */
- VALUE disasm = rb_iseq_disasm(iseqval);
+ VALUE disasm = rb_iseq_disasm(iseq);
printf("%s\n", StringValuePtr(disasm));
}
/* save new env */
- GetISeqPtr(iseqval, iseq);
- if (bind && iseq->local_table_size > 0) {
+ if (bind && iseq->body->local_table_size > 0) {
bind->env = vm_make_env_object(th, th->cfp);
}
@@ -2050,8 +2048,8 @@ rb_f_local_variables(void)
local_var_list_init(&vars);
while (cfp) {
if (cfp->iseq) {
- for (i = 0; i < cfp->iseq->local_table_size; i++) {
- local_var_list_add(&vars, cfp->iseq->local_table[i]);
+ for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
+ local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
}
}
if (!VM_EP_LEP_P(cfp->ep)) {
@@ -2117,7 +2115,7 @@ rb_current_realfilepath(void)
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
- if (cfp != 0) return cfp->iseq->location.absolute_path;
+ if (cfp != 0) return cfp->iseq->body->location.absolute_path;
return Qnil;
}
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index b3ff4fd0bc..357ed4daa4 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -845,15 +845,15 @@ vm_throw_start(rb_thread_t *const th, rb_control_frame_t *const reg_cfp, enum ru
const rb_iseq_t *base_iseq = GET_ISEQ();
escape_cfp = reg_cfp;
- while (base_iseq->type != ISEQ_TYPE_BLOCK) {
- if (escape_cfp->iseq->type == ISEQ_TYPE_CLASS) {
+ while (base_iseq->body->type != ISEQ_TYPE_BLOCK) {
+ if (escape_cfp->iseq->body->type == ISEQ_TYPE_CLASS) {
escape_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(escape_cfp);
ep = escape_cfp->ep;
base_iseq = escape_cfp->iseq;
}
else {
ep = VM_EP_PREV_EP(ep);
- base_iseq = base_iseq->parent_iseq;
+ base_iseq = base_iseq->body->parent_iseq;
escape_cfp = rb_vm_search_cf_from_ep(th, escape_cfp, ep);
VM_ASSERT(escape_cfp->iseq == base_iseq);
}
@@ -869,9 +869,9 @@ vm_throw_start(rb_thread_t *const th, rb_control_frame_t *const reg_cfp, enum ru
while (escape_cfp < eocfp) {
if (escape_cfp->ep == ep) {
- const VALUE epc = escape_cfp->pc - escape_cfp->iseq->iseq_encoded;
+ const VALUE epc = escape_cfp->pc - escape_cfp->iseq->body->iseq_encoded;
const rb_iseq_t * const iseq = escape_cfp->iseq;
- const struct iseq_catch_table * const ct = iseq->catch_table;
+ const struct iseq_catch_table * const ct = iseq->body->catch_table;
const int ct_size = ct->size;
int i;
@@ -919,7 +919,7 @@ vm_throw_start(rb_thread_t *const th, rb_control_frame_t *const reg_cfp, enum ru
target_lep = lep;
}
- if (lep == target_lep && escape_cfp->iseq->type == ISEQ_TYPE_CLASS) {
+ if (lep == target_lep && escape_cfp->iseq->body->type == ISEQ_TYPE_CLASS) {
in_class_frame = 1;
target_lep = 0;
}
@@ -944,7 +944,7 @@ vm_throw_start(rb_thread_t *const th, rb_control_frame_t *const reg_cfp, enum ru
}
}
- if (escape_cfp->ep == target_lep && escape_cfp->iseq->type == ISEQ_TYPE_METHOD) {
+ if (escape_cfp->ep == target_lep && escape_cfp->iseq->body->type == ISEQ_TYPE_METHOD) {
goto valid_return;
}
@@ -1198,9 +1198,9 @@ static VALUE *
vm_base_ptr(rb_control_frame_t *cfp)
{
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1;
+ VALUE *bp = prev_cfp->sp + cfp->iseq->body->local_size + 1;
- if (cfp->iseq->type == ISEQ_TYPE_METHOD) {
+ if (cfp->iseq->body->type == ISEQ_TYPE_METHOD) {
/* adjust `self' */
bp += 1;
}
@@ -1241,9 +1241,9 @@ vm_callee_setup_block_arg_arg0_splat(rb_control_frame_t *cfp, const rb_iseq_t *i
int i;
long len = RARRAY_LEN(ary);
- CHECK_VM_STACK_OVERFLOW(cfp, iseq->param.lead_num);
+ CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num);
- for (i=0; i<len && i<iseq->param.lead_num; i++) {
+ for (i=0; i<len && i<iseq->body->param.lead_num; i++) {
argv[i] = RARRAY_AREF(ary, i);
}
@@ -1253,12 +1253,12 @@ vm_callee_setup_block_arg_arg0_splat(rb_control_frame_t *cfp, const rb_iseq_t *i
static inline int
simple_iseq_p(const rb_iseq_t *iseq)
{
- return iseq->param.flags.has_opt == FALSE &&
- iseq->param.flags.has_rest == FALSE &&
- iseq->param.flags.has_post == FALSE &&
- iseq->param.flags.has_kw == FALSE &&
- iseq->param.flags.has_kwrest == FALSE &&
- iseq->param.flags.has_block == FALSE;
+ return iseq->body->param.flags.has_opt == FALSE &&
+ iseq->body->param.flags.has_rest == FALSE &&
+ iseq->body->param.flags.has_post == FALSE &&
+ iseq->body->param.flags.has_kw == FALSE &&
+ iseq->body->param.flags.has_kwrest == FALSE &&
+ iseq->body->param.flags.has_block == FALSE;
}
static inline void
@@ -1272,32 +1272,32 @@ vm_callee_setup_block_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *
if (arg_setup_type == arg_setup_block &&
ci->argc == 1 &&
- iseq->param.flags.has_lead &&
- !iseq->param.flags.ambiguous_param0 &&
+ iseq->body->param.flags.has_lead &&
+ !iseq->body->param.flags.ambiguous_param0 &&
!NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) {
ci->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
}
- if (ci->argc != iseq->param.lead_num) {
+ if (ci->argc != iseq->body->param.lead_num) {
if (arg_setup_type == arg_setup_block) {
- if (ci->argc < iseq->param.lead_num) {
+ if (ci->argc < iseq->body->param.lead_num) {
int i;
- CHECK_VM_STACK_OVERFLOW(cfp, iseq->param.lead_num);
- for (i=ci->argc; i<iseq->param.lead_num; i++) argv[i] = Qnil;
- ci->argc = iseq->param.lead_num; /* fill rest parameters */
+ CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num);
+ for (i=ci->argc; i<iseq->body->param.lead_num; i++) argv[i] = Qnil;
+ ci->argc = iseq->body->param.lead_num; /* fill rest parameters */
}
- else if (ci->argc > iseq->param.lead_num) {
- ci->argc = iseq->param.lead_num; /* simply truncate arguments */
+ else if (ci->argc > iseq->body->param.lead_num) {
+ ci->argc = iseq->body->param.lead_num; /* simply truncate arguments */
}
}
else if (arg_setup_type == arg_setup_lambda &&
ci->argc == 1 &&
!NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv)) &&
- RARRAY_LEN(arg0) == iseq->param.lead_num) {
+ RARRAY_LEN(arg0) == iseq->body->param.lead_num) {
ci->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
}
else {
- argument_arity_error(th, iseq, ci->argc, iseq->param.lead_num, iseq->param.lead_num);
+ argument_arity_error(th, iseq, ci->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
}
}
@@ -1316,8 +1316,8 @@ vm_callee_setup_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq,
CALLER_SETUP_ARG(cfp, ci); /* splat arg */
- if (ci->argc != iseq->param.lead_num) {
- argument_arity_error(th, iseq, ci->argc, iseq->param.lead_num, iseq->param.lead_num);
+ if (ci->argc != iseq->body->param.lead_num) {
+ argument_arity_error(th, iseq, ci->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
}
ci->aux.opt_pc = 0;
@@ -1365,16 +1365,16 @@ vm_call_iseq_setup_normal(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info
VALUE *argv = cfp->sp - ci->argc;
const rb_callable_method_entry_t *me = ci->me;
const rb_iseq_t *iseq = def_iseq_ptr(me->def);
- VALUE *sp = argv + iseq->param.size;
+ VALUE *sp = argv + iseq->body->param.size;
/* clear local variables (arg_size...local_size) */
- for (i = iseq->param.size, local_size = iseq->local_size; i < local_size; i++) {
+ for (i = iseq->body->param.size, local_size = iseq->body->local_size; i < local_size; i++) {
*sp++ = Qnil;
}
vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, ci->recv,
VM_ENVVAL_BLOCK_PTR(ci->blockptr), (VALUE)me,
- iseq->iseq_encoded + ci->aux.opt_pc, sp, 0, iseq->stack_max);
+ iseq->body->iseq_encoded + ci->aux.opt_pc, sp, 0, iseq->body->stack_max);
cfp->sp = argv - 1 /* recv */;
return Qundef;
@@ -1402,18 +1402,18 @@ vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_in
sp++;
/* copy arguments */
- for (i=0; i < iseq->param.size; i++) {
+ for (i=0; i < iseq->body->param.size; i++) {
*sp++ = src_argv[i];
}
/* clear local variables */
- for (i = 0; i < iseq->local_size - iseq->param.size; i++) {
+ for (i = 0; i < iseq->body->local_size - iseq->body->param.size; i++) {
*sp++ = Qnil;
}
vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | finish_flag,
ci->recv, VM_ENVVAL_BLOCK_PTR(ci->blockptr), (VALUE)me,
- iseq->iseq_encoded + ci->aux.opt_pc, sp, 0, iseq->stack_max);
+ iseq->body->iseq_encoded + ci->aux.opt_pc, sp, 0, iseq->body->stack_max);
cfp->sp = sp_orig;
return Qundef;
@@ -1869,8 +1869,9 @@ current_method_entry(rb_thread_t *th, rb_control_frame_t *cfp)
{
rb_control_frame_t *top_cfp = cfp;
- if (cfp->iseq && cfp->iseq->type == ISEQ_TYPE_BLOCK) {
- const rb_iseq_t *local_iseq = cfp->iseq->local_iseq;
+ if (cfp->iseq && cfp->iseq->body->type == ISEQ_TYPE_BLOCK) {
+ const rb_iseq_t *local_iseq = cfp->iseq->body->local_iseq;
+
do {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
@@ -2306,7 +2307,7 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci
{
const rb_block_t *block = VM_CF_BLOCK_PTR(reg_cfp);
const rb_iseq_t *iseq;
- VALUE type = GET_ISEQ()->local_iseq->type;
+ VALUE type = GET_ISEQ()->body->local_iseq->body->type;
if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) || block == 0) {
rb_vm_localjump_error("no block given (yield)", Qnil, 0);
@@ -2315,7 +2316,7 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci
if (!RUBY_VM_IFUNC_P(iseq)) {
int opt_pc;
- const int arg_size = iseq->param.size;
+ const int arg_size = iseq->body->param.size;
int is_lambda = block_proc_is_lambda(block->proc);
VALUE * const rsp = GET_SP() - ci->argc;
@@ -2327,9 +2328,9 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci
is_lambda ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK,
block->self,
VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
- iseq->iseq_encoded + opt_pc,
+ iseq->body->iseq_encoded + opt_pc,
rsp + arg_size,
- iseq->local_size - arg_size, iseq->stack_max);
+ iseq->body->local_size - arg_size, iseq->body->stack_max);
return Qundef;
}
diff --git a/vm_method.c b/vm_method.c
index 0ae14c833a..1364e5a4a5 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -254,7 +254,7 @@ method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def,
cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp && (line = rb_vm_get_sourceline(cfp))) {
- VALUE location = rb_ary_new3(2, cfp->iseq->location.path, INT2FIX(line));
+ VALUE location = rb_ary_new3(2, cfp->iseq->body->location.path, INT2FIX(line));
RB_OBJ_WRITE(me, &def->body.attr.location, rb_ary_freeze(location));
}
else {
@@ -296,7 +296,7 @@ method_definition_reset(const rb_method_entry_t *me)
switch(def->type) {
case VM_METHOD_TYPE_ISEQ:
- RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.iseqptr->self);
+ RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.iseqptr);
RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.cref);
break;
case VM_METHOD_TYPE_ATTRSET:
@@ -512,9 +512,9 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
default:
break;
}
- if (iseq && !NIL_P(iseq->location.path)) {
- int line = iseq->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq->self)) : 0;
- rb_compile_warning(RSTRING_PTR(iseq->location.path), line,
+ if (iseq && !NIL_P(iseq->body->location.path)) {
+ int line = iseq->body->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq)) : 0;
+ rb_compile_warning(RSTRING_PTR(iseq->body->location.path), line,
"previous definition of %"PRIsVALUE" was here",
rb_id2str(old_def->original_id));
}
@@ -583,19 +583,16 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
}
void
-rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi)
+rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
{
- rb_iseq_t *iseq;
struct { /* should be same fields with rb_method_iseq_struct */
- rb_iseq_t *iseqptr;
+ const rb_iseq_t *iseqptr;
rb_cref_t *cref;
} iseq_body;
- GetISeqPtr(iseqval, iseq);
iseq_body.iseqptr = iseq;
iseq_body.cref = cref;
rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
- RB_GC_GUARD(iseqval);
}
static rb_method_entry_t *
diff --git a/vm_trace.c b/vm_trace.c
index b46437038c..529cb720df 100644
--- a/vm_trace.c
+++ b/vm_trace.c
@@ -750,7 +750,7 @@ fill_path_and_lineno(rb_trace_arg_t *trace_arg)
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->th, trace_arg->cfp);
if (cfp) {
- trace_arg->path = cfp->iseq->location.path;
+ trace_arg->path = cfp->iseq->body->location.path;
trace_arg->lineno = rb_vm_get_sourceline(cfp);
}
else {