Re: [perl #20315] [PATCH] eval - inter code segment branches

2003-01-22 Thread Leopold Toetsch
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

2003-01-21 Thread Jason Gloudon
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

2003-01-21 Thread Leopold Toetsch
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

2003-01-21 Thread Jason Gloudon
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

2003-01-20 Thread Leopold Toetsch
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