rosella/doc/bytecode.txt

238 lines
8.5 KiB
Plaintext

top:
00xxxxxx out in in: expression
01xxxxxx in in in: statement
1xxxxxxx out in in: conditional
expression: up to 64, 1 out, 2 in
00000000 out sub in: unary-expr
00xxxxxx out in in: binary-expr, x > 1
unary-expr: up to 255, 1 out, 1 in
00 invalid / permanently reserved
01 (set! out in)
02 (set! out (unbox in))
03 (set! out (car in))
04 (set! out (cdr in))
08 (set! out (boolean? in)) ; value => bool
09 (set! out (fixnum? in)) ; value => bool
0a (set! out (box? in)) ; value => bool
0b (set! out (pair? in)) ; value => bool
0c (set! out (vector? in)) ; value => bool
0d (set! out (byte-string? in)) ; value => bool
0e (set! out (struct? in)) ; value => bool
0f (set! out (float? in)) ; value => bool
10 (set! out (builtin? in)) ; value => bool
18 (set! out (make-box in)) ; value => box
19 (set! out (make-struct in)) ; metastruct => struct
1a (set! out (make-float in)) ; fixnum => float
1b (set! out (lambda in)) ; template-or-lambda => lambda
20 (set! out (not in)) ; if in == #f then #t else #f
21 (set! out (bit-not in)) ; one's complement / bitwise negation
22 (set! out (fix- in)) ; two's complement / arithmetic negation
23 (set! out (float- in)) ; floating-point negation
28 (set! out (vector-size in))
29 (set! out (byte-string-size in))
2a (set! out (struct-nslots in))
2b (set! out (struct-type in))
; ISO C floating-point
30 (set! out (acos in))
31 (set! out (asin in))
32 (set! out (atan in))
33 (set! out (cos in))
34 (set! out (sin in))
35 (set! out (tan in))
36 (set! out (cosh in))
37 (set! out (sinh in))
38 (set! out (tanh in))
39 (set! out (exp in))
3a (set! out (frexp in)) ; float => (float . fixnum)
3b (set! out (log in)) ; base e
3c (set! out (log10 in))
3d (set! out (modf in)) ; float => (float . float)
3e (set! out (sqrt in))
3f (set! out (ceil in))
40 (set! out (fabs in))
41 (set! out (floor in))
; SVID & X/Open
50 (set! out (erf in))
51 (set! out (erfc in))
; (set! out (gamma in)) ; obsolete
52 (set! out (j0 in))
53 (set! out (j1 in))
54 (set! out (lgamma in)) ; float => (float . fixnum), actually lgamma_r
55 (set! out (y0 in))
56 (set! out (y1 in))
; SVID & XPG 4.2/5
57 (set! out (asinh in))
58 (set! out (acosh in))
59 (set! out (atanh in))
5a (set! out (cbrt in))
5b (set! out (logb in))
; XPG 4.2/5
5c (set! out (expm1 in))
5d (set! out (ilogb in))
5e (set! out (log1p in))
; (set! out (rint in)) ; implies changing rounding mode; use floor or ceil
; C99
70 (set! out (normal? in))
71 (set! out (finite? in))
72 (set! out (subnormal? in))
73 (set! out (infinite? in))
74 (set! out (nan? in))
binary-expr: up to 63 (01..3f), 1 out, 2 in
00 unary-expr
01 (set! out (eq? in1 in2)) ; any values; superset of fix=
02 (set! out (cons in1 in2)) ; car cdr
03 (set! out (make-vector in1 in2)) ; nelem iv, nelem >= 0
04 (set! out (make-byte-string in1 in2)) ; nbytes iv, nbytes >= 0
05 (set! out (vector-ref in1 in2)) ; vector n, 0 <= n < nelem
06 (set! out (byte-string-ref in1 in2)) ; string n, 0 <= n < nbytes
07 (set! out (struct-ref in1 in2)) ; struct n, 0 <= n < nslots
08 (set! out (fix+ in1 in2))
09 (set! out (fix- in1 in2))
0a (set! out (fix* in1 in2))
0b (set! out (fix/ in1 in2))
0c (set! out (fix% in1 in2))
0d (set! out (fix< in1 in2)) ; == (fix> in2 in1)
0e (set! out (fix>= in1 in2)) ; == (fix<= in2 in1)
10 (set! out (bit-and in1 in2))
11 (set! out (bit-or in1 in2))
12 (set! out (bit-xor in1 in2))
14 (set! out (fix<< in1 in2)) ; arithmetic left-shift (2*x) w/ overflow into sign
15 (set! out (fix>> in1 in2)) ; arithmetic right-shift (x/2)
16 (set! out (fix>>> in1 in2)) ; logical right-shift; sign becomes zero (+)
18 (set! out (float+ in1 in2))
19 (set! out (float- in1 in2))
1a (set! out (float* in1 in2))
1b (set! out (float/ in1 in2))
1c (set! out (float= in1 in2))
1d (set! out (float< in1 in2)) ; == (float> in2 in1)
1e (set! out (float>= in1 in2)) ; == (float<= in2 in1)
20 (set! out (atan2 in1 in2)) ; float float
21 (set! out (pow in1 in2)) ; float float
22 (set! out (ldexp in1 in2)) ; float fixnum
23 (set! out (fmod in1 in2)) ; float float
24 (set! out (hypot in1 in2)) ; float float
25 (set! out (jn in1 in2)) ; fixnum float
26 (set! out (yn in1 in2)) ; fixnum float
27 (set! out (nextafter in1 in2)) ; float float
28 (set! out (remainder in1 in2)) ; float float
29 (set! out (scalb in1 in2)) ; float float
30 (set! out (kind-of? in1 in2)) ; value struct-type
conditional: 1 out, 3 in
; 0x80 <= AA <= 0xf7 (f0-f119)
AA (set! AA (if in1 in2 in3)) ; in3 if in1 == #f, in2 otherwise
statement: up to 64 (40..7f), 3 in
; unary statements
40 (goto-end-if in1)
41 (goto-end-unless in1)
; binary statements
50 (set-box! in1 in2) ; box value
51 (set-car! in1 in2) ; pair value
52 (set-cdr! in1 in2) ; pair value
; ternary statements
60 (vector-set! in1 in2 in3) ; vector n value, 0 <= n < nelem
61 (byte-string-set! in1 in2 in3) ; string n value, 0 <= n < nbytes
62 (struct-set! in1 in2 in3) ; struct n value, 0 <= n < nslots
in:
nil (00000000) [g0, always NIL]
gN (00NNNNNN) [global, N < 64]
iN (01NNNNNN) [instance, N < 64]
fN (1NNNNNNN) [frame, N < 120]
-- (11111NNN) [reserved, N < 4]
self (11111100) [current lambda]
argv (11111101) [argument list]
ctx (11111110) [dynamic context]
k (11111111) [continuation]
out:
fN (1NNNNNNN) [0 <= N < 120]
lambda:[
global: vector of immutable values (g1..gN); shared between instances (lambdas)
instance: vector of immutable values (i0..iN); shared between frames (calls)
frame: number of frame variables; initially #<undefined>
code: byte-string containing sequence of 4-byte instruction words
tail-call: in-ref of lambda to tail-call
arguments: in-ref of argument list to pass to tail-call
context: in-ref of dynamic context to pass to tail-call
continuation: in-ref of continuation to pass to tail-call
]
template:[
global: linked
instance: byte-string of in-refs. to parent instance/frame slots
frame: copied verbatim
code: linked
tail-call: copied verbatim
arguments: copied verbatim
context: copied verbatim
continuation: copied verbatim
]
Protocol:
Normal function calls (return to caller, or caller's continuation if tail-call):
Call: Tail-call function with valid 'k' and original 'ctx'.
Return: Tail-call 'k' with #f continuation and context (ignored).
Coroutines (cooperating, interleaved tail-call chains in CPS):
Call: Tail-call function with valid 'k' and original 'ctx'.
Return: Tail-call 'k' with valid 'k' and original 'ctx'.
call-with-current-continuation:
Look up abort handler by prompt tag in incoming 'ctx'.
call provided lambda with lambda parameter as follows:
Tail-call abort handler with same parameters and 'k' & 'ctx' from call/cc.
call-with-composable-continuation:
(define (call-with-composable-continuation proc [prompt-tag (current-prompt-tag)])
(let [(meta-continuation (prompt-tag-meta-continuation prompt-tag))]
(call-with-current-continuation
(lambda (k)
(let [(result (let [(var (lambda values
(call-with-continuation-prompt
(lambda () (apply k values))
prompt-tag)))]
(proc var)))]
((meta-continuation) result))))]))
call-with-continuation-prompt:
(define (call-with-continuation-prompt body-thunk
[prompt-tag (current-prompt-tag)]
[abort-proc (lambda (fn . args)
(apply fn args))])
(let [(meta-continuation (prompt-tag-meta-continuation prompt-tag))
(abort-handler (prompt-tag-abort-handler prompt-tag))]
(call-with-current-continuation
(lambda (k)
(parameterize [(meta-continuation k)
(abort-handler abort-proc)]
(let [(result (body-thunk))]
((meta-continuation) result))))))]))
parameterize:
Call thunk with 'k' and updated context.
New context includes (parameter => value) association.
# vim:set sw=2 expandtab tw=0: