* 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:
parent
6053426a66
commit
e4198a73d4
45
ChangeLog
45
ChangeLog
@ -1,3 +1,48 @@
|
||||
Wed Jul 22 07:24:18 2015 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* make rb_iseq_t T_IMEMO object (type is imemo_iseq).
|
||||
|
||||
All contents of previous rb_iseq_t is in rb_iseq_t::body.
|
||||
Remove rb_iseq_t::self because rb_iseq_t is an object.
|
||||
|
||||
RubyVM::InstructionSequence is wrapper object points T_IMEMO/iseq.
|
||||
So RubyVM::ISeq.of(something) method returns different wrapper
|
||||
objects but they point the same T_IMEMO/iseq object.
|
||||
|
||||
This patch is big, but most of difference is replacement of
|
||||
iseq->xxx to iseq->body->xxx.
|
||||
|
||||
(previous) rb_iseq_t::compile_data is also located to
|
||||
rb_iseq_t::compile_data.
|
||||
It was moved from rb_iseq_body::compile_data.
|
||||
|
||||
Now rb_iseq_t has empty two pointers.
|
||||
I will split rb_iseq_body data into static data and dynamic data.
|
||||
|
||||
* compile.c: rename some functions/macros.
|
||||
Now, we don't need to separate iseq and iseqval (only VALUE).
|
||||
|
||||
* eval.c (ruby_exec_internal): `n' is rb_iseq_t (T_IMEMO/iseq).
|
||||
|
||||
* ext/objspace/objspace.c (count_imemo_objects): count T_IMEMO/iseq.
|
||||
|
||||
* gc.c: check T_IMEMO/iseq.
|
||||
|
||||
* internal.h: add imemo_type::imemo_iseq.
|
||||
|
||||
* iseq.c: define RubyVM::InstructionSequnce as T_OBJECT.
|
||||
Methods are implemented by functions named iseqw_....
|
||||
|
||||
* load.c (rb_load_internal0): rb_iseq_new_top() returns
|
||||
rb_iseq_t (T_IMEMO/iesq).
|
||||
|
||||
* method.h (rb_add_method_iseq): accept rb_iseq_t (T_IMEMO/iseq).
|
||||
|
||||
* vm_core.h (GetISeqPtr): removed because it is not T_DATA now.
|
||||
|
||||
* vm_core.h (struct rb_iseq_body): remove padding for
|
||||
[Bug #10037][ruby-core:63721].
|
||||
|
||||
Wed Jul 22 07:15:33 2015 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* ext/objspace/objspace.c (total_i): no need to skip singleton classes.
|
||||
|
2
class.c
2
class.c
@ -246,7 +246,7 @@ clone_method(VALUE old_klass, VALUE new_klass, ID mid, const rb_method_entry_t *
|
||||
if (me->def->type == VM_METHOD_TYPE_ISEQ) {
|
||||
rb_cref_t *new_cref;
|
||||
rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass, &new_cref);
|
||||
rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr->self, new_cref, METHOD_ENTRY_VISI(me));
|
||||
rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
|
||||
}
|
||||
else {
|
||||
rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me));
|
||||
|
6
eval.c
6
eval.c
@ -237,7 +237,7 @@ static int
|
||||
ruby_exec_internal(void *n)
|
||||
{
|
||||
volatile int state;
|
||||
VALUE iseq = (VALUE)n;
|
||||
rb_iseq_t *iseq = (rb_iseq_t *)n;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
|
||||
if (!n) return 0;
|
||||
@ -1448,10 +1448,10 @@ errinfo_place(rb_thread_t *th)
|
||||
|
||||
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
|
||||
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
||||
if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
|
||||
if (cfp->iseq->body->type == ISEQ_TYPE_RESCUE) {
|
||||
return &cfp->ep[-2];
|
||||
}
|
||||
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
|
||||
else if (cfp->iseq->body->type == ISEQ_TYPE_ENSURE &&
|
||||
!THROW_DATA_P(cfp->ep[-2]) &&
|
||||
!FIXNUM_P(cfp->ep[-2])) {
|
||||
return &cfp->ep[-2];
|
||||
|
@ -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
60
gc.c
@ -404,6 +404,7 @@ typedef struct RVALUE {
|
||||
struct vm_ifunc ifunc;
|
||||
struct MEMO memo;
|
||||
struct rb_method_entry_struct ment;
|
||||
const rb_iseq_t iseq;
|
||||
} imemo;
|
||||
struct {
|
||||
struct RBasic basic;
|
||||
@ -699,6 +700,7 @@ static rb_objspace_t rb_objspace = {{GC_MALLOC_LIMIT_MIN}};
|
||||
#endif
|
||||
|
||||
#define ruby_initial_gc_stress gc_params.gc_stress
|
||||
|
||||
VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
|
||||
|
||||
#define malloc_limit objspace->malloc_params.limit
|
||||
@ -778,6 +780,9 @@ int ruby_gc_debug_indent = 0;
|
||||
VALUE rb_mGC;
|
||||
int ruby_disable_gc = 0;
|
||||
|
||||
void rb_iseq_mark(const rb_iseq_t *iseq);
|
||||
void rb_iseq_free(const rb_iseq_t *iseq);
|
||||
|
||||
void rb_gcdebug_print_obj_condition(VALUE obj);
|
||||
|
||||
static void rb_objspace_call_finalizer(rb_objspace_t *objspace);
|
||||
@ -2140,11 +2145,18 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||
|
||||
case T_IMEMO:
|
||||
{
|
||||
if (imemo_type(obj) == imemo_ment) {
|
||||
switch (imemo_type(obj)) {
|
||||
case imemo_ment:
|
||||
rb_free_method_entry(&RANY(obj)->as.imemo.ment);
|
||||
break;
|
||||
case imemo_iseq:
|
||||
rb_iseq_free(&RANY(obj)->as.imemo.iseq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
rb_bug("gc_sweep(): unknown data type 0x%x(%p) 0x%"PRIxVALUE,
|
||||
@ -3924,7 +3936,7 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
|
||||
if (def) {
|
||||
switch (def->type) {
|
||||
case VM_METHOD_TYPE_ISEQ:
|
||||
if (def->body.iseq.iseqptr) gc_mark(objspace, def->body.iseq.iseqptr->self);
|
||||
if (def->body.iseq.iseqptr) gc_mark(objspace, (VALUE)def->body.iseq.iseqptr);
|
||||
gc_mark(objspace, (VALUE)def->body.iseq.cref);
|
||||
break;
|
||||
case VM_METHOD_TYPE_ATTRSET:
|
||||
@ -4272,6 +4284,9 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
||||
|
||||
case T_IMEMO:
|
||||
switch (imemo_type(obj)) {
|
||||
case imemo_none:
|
||||
rb_bug("unreachable");
|
||||
return;
|
||||
case imemo_cref:
|
||||
gc_mark(objspace, RANY(obj)->as.imemo.cref.klass);
|
||||
gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next);
|
||||
@ -4297,9 +4312,11 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
||||
case imemo_ment:
|
||||
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
|
||||
return;
|
||||
default:
|
||||
rb_bug("T_IMEMO: unreachable");
|
||||
case imemo_iseq:
|
||||
rb_iseq_mark((rb_iseq_t *)obj);
|
||||
return;
|
||||
}
|
||||
rb_bug("T_IMEMO: unreachable");
|
||||
}
|
||||
|
||||
gc_mark(objspace, any->as.basic.klass);
|
||||
@ -8917,15 +8934,7 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
|
||||
}
|
||||
case T_DATA: {
|
||||
const char * const type_name = rb_objspace_data_type_name(obj);
|
||||
if (type_name && strcmp(type_name, "iseq") == 0) {
|
||||
rb_iseq_t *iseq;
|
||||
GetISeqPtr(obj, iseq);
|
||||
if (iseq->location.label) {
|
||||
snprintf(buff, buff_size, "%s %s@%s:%d", buff,
|
||||
RSTRING_PTR(iseq->location.label), RSTRING_PTR(iseq->location.path), (int)iseq->location.first_lineno);
|
||||
}
|
||||
}
|
||||
else if (type_name) {
|
||||
if (type_name) {
|
||||
snprintf(buff, buff_size, "%s %s", buff, type_name);
|
||||
}
|
||||
break;
|
||||
@ -8945,10 +8954,25 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
|
||||
#undef IMEMO_NAME
|
||||
}
|
||||
snprintf(buff, buff_size, "%s %s", buff, imemo_name);
|
||||
if (imemo_type(obj) == imemo_ment) {
|
||||
const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment;
|
||||
snprintf(buff, buff_size, "%s (called_id: %s, type: %s, alias: %d, class: %s)", buff,
|
||||
rb_id2name(me->called_id), method_type_name(me->def->type), me->def->alias_count, obj_info(me->defined_class));
|
||||
|
||||
switch (imemo_type(obj)) {
|
||||
case imemo_ment: {
|
||||
const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment;
|
||||
snprintf(buff, buff_size, "%s (called_id: %s, type: %s, alias: %d, class: %s)", buff,
|
||||
rb_id2name(me->called_id), method_type_name(me->def->type), me->def->alias_count, obj_info(me->defined_class));
|
||||
break;
|
||||
}
|
||||
case imemo_iseq: {
|
||||
const rb_iseq_t *iseq = (const rb_iseq_t *)obj;
|
||||
|
||||
if (iseq->body->location.label) {
|
||||
snprintf(buff, buff_size, "%s %s@%s:%d", buff,
|
||||
RSTRING_PTR(iseq->body->location.label), RSTRING_PTR(iseq->body->location.path), (int)iseq->body->location.first_lineno);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
29
iseq.h
29
iseq.h
@ -15,12 +15,12 @@
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
|
||||
/* compile.c */
|
||||
VALUE rb_iseq_compile_node(VALUE self, NODE *node);
|
||||
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node);
|
||||
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
|
||||
VALUE *rb_iseq_original_iseq(rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
|
||||
VALUE locals, VALUE args,
|
||||
VALUE exception, VALUE body);
|
||||
VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
|
||||
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
|
||||
VALUE locals, VALUE args,
|
||||
VALUE exception, VALUE body);
|
||||
|
||||
/* iseq.c */
|
||||
void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj);
|
||||
@ -29,9 +29,18 @@ VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
|
||||
struct st_table *ruby_insn_make_insn_table(void);
|
||||
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos);
|
||||
|
||||
int rb_iseq_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data);
|
||||
VALUE rb_iseq_line_trace_all(VALUE iseqval);
|
||||
VALUE rb_iseq_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set);
|
||||
int rb_iseqw_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data);
|
||||
VALUE rb_iseqw_line_trace_all(VALUE iseqval);
|
||||
VALUE rb_iseqw_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set);
|
||||
VALUE rb_iseqw_new(const rb_iseq_t *iseq);
|
||||
const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw);
|
||||
|
||||
VALUE rb_iseq_path(const rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_absolute_path(const rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_label(const rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_base_label(const rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_method_name(const rb_iseq_t *iseq);
|
||||
|
||||
/* proc.c */
|
||||
const rb_iseq_t *rb_method_iseq(VALUE body);
|
||||
@ -63,7 +72,7 @@ struct iseq_catch_table_entry {
|
||||
CATCH_TYPE_REDO = INT2FIX(5),
|
||||
CATCH_TYPE_NEXT = INT2FIX(6)
|
||||
} type;
|
||||
VALUE iseq;
|
||||
const rb_iseq_t *iseq;
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
unsigned int cont;
|
||||
@ -109,7 +118,7 @@ struct iseq_compile_data {
|
||||
struct iseq_label_data *start_label;
|
||||
struct iseq_label_data *end_label;
|
||||
struct iseq_label_data *redo_label;
|
||||
VALUE current_block;
|
||||
const rb_iseq_t *current_block;
|
||||
VALUE ensure_node;
|
||||
VALUE for_iseq;
|
||||
struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
|
||||
|
4
load.c
4
load.c
@ -602,12 +602,12 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
|
||||
state = EXEC_TAG();
|
||||
if (state == 0) {
|
||||
NODE *node;
|
||||
VALUE iseq;
|
||||
rb_iseq_t *iseq;
|
||||
|
||||
th->mild_compile_error++;
|
||||
node = (NODE *)rb_load_file_str(fname);
|
||||
loaded = TRUE;
|
||||
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
|
||||
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), NULL);
|
||||
th->mild_compile_error--;
|
||||
rb_iseq_eval(iseq);
|
||||
}
|
||||
|
4
method.h
4
method.h
@ -121,7 +121,7 @@ typedef enum {
|
||||
typedef struct rb_iseq_struct rb_iseq_t;
|
||||
|
||||
typedef struct rb_method_iseq_struct {
|
||||
const rb_iseq_t * const iseqptr; /* should be separated from iseqval */
|
||||
const rb_iseq_t * const iseqptr; /* should be separated from iseqval */
|
||||
rb_cref_t * const cref; /* shoudl be marked */
|
||||
} rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */
|
||||
|
||||
@ -174,7 +174,7 @@ typedef struct rb_method_definition_struct {
|
||||
UNDEFINED_METHOD_ENTRY_P((def)->body.refined.orig_me))
|
||||
|
||||
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi);
|
||||
void rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi);
|
||||
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi);
|
||||
void rb_add_refined_method_entry(VALUE refined_class, ID mid);
|
||||
|
||||
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
|
||||
|
30
proc.c
30
proc.c
@ -369,8 +369,8 @@ get_local_variable_ptr(VALUE envval, ID lid)
|
||||
iseq = env->block.iseq;
|
||||
|
||||
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
|
||||
for (i=0; i<iseq->local_table_size; i++) {
|
||||
if (iseq->local_table[i] == lid) {
|
||||
for (i=0; i<iseq->body->local_table_size; i++) {
|
||||
if (iseq->body->local_table[i] == lid) {
|
||||
return &env->env[i];
|
||||
}
|
||||
}
|
||||
@ -735,7 +735,7 @@ proc_call(int argc, VALUE *argv, VALUE procval)
|
||||
GetProcPtr(procval, proc);
|
||||
|
||||
iseq = proc->block.iseq;
|
||||
if (RUBY_VM_IFUNC_P(iseq) || iseq->param.flags.has_block) {
|
||||
if (RUBY_VM_IFUNC_P(iseq) || iseq->body->param.flags.has_block) {
|
||||
if (rb_block_given_p()) {
|
||||
rb_proc_t *passed_proc;
|
||||
RB_GC_GUARD(passed_procval) = rb_block_proc();
|
||||
@ -847,11 +847,11 @@ proc_arity(VALUE self)
|
||||
static inline int
|
||||
rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max)
|
||||
{
|
||||
*max = iseq->param.flags.has_rest == FALSE ?
|
||||
iseq->param.lead_num + iseq->param.opt_num + iseq->param.post_num +
|
||||
(iseq->param.flags.has_kw == TRUE || iseq->param.flags.has_kwrest == TRUE)
|
||||
*max = iseq->body->param.flags.has_rest == FALSE ?
|
||||
iseq->body->param.lead_num + iseq->body->param.opt_num + iseq->body->param.post_num +
|
||||
(iseq->body->param.flags.has_kw == TRUE || iseq->body->param.flags.has_kwrest == TRUE)
|
||||
: UNLIMITED_ARGUMENTS;
|
||||
return iseq->param.lead_num + iseq->param.post_num + (iseq->param.flags.has_kw && iseq->param.keyword->required_num > 0);
|
||||
return iseq->body->param.lead_num + iseq->body->param.post_num + (iseq->body->param.flags.has_kw && iseq->body->param.keyword->required_num > 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -950,9 +950,9 @@ iseq_location(const rb_iseq_t *iseq)
|
||||
VALUE loc[2];
|
||||
|
||||
if (!iseq) return Qnil;
|
||||
loc[0] = iseq->location.path;
|
||||
if (iseq->line_info_table) {
|
||||
loc[1] = rb_iseq_first_lineno(iseq->self);
|
||||
loc[0] = iseq->body->location.path;
|
||||
if (iseq->body->line_info_table) {
|
||||
loc[1] = rb_iseq_first_lineno(iseq);
|
||||
}
|
||||
else {
|
||||
loc[1] = Qnil;
|
||||
@ -1066,11 +1066,11 @@ proc_to_s(VALUE self)
|
||||
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
|
||||
int first_lineno = 0;
|
||||
|
||||
if (iseq->line_info_table) {
|
||||
first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
|
||||
if (iseq->body->line_info_table) {
|
||||
first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
|
||||
}
|
||||
str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self,
|
||||
iseq->location.path, first_lineno, is_lambda);
|
||||
iseq->body->location.path, first_lineno, is_lambda);
|
||||
}
|
||||
else {
|
||||
str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
|
||||
@ -2558,8 +2558,8 @@ proc_binding(VALUE self)
|
||||
}
|
||||
|
||||
if (iseq) {
|
||||
bind->path = iseq->location.path;
|
||||
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
|
||||
bind->path = iseq->body->location.path;
|
||||
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
|
||||
}
|
||||
else {
|
||||
bind->path = Qnil;
|
||||
|
6
ruby.c
6
ruby.c
@ -1305,7 +1305,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
|
||||
{
|
||||
NODE *tree = 0;
|
||||
VALUE parser;
|
||||
VALUE iseq;
|
||||
const rb_iseq_t *iseq;
|
||||
rb_encoding *enc, *lenc;
|
||||
const char *s;
|
||||
char fbuf[MAXPATHLEN];
|
||||
@ -1544,7 +1544,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
|
||||
});
|
||||
|
||||
if (opt->dump & DUMP_BIT(insns)) {
|
||||
rb_io_write(rb_stdout, rb_iseq_disasm(iseq));
|
||||
rb_io_write(rb_stdout, rb_iseq_disasm((const rb_iseq_t *)iseq));
|
||||
rb_io_flush(rb_stdout);
|
||||
return Qtrue;
|
||||
}
|
||||
@ -1555,7 +1555,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
|
||||
|
||||
rb_set_safe_level(opt->safe_level);
|
||||
|
||||
return iseq;
|
||||
return (VALUE)iseq;
|
||||
}
|
||||
|
||||
struct load_file_arg {
|
||||
|
12
struct.c
12
struct.c
@ -19,8 +19,8 @@ enum {
|
||||
AREF_HASH_THRESHOLD = 10
|
||||
};
|
||||
|
||||
VALUE rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func);
|
||||
VALUE rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func);
|
||||
const rb_iseq_t *rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func);
|
||||
const rb_iseq_t *rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func);
|
||||
|
||||
VALUE rb_cStruct;
|
||||
static ID id_members, id_back_members;
|
||||
@ -287,18 +287,18 @@ static void
|
||||
define_aref_method(VALUE nstr, VALUE name, VALUE off)
|
||||
{
|
||||
rb_control_frame_t *FUNC_FASTCALL(rb_vm_opt_struct_aref)(rb_thread_t *, rb_control_frame_t *);
|
||||
VALUE iseqval = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref);
|
||||
const rb_iseq_t *iseq = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref);
|
||||
|
||||
rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, METHOD_VISI_PUBLIC);
|
||||
rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, METHOD_VISI_PUBLIC);
|
||||
}
|
||||
|
||||
static void
|
||||
define_aset_method(VALUE nstr, VALUE name, VALUE off)
|
||||
{
|
||||
rb_control_frame_t *FUNC_FASTCALL(rb_vm_opt_struct_aset)(rb_thread_t *, rb_control_frame_t *);
|
||||
VALUE iseqval = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset);
|
||||
const rb_iseq_t *iseq = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset);
|
||||
|
||||
rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, METHOD_VISI_PUBLIC);
|
||||
rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, METHOD_VISI_PUBLIC);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
2
thread.c
2
thread.c
@ -5226,7 +5226,7 @@ rb_check_deadlock(rb_vm_t *vm)
|
||||
static void
|
||||
update_coverage(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass)
|
||||
{
|
||||
VALUE coverage = GET_THREAD()->cfp->iseq->coverage;
|
||||
VALUE coverage = GET_THREAD()->cfp->iseq->body->coverage;
|
||||
if (coverage && RBASIC(coverage)->klass == 0) {
|
||||
long line = rb_sourceline() - 1;
|
||||
long count;
|
||||
|
153
vm.c
153
vm.c
@ -247,12 +247,9 @@ vm_stat(int argc, VALUE *argv, VALUE self)
|
||||
/* control stack frame */
|
||||
|
||||
static void
|
||||
vm_set_top_stack(rb_thread_t *th, VALUE iseqval)
|
||||
vm_set_top_stack(rb_thread_t *th, const rb_iseq_t *iseq)
|
||||
{
|
||||
rb_iseq_t *iseq;
|
||||
GetISeqPtr(iseqval, iseq);
|
||||
|
||||
if (iseq->type != ISEQ_TYPE_TOP) {
|
||||
if (iseq->body->type != ISEQ_TYPE_TOP) {
|
||||
rb_raise(rb_eTypeError, "Not a toplevel InstructionSequence");
|
||||
}
|
||||
|
||||
@ -260,37 +257,33 @@ vm_set_top_stack(rb_thread_t *th, VALUE iseqval)
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH, th->top_self,
|
||||
VM_ENVVAL_BLOCK_PTR(0),
|
||||
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
||||
iseq->iseq_encoded, th->cfp->sp, iseq->local_size, iseq->stack_max);
|
||||
iseq->body->iseq_encoded, th->cfp->sp, iseq->body->local_size, iseq->body->stack_max);
|
||||
}
|
||||
|
||||
static void
|
||||
vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const rb_cref_t *cref, rb_block_t *base_block)
|
||||
vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, rb_block_t *base_block)
|
||||
{
|
||||
rb_iseq_t *iseq;
|
||||
GetISeqPtr(iseqval, iseq);
|
||||
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL | VM_FRAME_FLAG_FINISH,
|
||||
base_block->self, VM_ENVVAL_PREV_EP_PTR(base_block->ep),
|
||||
(VALUE)cref, /* cref or me */
|
||||
iseq->iseq_encoded,
|
||||
th->cfp->sp, iseq->local_size, iseq->stack_max);
|
||||
iseq->body->iseq_encoded,
|
||||
th->cfp->sp, iseq->body->local_size, iseq->body->stack_max);
|
||||
}
|
||||
|
||||
static void
|
||||
vm_set_main_stack(rb_thread_t *th, VALUE iseqval)
|
||||
vm_set_main_stack(rb_thread_t *th, const rb_iseq_t *iseq)
|
||||
{
|
||||
VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING"));
|
||||
rb_binding_t *bind;
|
||||
rb_iseq_t *iseq;
|
||||
rb_env_t *env;
|
||||
|
||||
GetBindingPtr(toplevel_binding, bind);
|
||||
GetEnvPtr(bind->env, env);
|
||||
vm_set_eval_stack(th, iseqval, 0, &env->block);
|
||||
|
||||
vm_set_eval_stack(th, iseq, 0, &env->block);
|
||||
|
||||
/* save binding */
|
||||
GetISeqPtr(iseqval, iseq);
|
||||
if (bind && iseq->local_size > 0) {
|
||||
if (bind && iseq->body->local_size > 0) {
|
||||
bind->env = vm_make_env_object(th, th->cfp);
|
||||
}
|
||||
}
|
||||
@ -425,7 +418,7 @@ env_mark(void * const ptr)
|
||||
rb_gc_mark((VALUE)env->block.iseq);
|
||||
}
|
||||
else {
|
||||
RUBY_MARK_UNLESS_NULL(env->block.iseq->self);
|
||||
RUBY_MARK_UNLESS_NULL((VALUE)env->block.iseq);
|
||||
}
|
||||
}
|
||||
RUBY_MARK_LEAVE("env");
|
||||
@ -536,7 +529,7 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
|
||||
local_size = 1 /* cref/me */;
|
||||
}
|
||||
else {
|
||||
local_size = cfp->iseq->local_size;
|
||||
local_size = cfp->iseq->body->local_size;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -638,8 +631,8 @@ collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_li
|
||||
{
|
||||
int i;
|
||||
if (!iseq) return 0;
|
||||
for (i = 0; i < iseq->local_table_size; i++) {
|
||||
local_var_list_add(vars, iseq->local_table[i]);
|
||||
for (i = 0; i < iseq->body->local_table_size; i++) {
|
||||
local_var_list_add(vars, iseq->body->local_table[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -756,7 +749,7 @@ rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
|
||||
bindval = rb_binding_alloc(rb_cBinding);
|
||||
GetBindingPtr(bindval, bind);
|
||||
bind->env = envval;
|
||||
bind->path = ruby_level_cfp->iseq->location.path;
|
||||
bind->path = ruby_level_cfp->iseq->body->location.path;
|
||||
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
|
||||
|
||||
return bindval;
|
||||
@ -765,11 +758,11 @@ rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
|
||||
VALUE *
|
||||
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
||||
{
|
||||
VALUE envval = bind->env, path = bind->path, iseqval;
|
||||
VALUE envval = bind->env, path = bind->path;
|
||||
rb_env_t *env;
|
||||
rb_block_t *base_block;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
const rb_iseq_t *base_iseq;
|
||||
const rb_iseq_t *base_iseq, *iseq;
|
||||
NODE *node = 0;
|
||||
ID minibuf[4], *dyns = minibuf;
|
||||
VALUE idtmp = 0;
|
||||
@ -788,17 +781,16 @@ rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
||||
node = NEW_NODE(NODE_SCOPE, dyns, 0, 0);
|
||||
|
||||
if (base_iseq) {
|
||||
iseqval = rb_iseq_new(node, base_iseq->location.label, path, path,
|
||||
base_iseq->self, ISEQ_TYPE_EVAL);
|
||||
iseq = rb_iseq_new(node, base_iseq->body->location.label, path, path, base_iseq, ISEQ_TYPE_EVAL);
|
||||
}
|
||||
else {
|
||||
VALUE tempstr = rb_str_new2("<temp>");
|
||||
iseqval = rb_iseq_new_top(node, tempstr, tempstr, tempstr, Qfalse);
|
||||
iseq = rb_iseq_new_top(node, tempstr, tempstr, tempstr, NULL);
|
||||
}
|
||||
node->u1.tbl = 0; /* reset table */
|
||||
ALLOCV_END(idtmp);
|
||||
|
||||
vm_set_eval_stack(th, iseqval, 0, base_block);
|
||||
vm_set_eval_stack(th, iseq, 0, base_block);
|
||||
bind->env = vm_make_env_object(th, th->cfp);
|
||||
vm_pop_frame(th);
|
||||
GetEnvPtr(bind->env, env);
|
||||
@ -821,7 +813,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
|
||||
VALUE ret;
|
||||
const rb_iseq_t *iseq = block->iseq;
|
||||
const rb_control_frame_t *cfp;
|
||||
int i, opt_pc, arg_size = iseq->param.size;
|
||||
int i, opt_pc, arg_size = iseq->body->param.size;
|
||||
int type = block_proc_is_lambda(block->proc) ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
|
||||
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
|
||||
th->passed_bmethod_me = NULL;
|
||||
@ -839,9 +831,9 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
|
||||
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self,
|
||||
VM_ENVVAL_PREV_EP_PTR(block->ep),
|
||||
(VALUE)me, /* cref or method (TODO: can we ignore cref?) */
|
||||
iseq->iseq_encoded + opt_pc,
|
||||
cfp->sp + arg_size, iseq->local_size - arg_size,
|
||||
iseq->stack_max);
|
||||
iseq->body->iseq_encoded + opt_pc,
|
||||
cfp->sp + arg_size, iseq->body->local_size - arg_size,
|
||||
iseq->body->stack_max);
|
||||
|
||||
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->called_id);
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->called_id, me->owner, Qnil);
|
||||
@ -850,9 +842,9 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
|
||||
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH, self,
|
||||
VM_ENVVAL_PREV_EP_PTR(block->ep),
|
||||
(VALUE)cref, /* cref or method */
|
||||
iseq->iseq_encoded + opt_pc,
|
||||
cfp->sp + arg_size, iseq->local_size - arg_size,
|
||||
iseq->stack_max);
|
||||
iseq->body->iseq_encoded + opt_pc,
|
||||
cfp->sp + arg_size, iseq->body->local_size - arg_size,
|
||||
iseq->body->stack_max);
|
||||
}
|
||||
|
||||
ret = vm_exec(th);
|
||||
@ -1021,7 +1013,7 @@ rb_sourcefilename(void)
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
||||
|
||||
if (cfp) {
|
||||
return cfp->iseq->location.path;
|
||||
return cfp->iseq->body->location.path;
|
||||
}
|
||||
else {
|
||||
return Qnil;
|
||||
@ -1035,7 +1027,7 @@ rb_sourcefile(void)
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
||||
|
||||
if (cfp) {
|
||||
return RSTRING_PTR(cfp->iseq->location.path);
|
||||
return RSTRING_PTR(cfp->iseq->body->location.path);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
@ -1489,7 +1481,7 @@ vm_exec(rb_thread_t *th)
|
||||
struct iseq_catch_table_entry *entry;
|
||||
struct iseq_catch_table *ct;
|
||||
unsigned long epc, cont_pc, cont_sp;
|
||||
VALUE catch_iseqval;
|
||||
const rb_iseq_t *catch_iseq;
|
||||
rb_control_frame_t *cfp;
|
||||
VALUE type;
|
||||
const rb_control_frame_t *escape_cfp;
|
||||
@ -1497,7 +1489,8 @@ vm_exec(rb_thread_t *th)
|
||||
err = (struct vm_throw_data *)th->errinfo;
|
||||
|
||||
exception_handler:
|
||||
cont_pc = cont_sp = catch_iseqval = 0;
|
||||
cont_pc = cont_sp = 0;
|
||||
catch_iseq = NULL;
|
||||
|
||||
while (th->cfp->pc == 0 || th->cfp->iseq == 0) {
|
||||
if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
|
||||
@ -1512,7 +1505,7 @@ vm_exec(rb_thread_t *th)
|
||||
}
|
||||
|
||||
cfp = th->cfp;
|
||||
epc = cfp->pc - cfp->iseq->iseq_encoded;
|
||||
epc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||
|
||||
escape_cfp = NULL;
|
||||
if (state == TAG_BREAK || state == TAG_RETURN) {
|
||||
@ -1525,19 +1518,19 @@ vm_exec(rb_thread_t *th)
|
||||
THROW_DATA_STATE_SET(err, state = TAG_BREAK);
|
||||
}
|
||||
else {
|
||||
ct = cfp->iseq->catch_table;
|
||||
ct = cfp->iseq->body->catch_table;
|
||||
if (ct) for (i = 0; i < ct->size; i++) {
|
||||
entry = &ct->entries[i];
|
||||
if (entry->start < epc && entry->end >= epc) {
|
||||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||||
catch_iseqval = entry->iseq;
|
||||
catch_iseq = entry->iseq;
|
||||
cont_pc = entry->cont;
|
||||
cont_sp = entry->sp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!catch_iseqval) {
|
||||
if (!catch_iseq) {
|
||||
th->errinfo = Qnil;
|
||||
result = THROW_DATA_VAL(err);
|
||||
hook_before_rewind(th, th->cfp);
|
||||
@ -1561,14 +1554,14 @@ vm_exec(rb_thread_t *th)
|
||||
}
|
||||
|
||||
if (state == TAG_RAISE) {
|
||||
ct = cfp->iseq->catch_table;
|
||||
ct = cfp->iseq->body->catch_table;
|
||||
if (ct) for (i = 0; i < ct->size; i++) {
|
||||
entry = &ct->entries[i];
|
||||
if (entry->start < epc && entry->end >= epc) {
|
||||
|
||||
if (entry->type == CATCH_TYPE_RESCUE ||
|
||||
entry->type == CATCH_TYPE_ENSURE) {
|
||||
catch_iseqval = entry->iseq;
|
||||
catch_iseq = entry->iseq;
|
||||
cont_pc = entry->cont;
|
||||
cont_sp = entry->sp;
|
||||
break;
|
||||
@ -1577,13 +1570,13 @@ vm_exec(rb_thread_t *th)
|
||||
}
|
||||
}
|
||||
else if (state == TAG_RETRY) {
|
||||
ct = cfp->iseq->catch_table;
|
||||
ct = cfp->iseq->body->catch_table;
|
||||
if (ct) for (i = 0; i < ct->size; i++) {
|
||||
entry = &ct->entries[i];
|
||||
if (entry->start < epc && entry->end >= epc) {
|
||||
|
||||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||||
catch_iseqval = entry->iseq;
|
||||
catch_iseq = entry->iseq;
|
||||
cont_pc = entry->cont;
|
||||
cont_sp = entry->sp;
|
||||
break;
|
||||
@ -1592,7 +1585,7 @@ vm_exec(rb_thread_t *th)
|
||||
const rb_control_frame_t *escape_cfp;
|
||||
escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||
if (cfp == escape_cfp) {
|
||||
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
|
||||
cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
|
||||
th->errinfo = Qnil;
|
||||
goto vm_loop_start;
|
||||
}
|
||||
@ -1604,19 +1597,19 @@ vm_exec(rb_thread_t *th)
|
||||
type = CATCH_TYPE_BREAK;
|
||||
|
||||
search_restart_point:
|
||||
ct = cfp->iseq->catch_table;
|
||||
ct = cfp->iseq->body->catch_table;
|
||||
if (ct) for (i = 0; i < ct->size; i++) {
|
||||
entry = &ct->entries[i];
|
||||
|
||||
if (entry->start < epc && entry->end >= epc) {
|
||||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||||
catch_iseqval = entry->iseq;
|
||||
catch_iseq = entry->iseq;
|
||||
cont_pc = entry->cont;
|
||||
cont_sp = entry->sp;
|
||||
break;
|
||||
}
|
||||
else if (entry->type == type) {
|
||||
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
|
||||
cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
|
||||
cfp->sp = vm_base_ptr(cfp) + entry->sp;
|
||||
|
||||
if (state != TAG_REDO) {
|
||||
@ -1642,13 +1635,13 @@ vm_exec(rb_thread_t *th)
|
||||
goto search_restart_point;
|
||||
}
|
||||
else {
|
||||
ct = cfp->iseq->catch_table;
|
||||
ct = cfp->iseq->body->catch_table;
|
||||
if (ct) for (i = 0; i < ct->size; i++) {
|
||||
entry = &ct->entries[i];
|
||||
if (entry->start < epc && entry->end >= epc) {
|
||||
|
||||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||||
catch_iseqval = entry->iseq;
|
||||
catch_iseq = entry->iseq;
|
||||
cont_pc = entry->cont;
|
||||
cont_sp = entry->sp;
|
||||
break;
|
||||
@ -1657,14 +1650,10 @@ vm_exec(rb_thread_t *th)
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_iseqval != 0) {
|
||||
/* found catch table */
|
||||
rb_iseq_t *catch_iseq;
|
||||
|
||||
if (catch_iseq != 0) { /* found catch table */
|
||||
/* enter catch scope */
|
||||
GetISeqPtr(catch_iseqval, catch_iseq);
|
||||
cfp->sp = vm_base_ptr(cfp) + cont_sp;
|
||||
cfp->pc = cfp->iseq->iseq_encoded + cont_pc;
|
||||
cfp->pc = cfp->iseq->body->iseq_encoded + cont_pc;
|
||||
|
||||
/* push block frame */
|
||||
cfp->sp[0] = (VALUE)err;
|
||||
@ -1672,10 +1661,10 @@ vm_exec(rb_thread_t *th)
|
||||
cfp->self,
|
||||
VM_ENVVAL_PREV_EP_PTR(cfp->ep),
|
||||
0, /* cref or me */
|
||||
catch_iseq->iseq_encoded,
|
||||
catch_iseq->body->iseq_encoded,
|
||||
cfp->sp + 1 /* push value */,
|
||||
catch_iseq->local_size - 1,
|
||||
catch_iseq->stack_max);
|
||||
catch_iseq->body->local_size - 1,
|
||||
catch_iseq->body->stack_max);
|
||||
|
||||
state = 0;
|
||||
th->state = 0;
|
||||
@ -1706,28 +1695,23 @@ vm_exec(rb_thread_t *th)
|
||||
/* misc */
|
||||
|
||||
VALUE
|
||||
rb_iseq_eval(VALUE iseqval)
|
||||
rb_iseq_eval(const rb_iseq_t *iseq)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE val;
|
||||
|
||||
vm_set_top_stack(th, iseqval);
|
||||
|
||||
vm_set_top_stack(th, iseq);
|
||||
val = vm_exec(th);
|
||||
RB_GC_GUARD(iseqval); /* prohibit tail call optimization */
|
||||
return val;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_iseq_eval_main(VALUE iseqval)
|
||||
rb_iseq_eval_main(const rb_iseq_t *iseq)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE val;
|
||||
|
||||
vm_set_main_stack(th, iseqval);
|
||||
|
||||
vm_set_main_stack(th, iseq);
|
||||
val = vm_exec(th);
|
||||
RB_GC_GUARD(iseqval); /* prohibit tail call optimization */
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -1770,7 +1754,7 @@ rb_thread_current_status(const rb_thread_t *th)
|
||||
const rb_iseq_t *iseq = cfp->iseq;
|
||||
int line_no = rb_vm_get_sourceline(cfp);
|
||||
str = rb_sprintf("%"PRIsVALUE":%d:in `%"PRIsVALUE"'",
|
||||
iseq->location.path, line_no, iseq->location.label);
|
||||
iseq->body->location.path, line_no, iseq->body->location.label);
|
||||
}
|
||||
}
|
||||
else if ((me = rb_vm_frame_method_entry(cfp)) && me->def->original_id) {
|
||||
@ -1788,10 +1772,10 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
const rb_control_frame_t *reg_cfp = th->cfp;
|
||||
volatile VALUE iseqval = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
VALUE val;
|
||||
|
||||
vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
|
||||
recv, VM_ENVVAL_BLOCK_PTR(blockptr),
|
||||
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
||||
0, reg_cfp->sp, 1, 0);
|
||||
@ -2065,12 +2049,9 @@ rb_thread_mark(void *ptr)
|
||||
rb_gc_mark_values((long)(sp - p), p);
|
||||
|
||||
while (cfp != limit_cfp) {
|
||||
const rb_iseq_t *iseq = cfp->iseq;
|
||||
rb_gc_mark(cfp->proc);
|
||||
rb_gc_mark(cfp->self);
|
||||
if (iseq) {
|
||||
rb_gc_mark(RUBY_VM_NORMAL_ISEQ_P(iseq) ? iseq->self : (VALUE)iseq);
|
||||
}
|
||||
rb_gc_mark((VALUE)cfp->iseq);
|
||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
}
|
||||
}
|
||||
@ -2287,11 +2268,11 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
|
||||
visi = METHOD_VISI_PUBLIC;
|
||||
}
|
||||
|
||||
rb_add_method_iseq(klass, id, iseqval, cref, visi);
|
||||
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
|
||||
|
||||
if (!is_singleton && scope_visi->module_func) {
|
||||
klass = rb_singleton_class(klass);
|
||||
rb_add_method_iseq(klass, id, iseqval, cref, METHOD_VISI_PUBLIC);
|
||||
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2755,9 +2736,8 @@ Init_VM(void)
|
||||
rb_vm_t *vm = ruby_current_vm;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE filename = rb_str_new2("<main>");
|
||||
volatile VALUE iseqval = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
volatile VALUE th_self;
|
||||
rb_iseq_t *iseq;
|
||||
|
||||
/* create vm object */
|
||||
vm->self = TypedData_Wrap_Struct(rb_cRubyVM, &vm_data_type, vm);
|
||||
@ -2774,10 +2754,9 @@ Init_VM(void)
|
||||
|
||||
rb_vm_living_threads_insert(vm, th);
|
||||
|
||||
rb_gc_register_mark_object(iseqval);
|
||||
GetISeqPtr(iseqval, iseq);
|
||||
rb_gc_register_mark_object((VALUE)iseq);
|
||||
th->cfp->iseq = iseq;
|
||||
th->cfp->pc = iseq->iseq_encoded;
|
||||
th->cfp->pc = iseq->body->iseq_encoded;
|
||||
th->cfp->self = th->top_self;
|
||||
|
||||
th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, NULL);
|
||||
@ -2800,7 +2779,7 @@ rb_vm_set_progname(VALUE filename)
|
||||
rb_thread_t *th = GET_VM()->main_thread;
|
||||
rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size);
|
||||
--cfp;
|
||||
RB_OBJ_WRITE(cfp->iseq->self, &cfp->iseq->location.path, filename);
|
||||
RB_OBJ_WRITE(cfp->iseq, &cfp->iseq->body->location.path, filename);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
|
||||
@ -2893,7 +2872,7 @@ rb_ruby_debug_ptr(void)
|
||||
}
|
||||
|
||||
/* iseq.c */
|
||||
VALUE rb_insn_operand_intern(rb_iseq_t *iseq,
|
||||
VALUE rb_insn_operand_intern(const rb_iseq_t *iseq,
|
||||
VALUE insn, int op_no, VALUE op,
|
||||
int len, size_t pos, VALUE *pnop, VALUE child);
|
||||
|
||||
|
68
vm_args.c
68
vm_args.c
@ -384,10 +384,10 @@ static void
|
||||
args_setup_kw_parameters(VALUE* const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords,
|
||||
const rb_iseq_t * const iseq, VALUE * const locals)
|
||||
{
|
||||
const ID *acceptable_keywords = iseq->param.keyword->table;
|
||||
const int req_key_num = iseq->param.keyword->required_num;
|
||||
const int key_num = iseq->param.keyword->num;
|
||||
const VALUE * const default_values = iseq->param.keyword->default_values;
|
||||
const ID *acceptable_keywords = iseq->body->param.keyword->table;
|
||||
const int req_key_num = iseq->body->param.keyword->required_num;
|
||||
const int key_num = iseq->body->param.keyword->num;
|
||||
const VALUE * const default_values = iseq->body->param.keyword->default_values;
|
||||
VALUE missing = 0;
|
||||
int i, di, found = 0;
|
||||
int unspecified_bits = 0;
|
||||
@ -438,7 +438,7 @@ args_setup_kw_parameters(VALUE* const passed_values, const int passed_keyword_le
|
||||
}
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_kwrest) {
|
||||
if (iseq->body->param.flags.has_kwrest) {
|
||||
const int rest_hash_index = key_num + 1;
|
||||
locals[rest_hash_index] = make_unused_kw_hash(passed_keywords, passed_keyword_len, passed_values, FALSE);
|
||||
}
|
||||
@ -502,8 +502,8 @@ static int
|
||||
setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, rb_call_info_t * const ci,
|
||||
VALUE * const locals, const enum arg_setup_type arg_setup_type)
|
||||
{
|
||||
const int min_argc = iseq->param.lead_num + iseq->param.post_num;
|
||||
const int max_argc = (iseq->param.flags.has_rest == FALSE) ? min_argc + iseq->param.opt_num : UNLIMITED_ARGUMENTS;
|
||||
const int min_argc = iseq->body->param.lead_num + iseq->body->param.post_num;
|
||||
const int max_argc = (iseq->body->param.flags.has_rest == FALSE) ? min_argc + iseq->body->param.opt_num : UNLIMITED_ARGUMENTS;
|
||||
int opt_pc = 0;
|
||||
int given_argc;
|
||||
struct args_info args_body, *args;
|
||||
@ -516,16 +516,16 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
|
||||
*
|
||||
* [pushed values] [uninitialized values]
|
||||
* <- ci->argc -->
|
||||
* <- iseq->param.size------------------>
|
||||
* <- iseq->body->param.size------------>
|
||||
* ^ locals ^ sp
|
||||
*
|
||||
* =>
|
||||
* [pushed values] [initialized values ]
|
||||
* <- ci->argc -->
|
||||
* <- iseq->param.size------------------>
|
||||
* <- iseq->body->param.size------------>
|
||||
* ^ locals ^ sp
|
||||
*/
|
||||
for (i=ci->argc; i<iseq->param.size; i++) {
|
||||
for (i=ci->argc; i<iseq->body->param.size; i++) {
|
||||
locals[i] = Qnil;
|
||||
}
|
||||
th->cfp->sp = &locals[i];
|
||||
@ -537,7 +537,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
|
||||
args->argv = locals;
|
||||
|
||||
if (ci->kw_arg) {
|
||||
if (iseq->param.flags.has_kw) {
|
||||
if (iseq->body->param.flags.has_kw) {
|
||||
int kw_len = ci->kw_arg->keyword_len;
|
||||
/* copy kw_argv */
|
||||
args->kw_argv = ALLOCA_N(VALUE, kw_len);
|
||||
@ -568,17 +568,17 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
|
||||
break; /* do nothing special */
|
||||
case arg_setup_block:
|
||||
if (given_argc == 1 &&
|
||||
(min_argc > 0 || iseq->param.opt_num > 1 ||
|
||||
iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) &&
|
||||
!iseq->param.flags.ambiguous_param0 &&
|
||||
(min_argc > 0 || iseq->body->param.opt_num > 1 ||
|
||||
iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
|
||||
!iseq->body->param.flags.ambiguous_param0 &&
|
||||
args_check_block_arg0(args, th)) {
|
||||
given_argc = RARRAY_LENINT(args->rest);
|
||||
}
|
||||
break;
|
||||
case arg_setup_lambda:
|
||||
if (given_argc == 1 &&
|
||||
given_argc != iseq->param.lead_num &&
|
||||
!iseq->param.flags.has_rest &&
|
||||
given_argc != iseq->body->param.lead_num &&
|
||||
!iseq->body->param.flags.has_rest &&
|
||||
args_check_block_arg0(args, th)) {
|
||||
given_argc = RARRAY_LENINT(args->rest);
|
||||
}
|
||||
@ -603,7 +603,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
|
||||
}
|
||||
|
||||
if (given_argc > min_argc &&
|
||||
(iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) &&
|
||||
(iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
|
||||
args->kw_argv == NULL) {
|
||||
if (args_pop_keyword_hash(args, &keyword_hash, th)) {
|
||||
given_argc--;
|
||||
@ -621,25 +621,25 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
|
||||
}
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_lead) {
|
||||
args_setup_lead_parameters(args, iseq->param.lead_num, locals + 0);
|
||||
if (iseq->body->param.flags.has_lead) {
|
||||
args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0);
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_post) {
|
||||
args_setup_post_parameters(args, iseq->param.post_num, locals + iseq->param.post_start);
|
||||
if (iseq->body->param.flags.has_post) {
|
||||
args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start);
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_opt) {
|
||||
int opt = args_setup_opt_parameters(args, iseq->param.opt_num, locals + iseq->param.lead_num);
|
||||
opt_pc = (int)iseq->param.opt_table[opt];
|
||||
if (iseq->body->param.flags.has_opt) {
|
||||
int opt = args_setup_opt_parameters(args, iseq->body->param.opt_num, locals + iseq->body->param.lead_num);
|
||||
opt_pc = (int)iseq->body->param.opt_table[opt];
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_rest) {
|
||||
args_setup_rest_parameter(args, locals + iseq->param.rest_start);
|
||||
if (iseq->body->param.flags.has_rest) {
|
||||
args_setup_rest_parameter(args, locals + iseq->body->param.rest_start);
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_kw) {
|
||||
VALUE * const klocals = locals + iseq->param.keyword->bits_start - iseq->param.keyword->num;
|
||||
if (iseq->body->param.flags.has_kw) {
|
||||
VALUE * const klocals = locals + iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num;
|
||||
|
||||
if (args->kw_argv != NULL) {
|
||||
args_setup_kw_parameters(args->kw_argv, args->ci->kw_arg->keyword_len, args->ci->kw_arg->keywords, iseq, klocals);
|
||||
@ -660,18 +660,18 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
|
||||
args_setup_kw_parameters(NULL, 0, NULL, iseq, klocals);
|
||||
}
|
||||
}
|
||||
else if (iseq->param.flags.has_kwrest) {
|
||||
args_setup_kw_rest_parameter(keyword_hash, locals + iseq->param.keyword->rest_start);
|
||||
else if (iseq->body->param.flags.has_kwrest) {
|
||||
args_setup_kw_rest_parameter(keyword_hash, locals + iseq->body->param.keyword->rest_start);
|
||||
}
|
||||
|
||||
if (iseq->param.flags.has_block) {
|
||||
args_setup_block_parameter(th, ci, locals + iseq->param.block_start);
|
||||
if (iseq->body->param.flags.has_block) {
|
||||
args_setup_block_parameter(th, ci, locals + iseq->body->param.block_start);
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<iseq->param.size; i++) {
|
||||
for (i=0; i<iseq->body->param.size; i++) {
|
||||
fprintf(stderr, "local[%d] = %p\n", i, (void *)locals[i]);
|
||||
}
|
||||
}
|
||||
@ -691,7 +691,7 @@ raise_argument_error(rb_thread_t *th, const rb_iseq_t *iseq, const VALUE exc)
|
||||
if (iseq) {
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_DUMMY, Qnil /* self */,
|
||||
VM_ENVVAL_BLOCK_PTR(0) /* specval*/, Qfalse /* me or cref */,
|
||||
iseq->iseq_encoded, th->cfp->sp, 1 /* local_size (cref/me) */, 0 /* stack_max */);
|
||||
iseq->body->iseq_encoded, th->cfp->sp, 1 /* local_size (cref/me) */, 0 /* stack_max */);
|
||||
at = rb_vm_backtrace_object();
|
||||
vm_pop_frame(th);
|
||||
}
|
||||
|
@ -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
|
||||
|
51
vm_core.h
51
vm_core.h
@ -233,9 +233,6 @@ typedef struct rb_call_info_struct {
|
||||
#define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct((obj), type, (ptr))
|
||||
#endif
|
||||
|
||||
#define GetISeqPtr(obj, ptr) \
|
||||
GetCoreDataFromValue((obj), rb_iseq_t, (ptr))
|
||||
|
||||
typedef struct rb_iseq_location_struct {
|
||||
const VALUE path;
|
||||
const VALUE absolute_path;
|
||||
@ -244,7 +241,7 @@ typedef struct rb_iseq_location_struct {
|
||||
VALUE first_lineno; /* TODO: may be unsigned short */
|
||||
} rb_iseq_location_t;
|
||||
|
||||
struct rb_iseq_struct {
|
||||
struct rb_iseq_body {
|
||||
/***************/
|
||||
/* static data */
|
||||
/***************/
|
||||
@ -260,9 +257,7 @@ struct rb_iseq_struct {
|
||||
ISEQ_TYPE_MAIN,
|
||||
ISEQ_TYPE_DEFINED_GUARD
|
||||
} type; /* instruction sequence type */
|
||||
#if defined(WORDS_BIGENDIAN) && (SIZEOF_VALUE > SIZEOF_INT)
|
||||
char dummy[SIZEOF_VALUE - SIZEOF_INT]; /* [Bug #10037][ruby-core:63721] */
|
||||
#endif
|
||||
|
||||
int stack_max; /* for stack overflow check */
|
||||
|
||||
rb_iseq_location_t location;
|
||||
@ -370,19 +365,24 @@ struct rb_iseq_struct {
|
||||
/* dynamic data */
|
||||
/****************/
|
||||
|
||||
VALUE self;
|
||||
|
||||
/* misc */
|
||||
rb_num_t flip_cnt;
|
||||
|
||||
/* used at compile time */
|
||||
struct iseq_compile_data *compile_data;
|
||||
|
||||
/* original iseq, before encoding
|
||||
* used for debug/dump (TODO: union with compile_data) */
|
||||
VALUE *iseq;
|
||||
};
|
||||
|
||||
/* T_IMEMO/iseq */
|
||||
/* typedef rb_iseq_t is in method.h */
|
||||
struct rb_iseq_struct {
|
||||
VALUE flags;
|
||||
struct iseq_compile_data *compile_data; /* used at compile time */
|
||||
struct rb_iseq_body *body;
|
||||
VALUE dummy1;
|
||||
VALUE dummy2;
|
||||
};
|
||||
|
||||
enum ruby_special_exceptions {
|
||||
ruby_error_reenter,
|
||||
ruby_error_nomemory,
|
||||
@ -785,18 +785,18 @@ typedef enum {
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
|
||||
/* node -> iseq */
|
||||
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, enum iseq_type);
|
||||
VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE parent);
|
||||
VALUE rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path);
|
||||
VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE);
|
||||
VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, const rb_compile_option_t*);
|
||||
rb_iseq_t *rb_iseq_new(NODE*, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type);
|
||||
rb_iseq_t *rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, const rb_iseq_t *parent);
|
||||
rb_iseq_t *rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path);
|
||||
rb_iseq_t *rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE);
|
||||
rb_iseq_t *rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*);
|
||||
|
||||
/* src -> iseq */
|
||||
VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
|
||||
VALUE rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_block);
|
||||
VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt);
|
||||
rb_iseq_t *rb_iseq_compile(VALUE src, VALUE file, VALUE line);
|
||||
rb_iseq_t *rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_block);
|
||||
rb_iseq_t *rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt);
|
||||
|
||||
VALUE rb_iseq_disasm(VALUE self);
|
||||
VALUE rb_iseq_disasm(const rb_iseq_t *iseq);
|
||||
int rb_iseq_disasm_insn(VALUE str, const VALUE *iseqval, size_t pos, const rb_iseq_t *iseq, VALUE child);
|
||||
const char *ruby_node_name(int node);
|
||||
|
||||
@ -946,9 +946,8 @@ rb_block_t *rb_vm_control_frame_block_ptr(const rb_control_frame_t *cfp);
|
||||
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
|
||||
(!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th)))
|
||||
|
||||
#define RUBY_VM_IFUNC_P(ptr) RB_TYPE_P((VALUE)(ptr), T_IMEMO)
|
||||
#define RUBY_VM_NORMAL_ISEQ_P(ptr) \
|
||||
((ptr) && !RUBY_VM_IFUNC_P(ptr))
|
||||
#define RUBY_VM_IFUNC_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_ifunc)
|
||||
#define RUBY_VM_NORMAL_ISEQ_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_iseq)
|
||||
|
||||
#define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self))
|
||||
#define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \
|
||||
@ -972,8 +971,8 @@ NORETURN(void rb_bug_context(const void *, const char *fmt, ...));
|
||||
|
||||
/* functions about thread/vm execution */
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
VALUE rb_iseq_eval(VALUE iseqval);
|
||||
VALUE rb_iseq_eval_main(VALUE iseqval);
|
||||
VALUE rb_iseq_eval(const rb_iseq_t *iseq);
|
||||
VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
|
||||
|
||||
|
22
vm_dump.c
22
vm_dump.c
@ -39,7 +39,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||
const rb_callable_method_entry_t *me;
|
||||
|
||||
if (cfp->block_iseq != 0 && !RUBY_VM_IFUNC_P(cfp->block_iseq)) {
|
||||
biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */
|
||||
biseq_name = ""; /* RSTRING(cfp->block_iseq->body->location.label)->ptr; */
|
||||
}
|
||||
|
||||
if (ep < 0 || (size_t)ep > th->stack_size) {
|
||||
@ -99,11 +99,11 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||
iseq_name = "<ifunc>";
|
||||
}
|
||||
else {
|
||||
pc = cfp->pc - cfp->iseq->iseq_encoded;
|
||||
iseq_name = RSTRING_PTR(cfp->iseq->location.label);
|
||||
pc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||
iseq_name = RSTRING_PTR(cfp->iseq->body->location.label);
|
||||
line = rb_vm_get_sourceline(cfp);
|
||||
if (line) {
|
||||
snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->location.path), line);
|
||||
snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->body->location.path), line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,9 +233,9 @@ static VALUE *
|
||||
vm_base_ptr(rb_control_frame_t *cfp)
|
||||
{
|
||||
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1;
|
||||
VALUE *bp = prev_cfp->sp + cfp->iseq->body->local_size + 1;
|
||||
|
||||
if (cfp->iseq->type == ISEQ_TYPE_METHOD) {
|
||||
if (cfp->iseq->body->type == ISEQ_TYPE_METHOD) {
|
||||
bp += 1;
|
||||
}
|
||||
return bp;
|
||||
@ -266,9 +266,9 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||
name = "<ifunc>";
|
||||
}
|
||||
else {
|
||||
argc = iseq->param.lead_num;
|
||||
local_size = iseq->local_size;
|
||||
name = RSTRING_PTR(iseq->location.label);
|
||||
argc = iseq->body->param.lead_num;
|
||||
local_size = iseq->body->local_size;
|
||||
name = RSTRING_PTR(iseq->body->location.label);
|
||||
}
|
||||
|
||||
/* stack trace header */
|
||||
@ -335,7 +335,7 @@ rb_vmdebug_debug_print_register(rb_thread_t *th)
|
||||
ptrdiff_t cfpi;
|
||||
|
||||
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
||||
pc = cfp->pc - cfp->iseq->iseq_encoded;
|
||||
pc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||
}
|
||||
|
||||
if (ep < 0 || (size_t)ep > th->stack_size) {
|
||||
@ -361,7 +361,7 @@ rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp,VALUE *_pc)
|
||||
const rb_iseq_t *iseq = cfp->iseq;
|
||||
|
||||
if (iseq != 0) {
|
||||
ptrdiff_t pc = _pc - iseq->iseq_encoded;
|
||||
ptrdiff_t pc = _pc - iseq->body->iseq_encoded;
|
||||
int i;
|
||||
|
||||
for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) {
|
||||
|
20
vm_eval.c
20
vm_eval.c
@ -20,7 +20,7 @@ static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *a
|
||||
static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
|
||||
static inline VALUE vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, const rb_block_t *blockargptr);
|
||||
static VALUE vm_exec(rb_thread_t *th);
|
||||
static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const rb_cref_t *cref, rb_block_t *base_block);
|
||||
static void vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, rb_block_t *base_block);
|
||||
static int vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *dfp, const struct local_var_list *vars);
|
||||
|
||||
static VALUE rb_eUncaughtThrow;
|
||||
@ -1234,8 +1234,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
||||
if ((state = TH_EXEC_TAG()) == 0) {
|
||||
rb_cref_t *cref = cref_arg;
|
||||
rb_binding_t *bind = 0;
|
||||
rb_iseq_t *iseq;
|
||||
volatile VALUE iseqval;
|
||||
const rb_iseq_t *iseq;
|
||||
VALUE absolute_path = Qnil;
|
||||
VALUE fname;
|
||||
|
||||
@ -1282,7 +1281,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
||||
/* make eval iseq */
|
||||
th->parse_in_eval++;
|
||||
th->mild_compile_error++;
|
||||
iseqval = rb_iseq_compile_with_option(src, fname, absolute_path, INT2FIX(line), base_block, Qnil);
|
||||
iseq = rb_iseq_compile_with_option(src, fname, absolute_path, INT2FIX(line), base_block, Qnil);
|
||||
th->mild_compile_error--;
|
||||
th->parse_in_eval--;
|
||||
|
||||
@ -1297,17 +1296,16 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
||||
cref = rb_vm_get_cref(base_block->ep);
|
||||
}
|
||||
}
|
||||
vm_set_eval_stack(th, iseqval, cref, base_block);
|
||||
vm_set_eval_stack(th, iseq, cref, base_block);
|
||||
RB_GC_GUARD(crefval);
|
||||
|
||||
if (0) { /* for debug */
|
||||
VALUE disasm = rb_iseq_disasm(iseqval);
|
||||
VALUE disasm = rb_iseq_disasm(iseq);
|
||||
printf("%s\n", StringValuePtr(disasm));
|
||||
}
|
||||
|
||||
/* save new env */
|
||||
GetISeqPtr(iseqval, iseq);
|
||||
if (bind && iseq->local_table_size > 0) {
|
||||
if (bind && iseq->body->local_table_size > 0) {
|
||||
bind->env = vm_make_env_object(th, th->cfp);
|
||||
}
|
||||
|
||||
@ -2050,8 +2048,8 @@ rb_f_local_variables(void)
|
||||
local_var_list_init(&vars);
|
||||
while (cfp) {
|
||||
if (cfp->iseq) {
|
||||
for (i = 0; i < cfp->iseq->local_table_size; i++) {
|
||||
local_var_list_add(&vars, cfp->iseq->local_table[i]);
|
||||
for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
|
||||
local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
|
||||
}
|
||||
}
|
||||
if (!VM_EP_LEP_P(cfp->ep)) {
|
||||
@ -2117,7 +2115,7 @@ rb_current_realfilepath(void)
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->cfp;
|
||||
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
|
||||
if (cfp != 0) return cfp->iseq->location.absolute_path;
|
||||
if (cfp != 0) return cfp->iseq->body->location.absolute_path;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
17
vm_method.c
17
vm_method.c
@ -254,7 +254,7 @@ method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def,
|
||||
cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
||||
|
||||
if (cfp && (line = rb_vm_get_sourceline(cfp))) {
|
||||
VALUE location = rb_ary_new3(2, cfp->iseq->location.path, INT2FIX(line));
|
||||
VALUE location = rb_ary_new3(2, cfp->iseq->body->location.path, INT2FIX(line));
|
||||
RB_OBJ_WRITE(me, &def->body.attr.location, rb_ary_freeze(location));
|
||||
}
|
||||
else {
|
||||
@ -296,7 +296,7 @@ method_definition_reset(const rb_method_entry_t *me)
|
||||
|
||||
switch(def->type) {
|
||||
case VM_METHOD_TYPE_ISEQ:
|
||||
RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.iseqptr->self);
|
||||
RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.iseqptr);
|
||||
RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.cref);
|
||||
break;
|
||||
case VM_METHOD_TYPE_ATTRSET:
|
||||
@ -512,9 +512,9 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (iseq && !NIL_P(iseq->location.path)) {
|
||||
int line = iseq->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq->self)) : 0;
|
||||
rb_compile_warning(RSTRING_PTR(iseq->location.path), line,
|
||||
if (iseq && !NIL_P(iseq->body->location.path)) {
|
||||
int line = iseq->body->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq)) : 0;
|
||||
rb_compile_warning(RSTRING_PTR(iseq->body->location.path), line,
|
||||
"previous definition of %"PRIsVALUE" was here",
|
||||
rb_id2str(old_def->original_id));
|
||||
}
|
||||
@ -583,19 +583,16 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
|
||||
}
|
||||
|
||||
void
|
||||
rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi)
|
||||
rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
|
||||
{
|
||||
rb_iseq_t *iseq;
|
||||
struct { /* should be same fields with rb_method_iseq_struct */
|
||||
rb_iseq_t *iseqptr;
|
||||
const rb_iseq_t *iseqptr;
|
||||
rb_cref_t *cref;
|
||||
} iseq_body;
|
||||
|
||||
GetISeqPtr(iseqval, iseq);
|
||||
iseq_body.iseqptr = iseq;
|
||||
iseq_body.cref = cref;
|
||||
rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
|
||||
RB_GC_GUARD(iseqval);
|
||||
}
|
||||
|
||||
static rb_method_entry_t *
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user