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