This patch adds a new opcde for intersegment branches. I named it
"branch_cs". This takes one $I param, which is the entry in the
fixuptable.
Thanks to Jason Gloudon for hinting me, how to handle this beast.
(s thread "[perl #20315] [PATCH] eval - inter code segment branches")

The fixuptable may hold items of different types. I did define item
type "0" holding a segment nr and a branch offset.

Finally to have a non local return from the evaled code, I did split
the runops loop into two parts. The inner part handles resumes after
e.g. the trace opcode, the outer loop handles intersegment jumps,
marked with the resume_flag being 2.

To make this play with JIT too, I had to make the "invoke" opcode a
restartable opcode, which might be to expensive for the normal case.

So we might want to have an additional "invoke_cs" or "eval" opcode,
that might leave the current code segment.

Here is one test with trace, to better see what's goin on:

$ imcc -t t/syn/eval_3.imc
PC=0; OP=73 (set_i_ic); ARGS=(I1=0, 5)
PC=3; OP=87 (set_s_sc); ARGS=(S0=(null), ".sub _e\nif I1 == 6 g")
PC=6; OP=841 (compreg_p_sc); ARGS=(P2, "PIR")
PC=9; OP=838 (compile_p_p_s); ARGS=(P0, P2=Compiler=PMC(0x8183328), \
	S0=".sub _e\nif I1 == 6 g")
PC=13; OP=322 (inc_i); ARGS=(I1=5)
PC=15; OP=837 (invoke)
*** invoking EVAL_1
PC=0; OP=158 (eq_i_ic_ic); ARGS=(I1=6, 6, 5)
PC=5; OP=739 (branch_cs_ic); ARGS=(0)
*** back from EVAL_1
*** Resume at seg 0 ofs 13
PC=13; OP=322 (inc_i); ARGS=(I1=6)
PC=15; OP=837 (invoke)
*** invoking EVAL_1
PC=0; OP=158 (eq_i_ic_ic); ARGS=(I1=7, 6, 5)
PC=4; OP=0 (end)
*** back from EVAL_1
PC=16; OP=21 (print_i); ARGS=(I1=7)
7PC=18; OP=26 (print_sc); ARGS=("\n")

PC=20; OP=0 (end)

Have fun,
leo

Reply via email to