* 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
This commit is contained in:
ko1 2015-07-21 22:52:59 +00:00
parent 6053426a66
commit e4198a73d4
25 changed files with 1155 additions and 1138 deletions

View File

@ -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> Wed Jul 22 07:15:33 2015 Koichi Sasada <ko1@atdot.net>
* ext/objspace/objspace.c (total_i): no need to skip singleton classes. * ext/objspace/objspace.c (total_i): no need to skip singleton classes.

View File

@ -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) { if (me->def->type == VM_METHOD_TYPE_ISEQ) {
rb_cref_t *new_cref; rb_cref_t *new_cref;
rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass, &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 { else {
rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me)); rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me));

742
compile.c

File diff suppressed because it is too large Load Diff

6
eval.c
View File

@ -237,7 +237,7 @@ static int
ruby_exec_internal(void *n) ruby_exec_internal(void *n)
{ {
volatile int state; volatile int state;
VALUE iseq = (VALUE)n; rb_iseq_t *iseq = (rb_iseq_t *)n;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
if (!n) return 0; if (!n) return 0;
@ -1448,10 +1448,10 @@ errinfo_place(rb_thread_t *th)
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) { while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { 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]; 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]) && !THROW_DATA_P(cfp->ep[-2]) &&
!FIXNUM_P(cfp->ep[-2])) { !FIXNUM_P(cfp->ep[-2])) {
return &cfp->ep[-2]; return &cfp->ep[-2];

View File

@ -497,7 +497,7 @@ count_tdata_objects(int argc, VALUE *argv, VALUE self)
return hash; return hash;
} }
static ID imemo_type_ids[imemo_mask]; static ID imemo_type_ids[imemo_mask+1];
static int static int
count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data) 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[4] = rb_intern("imemo_ifunc");
imemo_type_ids[5] = rb_intern("imemo_memo"); imemo_type_ids[5] = rb_intern("imemo_memo");
imemo_type_ids[6] = rb_intern("imemo_ment"); 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); rb_objspace_each_objects(count_imemo_objects_i, (void *)hash);

60
gc.c
View File

@ -404,6 +404,7 @@ typedef struct RVALUE {
struct vm_ifunc ifunc; struct vm_ifunc ifunc;
struct MEMO memo; struct MEMO memo;
struct rb_method_entry_struct ment; struct rb_method_entry_struct ment;
const rb_iseq_t iseq;
} imemo; } imemo;
struct { struct {
struct RBasic basic; struct RBasic basic;
@ -699,6 +700,7 @@ static rb_objspace_t rb_objspace = {{GC_MALLOC_LIMIT_MIN}};
#endif #endif
#define ruby_initial_gc_stress gc_params.gc_stress #define ruby_initial_gc_stress gc_params.gc_stress
VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress; VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
#define malloc_limit objspace->malloc_params.limit #define malloc_limit objspace->malloc_params.limit
@ -778,6 +780,9 @@ int ruby_gc_debug_indent = 0;
VALUE rb_mGC; VALUE rb_mGC;
int ruby_disable_gc = 0; 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); void rb_gcdebug_print_obj_condition(VALUE obj);
static void rb_objspace_call_finalizer(rb_objspace_t *objspace); 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: 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); 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: default:
rb_bug("gc_sweep(): unknown data type 0x%x(%p) 0x%"PRIxVALUE, 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) { if (def) {
switch (def->type) { switch (def->type) {
case VM_METHOD_TYPE_ISEQ: 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); gc_mark(objspace, (VALUE)def->body.iseq.cref);
break; break;
case VM_METHOD_TYPE_ATTRSET: case VM_METHOD_TYPE_ATTRSET:
@ -4272,6 +4284,9 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case T_IMEMO: case T_IMEMO:
switch (imemo_type(obj)) { switch (imemo_type(obj)) {
case imemo_none:
rb_bug("unreachable");
return;
case imemo_cref: case imemo_cref:
gc_mark(objspace, RANY(obj)->as.imemo.cref.klass); gc_mark(objspace, RANY(obj)->as.imemo.cref.klass);
gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next); 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: case imemo_ment:
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment); mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
return; return;
default: case imemo_iseq:
rb_bug("T_IMEMO: unreachable"); rb_iseq_mark((rb_iseq_t *)obj);
return;
} }
rb_bug("T_IMEMO: unreachable");
} }
gc_mark(objspace, any->as.basic.klass); 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: { case T_DATA: {
const char * const type_name = rb_objspace_data_type_name(obj); const char * const type_name = rb_objspace_data_type_name(obj);
if (type_name && strcmp(type_name, "iseq") == 0) { if (type_name) {
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) {
snprintf(buff, buff_size, "%s %s", buff, type_name); snprintf(buff, buff_size, "%s %s", buff, type_name);
} }
break; break;
@ -8945,10 +8954,25 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
#undef IMEMO_NAME #undef IMEMO_NAME
} }
snprintf(buff, buff_size, "%s %s", buff, 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; switch (imemo_type(obj)) {
snprintf(buff, buff_size, "%s (called_id: %s, type: %s, alias: %d, class: %s)", buff, case imemo_ment: {
rb_id2name(me->called_id), method_type_name(me->def->type), me->def->alias_count, obj_info(me->defined_class)); 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: default:

View File

@ -337,7 +337,7 @@ putiseq
() ()
(VALUE ret) (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_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, klass,
VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()), VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
(VALUE)vm_cref_push(th, klass, NULL), (VALUE)vm_cref_push(th, klass, NULL),
class_iseq->iseq_encoded, GET_SP(), class_iseq->body->iseq_encoded, GET_SP(),
class_iseq->local_size, class_iseq->stack_max); class_iseq->body->local_size, class_iseq->body->stack_max);
RESTORE_REGS(); RESTORE_REGS();
NEXT_INSN(); NEXT_INSN();

View File

@ -546,6 +546,7 @@ enum imemo_type {
imemo_ifunc = 4, imemo_ifunc = 4,
imemo_memo = 5, imemo_memo = 5,
imemo_ment = 6, imemo_ment = 6,
imemo_iseq = 7,
imemo_mask = 0x07 imemo_mask = 0x07
}; };
@ -854,14 +855,6 @@ void rb_write_error_str(VALUE mesg);
VALUE rb_io_flush_raw(VALUE, int); VALUE rb_io_flush_raw(VALUE, int);
size_t rb_io_memsize(const rb_io_t *); 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 */ /* load.c */
VALUE rb_get_load_path(void); VALUE rb_get_load_path(void);
VALUE rb_get_expanded_load_path(void); VALUE rb_get_expanded_load_path(void);

828
iseq.c

File diff suppressed because it is too large Load Diff

29
iseq.h
View File

@ -15,12 +15,12 @@
RUBY_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
/* compile.c */ /* 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); int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
VALUE *rb_iseq_original_iseq(rb_iseq_t *iseq); VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
VALUE locals, VALUE args, VALUE locals, VALUE args,
VALUE exception, VALUE body); VALUE exception, VALUE body);
/* iseq.c */ /* iseq.c */
void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj); 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); struct st_table *ruby_insn_make_insn_table(void);
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos); 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); int rb_iseqw_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_iseqw_line_trace_all(VALUE iseqval);
VALUE rb_iseq_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set); 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 */ /* proc.c */
const rb_iseq_t *rb_method_iseq(VALUE body); 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_REDO = INT2FIX(5),
CATCH_TYPE_NEXT = INT2FIX(6) CATCH_TYPE_NEXT = INT2FIX(6)
} type; } type;
VALUE iseq; const rb_iseq_t *iseq;
unsigned int start; unsigned int start;
unsigned int end; unsigned int end;
unsigned int cont; unsigned int cont;
@ -109,7 +118,7 @@ struct iseq_compile_data {
struct iseq_label_data *start_label; struct iseq_label_data *start_label;
struct iseq_label_data *end_label; struct iseq_label_data *end_label;
struct iseq_label_data *redo_label; struct iseq_label_data *redo_label;
VALUE current_block; const rb_iseq_t *current_block;
VALUE ensure_node; VALUE ensure_node;
VALUE for_iseq; VALUE for_iseq;
struct iseq_compile_data_ensure_node_stack *ensure_node_stack; struct iseq_compile_data_ensure_node_stack *ensure_node_stack;

4
load.c
View File

@ -602,12 +602,12 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
state = EXEC_TAG(); state = EXEC_TAG();
if (state == 0) { if (state == 0) {
NODE *node; NODE *node;
VALUE iseq; rb_iseq_t *iseq;
th->mild_compile_error++; th->mild_compile_error++;
node = (NODE *)rb_load_file_str(fname); node = (NODE *)rb_load_file_str(fname);
loaded = TRUE; 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--; th->mild_compile_error--;
rb_iseq_eval(iseq); rb_iseq_eval(iseq);
} }

View File

@ -121,7 +121,7 @@ typedef enum {
typedef struct rb_iseq_struct rb_iseq_t; typedef struct rb_iseq_struct rb_iseq_t;
typedef struct rb_method_iseq_struct { 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_cref_t * const cref; /* shoudl be marked */
} rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */ } 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)) 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_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); 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); rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);

30
proc.c
View File

@ -369,8 +369,8 @@ get_local_variable_ptr(VALUE envval, ID lid)
iseq = env->block.iseq; iseq = env->block.iseq;
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) { if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
for (i=0; i<iseq->local_table_size; i++) { for (i=0; i<iseq->body->local_table_size; i++) {
if (iseq->local_table[i] == lid) { if (iseq->body->local_table[i] == lid) {
return &env->env[i]; return &env->env[i];
} }
} }
@ -735,7 +735,7 @@ proc_call(int argc, VALUE *argv, VALUE procval)
GetProcPtr(procval, proc); GetProcPtr(procval, proc);
iseq = proc->block.iseq; 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()) { if (rb_block_given_p()) {
rb_proc_t *passed_proc; rb_proc_t *passed_proc;
RB_GC_GUARD(passed_procval) = rb_block_proc(); RB_GC_GUARD(passed_procval) = rb_block_proc();
@ -847,11 +847,11 @@ proc_arity(VALUE self)
static inline int static inline int
rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max) rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max)
{ {
*max = iseq->param.flags.has_rest == FALSE ? *max = iseq->body->param.flags.has_rest == FALSE ?
iseq->param.lead_num + iseq->param.opt_num + iseq->param.post_num + iseq->body->param.lead_num + iseq->body->param.opt_num + iseq->body->param.post_num +
(iseq->param.flags.has_kw == TRUE || iseq->param.flags.has_kwrest == TRUE) (iseq->body->param.flags.has_kw == TRUE || iseq->body->param.flags.has_kwrest == TRUE)
: UNLIMITED_ARGUMENTS; : 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 static int
@ -950,9 +950,9 @@ iseq_location(const rb_iseq_t *iseq)
VALUE loc[2]; VALUE loc[2];
if (!iseq) return Qnil; if (!iseq) return Qnil;
loc[0] = iseq->location.path; loc[0] = iseq->body->location.path;
if (iseq->line_info_table) { if (iseq->body->line_info_table) {
loc[1] = rb_iseq_first_lineno(iseq->self); loc[1] = rb_iseq_first_lineno(iseq);
} }
else { else {
loc[1] = Qnil; loc[1] = Qnil;
@ -1066,11 +1066,11 @@ proc_to_s(VALUE self)
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) { if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
int first_lineno = 0; int first_lineno = 0;
if (iseq->line_info_table) { if (iseq->body->line_info_table) {
first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self)); first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
} }
str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self, 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 { else {
str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq, str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
@ -2558,8 +2558,8 @@ proc_binding(VALUE self)
} }
if (iseq) { if (iseq) {
bind->path = iseq->location.path; bind->path = iseq->body->location.path;
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self)); bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
} }
else { else {
bind->path = Qnil; bind->path = Qnil;

6
ruby.c
View File

@ -1305,7 +1305,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
{ {
NODE *tree = 0; NODE *tree = 0;
VALUE parser; VALUE parser;
VALUE iseq; const rb_iseq_t *iseq;
rb_encoding *enc, *lenc; rb_encoding *enc, *lenc;
const char *s; const char *s;
char fbuf[MAXPATHLEN]; char fbuf[MAXPATHLEN];
@ -1544,7 +1544,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
}); });
if (opt->dump & DUMP_BIT(insns)) { 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); rb_io_flush(rb_stdout);
return Qtrue; return Qtrue;
} }
@ -1555,7 +1555,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
rb_set_safe_level(opt->safe_level); rb_set_safe_level(opt->safe_level);
return iseq; return (VALUE)iseq;
} }
struct load_file_arg { struct load_file_arg {

View File

@ -19,8 +19,8 @@ enum {
AREF_HASH_THRESHOLD = 10 AREF_HASH_THRESHOLD = 10
}; };
VALUE rb_method_for_self_aref(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);
VALUE rb_method_for_self_aset(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; VALUE rb_cStruct;
static ID id_members, id_back_members; static ID id_members, id_back_members;
@ -287,18 +287,18 @@ static void
define_aref_method(VALUE nstr, VALUE name, VALUE off) 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 *); 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 static void
define_aset_method(VALUE nstr, VALUE name, VALUE off) 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 *); 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 static VALUE

View File

@ -5226,7 +5226,7 @@ rb_check_deadlock(rb_vm_t *vm)
static void static void
update_coverage(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass) 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) { if (coverage && RBASIC(coverage)->klass == 0) {
long line = rb_sourceline() - 1; long line = rb_sourceline() - 1;
long count; long count;

153
vm.c
View File

@ -247,12 +247,9 @@ vm_stat(int argc, VALUE *argv, VALUE self)
/* control stack frame */ /* control stack frame */
static void 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; if (iseq->body->type != ISEQ_TYPE_TOP) {
GetISeqPtr(iseqval, iseq);
if (iseq->type != ISEQ_TYPE_TOP) {
rb_raise(rb_eTypeError, "Not a toplevel InstructionSequence"); 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_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH, th->top_self,
VM_ENVVAL_BLOCK_PTR(0), VM_ENVVAL_BLOCK_PTR(0),
(VALUE)vm_cref_new_toplevel(th), /* cref or me */ (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 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, vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL | VM_FRAME_FLAG_FINISH,
base_block->self, VM_ENVVAL_PREV_EP_PTR(base_block->ep), base_block->self, VM_ENVVAL_PREV_EP_PTR(base_block->ep),
(VALUE)cref, /* cref or me */ (VALUE)cref, /* cref or me */
iseq->iseq_encoded, iseq->body->iseq_encoded,
th->cfp->sp, iseq->local_size, iseq->stack_max); th->cfp->sp, iseq->body->local_size, iseq->body->stack_max);
} }
static void 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")); VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING"));
rb_binding_t *bind; rb_binding_t *bind;
rb_iseq_t *iseq;
rb_env_t *env; rb_env_t *env;
GetBindingPtr(toplevel_binding, bind); GetBindingPtr(toplevel_binding, bind);
GetEnvPtr(bind->env, env); GetEnvPtr(bind->env, env);
vm_set_eval_stack(th, iseqval, 0, &env->block);
vm_set_eval_stack(th, iseq, 0, &env->block);
/* save binding */ /* save binding */
GetISeqPtr(iseqval, iseq); if (bind && iseq->body->local_size > 0) {
if (bind && iseq->local_size > 0) {
bind->env = vm_make_env_object(th, th->cfp); 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); rb_gc_mark((VALUE)env->block.iseq);
} }
else { else {
RUBY_MARK_UNLESS_NULL(env->block.iseq->self); RUBY_MARK_UNLESS_NULL((VALUE)env->block.iseq);
} }
} }
RUBY_MARK_LEAVE("env"); 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 */; local_size = 1 /* cref/me */;
} }
else { 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; int i;
if (!iseq) return 0; if (!iseq) return 0;
for (i = 0; i < iseq->local_table_size; i++) { for (i = 0; i < iseq->body->local_table_size; i++) {
local_var_list_add(vars, iseq->local_table[i]); local_var_list_add(vars, iseq->body->local_table[i]);
} }
return 1; 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); bindval = rb_binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind); GetBindingPtr(bindval, bind);
bind->env = envval; 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); bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
return bindval; return bindval;
@ -765,11 +758,11 @@ rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
VALUE * VALUE *
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars) 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_env_t *env;
rb_block_t *base_block; rb_block_t *base_block;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
const rb_iseq_t *base_iseq; const rb_iseq_t *base_iseq, *iseq;
NODE *node = 0; NODE *node = 0;
ID minibuf[4], *dyns = minibuf; ID minibuf[4], *dyns = minibuf;
VALUE idtmp = 0; 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); node = NEW_NODE(NODE_SCOPE, dyns, 0, 0);
if (base_iseq) { if (base_iseq) {
iseqval = rb_iseq_new(node, base_iseq->location.label, path, path, iseq = rb_iseq_new(node, base_iseq->body->location.label, path, path, base_iseq, ISEQ_TYPE_EVAL);
base_iseq->self, ISEQ_TYPE_EVAL);
} }
else { else {
VALUE tempstr = rb_str_new2("<temp>"); 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 */ node->u1.tbl = 0; /* reset table */
ALLOCV_END(idtmp); 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); bind->env = vm_make_env_object(th, th->cfp);
vm_pop_frame(th); vm_pop_frame(th);
GetEnvPtr(bind->env, env); GetEnvPtr(bind->env, env);
@ -821,7 +813,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
VALUE ret; VALUE ret;
const rb_iseq_t *iseq = block->iseq; const rb_iseq_t *iseq = block->iseq;
const rb_control_frame_t *cfp; 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; 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; const rb_callable_method_entry_t *me = th->passed_bmethod_me;
th->passed_bmethod_me = NULL; 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_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self,
VM_ENVVAL_PREV_EP_PTR(block->ep), VM_ENVVAL_PREV_EP_PTR(block->ep),
(VALUE)me, /* cref or method (TODO: can we ignore cref?) */ (VALUE)me, /* cref or method (TODO: can we ignore cref?) */
iseq->iseq_encoded + opt_pc, iseq->body->iseq_encoded + opt_pc,
cfp->sp + arg_size, iseq->local_size - arg_size, cfp->sp + arg_size, iseq->body->local_size - arg_size,
iseq->stack_max); iseq->body->stack_max);
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->called_id); 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); 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_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH, self,
VM_ENVVAL_PREV_EP_PTR(block->ep), VM_ENVVAL_PREV_EP_PTR(block->ep),
(VALUE)cref, /* cref or method */ (VALUE)cref, /* cref or method */
iseq->iseq_encoded + opt_pc, iseq->body->iseq_encoded + opt_pc,
cfp->sp + arg_size, iseq->local_size - arg_size, cfp->sp + arg_size, iseq->body->local_size - arg_size,
iseq->stack_max); iseq->body->stack_max);
} }
ret = vm_exec(th); 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); rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) { if (cfp) {
return cfp->iseq->location.path; return cfp->iseq->body->location.path;
} }
else { else {
return Qnil; return Qnil;
@ -1035,7 +1027,7 @@ rb_sourcefile(void)
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) { if (cfp) {
return RSTRING_PTR(cfp->iseq->location.path); return RSTRING_PTR(cfp->iseq->body->location.path);
} }
else { else {
return 0; return 0;
@ -1489,7 +1481,7 @@ vm_exec(rb_thread_t *th)
struct iseq_catch_table_entry *entry; struct iseq_catch_table_entry *entry;
struct iseq_catch_table *ct; struct iseq_catch_table *ct;
unsigned long epc, cont_pc, cont_sp; unsigned long epc, cont_pc, cont_sp;
VALUE catch_iseqval; const rb_iseq_t *catch_iseq;
rb_control_frame_t *cfp; rb_control_frame_t *cfp;
VALUE type; VALUE type;
const rb_control_frame_t *escape_cfp; const rb_control_frame_t *escape_cfp;
@ -1497,7 +1489,8 @@ vm_exec(rb_thread_t *th)
err = (struct vm_throw_data *)th->errinfo; err = (struct vm_throw_data *)th->errinfo;
exception_handler: 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) { while (th->cfp->pc == 0 || th->cfp->iseq == 0) {
if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) { if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
@ -1512,7 +1505,7 @@ vm_exec(rb_thread_t *th)
} }
cfp = th->cfp; cfp = th->cfp;
epc = cfp->pc - cfp->iseq->iseq_encoded; epc = cfp->pc - cfp->iseq->body->iseq_encoded;
escape_cfp = NULL; escape_cfp = NULL;
if (state == TAG_BREAK || state == TAG_RETURN) { 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); THROW_DATA_STATE_SET(err, state = TAG_BREAK);
} }
else { else {
ct = cfp->iseq->catch_table; ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) { if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i]; entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) { if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) { if (entry->type == CATCH_TYPE_ENSURE) {
catch_iseqval = entry->iseq; catch_iseq = entry->iseq;
cont_pc = entry->cont; cont_pc = entry->cont;
cont_sp = entry->sp; cont_sp = entry->sp;
break; break;
} }
} }
} }
if (!catch_iseqval) { if (!catch_iseq) {
th->errinfo = Qnil; th->errinfo = Qnil;
result = THROW_DATA_VAL(err); result = THROW_DATA_VAL(err);
hook_before_rewind(th, th->cfp); hook_before_rewind(th, th->cfp);
@ -1561,14 +1554,14 @@ vm_exec(rb_thread_t *th)
} }
if (state == TAG_RAISE) { if (state == TAG_RAISE) {
ct = cfp->iseq->catch_table; ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) { if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i]; entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) { if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_RESCUE || if (entry->type == CATCH_TYPE_RESCUE ||
entry->type == CATCH_TYPE_ENSURE) { entry->type == CATCH_TYPE_ENSURE) {
catch_iseqval = entry->iseq; catch_iseq = entry->iseq;
cont_pc = entry->cont; cont_pc = entry->cont;
cont_sp = entry->sp; cont_sp = entry->sp;
break; break;
@ -1577,13 +1570,13 @@ vm_exec(rb_thread_t *th)
} }
} }
else if (state == TAG_RETRY) { 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++) { if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i]; entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) { if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) { if (entry->type == CATCH_TYPE_ENSURE) {
catch_iseqval = entry->iseq; catch_iseq = entry->iseq;
cont_pc = entry->cont; cont_pc = entry->cont;
cont_sp = entry->sp; cont_sp = entry->sp;
break; break;
@ -1592,7 +1585,7 @@ vm_exec(rb_thread_t *th)
const rb_control_frame_t *escape_cfp; const rb_control_frame_t *escape_cfp;
escape_cfp = THROW_DATA_CATCH_FRAME(err); escape_cfp = THROW_DATA_CATCH_FRAME(err);
if (cfp == escape_cfp) { if (cfp == escape_cfp) {
cfp->pc = cfp->iseq->iseq_encoded + entry->cont; cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
th->errinfo = Qnil; th->errinfo = Qnil;
goto vm_loop_start; goto vm_loop_start;
} }
@ -1604,19 +1597,19 @@ vm_exec(rb_thread_t *th)
type = CATCH_TYPE_BREAK; type = CATCH_TYPE_BREAK;
search_restart_point: search_restart_point:
ct = cfp->iseq->catch_table; ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) { if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i]; entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) { if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) { if (entry->type == CATCH_TYPE_ENSURE) {
catch_iseqval = entry->iseq; catch_iseq = entry->iseq;
cont_pc = entry->cont; cont_pc = entry->cont;
cont_sp = entry->sp; cont_sp = entry->sp;
break; break;
} }
else if (entry->type == type) { 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; cfp->sp = vm_base_ptr(cfp) + entry->sp;
if (state != TAG_REDO) { if (state != TAG_REDO) {
@ -1642,13 +1635,13 @@ vm_exec(rb_thread_t *th)
goto search_restart_point; goto search_restart_point;
} }
else { else {
ct = cfp->iseq->catch_table; ct = cfp->iseq->body->catch_table;
if (ct) for (i = 0; i < ct->size; i++) { if (ct) for (i = 0; i < ct->size; i++) {
entry = &ct->entries[i]; entry = &ct->entries[i];
if (entry->start < epc && entry->end >= epc) { if (entry->start < epc && entry->end >= epc) {
if (entry->type == CATCH_TYPE_ENSURE) { if (entry->type == CATCH_TYPE_ENSURE) {
catch_iseqval = entry->iseq; catch_iseq = entry->iseq;
cont_pc = entry->cont; cont_pc = entry->cont;
cont_sp = entry->sp; cont_sp = entry->sp;
break; break;
@ -1657,14 +1650,10 @@ vm_exec(rb_thread_t *th)
} }
} }
if (catch_iseqval != 0) { if (catch_iseq != 0) { /* found catch table */
/* found catch table */
rb_iseq_t *catch_iseq;
/* enter catch scope */ /* enter catch scope */
GetISeqPtr(catch_iseqval, catch_iseq);
cfp->sp = vm_base_ptr(cfp) + cont_sp; 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 */ /* push block frame */
cfp->sp[0] = (VALUE)err; cfp->sp[0] = (VALUE)err;
@ -1672,10 +1661,10 @@ vm_exec(rb_thread_t *th)
cfp->self, cfp->self,
VM_ENVVAL_PREV_EP_PTR(cfp->ep), VM_ENVVAL_PREV_EP_PTR(cfp->ep),
0, /* cref or me */ 0, /* cref or me */
catch_iseq->iseq_encoded, catch_iseq->body->iseq_encoded,
cfp->sp + 1 /* push value */, cfp->sp + 1 /* push value */,
catch_iseq->local_size - 1, catch_iseq->body->local_size - 1,
catch_iseq->stack_max); catch_iseq->body->stack_max);
state = 0; state = 0;
th->state = 0; th->state = 0;
@ -1706,28 +1695,23 @@ vm_exec(rb_thread_t *th)
/* misc */ /* misc */
VALUE VALUE
rb_iseq_eval(VALUE iseqval) rb_iseq_eval(const rb_iseq_t *iseq)
{ {
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
VALUE val; VALUE val;
vm_set_top_stack(th, iseq);
vm_set_top_stack(th, iseqval);
val = vm_exec(th); val = vm_exec(th);
RB_GC_GUARD(iseqval); /* prohibit tail call optimization */
return val; return val;
} }
VALUE VALUE
rb_iseq_eval_main(VALUE iseqval) rb_iseq_eval_main(const rb_iseq_t *iseq)
{ {
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
VALUE val; VALUE val;
vm_set_main_stack(th, iseqval); vm_set_main_stack(th, iseq);
val = vm_exec(th); val = vm_exec(th);
RB_GC_GUARD(iseqval); /* prohibit tail call optimization */
return val; return val;
} }
@ -1770,7 +1754,7 @@ rb_thread_current_status(const rb_thread_t *th)
const rb_iseq_t *iseq = cfp->iseq; const rb_iseq_t *iseq = cfp->iseq;
int line_no = rb_vm_get_sourceline(cfp); int line_no = rb_vm_get_sourceline(cfp);
str = rb_sprintf("%"PRIsVALUE":%d:in `%"PRIsVALUE"'", 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) { 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(); rb_thread_t *th = GET_THREAD();
const rb_control_frame_t *reg_cfp = th->cfp; 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; 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), recv, VM_ENVVAL_BLOCK_PTR(blockptr),
(VALUE)vm_cref_new_toplevel(th), /* cref or me */ (VALUE)vm_cref_new_toplevel(th), /* cref or me */
0, reg_cfp->sp, 1, 0); 0, reg_cfp->sp, 1, 0);
@ -2065,12 +2049,9 @@ rb_thread_mark(void *ptr)
rb_gc_mark_values((long)(sp - p), p); rb_gc_mark_values((long)(sp - p), p);
while (cfp != limit_cfp) { while (cfp != limit_cfp) {
const rb_iseq_t *iseq = cfp->iseq;
rb_gc_mark(cfp->proc); rb_gc_mark(cfp->proc);
rb_gc_mark(cfp->self); rb_gc_mark(cfp->self);
if (iseq) { rb_gc_mark((VALUE)cfp->iseq);
rb_gc_mark(RUBY_VM_NORMAL_ISEQ_P(iseq) ? iseq->self : (VALUE)iseq);
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); 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; 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) { if (!is_singleton && scope_visi->module_func) {
klass = rb_singleton_class(klass); 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_vm_t *vm = ruby_current_vm;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
VALUE filename = rb_str_new2("<main>"); 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; volatile VALUE th_self;
rb_iseq_t *iseq;
/* create vm object */ /* create vm object */
vm->self = TypedData_Wrap_Struct(rb_cRubyVM, &vm_data_type, vm); 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_vm_living_threads_insert(vm, th);
rb_gc_register_mark_object(iseqval); rb_gc_register_mark_object((VALUE)iseq);
GetISeqPtr(iseqval, iseq);
th->cfp->iseq = 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->self = th->top_self;
th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, NULL); 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_thread_t *th = GET_VM()->main_thread;
rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size); rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size);
--cfp; --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 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
@ -2893,7 +2872,7 @@ rb_ruby_debug_ptr(void)
} }
/* iseq.c */ /* 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, VALUE insn, int op_no, VALUE op,
int len, size_t pos, VALUE *pnop, VALUE child); int len, size_t pos, VALUE *pnop, VALUE child);

View File

@ -384,10 +384,10 @@ static void
args_setup_kw_parameters(VALUE* const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords, 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 rb_iseq_t * const iseq, VALUE * const locals)
{ {
const ID *acceptable_keywords = iseq->param.keyword->table; const ID *acceptable_keywords = iseq->body->param.keyword->table;
const int req_key_num = iseq->param.keyword->required_num; const int req_key_num = iseq->body->param.keyword->required_num;
const int key_num = iseq->param.keyword->num; const int key_num = iseq->body->param.keyword->num;
const VALUE * const default_values = iseq->param.keyword->default_values; const VALUE * const default_values = iseq->body->param.keyword->default_values;
VALUE missing = 0; VALUE missing = 0;
int i, di, found = 0; int i, di, found = 0;
int unspecified_bits = 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; const int rest_hash_index = key_num + 1;
locals[rest_hash_index] = make_unused_kw_hash(passed_keywords, passed_keyword_len, passed_values, FALSE); 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, 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) 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 min_argc = iseq->body->param.lead_num + iseq->body->param.post_num;
const int max_argc = (iseq->param.flags.has_rest == FALSE) ? min_argc + iseq->param.opt_num : UNLIMITED_ARGUMENTS; 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 opt_pc = 0;
int given_argc; int given_argc;
struct args_info args_body, *args; 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] * [pushed values] [uninitialized values]
* <- ci->argc --> * <- ci->argc -->
* <- iseq->param.size------------------> * <- iseq->body->param.size------------>
* ^ locals ^ sp * ^ locals ^ sp
* *
* => * =>
* [pushed values] [initialized values ] * [pushed values] [initialized values ]
* <- ci->argc --> * <- ci->argc -->
* <- iseq->param.size------------------> * <- iseq->body->param.size------------>
* ^ locals ^ sp * ^ locals ^ sp
*/ */
for (i=ci->argc; i<iseq->param.size; i++) { for (i=ci->argc; i<iseq->body->param.size; i++) {
locals[i] = Qnil; locals[i] = Qnil;
} }
th->cfp->sp = &locals[i]; 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; args->argv = locals;
if (ci->kw_arg) { 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; int kw_len = ci->kw_arg->keyword_len;
/* copy kw_argv */ /* copy kw_argv */
args->kw_argv = ALLOCA_N(VALUE, kw_len); 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 */ break; /* do nothing special */
case arg_setup_block: case arg_setup_block:
if (given_argc == 1 && if (given_argc == 1 &&
(min_argc > 0 || iseq->param.opt_num > 1 || (min_argc > 0 || iseq->body->param.opt_num > 1 ||
iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) && iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
!iseq->param.flags.ambiguous_param0 && !iseq->body->param.flags.ambiguous_param0 &&
args_check_block_arg0(args, th)) { args_check_block_arg0(args, th)) {
given_argc = RARRAY_LENINT(args->rest); given_argc = RARRAY_LENINT(args->rest);
} }
break; break;
case arg_setup_lambda: case arg_setup_lambda:
if (given_argc == 1 && if (given_argc == 1 &&
given_argc != iseq->param.lead_num && given_argc != iseq->body->param.lead_num &&
!iseq->param.flags.has_rest && !iseq->body->param.flags.has_rest &&
args_check_block_arg0(args, th)) { args_check_block_arg0(args, th)) {
given_argc = RARRAY_LENINT(args->rest); 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 && 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) { args->kw_argv == NULL) {
if (args_pop_keyword_hash(args, &keyword_hash, th)) { if (args_pop_keyword_hash(args, &keyword_hash, th)) {
given_argc--; 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) { if (iseq->body->param.flags.has_lead) {
args_setup_lead_parameters(args, iseq->param.lead_num, locals + 0); args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0);
} }
if (iseq->param.flags.has_post) { if (iseq->body->param.flags.has_post) {
args_setup_post_parameters(args, iseq->param.post_num, locals + iseq->param.post_start); args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start);
} }
if (iseq->param.flags.has_opt) { if (iseq->body->param.flags.has_opt) {
int opt = args_setup_opt_parameters(args, iseq->param.opt_num, locals + iseq->param.lead_num); int opt = args_setup_opt_parameters(args, iseq->body->param.opt_num, locals + iseq->body->param.lead_num);
opt_pc = (int)iseq->param.opt_table[opt]; opt_pc = (int)iseq->body->param.opt_table[opt];
} }
if (iseq->param.flags.has_rest) { if (iseq->body->param.flags.has_rest) {
args_setup_rest_parameter(args, locals + iseq->param.rest_start); args_setup_rest_parameter(args, locals + iseq->body->param.rest_start);
} }
if (iseq->param.flags.has_kw) { if (iseq->body->param.flags.has_kw) {
VALUE * const klocals = locals + iseq->param.keyword->bits_start - iseq->param.keyword->num; VALUE * const klocals = locals + iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num;
if (args->kw_argv != NULL) { 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); 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); args_setup_kw_parameters(NULL, 0, NULL, iseq, klocals);
} }
} }
else if (iseq->param.flags.has_kwrest) { else if (iseq->body->param.flags.has_kwrest) {
args_setup_kw_rest_parameter(keyword_hash, locals + iseq->param.keyword->rest_start); args_setup_kw_rest_parameter(keyword_hash, locals + iseq->body->param.keyword->rest_start);
} }
if (iseq->param.flags.has_block) { if (iseq->body->param.flags.has_block) {
args_setup_block_parameter(th, ci, locals + iseq->param.block_start); args_setup_block_parameter(th, ci, locals + iseq->body->param.block_start);
} }
#if 0 #if 0
{ {
int i; 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]); 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) { if (iseq) {
vm_push_frame(th, iseq, VM_FRAME_MAGIC_DUMMY, Qnil /* self */, vm_push_frame(th, iseq, VM_FRAME_MAGIC_DUMMY, Qnil /* self */,
VM_ENVVAL_BLOCK_PTR(0) /* specval*/, Qfalse /* me or cref */, 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(); at = rb_vm_backtrace_object();
vm_pop_frame(th); vm_pop_frame(th);
} }

View File

@ -31,7 +31,7 @@ id2str(ID id)
inline static int inline static int
calc_lineno(const rb_iseq_t *iseq, const VALUE *pc) 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 int
@ -87,7 +87,7 @@ location_mark_entry(rb_backtrace_location_t *fi)
switch (fi->type) { switch (fi->type) {
case LOCATION_TYPE_ISEQ: case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED: case LOCATION_TYPE_ISEQ_CALCED:
rb_gc_mark(fi->body.iseq.iseq->self); rb_gc_mark((VALUE)fi->body.iseq.iseq);
break; break;
case LOCATION_TYPE_CFUNC: case LOCATION_TYPE_CFUNC:
case LOCATION_TYPE_IFUNC: case LOCATION_TYPE_IFUNC:
@ -157,7 +157,7 @@ location_label(rb_backtrace_location_t *loc)
switch (loc->type) { switch (loc->type) {
case LOCATION_TYPE_ISEQ: case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED: case LOCATION_TYPE_ISEQ_CALCED:
return loc->body.iseq.iseq->location.label; return loc->body.iseq.iseq->body->location.label;
case LOCATION_TYPE_CFUNC: case LOCATION_TYPE_CFUNC:
return rb_id2str(loc->body.cfunc.mid); return rb_id2str(loc->body.cfunc.mid);
case LOCATION_TYPE_IFUNC: case LOCATION_TYPE_IFUNC:
@ -206,7 +206,7 @@ location_base_label(rb_backtrace_location_t *loc)
switch (loc->type) { switch (loc->type) {
case LOCATION_TYPE_ISEQ: case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED: 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: case LOCATION_TYPE_CFUNC:
return rb_id2str(loc->body.cfunc.mid); return rb_id2str(loc->body.cfunc.mid);
case LOCATION_TYPE_IFUNC: case LOCATION_TYPE_IFUNC:
@ -233,7 +233,7 @@ location_path(rb_backtrace_location_t *loc)
switch (loc->type) { switch (loc->type) {
case LOCATION_TYPE_ISEQ: case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED: case LOCATION_TYPE_ISEQ_CALCED:
return loc->body.iseq.iseq->location.path; return loc->body.iseq.iseq->body->location.path;
case LOCATION_TYPE_CFUNC: case LOCATION_TYPE_CFUNC:
if (loc->body.cfunc.prev_loc) { if (loc->body.cfunc.prev_loc) {
return location_path(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) { switch (loc->type) {
case LOCATION_TYPE_ISEQ: case LOCATION_TYPE_ISEQ:
case LOCATION_TYPE_ISEQ_CALCED: 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: case LOCATION_TYPE_CFUNC:
if (loc->body.cfunc.prev_loc) { if (loc->body.cfunc.prev_loc) {
return location_absolute_path(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) { switch (loc->type) {
case LOCATION_TYPE_ISEQ: case LOCATION_TYPE_ISEQ:
file = loc->body.iseq.iseq->location.path; file = loc->body.iseq.iseq->body->location.path;
name = loc->body.iseq.iseq->location.label; 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); lineno = loc->body.iseq.lineno.lineno = calc_lineno(loc->body.iseq.iseq, loc->body.iseq.lineno.pc);
loc->type = LOCATION_TYPE_ISEQ_CALCED; loc->type = LOCATION_TYPE_ISEQ_CALCED;
break; break;
case LOCATION_TYPE_ISEQ_CALCED: 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; lineno = loc->body.iseq.lineno.lineno;
name = loc->body.iseq.iseq->location.label; name = loc->body.iseq.iseq->body->location.label;
break; break;
case LOCATION_TYPE_CFUNC: case LOCATION_TYPE_CFUNC:
if (loc->body.cfunc.prev_loc) { 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); lineno = location_lineno(loc->body.cfunc.prev_loc);
} }
else { else {
@ -693,8 +693,8 @@ oldbt_iter_iseq(void *ptr, const rb_control_frame_t *cfp)
const rb_iseq_t *iseq = cfp->iseq; const rb_iseq_t *iseq = cfp->iseq;
const VALUE *pc = cfp->pc; const VALUE *pc = cfp->pc;
struct oldbt_arg *arg = (struct oldbt_arg *)ptr; struct oldbt_arg *arg = (struct oldbt_arg *)ptr;
VALUE file = arg->filename = iseq->location.path; VALUE file = arg->filename = iseq->body->location.path;
VALUE name = iseq->location.label; VALUE name = iseq->body->location.label;
int lineno = arg->lineno = calc_lineno(iseq, pc); int lineno = arg->lineno = calc_lineno(iseq, pc);
(arg->func)(arg->data, file, lineno, name); (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_SELF, cfp->self);
rb_ary_store(frame, CALLER_BINDING_CLASS, get_klass(cfp)); 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_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_store(frame, CALLER_BINDING_CFP, GC_GUARDED_PTR(cfp));
rb_ary_push(data->ary, frame); 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) rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index)
{ {
VALUE frame = frame_get(dc, 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 VALUE
@ -1261,7 +1263,7 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
buff[i] = (VALUE)cme; buff[i] = (VALUE)cme;
} }
else { else {
buff[i] = cfp->iseq->self; buff[i] = (VALUE)cfp->iseq;
} }
if (cfp->iseq && lines) lines[i] = calc_lineno(cfp->iseq, cfp->pc); 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; return i;
} }
static VALUE static const rb_iseq_t *
frame2iseq(VALUE frame) frame2iseq(VALUE frame)
{ {
if (frame == Qnil) return Qnil; if (frame == Qnil) return NULL;
if (RB_TYPE_P(frame, T_DATA)) {
VM_ASSERT(strcmp(rb_objspace_data_type_name(frame), "iseq") == 0);
return frame;
}
if (RB_TYPE_P(frame, T_IMEMO)) { if (RB_TYPE_P(frame, T_IMEMO)) {
const rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)frame; switch (imemo_type(frame)) {
VM_ASSERT(imemo_type(frame) == imemo_ment); case imemo_iseq:
switch (cme->def->type) { return (const rb_iseq_t *)frame;
case VM_METHOD_TYPE_ISEQ: case imemo_ment:
return cme->def->body.iseq.iseqptr->self; {
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: default:
return Qnil; break;
} }
} }
rb_bug("frame2iseq: unreachable"); rb_bug("frame2iseq: unreachable");
@ -1300,36 +1305,36 @@ frame2iseq(VALUE frame)
VALUE VALUE
rb_profile_frame_path(VALUE frame) rb_profile_frame_path(VALUE frame)
{ {
VALUE iseqv = frame2iseq(frame); const rb_iseq_t *iseq = frame2iseq(frame);
return NIL_P(iseqv) ? Qnil : rb_iseq_path(iseqv); return iseq ? rb_iseq_path(iseq) : Qnil;
} }
VALUE VALUE
rb_profile_frame_absolute_path(VALUE frame) rb_profile_frame_absolute_path(VALUE frame)
{ {
VALUE iseqv = frame2iseq(frame); const rb_iseq_t *iseq = frame2iseq(frame);
return NIL_P(iseqv) ? Qnil : rb_iseq_absolute_path(iseqv); return iseq ? rb_iseq_absolute_path(iseq) : Qnil;
} }
VALUE VALUE
rb_profile_frame_label(VALUE frame) rb_profile_frame_label(VALUE frame)
{ {
VALUE iseqv = frame2iseq(frame); const rb_iseq_t *iseq = frame2iseq(frame);
return NIL_P(iseqv) ? Qnil : rb_iseq_label(iseqv); return iseq ? rb_iseq_label(iseq) : Qnil;
} }
VALUE VALUE
rb_profile_frame_base_label(VALUE frame) rb_profile_frame_base_label(VALUE frame)
{ {
VALUE iseqv = frame2iseq(frame); const rb_iseq_t *iseq = frame2iseq(frame);
return NIL_P(iseqv) ? Qnil : rb_iseq_base_label(iseqv); return iseq ? rb_iseq_base_label(iseq) : Qnil;
} }
VALUE VALUE
rb_profile_frame_first_lineno(VALUE frame) rb_profile_frame_first_lineno(VALUE frame)
{ {
VALUE iseqv = frame2iseq(frame); const rb_iseq_t *iseq = frame2iseq(frame);
return NIL_P(iseqv) ? Qnil : rb_iseq_first_lineno(iseqv); return iseq ? rb_iseq_first_lineno(iseq) : Qnil;
} }
static VALUE static VALUE
@ -1384,8 +1389,8 @@ rb_profile_frame_singleton_method_p(VALUE frame)
VALUE VALUE
rb_profile_frame_method_name(VALUE frame) rb_profile_frame_method_name(VALUE frame)
{ {
VALUE iseqv = frame2iseq(frame); const rb_iseq_t *iseq = frame2iseq(frame);
return NIL_P(iseqv) ? Qnil : rb_iseq_method_name(iseqv); return iseq ? rb_iseq_method_name(iseq) : Qnil;
} }
VALUE VALUE

View File

@ -233,9 +233,6 @@ typedef struct rb_call_info_struct {
#define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct((obj), type, (ptr)) #define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct((obj), type, (ptr))
#endif #endif
#define GetISeqPtr(obj, ptr) \
GetCoreDataFromValue((obj), rb_iseq_t, (ptr))
typedef struct rb_iseq_location_struct { typedef struct rb_iseq_location_struct {
const VALUE path; const VALUE path;
const VALUE absolute_path; const VALUE absolute_path;
@ -244,7 +241,7 @@ typedef struct rb_iseq_location_struct {
VALUE first_lineno; /* TODO: may be unsigned short */ VALUE first_lineno; /* TODO: may be unsigned short */
} rb_iseq_location_t; } rb_iseq_location_t;
struct rb_iseq_struct { struct rb_iseq_body {
/***************/ /***************/
/* static data */ /* static data */
/***************/ /***************/
@ -260,9 +257,7 @@ struct rb_iseq_struct {
ISEQ_TYPE_MAIN, ISEQ_TYPE_MAIN,
ISEQ_TYPE_DEFINED_GUARD ISEQ_TYPE_DEFINED_GUARD
} type; /* instruction sequence type */ } 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 */ int stack_max; /* for stack overflow check */
rb_iseq_location_t location; rb_iseq_location_t location;
@ -370,19 +365,24 @@ struct rb_iseq_struct {
/* dynamic data */ /* dynamic data */
/****************/ /****************/
VALUE self;
/* misc */ /* misc */
rb_num_t flip_cnt; rb_num_t flip_cnt;
/* used at compile time */
struct iseq_compile_data *compile_data;
/* original iseq, before encoding /* original iseq, before encoding
* used for debug/dump (TODO: union with compile_data) */ * used for debug/dump (TODO: union with compile_data) */
VALUE *iseq; 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 { enum ruby_special_exceptions {
ruby_error_reenter, ruby_error_reenter,
ruby_error_nomemory, ruby_error_nomemory,
@ -785,18 +785,18 @@ typedef enum {
RUBY_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
/* node -> iseq */ /* node -> iseq */
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, enum iseq_type); rb_iseq_t *rb_iseq_new(NODE*, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type);
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);
VALUE rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path); rb_iseq_t *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); rb_iseq_t *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_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*);
/* src -> iseq */ /* src -> iseq */
VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line); rb_iseq_t *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); rb_iseq_t *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_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); 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); 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) \ #define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
(!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th))) (!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_IFUNC_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_ifunc)
#define RUBY_VM_NORMAL_ISEQ_P(ptr) \ #define RUBY_VM_NORMAL_ISEQ_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_iseq)
((ptr) && !RUBY_VM_IFUNC_P(ptr))
#define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self)) #define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self))
#define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \ #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 */ /* functions about thread/vm execution */
RUBY_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
VALUE rb_iseq_eval(VALUE iseqval); VALUE rb_iseq_eval(const rb_iseq_t *iseq);
VALUE rb_iseq_eval_main(VALUE iseqval); VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
RUBY_SYMBOL_EXPORT_END RUBY_SYMBOL_EXPORT_END
int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp); int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);

View File

@ -39,7 +39,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
const rb_callable_method_entry_t *me; const rb_callable_method_entry_t *me;
if (cfp->block_iseq != 0 && !RUBY_VM_IFUNC_P(cfp->block_iseq)) { 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) { 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>"; iseq_name = "<ifunc>";
} }
else { else {
pc = cfp->pc - cfp->iseq->iseq_encoded; pc = cfp->pc - cfp->iseq->body->iseq_encoded;
iseq_name = RSTRING_PTR(cfp->iseq->location.label); iseq_name = RSTRING_PTR(cfp->iseq->body->location.label);
line = rb_vm_get_sourceline(cfp); line = rb_vm_get_sourceline(cfp);
if (line) { 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) vm_base_ptr(rb_control_frame_t *cfp)
{ {
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(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; bp += 1;
} }
return bp; return bp;
@ -266,9 +266,9 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
name = "<ifunc>"; name = "<ifunc>";
} }
else { else {
argc = iseq->param.lead_num; argc = iseq->body->param.lead_num;
local_size = iseq->local_size; local_size = iseq->body->local_size;
name = RSTRING_PTR(iseq->location.label); name = RSTRING_PTR(iseq->body->location.label);
} }
/* stack trace header */ /* stack trace header */
@ -335,7 +335,7 @@ rb_vmdebug_debug_print_register(rb_thread_t *th)
ptrdiff_t cfpi; ptrdiff_t cfpi;
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { 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) { 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; const rb_iseq_t *iseq = cfp->iseq;
if (iseq != 0) { if (iseq != 0) {
ptrdiff_t pc = _pc - iseq->iseq_encoded; ptrdiff_t pc = _pc - iseq->body->iseq_encoded;
int i; int i;
for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) { for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) {

View File

@ -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(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 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 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 int vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *dfp, const struct local_var_list *vars);
static VALUE rb_eUncaughtThrow; 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) { if ((state = TH_EXEC_TAG()) == 0) {
rb_cref_t *cref = cref_arg; rb_cref_t *cref = cref_arg;
rb_binding_t *bind = 0; rb_binding_t *bind = 0;
rb_iseq_t *iseq; const rb_iseq_t *iseq;
volatile VALUE iseqval;
VALUE absolute_path = Qnil; VALUE absolute_path = Qnil;
VALUE fname; VALUE fname;
@ -1282,7 +1281,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
/* make eval iseq */ /* make eval iseq */
th->parse_in_eval++; th->parse_in_eval++;
th->mild_compile_error++; 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->mild_compile_error--;
th->parse_in_eval--; 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); 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); RB_GC_GUARD(crefval);
if (0) { /* for debug */ if (0) { /* for debug */
VALUE disasm = rb_iseq_disasm(iseqval); VALUE disasm = rb_iseq_disasm(iseq);
printf("%s\n", StringValuePtr(disasm)); printf("%s\n", StringValuePtr(disasm));
} }
/* save new env */ /* save new env */
GetISeqPtr(iseqval, iseq); if (bind && iseq->body->local_table_size > 0) {
if (bind && iseq->local_table_size > 0) {
bind->env = vm_make_env_object(th, th->cfp); bind->env = vm_make_env_object(th, th->cfp);
} }
@ -2050,8 +2048,8 @@ rb_f_local_variables(void)
local_var_list_init(&vars); local_var_list_init(&vars);
while (cfp) { while (cfp) {
if (cfp->iseq) { if (cfp->iseq) {
for (i = 0; i < cfp->iseq->local_table_size; i++) { for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
local_var_list_add(&vars, cfp->iseq->local_table[i]); local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
} }
} }
if (!VM_EP_LEP_P(cfp->ep)) { if (!VM_EP_LEP_P(cfp->ep)) {
@ -2117,7 +2115,7 @@ rb_current_realfilepath(void)
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp; rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(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; return Qnil;
} }

View File

@ -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(); const rb_iseq_t *base_iseq = GET_ISEQ();
escape_cfp = reg_cfp; escape_cfp = reg_cfp;
while (base_iseq->type != ISEQ_TYPE_BLOCK) { while (base_iseq->body->type != ISEQ_TYPE_BLOCK) {
if (escape_cfp->iseq->type == ISEQ_TYPE_CLASS) { if (escape_cfp->iseq->body->type == ISEQ_TYPE_CLASS) {
escape_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(escape_cfp); escape_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(escape_cfp);
ep = escape_cfp->ep; ep = escape_cfp->ep;
base_iseq = escape_cfp->iseq; base_iseq = escape_cfp->iseq;
} }
else { else {
ep = VM_EP_PREV_EP(ep); 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); escape_cfp = rb_vm_search_cf_from_ep(th, escape_cfp, ep);
VM_ASSERT(escape_cfp->iseq == base_iseq); 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) { while (escape_cfp < eocfp) {
if (escape_cfp->ep == ep) { 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 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; const int ct_size = ct->size;
int i; 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; 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; in_class_frame = 1;
target_lep = 0; 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; goto valid_return;
} }
@ -1198,9 +1198,9 @@ static VALUE *
vm_base_ptr(rb_control_frame_t *cfp) vm_base_ptr(rb_control_frame_t *cfp)
{ {
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(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' */ /* adjust `self' */
bp += 1; 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; int i;
long len = RARRAY_LEN(ary); 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); 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 static inline int
simple_iseq_p(const rb_iseq_t *iseq) simple_iseq_p(const rb_iseq_t *iseq)
{ {
return iseq->param.flags.has_opt == FALSE && return iseq->body->param.flags.has_opt == FALSE &&
iseq->param.flags.has_rest == FALSE && iseq->body->param.flags.has_rest == FALSE &&
iseq->param.flags.has_post == FALSE && iseq->body->param.flags.has_post == FALSE &&
iseq->param.flags.has_kw == FALSE && iseq->body->param.flags.has_kw == FALSE &&
iseq->param.flags.has_kwrest == FALSE && iseq->body->param.flags.has_kwrest == FALSE &&
iseq->param.flags.has_block == FALSE; iseq->body->param.flags.has_block == FALSE;
} }
static inline void 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 && if (arg_setup_type == arg_setup_block &&
ci->argc == 1 && ci->argc == 1 &&
iseq->param.flags.has_lead && iseq->body->param.flags.has_lead &&
!iseq->param.flags.ambiguous_param0 && !iseq->body->param.flags.ambiguous_param0 &&
!NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) { !NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) {
ci->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0); 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 (arg_setup_type == arg_setup_block) {
if (ci->argc < iseq->param.lead_num) { if (ci->argc < iseq->body->param.lead_num) {
int i; int i;
CHECK_VM_STACK_OVERFLOW(cfp, iseq->param.lead_num); CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num);
for (i=ci->argc; i<iseq->param.lead_num; i++) argv[i] = Qnil; for (i=ci->argc; i<iseq->body->param.lead_num; i++) argv[i] = Qnil;
ci->argc = iseq->param.lead_num; /* fill rest parameters */ ci->argc = iseq->body->param.lead_num; /* fill rest parameters */
} }
else if (ci->argc > iseq->param.lead_num) { else if (ci->argc > iseq->body->param.lead_num) {
ci->argc = iseq->param.lead_num; /* simply truncate arguments */ ci->argc = iseq->body->param.lead_num; /* simply truncate arguments */
} }
} }
else if (arg_setup_type == arg_setup_lambda && else if (arg_setup_type == arg_setup_lambda &&
ci->argc == 1 && ci->argc == 1 &&
!NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv)) && !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); ci->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
} }
else { 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 */ CALLER_SETUP_ARG(cfp, ci); /* splat arg */
if (ci->argc != iseq->param.lead_num) { if (ci->argc != iseq->body->param.lead_num) {
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);
} }
ci->aux.opt_pc = 0; 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; VALUE *argv = cfp->sp - ci->argc;
const rb_callable_method_entry_t *me = ci->me; const rb_callable_method_entry_t *me = ci->me;
const rb_iseq_t *iseq = def_iseq_ptr(me->def); 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) */ /* 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; *sp++ = Qnil;
} }
vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, ci->recv, vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, ci->recv,
VM_ENVVAL_BLOCK_PTR(ci->blockptr), (VALUE)me, 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 */; cfp->sp = argv - 1 /* recv */;
return Qundef; return Qundef;
@ -1402,18 +1402,18 @@ vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_in
sp++; sp++;
/* copy arguments */ /* copy arguments */
for (i=0; i < iseq->param.size; i++) { for (i=0; i < iseq->body->param.size; i++) {
*sp++ = src_argv[i]; *sp++ = src_argv[i];
} }
/* clear local variables */ /* 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; *sp++ = Qnil;
} }
vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | finish_flag, vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | finish_flag,
ci->recv, VM_ENVVAL_BLOCK_PTR(ci->blockptr), (VALUE)me, 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; cfp->sp = sp_orig;
return Qundef; 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; rb_control_frame_t *top_cfp = cfp;
if (cfp->iseq && cfp->iseq->type == ISEQ_TYPE_BLOCK) { if (cfp->iseq && cfp->iseq->body->type == ISEQ_TYPE_BLOCK) {
const rb_iseq_t *local_iseq = cfp->iseq->local_iseq; const rb_iseq_t *local_iseq = cfp->iseq->body->local_iseq;
do { do {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, 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_block_t *block = VM_CF_BLOCK_PTR(reg_cfp);
const rb_iseq_t *iseq; 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) { if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) || block == 0) {
rb_vm_localjump_error("no block given (yield)", Qnil, 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)) { if (!RUBY_VM_IFUNC_P(iseq)) {
int opt_pc; 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); int is_lambda = block_proc_is_lambda(block->proc);
VALUE * const rsp = GET_SP() - ci->argc; 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, is_lambda ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK,
block->self, block->self,
VM_ENVVAL_PREV_EP_PTR(block->ep), 0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
iseq->iseq_encoded + opt_pc, iseq->body->iseq_encoded + opt_pc,
rsp + arg_size, rsp + arg_size,
iseq->local_size - arg_size, iseq->stack_max); iseq->body->local_size - arg_size, iseq->body->stack_max);
return Qundef; return Qundef;
} }

View File

@ -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); cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp && (line = rb_vm_get_sourceline(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)); RB_OBJ_WRITE(me, &def->body.attr.location, rb_ary_freeze(location));
} }
else { else {
@ -296,7 +296,7 @@ method_definition_reset(const rb_method_entry_t *me)
switch(def->type) { switch(def->type) {
case VM_METHOD_TYPE_ISEQ: 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); RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.cref);
break; break;
case VM_METHOD_TYPE_ATTRSET: case VM_METHOD_TYPE_ATTRSET:
@ -512,9 +512,9 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
default: default:
break; break;
} }
if (iseq && !NIL_P(iseq->location.path)) { if (iseq && !NIL_P(iseq->body->location.path)) {
int line = iseq->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq->self)) : 0; int line = iseq->body->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq)) : 0;
rb_compile_warning(RSTRING_PTR(iseq->location.path), line, rb_compile_warning(RSTRING_PTR(iseq->body->location.path), line,
"previous definition of %"PRIsVALUE" was here", "previous definition of %"PRIsVALUE" was here",
rb_id2str(old_def->original_id)); 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 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 */ struct { /* should be same fields with rb_method_iseq_struct */
rb_iseq_t *iseqptr; const rb_iseq_t *iseqptr;
rb_cref_t *cref; rb_cref_t *cref;
} iseq_body; } iseq_body;
GetISeqPtr(iseqval, iseq);
iseq_body.iseqptr = iseq; iseq_body.iseqptr = iseq;
iseq_body.cref = cref; iseq_body.cref = cref;
rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi); rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
RB_GC_GUARD(iseqval);
} }
static rb_method_entry_t * static rb_method_entry_t *

View File

@ -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); rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->th, trace_arg->cfp);
if (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); trace_arg->lineno = rb_vm_get_sourceline(cfp);
} }
else { else {