aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/target/jvm/instruction/bytecode.lux
diff options
context:
space:
mode:
authorEduardo Julian2019-07-08 00:24:20 -0400
committerEduardo Julian2019-07-08 00:24:20 -0400
commita952343569f321006d0183ef7ce250e3f8b996cb (patch)
tree5e360dc6b36cf32bf0566b4c4bbe27954e164ce0 /stdlib/source/lux/target/jvm/instruction/bytecode.lux
parent4db84442d8d1932c330bea1ffdd6ff18447a47de (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.lux490
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)))]))