Re: [perl #20315] [PATCH] eval - inter code segment branches
Jason Gloudon wrote: On Tue, Jan 21, 2003 at 08:21:42PM +0100, Leopold Toetsch wrote: # #!/usr/bin/perl -w # my $i= 5; # LAB: #$i++; #eval(goto LAB if ($i==6)); Ok. Having inter_cs call DO_OP just seems more involved than it has to be. Yep. How about a single self-contained inter-segment jump instruction. Since the compiler knows when a branch is non-local it can always break a non-local conditional branch into a conditional local branch to a non-local branch instruction. This would mean to rewrite the branch target to point to a location after the end of the current sub (or end of program). if i, non_local1 would become if i, taken1 ... end/ret # whatever taken1: inter_cs_jump non_local1 ... Yep. Seems really much simpler. I'll try this approach. Thanks for your input, leo
Re: [perl #20315] [PATCH] eval - inter code segment branches
On Tue, Jan 21, 2003 at 12:08:29AM +0100, Leopold Toetsch wrote: Here is a proposal for inter code segment jumps: The assembler (imcc) can recognize when a branch ins goes to a different code segment. For such a branch, imcc generates this opcode seqence: inter_cs if i, ic # or whatever Why do we need branches to go to different code segments ? I think the expectation has been that control transfers between segments would have their own op, because separate code segments would generally coincide with subs, closures or at least blocks, that have specific entry points. Maybe Dan could give us a hint about the closure/block/byte code segment relationship. -- Jason
Re: [perl #20315] [PATCH] eval - inter code segment branches
Jason Gloudon wrote: On Tue, Jan 21, 2003 at 12:08:29AM +0100, Leopold Toetsch wrote: Here is a proposal for inter code segment jumps: The assembler (imcc) can recognize when a branch ins goes to a different code segment. For such a branch, imcc generates this opcode seqence: inter_cs if i, ic # or whatever Why do we need branches to go to different code segments ? Because of this nasty piece of little code: t/syn/eval_3.imc: # #!/usr/bin/perl -w # my $i= 5; # LAB: #$i++; #eval(goto LAB if ($i==6)); #print $i\n; # # 7 # .sub _test I1 = 5 $S0 = .sub _e\nif I1 == 6 goto LAB\nend\n.end\n compreg P2, PIR compile P0, P2, $S0 LAB: inc I1 invoke print I1 print \n end .end ... I think the expectation has been that control transfers between segments would have their own op, because separate code segments would generally coincide with subs, closures or at least blocks, that have specific entry points. The problem is, that the invoke calls a different code segment, which eventually branches back. Parsing the eval code into the same code segment in not possible, we can't expand code segments, or let's say not easily, except (if even possible) with invalidating prederef and JIT code, and restarting. This is IMHO too expensive to go that road. The proposed inter_cs op is such a special op, but suitable for all branches. E.g. inter_cs ; bsr _somewhere Maybe Dan could give us a hint about the closure/block/byte code segment relationship. I just can tell you from imcc's POV. Everything compiled in one sequence (e.g. all subs of all files) could be one code segment. As soon as you start running the code, and you want to compile again, produced bytecode has to go into a different code segment. Of course, it could be more fine grained, but not less. leo
Re: [perl #20315] [PATCH] eval - inter code segment branches
On Tue, Jan 21, 2003 at 08:21:42PM +0100, Leopold Toetsch wrote: For such a branch, imcc generates this opcode seqence: inter_cs if i, ic # or whatever Why do we need branches to go to different code segments ? Because of this nasty piece of little code: t/syn/eval_3.imc: # #!/usr/bin/perl -w # my $i= 5; # LAB: #$i++; #eval(goto LAB if ($i==6)); Ok. Having inter_cs call DO_OP just seems more involved than it has to be. How about a single self-contained inter-segment jump instruction. Since the compiler knows when a branch is non-local it can always break a non-local conditional branch into a conditional local branch to a non-local branch instruction. For example if i, nonlocal ... not taken can be expressed as if i, TAKEN ... not taken ... TAKEN: inter_jump nonlocal -- Jason
Re: [perl #20315] [PATCH] eval - inter code segment branches
Leopold Toetsch wrote: I have it ready. It's based on the packfile patch #18056 by Juergen Boemmels. On top of this patch, it was quite easy to implement multiple code segments. And yet another f'up me. Here is a proposal for inter code segment jumps: The assembler (imcc) can recognize when a branch ins goes to a different code segment. For such a branch, imcc generates this opcode seqence: inter_cs if i, ic # or whatever The branch location ic is the index[1] into the fixuptable, which contains codesegment/offset pairs. The inter_cs instruction looks like: opcode_t *cur = cur_opcode; /* remember current */ // = CUR_OPCODE opcode_t *pc; DO_OP(pc, interpreter); /* pc is new pc now */ if (pc_is_outof_bounds) { /* branch taken */ index = (pc-code_start)/(sizeof opcode_t) ~0x8000; interp-resume_code_seg = fixup_table[index].code_seg; interp-resume_offset = fixup_table[index].offs; //= restart OFFSET(x) return 0; /* do a resume in new cs */ } cur_opcode = pc; /* branch not taken */ // = goto ADDRESS(pc); [1] the branch offsets are with the hight bit set, to allow recognition of out_of_bounds. Some help to translate this to OpsFile macros as well as of course always comments are welcome, leo