Dan Sugalski <[EMAIL PROTECTED]> wrote:
> At 10:10 AM +0200 10/25/03, Leopold Toetsch wrote:

> Oh, it certainly can be an absolute address, if you know what the
> address is when you're generating the code.

Did you ever try, what the assembler considers needing fixup: a
_non_local label. I don't know, if that's the problem. But local labels
(w/o underscores) are considered to be fixed up immediately, while global
labels are fixed up later.

> 2drop, for example, drops the two words on the top of the stack and
> is really just "drop drop", and can be build from existing words.
> (drop, in this case) The generated code for the word *should* look
> like:

>     jsr .drop
>     jsr .drop
>     ret

Yep, that's right. It would be slightly simpler, if there were one or
two tests in the forth directory, anyway, after sneaking into "info
gforth", I figured out that ": bla 2 + ; 1 bla ." would compile the
"bla" opcode and print 3 :)

I didn't look at that immediate thing yet, but it would be fine if you
could extract some PASM lines, that exhibit this inconsistency. But IIRC
gets the integer argument fixed up, while the constant isn't. This is
due to the fact, that opcodes don't have any information, which argument
is a branch offset or address. There is only one assumption, that, when
there is a branch, the last argument of one opcode is the branch offset.

So during label fixup there are some hardwired "is this a set_addr" or
such, and then when yes, fixup the second argument.

We should really have a syntax in core.ops that clearly states, here is
a label or such.

> I'm OK both with different bytecode
> segments sharing a constant table, as well as mandating that new
> segments may, if given the appropriate flags at creation time, can
> share the existing constant segment.

That's the way to go. The compile stuff was a joke in the first place to
get Jerome's bfc compiler running. The first implementation just used the
(one and only) constant table and generated a new bytecode segment. But
generally, an eval()ed piece of code could produce constants en mass,
never going away and exhausting memory finally.

So the plans (tm) are, to make such (compiled) code segments PMCs, which
can go out of scope like any other closure or such, and that get cleaned
up by DOD.

Coming back to your forth case. You didn't have constants in the
compiled code, so your hacks are working. But for general usage we need
some flags, what the compiled code should share with the calling
bytecode. This is not only the constant table but concerning all
segments like debug (currently line numbers only).

The general scheme looks like a tree:

  DIRECTROY
     BYTECODE
     CONSTANTS
     DEBUG
     ...
     EVAL_1_DIR
        EVAL_1_BYTECODE
        ...

A packfile directory can hold arbitrary other segments, which can be
directories again ad infinitum. We need some syntax to assign constant
or other segments to the parent or a new dir segment. Bytecode always
has to be in a new segment, we can't expand mmap()ed code nor JIT code.

This also means, that there will be some restructuring of
interpreter->code (and ->constants), the former is now the packfile, and
will be a directory segment finally, the shortcuts like constants or jit_code
will probably die, they make a mess out of code segment switching ...

leo

Reply via email to