зеркало из https://github.com/github/ruby.git
* compile.c, iseq.c: fix iseq some of load/store process.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12676 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
27013e71e4
Коммит
1ccf555a70
|
@ -1,3 +1,7 @@
|
||||||
|
Mon Jul 2 05:29:07 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* compile.c, iseq.c: fix iseq some of load/store process.
|
||||||
|
|
||||||
Mon Jul 2 03:09:36 2007 Koichi Sasada <ko1@atdot.net>
|
Mon Jul 2 03:09:36 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* yarvcore.h, compile.c, insnhelper.ci, iseq.c, vm.c:
|
* yarvcore.h, compile.c, insnhelper.ci, iseq.c, vm.c:
|
||||||
|
|
77
compile.c
77
compile.c
|
@ -4542,12 +4542,11 @@ iseq_build_exception(rb_iseq_t *iseq, struct st_table *labels_table,
|
||||||
return COMPILE_OK;
|
return COMPILE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct st_table *insn_make_insn_table(void);
|
struct st_table *insn_make_insn_table(void);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
||||||
VALUE body, VALUE line, struct st_table *labels_table)
|
VALUE body, struct st_table *labels_table)
|
||||||
{
|
{
|
||||||
/* TODO: body should be freezed */
|
/* TODO: body should be freezed */
|
||||||
VALUE *ptr = RARRAY_PTR(body);
|
VALUE *ptr = RARRAY_PTR(body);
|
||||||
|
@ -4577,14 +4576,16 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
||||||
VALUE *argv = 0;
|
VALUE *argv = 0;
|
||||||
int argc = RARRAY_LEN(obj) - 1;
|
int argc = RARRAY_LEN(obj) - 1;
|
||||||
VALUE insn_id;
|
VALUE insn_id;
|
||||||
|
VALUE insn;
|
||||||
|
|
||||||
if (st_lookup(insn_table, rb_ary_entry(obj, 0), &insn_id) == 0) {
|
insn = rb_ary_entry(obj, 0);
|
||||||
|
if (st_lookup(insn_table, insn, &insn_id) == 0) {
|
||||||
/* TODO: exception */
|
/* TODO: exception */
|
||||||
rb_bug("unknown instruction: ");
|
rb_raise(rb_eRuntimeError, "unknown instruction: %s", rb_inspect(insn));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != insn_len(insn_id)-1) {
|
if (argc != insn_len(insn_id)-1) {
|
||||||
rb_bug("operand size mismatch");
|
rb_raise(rb_eRuntimeError, "operand size mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
|
@ -4610,15 +4611,13 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
||||||
{
|
{
|
||||||
if (op != Qnil) {
|
if (op != Qnil) {
|
||||||
if (TYPE(op) == T_ARRAY) {
|
if (TYPE(op) == T_ARRAY) {
|
||||||
argv[j] =
|
argv[j] = iseq_load(0, op, iseq->self, Qnil);
|
||||||
iseq_load(0, op, iseq->self, Qnil);
|
|
||||||
}
|
}
|
||||||
else if (CLASS_OF(op) == rb_cISeq) {
|
else if (CLASS_OF(op) == rb_cISeq) {
|
||||||
argv[j] = op;
|
argv[j] = op;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* TODO: exception */
|
rb_raise(rb_eRuntimeError, "ISEQ is required");
|
||||||
rb_bug("not an iseq");
|
|
||||||
}
|
}
|
||||||
iseq_add_mark_object(iseq, argv[j]);
|
iseq_add_mark_object(iseq, argv[j]);
|
||||||
}
|
}
|
||||||
|
@ -4670,9 +4669,14 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
||||||
return COMPILE_OK;
|
return COMPILE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK_ARRAY(v) rb_convert_type(v, T_ARRAY, "Array", "to_ary")
|
||||||
|
#define CHECK_STRING(v) rb_convert_type(v, T_STRING, "String", "to_str")
|
||||||
|
#define CHECK_SYMBOL(v) rb_convert_type(v, T_SYMBOL, "Symbol", "to_sym")
|
||||||
|
#define CHECK_INTEGER(v) (NUM2LONG(v), v)
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
iseq_build_from_ary(rb_iseq_t *iseq, VALUE line,
|
iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args,
|
||||||
VALUE locals, VALUE args, VALUE exception, VALUE body)
|
VALUE exception, VALUE body)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
|
@ -4687,45 +4691,50 @@ iseq_build_from_ary(rb_iseq_t *iseq, VALUE line,
|
||||||
opt = 1;
|
opt = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
iseq->local_size = opt + RARRAY_LEN(locals);
|
iseq->local_table_size = opt + RARRAY_LEN(locals);
|
||||||
iseq->local_table_size = iseq->local_size;
|
iseq->local_table = tbl = (ID *)ALLOC_N(ID *, iseq->local_table_size);
|
||||||
iseq->local_table = (ID *)ALLOC_N(ID *, iseq->local_size);
|
iseq->local_size = opt + iseq->local_table_size;
|
||||||
tbl = iseq->local_table + opt;
|
|
||||||
|
|
||||||
for (i=0; i<RARRAY_LEN(locals); i++) {
|
for (i=0; i<RARRAY_LEN(locals); i++) {
|
||||||
tbl[i] = SYM2ID(RARRAY_PTR(locals)[i]);
|
tbl[i] = SYM2ID(CHECK_SYMBOL(RARRAY_PTR(locals)[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* args */
|
/* args */
|
||||||
if (FIXNUM_P(args)) {
|
if (FIXNUM_P(args)) {
|
||||||
iseq->argc = FIX2INT(args);
|
iseq->arg_size = iseq->argc = FIX2INT(args);
|
||||||
iseq->arg_simple = 1;
|
iseq->arg_simple = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/*
|
|
||||||
* [argc, # argc
|
|
||||||
* opts, # opts
|
|
||||||
* [label1, label2, ...] # opt labels
|
|
||||||
* rest_iex,
|
|
||||||
* block_idx,
|
|
||||||
* ]
|
|
||||||
* or
|
|
||||||
* argc (Fixnum) # arg_simple
|
|
||||||
*/
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
VALUE argc = rb_ary_entry(args, i++);
|
VALUE argc = CHECK_INTEGER(rb_ary_entry(args, i++));
|
||||||
VALUE arg_opts = rb_ary_entry(args, i++);
|
VALUE arg_opts = CHECK_INTEGER(rb_ary_entry(args, i++));
|
||||||
VALUE arg_opt_labels = rb_ary_entry(args, i++);
|
VALUE arg_opt_labels = CHECK_ARRAY(rb_ary_entry(args, i++));
|
||||||
VALUE arg_rest = rb_ary_entry(args, i++);
|
VALUE arg_post_len = CHECK_INTEGER(rb_ary_entry(args, i++));
|
||||||
VALUE arg_block = rb_ary_entry(args, i++);
|
VALUE arg_post_start = CHECK_INTEGER(rb_ary_entry(args, i++));
|
||||||
|
VALUE arg_rest = CHECK_INTEGER(rb_ary_entry(args, i++));
|
||||||
|
VALUE arg_block = CHECK_INTEGER(rb_ary_entry(args, i++));
|
||||||
|
|
||||||
iseq->argc = FIX2INT(argc);
|
iseq->argc = FIX2INT(argc);
|
||||||
iseq->arg_opts = FIX2INT(arg_opts);
|
iseq->arg_opts = FIX2INT(arg_opts);
|
||||||
iseq->arg_rest = FIX2INT(arg_rest);
|
iseq->arg_rest = FIX2INT(arg_rest);
|
||||||
|
iseq->arg_post_len = FIX2INT(arg_post_len);
|
||||||
|
iseq->arg_post_start = FIX2INT(arg_post_start);
|
||||||
iseq->arg_block = FIX2INT(arg_block);
|
iseq->arg_block = FIX2INT(arg_block);
|
||||||
|
|
||||||
iseq->arg_opt_table = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts);
|
iseq->arg_opt_table = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts);
|
||||||
|
|
||||||
|
if (iseq->arg_block != -1) {
|
||||||
|
iseq->arg_size = iseq->arg_block + 1;
|
||||||
|
}
|
||||||
|
else if (iseq->arg_post_len) {
|
||||||
|
iseq->arg_size = iseq->arg_post_start + iseq->arg_post_len;
|
||||||
|
}
|
||||||
|
else if (iseq->arg_rest != -1) {
|
||||||
|
iseq->arg_size = iseq->arg_rest + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iseq->arg_size = iseq->argc + iseq->arg_opts;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<RARRAY_LEN(arg_opt_labels); i++) {
|
for (i=0; i<RARRAY_LEN(arg_opt_labels); i++) {
|
||||||
iseq->arg_opt_table[i] =
|
iseq->arg_opt_table[i] =
|
||||||
(VALUE)register_label(iseq, labels_table,
|
(VALUE)register_label(iseq, labels_table,
|
||||||
|
@ -4737,6 +4746,6 @@ iseq_build_from_ary(rb_iseq_t *iseq, VALUE line,
|
||||||
iseq_build_exception(iseq, labels_table, exception);
|
iseq_build_exception(iseq, labels_table, exception);
|
||||||
|
|
||||||
/* body */
|
/* body */
|
||||||
iseq_build_body(iseq, anchor, body, line, labels_table);
|
iseq_build_body(iseq, anchor, body, labels_table);
|
||||||
return iseq->self;
|
return iseq->self;
|
||||||
}
|
}
|
||||||
|
|
50
iseq.c
50
iseq.c
|
@ -304,8 +304,8 @@ rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename,
|
||||||
bopt, &COMPILE_OPTION_DEFAULT);
|
bopt, &COMPILE_OPTION_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE iseq_build_from_ary(rb_iseq_t *iseq, VALUE line,
|
VALUE iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args,
|
||||||
VALUE locals, VALUE args, VALUE exception, VALUE body);
|
VALUE exception, VALUE body);
|
||||||
|
|
||||||
#define CHECK_ARRAY(v) rb_convert_type(v, T_ARRAY, "Array", "to_ary")
|
#define CHECK_ARRAY(v) rb_convert_type(v, T_ARRAY, "Array", "to_ary")
|
||||||
#define CHECK_STRING(v) rb_convert_type(v, T_STRING, "String", "to_str")
|
#define CHECK_STRING(v) rb_convert_type(v, T_STRING, "String", "to_str")
|
||||||
|
@ -344,10 +344,12 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
|
||||||
|
|
||||||
type = CHECK_SYMBOL(rb_ary_entry(data, 8));
|
type = CHECK_SYMBOL(rb_ary_entry(data, 8));
|
||||||
locals = CHECK_ARRAY(rb_ary_entry(data, 9));
|
locals = CHECK_ARRAY(rb_ary_entry(data, 9));
|
||||||
args = rb_ary_entry(data, 10);
|
|
||||||
|
args = rb_ary_entry(data, 10);
|
||||||
if (FIXNUM_P(args) || (args = CHECK_ARRAY(args))) {
|
if (FIXNUM_P(args) || (args = CHECK_ARRAY(args))) {
|
||||||
/* */
|
/* */
|
||||||
}
|
}
|
||||||
|
|
||||||
exception = CHECK_ARRAY(rb_ary_entry(data, 11));
|
exception = CHECK_ARRAY(rb_ary_entry(data, 11));
|
||||||
body = CHECK_ARRAY(rb_ary_entry(data, 12));
|
body = CHECK_ARRAY(rb_ary_entry(data, 12));
|
||||||
|
|
||||||
|
@ -377,7 +379,7 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
|
||||||
prepare_iseq_build(iseq, name, filename,
|
prepare_iseq_build(iseq, name, filename,
|
||||||
parent, iseq_type, 0, &option);
|
parent, iseq_type, 0, &option);
|
||||||
|
|
||||||
iseq_build_from_ary(iseq, line, locals, args, exception, body);
|
iseq_build_from_ary(iseq, locals, args, exception, body);
|
||||||
|
|
||||||
cleanup_iseq_build(iseq);
|
cleanup_iseq_build(iseq);
|
||||||
return iseqval;
|
return iseqval;
|
||||||
|
@ -1108,7 +1110,7 @@ cdhash_each(VALUE key, VALUE value, VALUE ary)
|
||||||
VALUE
|
VALUE
|
||||||
iseq_data_to_ary(rb_iseq_t *iseq)
|
iseq_data_to_ary(rb_iseq_t *iseq)
|
||||||
{
|
{
|
||||||
int i, pos;
|
int i, pos, line = 0, insn_pos = 0;
|
||||||
VALUE *seq;
|
VALUE *seq;
|
||||||
|
|
||||||
VALUE val = rb_ary_new();
|
VALUE val = rb_ary_new();
|
||||||
|
@ -1117,8 +1119,8 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
||||||
VALUE args = rb_ary_new();
|
VALUE args = rb_ary_new();
|
||||||
VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
|
VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
|
||||||
VALUE nbody;
|
VALUE nbody;
|
||||||
VALUE line = rb_ary_new();
|
|
||||||
VALUE exception = rb_ary_new(); /* [[....]] */
|
VALUE exception = rb_ary_new(); /* [[....]] */
|
||||||
|
VALUE misc = rb_hash_new();
|
||||||
|
|
||||||
static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE];
|
static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE];
|
||||||
struct st_table *labels_table = st_init_numtable();
|
struct st_table *labels_table = st_init_numtable();
|
||||||
|
@ -1173,11 +1175,12 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
||||||
/*
|
/*
|
||||||
* [argc, # argc
|
* [argc, # argc
|
||||||
* [label1, label2, ...] # opts
|
* [label1, label2, ...] # opts
|
||||||
* rest_iex,
|
* rest index,
|
||||||
* block_idx,
|
* post_len
|
||||||
|
* post_start
|
||||||
|
* block index,
|
||||||
|
* simple,
|
||||||
* ]
|
* ]
|
||||||
* or
|
|
||||||
* argc (Fixnum) # arg_simple
|
|
||||||
*/
|
*/
|
||||||
VALUE arg_opt_labels = rb_ary_new();
|
VALUE arg_opt_labels = rb_ary_new();
|
||||||
int j;
|
int j;
|
||||||
|
@ -1188,15 +1191,17 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* commit */
|
/* commit */
|
||||||
if (iseq->arg_simple) {
|
if (iseq->arg_simple == 1) {
|
||||||
args = INT2FIX(iseq->argc);
|
args = INT2FIX(iseq->argc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_ary_push(args, INT2FIX(iseq->argc));
|
rb_ary_push(args, INT2FIX(iseq->argc));
|
||||||
rb_ary_push(args, INT2FIX(iseq->arg_opts));
|
|
||||||
rb_ary_push(args, arg_opt_labels);
|
rb_ary_push(args, arg_opt_labels);
|
||||||
|
rb_ary_push(args, INT2FIX(iseq->arg_post_len));
|
||||||
|
rb_ary_push(args, INT2FIX(iseq->arg_post_start));
|
||||||
rb_ary_push(args, INT2FIX(iseq->arg_rest));
|
rb_ary_push(args, INT2FIX(iseq->arg_rest));
|
||||||
rb_ary_push(args, INT2FIX(iseq->arg_block));
|
rb_ary_push(args, INT2FIX(iseq->arg_block));
|
||||||
|
rb_ary_push(args, INT2FIX(iseq->arg_simple));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1294,7 +1299,7 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
||||||
rb_ary_push(exception, ary);
|
rb_ary_push(exception, ary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make body with labels */
|
/* make body with labels and insert line number */
|
||||||
body = rb_ary_new();
|
body = rb_ary_new();
|
||||||
|
|
||||||
for (i=0, pos=0; i<RARRAY_LEN(nbody); i++) {
|
for (i=0, pos=0; i<RARRAY_LEN(nbody); i++) {
|
||||||
|
@ -1305,26 +1310,33 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
||||||
rb_ary_push(body, label);
|
rb_ary_push(body, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iseq->insn_info_table[i].line_no != line) {
|
||||||
|
line = iseq->insn_info_table[i].line_no;
|
||||||
|
rb_ary_push(body, INT2FIX(line));
|
||||||
|
}
|
||||||
|
|
||||||
rb_ary_push(body, ary);
|
rb_ary_push(body, ary);
|
||||||
pos += RARRAY_LEN(ary);
|
pos += RARRAY_LEN(ary);
|
||||||
}
|
}
|
||||||
|
|
||||||
st_free_table(labels_table);
|
st_free_table(labels_table);
|
||||||
|
|
||||||
/* build array */
|
rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->arg_size));
|
||||||
|
rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->local_size));
|
||||||
|
rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->stack_max));
|
||||||
|
|
||||||
/* [magic, major_version, minor_version, format_type, misc,
|
/*
|
||||||
* name, filename, line,
|
* [:magic, :major_version, :minor_version, :format_type, :misc,
|
||||||
* type, args, vars, exception_table, body]
|
* :name, :filename, :type, :locals, :args,
|
||||||
|
* :catch_table, :bytecode]
|
||||||
*/
|
*/
|
||||||
rb_ary_push(val, rb_str_new2("YARVInstructionSimpledataFormat"));
|
rb_ary_push(val, rb_str_new2("YARVInstructionSimpledataFormat"));
|
||||||
rb_ary_push(val, INT2FIX(1));
|
rb_ary_push(val, INT2FIX(1));
|
||||||
rb_ary_push(val, INT2FIX(1));
|
rb_ary_push(val, INT2FIX(1));
|
||||||
rb_ary_push(val, INT2FIX(1));
|
rb_ary_push(val, INT2FIX(1));
|
||||||
rb_ary_push(val, Qnil);
|
rb_ary_push(val, misc);
|
||||||
rb_ary_push(val, iseq->name);
|
rb_ary_push(val, iseq->name);
|
||||||
rb_ary_push(val, iseq->filename);
|
rb_ary_push(val, iseq->filename);
|
||||||
rb_ary_push(val, line);
|
|
||||||
rb_ary_push(val, type);
|
rb_ary_push(val, type);
|
||||||
rb_ary_push(val, locals);
|
rb_ary_push(val, locals);
|
||||||
rb_ary_push(val, args);
|
rb_ary_push(val, args);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче