r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[rebcode] Rebcode discussion

Volker
22-Oct-2005
[600x2]
compilers with external assemblers pas such math to the assembler, 
emitting"label - base-address"
in assember we could have an "offset" for that. "offset target-label 
braw-label"
BrianH
22-Oct-2005
[602x2]
Now, it would be possible to have the offset values be referenced 
by label name in your calculations, but that would require some changes 
to the assembler as well, because those label words would also need 
to be replaced with literal offsets because of binding issues. This 
can be done in the same assembler phase as the branch label fixups. 
I actually made a similar change to the assembler to implement that 
HERE directive I proposed.
It would not be difficult to implement this. You wouldn't need to 
change the native code at all - even I could do it from here.
Volker
22-Oct-2005
[604x2]
For now we can do this:
rc: rebcode[v][
 probe v
 sub v 1
 add v v
 braw v
 bra do-1  bra do-2  bra do-3 bra do-4
 label do-1 probe 1.1 probe 1.2 probe 1.3 bra bye
 label do-2 probe 2.1 probe 2.2 bra bye 
 label do-3 probe 3.1 probe 3.2 bra bye
 label do-4 probe 4.1 probe 4.2 bra bye
 label bye 
]
rc 1 rc 2 rc 3 rc 4
BrianH
22-Oct-2005
[606]
All that would be required would be that here directive, probably 
renamed to offset, and some code to perform the label-word-to-offset 
switch.
Volker
22-Oct-2005
[607]
where to look for the assembler-source?
BrianH
22-Oct-2005
[608x3]
probe rebcode*
If I can set aside the time to this weekend, I'll do it myself.
The side effect of this is that you wouldn't be able to use label 
words as variables for other reasons in your rebcode. Is everyone 
OK with this restriction?
Volker
22-Oct-2005
[611]
Maybe we could access the label-table of the last definiton? And 
preparing own tables? could be blocks. then
BrianH
22-Oct-2005
[612]
That won't work. Every rebcode block gets its own label table, which 
is just a block, not a context, and is thrown away after the label 
fixups. These offsets need to be constant - a label table could be 
modified by the calling code. Really, it's easier to do the fixups 
in the fixup phase - that's what it's there for.
Volker
22-Oct-2005
[613]
Have to examine assembler before knowing such things :)
BrianH
22-Oct-2005
[614]
Well I have already :)
Volker
22-Oct-2005
[615]
Thats why i try to get away by just asking you :) But seems i should 
look too.
BrianH
22-Oct-2005
[616x2]
Actually, I pored over every line of code, tested most of the opcodes 
too. I've been taking this rebcode development very seriously, making 
suggestions, finding bugs. Trying to keep from making too much of 
a jerk of myself. I expect that I'll be using and generating a lot 
of rebcode in the future so I want it to be the best that it can 
be.
If anything, the conversations with Gabriele remind me of those we 
had on the list where we reverse-engineered REBOL's context handling, 
back when it wasn't documented.
Volker
22-Oct-2005
[618x3]
I agree. For small byte-crunchers its high-level enough. Maybe  it 
should integrate with parse too, that would be great for dialects 
(replacing chars and such).
and features to write specialized loops, like remove-each .
(indirect set mainly)
BrianH
22-Oct-2005
[621]
It does integrate with parse - have you tried the rewrite rules? 
More advanced stuff can be done with preprocessors like your altsyn.
Volker
22-Oct-2005
[622]
No, at runtime.
BrianH
22-Oct-2005
[623]
apply x parse [rules]
Volker
22-Oct-2005
[624]
in parse
  "<" rebcode[ append out "&lt;" ]
BrianH
22-Oct-2005
[625]
a: rebcode [args] [stuff]
parse dat [here: some-rule (a here)]
Volker
22-Oct-2005
[626x3]
I am talking speed ;) Your example goes thru a rebol-style call. 
a direct call may be much faster
ANd some1 (Gabriele) suggested parse can compete with rebcode in 
its area, its a vm too.
(Gabriele) -> (Gabriele?)
BrianH
22-Oct-2005
[629x2]
(yeah, that's right)
It would be interesting to have a parse opcode, but keep in mind 
that this kind of speedup would likely be implemented in the JIT, 
when we get that. And however fast parse is, its overhead dwarfs 
that of a function call. And remember, using apply would be significantly 
faster than calling a function in the do dialect because there isn't 
any evaluator overhead.
Volker
22-Oct-2005
[631]
Keep in mind that parse can be jitted too :)
BrianH
22-Oct-2005
[632]
No, it really can't. You could in theory build a compiler for a static 
subset of parse, but parse rules can change at runtime, even while 
they are running. They are passed by reference, remember. The reason 
you can JIT rebcode is because every code block must be supplied 
as an immediate literal and so can be considered static. If you do 
runtime modifications of the code blocks, code-as-data stuff or other 
REBOL-like tricks a JIT wouldn't really work, and certainly provide 
any speedup. Keep in mind that rebcode is a compilable subset of 
REBOL - the rest of REBOL mostly isn't compilable.
Volker
22-Oct-2005
[633]
JITs like hotspot can handle such changes.
BrianH
22-Oct-2005
[634]
Hotspot compiles a VM that doesn't allow self-modifying code, just 
replacable code.
Volker
22-Oct-2005
[635x2]
It can switch from native code back to bytecode if the mathod is 
changed. and from bytecode to native once something is compiled.
All you need is tracking references to a parse-rule, and signal such 
references to fall back to interpreter if rule is changed.
BrianH
22-Oct-2005
[637]
When Java bytecode is changed, the entire function is replaced with 
a new function with the changes. It's not changed in place.
Volker
22-Oct-2005
[638x4]
its practically changed in place. Thats magic inside vm, adapting 
stacks etc.
there was an example with a main which contained only a loop. it 
startd with bytecode, after a while it was compiled, and that loop 
was faster. without re-entering that method.
so practically changed in place.
But we would not need that, only a change-check when entering sub-blocks. 
and doing that block by interpreter. then.
BrianH
22-Oct-2005
[642]
The JIT replaces the bytecode function with native code. If the bytecode 
is changed, a new function is generated. The JIT can work on that 
new function too.
Volker
22-Oct-2005
[643x2]
Technically yes. Practically the current method is changed to a faster 
one.
Thats similar to changing a sub-rule at runtime. changing the current 
block would not work with my simpler propoal, but then i consider 
that bad style.
BrianH
22-Oct-2005
[645]
Back to parse, you could in theory statically translate the rules 
to an internal rebcode-like form for a different VM, and then JIT 
that. You wouldn't get as much of a speedup as you think though. 
The existing parse engine spends most of its time actually doing 
the parsing with the native code in the engine - a JIT would only 
speed up the reading of the parse rules, something it doesn't spend 
as much time doing in comparison.
Volker
22-Oct-2005
[646]
Bernd Paysan once wrote a regexp compiling to jitted forth. 10* faster 
than the usual c-interpreter.
BrianH
22-Oct-2005
[647]
Bad style? Certain parse tasks require you to at least swap between 
parse rules on occasion - for instance incremental parsing.
Volker
22-Oct-2005
[648x2]
parse processes bytes. thats what a compiler is good at. now you 
add some interpreter steps, one for any, one for the char. In comparison 
to byte-ops interpreter-steps are heavy.
bad style:
 rule: [ "<" (append rule [ | ">") ]