yarv-diff:341
From: ko1 atdot.net
Date: 4 Jul 2006 09:27:25 -0000
Subject: [yarv-diff:341] r507 - in trunk: . yarvtest
Author: ko1
Date: 2006-07-04 18:27:24 +0900 (Tue, 04 Jul 2006)
New Revision: 507
Modified:
trunk/
trunk/ChangeLog
trunk/compile.c
trunk/disasm.c
trunk/eval.c
trunk/insns.def
trunk/vm.c
trunk/yarvcore.c
trunk/yarvcore.h
trunk/yarvtest/yarvtest.rb
Log:
r787@lermite: ko1 | 2006-07-04 18:26:06 +0900
* compile.c : fix some bugs about load iseq data
* disasm.c : ditto (store)
* eval.c (rb_f_local_variables) : fix bugs
* insns.def : fix otp_ltlt condition bug
* vm.c : ditto
* yarvcore.c : rename some functions
* yarvtest/yarvtest.rb : add iseq load/store tests
(to enable this, remove comment)
Property changes on: trunk
___________________________________________________________________
Name: svk:merge
- 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:786
+ 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:787
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/ChangeLog 2006-07-04 09:27:24 UTC (rev 507)
@@ -3,6 +3,25 @@
# YARV ChangeLog
# from Mon, 03 May 2004 01:24:19 +0900
#
+
+2006-07-04(Tue) 18:17:15 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * compile.c : fix some bugs about load iseq data
+
+ * disasm.c : ditto (store)
+
+ * eval.c (rb_f_local_variables) : fix bugs
+
+ * insns.def : fix otp_ltlt condition bug
+
+ * vm.c : ditto
+
+ * yarvcore.c : rename some functions
+
+ * yarvtest/yarvtest.rb : add iseq load/store tests
+ (to enable this, remove comment)
+
+
2006-07-03(Mon) 01:54:23 +0900 Koichi Sasada <ko1 atdot.net>
* eval_thread.c : add parameter "th" to thread_set_raised
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/compile.c 2006-07-04 09:27:24 UTC (rev 507)
@@ -1289,22 +1289,22 @@
}
case TS_CDHASH:{
/*
- * [[obj, label], ...]
+ * [obj, label, ...]
*/
int i;
- VALUE lits = ((NODE *) operands[j])->u1.value;
+ VALUE lits = operands[j];
VALUE map = rb_hash_new();
- for (i = 0; i < RARRAY(lits)->len; i++) {
- VALUE pair = RARRAY(lits)->ptr[i];
- lobj = (LABEL *)(RARRAY(pair)->ptr[1] & ~1);
-
+ for (i=0; i < RARRAY(lits)->len; i+=2) {
+ VALUE obj = rb_ary_entry(lits, i);
+ VALUE lv = rb_ary_entry(lits, i+1);
+ lobj = (LABEL *)(lv & ~1);
+
if (lobj->set != Qtrue) {
rb_bug("unknown label");
}
- rb_hash_aset(map, RARRAY(pair)->ptr[0],
- INT2FIX(lobj->position -
- (pos + len)));
+ rb_hash_aset(map, obj,
+ INT2FIX(lobj->position - (pos+len)));
}
generated_iseq[pos + 1 + j] = map;
iseq_add_mark_object(iseq, map);
@@ -1423,18 +1423,22 @@
entry->end = label_get_position((LABEL *)(ptr[2] & ~1));
entry->iseq = ptr[3];
+ /* register iseq as mark object */
if (entry->iseq != 0) {
iseq_add_mark_object(iseq, entry->iseq);
}
+ /* stack depth */
if (ptr[4]) {
LABEL *lobj = (LABEL *)(ptr[4] & ~1);
entry->cont = label_get_position(lobj);
entry->sp = label_get_sp(lobj);
+
+ /* TODO: Dirty Hack! Fix me */
if (entry->type == CATCH_TYPE_RESCUE ||
- entry->type == CATCH_TYPE_BREAK || (((ptr[0] & 0x10000) == 0)
- && entry->type ==
- CATCH_TYPE_NEXT)) {
+ entry->type == CATCH_TYPE_BREAK ||
+ (((ptr[0] & 0x10000) == 0)
+ && entry->type == CATCH_TYPE_NEXT)) {
entry->sp--;
}
}
@@ -2581,8 +2585,8 @@
if ((lit = case_when_optimizable_literal(val))
&& special_literals) {
- rb_ary_push(special_literals,
- rb_ary_new3(2, lit, (VALUE)(l1) | 1));
+ rb_ary_push(special_literals, lit);
+ rb_ary_push(special_literals, (VALUE)(l1) | 1);
}
else {
special_literals = Qfalse;
@@ -2637,7 +2641,6 @@
}
if (special_literals) {
- special_literals = (VALUE)NEW_WHILE(special_literals, 0, 0);
ADD_INSN(ret, nd_line(tempnode), dup);
ADD_INSN2(ret, nd_line(tempnode), opt_case_dispatch,
special_literals, elselabel);
@@ -4612,9 +4615,8 @@
}
static int
-insn_simpledata2iseq_exception(yarv_iseq_t *iseq,
- struct st_table *labels_table,
- VALUE exception)
+iseq_build_exception(yarv_iseq_t *iseq, struct st_table *labels_table,
+ VALUE exception)
{
int i;
VALUE tmp;
@@ -4630,7 +4632,7 @@
eiseqval = 0;
}
else {
- eiseqval = iseq_load_simpledata(0, ptr[1], iseq->self);
+ eiseqval = iseq_load(0, ptr[1], iseq->self);
}
lstart = register_label(iseq, labels_table, ptr[2]);
@@ -4647,21 +4649,18 @@
struct st_table *insn_make_insn_table(void);
static int
-insn_simpledata2iseq_body(yarv_iseq_t *iseq, LINK_ANCHOR *anchor,
- VALUE body, VALUE line, VALUE exception)
+iseq_build_body(yarv_iseq_t *iseq, LINK_ANCHOR *anchor,
+ VALUE body, VALUE line, struct st_table *labels_table)
{
/* TODO: body should be freezed */
VALUE *ptr = RARRAY(body)->ptr;
int len = RARRAY(body)->len;
int i, j;
- struct st_table *labels_table = st_init_numtable();
/*
* index -> LABEL *label
*/
static struct st_table *insn_table;
- insn_simpledata2iseq_exception(iseq, labels_table, exception);
-
if (insn_table == 0) {
insn_table = insn_make_insn_table();
}
@@ -4714,7 +4713,7 @@
if (op != Qnil) {
if (TYPE(op) == T_ARRAY) {
argv[j] =
- iseq_load_simpledata(0, op, iseq->self);
+ iseq_load(0, op, iseq->self);
}
else if (CLASS_OF(op) == cYarvISeq) {
yarv_iseq_t *iseq;
@@ -4724,6 +4723,7 @@
/* TODO: exception */
rb_bug("not an iseq");
}
+ iseq_add_mark_object(iseq, argv[j]);
}
else {
argv[j] = 0;
@@ -4741,7 +4741,17 @@
argv[j] = op;
break;
case TS_CDHASH:
-
+ {
+ int i;
+ for (i=0; i<RARRAY(op)->len; i+=2) {
+ VALUE sym = rb_ary_entry(op, i+1);
+ LABEL *label =
+ register_label(iseq, labels_table, sym);
+ rb_ary_store(op, i+1, (VALUE)label | 1);
+ }
+ argv[j] = op;
+ }
+ break;
default:
rb_bug("unknown operand: %c", insn_op_type(insn_id, j));
}
@@ -4762,12 +4772,14 @@
}
VALUE
-iseq_simpledata2iseq(yarv_iseq_t *iseq, VALUE line,
- VALUE args, VALUE vars, VALUE exception, VALUE body)
+iseq_build_from_ary(yarv_iseq_t *iseq, VALUE line,
+ VALUE locals, VALUE args, VALUE exception, VALUE body)
{
int i;
int opt = 0;
ID *tbl;
+ struct st_table *labels_table = st_init_numtable();
+
DECL_ANCHOR(anchor);
if (iseq->type == ISEQ_TYPE_METHOD ||
@@ -4776,22 +4788,55 @@
opt = 1;
}
- iseq->local_size = opt + RARRAY(args)->len + RARRAY(vars)->len;
+ iseq->local_size = opt + RARRAY(locals)->len;
iseq->local_tbl = (ID *)ALLOC_N(ID *, iseq->local_size);
tbl = iseq->local_tbl + opt;
+ for (i=0; i<RARRAY(locals)->len; i++) {
+ tbl[i] = SYM2ID(RARRAY(locals)->ptr[i]);
+ }
+
/* args */
- for (i=0; i<RARRAY(args)->len; i++) {
- *tbl++ = SYM2ID(RARRAY(args)->ptr[i]);
+ if (FIXNUM_P(args)) {
+ iseq->argc = FIX2INT(args);
+ iseq->arg_simple = 1;
}
- iseq->argc = i;
+ else {
+ /*
+ * [argc, # argc
+ * opts, # opts
+ * [label1, label2, ...] # opt labels
+ * rest_iex,
+ * block_idx,
+ * ]
+ * or
+ * argc (Fixnum) # arg_simple
+ */
+ int i = 0;
+ VALUE argc = rb_ary_entry(args, i++);
+ VALUE arg_opts = rb_ary_entry(args, i++);
+ VALUE arg_opt_labels = rb_ary_entry(args, i++);
+ VALUE arg_rest = rb_ary_entry(args, i++);
+ VALUE arg_block = rb_ary_entry(args, i++);
- /* vars */
- for (i=0; i<RARRAY(vars)->len; i++) {
- *tbl++ = SYM2ID(RARRAY(vars)->ptr[i]);
+ iseq->argc = FIX2INT(argc);
+ iseq->arg_opts = FIX2INT(arg_opts);
+ iseq->arg_rest = FIX2INT(arg_rest);
+ iseq->arg_block = FIX2INT(arg_block);
+
+ iseq->arg_opt_tbl = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts);
+
+ for (i=0; i<RARRAY(arg_opt_labels)->len; i++) {
+ iseq->arg_opt_tbl[i] =
+ register_label(iseq, labels_table,
+ rb_ary_entry(arg_opt_labels, i));
+ }
}
+ /* exception */
+ iseq_build_exception(iseq, labels_table, exception);
+
/* body */
- insn_simpledata2iseq_body(iseq, anchor, body, line, exception);
+ iseq_build_body(iseq, anchor, body, line, labels_table);
return iseq->self;
}
Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/disasm.c 2006-07-04 09:27:24 UTC (rev 507)
@@ -74,6 +74,7 @@
case TS_LINDEX:
{
yarv_iseq_t *ip = iseq->local_iseq;
+
ret =
rb_str_new2(
rb_id2name(ip->local_tbl[ip->local_size - op + 1]));
@@ -578,8 +579,9 @@
static VALUE
register_label(struct st_table *table, int idx)
{
- VALUE sym;
+ VALUE sym, tsym;
char buff[0x20];
+
snprintf(buff, 0x20, "label_%u", idx);
sym = ID2SYM(rb_intern(buff));
st_insert(table, idx, sym);
@@ -603,6 +605,14 @@
return ID2SYM(id);
}
+static int
+cdhash_each(VALUE key, VALUE value, VALUE ary)
+{
+ rb_ary_push(ary, key);
+ rb_ary_push(ary, value);
+ return ST_CONTINUE;
+}
+
VALUE
iseq_data_to_ary(yarv_iseq_t *iseq)
{
@@ -611,8 +621,8 @@
VALUE val = rb_ary_new();
VALUE type; /* Symbol */
- VALUE args = rb_ary_new(); /* [:arg1, ...] */
- VALUE vars = rb_ary_new(); /* [:var1, ...] */
+ VALUE locals = rb_ary_new();
+ VALUE args = rb_ary_new();
VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
VALUE nbody;
VALUE line = rb_ary_new();
@@ -660,25 +670,62 @@
iseq->type == ISEQ_TYPE_CLASS) {
opt = 1;
}
+
+ /* locals */
+ for (i=opt; i<iseq->local_size; i++) {
+ ID lid = iseq->local_tbl[i];
+ if (lid) {
+ rb_ary_push(locals, ID2SYM(lid));
+ }
+ else {
+ rb_ary_push(locals, ID2SYM(rb_intern("#arg_rest")));
+ }
+ }
+
/* args */
- for (i=0; i<iseq->argc; i++) {
- rb_ary_push(args, ID2SYM(iseq->local_tbl[i+opt]));
+ {
+ /*
+ * [argc, # argc
+ * [label1, label2, ...] # opts
+ * rest_iex,
+ * block_idx,
+ * ]
+ * or
+ * argc (Fixnum) # arg_simple
+ */
+ VALUE arg_opt_labels = rb_ary_new();
+ int j;
+
+ for (j=0; j<iseq->arg_opts; j++) {
+ rb_ary_push(arg_opt_labels,
+ register_label(labels_table, iseq->arg_opt_tbl[j]));
+ }
+
+ /* commit */
+ if (iseq->arg_simple) {
+ args = INT2FIX(iseq->argc);
+ }
+ else {
+ 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, INT2FIX(iseq->arg_rest));
+ rb_ary_push(args, INT2FIX(iseq->arg_block));
+ }
}
- /* vars */
- for(; i<iseq->local_size - opt; i++) {
- rb_ary_push(vars, ID2SYM(iseq->local_tbl[i+opt]));
- }
-
+
/* body */
for (seq = iseq->iseq; seq < iseq->iseq + iseq->size; ) {
VALUE ary = rb_ary_new();
VALUE insn = *seq++;
- int j;
+ int j, len = insn_len(insn);
+ VALUE *nseq = seq + len - 1;
+
rb_ary_push(ary, insn_syms[insn]);
- for (j=0; j<insn_len(insn)-1; j++, seq++) {
+ for (j=0; j<len-1; j++, seq++) {
switch (insn_op_type(insn, j)) {
case TS_OFFSET: {
- unsigned int idx = seq - iseq->iseq + *seq + 1;
+ unsigned int idx = nseq - iseq->iseq + *seq;
rb_ary_push(ary, register_label(labels_table, idx));
break;
}
@@ -715,6 +762,23 @@
rb_ary_push(ary, ID2SYM(*seq));
break;
case TS_CDHASH:
+ {
+ VALUE hash = *seq;
+ VALUE val = rb_ary_new();
+ int i;
+
+ rb_hash_foreach(hash, cdhash_each, val);
+
+ for (i=0; i<RARRAY(val)->len; i+=2) {
+ VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
+ unsigned int idx = nseq - iseq->iseq + pos;
+
+ rb_ary_store(val, i+1,
+ register_label(labels_table, idx));
+ }
+ rb_ary_push(ary, val);
+ }
+ break;
default:
rb_bug("unknown operand: %c", insn_op_type(insn, j));
}
@@ -743,24 +807,25 @@
rb_ary_push(ary, INT2FIX(entry->sp));
rb_ary_push(exception, ary);
}
-
+
/* make body with labels */
body = rb_ary_new();
for (i=0, pos=0; i<RARRAY(nbody)->len; i++) {
VALUE ary = RARRAY(nbody)->ptr[i];
VALUE label;
-
+
if (st_lookup(labels_table, pos, &label)) {
rb_ary_push(body, label);
}
+
rb_ary_push(body, ary);
pos += RARRAY(ary)->len;
}
st_free_table(labels_table);
- /* build */
+ /* build array */
/* [magic, major_version, minor_version, format_type, misc,
* name, filename, line,
@@ -775,8 +840,8 @@
rb_ary_push(val, iseq->file_name);
rb_ary_push(val, line);
rb_ary_push(val, type);
+ rb_ary_push(val, locals);
rb_ary_push(val, args);
- rb_ary_push(val, vars);
rb_ary_push(val, exception);
rb_ary_push(val, body);
return val;
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/eval.c 2006-07-04 09:27:24 UTC (rev 507)
@@ -2761,8 +2761,7 @@
* local_variables #=> ["fred", "i"]
*/
-int
- th_collect_local_variables_in_heap(yarv_thread_t *th, VALUE *dfp, VALUE ary);
+int th_collect_local_variables_in_heap(yarv_thread_t *th, VALUE *dfp, VALUE ary);
static VALUE
rb_f_local_variables(void)
@@ -2780,8 +2779,10 @@
start = 1;
}
for (i = start; i < cfp->iseq->local_size; i++) {
- rb_ary_push(ary,
- rb_str_new2(rb_id2name(cfp->iseq->local_tbl[i])));
+ ID lid = cfp->iseq->local_tbl[i];
+ if (lid) {
+ rb_ary_push(ary, rb_str_new2(rb_id2name(lid)));
+ }
}
}
if (cfp->lfp != cfp->dfp) {
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/insns.def 2006-07-04 09:27:24 UTC (rev 507)
@@ -2060,10 +2060,11 @@
{
if (0) {
}
- if (!SPECIAL_CONST_P(recv) && SPECIAL_CONST_P(obj)) {
- if (HEAP_CLASS_OF(recv) == rb_cString &&
- HEAP_CLASS_OF(obj) == rb_cString &&
- BASIC_OP_UNREDEFINED(STRING_LTLT)) {
+ if (!SPECIAL_CONST_P(recv)) {
+ if (0) {
+ }
+ else if (HEAP_CLASS_OF(recv) == rb_cString &&
+ BASIC_OP_UNREDEFINED(STRING_LTLT)) {
val = rb_str_concat(recv, obj);
}
else if (HEAP_CLASS_OF(recv) == rb_cArray &&
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/vm.c 2006-07-04 09:27:24 UTC (rev 507)
@@ -322,8 +322,10 @@
return 0;
}
for (i = 0; i < env->block.iseq->local_size; i++) {
- rb_ary_push(ary,
- rb_str_new2(rb_id2name(env->block.iseq->local_tbl[i])));
+ ID lid = env->block.iseq->local_tbl[i];
+ if (lid) {
+ rb_ary_push(ary, rb_str_new2(rb_id2name(lid)));
+ }
}
if (env->prev_envval) {
GetEnvVal(env->prev_envval, env);
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/yarvcore.c 2006-07-04 09:27:24 UTC (rev 507)
@@ -56,6 +56,7 @@
ID idEnd;
ID idBitblt;
ID idAnswer;
+ID idSvarPlaceholder;
unsigned long yarvGlobalStateVersion = 1;
@@ -465,13 +466,13 @@
}
VALUE
-iseq_load_simpledata(VALUE self, VALUE data, VALUE parent)
+iseq_load(VALUE self, VALUE data, VALUE parent)
{
VALUE iseqval = iseq_alloc(cYarvISeq);
VALUE magic, version1, version2, format_type, misc;
VALUE name, filename, line;
- VALUE type, body, args, vars, exception;
+ VALUE type, body, locals, args, exception;
VALUE iseq_type;
struct st_table *type_map = 0;
@@ -479,7 +480,7 @@
/* [magic, major_version, minor_version, format_type, misc,
* name, filename, line,
- * type, args, vars, exception_table, body]
+ * type, locals, args, exception_table, body]
*/
magic = rb_ary_entry(data, 0);
@@ -495,8 +496,8 @@
line = rb_ary_entry(data, 7);
type = rb_ary_entry(data, 8);
- args = rb_ary_entry(data, 9);
- vars = rb_ary_entry(data, 10);
+ locals = rb_ary_entry(data, 9);
+ args = rb_ary_entry(data, 10);
exception = rb_ary_entry(data, 11);
body = rb_ary_entry(data, 12);
@@ -528,16 +529,16 @@
name, filename,
parent, iseq_type, 0);
- iseq_simpledata2iseq(iseq, line, args, vars, exception, body);
+ iseq_build_from_ary(iseq, line, locals, args, exception, body);
cleanup_iseq_build(iseq);
return iseqval;
}
static VALUE
-iseq_m_load_simpledata(VALUE self, VALUE data)
+iseq_s_load(VALUE self, VALUE data)
{
- return iseq_load_simpledata(self, data, 0);
+ return iseq_load(self, data, 0);
}
static VALUE
@@ -1218,8 +1219,8 @@
rb_define_method(cYarvISeq, "disasm", iseq_disasm, 0);
rb_define_method(cYarvISeq, "to_a", iseq_to_a, 0);
rb_define_method(cYarvISeq, "eval", iseq_eval, 0);
- rb_define_singleton_method(cYarvISeq, "load_simpledata",
- iseq_m_load_simpledata, 1);
+ rb_define_singleton_method(cYarvISeq, "load",
+ iseq_s_load, 1);
/* declare YARVCore::VM */
cYarvVM = rb_define_class_under(mYarvCore, "VM", rb_cObject);
@@ -1310,6 +1311,7 @@
idBitblt = rb_intern("bitblt");
idAnswer = rb_intern("the_answer_to_life_the_universe_and_everything");
+ idSvarPlaceholder = rb_intern("#svar");
#if TEST_AOT_COMPILE
Init_compiled();
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/yarvcore.h 2006-07-04 09:27:24 UTC (rev 507)
@@ -135,6 +135,7 @@
extern ID idEnd;
extern ID idBitblt;
extern ID idAnswer;
+extern ID idSvarPlaceholder;
extern unsigned long yarvGlobalStateVersion;
Modified: trunk/yarvtest/yarvtest.rb
===================================================================
--- trunk/yarvtest/yarvtest.rb 2006-07-04 09:26:44 UTC (rev 506)
+++ trunk/yarvtest/yarvtest.rb 2006-07-04 09:27:24 UTC (rev 507)
@@ -74,7 +74,18 @@
tmpf.close(true)
result
end
-
+
+ def dump_and_exec exec_file, str
+ asmstr = <<-EOASMSTR
+ iseq = YARVCore::parse(<<-'EOS__', 'eval', 1)
+ #{str}
+ EOS__
+ p YARVCore::InstructionSequence.load(iseq.to_a).eval
+ EOASMSTR
+
+ exec(exec_file, asmstr)
+ end
+
def exec_ exec_file, program
exec_file.tr!('\\', '/')
r = ''
@@ -95,14 +106,14 @@
end
def ae str
- str = %{
+ evalstr = %{
p eval(%q{
#{str}
})
}
- ruby = exec(@ruby, str)
- yarv = exec(@yarv, str)
+ ruby = exec(@ruby, evalstr)
+ yarv = exec(@yarv, evalstr)
if $DEBUG #|| true
puts "yarv (#@yarv): #{yarv}"
@@ -110,6 +121,12 @@
end
assert_equal(ruby.gsub(/\r/, ''), yarv.gsub(/\r/, ''))
+
+ # store/load test
+ if false || true
+ yarvasm = dump_and_exec(@yarv, str)
+ assert_equal(ruby.gsub(/\r/, ''), yarvasm.gsub(/\r/, ''))
+ end
end
def test_
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml