diff options
author | Eduardo Julian | 2019-07-08 00:24:20 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-07-08 00:24:20 -0400 |
commit | a952343569f321006d0183ef7ce250e3f8b996cb (patch) | |
tree | 5e360dc6b36cf32bf0566b4c4bbe27954e164ce0 /stdlib/source/lux/target/jvm/instruction/bytecode.lux | |
parent | 4db84442d8d1932c330bea1ffdd6ff18447a47de (diff) |
* Re-named "Instruction" to "Bytecode".
* Re-named "Program" to "Instruction".
Diffstat (limited to 'stdlib/source/lux/target/jvm/instruction/bytecode.lux')
-rw-r--r-- | stdlib/source/lux/target/jvm/instruction/bytecode.lux | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/stdlib/source/lux/target/jvm/instruction/bytecode.lux b/stdlib/source/lux/target/jvm/instruction/bytecode.lux new file mode 100644 index 000000000..bef2628f6 --- /dev/null +++ b/stdlib/source/lux/target/jvm/instruction/bytecode.lux @@ -0,0 +1,490 @@ +(.module: + [lux (#- Code) + [abstract + [monad (#+ do)] + [monoid (#+ Monoid)]] + [control + ["." try (#+ Try)] + ["." exception (#+ exception:)]] + [data + [number (#+ hex)] + ["." binary] + [text + ["%" format (#+ format)]] + [format + [".F" binary (#+ Mutation Specification)]]] + [macro + ["." template]] + [type + abstract]] + ["." // #_ + ["#." resources (#+ Resources)] + ["/" condition (#+ Environment Condition Local) ("#@." monoid)] + ["#." jump (#+ Jump Big-Jump)] + ["/#" // #_ + ["#." index (#+ Index)] + ["#." descriptor (#+ Field Method)] + ["#." constant (#+ Class Reference)] + [encoding + ["#." unsigned (#+ U1 U2 U4)] + ["#." signed (#+ S2 S4)]]]]) + +(type: #export Size Nat) + +(type: #export Bytecode + [Size (-> [Environment Specification] (Try [Environment Specification]))]) + +(def: #export (run bytecode) + (-> Bytecode (Try [Environment Specification])) + (let [[_ bytecode'] bytecode] + (bytecode' [/.start binaryF.no-op]))) + +(def: (bytecode size condition transform) + (-> Size Condition (-> Specification Specification) Bytecode) + [size + (function (_ [environment specification]) + (do try.monad + [environment' (condition environment)] + (wrap [environment' + (transform specification)])))]) + +(type: Code Nat) + +(def: (nullary' code) + (-> Code Mutation) + (function (_ [offset binary]) + [(n/+ 1 offset) + (try.assume + (binary.write/8 offset code binary))])) + +(def: (nullary code [size mutation]) + (-> Code (-> Specification Specification)) + [(n/+ 1 size) + (|>> mutation ((nullary' code)))]) + +(template [<shift> <name> <inputT> <writer> <unwrap>] + [(with-expansions [<private> (template.identifier [<name> "'"])] + (def: (<private> code input0) + (-> Code <inputT> Mutation) + (function (_ [offset binary]) + [(n/+ <shift> offset) + (try.assume + (do try.monad + [_ (binary.write/8 offset code binary)] + (<writer> (n/+ 1 offset) (<unwrap> input0) binary)))])) + + (def: (<name> code input0 [size mutation]) + (-> Code <inputT> (-> Specification Specification)) + [(n/+ <shift> size) + (|>> mutation ((<private> code input0)))]))] + + [2 unary/1 U1 binary.write/8 ///unsigned.nat] + [3 unary/2 U2 binary.write/16 ///unsigned.nat] + [3 jump/2 S2 binary.write/16 ///signed.int] + [5 jump/4 S4 binary.write/32 ///signed.int] + ) + +(def: (binary/11' code input0 input1) + (-> Code U1 U1 Mutation) + (function (_ [offset binary]) + [(n/+ 3 offset) + (try.assume + (do try.monad + [_ (binary.write/8 offset code binary) + _ (binary.write/8 (n/+ 1 offset) (///unsigned.nat input0) binary)] + (binary.write/8 (n/+ 2 offset) (///unsigned.nat input1) binary)))])) + +(def: (binary/11 code input0 input1 [size mutation]) + (-> Code U1 U1 (-> Specification Specification)) + [(n/+ 3 size) + (|>> mutation ((binary/11' code input0 input1)))]) + +(def: (binary/21' code input0 input1) + (-> Code U2 U1 Mutation) + (function (_ [offset binary]) + [(n/+ 4 offset) + (try.assume + (do try.monad + [_ (binary.write/8 offset code binary) + _ (binary.write/16 (n/+ 1 offset) (///unsigned.nat input0) binary)] + (binary.write/8 (n/+ 3 offset) (///unsigned.nat input1) binary)))])) + +(def: (binary/21 code input0 input1 [size mutation]) + (-> Code U2 U1 (-> Specification Specification)) + [(n/+ 4 size) + (|>> mutation ((binary/21' code input0 input1)))]) + +(def: (trinary/211' code input0 input1 input2) + (-> Code U2 U1 U1 Mutation) + (function (_ [offset binary]) + [(n/+ 5 offset) + (try.assume + (do try.monad + [_ (binary.write/8 offset code binary) + _ (binary.write/16 (n/+ 1 offset) (///unsigned.nat input0) binary) + _ (binary.write/8 (n/+ 3 offset) (///unsigned.nat input1) binary)] + (binary.write/8 (n/+ 4 offset) (///unsigned.nat input2) binary)))])) + +(def: (trinary/211 code input0 input1 input2 [size mutation]) + (-> Code U2 U1 U1 (-> Specification Specification)) + [(n/+ 5 size) + (|>> mutation ((trinary/211' code input0 input1 input2)))]) + +(abstract: #export Primitive-Array-Type + {} + + U1 + + (def: code + (-> Primitive-Array-Type U1) + (|>> :representation)) + + (template [<code> <name>] + [(def: #export <name> (|> <code> ///unsigned.u1 :abstraction))] + + [04 t-boolean] + [05 t-char] + [06 t-float] + [07 t-double] + [08 t-byte] + [09 t-short] + [10 t-int] + [11 t-long] + )) + +## https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5 +(with-expansions [<constants> (template [<code> <name> <output-size>] + [[<code> <name> [] [] 0 <output-size> []]] + + ["01" aconst-null 1] + + ["02" iconst-m1 1] + ["03" iconst-0 1] + ["04" iconst-1 1] + ["05" iconst-2 1] + ["06" iconst-3 1] + ["07" iconst-4 1] + ["08" iconst-5 1] + + ["09" lconst-0 2] + ["0A" lconst-1 2] + + ["0B" fconst-0 1] + ["0C" fconst-1 1] + ["0D" fconst-2 1] + + ["0E" dconst-0 2] + ["0F" dconst-1 2]) + <local-loads> (template [<code> <name> <output-size>] + [[<code> <name> [[local Local]] [local] 0 <output-size> [[local]]]] + + ["15" iload 1] + ["16" lload 2] + ["17" fload 1] + ["18" dload 2] + ["19" aload 1]) + <simple-local-loads> (template [<code> <name> <output-size> <local-end>] + [[<code> <name> [] [] 0 <output-size> [[(///unsigned.u1 <local-end>)]]]] + + ["1A" iload-0 1 0] + ["1B" iload-1 1 1] + ["1C" iload-2 1 2] + ["1D" iload-3 1 3] + + ["1E" lload-0 2 1] + ["1F" lload-1 2 2] + ["20" lload-2 2 3] + ["21" lload-3 2 4] + + ["22" fload-0 1 0] + ["23" fload-1 1 1] + ["24" fload-2 1 2] + ["25" fload-3 1 3] + + ["26" dload-0 2 1] + ["27" dload-1 2 2] + ["28" dload-2 2 3] + ["29" dload-3 2 4] + + ["2A" aload-0 1 0] + ["2B" aload-1 1 1] + ["2C" aload-2 1 2] + ["2D" aload-3 1 3]) + <local-stores> (template [<code> <name> <input-size>] + [[<code> <name> [[local Local]] [local] <input-size> 0 [[local]]]] + + ["36" istore 1] + ["37" lstore 2] + ["38" fstore 1] + ["39" dstore 2] + ["3A" astore 1]) + <simple-local-stores> (template [<code> <name> <input-size> <local-end>] + [[<code> <name> [] [] <input-size> 0 [[(///unsigned.u1 <local-end>)]]]] + + ["3B" istore-0 1 0] + ["3C" istore-1 1 1] + ["3D" istore-2 1 2] + ["3E" istore-3 1 3] + + ["3F" lstore-0 2 1] + ["40" lstore-1 2 2] + ["41" lstore-2 2 3] + ["42" lstore-3 2 4] + + ["43" fstore-0 1 0] + ["44" fstore-1 1 1] + ["45" fstore-2 1 2] + ["46" fstore-3 1 3] + + ["47" dstore-0 2 1] + ["48" dstore-1 2 2] + ["49" dstore-2 2 3] + ["4A" dstore-3 2 4] + + ["4B" astore-0 1 0] + ["4C" astore-1 1 1] + ["4D" astore-2 1 2] + ["4E" astore-3 1 3]) + <array-loads> (template [<code> <name> <output-size>] + [[<code> <name> [] [] 2 <output-size> []]] + + ["2E" iaload 1] + ["2F" laload 2] + ["30" faload 1] + ["31" daload 2] + ["32" aaload 1] + ["33" baload 1] + ["34" caload 1] + ["35" saload 1]) + <array-stores> (template [<code> <name> <input-size>] + [[<code> <name> [] [] <input-size> 0 []]] + + ["4f" iastore 3] + ["50" lastore 4] + ["51" fastore 3] + ["52" dastore 4] + ["53" aastore 3] + ["54" bastore 3] + ["55" castore 3] + ["56" sastore 3]) + <arithmetic> (template [<code> <name> <input-size> <output-size>] + [[<code> <name> [] [] <input-size> <output-size> []]] + + ["60" iadd 2 1] + ["64" isub 2 1] + ["68" imul 2 1] + ["6c" idiv 2 1] + ["70" irem 2 1] + ["74" ineg 1 1] + ["78" ishl 2 1] + ["7a" ishr 2 1] + ["7c" iushr 2 1] + ["7e" iand 2 1] + ["80" ior 2 1] + ["82" ixor 2 1] + + ["61" ladd 4 2] + ["65" lsub 4 2] + ["69" lmul 4 2] + ["6D" ldiv 4 2] + ["71" lrem 4 2] + ["75" lneg 2 2] + ["7F" land 4 2] + ["81" lor 4 2] + ["83" lxor 4 2] + + ["62" fadd 2 1] + ["66" fsub 2 1] + ["6A" fmul 2 1] + ["6E" fdiv 2 1] + ["72" frem 2 1] + ["76" fneg 1 1] + + ["63" dadd 4 2] + ["67" dsub 4 2] + ["6B" dmul 4 2] + ["6F" ddiv 4 2] + ["73" drem 4 2] + ["77" dneg 2 2]) + <conversions> (template [<code> <name> <input-size> <output-size>] + [[<code> <name> [] [] <input-size> <output-size> []]] + + ["88" l2i 2 1] + ["89" l2f 2 1] + ["8A" l2d 2 2] + + ["8B" f2i 1 1] + ["8C" f2l 1 2] + ["8D" f2d 1 2] + + ["8E" d2i 2 1] + ["8F" d2l 2 2] + ["90" d2f 2 1] + + ["85" i2l 1 2] + ["86" i2f 1 1] + ["87" i2d 1 2] + ["91" i2b 1 1] + ["92" i2c 1 1] + ["93" i2s 1 1]) + <comparisons> (template [<code> <name> <input-size>] + [[<code> <name> [] [] <input-size> 1 []]] + + ["94" lcmp 4] + + ["95" fcmpl 2] + ["96" fcmpg 2] + + ["97" dcmpl 4] + ["98" dcmpg 4]) + <returns> (template [<code> <name> <input-size>] + [[<code> <name> [] [] <input-size> 0 []]] + + ["AC" ireturn 1] + ["AD" lreturn 2] + ["AE" freturn 1] + ["AF" dreturn 2] + ["B0" areturn 1] + ["B1" return 0] + ) + <jumps> (template [<code> <name> <input-size> <output-size>] + [[<code> <name> [[jump Jump]] [jump] <input-size> <output-size> []]] + + ["99" ifeq 2 0] + ["9A" ifne 2 0] + ["9B" iflt 2 0] + ["9C" ifge 2 0] + ["9D" ifgt 2 0] + ["9E" ifle 2 0] + + ["9F" if-icmpeq 2 0] + ["A0" if-icmpne 2 0] + ["A1" if-icmplt 2 0] + ["A2" if-icmpge 2 0] + ["A3" if-icmpgt 2 0] + ["A4" if-icmple 2 0] + + ["A5" if-acmpeq 2 0] + ["A6" if-acmpne 2 0] + + ["A7" goto 0 0] + ["A8" jsr 0 1] + + ["C6" ifnull 1 0] + ["C7" ifnonnull 1 0]) + <fields> (template [<code> <name> <input-size> <output-size>] + [[<code> <name> [[index (Index (Reference Field))]] [(///index.number index)] <input-size> <output-size> []]] + + ["B2" getstatic/1 0 1] ["B2" getstatic/2 0 2] + ["B3" putstatic/1 1 1] ["B3" putstatic/2 1 2] + ["B4" getfield/1 1 1] ["B4" getfield/2 1 2] + ["B5" putfield/1 2 1] ["B5" putfield/2 2 2])] + (template [<arity> <size> <definitions>] + [(with-expansions [<definitions>' (template.splice <definitions>)] + (template [<code> <name> <bytecode-inputs> <arity-inputs> <consumes> <produces> <locals>] + [(with-expansions [<inputs>' (template.splice <bytecode-inputs>) + <input-types> (template [<input-name> <input-type>] + [<input-type>] + + <inputs>') + <input-names> (template [<input-name> <input-type>] + [<input-name>] + + <inputs>') + <locals>' (template.splice <locals>)] + (def: #export (<name> <input-names>) + (-> <input-types> Bytecode) + (..bytecode + <size> + (`` ($_ /@compose + (/.consumes <consumes>) + (/.produces <produces>) + (~~ (template [<local>] + [(/.has-local <local>)] + + <locals>')))) + (`` (<arity> (hex <code>) (~~ (template.splice <arity-inputs>)))))))] + + <definitions>' + ))] + + [..nullary 1 + [["00" nop [] [] 0 0 []] + <constants> + ["57" pop [] [] 1 0 []] + ["58" pop2 [] [] 2 0 []] + ["59" dup [] [] 1 2 []] + ["5A" dup-x1 [] [] 2 3 []] + ["5B" dup-x2 [] [] 3 4 []] + ["5C" dup2 [] [] 2 4 []] + ["5D" dup2-x1 [] [] 3 5 []] + ["5E" dup2-x2 [] [] 4 6 []] + ["5F" swap [] [] 2 2 []] + <simple-local-loads> + <array-loads> + <simple-local-stores> + <array-stores> + <arithmetic> + ["79" lshl [] [] 3 2 []] + ["7B" lshr [] [] 3 2 []] + ["7D" lushr [] [] 3 2 []] + <conversions> + <comparisons> + <returns> + ["BE" arraylength [] [] 1 1 []] + ["BF" athrow [] [] 1 0 []] + ["C2" monitorenter [] [] 1 0 []] + ["C3" monitorexit [] [] 1 0 []]]] + + [..unary/1 2 + [["10" bipush [[byte U1]] [byte] 0 1 []] + ["12" ldc [[index U1]] [index] 0 1 []] + <local-loads> + <local-stores> + ["A9" ret [[local Local]] [local] 0 0 [[local]]] + ["BC" newarray [[type Primitive-Array-Type]] [(..code type)] 1 1 []]]] + + [..unary/2 3 + [["11" sipush [[short U2]] [short] 0 1 []] + ["13" ldc-w/integer [[index (Index ///constant.Integer)]] [(///index.number index)] 0 1 []] + ["13" ldc-w/float [[index (Index ///constant.Float)]] [(///index.number index)] 0 1 []] + ["13" ldc-w/string [[index (Index ///constant.String)]] [(///index.number index)] 0 1 []] + ["14" ldc2-w/long [[index (Index ///constant.Long)]] [(///index.number index)] 0 2 []] + ["14" ldc2-w/double [[index (Index ///constant.Double)]] [(///index.number index)] 0 2 []] + <fields> + ["BB" new [[index (Index Class)]] [(///index.number index)] 0 1 []] + ["BD" anewarray [[index (Index Class)]] [(///index.number index)] 1 1 []] + ["C0" checkcast [[index (Index Class)]] [(///index.number index)] 1 1 []] + ["C1" instanceof [[index (Index Class)]] [(///index.number index)] 1 1 []] + ["B6" invokevirtual [[index (Index (Reference Method))] [count U1] [output-count U1]] [(///index.number index)] (///unsigned.nat count) (///unsigned.nat output-count) []] + ["B7" invokespecial [[index (Index (Reference Method))] [count U1] [output-count U1]] [(///index.number index)] (///unsigned.nat count) (///unsigned.nat output-count) []] + ["B8" invokestatic [[index (Index (Reference Method))] [count U1] [output-count U1]] [(///index.number index)] (///unsigned.nat count) (///unsigned.nat output-count) []]]] + + [..jump/2 3 + [<jumps>]] + + [..jump/4 5 + [["C8" goto-w [[jump Big-Jump]] [jump] 0 0 []] + ["C9" jsr-w [[jump Big-Jump]] [jump] 0 1 []]]] + + [..binary/11 3 + [["84" iinc [[local Local] [byte U1]] [local byte] 0 0 [[local]]]]] + + [..binary/21 4 + [["C5" multianewarray [[index (Index Class)] [count U1]] [(///index.number index) count] (///unsigned.nat count) 1 []]]] + + [..trinary/211 5 + [["B9" invokeinterface [[index (Index (Reference Method))] [count U1] [output-count U1]] [(///index.number index) count (///unsigned.u1 0)] (///unsigned.nat count) (///unsigned.nat output-count) []]]] + )) + +(structure: #export monoid + (Monoid Bytecode) + + (def: identity ..nop) + + (def: (compose [left-size left] [right-size right]) + [(n/+ left-size right-size) + (function (_ input) + (do try.monad + [temp (left input)] + (right temp)))])) |