(;module: [lux #- char] (lux (control monad ["p" parser]) (data text/format (coll [list "L/" Functor])) [host #+ jvm-import do-to] [macro] (macro [code] ["s" syntax #+ syntax:])) ["$" ..] (.. ["$t" type])) ## [Host] (jvm-import #long java.lang.Object) (jvm-import #long java.lang.String) (syntax: (declare [codes (p;many s;local-symbol)]) (|> codes (L/map (function [code] (` ((~' #static) (~ (code;local-symbol code)) (~' int))))) wrap)) (with-expansions [ (declare T_BOOLEAN T_CHAR T_FLOAT T_DOUBLE T_BYTE T_SHORT T_INT T_LONG) (declare DUP DUP2_X1 POP POP2 SWAP) (declare IF_ICMPEQ IF_ACMPEQ IFNULL IFLT IFLE IFGT IFGE GOTO)] (jvm-import org.objectweb.asm.Opcodes (#static CHECKCAST int) (#static NEW int) (#static NEWARRAY int) (#static ANEWARRAY int) (#static ACONST_NULL int) (#static ILOAD int) (#static LLOAD int) (#static ALOAD int) (#static IADD int) (#static LAND int) (#static LOR int) (#static LXOR int) (#static LSHL int) (#static LSHR int) (#static LUSHR int) (#static LADD int) (#static LSUB int) (#static LMUL int) (#static LDIV int) (#static LREM int) (#static LCMP int) (#static DADD int) (#static DSUB int) (#static DMUL int) (#static DDIV int) (#static DREM int) (#static DCMPG int) (#static I2L int) (#static L2I int) (#static L2D int) (#static D2L int) (#static I2C int) (#static AALOAD int) (#static AASTORE int) (#static ARRAYLENGTH int) (#static GETSTATIC int) (#static PUTSTATIC int) (#static GETFIELD int) (#static PUTFIELD int) (#static INVOKESTATIC int) (#static INVOKESPECIAL int) (#static INVOKEVIRTUAL int) (#static ATHROW int) (#static RETURN int) (#static IRETURN int) (#static LRETURN int) (#static ARETURN int) )) (jvm-import org.objectweb.asm.FieldVisitor (visitEnd [] void)) (jvm-import org.objectweb.asm.Label (new [])) (jvm-import org.objectweb.asm.MethodVisitor (visitCode [] void) (visitMaxs [int int] void) (visitEnd [] void) (visitInsn [int] void) (visitLdcInsn [Object] void) (visitFieldInsn [int String String String] void) (visitTypeInsn [int String] void) (visitVarInsn [int int] void) (visitIntInsn [int int] void) (visitMethodInsn [int String String String boolean] void) (visitLabel [Label] void) (visitJumpInsn [int Label] void)) ## [Insts] (def: #export (with-label action) (-> (-> Label $;Inst) $;Inst) (action (Label.new []))) (do-template [ ] [(def: #export ( value) (-> $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitLdcInsn [( value)]))))] [boolean Bool id] [int Int host;l2i] [long Int id] [double Real id] [char Nat (|>. nat-to-int host;l2i host;i2c)] [string Text id] ) (syntax: (prefix [base s;local-symbol]) (wrap (list (code;local-symbol (format "Opcodes." base))))) (def: #export NULL $;Inst (function [visitor] (do-to visitor (MethodVisitor.visitInsn [(prefix ACONST_NULL)])))) (do-template [] [(def: #export $;Inst (function [visitor] (do-to visitor (MethodVisitor.visitInsn [(prefix )]))))] ## Stack [DUP] [DUP2_X1] [POP] [POP2] [SWAP] ## Integer arithmetic [IADD] ## Long bitwise [LAND] [LOR] [LXOR] [LSHL] [LSHR] [LUSHR] ## Long arithmethic [LADD] [LSUB] [LMUL] [LDIV] [LREM] [LCMP] ## Double arithmetic [DADD] [DSUB] [DMUL] [DDIV] [DREM] [DCMPG] ## Conversions [I2L] [L2I] [L2D] [D2L] [I2C] ## Array [AALOAD] [AASTORE] [ARRAYLENGTH] ## Exceptions [ATHROW] ## Return [RETURN] [IRETURN] [LRETURN] [ARETURN] ) (do-template [ ] [(def: #export ( register) (-> Nat $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitVarInsn [ (nat-to-int register)]))))] [ILOAD Opcodes.ILOAD] [LLOAD Opcodes.LLOAD] [ALOAD Opcodes.ALOAD] ) (do-template [ ] [(def: #export ( class field type) (-> Text Text $;Type $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitFieldInsn [ ($t;binary-name class) field ($t;descriptor type)]))))] [GETSTATIC Opcodes.GETSTATIC] [PUTSTATIC Opcodes.PUTSTATIC] [PUTFIELD Opcodes.PUTFIELD] [GETFIELD Opcodes.GETFIELD] ) (do-template [ ] [(def: #export ( class) (-> Text $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitTypeInsn [ ($t;binary-name class)]))))] [CHECKCAST Opcodes.CHECKCAST] [NEW Opcodes.NEW] [ANEWARRAY Opcodes.ANEWARRAY] ) (def: #export (NEWARRAY type) (-> $;Primitive $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitIntInsn [Opcodes.NEWARRAY (case type #$;Boolean Opcodes.T_BOOLEAN #$;Byte Opcodes.T_SHORT #$;Short Opcodes.T_SHORT #$;Int Opcodes.T_INT #$;Long Opcodes.T_LONG #$;Float Opcodes.T_FLOAT #$;Double Opcodes.T_DOUBLE #$;Char Opcodes.T_CHAR)])))) (do-template [ ] [(def: #export ( class method-name method-signature interface?) (-> Text Text $;Method Bool $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitMethodInsn [ ($t;binary-name class) method-name ($t;method-descriptor method-signature) interface?]))))] [INVOKESTATIC Opcodes.INVOKESTATIC] [INVOKEVIRTUAL Opcodes.INVOKEVIRTUAL] [INVOKESPECIAL Opcodes.INVOKESPECIAL] ) (do-template [] [(def: #export ( @where) (-> $;Label $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitJumpInsn [(prefix ) @where]))))] [IF_ICMPEQ] [IF_ACMPEQ] [IFNULL] [IFLT] [IFLE] [IFGT] [IFGE] [GOTO] ) (def: #export (label @label) (-> $;Label $;Inst) (function [visitor] (do-to visitor (MethodVisitor.visitLabel [@label])))) (def: #export (array type size) (-> $;Type Nat $;Inst) (case type (#$;Primitive prim) (|>. (int (nat-to-int size)) (NEWARRAY prim)) (#$;Generic generic) (let [elem-class (case generic (#$;Class class params) ($t;binary-name class) _ ($t;binary-name "java.lang.Object"))] (|>. (int (nat-to-int size)) (ANEWARRAY elem-class))) _ (|>. (int (nat-to-int size)) (ANEWARRAY ($t;descriptor type))))) (do-template [ ] [(def: #export $;Inst (|>. (INVOKESTATIC "valueOf" ($t;method (list ) (#;Some ($t;class (list))) (list)) false))) (def: #export $;Inst (|>. (CHECKCAST ) (INVOKEVIRTUAL ($t;method (list) (#;Some ) (list)) false)))] [wrap-boolean unwrap-boolean "java.lang.Boolean" "booleanValue" $t;boolean] [wrap-byte unwrap-byte "java.lang.Byte" "byteValue" $t;byte] [wrap-short unwrap-short "java.lang.Short" "shortValue" $t;short] [wrap-int unwrap-int "java.lang.Integer" "intValue" $t;int] [wrap-long unwrap-long "java.lang.Long" "longValue" $t;long] [wrap-float unwrap-float "java.lang.Float" "floatValue" $t;float] [wrap-double unwrap-double "java.lang.Double" "doubleValue" $t;double] [wrap-char unwrap-char "java.lang.Character" "charValue" $t;char] ) (def: #export (fuse insts) (-> (List $;Inst) $;Inst) (case insts #;Nil id (#;Cons singleton #;Nil) singleton (#;Cons head tail) (. head (fuse tail))))