* 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>
* 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) {
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));

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)
{
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];

View File

@ -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);

60
gc.c
View File

@ -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:

View File

@ -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();

View File

@ -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);

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
/* 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;

4
load.c
View File

@ -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);
}

View File

@ -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);

30
proc.c
View File

@ -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;

6
ruby.c
View File

@ -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 {

View File

@ -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

View File

@ -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;

153
vm.c
View File

@ -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);

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,
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);
}

View File

@ -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

View File

@ -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);

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;
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++) {

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_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;
}

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();
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;
}

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);
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 *

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);
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 {