diff --git a/.github/linters/.yaml-lint.yml b/.github/linters/.yaml-lint.yml new file mode 100644 index 000000000..d1b0953bd --- /dev/null +++ b/.github/linters/.yaml-lint.yml @@ -0,0 +1,3 @@ +rules: + line-length: disable + document-start: disable diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml index 2726d78c4..ebcb79428 100644 --- a/.github/workflows/install.yml +++ b/.github/workflows/install.yml @@ -12,7 +12,7 @@ on: env: IDRIS2_TESTS_CG: jvm ACTIONS_ALLOW_UNSECURE_COMMANDS: true - PREVIOUS_VERSION: 0.6.0.11 + PREVIOUS_VERSION: 0.7.0 jobs: ubuntu-build: diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 1d6fe3895..5866e4453 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -8,7 +8,7 @@ on: env: IDRIS2_TESTS_CG: jvm ACTIONS_ALLOW_UNSECURE_COMMANDS: true - PREVIOUS_VERSION: 0.6.0.11 + PREVIOUS_VERSION: 0.7.0 jobs: pre-release: @@ -41,7 +41,7 @@ jobs: run: | mvn dependency:copy "-Dartifact=io.github.mmhelloworld:idris-jvm-compiler:$PREVIOUS_VERSION:zip" -DoutputDirectory=. -U unzip idris-jvm-compiler-*.zip -d "$HOME/bin" - echo "::add-path::$HOME/bin/idris2-$PREVIOUS_VERSION/exec" + echo "$HOME/bin/idris2-$PREVIOUS_VERSION/exec" >> "$GITHUB_PATH" - name: Publish to Maven Central run: mvn -B -Prelease deploy diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c6ba4d260..b35edaefa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ on: env: IDRIS2_TESTS_CG: jvm ACTIONS_ALLOW_UNSECURE_COMMANDS: true - PREVIOUS_VERSION: 0.6.0.11 + PREVIOUS_VERSION: 0.7.0 jobs: release: @@ -47,7 +47,7 @@ jobs: run: | mvn dependency:copy "-Dartifact=io.github.mmhelloworld:idris-jvm-compiler:$PREVIOUS_VERSION:zip" -DoutputDirectory=. -U unzip idris-jvm-compiler-*.zip -d "$HOME/bin" - echo "::add-path::$HOME/bin/idris2-$PREVIOUS_VERSION/exec" + echo "$HOME/bin/idris2-$PREVIOUS_VERSION/exec" >> "$GITHUB_PATH" - name: Configure Git user run: | diff --git a/idris-jvm-assembler/src/main/java/io/github/mmhelloworld/idrisjvm/assembler/Assembler.java b/idris-jvm-assembler/src/main/java/io/github/mmhelloworld/idrisjvm/assembler/Assembler.java index 3d990dfef..462f15aa8 100644 --- a/idris-jvm-assembler/src/main/java/io/github/mmhelloworld/idrisjvm/assembler/Assembler.java +++ b/idris-jvm-assembler/src/main/java/io/github/mmhelloworld/idrisjvm/assembler/Assembler.java @@ -475,7 +475,9 @@ public void castore() { } public void checkcast(String desc) { - mv.visitTypeInsn(CHECKCAST, desc); + if (!desc.equals("java/lang/Object")) { + mv.visitTypeInsn(CHECKCAST, desc); + } } public void classCodeStart(int version, diff --git a/src/Compiler/Jvm/Asm.idr b/src/Compiler/Jvm/Asm.idr index ba1c15c9f..fb4d728d9 100644 --- a/src/Compiler/Jvm/Asm.idr +++ b/src/Compiler/Jvm/Asm.idr @@ -5,6 +5,7 @@ import Compiler.CompileExpr import Compiler.Inline import Core.Context +import Core.Core import Core.Name import Core.Reflect import Core.TT @@ -28,11 +29,16 @@ import System.FFI %hide Core.Name.Scoped.Scope %hide Debug.Trace.toString +%hide Core.TT.Primitive.Constant public export -data Assembler : Type where [external] +Assembler : Type +Assembler = Struct "io/github/mmhelloworld/idrisjvm/assembler/Assembler" [] + +public export +JAnnotation : Type +JAnnotation = Struct "io/github/mmhelloworld/idrisjvm/assembler/Annotation" [] -data JAnnotation : Type where [external] data JAnnString : Type where [external] data JAnnEnum : Type where [external] data JAnnInt : Type where [external] @@ -626,164 +632,6 @@ export %foreign "jvm:#JAVA_VERSION(int),io/github/mmhelloworld/idrisjvm/assembler/Assembler" javaClassFileVersion : Int -public export -data Asm : Type -> Type where - Aaload : Asm () - Aastore : Asm () - Aconstnull : Asm () - Aload : Int -> Asm () - Anewarray : (descriptor: String) -> Asm () - - Anewbooleanarray : Asm () - Anewbytearray : Asm () - Anewchararray : Asm () - Anewshortarray : Asm () - Anewintarray : Asm () - Anewlongarray : Asm () - Anewfloatarray : Asm () - Anewdoublearray : Asm () - - Arraylength : Asm () - Areturn : Asm () - Astore : Int -> Asm () - Baload : Asm () - Bastore : Asm () - Caload : Asm () - Castore : Asm () - Checkcast : (descriptor: String) -> Asm () - ClassCodeStart : Int -> List Access -> (className: String) -> (signature: Maybe String) -> (parentClassName: String) -> - (interfaces: List String) -> List Asm.Annotation -> Asm () - CreateClass : List ClassOpts -> Asm () - CreateField : List Access -> (sourceFileName: String) -> (className: String) -> (fieldName: String) -> (descriptor: String) -> - (signature: Maybe String) -> Maybe FieldInitialValue -> (annotations: List Asm.Annotation) -> Asm () - CreateLabel : String -> Asm () - CreateMethod : List Access -> (sourceFileName: String) -> (className: String) -> - (methodName: String) -> (descriptor: String) -> - (signature: Maybe String) -> (exceptions: Maybe (List String)) -> - (annotations: List Asm.Annotation) -> - (parameterAnnotations: List (List Asm.Annotation)) -> Asm () - CreateIdrisConstructorClass : String -> Bool -> Int -> Asm () - D2i : Asm () - D2f : Asm () - D2l : Asm () - Dadd : Asm () - Daload : Asm () - Dastore : Asm () - Dcmpg : Asm () - Dcmpl : Asm () - Dconst : Double -> Asm () - Ddiv : Asm () - Debug : String -> Asm () - Dload : Int -> Asm () - Dmul : Asm () - Dneg : Asm () - Drem : Asm () - Dreturn : Asm () - Dstore : Int -> Asm () - Dsub : Asm () - Dup : Asm () - Error : String -> Asm () - F2d : Asm () - Faload : Asm () - Fastore : Asm () - Fconst : Double -> Asm () - Field : FieldInstructionType -> (className: String) -> (fieldName: String) -> (descriptor: String) -> Asm () - FieldEnd : Asm () - Fload : Int -> Asm () - Frame : FrameType -> Int -> (signatures: List String) -> Int -> (signatures: List String) -> Asm () - Freturn : Asm () - Fstore : Int -> Asm () - Goto : (label: String) -> Asm () - I2b : Asm () - I2c : Asm () - I2d : Asm () - I2l : Asm () - I2s : Asm () - Iadd : Asm () - Iaload : Asm () - Iand : Asm () - Iastore : Asm () - Ior : Asm () - Ixor : Asm () - Icompl : Asm () - Iconst : Int -> Asm () - Idiv : Asm () - Ifeq : (label: String) -> Asm () - Ifge : (label: String) -> Asm () - Ifgt : (label: String) -> Asm () - Ificmpge : (label: String) -> Asm () - Ificmpgt : (label: String) -> Asm () - Ificmple : (label: String) -> Asm () - Ificmplt : (label: String) -> Asm () - Ificmpeq : (label: String) -> Asm () - Ifacmpne : (label: String) -> Asm () - Ificmpne : (label: String) -> Asm () - Ifle : (label: String) -> Asm () - Iflt : (label: String) -> Asm () - Ifne : (label: String) -> Asm () - Ifnonnull : (label: String) -> Asm () - Ifnull : (label: String) -> Asm () - Iload : Int -> Asm () - Imul : Asm () - Ineg : Asm () - InstanceOf : (className: String) -> Asm () - InvokeMethod : InvocationType -> (className: String) -> (methodName: String) -> (descriptor: String) - -> Bool -> Asm () - InvokeDynamic : (methodName: String) -> (descriptor: String) -> Handle -> List BsmArg -> Asm () - Irem : Asm () - Ireturn : Asm () - Ishl : Asm () - Ishr : Asm () - Istore : Int -> Asm () - Isub : Asm () - Iushr : Asm () - L2d : Asm () - L2i : Asm () - LabelStart : (label: String) -> Asm () - Ladd : Asm () - Laload : Asm () - Land : Asm () - Lastore : Asm () - Lcmp : Asm () - Lcompl : Asm () - Ldc : Asm.Constant -> Asm () - Ldiv : Asm () - LineNumber : Int -> String -> Asm () - Lload : Int -> Asm () - Lmul : Asm () - Lneg : Asm () - LocalVariable : (name: String) -> (descriptor: String) -> (signature: Maybe String) -> (startLabel: String) -> - (endLabel: String) -> (index: Int) -> Asm () - LookupSwitch : (defaultLabel: String) -> (labels: List String) -> (cases: List Int) -> Asm () - Lor : Asm () - Lrem : Asm () - Lreturn : Asm () - Lshl : Asm () - Lshr : Asm () - Lstore : Int -> Asm () - Lsub : Asm () - Lushr : Asm () - Lxor : Asm () - MaxStackAndLocal : Int -> Int -> Asm () - MethodCodeStart : Asm () - MethodCodeEnd : Asm () - Multianewarray : (descriptor: String) -> Int -> Asm () - New : (className: String) -> Asm () - Pop : Asm () - Pop2 : Asm () - Return : Asm () - Saload : Asm () - Sastore : Asm () - SourceInfo : (sourceFileName: String) -> Asm () - LiftIo : IO a -> Asm a - - Throw : FC -> String -> Asm a - GetState : Asm AsmState - SetState : AsmState -> Asm () - - Pure : ty -> Asm ty - Bind : Asm a -> (a -> Asm b) -> Asm b - export Show Scope where show scope = showType "Scope" [ @@ -818,30 +666,6 @@ Show AsmState where ("lambdaCounter", show $ lambdaCounter asmState) ] -%inline -public export -Functor Asm where - map f a = Bind a (\a' => Pure $ f a') - -%inline -public export -Applicative Asm where - pure = Pure - - (<*>) f a = Bind f (\f' => - Bind a (\a' => - Pure (f' a'))) - -%inline -public export -Monad Asm where - (>>=) = Bind - -%inline -public export -HasIO Asm where - liftIO = LiftIo - public export newAsmState : HasIO io => AsmGlobalState -> Assembler -> io AsmState newAsmState globalState assembler = do @@ -852,1315 +676,2117 @@ newAsmState globalState assembler = do 0 defaultName (NmCrash emptyFC "uninitialized function") pure $ MkAsmState globalState function defaultName 0 0 0 0 lineNumberLabels assembler -export -updateState : (AsmState -> AsmState) -> Asm () -updateState f = SetState $ f !GetState - -getAndUpdateState : (AsmState -> AsmState) -> Asm AsmState -getAndUpdateState f = do - state <- GetState - SetState $ f state - Pure state - public export %foreign "jvm:crash(String java/lang/Object),io/github/mmhelloworld/idrisjvm/runtime/Runtime" crash : String -> Object export -asmCrash : String -> Asm a -asmCrash message = Pure $ believe_me $ crash message - -export -newBigInteger : String -> Asm () -newBigInteger "0" = Field GetStatic "java/math/BigInteger" "ZERO" "Ljava/math/BigInteger;" -newBigInteger "1" = Field GetStatic "java/math/BigInteger" "ONE" "Ljava/math/BigInteger;" -newBigInteger "10" = Field GetStatic "java/math/BigInteger" "TEN" "Ljava/math/BigInteger;" -newBigInteger i = do - New "java/math/BigInteger" - Dup - Ldc $ StringConst i - InvokeMethod InvokeSpecial "java/math/BigInteger" "" "(Ljava/lang/String;)V" False +asmCrash : String -> Core a +asmCrash message = throw (InternalError message) -export -getGlobalState : Asm AsmGlobalState -getGlobalState = Pure $ globalState !GetState +isBoolTySpec : Name -> Bool +isBoolTySpec name = name == basics "Bool" || name == (NS preludeNS (UN $ Basic "Bool")) -export -findFunction : Jname -> Asm (Maybe Function) -findFunction name = LiftIo $ AsmGlobalState.findFunction !getGlobalState name +mutual + tySpecFn : String -> InferredFunctionType + tySpecFn desc = case reverse $ toList $ String.split (== '⟶') desc of + [] => assert_total $ idris_crash ("Invalid function type descriptor: " ++ desc) + (returnTypeStr :: argsReversed) => + MkInferredFunctionType (tySpecStr returnTypeStr) (reverse $ (tySpecStr <$> argsReversed)) -export -getFunction : Jname -> Asm Function -getFunction name = maybe (asmCrash $ "Unknown function " ++ show name) Pure !(findFunction name) + tySpecLambda : String -> JavaLambdaType + tySpecLambda desc = case toList $ String.split (== ',') desc of + [intfStr, method, methodTypeStr, implementationTypeStr] => + MkJavaLambdaType (tySpecStr intfStr) method (tySpecFn methodTypeStr) (tySpecFn implementationTypeStr) + _ => assert_total $ idris_crash ("Invalid lambda type descriptor: " ++ desc) -export -getCurrentFunction : Asm Function -getCurrentFunction = currentIdrisFunction <$> GetState + tySpecStr : String -> InferredType + tySpecStr "Int" = IInt + tySpecStr "Int8" = IByte + tySpecStr "Int16" = IShort + tySpecStr "Int32" = IInt + tySpecStr "Int64" = ILong + tySpecStr "Integer" = inferredBigIntegerType + tySpecStr "String" = inferredStringType + tySpecStr "Double" = IDouble + tySpecStr "Char" = IChar + tySpecStr "Bool" = IBool + tySpecStr "long" = ILong + tySpecStr "void" = IVoid + tySpecStr "%World" = IInt + tySpecStr "[" = assert_total $ idris_crash "Invalid type descriptor: [" + tySpecStr "λ" = assert_total $ idris_crash "Invalid type descriptor: λ" + tySpecStr desc = + cond [(startsWith desc "[", IArray (tySpecStr (assert_total (strTail desc)))), + (startsWith desc "λ", IFunction (tySpecLambda (assert_total (strTail desc)))) + ] + (iref desc []) export -getProgramName : Asm String -getProgramName = LiftIo $ AsmGlobalState.getProgramName !getGlobalState +structName : Name +structName = NS (mkNamespace "System.FFI") (UN $ Basic "Struct") export -getFcAndDefinition : String -> Asm (FC, NamedDef) -getFcAndDefinition name = LiftIo $ AsmGlobalState.getFcAndDefinition !getGlobalState name +arrayName : Name +arrayName = NS (mkNamespace "Java.Lang") (UN $ Basic "Array") -export -isUntypedFunction : Jname -> Asm Bool -isUntypedFunction name = LiftIo $ AsmGlobalState.isUntypedFunction !getGlobalState name +getIdrisConstructorType : ConInfo -> (tag: Maybe Int) -> Nat -> Name -> InferredType +getIdrisConstructorType conInfo tag arity name = + if isBoolTySpec name then IBool + else if name == basics "List" then idrisListType + else if name == preludetypes "Maybe" then idrisMaybeType + else if name == preludetypes "Nat" then inferredBigIntegerType + else inferredObjectType -export -addUntypedFunction : Jname -> Asm () -addUntypedFunction name = LiftIo $ AsmGlobalState.addUntypedFunction !getGlobalState name +parseName : String -> Maybe InferredType +parseName name = + case words name of + (interfaceName :: methodName :: _) => Just $ IRef interfaceName Interface [] + (className :: []) => Just $ iref className [] + _ => Nothing export -setCurrentFunction : Function -> Asm () -setCurrentFunction function = updateState $ { currentIdrisFunction := function } - -getAndUpdateFunction : (Function -> Function) -> Asm Function -getAndUpdateFunction f = do - function <- getCurrentFunction - let newFunction = f function - setCurrentFunction newFunction - globalState <- getGlobalState - LiftIo $ addFunction globalState (idrisName newFunction) newFunction - Pure function +getJvmTypeDescriptor : InferredType -> String +getJvmTypeDescriptor IByte = "B" +getJvmTypeDescriptor IChar = "C" +getJvmTypeDescriptor IShort = "S" +getJvmTypeDescriptor IBool = "Z" +getJvmTypeDescriptor IDouble = "D" +getJvmTypeDescriptor IFloat = "F" +getJvmTypeDescriptor IInt = "I" +getJvmTypeDescriptor ILong = "J" +getJvmTypeDescriptor IVoid = "V" +getJvmTypeDescriptor (IRef ty _ _) = "L" ++ ty ++ ";" +getJvmTypeDescriptor (IArray ty) = "[" ++ getJvmTypeDescriptor ty +getJvmTypeDescriptor (IFunction lambdaType) = getJvmTypeDescriptor (lambdaType.javaInterface) +getJvmTypeDescriptor IUnknown = getJvmTypeDescriptor inferredObjectType +getJvmTypeDescriptor (TypeParam name) = getJvmTypeDescriptor inferredObjectType export -updateCurrentFunction : (Function -> Function) -> Asm () -updateCurrentFunction f = ignore $ getAndUpdateFunction f +getJvmReferenceTypeName : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Core String +getJvmReferenceTypeName (IRef ty _ _) = pure ty +getJvmReferenceTypeName (IArray (IRef ty _ _)) = pure ("[L" ++ ty ++ ";") +getJvmReferenceTypeName (IArray ty) = pure ("[" ++ !(getJvmReferenceTypeName ty)) +getJvmReferenceTypeName (IFunction lambdaType) = getJvmReferenceTypeName (lambdaType.javaInterface) +getJvmReferenceTypeName ty = asmCrash ("Expected a reference type but found " ++ show ty) export -loadFunction : Jname -> Asm () -loadFunction idrisName = do - function <- getFunction idrisName - updateState $ { currentIdrisFunction := function } +getSignature : InferredType -> String +getSignature (IRef ty _ typeParams@(_ :: _)) = + let typeParamsSignature = concat (getSignature <$> typeParams) + in "L" ++ ty ++ "<" ++ typeParamsSignature ++ ">;" +getSignature (TypeParam name) = "T" ++ name ++ ";" +getSignature (IArray ty) = "[" ++ getSignature ty +getSignature type = getJvmTypeDescriptor type +-- constant values from org.objectweb.asm.Opcodes export -getFunctionType : Jname -> Asm InferredFunctionType -getFunctionType name = inferredFunctionType <$> (getFunction name) +accessNum : Access -> Int +accessNum Public = 0x0001 +accessNum Private = 0x0002 +accessNum Protected = 0x0004 +accessNum Static = 0x0008 +accessNum Final = 0x0010 +accessNum Interface = 0x0200 +accessNum Abstract = 0x0400 +accessNum Synthetic = 0x1000 +accessNum Transient = 0x0080 export -getFunctionParameterTypes : Jname -> Asm (List InferredType) -getFunctionParameterTypes functionName = do - functionType <- getFunctionType functionName - pure $ parameterTypes functionType +fieldInsTypeNum : FieldInstructionType -> Int +fieldInsTypeNum GetStatic = 178 +fieldInsTypeNum PutStatic = 179 +fieldInsTypeNum GetField = 180 +fieldInsTypeNum PutField = 181 export -findFunctionType : Jname -> Asm (Maybe InferredFunctionType) -findFunctionType functionName = do - state <- GetState - function <- findFunction functionName - Pure $ inferredFunctionType <$> function +frameTypeNum : FrameType -> Int +frameTypeNum Full = 0 +frameTypeNum Same = 3 +frameTypeNum Append = 1 export -getFunctionReturnType : Jname -> Asm InferredType -getFunctionReturnType functionName = do - state <- GetState - function <- findFunction functionName - Pure $ maybe IUnknown (returnType . inferredFunctionType) $ function +invocTypeNum : InvocationType -> Int +invocTypeNum InvokeInterface = 185 +invocTypeNum InvokeSpecial = 183 +invocTypeNum InvokeStatic = 184 +invocTypeNum InvokeVirtual = 182 export -getCurrentScopeIndex : Asm Int -getCurrentScopeIndex = currentScopeIndex <$> GetState +handleTagOpcode : HandleTag -> Int +handleTagOpcode GetField = 1 +handleTagOpcode GetStatic = 2 +handleTagOpcode PutField = 3 +handleTagOpcode PutStatic = 4 +handleTagOpcode InvokeVirtual = 5 +handleTagOpcode InvokeStatic = 6 +handleTagOpcode InvokeSpecial = 7 +handleTagOpcode NewInvokeSpecial = 8 +handleTagOpcode InvokeInterface = 9 +%foreign + jvm' "java/lang/Integer" "valueOf" "int" "java/lang/Integer" export -updateCurrentScopeIndex : Int -> Asm () -updateCurrentScopeIndex scopeIndex = updateState $ { currentScopeIndex := scopeIndex } +integerValueOf : Int -> JInteger +%foreign + jvm' "java/lang/Double" "valueOf" "double" "java/lang/Double" export -newScopeIndex : Asm Int -newScopeIndex = scopeCounter <$> (getAndUpdateState $ {scopeCounter $= (+1)}) +doubleValueOf : Double -> JDouble +%foreign + jvm' "java/lang/Long" "valueOf" "long" "java/lang/Long" export -newDynamicVariableIndex : Asm Int -newDynamicVariableIndex = dynamicVariableCounter <$> (getAndUpdateFunction $ {dynamicVariableCounter $= (+1)}) +bits64ToJLong : Bits64 -> JLong +%foreign + jvm' "java/lang/Long" "valueOf" "long" "java/lang/Long" export -resetScope : Asm () -resetScope = updateState $ - { - scopeCounter := 0, - currentScopeIndex := 0 - } - -fillNull : (HasIO io, Inherits list (JList a)) => Int -> list -> io () -fillNull index aList = do - let list = the (JList a) $ believe_me aList - size <- Collection.size {elemTy=a,obj=Collection a} $ believe_me list - nulls <- JList.nCopies {a=a} (index - size) nullValue - ignore $ JList.addAll {a=a, obj=Collection a} list $ believe_me nulls +int64ToJLong : Int64 -> JLong export -saveScope : Scope -> Asm () -saveScope scope = do - scopes <- scopes <$> getCurrentFunction - size <- LiftIo $ Collection.size {elemTy=Scope, obj=Collection Scope} $ believe_me scopes - let scopeIndex = index scope - LiftIo $ - if scopeIndex < size - then ignore $ JList.set scopes scopeIndex scope - else do - fillNull {a=Scope} scopeIndex scopes - JList.add scopes scopeIndex scope +constantToObject : {auto stateRef: Ref AsmState AsmState} -> Constant -> Object +constantToObject (DoubleConst d) = believe_me $ doubleValueOf d +constantToObject (IntegerConst n) = believe_me $ integerValueOf n +constantToObject (Int64Const n) = believe_me $ int64ToJLong n +constantToObject (Bits64Const n) = believe_me $ bits64ToJLong n +constantToObject (StringConst str) = believe_me str +constantToObject (TypeConst str) = believe_me str -export -getScope : Int -> Asm Scope -getScope scopeIndex = do - scopes <- scopes <$> getCurrentFunction - LiftIo $ JList.get scopes scopeIndex +toJClassOpts : ClassOpts -> Int +toJClassOpts ComputeMaxs = 1 +toJClassOpts ComputeFrames = 2 -export -addScopeChild : Int -> Int -> Asm () -addScopeChild parentScopeIndex childScopeIndex = do - scope <- getScope parentScopeIndex - saveScope $ {childIndices $= (childScopeIndex ::)} scope +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/JHandle" "" + "int String String String boolean" + "io/github/mmhelloworld/idrisjvm/assembler/JHandle" +prim_newJHandle : Int -> String -> String -> String -> Bool -> PrimIO JHandle -export -getRootMethodName : Asm Jname -getRootMethodName = jvmClassMethodName <$> getCurrentFunction +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgHandle" "" + "io/github/mmhelloworld/idrisjvm/assembler/JHandle" + "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgHandle" +prim_newJBsmArgHandle : JHandle -> PrimIO JBsmArgHandle -export -newLabel : Asm String -newLabel = do - state <- GetState - let label = "L" ++ show (labelCounter state) - updateState $ { labelCounter $= (+1) } - Pure label +%inline +newJBsmArgHandle : HasIO io => JHandle -> io JBsmArgHandle +newJBsmArgHandle = primIO . prim_newJBsmArgHandle -hasLabelAtLine : Int -> Asm Bool -hasLabelAtLine lineNumber = do - state <- GetState - LiftIo $ Map.containsKey {value=String} (lineNumberLabels state) lineNumber +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgGetType" "" + "String" + "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgGetType" +prim_newJBsmArgGetType : String -> PrimIO JBsmArgGetType -export -addLineNumber : Int -> String -> Asm () -addLineNumber lineNumber label = do - hasLabel <- hasLabelAtLine lineNumber - when (not hasLabel) $ do - state <- GetState - LineNumber lineNumber label - _ <- LiftIo $ Map.put (lineNumberLabels state) lineNumber label - Pure () +%inline +newJBsmArgGetType : HasIO io => String -> io JBsmArgGetType +newJBsmArgGetType = primIO . prim_newJBsmArgGetType -export -getLineNumberLabel : Int -> Asm String -getLineNumberLabel lineNumber = do - state <- GetState - let currentLineNumberLabels = lineNumberLabels state - optLabel <- LiftIo $ Map.get {value=String} currentLineNumberLabels lineNumber - case nullableToMaybe optLabel of - Just label => Pure label - Nothing => do - label <- newLabel - _ <- LiftIo $ Map.put currentLineNumberLabels lineNumber label - Pure label +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnString" "" + "String" + "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnString" +prim_newJAnnString : String -> PrimIO JAnnString -export -getClassName : Asm String -getClassName = className . currentMethodName <$> GetState +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnEnum" "" + "String String" + "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnEnum" +prim_newJAnnEnum : String -> String -> PrimIO JAnnEnum -export -getMethodName : Asm String -getMethodName = methodName . currentMethodName <$> GetState +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnInt" "" + "int" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnInt" +prim_newJAnnInt : Int -> PrimIO JAnnInt -export -freshLambdaIndex : Asm Int -freshLambdaIndex = lambdaCounter <$> (getAndUpdateState $ {lambdaCounter $= (+1)}) +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnBoolean" "" + "boolean" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnBoolean" +prim_newJAnnBoolean : Bool -> PrimIO JAnnBoolean -export -setScopeCounter : Int -> Asm () -setScopeCounter scopeCounter = updateState $ {scopeCounter := scopeCounter} +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnChar" "" + "char" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnChar" +prim_newJAnnChar : Char -> PrimIO JAnnChar -export -updateScopeStartLabel : Int -> String -> Asm () -updateScopeStartLabel scopeIndex label = do - scope <- getScope scopeIndex - saveScope $ {labels $= updateFirst label} scope +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnDouble" "" + "double" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnDouble" +prim_newJAnnDouble : Double -> PrimIO JAnnDouble -export -updateScopeEndLabel : Int -> String -> Asm () -updateScopeEndLabel scopeIndex label = do - scope <- getScope scopeIndex - saveScope $ {labels $= updateSecond label} scope +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnClass" "" + "String" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnClass" +prim_newJAnnClass : String -> PrimIO JAnnClass + +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnAnnotation" "" + "io/github/mmhelloworld/idrisjvm/assembler/Annotation" + "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnAnnotation" +prim_newJAnnAnnotation : JAnnotation -> PrimIO JAnnAnnotation + +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnArray" "" + "java/util/List" + "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnArray" +prim_newJAnnArray : JList JAnnotationValue -> PrimIO JAnnArray + +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationProperty" "" + "String io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue" + "io/github/mmhelloworld/idrisjvm/assembler/AnnotationProperty" +prim_newJAnnotationProperty : String -> JAnnotationValue -> PrimIO JAnnotationProperty + +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/Annotation" "" + "String java/util/List" + "io/github/mmhelloworld/idrisjvm/assembler/Annotation" +prim_newJAnnotation : String -> JList JAnnotationProperty -> PrimIO JAnnotation export -createVariable : String -> Asm () -createVariable var = do - scopeIndex <- getCurrentScopeIndex - scope <- getScope scopeIndex - let variableIndex = nextVariableIndex scope - _ <- LiftIo $ Map.put (variableTypes scope) var IUnknown - _ <- LiftIo $ Map.put (variableIndices scope) var variableIndex - saveScope $ { nextVariableIndex $= (+1) } scope +toJHandle : HasIO io => Handle -> io JHandle +toJHandle (MkHandle tag hcname hmname hdesc hIsIntf) = do + let tagNum = handleTagOpcode tag + primIO $ prim_newJHandle tagNum hcname hmname hdesc hIsIntf export -generateVariable : String -> Asm String -generateVariable namePrefix = do - dynamicVariableIndex <- newDynamicVariableIndex - let variableName = namePrefix ++ show dynamicVariableIndex - createVariable variableName - Pure variableName +toJbsmArg : HasIO io => BsmArg -> io JBsmArg +toJbsmArg (BsmArgGetType desc) = believe_me <$> newJBsmArgGetType desc +toJbsmArg (BsmArgHandle handle) = do + jhandle <- toJHandle handle + believe_me <$> newJBsmArgHandle jhandle -namespace JAsmState - %foreign jvm' "io/github/mmhelloworld/idrisjvm/assembler/AsmState" "updateVariableIndices" "java/util/Map java/util/Map" "void" - prim_updateVariableIndices : Map key value -> Map key value -> PrimIO () +mutual + toJAnnotationValue : HasIO io => Asm.AnnotationValue -> io JAnnotationValue + toJAnnotationValue (AnnString s) = believe_me <$> primIO (prim_newJAnnString s) + toJAnnotationValue (AnnEnum enum s) = believe_me <$> primIO (prim_newJAnnEnum enum s) + toJAnnotationValue (AnnInt n) = believe_me <$> primIO (prim_newJAnnInt n) + toJAnnotationValue (AnnBoolean n) = believe_me <$> primIO (prim_newJAnnBoolean n) + toJAnnotationValue (AnnChar n) = believe_me <$> primIO (prim_newJAnnChar n) + toJAnnotationValue (AnnDouble n) = believe_me <$> primIO (prim_newJAnnDouble n) + toJAnnotationValue (AnnClass n) = believe_me <$> primIO (prim_newJAnnClass n) + toJAnnotationValue (AnnAnnotation n) = do + jAnn <- toJAnnotation n + believe_me <$> primIO (prim_newJAnnAnnotation jAnn) + toJAnnotationValue (AnnArray values) = + believe_me <$> primIO (prim_newJAnnArray $ subtyping !(traverse toJAnnotationValue values)) - export - updateVariableIndices : HasIO io => Map String Int -> Map String Int -> io () - updateVariableIndices resultIndicesByName indicesByName = - primIO $ prim_updateVariableIndices resultIndicesByName indicesByName + toJAnnotationProperty : HasIO io => Asm.AnnotationProperty -> io JAnnotationProperty + toJAnnotationProperty (name, annValue) = do + jAnnotationValue <- toJAnnotationValue annValue + primIO $ prim_newJAnnotationProperty name jAnnotationValue - %foreign jvm' "io/github/mmhelloworld/idrisjvm/assembler/AsmState" "getVariableNames" "java/util/Map" "java/util/List" - prim_getVariableNames : Map key value -> PrimIO (JList key) + toJAnnotation : HasIO io => Asm.Annotation -> io JAnnotation + toJAnnotation (MkAnnotation name props) = do + properties <- traverse toJAnnotationProperty props + primIO $ prim_newJAnnotation name $ believe_me properties - export - getVariableNames : HasIO io => Map String Int -> io (List String) - getVariableNames indicesByName = do - jlist <- primIO $ prim_getVariableNames indicesByName - JList.fromIterable jlist +mutual + asmAnnotationValue : AnnotationValue -> AnnotationValue + asmAnnotationValue (AnnArray values) = AnnArray (asmAnnotationValue <$> values) + asmAnnotationValue (AnnAnnotation annotation) = AnnAnnotation (asmAnnotation annotation) + asmAnnotationValue value = value -retrieveVariableIndicesByName : Int -> Asm (Map String Int) -retrieveVariableIndicesByName scopeIndex = do - variableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} - go variableIndices scopeIndex - Pure variableIndices - where - go : Map String Int -> Int -> Asm () - go acc scopeIndex = go1 scopeIndex where - go1 : Int -> Asm () - go1 scopeIndex = do - scope <- getScope scopeIndex - LiftIo $ updateVariableIndices acc (variableIndices scope) - maybe (Pure ()) go1 (parentIndex scope) + asmAnnotationProperty : (String, AnnotationValue) -> (String, AnnotationValue) + asmAnnotationProperty (name, value) = (name, asmAnnotationValue value) + + export + asmAnnotation : Annotation -> Annotation + asmAnnotation (MkAnnotation name properties) = + MkAnnotation ("L" ++ name ++ ";") (asmAnnotationProperty <$> properties) export -retrieveVariables : Int -> Asm (List String) -retrieveVariables scopeIndex = do - variableIndicesByName <- retrieveVariableIndicesByName scopeIndex - LiftIo $ getVariableNames variableIndicesByName +toJFieldInitialValue : FieldInitialValue -> Object +toJFieldInitialValue (IntField n) = believe_me $ integerValueOf n +toJFieldInitialValue (StringField s) = believe_me s +toJFieldInitialValue (DoubleField d) = believe_me $ doubleValueOf d -retrieveVariableIndexAtScope : Int -> String -> Asm Int -retrieveVariableIndexAtScope currentScopeIndex name = go currentScopeIndex where - go : Int -> Asm Int - go scopeIndex = do - scope <- getScope scopeIndex - optIndex <- LiftIo $ Map.get {value=Int} (variableIndices scope) name - case nullableToMaybe optIndex of - Just index => Pure index - Nothing => case parentIndex scope of - Just parentScopeIndex => go parentScopeIndex - Nothing => do - rootMethodName <- getRootMethodName - Throw emptyFC - ("retrieveVariableIndexAtScope: " ++ show rootMethodName ++ ": Unknown var " ++ - name ++ " at index " ++ show currentScopeIndex) +export +getMethodDescriptor : InferredFunctionType -> String +getMethodDescriptor (MkInferredFunctionType retTy []) = "()" ++ getJvmTypeDescriptor retTy +getMethodDescriptor (MkInferredFunctionType retTy argTypes) = + let argDescs = getJvmTypeDescriptor <$> argTypes + retTyDesc = getJvmTypeDescriptor retTy + in "(" ++ (the String $ concat argDescs) ++ ")" ++ retTyDesc export -retrieveVariableIndex : String -> Asm Int -retrieveVariableIndex name = retrieveVariableIndexAtScope !getCurrentScopeIndex name +getMethodSignature : InferredFunctionType -> String +getMethodSignature (MkInferredFunctionType retTy []) = "()" ++ getSignature retTy +getMethodSignature (MkInferredFunctionType retTy argTypes) = + let argDescs = getSignature <$> argTypes + retTyDesc = getSignature retTy + in "(" ++ (the String $ concat argDescs) ++ ")" ++ retTyDesc -retrieveVariableTypeAtScope : Int -> String -> Asm InferredType -retrieveVariableTypeAtScope scopeIndex name = do - scope <- getScope scopeIndex - optTy <- LiftIo $ Map.get (variableTypes scope) name - case nullableToMaybe optTy of - Just ty => Pure ty - Nothing => case parentIndex scope of - Just parentScope => retrieveVariableTypeAtScope parentScope name - Nothing => pure IUnknown +%foreign + jvm' "io/github/mmhelloworld/idrisjvm/assembler/IdrisName" "getIdrisFunctionName" + "String String String" "io/github/mmhelloworld/idrisjvm/runtime/IdrisList" +jgetIdrisFunctionName : String -> String -> String -> List String export -retrieveVariableTypesAtScope : Int -> Asm (Map Int InferredType) -retrieveVariableTypesAtScope scopeIndex = do - typesByIndex <- LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} - go typesByIndex !(retrieveVariables scopeIndex) - Pure typesByIndex - where - go : Map Int InferredType -> List String -> Asm () - go acc names = go1 names where - go1 : List String -> Asm () - go1 [] = Pure () - go1 (var :: vars) = do - varIndex <- retrieveVariableIndexAtScope scopeIndex var - ty <- retrieveVariableTypeAtScope scopeIndex var - hasVar <- LiftIo $ containsKey {value=InferredType} acc varIndex - when (not hasVar) $ LiftIo $ do - oldTy <- Map.put acc varIndex ty - pure () - go1 vars +getIdrisFunctionName : String -> String -> String -> Jname +getIdrisFunctionName programName moduleName idrisFunctionName = + case jgetIdrisFunctionName programName moduleName idrisFunctionName of + (className :: functionName :: _) => Jqualified className functionName + _ => Jqualified moduleName idrisFunctionName -export -getVariableIndicesByName : Int -> Asm (Map String Int) -getVariableIndicesByName scopeIndex = allVariableIndices <$> getScope scopeIndex +%inline +metafactoryDesc : String +metafactoryDesc = + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;" export -getVariableIndexAtScope : Int -> String -> Asm Int -getVariableIndexAtScope currentScopeIndex name = do - variableIndicesByName <- getVariableIndicesByName currentScopeIndex - optIndex <- LiftIo $ Map.get {value=Int} variableIndicesByName name - case nullableToMaybe optIndex of - Just index => Pure index - Nothing => do - rootMethodName <- getRootMethodName - asmCrash ("getVariableIndexAtScope: " ++ show rootMethodName ++ ": Unknown var " ++ - name ++ " at index " ++ show currentScopeIndex) +shouldDebugAsm : Bool +shouldDebugAsm = + let shouldDebugProperty = fromMaybe "" $ unsafePerformIO (getEnv "IDRIS_JVM_DEBUG_ASM") + in shouldDebugProperty == "true" export -getVariableIndex : String -> Asm Int -getVariableIndex name = getVariableIndexAtScope !getCurrentScopeIndex name +shouldDebug : Bool +shouldDebug = + let shouldDebugProperty = fromMaybe "" $ unsafePerformIO (getEnv "IDRIS_JVM_DEBUG") + in shouldDebugProperty /= "" && shouldDebugProperty /= "false" export -getVariableTypesAtScope : Int -> Asm (Map Int InferredType) -getVariableTypesAtScope scopeIndex = allVariableTypes <$> getScope scopeIndex +debugFunction : String +debugFunction = fromMaybe "" $ unsafePerformIO $ getEnv "IDRIS_JVM_DEBUG" export -getVariableTypes : Asm (Map Int InferredType) -getVariableTypes = getVariableTypesAtScope !getCurrentScopeIndex +shouldDebugFunction : Jname -> Bool +shouldDebugFunction jname = shouldDebug && (debugFunction == "" || (debugFunction `isInfixOf` (getSimpleName jname))) + +namespace LocalDateTime + data LocalDateTime : Type where [external] + + %foreign "jvm:now(java/lang/Object java/time/LocalDateTime),java/time/LocalDateTime" + prim_now : PrimIO LocalDateTime + + %foreign jvm' "java/time/LocalDateTime" ".toString" "java/time/LocalDateTime" "String" + prim_toString : LocalDateTime -> PrimIO String + + export + currentTimeString : HasIO io => io String + currentTimeString = do + now <- primIO prim_now + primIO $ prim_toString now + +%foreign "jvm:getCurrentThreadName(java/lang/Object java/lang/String),io/github/mmhelloworld/idrisjvm/runtime/Runtime" +prim_getCurrentThreadName : PrimIO String export -getVariableTypeAtScope : Int -> String -> Asm InferredType -getVariableTypeAtScope scopeIndex name = do - scope <- getScope scopeIndex - variableIndicesByName <- getVariableIndicesByName scopeIndex - optIndex <- LiftIo $ Map.get {value=Int} variableIndicesByName name - case nullableToMaybe optIndex of - Just index => do - variableTypes <- getVariableTypesAtScope scopeIndex - optTy <- LiftIo $ Map.get {value=InferredType} variableTypes index - Pure $ fromMaybe IUnknown $ nullableToMaybe optTy - Nothing => Pure IUnknown +getCurrentThreadName : HasIO io => io String +getCurrentThreadName = primIO prim_getCurrentThreadName export -getVariableType : String -> Asm InferredType -getVariableType name = getVariableTypeAtScope !getCurrentScopeIndex name +getJvmClassMethodName : String -> Name -> Jname +getJvmClassMethodName programName name = + let jname = jvmName name + in getIdrisFunctionName programName (className jname) (methodName jname) -updateArgumentsForUntyped : Map Int InferredType -> Nat -> IO () -updateArgumentsForUntyped _ Z = pure () -updateArgumentsForUntyped types (S n) = do - ignore $ Map.put types (cast {to=Int} n) inferredObjectType - updateArgumentsForUntyped types n +export +createAsmStateJavaName : AsmGlobalState -> String -> IO AsmState +createAsmStateJavaName globalState name = do + assembler <- getAssembler globalState name + newAsmState globalState assembler export -updateScopeVariableTypes : Nat -> Asm () -updateScopeVariableTypes arity = go (scopeCounter !GetState - 1) where - go : Int -> Asm () - go scopeIndex = - if scopeIndex < 0 then Pure () - else do - variableTypes <- retrieveVariableTypesAtScope scopeIndex - when (scopeIndex == 0) $ LiftIo $ updateArgumentsForUntyped variableTypes arity - variableIndices <- retrieveVariableIndicesByName scopeIndex - scope <- getScope scopeIndex - saveScope $ {allVariableTypes := variableTypes, allVariableIndices := variableIndices} scope - go (scopeIndex - 1) +createAsmState : AsmGlobalState -> Name -> IO AsmState +createAsmState globalState name = do + programName <- AsmGlobalState.getProgramName globalState + let jvmClassMethodName = getJvmClassMethodName programName name + createAsmStateJavaName globalState (className jvmClassMethodName) -getVariableScope : String -> Asm Scope -getVariableScope name = go !getCurrentScopeIndex where - go : Int -> Asm Scope - go scopeIndex = do - scope <- getScope scopeIndex - optTy <- LiftIo $ Map.get {value=InferredType} (variableTypes scope) name - case nullableToMaybe optTy of - Just _ => Pure scope - Nothing => case parentIndex scope of - Just parentScopeIndex => go parentScopeIndex - Nothing => asmCrash ("Unknown variable " ++ name) +%foreign jvm' "io/github/mmhelloworld/idrisjvm/runtime/Runtime" "waitForFuturesToComplete" "java/util/List" "void" +prim_waitForFuturesToComplete : List ThreadID -> PrimIO () export -addVariableType : String -> InferredType -> Asm InferredType -addVariableType var IUnknown = Pure IUnknown -addVariableType var ty = do - scope <- getVariableScope var - let scopeIndex = index scope - existingTy <- retrieveVariableTypeAtScope scopeIndex var - let newTy = existingTy <+> ty - _ <- LiftIo $ Map.put (variableTypes scope) var newTy - Pure newTy +waitForFuturesToComplete : List ThreadID -> IO () +waitForFuturesToComplete futures = primIO $ prim_waitForFuturesToComplete futures -%inline export -lambdaMaxCountPerMethod: Int -lambdaMaxCountPerMethod = 50 +log : Lazy String -> (result : a) -> a +log message val = + if shouldDebug + then unsafePerformIO $ do + time <- currentTimeString + threadName <- getCurrentThreadName + putStrLn (time ++ " [" ++ threadName ++ "]: " ++ message) + pure val + else val export -getLambdaImplementationMethodName : String -> Asm Jname -getLambdaImplementationMethodName namePrefix = do - lambdaIndex <- freshLambdaIndex - rootMethodJname <- getRootMethodName - let declaringMethodName = methodName rootMethodJname - let rootMethodClassName = className rootMethodJname - let lambdaClassName = - if lambdaIndex >= lambdaMaxCountPerMethod - then rootMethodClassName ++ "$" ++ namePrefix ++ "$" ++ declaringMethodName ++ "$" ++ show (lambdaIndex `div` 100) - else rootMethodClassName - let lambdaMethodName = - if lambdaIndex >= lambdaMaxCountPerMethod - then namePrefix ++ "$" ++ show lambdaIndex - else namePrefix ++ "$" ++ declaringMethodName ++ "$" ++ show lambdaIndex - Pure $ Jqualified lambdaClassName lambdaMethodName - -isBoolTySpec : Name -> Bool -isBoolTySpec name = name == basics "Bool" || name == (NS preludeNS (UN $ Basic "Bool")) +logAsm : {auto stateRef: Ref AsmState AsmState} -> Lazy String -> Core () +logAsm message = log message (pure ()) -mutual - tySpecFn : String -> InferredFunctionType - tySpecFn desc = case reverse $ toList $ String.split (== '⟶') desc of - [] => assert_total $ idris_crash ("Invalid function type descriptor: " ++ desc) - (returnTypeStr :: argsReversed) => - MkInferredFunctionType (tySpecStr returnTypeStr) (reverse $ (tySpecStr <$> argsReversed)) +public export +data FArgList : Type where + Nil : FArgList + (::) : {a : Type} -> (1 arg : a) -> (1 args : FArgList) -> FArgList - tySpecLambda : String -> JavaLambdaType - tySpecLambda desc = case toList $ String.split (== ',') desc of - [intfStr, method, methodTypeStr, implementationTypeStr] => - MkJavaLambdaType (tySpecStr intfStr) method (tySpecFn methodTypeStr) (tySpecFn implementationTypeStr) - _ => assert_total $ idris_crash ("Invalid lambda type descriptor: " ++ desc) +export +%extern prim__jvmInstance : (ret : Type) -> String -> (1 args : FArgList) -> (1 x : %World) -> IORes ret - tySpecStr : String -> InferredType - tySpecStr "Int" = IInt - tySpecStr "Int8" = IByte - tySpecStr "Int16" = IShort - tySpecStr "Int32" = IInt - tySpecStr "Int64" = ILong - tySpecStr "Integer" = inferredBigIntegerType - tySpecStr "String" = inferredStringType - tySpecStr "Double" = IDouble - tySpecStr "Char" = IChar - tySpecStr "Bool" = IBool - tySpecStr "long" = ILong - tySpecStr "void" = IVoid - tySpecStr "%World" = IInt - tySpecStr "[" = assert_total $ idris_crash "Invalid type descriptor: [" - tySpecStr "λ" = assert_total $ idris_crash "Invalid type descriptor: λ" - tySpecStr desc = - cond [(startsWith desc "[", IArray (tySpecStr (assert_total (strTail desc)))), - (startsWith desc "λ", IFunction (tySpecLambda (assert_total (strTail desc)))) - ] - (iref desc []) +export %inline +jvmInstance : (ret : Type) -> String -> (1 args : FArgList) -> IO ret +jvmInstance ret fn args = fromPrim (prim__jvmInstance ret fn args) export -structName : Name -structName = NS (mkNamespace "System.FFI") (UN $ Basic "Struct") +superName : Name +superName = NS (mkNamespace "Java.Lang") (UN $ Basic "super") export -arrayName : Name -arrayName = NS (mkNamespace "Java.Lang") (UN $ Basic "Array") +isSuperCall : Name -> List NamedCExp -> Bool +isSuperCall name + [(NmExtPrim fc f@(NS ns (UN (Basic "prim__jvmStatic"))) args@(ret :: NmPrimVal primFc (Str fn):: rest))] + = name == superName && endsWith "." fn +isSuperCall _ _ = False -getIdrisConstructorType : ConInfo -> (tag: Maybe Int) -> Nat -> Name -> InferredType -getIdrisConstructorType conInfo tag arity name = - if isBoolTySpec name then IBool - else if name == basics "List" then idrisListType - else if name == preludetypes "Maybe" then idrisMaybeType - else if name == preludetypes "Nat" then inferredBigIntegerType - else inferredObjectType +public export +%inline +methodStartLabel : String +methodStartLabel = "methodStartLabel" -parseName : String -> Maybe InferredType -parseName name = - case words name of - (interfaceName :: methodName :: _) => Just $ IRef interfaceName Interface [] - (className :: []) => Just $ iref className [] - _ => Nothing +public export +%inline +methodEndLabel : String +methodEndLabel = "methodEndLabel" -mutual - parseArrayType : NamedCExp -> Asm (Maybe InferredType) - parseArrayType expr@(NmCon _ name _ _ [elemTy]) = - if name == arrayName then Pure . Just $ IArray !(tySpec elemTy) - else Pure Nothing - parseArrayType _ = Pure Nothing +%foreign "jvm:.invokeMethod(io/github/mmhelloworld/idrisjvm/assembler/Assembler int String String String boolean void),io/github/mmhelloworld/idrisjvm/assembler/Assembler" +asmInvokeMethod : Assembler -> Int -> (className: String) -> (methodName: String) -> (descriptor: String) -> Bool -> PrimIO () - parseLambdaType : NamedCExp -> Asm (Maybe InferredType) - parseLambdaType (NmCon _ name _ _ [interfaceType, _]) = - if name == builtin "Pair" then parseJvmReferenceType interfaceType - else Pure Nothing - parseLambdaType _ = Pure Nothing +%foreign "jvm:.classCodeStart" +asmClassCodeStart : Assembler -> (version: Int) -> (access: Int) -> (className: String) -> (sig: String) + -> (parent: String) -> (intf: JList String) -> (anns: JList JAnnotation) -> PrimIO () - parseJvmReferenceType : NamedCExp -> Asm (Maybe InferredType) - parseJvmReferenceType (NmCon _ name _ _ (NmPrimVal _ (Str namePartsStr) :: _)) = - if name == structName - then Pure $ parseName namePartsStr - else Pure Nothing - parseJvmReferenceType (NmCon _ name conInfo tag args) = - if name == primio "IORes" then - maybe (asmCrash "Expected an argument for IORes") (\res => Pure $ Just !(tySpec res)) (head' args) - else Pure $ Just $ getIdrisConstructorType conInfo tag (length args) name - parseJvmReferenceType (NmApp fc (NmRef _ name) _) = do - (_, MkNmFun _ def) <- getFcAndDefinition (jvmSimpleName name) - | _ => asmCrash ("Expected a function returning a tuple containing interface type and method type at " ++ - show fc) - ty <- tySpec def - Pure $ Just ty - parseJvmReferenceType (NmDelay _ _ expr) = Pure $ Just !(tySpec expr) - parseJvmReferenceType expr = Pure Nothing +%foreign "jvm:.createClass" +asmCreateClass : Assembler -> Int -> PrimIO () - tryParse : NamedCExp -> Asm (Maybe InferredType) - tryParse expr = do - arrayTypeMaybe <- parseArrayType expr - case arrayTypeMaybe of - Nothing => do - lambdaTypeMaybe <- parseLambdaType expr - case lambdaTypeMaybe of - Nothing => parseJvmReferenceType expr - Just lambdaType => Pure $ Just lambdaType - Just arrayType => Pure $ Just arrayType +%foreign "jvm:.createField" +asmCreateField : Assembler -> (access: Int) -> (sourceFileName: String) -> (className: String) -> (fieldName: String) + -> (descriptor: String) -> (signature: String) -> (initialValue: Object) + -> (annotations: JList JAnnotation) -> PrimIO () - export - tySpec : NamedCExp -> Asm InferredType - tySpec (NmCon _ (UN (Basic ty)) _ _ []) = Pure $ tySpecStr ty - tySpec (NmCon _ _ NOTHING _ []) = Pure idrisMaybeType - tySpec (NmCon _ _ JUST _ [_]) = Pure idrisMaybeType - tySpec (NmCon _ _ NIL _ []) = Pure idrisListType - tySpec (NmCon _ _ CONS _ [_, _]) = Pure idrisListType - tySpec expr@(NmCon _ (NS _ (UN (Basic "Unit"))) _ _ []) = Pure IVoid - tySpec expr = do - ty <- tryParse expr - Pure $ fromMaybe inferredObjectType ty +%foreign "jvm:.createMethod" +asmCreateMethod : Assembler -> (access: Int) -> (sourceFileName: String) -> (className: String) -> + (methodName: String) -> (descriptor: String) -> + (signature: String) -> (exceptions: JList String) -> + (annotations: JList JAnnotation) -> + (parameterAnnotations: JList (JList JAnnotation)) -> PrimIO () -export -getJvmTypeDescriptor : InferredType -> String -getJvmTypeDescriptor IByte = "B" -getJvmTypeDescriptor IChar = "C" -getJvmTypeDescriptor IShort = "S" -getJvmTypeDescriptor IBool = "Z" -getJvmTypeDescriptor IDouble = "D" -getJvmTypeDescriptor IFloat = "F" -getJvmTypeDescriptor IInt = "I" -getJvmTypeDescriptor ILong = "J" -getJvmTypeDescriptor IVoid = "V" -getJvmTypeDescriptor (IRef ty _ _) = "L" ++ ty ++ ";" -getJvmTypeDescriptor (IArray ty) = "[" ++ getJvmTypeDescriptor ty -getJvmTypeDescriptor (IFunction lambdaType) = getJvmTypeDescriptor (lambdaType.javaInterface) -getJvmTypeDescriptor IUnknown = getJvmTypeDescriptor inferredObjectType +%foreign "jvm:.createIdrisConstructorClass(io/github/mmhelloworld/idrisjvm/assembler/Assembler String boolean int void),io/github/mmhelloworld/idrisjvm/assembler/Assembler" +asmCreateIdrisConstructorClass : Assembler -> String -> Bool -> Int -> PrimIO () -export -getJvmReferenceTypeName : InferredType -> Asm String -getJvmReferenceTypeName (IRef ty _ _) = Pure ty -getJvmReferenceTypeName (IArray (IRef ty _ _)) = Pure ("[L" ++ ty ++ ";") -getJvmReferenceTypeName (IArray ty) = Pure ("[" ++ !(getJvmReferenceTypeName ty)) -getJvmReferenceTypeName (IFunction lambdaType) = getJvmReferenceTypeName (lambdaType.javaInterface) -getJvmReferenceTypeName ty = asmCrash ("Expected a reference type but found " ++ show ty) +%foreign "jvm:.field" +asmField : Assembler -> Int -> (className: String) -> (fieldName: String) -> (descriptor: String) -> PrimIO () -export -getSignature : InferredType -> String -getSignature (IRef ty _ typeParams@(_ :: _)) = - let typeParamsDescriptor = concat (getJvmTypeDescriptor <$> typeParams) - in "L" ++ ty ++ "<" ++ typeParamsDescriptor ++ ">;" -getSignature type = getJvmTypeDescriptor type +%foreign "jvm:.frame" +asmFrame : Assembler -> Int -> Int -> (signatures: JList String) -> Int -> (signatures: JList String) -> PrimIO () -export -asmReturn : InferredType -> Asm () -asmReturn IVoid = Return -asmReturn IBool = Ireturn -asmReturn IByte = Ireturn -asmReturn IShort = Ireturn -asmReturn IInt = Ireturn -asmReturn IChar = Ireturn -asmReturn ILong = Lreturn -asmReturn IFloat = Freturn -asmReturn IDouble = Dreturn -asmReturn _ = Areturn +%foreign "jvm:.localVariable" +asmLocalVariable : Assembler -> (name: String) -> (descriptor: String) -> (signature: String) -> (startLabel: String) + -> (endLabel: String) -> (index: Int) -> PrimIO () -export --- constant values from org.objectweb.asm.Opcodes -accessNum : Access -> Int -accessNum Public = 0x0001 -accessNum Private = 0x0002 -accessNum Protected = 0x0004 -accessNum Static = 0x0008 -accessNum Final = 0x0010 -accessNum Interface = 0x0200 -accessNum Abstract = 0x0400 -accessNum Synthetic = 0x1000 -accessNum Transient = 0x0080 +%foreign "jvm:.lookupSwitch" +asmLookupSwitch : Assembler -> (defaultLabel: String) -> (labels: JList String) -> (cases: JList Int) -> PrimIO () -export -fieldInsTypeNum : FieldInstructionType -> Int -fieldInsTypeNum GetStatic = 178 -fieldInsTypeNum PutStatic = 179 -fieldInsTypeNum GetField = 180 -fieldInsTypeNum PutField = 181 +%foreign "jvm:.maxStackAndLocal" +asmMaxStackAndLocal : Assembler -> Int -> Int -> PrimIO () -export -frameTypeNum : FrameType -> Int -frameTypeNum Full = 0 -frameTypeNum Same = 3 -frameTypeNum Append = 1 +parameters {auto state: Ref AsmState AsmState} + public export + %inline + aaload : Core () -export -invocTypeNum : InvocationType -> Int -invocTypeNum InvokeInterface = 185 -invocTypeNum InvokeSpecial = 183 -invocTypeNum InvokeStatic = 184 -invocTypeNum InvokeVirtual = 182 + public export + %inline + aastore : Core () + + public export + %inline + aconstnull : Core () + + public export + %inline + aload : Int -> Core () + + public export + %inline + anewarray : (descriptor: String) -> Core () + + public export + %inline + anewbooleanarray : Core () + + public export + %inline + anewbytearray : Core () + + public export + %inline + anewchararray : Core () + + public export + %inline + anewshortarray : Core () + + public export + %inline + anewintarray : Core () + + public export + %inline + anewlongarray : Core () + + public export + %inline + anewfloatarray : Core () + + public export + %inline + anewdoublearray : Core () + + public export + %inline + arraylength : Core () + + public export + %inline + areturn : Core () + + public export + %inline + astore : Int -> Core () + + public export + %inline + baload : Core () + + public export + %inline + bastore : Core () + + public export + %inline + caload : Core () + + public export + %inline + castore : Core () + + public export + %inline + checkcast : (descriptor: String) -> Core () + + public export + %inline + classCodeStart : Int -> List Access -> (className: String) -> (signature: Maybe String) -> (parentClassName: String) -> + (interfaces: List String) -> List Asm.Annotation -> Core () + + public export + %inline + createClass : List ClassOpts -> Core () + + public export + %inline + createField : List Access -> (sourceFileName: String) -> (className: String) -> (fieldName: String) -> (descriptor: String) -> + (signature: Maybe String) -> Maybe FieldInitialValue -> (annotations: List Asm.Annotation) -> Core () + + public export + %inline + createLabel : String -> Core () + + public export + %inline + createMethod : List Access -> (sourceFileName: String) -> (className: String) -> + (methodName: String) -> (descriptor: String) -> + (signature: Maybe String) -> (exceptions: Maybe (List String)) -> + (annotations: List Asm.Annotation) -> + (parameterAnnotations: List (List Asm.Annotation)) -> Core () + + public export + %inline + createIdrisConstructorClass : String -> Bool -> Int -> Core () + + public export + %inline + d2i : Core () + + public export + %inline + d2f : Core () + + public export + %inline + d2l : Core () + + public export + %inline + dadd : Core () + + public export + %inline + daload : Core () + + public export + %inline + dastore : Core () + + public export + %inline + dcmpg : Core () + + public export + %inline + dcmpl : Core () + + public export + %inline + dconst : Double -> Core () + + public export + %inline + ddiv : Core () + + public export + %inline + debug : String -> Core () + + public export + %inline + dload : Int -> Core () + + public export + %inline + dmul : Core () + + public export + %inline + dneg : Core () + + public export + %inline + drem : Core () + + public export + %inline + dreturn : Core () + + public export + %inline + dstore : Int -> Core () + + public export + %inline + dsub : Core () + + public export + %inline + dup : Core () + + public export + %inline + f2d : Core () + + public export + %inline + faload : Core () + + public export + %inline + fastore : Core () + + public export + %inline + fconst : Double -> Core () + + public export + %inline + field : FieldInstructionType -> (className: String) -> (fieldName: String) -> (descriptor: String) -> Core () + + public export + %inline + fieldEnd : Core () + + public export + %inline + fload : Int -> Core () + + public export + %inline + frame : FrameType -> Int -> (signatures: List String) -> Int -> (signatures: List String) -> Core () + + public export + %inline + freturn : Core () + + public export + %inline + fstore : Int -> Core () + + public export + %inline + goto : (label: String) -> Core () + + public export + %inline + i2b : Core () + + public export + %inline + i2c : Core () + + public export + %inline + i2d : Core () + + public export + %inline + i2l : Core () + + public export + %inline + i2s : Core () + + public export + %inline + iadd : Core () + + public export + %inline + iaload : Core () + + public export + %inline + iand : Core () + + public export + %inline + iastore : Core () + + public export + %inline + ior : Core () + + public export + %inline + ixor : Core () + + public export + %inline + icompl : Core () + + public export + %inline + iconst : Int -> Core () + + public export + %inline + idiv : Core () + + public export + %inline + ifeq : (label: String) -> Core () + + public export + %inline + ifge : (label: String) -> Core () + + public export + %inline + ifgt : (label: String) -> Core () + + public export + %inline + ificmpge : (label: String) -> Core () + + public export + %inline + ificmpgt : (label: String) -> Core () + + public export + %inline + ificmple : (label: String) -> Core () + + public export + %inline + ificmplt : (label: String) -> Core () + + public export + %inline + ificmpeq : (label: String) -> Core () + + public export + %inline + ifacmpne : (label: String) -> Core () + + public export + %inline + ificmpne : (label: String) -> Core () + + public export + %inline + ifle : (label: String) -> Core () + + public export + %inline + iflt : (label: String) -> Core () + + public export + %inline + ifne : (label: String) -> Core () + + public export + %inline + ifnonnull : (label: String) -> Core () + + public export + %inline + ifnull : (label: String) -> Core () + + public export + %inline + iload : Int -> Core () + + public export + %inline + imul : Core () + + public export + %inline + ineg : Core () + + public export + %inline + instanceOf : (className: String) -> Core () + + public export + %inline + invokeMethod : InvocationType -> (className: String) -> (methodName: String) -> (descriptor: String) + -> Bool -> Core () + public export + %inline + invokeDynamic : (methodName: String) -> (descriptor: String) -> Handle -> List BsmArg -> Core () + + public export + %inline + irem : Core () + + public export + %inline + ireturn : Core () + + public export + %inline + ishl : Core () + + public export + %inline + ishr : Core () + + public export + %inline + istore : Int -> Core () + + public export + %inline + isub : Core () + + public export + %inline + iushr : Core () + + public export + %inline + l2d : Core () + + public export + %inline + l2i : Core () + + public export + %inline + labelStart : (label: String) -> Core () + + public export + %inline + ladd : Core () + + public export + %inline + laload : Core () + + public export + %inline + land : Core () + + public export + %inline + lastore : Core () + + public export + %inline + lcmp : Core () + + public export + %inline + lcompl : Core () + + public export + %inline + ldc : Constant -> Core () + + public export + %inline + ldiv : Core () + + public export + %inline + lineNumber : Int -> String -> Core () + + public export + %inline + lload : Int -> Core () + + public export + %inline + lmul : Core () + + public export + %inline + lneg : Core () + + public export + %inline + localVariable : (name: String) -> (descriptor: String) -> (signature: Maybe String) -> (startLabel: String) -> + (endLabel: String) -> (index: Int) -> Core () + + public export + %inline + lookupSwitch : (defaultLabel: String) -> (labels: List String) -> (cases: List Int) -> Core () + + public export + %inline + lor : Core () + + public export + %inline + lrem : Core () + + public export + %inline + lreturn : Core () + + public export + %inline + lshl : Core () + + public export + %inline + lshr : Core () + + public export + %inline + lstore : Int -> Core () + + public export + %inline + lsub : Core () + + public export + %inline + lushr : Core () + + public export + %inline + lxor : Core () + + public export + %inline + maxStackAndLocal : Int -> Int -> Core () + + public export + %inline + methodCodeStart : Core () + + public export + %inline + methodCodeEnd : Core () + + public export + %inline + multianewarray : (descriptor: String) -> Int -> Core () + + public export + %inline + new : (className: String) -> Core () + + public export + %inline + pop : Core () + + public export + %inline + pop2 : Core () + + public export + %inline + return : Core () + + public export + %inline + saload : Core () + + public export + %inline + sastore : Core () + + public export + %inline + sourceInfo : (sourceFileName: String) -> Core () + + public export + %inline + getState : Core AsmState + + public export + %inline + setState : AsmState -> Core () + + aaload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aaload" [assembler state] + + aastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aastore" [assembler state] + + aconstnull = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aconstnull" [assembler state] + + aload n = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aload" [assembler state, n] + + anewarray desc = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewarray" [assembler state, desc] + anewintarray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewintarray" [assembler state] + anewbooleanarray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewbooleanarray" [assembler state] + anewbytearray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewbytearray" [assembler state] + anewchararray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewchararray" [assembler state] + anewshortarray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewshortarray" [assembler state] + anewlongarray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewlongarray" [assembler state] + anewfloatarray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewfloatarray" [assembler state] + anewdoublearray = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewdoublearray" [assembler state] + arraylength = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.arraylength" [assembler state] + areturn = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.areturn" [assembler state] + astore n = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.astore" [assembler state, n] + baload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.baload" [assembler state] + bastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.bastore" [assembler state] + caload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.caload" [assembler state] + castore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.castore" [assembler state] + checkcast desc = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.checkcast" [assembler state, desc] + + classCodeStart version access className sig parent intf anns = do + state <- get AsmState + coreLift $ do + janns <- sequence $ toJAnnotation <$> anns + primIO $ asmClassCodeStart (assembler state) version (sum $ accessNum <$> access) className (maybeToNullable sig) parent + (the (JList String) $ believe_me intf) (the (JList JAnnotation) $ believe_me janns) + + createClass opts = do + state <- getState + coreLift $ primIO $ asmCreateClass (assembler state) (sum $ toJClassOpts <$> opts) + + createField accs sourceFileName className fieldName desc sig fieldInitialValue anns = do + state <- get AsmState + coreLift $ do + let jaccs = sum $ accessNum <$> accs + janns <- sequence $ toJAnnotation <$> anns + primIO $ asmCreateField + (assembler state) jaccs sourceFileName className fieldName desc (maybeToNullable sig) + (maybeToNullable (toJFieldInitialValue <$> fieldInitialValue)) (the (JList JAnnotation) $ believe_me janns) + + createLabel label = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.createLabel" [assembler state, label] + + createMethod accs sourceFileName className methodName desc sig exceptions anns paramAnns = do + state <- get AsmState + put AsmState ({ currentMethodName := Jqualified className methodName } state) + coreLift $ do + let jaccs = sum $ accessNum <$> accs + janns <- sequence $ toJAnnotation <$> anns + jparamAnns <- sequence $ (\paramAnn => sequence $ toJAnnotation <$> paramAnn) <$> paramAnns + primIO $ asmCreateMethod + (assembler state) jaccs sourceFileName className methodName desc (maybeToNullable sig) + (the (JList String) $ believe_me $ maybeToNullable exceptions) + (the (JList JAnnotation) $ believe_me janns) (the (JList (JList JAnnotation)) $ believe_me jparamAnns) + + createIdrisConstructorClass className isStringConstructor constructorParameterCount = do + state <- getState + coreLift $ primIO $ asmCreateIdrisConstructorClass (assembler state) className isStringConstructor + constructorParameterCount + + d2i = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.d2i" [assembler state] + d2f = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.d2f" [assembler state] + d2l = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.d2l" [assembler state] + dadd = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dadd" [assembler state] + dcmpg = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dcmpg" [assembler state] + dcmpl = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dcmpl" [assembler state] + dconst n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dconst" [assembler state, n] + daload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.daload" [assembler state] + dastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dastore" [assembler state] + ddiv = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ddiv" [assembler state] + debug message = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.debug" + [assembler state, message] + dload n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dload" [assembler state, n] + dmul = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dmul" [assembler state] + dneg = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dneg" [assembler state] + drem = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.drem" [assembler state] + dreturn = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dreturn" [assembler state] + dstore n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dstore" [assembler state, n] + dsub = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dsub" [assembler state] + dup = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dup" [assembler state] + f2d = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.f2d" [assembler state] + faload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.faload" [assembler state] + fastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fastore" [assembler state] + fconst n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fconst" [assembler state, n] + field finsType cname fname desc = do + state <- get AsmState + coreLift $ do + let finsTypeNum = fieldInsTypeNum finsType + primIO $ asmField (assembler state) finsTypeNum cname fname desc + + fieldEnd = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fieldEnd" [assembler state] + + fload n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fload" [assembler state, n] + + frame frameType nLocal localSigs nStack stackSigs = do + state <- get AsmState + coreLift $ do + let ftypeNum = frameTypeNum frameType + primIO $ asmFrame + (assembler state) ftypeNum nLocal (the (JList String) $ believe_me localSigs) nStack + (the (JList String) $ believe_me stackSigs) + + freturn = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.freturn" [assembler state] + fstore n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fstore" [assembler state, n] + + goto label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.gotoLabel" + [assembler state, label] + + i2b = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2b" [assembler state] + i2c = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2c" [assembler state] + i2d = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2d" [assembler state] + i2l = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2l" [assembler state] + i2s = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2s" [assembler state] + iadd = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iadd" [assembler state] + iaload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iaload" [assembler state] + iand = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iand" [assembler state] + iastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iastore" [assembler state] + ior = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ior" [assembler state] + ixor = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ixor" [assembler state] + icompl = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.icompl" [assembler state] + iconst n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iconst" [assembler state, n] + idiv = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.idiv" [assembler state] + ifeq label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifeq" [assembler state, label] + ifge label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifge" [assembler state, label] + ifgt label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifgt" [assembler state, label] + ificmpge label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpge" [assembler state, label] + ificmpgt label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpgt" [assembler state, label] + ificmple label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmple" [assembler state, label] + ificmplt label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmplt" [assembler state, label] + ificmpeq label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpeq" [assembler state, label] + ifacmpne label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifacmpne" [assembler state, label] + ificmpne label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpne" [assembler state, label] + ifle label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifle" [assembler state, label] + iflt label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iflt" [assembler state, label] + ifne label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifne" [assembler state, label] + ifnonnull label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifnonnull" [assembler state, label] + ifnull label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifnull" [assembler state, label] + iload n = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iload" [assembler state, n] + imul = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.imul" [assembler state] + ineg = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ineg" [assembler state] + instanceOf className = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.instanceOf" [assembler state, className] + invokeMethod invocType cname mname desc isIntf = do + state <- get AsmState + + coreLift $ do + let invocTypeAsm = invocTypeNum invocType + primIO $ asmInvokeMethod (assembler state) invocTypeAsm cname mname desc isIntf + + invokeDynamic mname desc handle bsmArgs = do + state <- get AsmState + coreLift $ do + jbsmArgsList <- sequence $ toJbsmArg <$> bsmArgs + jhandle <- toJHandle handle + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.invokeDynamic" + [assembler state, mname, desc, jhandle, the (JList JBsmArg) $ believe_me jbsmArgsList] + + irem = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.irem" [assembler state] + ireturn = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ireturn" [assembler state] + ishl = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ishl" [assembler state] + ishr = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ishr" [assembler state] + istore n = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.istore" [assembler state, n] + isub = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.isub" [assembler state] + iushr = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iushr" [assembler state] + l2d = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.l2d" [assembler state] + l2i = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.l2i" [assembler state] + labelStart label = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.labelStart" [assembler state, label] + ladd = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ladd" [assembler state] + land = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.land" [assembler state] + laload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.laload" [assembler state] + lastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lastore" [assembler state] + lcmp = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lcmp" [assembler state] + lor = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lor" [assembler state] + lxor = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lxor" [assembler state] + lcompl = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lcompl" [assembler state] + + ldc (TypeConst ty) = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ldcType" [assembler state, ty] + ldc constant = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ldc" [assembler state, constantToObject constant] + + ldiv = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ldiv" [assembler state] + + lineNumber number label = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lineNumber" [assembler state, number, label] + + lload n = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lload" [assembler state, n] + lmul = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lmul" [assembler state] + lneg = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lneg" [assembler state] + lookupSwitch defaultLabel labels cases = do + state <- get AsmState + coreLift $ do + let jcases = integerValueOf <$> cases + primIO $ asmLookupSwitch + (assembler state) defaultLabel (the (JList String) $ believe_me labels) (the (JList Int) $ believe_me jcases) + + localVariable name descriptor signature startLabel endLabel index = do + state <- get AsmState + coreLift $ primIO $ asmLocalVariable + (assembler state) name descriptor (maybeToNullable signature) startLabel endLabel index + + lrem = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lrem" [assembler state] + lreturn = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lreturn" [assembler state] + lshl = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lshl" [assembler state] + lshr = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lshr" [assembler state] + lstore n = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lstore" [assembler state, n] + lsub = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lsub" [assembler state] + lushr = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lushr" [assembler state] + maxStackAndLocal stack local = do + state <- getState + coreLift $ primIO $ asmMaxStackAndLocal (assembler state) stack local + methodCodeStart = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.methodCodeStart" [assembler state] + methodCodeEnd = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.methodCodeEnd" [assembler state] + multianewarray desc dims = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.multiANewArray" [assembler state, desc, dims] + new cname = do + state <- getState + coreLift $ + jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.asmNew" [assembler state, cname] + pop = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.pop" [assembler state] + pop2 = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.pop2" [assembler state] + return = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.voidReturn" [assembler state] + saload = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.saload" [assembler state] + sastore = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.sastore" [assembler state] + sourceInfo sourceFileName = do + state <- getState + coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.sourceInfo" [assembler state, sourceFileName] + + getState = get AsmState + setState newState = put AsmState newState + +export +updateState : {auto stateRef: Ref AsmState AsmState} -> (AsmState -> AsmState) -> Core () +updateState = update AsmState + +getAndUpdateState : {auto stateRef: Ref AsmState AsmState} -> (AsmState -> AsmState) -> Core AsmState +getAndUpdateState f = do + state <- getState + updateState f + pure state export -handleTagOpcode : HandleTag -> Int -handleTagOpcode GetField = 1 -handleTagOpcode GetStatic = 2 -handleTagOpcode PutField = 3 -handleTagOpcode PutStatic = 4 -handleTagOpcode InvokeVirtual = 5 -handleTagOpcode InvokeStatic = 6 -handleTagOpcode InvokeSpecial = 7 -handleTagOpcode NewInvokeSpecial = 8 -handleTagOpcode InvokeInterface = 9 +loadBigInteger : {auto stateRef: Ref AsmState AsmState} -> Integer -> Core () +loadBigInteger 0 = field GetStatic "java/math/BigInteger" "ZERO" "Ljava/math/BigInteger;" +loadBigInteger 1 = field GetStatic "java/math/BigInteger" "ONE" "Ljava/math/BigInteger;" +loadBigInteger 10 = field GetStatic "java/math/BigInteger" "TEN" "Ljava/math/BigInteger;" +loadBigInteger value = do + new "java/math/BigInteger" + dup + ldc $ StringConst $ show value + invokeMethod InvokeSpecial "java/math/BigInteger" "" "(Ljava/lang/String;)V" False -%foreign - jvm' "java/lang/Integer" "valueOf" "int" "java/lang/Integer" export -integerValueOf : Int -> JInteger +asmInvokeDynamic : {auto stateRef: Ref AsmState AsmState} -> (implClassName: String) -> (implMethodName: String) + -> (interfaceMethodName: String) -> (invokeDynamicDesc: String) -> (samDesc: String) + -> (implMethodDesc: String) -> (instantiatedMethodDesc: String) -> Core () +asmInvokeDynamic implClassName implMethodName interfaceMethodName invokeDynamicDesc samDesc implMethodDesc + instantiatedMethodDesc = + let metafactoryHandle = MkHandle InvokeStatic "java/lang/invoke/LambdaMetafactory" "metafactory" + metafactoryDesc False + implMethodHandle = MkHandle InvokeStatic implClassName implMethodName implMethodDesc False + metafactoryArgs = [ BsmArgGetType samDesc + , BsmArgHandle implMethodHandle + , BsmArgGetType instantiatedMethodDesc + ] + in invokeDynamic interfaceMethodName invokeDynamicDesc metafactoryHandle metafactoryArgs -%foreign - jvm' "java/lang/Double" "valueOf" "double" "java/lang/Double" export -doubleValueOf : Double -> JDouble +newBigInteger : {auto stateRef: Ref AsmState AsmState} -> String -> Core () +newBigInteger "0" = field GetStatic "java/math/BigInteger" "ZERO" "Ljava/math/BigInteger;" +newBigInteger "1" = field GetStatic "java/math/BigInteger" "ONE" "Ljava/math/BigInteger;" +newBigInteger "10" = field GetStatic "java/math/BigInteger" "TEN" "Ljava/math/BigInteger;" +newBigInteger i = do + new "java/math/BigInteger" + dup + ldc $ StringConst i + invokeMethod InvokeSpecial "java/math/BigInteger" "" "(Ljava/lang/String;)V" False -%foreign - jvm' "java/lang/Long" "valueOf" "long" "java/lang/Long" export -bits64ToJLong : Bits64 -> JLong +getGlobalState : {auto stateRef: Ref AsmState AsmState} -> Core AsmGlobalState +getGlobalState = pure $ globalState !getState -%foreign - jvm' "java/lang/Long" "valueOf" "long" "java/lang/Long" export -int64ToJLong : Int64 -> JLong +findFunction : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core (Maybe Function) +findFunction name = coreLift $ AsmGlobalState.findFunction !getGlobalState name export -constantToObject : Asm.Constant -> Object -constantToObject (DoubleConst d) = believe_me $ doubleValueOf d -constantToObject (IntegerConst n) = believe_me $ integerValueOf n -constantToObject (Int64Const n) = believe_me $ int64ToJLong n -constantToObject (Bits64Const n) = believe_me $ bits64ToJLong n -constantToObject (StringConst str) = believe_me str -constantToObject (TypeConst str) = believe_me str - -toJClassOpts : ClassOpts -> Int -toJClassOpts ComputeMaxs = 1 -toJClassOpts ComputeFrames = 2 - -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/JHandle" "" - "int String String String boolean" - "io/github/mmhelloworld/idrisjvm/assembler/JHandle" -prim_newJHandle : Int -> String -> String -> String -> Bool -> PrimIO JHandle - -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgHandle" "" - "io/github/mmhelloworld/idrisjvm/assembler/JHandle" - "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgHandle" -prim_newJBsmArgHandle : JHandle -> PrimIO JBsmArgHandle - -%inline -newJBsmArgHandle : HasIO io => JHandle -> io JBsmArgHandle -newJBsmArgHandle = primIO . prim_newJBsmArgHandle - -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgGetType" "" - "String" - "io/github/mmhelloworld/idrisjvm/assembler/JBsmArg$JBsmArgGetType" -prim_newJBsmArgGetType : String -> PrimIO JBsmArgGetType +getFunction : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core Function +getFunction name = maybe (asmCrash $ "Unknown function " ++ show name) pure!(findFunction name) -%inline -newJBsmArgGetType : HasIO io => String -> io JBsmArgGetType -newJBsmArgGetType = primIO . prim_newJBsmArgGetType +export +getCurrentFunction : {auto stateRef: Ref AsmState AsmState} -> Core Function +getCurrentFunction = currentIdrisFunction <$> getState -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnString" "" - "String" - "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnString" -prim_newJAnnString : String -> PrimIO JAnnString +export +getProgramName : {auto stateRef: Ref AsmState AsmState} -> Core String +getProgramName = coreLift $ AsmGlobalState.getProgramName !getGlobalState -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnEnum" "" - "String String" - "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnEnum" -prim_newJAnnEnum : String -> String -> PrimIO JAnnEnum +export +getFcAndDefinition : {auto stateRef: Ref AsmState AsmState} -> String -> Core (FC, NamedDef) +getFcAndDefinition name = coreLift $ AsmGlobalState.getFcAndDefinition !getGlobalState name -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnInt" "" - "int" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnInt" -prim_newJAnnInt : Int -> PrimIO JAnnInt +export +isUntypedFunction : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core Bool +isUntypedFunction name = coreLift $ AsmGlobalState.isUntypedFunction !getGlobalState name -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnBoolean" "" - "boolean" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnBoolean" -prim_newJAnnBoolean : Bool -> PrimIO JAnnBoolean +export +addUntypedFunction : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core () +addUntypedFunction name = coreLift $ AsmGlobalState.addUntypedFunction !getGlobalState name -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnChar" "" - "char" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnChar" -prim_newJAnnChar : Char -> PrimIO JAnnChar +export +setCurrentFunction : {auto stateRef: Ref AsmState AsmState} -> Function -> Core () +setCurrentFunction function = updateState $ { currentIdrisFunction := function } -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnDouble" "" - "double" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnDouble" -prim_newJAnnDouble : Double -> PrimIO JAnnDouble +getAndUpdateFunction : {auto stateRef: Ref AsmState AsmState} -> (Function -> Function) -> Core Function +getAndUpdateFunction f = do + function <- getCurrentFunction + let newFunction = f function + setCurrentFunction newFunction + globalState <- getGlobalState + coreLift $ addFunction globalState (idrisName newFunction) newFunction + pure function -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnClass" "" - "String" "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnClass" -prim_newJAnnClass : String -> PrimIO JAnnClass +export +updateCurrentFunction : {auto stateRef: Ref AsmState AsmState} -> (Function -> Function) -> Core () +updateCurrentFunction f = ignore $ getAndUpdateFunction f -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnAnnotation" "" - "io/github/mmhelloworld/idrisjvm/assembler/Annotation" - "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnAnnotation" -prim_newJAnnAnnotation : JAnnotation -> PrimIO JAnnAnnotation +export +loadFunction : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core () +loadFunction idrisName = do + function <- getFunction idrisName + updateState $ { currentIdrisFunction := function } -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnArray" "" - "java/util/List" - "io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue$AnnArray" -prim_newJAnnArray : JList JAnnotationValue -> PrimIO JAnnArray +export +getFunctionType : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core InferredFunctionType +getFunctionType name = inferredFunctionType <$> (getFunction name) -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/AnnotationProperty" "" - "String io/github/mmhelloworld/idrisjvm/assembler/AnnotationValue" - "io/github/mmhelloworld/idrisjvm/assembler/AnnotationProperty" -prim_newJAnnotationProperty : String -> JAnnotationValue -> PrimIO JAnnotationProperty +export +getFunctionParameterTypes : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core (List InferredType) +getFunctionParameterTypes functionName = do + functionType <- getFunctionType functionName + pure $ parameterTypes functionType -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/Annotation" "" - "String java/util/List" - "io/github/mmhelloworld/idrisjvm/assembler/Annotation" -prim_newJAnnotation : String -> JList JAnnotationProperty -> PrimIO JAnnotation +export +findFunctionType : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core (Maybe InferredFunctionType) +findFunctionType functionName = do + state <- getState + function <- findFunction functionName + pure $ inferredFunctionType <$> function export -toJHandle : HasIO io => Handle -> io JHandle -toJHandle (MkHandle tag hcname hmname hdesc hIsIntf) = do - let tagNum = handleTagOpcode tag - primIO $ prim_newJHandle tagNum hcname hmname hdesc hIsIntf +getFunctionReturnType : {auto stateRef: Ref AsmState AsmState} -> Jname -> Core InferredType +getFunctionReturnType functionName = do + state <- getState + function <- findFunction functionName + pure $ maybe IUnknown (returnType . inferredFunctionType) $ function export -toJbsmArg : HasIO io => BsmArg -> io JBsmArg -toJbsmArg (BsmArgGetType desc) = believe_me <$> newJBsmArgGetType desc -toJbsmArg (BsmArgHandle handle) = do - jhandle <- toJHandle handle - believe_me <$> newJBsmArgHandle jhandle +getCurrentScopeIndex : {auto stateRef: Ref AsmState AsmState} -> Core Int +getCurrentScopeIndex = currentScopeIndex <$> getState -mutual - toJAnnotationValue : HasIO io => Asm.AnnotationValue -> io JAnnotationValue - toJAnnotationValue (AnnString s) = believe_me <$> primIO (prim_newJAnnString s) - toJAnnotationValue (AnnEnum enum s) = believe_me <$> primIO (prim_newJAnnEnum enum s) - toJAnnotationValue (AnnInt n) = believe_me <$> primIO (prim_newJAnnInt n) - toJAnnotationValue (AnnBoolean n) = believe_me <$> primIO (prim_newJAnnBoolean n) - toJAnnotationValue (AnnChar n) = believe_me <$> primIO (prim_newJAnnChar n) - toJAnnotationValue (AnnDouble n) = believe_me <$> primIO (prim_newJAnnDouble n) - toJAnnotationValue (AnnClass n) = believe_me <$> primIO (prim_newJAnnClass n) - toJAnnotationValue (AnnAnnotation n) = do - jAnn <- toJAnnotation n - believe_me <$> primIO (prim_newJAnnAnnotation jAnn) - toJAnnotationValue (AnnArray values) = - believe_me <$> primIO (prim_newJAnnArray $ subtyping !(traverse toJAnnotationValue values)) +export +updateCurrentScopeIndex : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () +updateCurrentScopeIndex scopeIndex = updateState $ { currentScopeIndex := scopeIndex } - toJAnnotationProperty : HasIO io => Asm.AnnotationProperty -> io JAnnotationProperty - toJAnnotationProperty (name, annValue) = do - jAnnotationValue <- toJAnnotationValue annValue - primIO $ prim_newJAnnotationProperty name jAnnotationValue +export +newScopeIndex : {auto stateRef: Ref AsmState AsmState} -> Core Int +newScopeIndex = scopeCounter <$> (getAndUpdateState $ {scopeCounter $= (+1)}) - toJAnnotation : HasIO io => Asm.Annotation -> io JAnnotation - toJAnnotation (MkAnnotation name props) = do - properties <- traverse toJAnnotationProperty props - primIO $ prim_newJAnnotation name $ believe_me properties +export +newDynamicVariableIndex : {auto stateRef: Ref AsmState AsmState} -> Core Int +newDynamicVariableIndex = dynamicVariableCounter <$> (getAndUpdateFunction $ {dynamicVariableCounter $= (+1)}) -mutual - asmAnnotationValue : AnnotationValue -> AnnotationValue - asmAnnotationValue (AnnArray values) = AnnArray (asmAnnotationValue <$> values) - asmAnnotationValue (AnnAnnotation annotation) = AnnAnnotation (asmAnnotation annotation) - asmAnnotationValue value = value +export +resetScope : {auto stateRef: Ref AsmState AsmState} -> Core () +resetScope = updateState $ + { + scopeCounter := 0, + currentScopeIndex := 0 + } - asmAnnotationProperty : (String, AnnotationValue) -> (String, AnnotationValue) - asmAnnotationProperty (name, value) = (name, asmAnnotationValue value) +fillNull : (HasIO io, Inherits list (JList a)) => Int -> list -> io () +fillNull index aList = do + let list = the (JList a) $ believe_me aList + size <- Collection.size {elemTy=a,obj=Collection a} $ believe_me list + nulls <- JList.nCopies {a=a} (index - size) nullValue + ignore $ JList.addAll {a=a, obj=Collection a} list $ believe_me nulls - export - asmAnnotation : Annotation -> Annotation - asmAnnotation (MkAnnotation name properties) = - MkAnnotation ("L" ++ name ++ ";") (asmAnnotationProperty <$> properties) +export +saveScope : {auto stateRef: Ref AsmState AsmState} -> Scope -> Core () +saveScope scope = do + scopes <- scopes <$> getCurrentFunction + size <- coreLift $ Collection.size {elemTy=Scope, obj=Collection Scope} $ believe_me scopes + let scopeIndex = index scope + coreLift $ + if scopeIndex < size + then ignore $ JList.set scopes scopeIndex scope + else do + fillNull {a=Scope} scopeIndex scopes + JList.add scopes scopeIndex scope export -toJFieldInitialValue : FieldInitialValue -> Object -toJFieldInitialValue (IntField n) = believe_me $ integerValueOf n -toJFieldInitialValue (StringField s) = believe_me s -toJFieldInitialValue (DoubleField d) = believe_me $ doubleValueOf d +getScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Core Scope +getScope scopeIndex = do + scopes <- scopes <$> getCurrentFunction + coreLift $ JList.get scopes scopeIndex export -loadBigInteger : Integer -> Asm () -loadBigInteger 0 = Field GetStatic "java/math/BigInteger" "ZERO" "Ljava/math/BigInteger;" -loadBigInteger 1 = Field GetStatic "java/math/BigInteger" "ONE" "Ljava/math/BigInteger;" -loadBigInteger 10 = Field GetStatic "java/math/BigInteger" "TEN" "Ljava/math/BigInteger;" -loadBigInteger value = do - New "java/math/BigInteger" - Dup - Ldc $ StringConst $ show value - InvokeMethod InvokeSpecial "java/math/BigInteger" "" "(Ljava/lang/String;)V" False +addScopeChild : {auto stateRef: Ref AsmState AsmState} -> Int -> Int -> Core () +addScopeChild parentScopeIndex childScopeIndex = do + scope <- getScope parentScopeIndex + saveScope $ {childIndices $= (childScopeIndex ::)} scope export -getMethodDescriptor : InferredFunctionType -> String -getMethodDescriptor (MkInferredFunctionType retTy []) = "()" ++ getJvmTypeDescriptor retTy -getMethodDescriptor (MkInferredFunctionType retTy argTypes) = - let argDescs = getJvmTypeDescriptor <$> argTypes - retTyDesc = getJvmTypeDescriptor retTy - in "(" ++ (the String $ concat argDescs) ++ ")" ++ retTyDesc +getRootMethodName : {auto stateRef: Ref AsmState AsmState} -> Core Jname +getRootMethodName = jvmClassMethodName <$> getCurrentFunction export -getMethodSignature : InferredFunctionType -> String -getMethodSignature (MkInferredFunctionType retTy []) = "()" ++ getSignature retTy -getMethodSignature (MkInferredFunctionType retTy argTypes) = - let argDescs = getSignature <$> argTypes - retTyDesc = getSignature retTy - in "(" ++ (the String $ concat argDescs) ++ ")" ++ retTyDesc +newLabel : {auto stateRef: Ref AsmState AsmState} -> Core String +newLabel = do + state <- getState + let label = "L" ++ show (labelCounter state) + updateState $ { labelCounter $= (+1) } + pure label + +hasLabelAtLine : {auto stateRef: Ref AsmState AsmState} -> Int -> Core Bool +hasLabelAtLine lineNumber = do + state <- getState + coreLift $ Map.containsKey {value=String} (lineNumberLabels state) lineNumber export -assemble : HasIO io => AsmState -> IO a -> io (a, AsmState) -assemble state m = do - res <- primIO $ toPrim m - pure (res, state) +addLineNumber : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core () +addLineNumber number label = do + hasLabel <- hasLabelAtLine number + when (not hasLabel) $ do + state <- getState + lineNumber number label + ignore $ coreLift $ Map.put (lineNumberLabels state) number label -%foreign - jvm' "io/github/mmhelloworld/idrisjvm/assembler/IdrisName" "getIdrisFunctionName" - "String String String" "io/github/mmhelloworld/idrisjvm/runtime/IdrisList" -jgetIdrisFunctionName : String -> String -> String -> List String +export +getLineNumberLabel : {auto stateRef: Ref AsmState AsmState} -> Int -> Core String +getLineNumberLabel lineNumber = do + state <- getState + let currentLineNumberLabels = lineNumberLabels state + optLabel <- coreLift $ Map.get {value=String} currentLineNumberLabels lineNumber + case nullableToMaybe optLabel of + Just label => pure label + Nothing => do + label <- newLabel + _ <- coreLift $ Map.put currentLineNumberLabels lineNumber label + pure label export -getIdrisFunctionName : String -> String -> String -> Jname -getIdrisFunctionName programName moduleName idrisFunctionName = - case jgetIdrisFunctionName programName moduleName idrisFunctionName of - (className :: functionName :: _) => Jqualified className functionName - _ => Jqualified moduleName idrisFunctionName +getClassName : {auto stateRef: Ref AsmState AsmState} -> Core String +getClassName = className . currentMethodName <$> getState -%inline -metafactoryDesc : String -metafactoryDesc = - "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;" +export +getMethodName : {auto stateRef: Ref AsmState AsmState} -> Core String +getMethodName = methodName . currentMethodName <$> getState export -invokeDynamic : (implClassName: String) -> (implMethodName: String) -> (interfaceMethodName: String) -> - (invokeDynamicDesc: String) -> (samDesc: String) -> (implMethodDesc: String) -> - (instantiatedMethodDesc: String) -> Asm () -invokeDynamic implClassName implMethodName interfaceMethodName invokeDynamicDesc samDesc implMethodDesc - instantiatedMethodDesc = - let metafactoryHandle = MkHandle InvokeStatic "java/lang/invoke/LambdaMetafactory" "metafactory" - metafactoryDesc False - implMethodHandle = MkHandle InvokeStatic implClassName implMethodName implMethodDesc False - metafactoryArgs = [ BsmArgGetType samDesc - , BsmArgHandle implMethodHandle - , BsmArgGetType instantiatedMethodDesc - ] - in InvokeDynamic interfaceMethodName invokeDynamicDesc metafactoryHandle metafactoryArgs +freshLambdaIndex : {auto stateRef: Ref AsmState AsmState} -> Core Int +freshLambdaIndex = lambdaCounter <$> (getAndUpdateState $ {lambdaCounter $= (+1)}) export -shouldDebugAsm : Bool -shouldDebugAsm = - let shouldDebugProperty = fromMaybe "" $ unsafePerformIO (getEnv "IDRIS_JVM_DEBUG_ASM") - in shouldDebugProperty == "true" +setScopeCounter : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () +setScopeCounter scopeCounter = updateState $ {scopeCounter := scopeCounter} export -shouldDebug : Bool -shouldDebug = - let shouldDebugProperty = fromMaybe "" $ unsafePerformIO (getEnv "IDRIS_JVM_DEBUG") - in shouldDebugProperty /= "" && shouldDebugProperty /= "false" +updateScopeStartLabel : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core () +updateScopeStartLabel scopeIndex label = do + scope <- getScope scopeIndex + saveScope $ {labels $= updateFirst label} scope export -debugFunction : String -debugFunction = fromMaybe "" $ unsafePerformIO $ getEnv "IDRIS_JVM_DEBUG" +updateScopeEndLabel : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core () +updateScopeEndLabel scopeIndex label = do + scope <- getScope scopeIndex + saveScope $ {labels $= updateSecond label} scope export -shouldDebugFunction : Jname -> Bool -shouldDebugFunction jname = shouldDebug && (debugFunction == "" || (debugFunction `isInfixOf` (getSimpleName jname))) +createVariable : {auto stateRef: Ref AsmState AsmState} -> String -> Core () +createVariable var = do + scopeIndex <- getCurrentScopeIndex + scope <- getScope scopeIndex + let variableIndex = nextVariableIndex scope + _ <- coreLift $ Map.put (variableTypes scope) var IUnknown + _ <- coreLift $ Map.put (variableIndices scope) var variableIndex + saveScope $ { nextVariableIndex $= (+1) } scope -namespace LocalDateTime - data LocalDateTime : Type where [external] +export +generateVariable : {auto stateRef: Ref AsmState AsmState} -> String -> Core String +generateVariable namePrefix = do + dynamicVariableIndex <- newDynamicVariableIndex + let variableName = namePrefix ++ show dynamicVariableIndex + createVariable variableName + pure variableName - %foreign "jvm:now(java/lang/Object java/time/LocalDateTime),java/time/LocalDateTime" - prim_now : PrimIO LocalDateTime +namespace JAsmState + %foreign jvm' "io/github/mmhelloworld/idrisjvm/assembler/AsmState" "updateVariableIndices" "java/util/Map java/util/Map" "void" + prim_updateVariableIndices : Map key value -> Map key value -> PrimIO () - %foreign jvm' "java/time/LocalDateTime" ".toString" "java/time/LocalDateTime" "String" - prim_toString : LocalDateTime -> PrimIO String + export + updateVariableIndices : HasIO io => Map String Int -> Map String Int -> io () + updateVariableIndices resultIndicesByName indicesByName = + primIO $ prim_updateVariableIndices resultIndicesByName indicesByName + + %foreign jvm' "io/github/mmhelloworld/idrisjvm/assembler/AsmState" "getVariableNames" "java/util/Map" "java/util/List" + prim_getVariableNames : Map key value -> PrimIO (JList key) export - currentTimeString : HasIO io => io String - currentTimeString = do - now <- primIO prim_now - primIO $ prim_toString now + getVariableNames : HasIO io => Map String Int -> io (List String) + getVariableNames indicesByName = do + jlist <- primIO $ prim_getVariableNames indicesByName + JList.fromIterable jlist -%foreign "jvm:getCurrentThreadName(java/lang/Object java/lang/String),io/github/mmhelloworld/idrisjvm/runtime/Runtime" -prim_getCurrentThreadName : PrimIO String +retrieveVariableIndicesByName : {auto stateRef: Ref AsmState AsmState} -> Int -> Core (Map String Int) +retrieveVariableIndicesByName scopeIndex = do + variableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} + go variableIndices scopeIndex + pure variableIndices + where + go : Map String Int -> Int -> Core () + go acc scopeIndex = go1 scopeIndex where + go1 : Int -> Core () + go1 scopeIndex = do + scope <- getScope scopeIndex + coreLift $ updateVariableIndices acc (variableIndices scope) + maybe (pure ()) go1 (parentIndex scope) export -getCurrentThreadName : HasIO io => io String -getCurrentThreadName = primIO prim_getCurrentThreadName +retrieveVariables : {auto stateRef: Ref AsmState AsmState} -> Int -> Core (List String) +retrieveVariables scopeIndex = do + variableIndicesByName <- retrieveVariableIndicesByName scopeIndex + coreLift $ getVariableNames variableIndicesByName + +retrieveVariableIndexAtScope : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core Int +retrieveVariableIndexAtScope currentScopeIndex name = go currentScopeIndex where + go : Int -> Core Int + go scopeIndex = do + scope <- getScope scopeIndex + optIndex <- coreLift $ Map.get {value=Int} (variableIndices scope) name + case nullableToMaybe optIndex of + Just index => pure index + Nothing => case parentIndex scope of + Just parentScopeIndex => go parentScopeIndex + Nothing => do + rootMethodName <- getRootMethodName + throw $ GenericMsg emptyFC + ("retrieveVariableIndexAtScope: " ++ show rootMethodName ++ ": Unknown var " ++ + name ++ " at index " ++ show currentScopeIndex) export -getJvmClassMethodName : String -> Name -> Jname -getJvmClassMethodName programName name = - let jname = jvmName name - in getIdrisFunctionName programName (className jname) (methodName jname) +retrieveVariableIndex : {auto stateRef: Ref AsmState AsmState} -> String -> Core Int +retrieveVariableIndex name = retrieveVariableIndexAtScope !getCurrentScopeIndex name + +retrieveVariableTypeAtScope : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core InferredType +retrieveVariableTypeAtScope scopeIndex name = do + scope <- getScope scopeIndex + optTy <- coreLift $ Map.get (variableTypes scope) name + case nullableToMaybe optTy of + Just ty => pure ty + Nothing => case parentIndex scope of + Just parentScope => retrieveVariableTypeAtScope parentScope name + Nothing => pure IUnknown export -createAsmStateJavaName : AsmGlobalState -> String -> IO AsmState -createAsmStateJavaName globalState name = do - assembler <- getAssembler globalState name - newAsmState globalState assembler +retrieveVariableTypesAtScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Core (Map Int InferredType) +retrieveVariableTypesAtScope scopeIndex = do + typesByIndex <- coreLift $ Map.newTreeMap {key=Int} {value=InferredType} + go typesByIndex !(retrieveVariables scopeIndex) + pure typesByIndex + where + go : Map Int InferredType -> List String -> Core () + go acc names = go1 names where + go1 : List String -> Core () + go1 [] = pure () + go1 (var :: vars) = do + varIndex <- retrieveVariableIndexAtScope scopeIndex var + ty <- retrieveVariableTypeAtScope scopeIndex var + hasVar <- coreLift $ containsKey {value=InferredType} acc varIndex + when (not hasVar) $ coreLift $ do + oldTy <- Map.put acc varIndex ty + pure () + go1 vars export -createAsmState : AsmGlobalState -> Name -> IO AsmState -createAsmState globalState name = do - programName <- AsmGlobalState.getProgramName globalState - let jvmClassMethodName = getJvmClassMethodName programName name - createAsmStateJavaName globalState (className jvmClassMethodName) +getVariableIndicesByName : {auto stateRef: Ref AsmState AsmState} -> Int -> Core (Map String Int) +getVariableIndicesByName scopeIndex = allVariableIndices <$> getScope scopeIndex -%foreign jvm' "io/github/mmhelloworld/idrisjvm/runtime/Runtime" "waitForFuturesToComplete" "java/util/List" "void" -prim_waitForFuturesToComplete : List ThreadID -> PrimIO () +export +getVariableIndexAtScope : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core Int +getVariableIndexAtScope currentScopeIndex name = do + variableIndicesByName <- getVariableIndicesByName currentScopeIndex + optIndex <- coreLift $ Map.get {value=Int} variableIndicesByName name + case nullableToMaybe optIndex of + Just index => pure index + Nothing => do + rootMethodName <- getRootMethodName + asmCrash ("getVariableIndexAtScope: " ++ show rootMethodName ++ ": Unknown var " ++ + name ++ " at index " ++ show currentScopeIndex) export -waitForFuturesToComplete : List ThreadID -> IO () -waitForFuturesToComplete futures = primIO $ prim_waitForFuturesToComplete futures +getVariableIndex : {auto stateRef: Ref AsmState AsmState} -> String -> Core Int +getVariableIndex name = getVariableIndexAtScope !getCurrentScopeIndex name export -log : Lazy String -> (result : a) -> a -log message val = - if shouldDebug - then unsafePerformIO $ do - time <- currentTimeString - threadName <- getCurrentThreadName - putStrLn (time ++ " [" ++ threadName ++ "]: " ++ message) - pure val - else val +getVariableTypesAtScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Core (Map Int InferredType) +getVariableTypesAtScope scopeIndex = allVariableTypes <$> getScope scopeIndex export -logAsm : Lazy String -> Asm () -logAsm message = log message (Pure ()) +getVariableTypes : {auto stateRef: Ref AsmState AsmState} -> Core (Map Int InferredType) +getVariableTypes = getVariableTypesAtScope !getCurrentScopeIndex -public export -data FArgList : Type where - Nil : FArgList - (::) : {a : Type} -> (1 arg : a) -> (1 args : FArgList) -> FArgList +export +getVariableTypeAtScope : {auto stateRef: Ref AsmState AsmState} -> Int -> String -> Core InferredType +getVariableTypeAtScope scopeIndex name = do + scope <- getScope scopeIndex + variableIndicesByName <- getVariableIndicesByName scopeIndex + optIndex <- coreLift $ Map.get {value=Int} variableIndicesByName name + case nullableToMaybe optIndex of + Just index => do + variableTypes <- getVariableTypesAtScope scopeIndex + optTy <- coreLift $ Map.get {value=InferredType} variableTypes index + pure $ fromMaybe IUnknown $ nullableToMaybe optTy + Nothing => pure IUnknown export -%extern prim__jvmInstance : (ret : Type) -> String -> (1 args : FArgList) -> (1 x : %World) -> IORes ret +getVariableType : {auto stateRef: Ref AsmState AsmState} -> String -> Core InferredType +getVariableType name = getVariableTypeAtScope !getCurrentScopeIndex name -export %inline -jvmInstance : (ret : Type) -> String -> (1 args : FArgList) -> IO ret -jvmInstance ret fn args = fromPrim (prim__jvmInstance ret fn args) +updateArgumentsForUntyped : Map Int InferredType -> Nat -> IO () +updateArgumentsForUntyped _ Z = pure () +updateArgumentsForUntyped types (S n) = do + ignore $ Map.put types (cast {to=Int} n) inferredObjectType + updateArgumentsForUntyped types n export -superName : Name -superName = NS (mkNamespace "Java.Lang") (UN $ Basic "super") +updateScopeVariableTypes : {auto stateRef: Ref AsmState AsmState} -> Nat -> Core () +updateScopeVariableTypes arity = go (scopeCounter !getState - 1) where + go : Int -> Core () + go scopeIndex = + if scopeIndex < 0 then pure () + else do + variableTypes <- retrieveVariableTypesAtScope scopeIndex + when (scopeIndex == 0) $ coreLift $ updateArgumentsForUntyped variableTypes arity + variableIndices <- retrieveVariableIndicesByName scopeIndex + scope <- getScope scopeIndex + saveScope $ {allVariableTypes := variableTypes, allVariableIndices := variableIndices} scope + go (scopeIndex - 1) -export -isSuperCall : Name -> List NamedCExp -> Bool -isSuperCall name - [(NmExtPrim fc f@(NS ns (UN (Basic "prim__jvmStatic"))) args@(ret :: NmPrimVal primFc (Str fn):: rest))] - = name == superName && endsWith "." fn -isSuperCall _ _ = False +getVariableScope : {auto stateRef: Ref AsmState AsmState} -> String -> Core Scope +getVariableScope name = go !getCurrentScopeIndex where + go : Int -> Core Scope + go scopeIndex = do + scope <- getScope scopeIndex + optTy <- coreLift $ Map.get {value=InferredType} (variableTypes scope) name + case nullableToMaybe optTy of + Just _ => pure scope + Nothing => case parentIndex scope of + Just parentScopeIndex => go parentScopeIndex + Nothing => asmCrash ("Unknown variable " ++ name) -public export -%inline -methodStartLabel : String -methodStartLabel = "methodStartLabel" +export +addVariableType : {auto stateRef: Ref AsmState AsmState} -> String -> InferredType -> Core InferredType +addVariableType var IUnknown = pure IUnknown +addVariableType var ty = do + scope <- getVariableScope var + let scopeIndex = index scope + existingTy <- retrieveVariableTypeAtScope scopeIndex var + let newTy = existingTy <+> ty + _ <- coreLift $ Map.put (variableTypes scope) var newTy + pure newTy -public export %inline -methodEndLabel : String -methodEndLabel = "methodEndLabel" +export +lambdaMaxCountPerMethod: Int +lambdaMaxCountPerMethod = 50 export -runAsm : HasIO io => AsmState -> Asm a -> io (a, AsmState) -runAsm state Aaload = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aaload" [assembler state] - -runAsm state Aastore = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aastore" [assembler state] - -runAsm state Aconstnull = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aconstnull" [assembler state] - -runAsm state (Aload n) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aload" [assembler state, n] - -runAsm state (Anewarray desc) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewarray" [assembler state, desc] -runAsm state Anewintarray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewintarray" [assembler state] -runAsm state Anewbooleanarray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewbooleanarray" [assembler state] -runAsm state Anewbytearray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewbytearray" [assembler state] -runAsm state Anewchararray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewchararray" [assembler state] -runAsm state Anewshortarray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewshortarray" [assembler state] -runAsm state Anewlongarray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewlongarray" [assembler state] -runAsm state Anewfloatarray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewfloatarray" [assembler state] -runAsm state Anewdoublearray = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.anewdoublearray" [assembler state] -runAsm state Arraylength = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.arraylength" [assembler state] -runAsm state Areturn = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.areturn" [assembler state] -runAsm state (Astore n) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.astore" [assembler state, n] -runAsm state Baload = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.baload" [assembler state] -runAsm state Bastore = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.bastore" [assembler state] -runAsm state Caload = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.caload" [assembler state] -runAsm state Castore = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.castore" [assembler state] -runAsm state (Checkcast desc) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.checkcast" [assembler state, desc] -runAsm state (ClassCodeStart version access className sig parent intf anns) = assemble state $ do - janns <- sequence $ toJAnnotation <$> anns - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.classCodeStart" - [assembler state, version, sum $ accessNum <$> access, className, maybeToNullable sig, parent, - the (JList String) $ believe_me intf, the (JList JAnnotation) $ believe_me janns] - -runAsm state (CreateClass opts) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.createClass" - [assembler state, sum $ toJClassOpts <$> opts] -runAsm state (CreateField accs sourceFileName className fieldName desc sig fieldInitialValue anns) = assemble state $ do - let jaccs = sum $ accessNum <$> accs - janns <- sequence $ toJAnnotation <$> anns - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.createField" - [assembler state, jaccs, sourceFileName, className, fieldName, desc, maybeToNullable sig, - maybeToNullable (toJFieldInitialValue <$> fieldInitialValue), the (JList JAnnotation) $ believe_me janns] - -runAsm state (CreateLabel label) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.createLabel" [assembler state, label] - -runAsm state (CreateMethod accs sourceFileName className methodName desc sig exceptions anns paramAnns) = - let newState = { currentMethodName := Jqualified className methodName } state - in assemble newState $ do - let jaccs = sum $ accessNum <$> accs - janns <- sequence $ toJAnnotation <$> anns - jparamAnns <- sequence $ (\paramAnn => sequence $ toJAnnotation <$> paramAnn) <$> paramAnns - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.createMethod" - [assembler state, jaccs, sourceFileName, className, methodName, desc, maybeToNullable sig, - the (JList String) $ believe_me $ maybeToNullable exceptions, - the (JList JAnnotation) $ believe_me janns, the (JList (JList JAnnotation)) $ believe_me jparamAnns] - -runAsm state (CreateIdrisConstructorClass className isStringConstructor constructorParameterCount) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.createIdrisConstructorClass" - [assembler state, className, isStringConstructor, constructorParameterCount] - -runAsm state D2i = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.d2i" [assembler state] -runAsm state D2f = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.d2f" [assembler state] -runAsm state D2l = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.d2l" [assembler state] -runAsm state Dadd = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dadd" [assembler state] -runAsm state Dcmpg = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dcmpg" [assembler state] -runAsm state Dcmpl = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dcmpl" [assembler state] -runAsm state (Dconst n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dconst" [assembler state, n] -runAsm state Daload = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.daload" [assembler state] -runAsm state Dastore = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dastore" [assembler state] -runAsm state Ddiv = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ddiv" [assembler state] -runAsm state (Debug message) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.debug" - [assembler state, message] -runAsm state (Dload n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dload" [assembler state, n] -runAsm state Dmul = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dmul" [assembler state] -runAsm state Dneg = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dneg" [assembler state] -runAsm state Drem = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.drem" [assembler state] -runAsm state Dreturn = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dreturn" [assembler state] -runAsm state (Dstore n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dstore" [assembler state, n] -runAsm state Dsub = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dsub" [assembler state] -runAsm state Dup = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.dup" [assembler state] -runAsm state (Error err) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.error" [assembler state, err] -runAsm state F2d = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.f2d" [assembler state] -runAsm state Faload = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.faload" [assembler state] -runAsm state Fastore = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fastore" [assembler state] -runAsm state (Fconst n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fconst" [assembler state, n] -runAsm state (Field finsType cname fname desc) = assemble state $ do - let finsTypeNum = fieldInsTypeNum finsType - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.field" - [assembler state, finsTypeNum, cname, fname, desc] - -runAsm state FieldEnd = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fieldEnd" [assembler state] - -runAsm state (Fload n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fload" [assembler state, n] - -runAsm state (Frame frameType nLocal localSigs nStack stackSigs) = assemble state $ do - let ftypeNum = frameTypeNum frameType - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.frame" - [assembler state, ftypeNum, nLocal, the (JList String) $ believe_me localSigs, nStack, - the (JList String) $ believe_me stackSigs] - -runAsm state Freturn = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.freturn" [assembler state] -runAsm state (Fstore n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.fstore" [assembler state, n] - -runAsm state (Goto label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.gotoLabel" - [assembler state, label] - -runAsm state I2b = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2b" [assembler state] -runAsm state I2c = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2c" [assembler state] -runAsm state I2d = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2d" [assembler state] -runAsm state I2l = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2l" [assembler state] -runAsm state I2s = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.i2s" [assembler state] -runAsm state Iadd = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iadd" [assembler state] -runAsm state Iaload = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iaload" [assembler state] -runAsm state Iand = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iand" [assembler state] -runAsm state Iastore = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iastore" [assembler state] -runAsm state Ior = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ior" [assembler state] -runAsm state Ixor = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ixor" [assembler state] -runAsm state Icompl = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.icompl" [assembler state] -runAsm state (Iconst n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iconst" [assembler state, n] -runAsm state Idiv = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.idiv" [assembler state] -runAsm state (Ifeq label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifeq" [assembler state, label] -runAsm state (Ifge label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifge" [assembler state, label] -runAsm state (Ifgt label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifgt" [assembler state, label] -runAsm state (Ificmpge label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpge" [assembler state, label] -runAsm state (Ificmpgt label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpgt" [assembler state, label] -runAsm state (Ificmple label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmple" [assembler state, label] -runAsm state (Ificmplt label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmplt" [assembler state, label] -runAsm state (Ificmpeq label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpeq" [assembler state, label] -runAsm state (Ifacmpne label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifacmpne" [assembler state, label] -runAsm state (Ificmpne label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ificmpne" [assembler state, label] -runAsm state (Ifle label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifle" [assembler state, label] -runAsm state (Iflt label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iflt" [assembler state, label] -runAsm state (Ifne label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifne" [assembler state, label] -runAsm state (Ifnonnull label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifnonnull" [assembler state, label] -runAsm state (Ifnull label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ifnull" [assembler state, label] -runAsm state (Iload n) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iload" [assembler state, n] -runAsm state Imul = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.imul" [assembler state] -runAsm state Ineg = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ineg" [assembler state] -runAsm state (InstanceOf className) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.instanceOf" [assembler state, className] -runAsm state (InvokeMethod invocType cname mname desc isIntf) = assemble state $ do - let invocTypeAsm = invocTypeNum invocType - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.invokeMethod" - [assembler state, invocTypeAsm, cname, mname, desc, isIntf] - -runAsm state (InvokeDynamic mname desc handle bsmArgs) = assemble state $ do - jbsmArgsList <- sequence $ toJbsmArg <$> bsmArgs - jhandle <- toJHandle handle - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.invokeDynamic" - [assembler state, mname, desc, jhandle, the (JList JBsmArg) $ believe_me jbsmArgsList] - -runAsm state Irem = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.irem" [assembler state] -runAsm state Ireturn = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ireturn" [assembler state] -runAsm state Ishl = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ishl" [assembler state] -runAsm state Ishr = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ishr" [assembler state] -runAsm state (Istore n) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.istore" [assembler state, n] -runAsm state Isub = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.isub" [assembler state] -runAsm state Iushr = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.iushr" [assembler state] -runAsm state L2d = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.l2d" [assembler state] -runAsm state L2i = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.l2i" [assembler state] -runAsm state (LabelStart label) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.labelStart" [assembler state, label] -runAsm state Ladd = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ladd" [assembler state] -runAsm state Land = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.land" [assembler state] -runAsm state Laload = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.laload" [assembler state] -runAsm state Lastore = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lastore" [assembler state] -runAsm state Lcmp = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lcmp" [assembler state] -runAsm state Lor = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lor" [assembler state] -runAsm state Lxor = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lxor" [assembler state] -runAsm state Lcompl = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lcompl" [assembler state] - -runAsm state (Ldc (TypeConst ty)) = - assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ldcType" [assembler state, ty] -runAsm state (Ldc constant) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ldc" [assembler state, constantToObject constant] - -runAsm state Ldiv = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.ldiv" [assembler state] - -runAsm state (LineNumber lineNumber label) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lineNumber" [assembler state, lineNumber, label] - -runAsm state (Lload n) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lload" [assembler state, n] -runAsm state Lmul = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lmul" [assembler state] -runAsm state Lneg = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lneg" [assembler state] -runAsm state (LookupSwitch defaultLabel labels cases) = assemble state $ do - let jcases = integerValueOf <$> cases - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lookupSwitch" - [assembler state, defaultLabel, the (JList String) $ believe_me labels, the (JList Int) $ believe_me jcases] - -runAsm state (LocalVariable name descriptor signature startLabel endLabel index) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.localVariable" - [assembler state, name, descriptor, maybeToNullable signature, startLabel, endLabel, index] - -runAsm state Lrem = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lrem" [assembler state] -runAsm state Lreturn = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lreturn" [assembler state] -runAsm state Lshl = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lshl" [assembler state] -runAsm state Lshr = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lshr" [assembler state] -runAsm state (Lstore n) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lstore" [assembler state, n] -runAsm state Lsub = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lsub" [assembler state] -runAsm state Lushr = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lushr" [assembler state] -runAsm state (MaxStackAndLocal stack local) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.maxStackAndLocal" [assembler state, stack, local] -runAsm state MethodCodeStart = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.methodCodeStart" [assembler state] -runAsm state MethodCodeEnd = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.methodCodeEnd" [assembler state] -runAsm state (Multianewarray desc dims) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.multiANewArray" [assembler state, desc, dims] -runAsm state (New cname) = assemble state $ - jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.asmNew" [assembler state, cname] -runAsm state Pop = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.pop" [assembler state] -runAsm state Pop2 = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.pop2" [assembler state] -runAsm state Return = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.voidReturn" [assembler state] -runAsm state Saload = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.saload" [assembler state] -runAsm state Sastore = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.sastore" [assembler state] -runAsm state (SourceInfo sourceFileName) - = assemble state $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.sourceInfo" [assembler state, sourceFileName] -runAsm state (LiftIo action) = assemble state action - -runAsm state (Throw fc message) = pure (believe_me $ crash $ show fc ++ ": " ++ message, state) -runAsm state GetState = pure (state, state) -runAsm state (SetState newState) = pure ((), newState) - -runAsm st (Pure value) = pure (value, st) -runAsm st (Bind action f) = do - (result, nextSt) <- runAsm st action - runAsm nextSt $ f result +getLambdaImplementationMethodName : {auto stateRef: Ref AsmState AsmState} -> String -> Core Jname +getLambdaImplementationMethodName namePrefix = do + lambdaIndex <- freshLambdaIndex + rootMethodJname <- getRootMethodName + let declaringMethodName = methodName rootMethodJname + let rootMethodClassName = className rootMethodJname + let lambdaClassName = + if lambdaIndex >= lambdaMaxCountPerMethod + then rootMethodClassName ++ "$" ++ namePrefix ++ "$" ++ declaringMethodName ++ "$" ++ show (lambdaIndex `div` 100) + else rootMethodClassName + let lambdaMethodName = + if lambdaIndex >= lambdaMaxCountPerMethod + then namePrefix ++ "$" ++ show lambdaIndex + else namePrefix ++ "$" ++ declaringMethodName ++ "$" ++ show lambdaIndex + pure $ Jqualified lambdaClassName lambdaMethodName + +mutual + parseArrayType : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core (Maybe InferredType) + parseArrayType expr@(NmCon _ name _ _ [elemTy]) = + if name == arrayName then pure. Just $ IArray !(tySpec elemTy) + else pure Nothing + parseArrayType _ = pure Nothing + + parseLambdaType : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core (Maybe InferredType) + parseLambdaType (NmCon _ name _ _ [interfaceType, _]) = + if name == builtin "Pair" then parseJvmReferenceType interfaceType + else pure Nothing + parseLambdaType _ = pure Nothing + + parseJvmReferenceType : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core (Maybe InferredType) + parseJvmReferenceType (NmCon _ name _ _ (NmPrimVal _ (Str namePartsStr) :: _)) = + if name == structName + then pure $ parseName namePartsStr + else pure Nothing + parseJvmReferenceType (NmCon _ name conInfo tag args) = + if name == primio "IORes" then + maybe (asmCrash "Expected an argument for IORes") (\res => pure $ Just !(tySpec res)) (head' args) + else pure $ Just $ getIdrisConstructorType conInfo tag (length args) name + parseJvmReferenceType (NmApp fc (NmRef _ name) _) = do + (_, MkNmFun _ def) <- getFcAndDefinition (jvmSimpleName name) + | _ => asmCrash ("Expected a function returning a tuple containing interface type and method type at " ++ + show fc) + ty <- tySpec def + pure $ Just ty + parseJvmReferenceType (NmDelay _ _ expr) = pure $ Just !(tySpec expr) + parseJvmReferenceType expr = pure Nothing + + tryParse : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core (Maybe InferredType) + tryParse expr = do + arrayTypeMaybe <- parseArrayType expr + case arrayTypeMaybe of + Nothing => do + lambdaTypeMaybe <- parseLambdaType expr + case lambdaTypeMaybe of + Nothing => parseJvmReferenceType expr + Just lambdaType => pure $ Just lambdaType + Just arrayType => pure $ Just arrayType + + export + tySpec : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core InferredType + tySpec (NmCon _ (UN (Basic ty)) _ _ []) = pure $ tySpecStr ty + tySpec (NmCon _ _ NOTHING _ []) = pure idrisMaybeType + tySpec (NmCon _ _ JUST _ [_]) = pure idrisMaybeType + tySpec (NmCon _ _ NIL _ []) = pure idrisListType + tySpec (NmCon _ _ CONS _ [_, _]) = pure idrisListType + tySpec expr@(NmCon _ (NS _ (UN (Basic "Unit"))) _ _ []) = pure IVoid + tySpec expr = do + ty <- tryParse expr + pure $ fromMaybe inferredObjectType ty + + +export +asmReturn : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Core () +asmReturn IVoid = return +asmReturn IBool = ireturn +asmReturn IByte = ireturn +asmReturn IShort = ireturn +asmReturn IInt = ireturn +asmReturn IChar = ireturn +asmReturn ILong = lreturn +asmReturn IFloat = freturn +asmReturn IDouble = dreturn +asmReturn _ = areturn + +export +runAsm : AsmState -> (Ref AsmState AsmState -> Core a) -> IO a +runAsm asmState action = coreRun (do ref <- newRef AsmState asmState + put AsmState asmState + action ref) + (\err: Error => do printLn err + exitWith (ExitFailure 1)) + pure diff --git a/src/Compiler/Jvm/Codegen.idr b/src/Compiler/Jvm/Codegen.idr index d62d39bfc..6b4b3b767 100644 --- a/src/Compiler/Jvm/Codegen.idr +++ b/src/Compiler/Jvm/Codegen.idr @@ -6,6 +6,7 @@ import Compiler.Inline import Compiler.NoMangle import Core.Context +import Core.Core import Core.Directory import Core.Name import Core.Options @@ -20,6 +21,13 @@ import Data.Vect import Debug.Trace +import Core.Env + +import Idris.Pretty.Annotations +import Idris.Syntax +import Idris.Resugar +import Idris.Doc.String + import Libraries.Data.NameMap import Libraries.Data.SortedMap import Libraries.Utils.Path @@ -47,91 +55,98 @@ import Idris.Syntax %hide Core.Context.Context.Constructor.arity %hide Core.Name.Scoped.Scope -%hide Compiler.Jvm.Asm.assemble %hide System.FFI.runtimeClass -addScopeLocalVariables : Scope -> Asm () +getType : {auto c : Ref Ctxt Defs} -> {auto s : Ref Syn SyntaxInfo} -> Name -> Core (Maybe (Term [])) +getType name = do + defs <- get Ctxt + Just gdef <- lookupCtxtExact name (gamma defs) + | Nothing => pure Nothing + ty <- normaliseHoles defs [] gdef.type + Just <$> toFullNames ty + +addScopeLocalVariables : {auto stateRef: Ref AsmState AsmState} -> Scope -> Core () addScopeLocalVariables scope = do let scopeIndex = index scope let (lineNumberStart, lineNumberEnd) = lineNumbers scope let (labelStart, labelEnd) = labels scope - nameAndIndices <- LiftIo $ Map.toList $ variableIndices scope + nameAndIndices <- coreLift $ Map.toList $ variableIndices scope go labelStart labelEnd nameAndIndices where - go : String -> String -> List (String, Int) -> Asm () - go _ _ [] = Pure () + go : String -> String -> List (String, Int) -> Core () + go _ _ [] = pure () go labelStart labelEnd ((name, varIndex) :: rest) = do variableType <- getVariableTypeAtScope (index scope) name - LocalVariable name (getJvmTypeDescriptor variableType) Nothing labelStart labelEnd varIndex + localVariable name (getJvmTypeDescriptor variableType) Nothing labelStart labelEnd varIndex go labelStart labelEnd rest -addLocalVariables : Int -> Asm () +addLocalVariables : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () addLocalVariables scopeIndex = do scope <- getScope scopeIndex addScopeLocalVariables scope traverse_ addLocalVariables $ childIndices scope -enterScope : Asm () +enterScope : {auto stateRef: Ref AsmState AsmState} -> Core () enterScope = do scopeIndex <- newScopeIndex updateCurrentScopeIndex scopeIndex -exitScope : Int -> Asm () +exitScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () exitScope = updateCurrentScopeIndex -withScope : Lazy (Asm ()) -> Asm () +withScope : {auto stateRef: Ref AsmState AsmState} -> Lazy (Core ()) -> Core () withScope op = do scopeIndex <- getCurrentScopeIndex enterScope op exitScope scopeIndex -defaultValue : InferredType -> Asm () -defaultValue IBool = Iconst 0 -defaultValue IByte = Iconst 0 -defaultValue IChar = Iconst 0 -defaultValue IShort = Iconst 0 -defaultValue IInt = Iconst 0 -defaultValue ILong = Ldc $ Int64Const 0 -defaultValue IFloat = Fconst 0 -defaultValue IDouble = Dconst 0 -defaultValue _ = Aconstnull - -assembleArray : (elemTy: InferredType) -> Asm () -assembleArray IBool = Anewbooleanarray -assembleArray IByte = Anewbytearray -assembleArray IChar = Anewchararray -assembleArray IShort = Anewshortarray -assembleArray IInt = Anewintarray -assembleArray ILong = Anewlongarray -assembleArray IFloat = Anewfloatarray -assembleArray IDouble = Anewdoublearray -assembleArray (IRef ty _ _) = Anewarray ty -assembleArray (IArray ty) = Anewarray (getJvmTypeDescriptor ty) -assembleArray (IFunction (MkJavaLambdaType (IRef ty _ _) _ _ _)) = Anewarray ty -assembleArray _ = Anewarray "java/lang/Object" - -storeArray : (elemTy: InferredType) -> Asm () -storeArray IBool = Bastore -storeArray IByte = Bastore -storeArray IChar = Castore -storeArray IShort = Sastore -storeArray IInt = Iastore -storeArray ILong = Lastore -storeArray IFloat = Fastore -storeArray IDouble = Dastore -storeArray _ = Aastore - -loadArray : (elemTy: InferredType) -> Asm () -loadArray IBool = Baload -loadArray IByte = Baload -loadArray IChar = Caload -loadArray IShort = Saload -loadArray IInt = Iaload -loadArray ILong = Laload -loadArray IFloat = Faload -loadArray IDouble = Daload -loadArray _ = Aaload +defaultValue : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Core () +defaultValue IBool = iconst 0 +defaultValue IByte = iconst 0 +defaultValue IChar = iconst 0 +defaultValue IShort = iconst 0 +defaultValue IInt = iconst 0 +defaultValue ILong = ldc $ Int64Const 0 +defaultValue IFloat = fconst 0 +defaultValue IDouble = dconst 0 +defaultValue _ = aconstnull + +assembleArray : {auto stateRef: Ref AsmState AsmState} -> (elemTy: InferredType) -> Core () +assembleArray IBool = anewbooleanarray +assembleArray IByte = anewbytearray +assembleArray IChar = anewchararray +assembleArray IShort = anewshortarray +assembleArray IInt = anewintarray +assembleArray ILong = anewlongarray +assembleArray IFloat = anewfloatarray +assembleArray IDouble = anewdoublearray +assembleArray (IRef ty _ _) = anewarray ty +assembleArray (IArray ty) = anewarray (getJvmTypeDescriptor ty) +assembleArray (IFunction (MkJavaLambdaType (IRef ty _ _) _ _ _)) = anewarray ty +assembleArray _ = anewarray "java/lang/Object" + +storeArray : {auto stateRef: Ref AsmState AsmState} -> (elemTy: InferredType) -> Core () +storeArray IBool = bastore +storeArray IByte = bastore +storeArray IChar = castore +storeArray IShort = sastore +storeArray IInt = iastore +storeArray ILong = lastore +storeArray IFloat = fastore +storeArray IDouble = dastore +storeArray _ = aastore + +loadArray : {auto stateRef: Ref AsmState AsmState} -> (elemTy: InferredType) -> Core () +loadArray IBool = baload +loadArray IByte = baload +loadArray IChar = caload +loadArray IShort = saload +loadArray IInt = iaload +loadArray ILong = laload +loadArray IFloat = faload +loadArray IDouble = daload +loadArray _ = aaload jIntKind : PrimType -> IntKind jIntKind ty = fromMaybe (Signed (P 32)) (intKind ty) @@ -147,11 +162,11 @@ multiValueMap f g xs = go SortedMap.empty xs where newAcc = SortedMap.insert key (value :: vs) acc in go newAcc xs -constantAltIntExpr : FC -> NamedConstAlt -> Asm (String, Int, NamedConstAlt) +constantAltIntExpr : {auto stateRef: Ref AsmState AsmState} -> FC -> NamedConstAlt -> Core (String, Int, NamedConstAlt) constantAltIntExpr fc alt@(MkNConstAlt constant _) = do constExpr <- getIntConstantValue fc constant label <- newLabel - Pure (label, constExpr, alt) + pure (label, constExpr, alt) %foreign jvm' "java/lang/Long" "hashCode" "long" "int" int64HashCode : Int64 -> Int @@ -166,41 +181,41 @@ hashCode (B64 value) = Just $ bits64HashCode value hashCode (Str value) = Just $ Object.hashCode value hashCode x = Nothing -getHashCodeSwitchClass : FC -> InferredType -> Asm String -getHashCodeSwitchClass fc (IRef "java/lang/String" _ _) = Pure stringClass -getHashCodeSwitchClass fc (IRef "java/math/BigInteger" _ _) = Pure bigIntegerClass -getHashCodeSwitchClass fc ILong = Pure "java/lang/Long" +getHashCodeSwitchClass : {auto stateRef: Ref AsmState AsmState} -> FC -> InferredType -> Core String +getHashCodeSwitchClass fc (IRef "java/lang/String" _ _) = pure stringClass +getHashCodeSwitchClass fc (IRef "java/math/BigInteger" _ _) = pure bigIntegerClass +getHashCodeSwitchClass fc ILong = pure"java/lang/Long" getHashCodeSwitchClass fc constantType = asmCrash ("Constant type " ++ show constantType ++ " cannot be compiled to 'Switch'.") -assembleHashCodeSwitchConstant : FC -> Primitive.Constant -> Asm () +assembleHashCodeSwitchConstant : {auto stateRef: Ref AsmState AsmState} -> FC -> Primitive.Constant -> Core () assembleHashCodeSwitchConstant _ (BI value) = newBigInteger $ show value -assembleHashCodeSwitchConstant _ (I64 value) = Ldc $ Int64Const value -assembleHashCodeSwitchConstant _ (B64 value) = Ldc $ Bits64Const value -assembleHashCodeSwitchConstant _ (Str value) = Ldc $ StringConst value +assembleHashCodeSwitchConstant _ (I64 value) = ldc $ Int64Const value +assembleHashCodeSwitchConstant _ (B64 value) = ldc $ Bits64Const value +assembleHashCodeSwitchConstant _ (Str value) = ldc $ StringConst value assembleHashCodeSwitchConstant fc constant = asmCrash $ "Constant " ++ show constant ++ " cannot be compiled to 'switch'" -conAltIntExpr : NamedConAlt -> Asm (String, Int, NamedConAlt) +conAltIntExpr : {auto stateRef: Ref AsmState AsmState} -> NamedConAlt -> Core (String, Int, NamedConAlt) conAltIntExpr alt@(MkNConAlt name conInfo tag _ expr) = do label <- newLabel intValue <- case conInfo of - NOTHING => Pure 0 - NIL => Pure 0 - JUST => Pure 1 - CONS => Pure 1 - _ => maybe (asmCrash $ "Missing constructor tag " ++ show name) Pure tag - Pure (label, intValue, alt) - -conAltStringExpr : NamedConAlt -> Asm (String, String, NamedConAlt) + NOTHING => pure 0 + NIL => pure 0 + JUST => pure 1 + CONS => pure 1 + _ => maybe (asmCrash $ "Missing constructor tag " ++ show name) pure tag + pure (label, intValue, alt) + +conAltStringExpr : {auto stateRef: Ref AsmState AsmState} -> NamedConAlt -> Core (String, String, NamedConAlt) conAltStringExpr alt@(MkNConAlt name _ _ _ expr) = do label <- newLabel - Pure (label, jvmSimpleName name, alt) + pure (label, jvmSimpleName name, alt) -createDefaultLabel : Asm String +createDefaultLabel : {auto stateRef: Ref AsmState AsmState} -> Core String createDefaultLabel = do label <- newLabel - CreateLabel label - Pure label + createLabel label + pure label getSwitchCasesWithEndLabel : List (String, Int, a) -> List String -> List (String, Int, a, String) getSwitchCasesWithEndLabel switchCases labelStarts = go $ zip switchCases (drop 1 labelStarts ++ [methodEndLabel]) @@ -209,33 +224,32 @@ getSwitchCasesWithEndLabel switchCases labelStarts = go $ zip switchCases (drop go (((labelStart, constExpr, body), labelEnd) :: xs) = (labelStart, constExpr, body, labelEnd) :: go xs go [] = [] -labelHashCodeAlt : (Int, a) -> Asm (String, Int, a) -labelHashCodeAlt (hash, expressions) = Pure (!newLabel, hash, expressions) +labelHashCodeAlt : {auto stateRef: Ref AsmState AsmState} -> (Int, a) -> Core (String, Int, a) +labelHashCodeAlt (hash, expressions) = pure (!newLabel, hash, expressions) -getHashCodeCasesWithLabels : SortedMap Int (List (Int, a)) -> - Asm (List (String, Int, List (Int, a))) +getHashCodeCasesWithLabels : {auto stateRef: Ref AsmState AsmState} -> SortedMap Int (List (Int, a)) -> Core (List (String, Int, List (Int, a))) getHashCodeCasesWithLabels positionAndAltsByHash = traverse labelHashCodeAlt $ SortedMap.toList positionAndAltsByHash -toUnsignedInt : Int -> Asm () +toUnsignedInt : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () toUnsignedInt bits = do - Iconst bits - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + iconst bits + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False -assembleInt : (isTailCall: Bool) -> InferredType -> Int -> Asm () +assembleInt : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Int -> Core () assembleInt isTailCall returnType value = do - Iconst value + iconst value asmCast IInt returnType when isTailCall $ asmReturn returnType -assembleInt64 : (isTailCall: Bool) -> InferredType -> Int64 -> Asm () +assembleInt64 : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Int64 -> Core () assembleInt64 isTailCall returnType value = do - Ldc $ Int64Const value + ldc $ Int64Const value asmCast ILong returnType when isTailCall $ asmReturn returnType -assembleBits64 : (isTailCall: Bool) -> InferredType -> Bits64 -> Asm () +assembleBits64 : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Bits64 -> Core () assembleBits64 isTailCall returnType value = do - Ldc $ Bits64Const value + ldc $ Bits64Const value asmCast ILong returnType when isTailCall $ asmReturn returnType @@ -243,47 +257,47 @@ isInterfaceInvocation : InferredType -> Bool isInterfaceInvocation (IRef _ Interface _) = True isInterfaceInvocation _ = False -assembleNil : (isTailCall: Bool) -> InferredType -> Asm () +assembleNil : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Core () assembleNil isTailCall returnType = do - Field GetStatic idrisNilClass "INSTANCE" "Lio/github/mmhelloworld/idrisjvm/runtime/IdrisList$Nil;" + field GetStatic idrisNilClass "INSTANCE" "Lio/github/mmhelloworld/idrisjvm/runtime/IdrisList$Nil;" asmCast idrisObjectType returnType when isTailCall $ asmReturn returnType -assembleNothing : (isTailCall: Bool) -> InferredType -> Asm () +assembleNothing : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Core () assembleNothing isTailCall returnType = do - Field GetStatic idrisNothingClass "INSTANCE" "Lio/github/mmhelloworld/idrisjvm/runtime/Maybe$Nothing;" + field GetStatic idrisNothingClass "INSTANCE" "Lio/github/mmhelloworld/idrisjvm/runtime/Maybe$Nothing;" asmCast idrisObjectType returnType when isTailCall $ asmReturn returnType -getDynamicVariableIndex : (variablePrefix: String) -> Asm Int +getDynamicVariableIndex : {auto stateRef: Ref AsmState AsmState} -> (variablePrefix: String) -> Core Int getDynamicVariableIndex variablePrefix = do suffixIndex <- newDynamicVariableIndex let variableName = variablePrefix ++ show suffixIndex getVariableIndex variableName -assembleIdentityLambda : (isTailCall : Bool) -> Asm () +assembleIdentityLambda : {auto stateRef: Ref AsmState AsmState} -> (isTailCall : Bool) -> Core () assembleIdentityLambda isTailCall = do - Field GetStatic functionsClass "IDENTITY" (getJvmTypeDescriptor inferredLambdaType) + field GetStatic functionsClass "IDENTITY" (getJvmTypeDescriptor inferredLambdaType) when isTailCall $ asmReturn inferredLambdaType -assembleIdentity1Lambda : (isTailCall : Bool) -> Asm () +assembleIdentity1Lambda : {auto stateRef: Ref AsmState AsmState} -> (isTailCall : Bool) -> Core () assembleIdentity1Lambda isTailCall = do - Field GetStatic functionsClass "IDENTITY_1" (getJvmTypeDescriptor inferredLambdaType) + field GetStatic functionsClass "IDENTITY_1" (getJvmTypeDescriptor inferredLambdaType) when isTailCall $ asmReturn inferredLambdaType -assembleIdentity2Lambda : (isTailCall : Bool) -> Asm () +assembleIdentity2Lambda : {auto stateRef: Ref AsmState AsmState} -> (isTailCall : Bool) -> Core () assembleIdentity2Lambda isTailCall = do - Field GetStatic functionsClass "IDENTITY_2" (getJvmTypeDescriptor inferredLambdaType) + field GetStatic functionsClass "IDENTITY_2" (getJvmTypeDescriptor inferredLambdaType) when isTailCall $ asmReturn inferredLambdaType -assembleConstantLambda : (isTailCall : Bool) -> Asm () +assembleConstantLambda : {auto stateRef: Ref AsmState AsmState} -> (isTailCall : Bool) -> Core () assembleConstantLambda isTailCall = do - Field GetStatic functionsClass "CONSTANT" (getJvmTypeDescriptor inferredLambdaType) + field GetStatic functionsClass "CONSTANT" (getJvmTypeDescriptor inferredLambdaType) when isTailCall $ asmReturn inferredLambdaType -assembleConstant1Lambda : (isTailCall : Bool) -> Asm () +assembleConstant1Lambda : {auto stateRef: Ref AsmState AsmState} -> (isTailCall : Bool) -> Core () assembleConstant1Lambda isTailCall = do - Field GetStatic functionsClass "CONSTANT_1" (getJvmTypeDescriptor inferredLambdaType) + field GetStatic functionsClass "CONSTANT_1" (getJvmTypeDescriptor inferredLambdaType) when isTailCall $ asmReturn inferredLambdaType getLambdaTypeByArity: (arity: Nat) -> LambdaType @@ -293,25 +307,25 @@ getLambdaTypeByArity 4 = Function4Lambda getLambdaTypeByArity 5 = Function5Lambda getLambdaTypeByArity _ = FunctionLambda -assembleClassLiteral : InferredType -> Asm () -assembleClassLiteral IByte = Field GetStatic "java/lang/Byte" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IChar = Field GetStatic "java/lang/Character" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IShort = Field GetStatic "java/lang/Short" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IBool = Field GetStatic "java/lang/Boolean" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IDouble = Field GetStatic "java/lang/Double" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IFloat = Field GetStatic "java/lang/Float" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IInt = Field GetStatic "java/lang/Integer" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral ILong = Field GetStatic "java/lang/Long" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral IVoid = Field GetStatic "java/lang/Void" "TYPE" "Ljava/lang/Class;" -assembleClassLiteral type = Ldc $ TypeConst $ getJvmTypeDescriptor type - -intToBigInteger : Asm () +assembleClassLiteral : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Core () +assembleClassLiteral IByte = field GetStatic "java/lang/Byte" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IChar = field GetStatic "java/lang/Character" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IShort = field GetStatic "java/lang/Short" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IBool = field GetStatic "java/lang/Boolean" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IDouble = field GetStatic "java/lang/Double" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IFloat = field GetStatic "java/lang/Float" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IInt = field GetStatic "java/lang/Integer" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral ILong = field GetStatic "java/lang/Long" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral IVoid = field GetStatic "java/lang/Void" "TYPE" "Ljava/lang/Class;" +assembleClassLiteral type = ldc $ TypeConst $ getJvmTypeDescriptor type + +intToBigInteger : {auto stateRef: Ref AsmState AsmState} -> Core () intToBigInteger = do - I2l - InvokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False + i2l + invokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False mutual - assembleExpr : (isTailCall: Bool) -> InferredType -> NamedCExp -> Asm () + assembleExpr : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> NamedCExp -> Core () assembleExpr isTailCall returnType (NmDelay _ _ expr) = assembleSubMethodWithScope isTailCall returnType Nothing Nothing expr assembleExpr isTailCall returnType (NmLocal _ loc) = do @@ -328,9 +342,9 @@ mutual assembleExpr isTailCall returnType (NmLet _ var value expr) = do valueScopeStartLabel <- newLabel - CreateLabel valueScopeStartLabel + createLabel valueScopeStartLabel targetExprScopeStartLabel <- newLabel - CreateLabel targetExprScopeStartLabel + createLabel targetExprScopeStartLabel letScopeIndex <- getCurrentScopeIndex let variableName = jvmSimpleName var variableType <- getVariableType variableName @@ -342,7 +356,7 @@ mutual let (lineNumberStart, lineNumberEnd) = lineNumbers scope updateScopeStartLabel valueScopeIndex valueScopeStartLabel updateScopeEndLabel valueScopeIndex targetExprScopeStartLabel - LabelStart valueScopeStartLabel + labelStart valueScopeStartLabel addLineNumber lineNumberStart valueScopeStartLabel assembleExpr False variableType value storeVar variableType variableType variableIndex @@ -352,7 +366,7 @@ mutual scope <- getScope targetExprScopeIndex let (lineNumberStart, lineNumberEnd) = lineNumbers scope updateScopeStartLabel targetExprScopeIndex targetExprScopeStartLabel - LabelStart targetExprScopeStartLabel + labelStart targetExprScopeStartLabel addLineNumber lineNumberStart targetExprScopeStartLabel updateScopeEndLabel targetExprScopeIndex methodEndLabel assembleExpr isTailCall returnType expr @@ -360,7 +374,7 @@ mutual -- Tail recursion. Store arguments and recur to the beginning of the method assembleExpr _ returnType app@(NmApp fc (NmRef _ (UN (Basic "$idrisTailRec"))) args) = case length args of - Z => Goto methodStartLabel + Z => goto methodStartLabel (S lastArgIndex) => do jname <- idrisName <$> getCurrentFunction parameterTypes <- getFunctionParameterTypes jname @@ -369,9 +383,9 @@ mutual let argIndices = [0 .. the Int $ cast lastArgIndex] targetVariableIndices <- traverse (storeParameter variableTypes) $ zip argIndices argsWithTypes traverse_ (assign variableTypes) $ zip targetVariableIndices $ zip argIndices parameterTypes - Goto methodStartLabel + goto methodStartLabel where - assign : Map Int InferredType -> (Int, Int, InferredType) -> Asm () + assign : Map Int InferredType -> (Int, Int, InferredType) -> Core () assign types (targetVariableIndex, argIndex, ty) = when (targetVariableIndex /= argIndex) $ do loadVar types ty ty targetVariableIndex @@ -380,12 +394,12 @@ mutual assembleExpr isTailCall returnType (NmApp _ (NmRef _ idrisName) []) = assembleNmAppNilArity isTailCall returnType idrisName assembleExpr isTailCall returnType (NmApp _ (NmRef _ idrisName) args) = - if isSuperCall idrisName args then do Aconstnull; when isTailCall $ asmReturn returnType + if isSuperCall idrisName args then do aconstnull; when isTailCall $ asmReturn returnType else do let jname = jvmName idrisName functionType <- case !(findFunctionType jname) of - Just ty => Pure ty - Nothing => Pure $ MkInferredFunctionType inferredObjectType $ replicate (length args) inferredObjectType + Just ty => pure ty + Nothing => pure $ MkInferredFunctionType inferredObjectType $ replicate (length args) inferredObjectType let paramTypes = parameterTypes functionType if paramTypes == [] then assembleNmAppNilArity isTailCall returnType idrisName @@ -395,27 +409,28 @@ mutual let methodReturnType = InferredFunctionType.returnType functionType let methodDescriptor = getMethodDescriptor $ MkInferredFunctionType methodReturnType paramTypes let functionName = getIdrisFunctionName !getProgramName (className jname) (methodName jname) - InvokeMethod InvokeStatic (className functionName) (methodName functionName) methodDescriptor False + invokeMethod InvokeStatic (className functionName) (methodName functionName) methodDescriptor False asmCast methodReturnType returnType when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmApp _ lambdaVariable [arg]) = do assembleExpr False inferredLambdaType lambdaVariable assembleExpr False IUnknown arg - InvokeMethod InvokeInterface "java/util/function/Function" "apply" "(Ljava/lang/Object;)Ljava/lang/Object;" True + invokeMethod InvokeInterface "java/util/function/Function" "apply" "(Ljava/lang/Object;)Ljava/lang/Object;" True asmCast inferredObjectType returnType when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType expr@(NmCon _ _ NOTHING _ []) = assembleNothing isTailCall returnType - assembleExpr isTailCall returnType expr@(NmCon fc _ NOTHING _ _) = Throw fc "Invalid NOTHING constructor" + assembleExpr isTailCall returnType expr@(NmCon fc _ NOTHING _ _) = + throw $ GenericMsg fc "Invalid NOTHING constructor" assembleExpr isTailCall returnType expr@(NmCon _ _ JUST _ [value]) = assembleJust isTailCall returnType value - assembleExpr isTailCall returnType expr@(NmCon fc _ JUST _ _) = Throw fc "Invalid JUST constructor" + assembleExpr isTailCall returnType expr@(NmCon fc _ JUST _ _) = throw $ GenericMsg fc "Invalid JUST constructor" assembleExpr isTailCall returnType expr@(NmCon _ _ NIL _ []) = assembleNil isTailCall returnType - assembleExpr isTailCall returnType expr@(NmCon fc _ NIL _ _) = Throw fc "Invalid NIL constructor" + assembleExpr isTailCall returnType expr@(NmCon fc _ NIL _ _) = throw $ GenericMsg fc "Invalid NIL constructor" assembleExpr isTailCall returnType expr@(NmCon _ _ CONS _ [head, tail]) = assembleCons isTailCall returnType head tail - assembleExpr isTailCall returnType expr@(NmCon fc _ CONS _ _) = Throw fc "Invalid CONS constructor" + assembleExpr isTailCall returnType expr@(NmCon fc _ CONS _ _) = throw $ GenericMsg fc "Invalid CONS constructor" assembleExpr isTailCall returnType expr@(NmCon fc name conInfo tag args) = assembleCon isTailCall returnType fc name tag args @@ -428,7 +443,7 @@ mutual when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmForce _ _ expr) = do assembleExpr False delayedType expr - InvokeMethod InvokeStatic runtimeClass "force" "(Ljava/lang/Object;)Ljava/lang/Object;" False + invokeMethod InvokeStatic runtimeClass "force" "(Ljava/lang/Object;)Ljava/lang/Object;" False asmCast inferredObjectType returnType when isTailCall $ asmReturn returnType @@ -465,73 +480,74 @@ mutual asmCast inferredBigIntegerType returnType when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmPrimVal fc (Str value)) = do - Ldc $ StringConst value + ldc $ StringConst value asmCast inferredStringType returnType when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmPrimVal fc (Ch value)) = do - Iconst $ cast value + iconst $ cast value asmCast IChar returnType when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmPrimVal fc (Db value)) = do - Ldc $ DoubleConst value + ldc $ DoubleConst value asmCast IDouble returnType when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmPrimVal fc _) = do - Iconst 0 + iconst 0 asmCast IInt returnType when isTailCall $ asmReturn returnType - assembleExpr isTailCall IInt (NmErased fc) = do Iconst 0; when isTailCall $ asmReturn IInt - assembleExpr isTailCall IChar (NmErased fc) = do Iconst 0; when isTailCall $ asmReturn IChar - assembleExpr isTailCall IDouble (NmErased fc) = do Ldc $ DoubleConst 0; when isTailCall $ asmReturn IDouble - assembleExpr isTailCall returnType (NmErased fc) = do Aconstnull; when isTailCall $ asmReturn returnType + assembleExpr isTailCall IInt (NmErased fc) = do iconst 0; when isTailCall $ asmReturn IInt + assembleExpr isTailCall IChar (NmErased fc) = do iconst 0; when isTailCall $ asmReturn IChar + assembleExpr isTailCall IDouble (NmErased fc) = do ldc $ DoubleConst 0; when isTailCall $ asmReturn IDouble + assembleExpr isTailCall returnType (NmErased fc) = do aconstnull; when isTailCall $ asmReturn returnType assembleExpr isTailCall returnType (NmCrash fc msg) = do - Ldc $ StringConst msg - InvokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False + ldc $ StringConst msg + invokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False asmCast inferredObjectType returnType when isTailCall $ asmReturn returnType - assembleExpr _ _ expr = Throw (getFC expr) $ "Cannot compile " ++ show expr ++ " yet" + assembleExpr _ _ expr = throw $ GenericMsg (getFC expr) $ "Cannot compile " ++ show expr ++ " yet" - castInt : InferredType -> Asm() -> NamedCExp -> Asm () + castInt : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Core () -> NamedCExp -> Core () castInt returnType conversionOp expr = jassembleCast returnType IInt IInt conversionOp expr - jassembleCast : InferredType -> InferredType -> InferredType -> Asm() -> NamedCExp -> Asm () + jassembleCast : {auto stateRef: Ref AsmState AsmState} -> InferredType -> InferredType -> InferredType -> Core () + -> NamedCExp -> Core () jassembleCast returnType from to conversionOp expr = do assembleExpr False from expr conversionOp asmCast to returnType - assembleNmAppNilArity : (isTailCall : Bool) -> InferredType -> Name -> Asm () + assembleNmAppNilArity : {auto stateRef: Ref AsmState AsmState} -> (isTailCall : Bool) -> InferredType -> Name -> Core () assembleNmAppNilArity isTailCall returnType idrisName = do let jname = jvmName idrisName let functionName = getIdrisFunctionName !getProgramName (className jname) (methodName jname) - Field GetStatic (className functionName) (methodName functionName) + field GetStatic (className functionName) (methodName functionName) "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" - InvokeMethod InvokeVirtual "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "evaluate" + invokeMethod InvokeVirtual "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "evaluate" "()Ljava/lang/Object;" False asmCast inferredObjectType returnType when isTailCall $ asmReturn returnType - unsignedIntToBigInteger : Asm () + unsignedIntToBigInteger : {auto stateRef: Ref AsmState AsmState} -> Core () unsignedIntToBigInteger = do - InvokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False - InvokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False + invokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False + invokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False - unsignedIntToString : Asm () - unsignedIntToString = InvokeMethod InvokeStatic "java/lang/Integer" "toUnsignedString" "(I)Ljava/lang/String;" False + unsignedIntToString : {auto stateRef: Ref AsmState AsmState} -> Core () + unsignedIntToString = invokeMethod InvokeStatic "java/lang/Integer" "toUnsignedString" "(I)Ljava/lang/String;" False - bigIntegerToInt : Asm () -> Asm () + bigIntegerToInt : {auto stateRef: Ref AsmState AsmState} -> Core () -> Core () bigIntegerToInt op = do - InvokeMethod InvokeVirtual "java/math/BigInteger" "intValue" "()I" False + invokeMethod InvokeVirtual "java/math/BigInteger" "intValue" "()I" False op - assembleCon : (isTailCall: Bool) -> InferredType -> FC -> Name -> (tag : Maybe Int) -> List NamedCExp -> Asm () + assembleCon : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> FC -> Name -> (tag : Maybe Int) -> List NamedCExp -> Core () assembleCon isTailCall returnType fc name tag args = do let fileName = fst $ getSourceLocationFromFc fc let constructorClassName = getIdrisConstructorClassName (jvmSimpleName name) let constructorType = maybe inferredStringType (const IInt) tag - New constructorClassName - Dup - maybe (Ldc . StringConst $ constructorClassName) Iconst tag + new constructorClassName + dup + maybe (ldc . StringConst $ constructorClassName) iconst tag let constructorParameterCountNat = length args let constructorParameterCount = the Int $ cast constructorParameterCountNat let constructorTypes = constructorType :: replicate constructorParameterCountNat inferredObjectType @@ -539,411 +555,412 @@ mutual traverse_ assembleParameter argsWithTypes let descriptor = getMethodDescriptor $ MkInferredFunctionType IVoid constructorTypes globalState <- getGlobalState - hasConstructor <- LiftIo $ AsmGlobalState.hasConstructor globalState constructorClassName + hasConstructor <- coreLift $ AsmGlobalState.hasConstructor globalState constructorClassName when (not hasConstructor) $ do - LiftIo $ AsmGlobalState.addConstructor globalState constructorClassName - CreateIdrisConstructorClass constructorClassName (isNothing tag) constructorParameterCount - InvokeMethod InvokeSpecial constructorClassName "" descriptor False + coreLift $ AsmGlobalState.addConstructor globalState constructorClassName + createIdrisConstructorClass constructorClassName (isNothing tag) constructorParameterCount + invokeMethod InvokeSpecial constructorClassName "" descriptor False asmCast idrisObjectType returnType when isTailCall $ asmReturn returnType - assembleCons : (isTailCall: Bool) -> InferredType -> NamedCExp -> NamedCExp -> Asm () + assembleCons : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> NamedCExp -> NamedCExp -> Core () assembleCons isTailCall returnType head tail = do - New idrisConsClass - Dup + new idrisConsClass + dup assembleExpr False inferredObjectType head assembleExpr False inferredObjectType tail - InvokeMethod InvokeSpecial idrisConsClass "" "(Ljava/lang/Object;Ljava/lang/Object;)V" False + invokeMethod InvokeSpecial idrisConsClass "" "(Ljava/lang/Object;Ljava/lang/Object;)V" False asmCast idrisObjectType returnType when isTailCall $ asmReturn returnType - assembleJust : (isTailCall: Bool) -> InferredType -> NamedCExp -> Asm () + assembleJust : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> NamedCExp -> Core () assembleJust isTailCall returnType value = do - New idrisJustClass - Dup + new idrisJustClass + dup assembleExpr False inferredObjectType value - InvokeMethod InvokeSpecial idrisJustClass "" "(Ljava/lang/Object;)V" False + invokeMethod InvokeSpecial idrisJustClass "" "(Ljava/lang/Object;)V" False asmCast idrisObjectType returnType when isTailCall $ asmReturn returnType - assembleConstructorSwitchExpr : NamedCExp -> Asm Int + assembleConstructorSwitchExpr : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core Int assembleConstructorSwitchExpr (NmLocal _ loc) = getVariableIndex $ jvmSimpleName loc assembleConstructorSwitchExpr sc = do idrisObjectVariableIndex <- getVariableIndex $ "constructorSwitchValue" ++ show !newDynamicVariableIndex assembleExpr False idrisObjectType sc storeVar idrisObjectType idrisObjectType idrisObjectVariableIndex - Pure idrisObjectVariableIndex + pure idrisObjectVariableIndex - assembleExprBinaryOp : InferredType -> InferredType -> Asm () -> NamedCExp -> NamedCExp -> Asm () + assembleExprBinaryOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> InferredType -> Core () + -> NamedCExp -> NamedCExp -> Core () assembleExprBinaryOp returnType exprType operator expr1 expr2 = do assembleExpr False exprType expr1 assembleExpr False exprType expr2 operator asmCast exprType returnType - assembleExprBinaryBoolOp : InferredType -> InferredType -> (String -> Asm ()) -> - NamedCExp -> NamedCExp -> Asm () + assembleExprBinaryBoolOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> InferredType + -> (String -> Core ()) -> NamedCExp -> NamedCExp -> Core () assembleExprBinaryBoolOp returnType exprType operator expr1 expr2 = do assembleExpr False exprType expr1 assembleExpr False exprType expr2 ifLabel <- newLabel - CreateLabel ifLabel + createLabel ifLabel elseLabel <- newLabel - CreateLabel elseLabel + createLabel elseLabel endLabel <- newLabel - CreateLabel endLabel + createLabel endLabel operator elseLabel - LabelStart ifLabel - Iconst 1 - Goto endLabel - LabelStart elseLabel - Iconst 0 - LabelStart endLabel + labelStart ifLabel + iconst 1 + goto endLabel + labelStart elseLabel + iconst 0 + labelStart endLabel asmCast IInt returnType - assembleExprComparableBinaryBoolOp : InferredType -> String -> (String -> Asm ()) -> - NamedCExp -> NamedCExp -> Asm () + assembleExprComparableBinaryBoolOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> String -> (String -> Core ()) -> + NamedCExp -> NamedCExp -> Core () assembleExprComparableBinaryBoolOp returnType className operator expr1 expr2 = do let exprType = IRef className Class [] assembleExpr False exprType expr1 assembleExpr False exprType expr2 ifLabel <- newLabel - CreateLabel ifLabel + createLabel ifLabel elseLabel <- newLabel - CreateLabel elseLabel + createLabel elseLabel endLabel <- newLabel - CreateLabel endLabel - InvokeMethod InvokeVirtual className "compareTo" ("(L" ++ className ++ ";)I") False + createLabel endLabel + invokeMethod InvokeVirtual className "compareTo" ("(L" ++ className ++ ";)I") False operator elseLabel - LabelStart ifLabel - Iconst 1 - Goto endLabel - LabelStart elseLabel - Iconst 0 - LabelStart endLabel + labelStart ifLabel + iconst 1 + goto endLabel + labelStart elseLabel + iconst 0 + labelStart endLabel asmCast IInt returnType - assembleExprUnaryOp : InferredType -> InferredType -> Asm () -> NamedCExp -> Asm () + assembleExprUnaryOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> InferredType -> Core () -> NamedCExp -> Core () assembleExprUnaryOp returnType exprType operator expr = do assembleExpr False exprType expr operator asmCast exprType returnType - assembleStrCons : InferredType -> (char: NamedCExp) -> (str: NamedCExp) -> Asm () + assembleStrCons : {auto stateRef: Ref AsmState AsmState} -> InferredType -> (char: NamedCExp) -> (str: NamedCExp) -> Core () assembleStrCons returnType char str = do - New "java/lang/StringBuilder" - Dup - InvokeMethod InvokeSpecial "java/lang/StringBuilder" "" "()V" False + new "java/lang/StringBuilder" + dup + invokeMethod InvokeSpecial "java/lang/StringBuilder" "" "()V" False assembleExpr False IChar char - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(C)Ljava/lang/StringBuilder;" False + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(C)Ljava/lang/StringBuilder;" False assembleExpr False inferredStringType str - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;" False - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;" False + invokeMethod InvokeVirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;" False asmCast inferredStringType returnType - assembleStrReverse : InferredType -> NamedCExp -> Asm () + assembleStrReverse : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> Core () assembleStrReverse returnType str = do - New "java/lang/StringBuilder" - Dup + new "java/lang/StringBuilder" + dup assembleExpr False inferredStringType str - InvokeMethod InvokeSpecial "java/lang/StringBuilder" "" "(Ljava/lang/String;)V" False - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "reverse" "()Ljava/lang/StringBuilder;" False - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;" False + invokeMethod InvokeSpecial "java/lang/StringBuilder" "" "(Ljava/lang/String;)V" False + invokeMethod InvokeVirtual "java/lang/StringBuilder" "reverse" "()Ljava/lang/StringBuilder;" False + invokeMethod InvokeVirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;" False asmCast inferredStringType returnType - compareUnsignedLong : (String -> Asm ()) -> String -> Asm () + compareUnsignedLong : {auto stateRef: Ref AsmState AsmState} -> (String -> Core ()) -> String -> Core () compareUnsignedLong op label = do longCompareUnsigned; op label - compareUnsignedInt : (String -> Asm ()) -> String -> Asm () + compareUnsignedInt : {auto stateRef: Ref AsmState AsmState} -> (String -> Core ()) -> String -> Core () compareUnsignedInt op label = do integerCompareUnsigned; op label - compareSignedLong : (String -> Asm ()) -> String -> Asm () - compareSignedLong op label = do Lcmp; op label + compareSignedLong : {auto stateRef: Ref AsmState AsmState} -> (String -> Core ()) -> String -> Core () + compareSignedLong op label = do lcmp; op label - assembleCast : InferredType -> FC -> PrimType -> PrimType -> NamedCExp -> Asm () + assembleCast : {auto stateRef: Ref AsmState AsmState} -> InferredType -> FC -> PrimType -> PrimType -> NamedCExp -> Core () assembleCast returnType fc from to x = jassembleCast returnType (getInferredType from) (getInferredType to) (getCastAsmOp from to) x - getCastAsmOp : PrimType -> PrimType -> Asm () + getCastAsmOp : {auto stateRef: Ref AsmState AsmState} -> PrimType -> PrimType -> Core () getCastAsmOp IntegerType Bits8Type = do - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(Ljava/math/BigInteger;I)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(Ljava/math/BigInteger;I)I" False getCastAsmOp IntegerType Bits16Type = do - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(Ljava/math/BigInteger;I)I" False + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(Ljava/math/BigInteger;I)I" False getCastAsmOp IntegerType Bits32Type = do - Iconst 32 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(Ljava/math/BigInteger;I)I" False + iconst 32 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(Ljava/math/BigInteger;I)I" False getCastAsmOp IntegerType Bits64Type = do - Iconst 64 - InvokeMethod InvokeStatic conversionClass "toUnsignedLong" "(Ljava/math/BigInteger;I)J" False - getCastAsmOp IntegerType Int64Type = InvokeMethod InvokeVirtual "java/math/BigInteger" "longValue" "()J" False - getCastAsmOp IntegerType Int16Type = bigIntegerToInt I2s - getCastAsmOp IntegerType Int32Type = bigIntegerToInt (Pure ()) - getCastAsmOp IntegerType Int8Type = bigIntegerToInt I2b - getCastAsmOp IntegerType IntType = bigIntegerToInt (Pure ()) + iconst 64 + invokeMethod InvokeStatic conversionClass "toUnsignedLong" "(Ljava/math/BigInteger;I)J" False + getCastAsmOp IntegerType Int64Type = invokeMethod InvokeVirtual "java/math/BigInteger" "longValue" "()J" False + getCastAsmOp IntegerType Int16Type = bigIntegerToInt i2s + getCastAsmOp IntegerType Int32Type = bigIntegerToInt (pure ()) + getCastAsmOp IntegerType Int8Type = bigIntegerToInt i2b + getCastAsmOp IntegerType IntType = bigIntegerToInt (pure ()) getCastAsmOp IntegerType CharType = - bigIntegerToInt (InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False) - getCastAsmOp IntegerType DoubleType = InvokeMethod InvokeVirtual "java/math/BigInteger" "doubleValue" "()D" False - getCastAsmOp IntegerType StringType = InvokeMethod InvokeVirtual "java/math/BigInteger" "toString" "()Ljava/lang/String;" False + bigIntegerToInt (invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False) + getCastAsmOp IntegerType DoubleType = invokeMethod InvokeVirtual "java/math/BigInteger" "doubleValue" "()D" False + getCastAsmOp IntegerType StringType = invokeMethod InvokeVirtual "java/math/BigInteger" "toString" "()Ljava/lang/String;" False - getCastAsmOp Int8Type Bits64Type = I2l + getCastAsmOp Int8Type Bits64Type = i2l getCastAsmOp Int8Type IntegerType = intToBigInteger - getCastAsmOp Int8Type Int64Type = I2l - getCastAsmOp Int8Type DoubleType = I2d - getCastAsmOp Int8Type CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + getCastAsmOp Int8Type Int64Type = i2l + getCastAsmOp Int8Type DoubleType = i2d + getCastAsmOp Int8Type CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False - getCastAsmOp Int16Type Int8Type = I2b + getCastAsmOp Int16Type Int8Type = i2b getCastAsmOp Int16Type IntegerType = intToBigInteger - getCastAsmOp Int16Type Bits64Type = I2l - getCastAsmOp Int16Type Int64Type = I2l - getCastAsmOp Int16Type DoubleType = I2d - getCastAsmOp Int16Type CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False - - getCastAsmOp Int32Type Int8Type = I2b - getCastAsmOp Int32Type Int16Type = I2s - getCastAsmOp Int32Type Int64Type = I2l - getCastAsmOp Int32Type Bits64Type = I2l + getCastAsmOp Int16Type Bits64Type = i2l + getCastAsmOp Int16Type Int64Type = i2l + getCastAsmOp Int16Type DoubleType = i2d + getCastAsmOp Int16Type CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + + getCastAsmOp Int32Type Int8Type = i2b + getCastAsmOp Int32Type Int16Type = i2s + getCastAsmOp Int32Type Int64Type = i2l + getCastAsmOp Int32Type Bits64Type = i2l getCastAsmOp Int32Type Bits16Type = toUnsignedInt 16 getCastAsmOp Int32Type Bits8Type = toUnsignedInt 8 getCastAsmOp Int32Type IntegerType = intToBigInteger - getCastAsmOp Int32Type DoubleType = I2d - getCastAsmOp Int32Type CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + getCastAsmOp Int32Type DoubleType = i2d + getCastAsmOp Int32Type CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False - getCastAsmOp IntType Int8Type = I2b - getCastAsmOp IntType Int16Type = I2s - getCastAsmOp IntType Int64Type = I2l - getCastAsmOp IntType Bits64Type = I2l + getCastAsmOp IntType Int8Type = i2b + getCastAsmOp IntType Int16Type = i2s + getCastAsmOp IntType Int64Type = i2l + getCastAsmOp IntType Bits64Type = i2l getCastAsmOp IntType Bits16Type = toUnsignedInt 16 getCastAsmOp IntType Bits8Type = toUnsignedInt 8 getCastAsmOp IntType IntegerType = intToBigInteger - getCastAsmOp IntType DoubleType = I2d - getCastAsmOp IntType CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + getCastAsmOp IntType DoubleType = i2d + getCastAsmOp IntType CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False getCastAsmOp DoubleType StringType = - InvokeMethod InvokeStatic "java/lang/Double" "toString" "(D)Ljava/lang/String;" False + invokeMethod InvokeStatic "java/lang/Double" "toString" "(D)Ljava/lang/String;" False getCastAsmOp DoubleType IntegerType = do - InvokeMethod InvokeStatic "java/math/BigDecimal" "valueOf" "(D)Ljava/math/BigDecimal;" False - InvokeMethod InvokeVirtual "java/math/BigDecimal" "toBigInteger" "()Ljava/math/BigInteger;" False - getCastAsmOp DoubleType Bits8Type = do D2i; toUnsignedInt 8 - getCastAsmOp DoubleType Bits16Type = do D2i; toUnsignedInt 16 - getCastAsmOp DoubleType Bits32Type = do D2l; L2i - getCastAsmOp DoubleType Bits64Type = InvokeMethod InvokeStatic conversionClass "toLong" "(D)J" False - getCastAsmOp DoubleType IntType = do D2l; L2i - getCastAsmOp DoubleType Int8Type = do D2i; I2b - getCastAsmOp DoubleType Int16Type = do D2i; I2s - getCastAsmOp DoubleType Int32Type = do D2l; L2i - getCastAsmOp DoubleType Int64Type = InvokeMethod InvokeStatic conversionClass "toLong" "(D)J" False - getCastAsmOp DoubleType _ = D2i + invokeMethod InvokeStatic "java/math/BigDecimal" "valueOf" "(D)Ljava/math/BigDecimal;" False + invokeMethod InvokeVirtual "java/math/BigDecimal" "toBigInteger" "()Ljava/math/BigInteger;" False + getCastAsmOp DoubleType Bits8Type = do d2i; toUnsignedInt 8 + getCastAsmOp DoubleType Bits16Type = do d2i; toUnsignedInt 16 + getCastAsmOp DoubleType Bits32Type = do d2l; l2i + getCastAsmOp DoubleType Bits64Type = invokeMethod InvokeStatic conversionClass "toLong" "(D)J" False + getCastAsmOp DoubleType IntType = do d2l; l2i + getCastAsmOp DoubleType Int8Type = do d2i; i2b + getCastAsmOp DoubleType Int16Type = do d2i; i2s + getCastAsmOp DoubleType Int32Type = do d2l; l2i + getCastAsmOp DoubleType Int64Type = invokeMethod InvokeStatic conversionClass "toLong" "(D)J" False + getCastAsmOp DoubleType _ = d2i getCastAsmOp CharType IntegerType = do - I2l - InvokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False - getCastAsmOp CharType Bits64Type = I2l - getCastAsmOp CharType Int64Type = I2l - getCastAsmOp CharType DoubleType = I2d + i2l + invokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False + getCastAsmOp CharType Bits64Type = i2l + getCastAsmOp CharType Int64Type = i2l + getCastAsmOp CharType DoubleType = i2d getCastAsmOp CharType StringType = - InvokeMethod InvokeStatic "java/lang/Character" "toString" "(C)Ljava/lang/String;" False - getCastAsmOp CharType _ = Pure () + invokeMethod InvokeStatic "java/lang/Character" "toString" "(C)Ljava/lang/String;" False + getCastAsmOp CharType _ = pure () getCastAsmOp Bits8Type Bits16Type = do - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp Bits8Type Bits32Type = do - I2l - Iconst 32 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + i2l + iconst 32 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp Bits8Type Bits64Type = do - Iconst 64 - InvokeMethod InvokeStatic conversionClass "toUnsignedLong" "(II)J" False + iconst 64 + invokeMethod InvokeStatic conversionClass "toUnsignedLong" "(II)J" False getCastAsmOp Bits8Type IntegerType = unsignedIntToBigInteger - getCastAsmOp Bits8Type Int8Type = I2b - getCastAsmOp Bits8Type Int16Type = I2s - getCastAsmOp Bits8Type Int64Type = I2l - getCastAsmOp Bits8Type CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + getCastAsmOp Bits8Type Int8Type = i2b + getCastAsmOp Bits8Type Int16Type = i2s + getCastAsmOp Bits8Type Int64Type = i2l + getCastAsmOp Bits8Type CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False getCastAsmOp Bits8Type StringType = unsignedIntToString - getCastAsmOp Bits8Type DoubleType = I2d - getCastAsmOp Bits8Type _ = Pure () + getCastAsmOp Bits8Type DoubleType = i2d + getCastAsmOp Bits8Type _ = pure () getCastAsmOp Bits16Type Bits8Type = do - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp Bits16Type Bits32Type = do - I2l - Iconst 32 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False - getCastAsmOp Bits16Type IntType = Pure () + i2l + iconst 32 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + getCastAsmOp Bits16Type IntType = pure () getCastAsmOp Bits16Type Bits64Type = do - Iconst 64 - InvokeMethod InvokeStatic conversionClass "toUnsignedLong" "(II)J" False + iconst 64 + invokeMethod InvokeStatic conversionClass "toUnsignedLong" "(II)J" False getCastAsmOp Bits16Type IntegerType = unsignedIntToBigInteger - getCastAsmOp Bits16Type Int8Type = I2b - getCastAsmOp Bits16Type Int16Type = I2s - getCastAsmOp Bits16Type Int64Type = I2l - getCastAsmOp Bits16Type CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False - getCastAsmOp Bits16Type DoubleType = I2d + getCastAsmOp Bits16Type Int8Type = i2b + getCastAsmOp Bits16Type Int16Type = i2s + getCastAsmOp Bits16Type Int64Type = i2l + getCastAsmOp Bits16Type CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + getCastAsmOp Bits16Type DoubleType = i2d getCastAsmOp Bits16Type StringType = unsignedIntToString getCastAsmOp Bits32Type Bits8Type = do - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp Bits32Type Bits16Type = do - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False - getCastAsmOp Bits32Type IntType = Pure () + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + getCastAsmOp Bits32Type IntType = pure () getCastAsmOp Bits32Type Bits64Type = - InvokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False + invokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False getCastAsmOp Bits32Type IntegerType = unsignedIntToBigInteger - getCastAsmOp Bits32Type Int8Type = I2b - getCastAsmOp Bits32Type Int16Type = I2s - getCastAsmOp Bits32Type Int64Type = InvokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False + getCastAsmOp Bits32Type Int8Type = i2b + getCastAsmOp Bits32Type Int16Type = i2s + getCastAsmOp Bits32Type Int64Type = invokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False getCastAsmOp Bits32Type DoubleType = do - InvokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False - L2d - getCastAsmOp Bits32Type CharType = InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + invokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False + l2d + getCastAsmOp Bits32Type CharType = invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False getCastAsmOp Bits32Type StringType = unsignedIntToString getCastAsmOp Bits64Type Bits8Type = do - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp Bits64Type Bits16Type = do - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp Bits64Type Bits32Type = do - Iconst 32 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + iconst 32 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp Bits64Type IntegerType = - InvokeMethod InvokeStatic conversionClass "toUnsignedBigInteger" "(J)Ljava/math/BigInteger;" False - getCastAsmOp Bits64Type Int64Type = Pure () - getCastAsmOp Bits64Type Int8Type = L2i - getCastAsmOp Bits64Type Int16Type = L2i - getCastAsmOp Bits64Type Int32Type = L2i - getCastAsmOp Bits64Type IntType = L2i - getCastAsmOp Bits64Type DoubleType = InvokeMethod InvokeStatic conversionClass "unsignedLongToDouble" "(J)D" False + invokeMethod InvokeStatic conversionClass "toUnsignedBigInteger" "(J)Ljava/math/BigInteger;" False + getCastAsmOp Bits64Type Int64Type = pure () + getCastAsmOp Bits64Type Int8Type = l2i + getCastAsmOp Bits64Type Int16Type = l2i + getCastAsmOp Bits64Type Int32Type = l2i + getCastAsmOp Bits64Type IntType = l2i + getCastAsmOp Bits64Type DoubleType = invokeMethod InvokeStatic conversionClass "unsignedLongToDouble" "(J)D" False getCastAsmOp Bits64Type CharType = do - L2i - InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + l2i + invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False getCastAsmOp Bits64Type StringType = - InvokeMethod InvokeStatic "java/lang/Long" "toUnsignedString" "(J)Ljava/lang/String;" False + invokeMethod InvokeStatic "java/lang/Long" "toUnsignedString" "(J)Ljava/lang/String;" False getCastAsmOp Int64Type IntegerType = - InvokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False + invokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False getCastAsmOp Int64Type Bits8Type = do - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp Int64Type Bits16Type = do - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp Int64Type Bits32Type = do - Iconst 32 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False - getCastAsmOp Int64Type Bits64Type = Pure () - getCastAsmOp Int64Type Int8Type = L2i - getCastAsmOp Int64Type Int16Type = L2i - getCastAsmOp Int64Type Int32Type = L2i - getCastAsmOp Int64Type IntType = L2i - getCastAsmOp Int64Type DoubleType = L2d - getCastAsmOp Int64Type CharType = do L2i; InvokeMethod InvokeStatic conversionClass "toChar" "(I)C" False + iconst 32 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + getCastAsmOp Int64Type Bits64Type = pure () + getCastAsmOp Int64Type Int8Type = l2i + getCastAsmOp Int64Type Int16Type = l2i + getCastAsmOp Int64Type Int32Type = l2i + getCastAsmOp Int64Type IntType = l2i + getCastAsmOp Int64Type DoubleType = l2d + getCastAsmOp Int64Type CharType = do l2i; invokeMethod InvokeStatic conversionClass "toChar" "(I)C" False getCastAsmOp Int64Type StringType = - InvokeMethod InvokeStatic "java/lang/Long" "toString" "(J)Ljava/lang/String;" False + invokeMethod InvokeStatic "java/lang/Long" "toString" "(J)Ljava/lang/String;" False getCastAsmOp StringType IntegerType = - InvokeMethod InvokeStatic conversionClass "toInteger" "(Ljava/lang/String;)Ljava/math/BigInteger;" False + invokeMethod InvokeStatic conversionClass "toInteger" "(Ljava/lang/String;)Ljava/math/BigInteger;" False getCastAsmOp StringType Bits8Type = do - InvokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + invokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp StringType Bits16Type = do - InvokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + invokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp StringType Bits32Type = do - InvokeMethod InvokeStatic "java/lang/Long" "parseLong" "(Ljava/lang/String;)J" False - L2i + invokeMethod InvokeStatic "java/lang/Long" "parseLong" "(Ljava/lang/String;)J" False + l2i getCastAsmOp StringType Bits64Type = - InvokeMethod InvokeStatic conversionClass "toLong" "(Ljava/lang/String;)J" False + invokeMethod InvokeStatic conversionClass "toLong" "(Ljava/lang/String;)J" False getCastAsmOp StringType Int8Type = do - InvokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False - I2b + invokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False + i2b getCastAsmOp StringType Int16Type = do - InvokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False - I2s + invokeMethod InvokeStatic "java/lang/Integer" "parseInt" "(Ljava/lang/String;)I" False + i2s getCastAsmOp StringType Int32Type = do - InvokeMethod InvokeStatic "java/lang/Long" "parseLong" "(Ljava/lang/String;)J" False - L2i - getCastAsmOp StringType IntType = InvokeMethod InvokeStatic conversionClass "toInt" "(Ljava/lang/String;)I" False + invokeMethod InvokeStatic "java/lang/Long" "parseLong" "(Ljava/lang/String;)J" False + l2i + getCastAsmOp StringType IntType = invokeMethod InvokeStatic conversionClass "toInt" "(Ljava/lang/String;)I" False getCastAsmOp StringType Int64Type = - InvokeMethod InvokeStatic conversionClass "toLong" "(Ljava/lang/String;)J" False + invokeMethod InvokeStatic conversionClass "toLong" "(Ljava/lang/String;)J" False getCastAsmOp StringType DoubleType = - InvokeMethod InvokeStatic "java/lang/Double" "parseDouble" "(Ljava/lang/String;)D" False + invokeMethod InvokeStatic "java/lang/Double" "parseDouble" "(Ljava/lang/String;)D" False getCastAsmOp StringType CharType = do - Iconst 0 - InvokeMethod InvokeVirtual "java/lang/String" "charAt" "(Ljava/lang/String;I)C" False + iconst 0 + invokeMethod InvokeVirtual "java/lang/String" "charAt" "(Ljava/lang/String;I)C" False getCastAsmOp StringType _ = - InvokeMethod InvokeStatic conversionClass "toInt" "(Ljava/lang/String;)I" False + invokeMethod InvokeStatic conversionClass "toInt" "(Ljava/lang/String;)I" False getCastAsmOp _ Bits8Type = do - Iconst 8 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + iconst 8 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp _ Bits16Type = do - Iconst 16 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False + iconst 16 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(II)I" False getCastAsmOp _ Bits32Type = do - I2l - Iconst 32 - InvokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False + i2l + iconst 32 + invokeMethod InvokeStatic conversionClass "toUnsignedInt" "(JI)I" False getCastAsmOp _ Bits64Type = - InvokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False - getCastAsmOp _ Int64Type = I2l + invokeMethod InvokeStatic "java/lang/Integer" "toUnsignedLong" "(I)J" False + getCastAsmOp _ Int64Type = i2l getCastAsmOp _ IntegerType = do - I2l - InvokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False - getCastAsmOp _ DoubleType = I2d + i2l + invokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False + getCastAsmOp _ DoubleType = i2d getCastAsmOp _ StringType = - InvokeMethod InvokeStatic "java/lang/Integer" "toString" "(I)Ljava/lang/String;" False - getCastAsmOp _ _ = Pure () - - assembleExprOp : InferredType -> FC -> PrimFn arity -> Vect arity NamedCExp -> Asm () - assembleExprOp returnType fc (Neg Bits64Type) [x] = assembleExprUnaryOp returnType ILong Lneg x - assembleExprOp returnType fc (ShiftR Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong (do L2i; Lushr) x y - assembleExprOp returnType fc (BAnd Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong Land x y - assembleExprOp returnType fc (BOr Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong Lor x y - assembleExprOp returnType fc (BXOr Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong Lxor x y - - assembleExprOp returnType fc (Neg Int64Type) [x] = assembleExprUnaryOp returnType ILong Lneg x - assembleExprOp returnType fc (ShiftR Int64Type) [x, y] = assembleExprBinaryOp returnType ILong (do L2i; Lshr) x y - assembleExprOp returnType fc (BAnd Int64Type) [x, y] = assembleExprBinaryOp returnType ILong Land x y - assembleExprOp returnType fc (BOr Int64Type) [x, y] = assembleExprBinaryOp returnType ILong Lor x y - assembleExprOp returnType fc (BXOr Int64Type) [x, y] = assembleExprBinaryOp returnType ILong Lxor x y + invokeMethod InvokeStatic "java/lang/Integer" "toString" "(I)Ljava/lang/String;" False + getCastAsmOp _ _ = pure () + + assembleExprOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> FC -> PrimFn arity -> Vect arity NamedCExp -> Core () + assembleExprOp returnType fc (Neg Bits64Type) [x] = assembleExprUnaryOp returnType ILong lneg x + assembleExprOp returnType fc (ShiftR Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong (do l2i; lushr) x y + assembleExprOp returnType fc (BAnd Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong land x y + assembleExprOp returnType fc (BOr Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong lor x y + assembleExprOp returnType fc (BXOr Bits64Type) [x, y] = assembleExprBinaryOp returnType ILong lxor x y + + assembleExprOp returnType fc (Neg Int64Type) [x] = assembleExprUnaryOp returnType ILong lneg x + assembleExprOp returnType fc (ShiftR Int64Type) [x, y] = assembleExprBinaryOp returnType ILong (do l2i; lshr) x y + assembleExprOp returnType fc (BAnd Int64Type) [x, y] = assembleExprBinaryOp returnType ILong land x y + assembleExprOp returnType fc (BOr Int64Type) [x, y] = assembleExprBinaryOp returnType ILong lor x y + assembleExprOp returnType fc (BXOr Int64Type) [x, y] = assembleExprBinaryOp returnType ILong lxor x y assembleExprOp returnType fc (Neg IntegerType) [x] = - let op = InvokeMethod InvokeVirtual "java/math/BigInteger" "negate" "()Ljava/math/BigInteger;" False + let op = invokeMethod InvokeVirtual "java/math/BigInteger" "negate" "()Ljava/math/BigInteger;" False in assembleExprUnaryOp returnType inferredBigIntegerType op x assembleExprOp returnType fc (ShiftR IntegerType) [x, y] = do let op = do - InvokeMethod InvokeVirtual "java/math/BigInteger" "intValueExact" "()I" False - InvokeMethod InvokeVirtual "java/math/BigInteger" "shiftRight" "(I)Ljava/math/BigInteger;" False + invokeMethod InvokeVirtual "java/math/BigInteger" "intValueExact" "()I" False + invokeMethod InvokeVirtual "java/math/BigInteger" "shiftRight" "(I)Ljava/math/BigInteger;" False assembleExprBinaryOp returnType inferredBigIntegerType op x y assembleExprOp returnType fc (BAnd IntegerType) [x, y] = do - let op = InvokeMethod InvokeVirtual "java/math/BigInteger" "and" + let op = invokeMethod InvokeVirtual "java/math/BigInteger" "and" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False assembleExprBinaryOp returnType inferredBigIntegerType op x y assembleExprOp returnType fc (BOr IntegerType) [x, y] = do - let op = InvokeMethod InvokeVirtual "java/math/BigInteger" "or" + let op = invokeMethod InvokeVirtual "java/math/BigInteger" "or" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False assembleExprBinaryOp returnType inferredBigIntegerType op x y assembleExprOp returnType fc (BXOr IntegerType) [x, y] = do - let op = InvokeMethod InvokeVirtual "java/math/BigInteger" "xor" + let op = invokeMethod InvokeVirtual "java/math/BigInteger" "xor" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False assembleExprBinaryOp returnType inferredBigIntegerType op x y - assembleExprOp returnType fc (Add DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble Dadd x y - assembleExprOp returnType fc (Sub DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble Dsub x y - assembleExprOp returnType fc (Mul DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble Dmul x y - assembleExprOp returnType fc (Div DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble Ddiv x y - assembleExprOp returnType fc (Neg DoubleType) [x] = assembleExprUnaryOp returnType IDouble Dneg x + assembleExprOp returnType fc (Add DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble dadd x y + assembleExprOp returnType fc (Sub DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble dsub x y + assembleExprOp returnType fc (Mul DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble dmul x y + assembleExprOp returnType fc (Div DoubleType) [x, y] = assembleExprBinaryOp returnType IDouble ddiv x y + assembleExprOp returnType fc (Neg DoubleType) [x] = assembleExprUnaryOp returnType IDouble dneg x assembleExprOp returnType fc (Add ty) [x, y] = assembleExprBinaryOp returnType (getInferredType ty) (add (jIntKind ty)) x y @@ -955,115 +972,115 @@ mutual assembleExprBinaryOp returnType (getInferredType ty) (div (jIntKind ty)) x y assembleExprOp returnType fc (Mod ty) [x, y] = assembleExprBinaryOp returnType (getInferredType ty) (mod (jIntKind ty)) x y - assembleExprOp returnType fc (Neg ty) [x] = assembleExprUnaryOp returnType IInt Ineg x + assembleExprOp returnType fc (Neg ty) [x] = assembleExprUnaryOp returnType IInt ineg x assembleExprOp returnType fc (ShiftL ty) [x, y] = assembleExprBinaryOp returnType (getInferredType ty) (shl (jIntKind ty)) x y - assembleExprOp returnType fc (ShiftR Bits32Type) [x, y] = assembleExprBinaryOp returnType IInt Iushr x y - assembleExprOp returnType fc (ShiftR ty) [x, y] = assembleExprBinaryOp returnType IInt Ishr x y - assembleExprOp returnType fc (BAnd ty) [x, y] = assembleExprBinaryOp returnType IInt Iand x y - assembleExprOp returnType fc (BOr ty) [x, y] = assembleExprBinaryOp returnType IInt Ior x y - assembleExprOp returnType fc (BXOr ty) [x, y] = assembleExprBinaryOp returnType IInt Ixor x y + assembleExprOp returnType fc (ShiftR Bits32Type) [x, y] = assembleExprBinaryOp returnType IInt iushr x y + assembleExprOp returnType fc (ShiftR ty) [x, y] = assembleExprBinaryOp returnType IInt ishr x y + assembleExprOp returnType fc (BAnd ty) [x, y] = assembleExprBinaryOp returnType IInt iand x y + assembleExprOp returnType fc (BOr ty) [x, y] = assembleExprBinaryOp returnType IInt ior x y + assembleExprOp returnType fc (BXOr ty) [x, y] = assembleExprBinaryOp returnType IInt ixor x y assembleExprOp returnType fc (LT DoubleType) [x, y] = - assembleExprBinaryBoolOp returnType IDouble (\label => do Dcmpg; Ifge label) x y + assembleExprBinaryBoolOp returnType IDouble (\label => do dcmpg; ifge label) x y assembleExprOp returnType fc (LTE DoubleType) [x, y] = - assembleExprBinaryBoolOp returnType IDouble (\label => do Dcmpg; Ifgt label) x y + assembleExprBinaryBoolOp returnType IDouble (\label => do dcmpg; ifgt label) x y assembleExprOp returnType fc (EQ DoubleType) [x, y] = - assembleExprBinaryBoolOp returnType IDouble (\label => do Dcmpl; Ifne label) x y + assembleExprBinaryBoolOp returnType IDouble (\label => do dcmpl; ifne label) x y assembleExprOp returnType fc (GTE DoubleType) [x, y] = - assembleExprBinaryBoolOp returnType IDouble (\label => do Dcmpl; Iflt label) x y + assembleExprBinaryBoolOp returnType IDouble (\label => do dcmpl; iflt label) x y assembleExprOp returnType fc (GT DoubleType) [x, y] = - assembleExprBinaryBoolOp returnType IDouble (\label => do Dcmpl; Ifle label) x y + assembleExprBinaryBoolOp returnType IDouble (\label => do dcmpl; ifle label) x y assembleExprOp returnType fc (LT IntegerType) [x, y] = - assembleExprComparableBinaryBoolOp returnType bigIntegerClass Ifge x y + assembleExprComparableBinaryBoolOp returnType bigIntegerClass ifge x y assembleExprOp returnType fc (LTE IntegerType) [x, y] = - assembleExprComparableBinaryBoolOp returnType bigIntegerClass Ifgt x y + assembleExprComparableBinaryBoolOp returnType bigIntegerClass ifgt x y assembleExprOp returnType fc (EQ IntegerType) [x, y] = - assembleExprComparableBinaryBoolOp returnType bigIntegerClass Ifne x y + assembleExprComparableBinaryBoolOp returnType bigIntegerClass ifne x y assembleExprOp returnType fc (GTE IntegerType) [x, y] = - assembleExprComparableBinaryBoolOp returnType bigIntegerClass Iflt x y + assembleExprComparableBinaryBoolOp returnType bigIntegerClass iflt x y assembleExprOp returnType fc (GT IntegerType) [x, y] = - assembleExprComparableBinaryBoolOp returnType bigIntegerClass Ifle x y + assembleExprComparableBinaryBoolOp returnType bigIntegerClass ifle x y assembleExprOp returnType fc (LT StringType) [x, y] = - assembleExprComparableBinaryBoolOp returnType stringClass Ifge x y + assembleExprComparableBinaryBoolOp returnType stringClass ifge x y assembleExprOp returnType fc (LTE StringType) [x, y] = - assembleExprComparableBinaryBoolOp returnType stringClass Ifgt x y + assembleExprComparableBinaryBoolOp returnType stringClass ifgt x y assembleExprOp returnType fc (EQ StringType) [x, y] = - assembleExprComparableBinaryBoolOp returnType stringClass Ifne x y + assembleExprComparableBinaryBoolOp returnType stringClass ifne x y assembleExprOp returnType fc (GTE StringType) [x, y] = - assembleExprComparableBinaryBoolOp returnType stringClass Iflt x y + assembleExprComparableBinaryBoolOp returnType stringClass iflt x y assembleExprOp returnType fc (GT StringType) [x, y] = - assembleExprComparableBinaryBoolOp returnType stringClass Ifle x y + assembleExprComparableBinaryBoolOp returnType stringClass ifle x y assembleExprOp returnType fc (LT Bits64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong Ifge) x y + assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong ifge) x y assembleExprOp returnType fc (LTE Bits64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong Ifgt) x y + assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong ifgt) x y assembleExprOp returnType fc (EQ Bits64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong Ifne) x y + assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong ifne) x y assembleExprOp returnType fc (GTE Bits64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong Iflt) x y + assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong iflt) x y assembleExprOp returnType fc (GT Bits64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong Ifle) x y + assembleExprBinaryBoolOp returnType ILong (compareUnsignedLong ifle) x y assembleExprOp returnType fc (LT Int64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareSignedLong Ifge) x y + assembleExprBinaryBoolOp returnType ILong (compareSignedLong ifge) x y assembleExprOp returnType fc (LTE Int64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareSignedLong Ifgt) x y + assembleExprBinaryBoolOp returnType ILong (compareSignedLong ifgt) x y assembleExprOp returnType fc (EQ Int64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareSignedLong Ifne) x y + assembleExprBinaryBoolOp returnType ILong (compareSignedLong ifne) x y assembleExprOp returnType fc (GTE Int64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareSignedLong Iflt) x y + assembleExprBinaryBoolOp returnType ILong (compareSignedLong iflt) x y assembleExprOp returnType fc (GT Int64Type) [x, y] = - assembleExprBinaryBoolOp returnType ILong (compareSignedLong Ifle) x y + assembleExprBinaryBoolOp returnType ILong (compareSignedLong ifle) x y assembleExprOp returnType fc (LT Bits32Type) [x, y] = - assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt Ifge) x y + assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt ifge) x y assembleExprOp returnType fc (LTE Bits32Type) [x, y] = - assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt Ifgt) x y + assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt ifgt) x y assembleExprOp returnType fc (EQ Bits32Type) [x, y] = - assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt Ifne) x y + assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt ifne) x y assembleExprOp returnType fc (GTE Bits32Type) [x, y] = - assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt Iflt) x y + assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt iflt) x y assembleExprOp returnType fc (GT Bits32Type) [x, y] = - assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt Ifle) x y + assembleExprBinaryBoolOp returnType IInt (compareUnsignedInt ifle) x y - assembleExprOp returnType fc (LT ty) [x, y] = assembleExprBinaryBoolOp returnType IInt Ificmpge x y - assembleExprOp returnType fc (LTE ty) [x, y] = assembleExprBinaryBoolOp returnType IInt Ificmpgt x y - assembleExprOp returnType fc (EQ ty) [x, y] = assembleExprBinaryBoolOp returnType IInt Ificmpne x y - assembleExprOp returnType fc (GTE ty) [x, y] = assembleExprBinaryBoolOp returnType IInt Ificmplt x y - assembleExprOp returnType fc (GT ty) [x, y] = assembleExprBinaryBoolOp returnType IInt Ificmple x y + assembleExprOp returnType fc (LT ty) [x, y] = assembleExprBinaryBoolOp returnType IInt ificmpge x y + assembleExprOp returnType fc (LTE ty) [x, y] = assembleExprBinaryBoolOp returnType IInt ificmpgt x y + assembleExprOp returnType fc (EQ ty) [x, y] = assembleExprBinaryBoolOp returnType IInt ificmpne x y + assembleExprOp returnType fc (GTE ty) [x, y] = assembleExprBinaryBoolOp returnType IInt ificmplt x y + assembleExprOp returnType fc (GT ty) [x, y] = assembleExprBinaryBoolOp returnType IInt ificmple x y assembleExprOp returnType fc StrLength [x] = do assembleExpr False inferredStringType x - InvokeMethod InvokeVirtual "java/lang/String" "length" "()I" False + invokeMethod InvokeVirtual "java/lang/String" "length" "()I" False asmCast IInt returnType assembleExprOp returnType fc StrHead [x] = do assembleExpr False inferredStringType x - Iconst 0 - InvokeMethod InvokeVirtual "java/lang/String" "charAt" "(I)C" False + iconst 0 + invokeMethod InvokeVirtual "java/lang/String" "charAt" "(I)C" False asmCast IChar returnType assembleExprOp returnType fc StrTail [x] = do assembleExpr False inferredStringType x - Iconst 1 - InvokeMethod InvokeVirtual "java/lang/String" "substring" "(I)Ljava/lang/String;" False + iconst 1 + invokeMethod InvokeVirtual "java/lang/String" "substring" "(I)Ljava/lang/String;" False asmCast inferredStringType returnType assembleExprOp returnType fc StrIndex [x, i] = do assembleExpr False inferredStringType x assembleExpr False IInt i - InvokeMethod InvokeVirtual "java/lang/String" "charAt" "(I)C" False + invokeMethod InvokeVirtual "java/lang/String" "charAt" "(I)C" False asmCast IChar returnType assembleExprOp returnType fc StrCons [x, y] = assembleStrCons returnType x y assembleExprOp returnType fc StrAppend [x, y] = - let op = InvokeMethod InvokeVirtual "java/lang/String" "concat" "(Ljava/lang/String;)Ljava/lang/String;" False + let op = invokeMethod InvokeVirtual "java/lang/String" "concat" "(Ljava/lang/String;)Ljava/lang/String;" False in assembleExprBinaryOp returnType inferredStringType op x y assembleExprOp returnType fc StrReverse [x] = assembleStrReverse returnType x @@ -1072,47 +1089,47 @@ mutual assembleExpr False IInt offset assembleExpr False IInt len assembleExpr False inferredStringType str - InvokeMethod InvokeStatic (getRuntimeClass "Strings") "substring" + invokeMethod InvokeStatic (getRuntimeClass "Strings") "substring" "(IILjava/lang/String;)Ljava/lang/String;" False asmCast inferredStringType returnType -- `e` is Euler's number, which approximates to: 2.718281828459045 assembleExprOp returnType fc DoubleExp [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "exp" "(D)D" False -- Base is `e`. Same as: `pow(e, x) + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "exp" "(D)D" False -- Base is `e`. Same as: `pow(e, x) assembleExprOp returnType fc DoubleLog [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "log" "(D)D" False -- Base is `e`. + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "log" "(D)D" False -- Base is `e`. assembleExprOp returnType fc DoublePow [x, y] = - let op = InvokeMethod InvokeStatic "java/lang/Math" "pow" "(DD)D" False + let op = invokeMethod InvokeStatic "java/lang/Math" "pow" "(DD)D" False in assembleExprBinaryOp returnType IDouble op x y assembleExprOp returnType fc DoubleSin [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "sin" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "sin" "(D)D" False assembleExprOp returnType fc DoubleCos [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "cos" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "cos" "(D)D" False assembleExprOp returnType fc DoubleTan [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "tan" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "tan" "(D)D" False assembleExprOp returnType fc DoubleASin [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "asin" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "asin" "(D)D" False assembleExprOp returnType fc DoubleACos [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "acos" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "acos" "(D)D" False assembleExprOp returnType fc DoubleATan [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "atan" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "atan" "(D)D" False assembleExprOp returnType fc DoubleSqrt [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "sqrt" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "sqrt" "(D)D" False assembleExprOp returnType fc DoubleFloor [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "floor" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "floor" "(D)D" False assembleExprOp returnType fc DoubleCeiling [x] = assembleExprUnaryOp returnType IDouble op x where - op : Asm () - op = InvokeMethod InvokeStatic "java/lang/Math" "ceil" "(D)D" False + op : Core () + op = invokeMethod InvokeStatic "java/lang/Math" "ceil" "(D)D" False assembleExprOp returnType fc (Cast from to) [arg] = assembleCast returnType fc from to arg @@ -1122,15 +1139,16 @@ mutual assembleExprOp returnType fc Crash [_, msg] = do assembleExpr False inferredStringType msg - InvokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False + invokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False asmCast inferredObjectType returnType - assembleExprOp returnType fc op _ = Throw fc ("Unsupported operator " ++ show op) + assembleExprOp returnType fc op _ = throw $ GenericMsg fc ("Unsupported operator " ++ show op) - assembleParameter : (NamedCExp, InferredType) -> Asm () + assembleParameter : {auto stateRef: Ref AsmState AsmState} -> (NamedCExp, InferredType) -> Core () assembleParameter (param, ty) = assembleExpr False ty param - storeParameter : Map Int InferredType -> (Int, NamedCExp, InferredType) -> Asm Int + storeParameter : {auto stateRef: Ref AsmState AsmState} -> Map Int InferredType + -> (Int, NamedCExp, InferredType) -> Core Int storeParameter variableTypes (var, (NmLocal _ loc), ty) = do let valueVariableName = jvmSimpleName loc valueVariableIndex <- getVariableIndex valueVariableName @@ -1140,61 +1158,63 @@ mutual loadVar variableTypes valueVariableType ty valueVariableIndex targetVariableIndex <- getDynamicVariableIndex "tailRecArg" storeVar ty ty targetVariableIndex - Pure targetVariableIndex - else Pure var + pure targetVariableIndex + else pure var storeParameter _ (var, param, ty) = do assembleExpr False ty param targetVariableIndex <- getDynamicVariableIndex "tailRecArg" storeVar ty ty targetVariableIndex - Pure targetVariableIndex + pure targetVariableIndex - createMethodReference : (isTailCall: Bool) -> (arity: Nat) -> Name -> Asm () + createMethodReference : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> (arity: Nat) -> Name -> Core () createMethodReference isTailCall arity name = do let jname = jvmName name functionType <- case !(findFunctionType jname) of - Just ty => Pure ty - Nothing => Pure $ MkInferredFunctionType inferredObjectType $ replicate arity inferredObjectType + Just ty => pure ty + Nothing => pure $ MkInferredFunctionType inferredObjectType $ replicate arity inferredObjectType let methodReturnType = InferredFunctionType.returnType functionType let paramTypes = parameterTypes functionType let methodDescriptor = getMethodDescriptor $ MkInferredFunctionType methodReturnType paramTypes let functionName = getIdrisFunctionName !getProgramName (className jname) (methodName jname) let functionInterface = getFunctionInterface arity let invokeDynamicDescriptor = getMethodDescriptor $ MkInferredFunctionType functionInterface [] - invokeDynamic (className functionName) (methodName functionName) "apply" invokeDynamicDescriptor + asmInvokeDynamic (className functionName) (methodName functionName) "apply" invokeDynamicDescriptor (getSamDesc (getLambdaTypeByArity arity)) methodDescriptor methodDescriptor when (arity > 1) $ do let methodDescriptor = getMethodDescriptor $ MkInferredFunctionType inferredLambdaType [functionInterface] - InvokeMethod InvokeStatic functionsClass "curry" methodDescriptor False + invokeMethod InvokeStatic functionsClass "curry" methodDescriptor False when isTailCall $ asmReturn inferredLambdaType - assembleSubMethodWithScope1 : (isTailCall: Bool) -> InferredType -> (parameterName : Maybe Name) -> - NamedCExp -> Asm () + assembleSubMethodWithScope1 : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType + -> (parameterName : Maybe Name) -> NamedCExp -> Core () assembleSubMethodWithScope1 isTailCall returnType parameterName body = do parentScope <- getScope !getCurrentScopeIndex withScope $ assembleSubMethod isTailCall returnType Nothing parameterName parentScope body - assembleMethodReference : (isTailCall: Bool) -> InferredType -> (isMethodReference : Bool) -> (arity: Nat) -> - (functionName: Name) -> (parameterName : Maybe Name) -> NamedCExp -> Asm () + assembleMethodReference : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType + -> (isMethodReference : Bool) -> (arity: Nat) -> (functionName: Name) + -> (parameterName : Maybe Name) -> NamedCExp -> Core () assembleMethodReference isTailCall returnType isMethodReference arity functionName parameterName body = if isMethodReference then createMethodReference isTailCall arity functionName else assembleSubMethodWithScope1 isTailCall returnType parameterName body - assembleSubMethodWithScope : (isTailCall: Bool) -> InferredType -> (parameterValue: Maybe NamedCExp) -> - (parameterName : Maybe Name) -> NamedCExp -> Asm () + assembleSubMethodWithScope : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType + -> (parameterValue: Maybe NamedCExp) -> (parameterName : Maybe Name) + -> NamedCExp -> Core () assembleSubMethodWithScope isTailCall returnType (Just value) (Just name) body = do parentScope <- getScope !getCurrentScopeIndex let shouldGenerateVariable = name == extractedMethodArgumentName parameterValueVariable <- if shouldGenerateVariable - then Pure $ jvmSimpleName name ++ show !newDynamicVariableIndex - else Pure $ jvmSimpleName name + then pure $ jvmSimpleName name ++ show !newDynamicVariableIndex + else pure $ jvmSimpleName name let parameterValueVariableName = UN $ Basic parameterValueVariable withScope $ assembleSubMethod isTailCall returnType (Just (assembleValue parentScope parameterValueVariable)) (Just parameterValueVariableName) parentScope (substituteVariableSubMethodBody (NmLocal (getFC body) parameterValueVariableName) body) where - assembleValue : Scope -> String -> Asm () + assembleValue : Scope -> String -> Core () assembleValue enclosingScope variableName = do lambdaScopeIndex <- getCurrentScopeIndex updateCurrentScopeIndex (index enclosingScope) @@ -1242,20 +1262,21 @@ mutual assembleSubMethodWithScope isTailCall returnType _ parameterName body = assembleSubMethodWithScope1 isTailCall returnType parameterName body - assembleSubMethod : (isTailCall: Bool) -> InferredType -> (parameterValueExpr: (Maybe (Asm ()))) -> - (parameterName: Maybe Name) -> Scope -> NamedCExp -> Asm () + assembleSubMethod : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType + -> (parameterValueExpr: (Maybe (Core ()))) -> (parameterName: Maybe Name) -> Scope + -> NamedCExp -> Core () assembleSubMethod isTailCall lambdaReturnType parameterValueExpr parameterName declaringScope expr = do scope <- getScope !getCurrentScopeIndex - maybe (Pure ()) (setScopeCounter . succ) (parentIndex scope) + maybe (pure ()) (setScopeCounter . succ) (parentIndex scope) let lambdaBodyReturnType = returnType scope let lambdaType = getLambdaTypeByParameter parameterName when (lambdaType == DelayedLambda) $ do - New "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" - Dup + new "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" + dup let lambdaInterfaceType = getLambdaInterfaceType lambdaType - parameterType <- the (Asm (Maybe InferredType)) $ traverse getVariableType (jvmSimpleName <$> parameterName) - variableTypes <- LiftIo $ Map.values {key=Int} !(loadClosures declaringScope scope) - maybe (Pure ()) id parameterValueExpr + parameterType <- traverseOpt getVariableType (jvmSimpleName <$> parameterName) + variableTypes <- coreLift $ Map.values {key=Int} !(loadClosures declaringScope scope) + maybe (pure ()) id parameterValueExpr let invokeDynamicDescriptor = getMethodDescriptor $ MkInferredFunctionType lambdaInterfaceType variableTypes let isExtracted = isJust parameterValueExpr let implementationMethodReturnType = @@ -1268,145 +1289,146 @@ mutual let lambdaMethodName = methodName lambdaClassMethodName let lambdaClassName = className lambdaClassMethodName let interfaceMethodName = getLambdaInterfaceMethodName lambdaType - let indy = the (Asm ()) $ do + let indy = the (Core ()) $ do let instantiatedMethodDescriptor = getMethodDescriptor $ MkInferredFunctionType implementationMethodReturnType $ toList parameterType - invokeDynamic lambdaClassName lambdaMethodName interfaceMethodName invokeDynamicDescriptor + asmInvokeDynamic lambdaClassName lambdaMethodName interfaceMethodName invokeDynamicDescriptor (getSamDesc lambdaType) implementationMethodDescriptor instantiatedMethodDescriptor when (lambdaType == DelayedLambda) $ - InvokeMethod InvokeSpecial "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "" + invokeMethod InvokeSpecial "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "" "(Lio/github/mmhelloworld/idrisjvm/runtime/Delayed;)V" False let staticCall = do - InvokeMethod InvokeStatic lambdaClassName lambdaMethodName implementationMethodDescriptor False + invokeMethod InvokeStatic lambdaClassName lambdaMethodName implementationMethodDescriptor False asmCast lambdaBodyReturnType lambdaReturnType maybe indy (const staticCall) parameterValueExpr when isTailCall $ if isExtracted then asmReturn lambdaReturnType else asmReturn lambdaInterfaceType - let oldLineNumberLabels = lineNumberLabels !GetState - newLineNumberLabels <- LiftIo $ Map.newTreeMap {key=Int} {value=String} + let oldLineNumberLabels = lineNumberLabels !getState + newLineNumberLabels <- coreLift $ Map.newTreeMap {key=Int} {value=String} updateState $ { lineNumberLabels := newLineNumberLabels } let accessModifiers = if isExtracted then [Public, Static] else [Public, Static, Synthetic] - CreateMethod accessModifiers "" lambdaClassName lambdaMethodName implementationMethodDescriptor + createMethod accessModifiers "" lambdaClassName lambdaMethodName implementationMethodDescriptor Nothing Nothing [] [] - MethodCodeStart + methodCodeStart let labelStart = methodStartLabel let labelEnd = methodEndLabel addLambdaStartLabel scope labelStart - maybe (Pure ()) (\parentScopeIndex => updateScopeStartLabel parentScopeIndex labelStart) (parentIndex scope) + maybe (pure ()) (\parentScopeIndex => updateScopeStartLabel parentScopeIndex labelStart) (parentIndex scope) let lambdaReturnType = if isExtracted then lambdaBodyReturnType else inferredObjectType assembleExpr True lambdaReturnType expr addLambdaEndLabel scope labelEnd - maybe (Pure ()) (\parentScopeIndex => updateScopeEndLabel parentScopeIndex labelEnd) (parentIndex scope) + maybe (pure ()) (\parentScopeIndex => updateScopeEndLabel parentScopeIndex labelEnd) (parentIndex scope) addLocalVariables $ fromMaybe (index scope) (parentIndex scope) - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd updateState $ { lineNumberLabels := oldLineNumberLabels } where - addLambdaStartLabel : Scope -> String -> Asm () + addLambdaStartLabel : Scope -> String -> Core () addLambdaStartLabel scope label = do let scopeIndex = index scope let lineNumberStart = fst $ lineNumbers scope - CreateLabel label - LabelStart label + createLabel label + labelStart label addLineNumber lineNumberStart label updateScopeStartLabel scopeIndex label - addLambdaEndLabel : Scope -> String -> Asm () + addLambdaEndLabel : Scope -> String -> Core () addLambdaEndLabel scope label = do let scopeIndex = index scope let lineNumberEnd = snd $ lineNumbers scope - CreateLabel label - LabelStart label + createLabel label + labelStart label updateScopeEndLabel scopeIndex label readSourceTargetType : Maybe (Entry InferredType InferredType) -> IO (InferredType, InferredType) readSourceTargetType Nothing = pure (IUnknown, IUnknown) readSourceTargetType (Just entry) = Entry.toTuple {k=InferredType} {v=InferredType} entry - loadVariables : Map Int InferredType -> Map Int (Entry InferredType InferredType) -> List Int -> Asm () - loadVariables _ _ [] = Pure () + loadVariables : Map Int InferredType -> Map Int (Entry InferredType InferredType) -> List Int -> Core () + loadVariables _ _ [] = pure () loadVariables declaringScopeVariableTypes types (var :: vars) = do - sourceTargetTypeEntry <- LiftIo $ Map.get types var - (sourceType, targetType) <- LiftIo $ readSourceTargetType $ nullableToMaybe sourceTargetTypeEntry + sourceTargetTypeEntry <- coreLift $ Map.get types var + (sourceType, targetType) <- coreLift $ readSourceTargetType $ nullableToMaybe sourceTargetTypeEntry loadVar declaringScopeVariableTypes sourceType targetType var loadVariables declaringScopeVariableTypes types vars - loadClosures : Scope -> Scope -> Asm (Map Int InferredType) + loadClosures : Scope -> Scope -> Core (Map Int InferredType) loadClosures declaringScope currentScope = case parentIndex currentScope of Just parentScopeIndex => do parentScope <- getScope parentScopeIndex - variableNames <- LiftIo $ Map.keys {value=Int} $ variableIndices parentScope + variableNames <- coreLift $ Map.keys {value=Int} $ variableIndices parentScope variableNameAndIndex <- traverse getVariableNameAndIndex variableNames typesByIndex <- getIndexAndType variableNameAndIndex declaringScopeVariableTypes <- getVariableTypesAtScope (index declaringScope) - indices <- LiftIo $ Map.keys {value=Entry InferredType InferredType} typesByIndex + indices <- coreLift $ Map.keys {value=Entry InferredType InferredType} typesByIndex loadVariables declaringScopeVariableTypes typesByIndex indices - LiftIo $ Map.getValue2 {k=Int} {v1=InferredType} {v2=InferredType} typesByIndex - Nothing => LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} + coreLift $ Map.getValue2 {k=Int} {v1=InferredType} {v2=InferredType} typesByIndex + Nothing => coreLift $ Map.newTreeMap {key=Int} {value=InferredType} where - getVariableNameAndIndex : String -> Asm (String, Int) + getVariableNameAndIndex : String -> Core (String, Int) getVariableNameAndIndex name = do variableIndex <- getVariableIndexAtScope (index declaringScope) name - Pure (name, variableIndex) + pure (name, variableIndex) - getIndexAndType : List (String, Int) -> Asm (Map Int (Entry InferredType InferredType)) + getIndexAndType : List (String, Int) -> Core (Map Int (Entry InferredType InferredType)) getIndexAndType nameAndIndices = do - typesByIndexMap <- LiftIo $ Map.newTreeMap {key=Int} {value=Entry InferredType InferredType} + typesByIndexMap <- coreLift $ Map.newTreeMap {key=Int} {value=Entry InferredType InferredType} go typesByIndexMap - Pure typesByIndexMap + pure typesByIndexMap where - go : Map Int (Entry InferredType InferredType) -> Asm () + go : Map Int (Entry InferredType InferredType) -> Core () go typesByIndexMap = go1 nameAndIndices where - go1 : List (String, Int) -> Asm () - go1 [] = Pure () + go1 : List (String, Int) -> Core () + go1 [] = pure () go1 ((name, varIndex) :: rest) = do targetType <- getVariableType name sourceType <- getVariableTypeAtScope (index declaringScope) name - entry <- LiftIo $ Entry.new sourceType targetType - _ <- LiftIo $ Map.put typesByIndexMap varIndex entry + entry <- coreLift $ Entry.new sourceType targetType + _ <- coreLift $ Map.put typesByIndexMap varIndex entry go1 rest - assembleMissingDefault :InferredType -> FC -> String -> Asm () + assembleMissingDefault : {auto stateRef: Ref AsmState AsmState} ->InferredType -> FC -> String -> Core () assembleMissingDefault returnType fc defaultLabel = do - LabelStart defaultLabel + labelStart defaultLabel defaultValue returnType asmReturn returnType - assembleConstantSwitch : (returnType: InferredType) -> (switchExprType: InferredType) -> FC -> - NamedCExp -> List NamedConstAlt -> Maybe NamedCExp -> Asm () - assembleConstantSwitch _ _ fc _ [] _ = Throw fc "Empty cases" + assembleConstantSwitch : {auto stateRef: Ref AsmState AsmState} -> (returnType: InferredType) + -> (switchExprType: InferredType) -> FC -> NamedCExp -> List NamedConstAlt + -> Maybe NamedCExp -> Core () + assembleConstantSwitch _ _ fc _ [] _ = throw $ GenericMsg fc "Empty cases" assembleConstantSwitch returnType IInt fc sc alts def = do assembleExpr False IInt sc switchCases <- getCasesWithLabels alts let labels = fst <$> switchCases let exprs = second <$> switchCases - traverse_ CreateLabel labels + traverse_ createLabel labels defaultLabel <- createDefaultLabel - LookupSwitch defaultLabel labels exprs + lookupSwitch defaultLabel labels exprs let switchCasesWithEndLabel = getSwitchCasesWithEndLabel switchCases labels traverse_ assembleExprConstAlt switchCasesWithEndLabel maybe (assembleMissingDefault returnType fc defaultLabel) (assembleDefault defaultLabel) def where - getCasesWithLabels : List NamedConstAlt -> Asm (List (String, Int, NamedConstAlt)) + getCasesWithLabels : List NamedConstAlt -> Core (List (String, Int, NamedConstAlt)) getCasesWithLabels alts = do caseExpressionsWithLabels <- traverse (constantAltIntExpr fc) alts - Pure $ sortBy (comparing second) caseExpressionsWithLabels + pure $ sortBy (comparing second) caseExpressionsWithLabels - assembleCaseWithScope : String -> String -> NamedCExp -> Asm () - assembleCaseWithScope labelStart labelEnd expr = withScope $ do + assembleCaseWithScope : String -> String -> NamedCExp -> Core () + assembleCaseWithScope lblStart lblEnd expr = withScope $ do scopeIndex <- getCurrentScopeIndex scope <- getScope scopeIndex let (lineNumberStart, lineNumberEnd) = lineNumbers scope - LabelStart labelStart - updateScopeStartLabel scopeIndex labelStart - addLineNumber lineNumberStart labelStart - updateScopeEndLabel scopeIndex labelEnd + labelStart lblStart + updateScopeStartLabel scopeIndex lblStart + addLineNumber lineNumberStart lblStart + updateScopeEndLabel scopeIndex lblEnd assembleExpr True returnType expr - assembleDefault : String -> NamedCExp -> Asm () + assembleDefault : String -> NamedCExp -> Core () assembleDefault defaultLabel expr = assembleCaseWithScope defaultLabel methodEndLabel expr - assembleExprConstAlt : (String, Int, NamedConstAlt, String) -> Asm () + assembleExprConstAlt : (String, Int, NamedConstAlt, String) -> Core () assembleExprConstAlt (labelStart, _, (MkNConstAlt _ expr), labelEnd) = assembleCaseWithScope labelStart labelEnd expr @@ -1418,8 +1440,8 @@ mutual let labels = fst <$> hashCodeSwitchCases let exprs = second <$> hashCodeSwitchCases switchEndLabel <- newLabel - CreateLabel switchEndLabel - traverse_ CreateLabel labels + createLabel switchEndLabel + traverse_ createLabel labels assembleExpr False constantType sc constantExprVariableSuffixIndex <- newDynamicVariableIndex let constantExprVariableName = "constantCaseExpr" ++ show constantExprVariableSuffixIndex @@ -1429,28 +1451,29 @@ mutual hashCodePositionVariableIndex <- getVariableIndex hashCodePositionVariableName storeVar constantType constantType constantExprVariableIndex constantClass <- getHashCodeSwitchClass fc constantType - Iconst (-1) + iconst (-1) storeVar IInt IInt hashCodePositionVariableIndex loadVar !getVariableTypes constantType constantType constantExprVariableIndex let isLong = constantClass == "java/lang/Long" let invocationType = if isLong then InvokeStatic else InvokeVirtual let signature = if isLong then "(J)I" else "()I" - InvokeMethod invocationType constantClass "hashCode" signature False - LookupSwitch switchEndLabel labels exprs + invokeMethod invocationType constantClass "hashCode" signature False + lookupSwitch switchEndLabel labels exprs traverse_ (assembleHashCodeSwitchCases fc constantClass constantExprVariableIndex hashCodePositionVariableIndex switchEndLabel) hashCodeSwitchCases scope <- getScope !getCurrentScopeIndex let lineNumberStart = fst $ lineNumbers scope - LabelStart switchEndLabel + labelStart switchEndLabel addLineNumber lineNumberStart switchEndLabel assembleConstantSwitch returnType IInt fc (NmLocal fc $ UN $ Basic hashCodePositionVariableName) (hashPositionSwitchAlts hashPositionAndAlts) def where - constantAltHashCodeExpr : FC -> (Int, NamedConstAlt) -> Asm (Int, Int, NamedConstAlt) + constantAltHashCodeExpr : FC + -> (Int, NamedConstAlt) -> Core (Int, Int, NamedConstAlt) constantAltHashCodeExpr fc positionAndAlt@(position, MkNConstAlt constant _) = case hashCode constant of - Just hashCodeValue => Pure (hashCodeValue, position, snd positionAndAlt) + Just hashCodeValue => pure (hashCodeValue, position, snd positionAndAlt) Nothing => asmCrash ("Constant " ++ show constant ++ " cannot be compiled to 'Switch'.") hashPositionSwitchAlts : List (Int, Int, NamedConstAlt) -> List NamedConstAlt @@ -1460,9 +1483,9 @@ mutual go acc ((_, position, (MkNConstAlt _ expr)) :: alts) = go (MkNConstAlt (I position) expr :: acc) alts - assembleHashCodeSwitchCases : FC -> String -> Int -> Int -> String -> - (String, Int, List (Int, NamedConstAlt)) -> Asm () - assembleHashCodeSwitchCases fc _ _ _ _ (_, _, []) = Throw fc "Empty cases" + assembleHashCodeSwitchCases : FC -> String -> Int -> Int + -> String -> (String, Int, List (Int, NamedConstAlt)) -> Core () + assembleHashCodeSwitchCases fc _ _ _ _ (_, _, []) = throw $ GenericMsg fc "Empty cases" assembleHashCodeSwitchCases fc constantClass constantExprVariableIndex hashCodePositionVariableIndex switchEndLabel (label, _, positionAndAlts) = go label positionAndAlts where @@ -1475,122 +1498,122 @@ mutual isComparator : String -> Bool isComparator constantClass = constantClass == "java/lang/Long" - compareConstant : String -> Asm () - compareConstant "java/lang/Long" = Lcmp + compareConstant : String -> Core () + compareConstant "java/lang/Long" = lcmp compareConstant "java/lang/String" = - InvokeMethod InvokeVirtual stringClass "equals" "(Ljava/lang/Object;)Z" False + invokeMethod InvokeVirtual stringClass "equals" "(Ljava/lang/Object;)Z" False compareConstant "java/math/BigInteger" = - InvokeMethod InvokeVirtual bigIntegerClass "equals" "(Ljava/lang/Object;)Z" False + invokeMethod InvokeVirtual bigIntegerClass "equals" "(Ljava/lang/Object;)Z" False compareConstant clazz = asmCrash ("Unknown constant class " ++ clazz ++ " for switch") - switchBody : String -> String -> Int -> NamedConstAlt -> Asm () + switchBody : String -> String -> Int -> NamedConstAlt -> Core () switchBody label nextLabel position (MkNConstAlt constant _) = do scope <- getScope !getCurrentScopeIndex let lineNumberStart = fst $ lineNumbers scope - LabelStart label + labelStart label addLineNumber lineNumberStart label loadVar !getVariableTypes constantType constantType constantExprVariableIndex assembleHashCodeSwitchConstant fc constant compareConstant constantClass - let condition = if isComparator constantClass then Ifne else Ifeq + let condition = if isComparator constantClass then ifne else ifeq condition nextLabel - Iconst position + iconst position storeVar IInt IInt hashCodePositionVariableIndex - Goto switchEndLabel + goto switchEndLabel - go : String -> List (Int, NamedConstAlt) -> Asm () - go _ [] = Pure () + go : String -> List (Int, NamedConstAlt) -> Core () + go _ [] = pure () go label ((position, alt) :: []) = switchBody label switchEndLabel position alt go label ((position, alt) :: positionAndAlts) = do nextLabel <- newLabel switchBody label nextLabel position alt go nextLabel positionAndAlts - assembleConCase : InferredType -> FC -> (sc : NamedCExp) -> List NamedConAlt -> Maybe NamedCExp -> Asm () + assembleConCase : {auto stateRef: Ref AsmState AsmState} -> InferredType -> FC -> (sc : NamedCExp) -> List NamedConAlt -> Maybe NamedCExp -> Core () assembleConCase returnType fc sc alts def = do idrisObjectVariableIndex <- assembleConstructorSwitchExpr sc let hasTypeCase = any isTypeCase alts let constructorType = if hasTypeCase then "Ljava/lang/String;" else "I" variableTypes <- getVariableTypes - optTy <- LiftIo $ Map.get variableTypes idrisObjectVariableIndex + optTy <- coreLift $ Map.get variableTypes idrisObjectVariableIndex let idrisObjectVariableType = fromMaybe IUnknown $ nullableToMaybe optTy loadVar variableTypes idrisObjectVariableType idrisObjectType idrisObjectVariableIndex when (idrisObjectVariableType /= idrisObjectType) $ do storeVar idrisObjectType idrisObjectType idrisObjectVariableIndex loadVar !getVariableTypes idrisObjectType idrisObjectType idrisObjectVariableIndex let constructorGetter = if hasTypeCase then "getStringConstructorId" else "getConstructorId" - InvokeMethod InvokeInterface idrisObjectClass constructorGetter ("()" ++ constructorType) True + invokeMethod InvokeInterface idrisObjectClass constructorGetter ("()" ++ constructorType) True if hasTypeCase then assembleStringConstructorSwitch returnType fc idrisObjectVariableIndex alts def else assembleConstructorSwitch returnType fc idrisObjectVariableIndex alts def - assembleConCaseExpr : InferredType -> Int -> List Name -> NamedCExp -> Asm () + assembleConCaseExpr : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Int -> List Name -> NamedCExp -> Core () assembleConCaseExpr returnType idrisObjectVariableIndex args expr = do variableTypes <- getVariableTypes - optTy <- LiftIo $ Map.get variableTypes idrisObjectVariableIndex + optTy <- coreLift $ Map.get variableTypes idrisObjectVariableIndex let idrisObjectVariableType = fromMaybe IUnknown $ nullableToMaybe optTy bindArg idrisObjectVariableType variableTypes 0 args assembleExpr True returnType expr where - bindArg : InferredType -> Map Int InferredType -> Int -> List Name -> Asm () - bindArg _ _ _ [] = Pure () + bindArg : InferredType -> Map Int InferredType -> Int -> List Name -> Core () + bindArg _ _ _ [] = pure () bindArg idrisObjectVariableType variableTypes index (var :: vars) = do let variableName = jvmSimpleName var when (used variableName expr) $ do loadVar variableTypes idrisObjectVariableType idrisObjectType idrisObjectVariableIndex - Iconst index - InvokeMethod InvokeInterface idrisObjectClass "getProperty" "(I)Ljava/lang/Object;" True + iconst index + invokeMethod InvokeInterface idrisObjectClass "getProperty" "(I)Ljava/lang/Object;" True variableIndex <- getVariableIndex variableName storeVar inferredObjectType !(getVariableType variableName) variableIndex bindArg idrisObjectVariableType variableTypes (index + 1) vars - assembleConstructorSwitch : InferredType -> FC -> Int -> List NamedConAlt -> Maybe NamedCExp -> Asm () + assembleConstructorSwitch : {auto stateRef: Ref AsmState AsmState} -> InferredType -> FC -> Int -> List NamedConAlt -> Maybe NamedCExp -> Core () assembleConstructorSwitch returnType fc idrisObjectVariableIndex alts def = do switchCases <- getCasesWithLabels alts let labels = fst <$> switchCases let switchCasesWithEndLabel = getSwitchCasesWithEndLabel switchCases labels let exprs = caseExpression <$> switchCases - traverse_ CreateLabel labels + traverse_ createLabel labels defaultLabel <- createDefaultLabel - LookupSwitch defaultLabel labels exprs + lookupSwitch defaultLabel labels exprs traverse_ assembleExprConAlt switchCasesWithEndLabel maybe (assembleMissingDefault returnType fc defaultLabel) (assembleDefault defaultLabel) def where caseExpression : (String, Int, NamedConAlt) -> Int caseExpression (_, expr, _) = expr - getCasesWithLabels : List NamedConAlt -> Asm (List (String, Int, NamedConAlt)) + getCasesWithLabels : List NamedConAlt -> Core (List (String, Int, NamedConAlt)) getCasesWithLabels alts = do caseExpressionsWithLabels <- traverse conAltIntExpr alts - Pure $ sortBy (comparing caseExpression) caseExpressionsWithLabels + pure $ sortBy (comparing caseExpression) caseExpressionsWithLabels - assembleDefault : String -> NamedCExp -> Asm () - assembleDefault labelStart expr = withScope $ do + assembleDefault : String -> NamedCExp -> Core () + assembleDefault lblStart expr = withScope $ do scopeIndex <- getCurrentScopeIndex scope <- getScope scopeIndex let (lineNumberStart, lineNumberEnd) = lineNumbers scope - LabelStart labelStart - addLineNumber lineNumberStart labelStart - updateScopeStartLabel scopeIndex labelStart + labelStart lblStart + addLineNumber lineNumberStart lblStart + updateScopeStartLabel scopeIndex lblStart updateScopeEndLabel scopeIndex methodEndLabel assembleExpr True returnType expr - assembleCaseWithScope : String -> String -> List Name -> NamedCExp -> Asm () - assembleCaseWithScope labelStart labelEnd args expr = withScope $ do + assembleCaseWithScope : String -> String -> List Name -> NamedCExp -> Core () + assembleCaseWithScope lblStart lblEnd args expr = withScope $ do scopeIndex <- getCurrentScopeIndex scope <- getScope scopeIndex let (lineNumberStart, lineNumberEnd) = lineNumbers scope - LabelStart labelStart - addLineNumber lineNumberStart labelStart - updateScopeStartLabel scopeIndex labelStart - updateScopeEndLabel scopeIndex labelEnd + labelStart lblStart + addLineNumber lineNumberStart lblStart + updateScopeStartLabel scopeIndex lblStart + updateScopeEndLabel scopeIndex lblEnd assembleConCaseExpr returnType idrisObjectVariableIndex args expr - assembleExprConAlt : (String, Int, NamedConAlt, String) -> Asm () + assembleExprConAlt : (String, Int, NamedConAlt, String) -> Core () assembleExprConAlt (labelStart, _, (MkNConAlt _ _ _ args expr), labelEnd) = assembleCaseWithScope labelStart labelEnd args expr - assembleStringConstructorSwitch : InferredType -> FC -> Int -> List NamedConAlt -> Maybe NamedCExp -> Asm () + assembleStringConstructorSwitch : {auto stateRef: Ref AsmState AsmState} -> InferredType -> FC -> Int -> List NamedConAlt -> Maybe NamedCExp -> Core () assembleStringConstructorSwitch returnType fc idrisObjectVariableIndex alts def = do constantExprVariableSuffixIndex <- newDynamicVariableIndex let constantExprVariableName = "constructorCaseExpr" ++ show constantExprVariableSuffixIndex @@ -1606,31 +1629,31 @@ mutual let labels = fst <$> hashCodeSwitchCases let exprs = second <$> hashCodeSwitchCases switchEndLabel <- newLabel - CreateLabel switchEndLabel - traverse_ CreateLabel labels + createLabel switchEndLabel + traverse_ createLabel labels let constantType = inferredStringType constantClass <- getHashCodeSwitchClass fc constantType - Iconst (-1) + iconst (-1) storeVar IInt IInt hashCodePositionVariableIndex loadVar !getVariableTypes constantType constantType constantExprVariableIndex - InvokeMethod InvokeVirtual constantClass "hashCode" "()I" False - LookupSwitch switchEndLabel labels exprs + invokeMethod InvokeVirtual constantClass "hashCode" "()I" False + lookupSwitch switchEndLabel labels exprs traverse_ (assembleHashCodeSwitchCases fc constantClass constantExprVariableIndex hashCodePositionVariableIndex switchEndLabel) hashCodeSwitchCases scope <- getScope !getCurrentScopeIndex let lineNumberStart = fst $ lineNumbers scope - LabelStart switchEndLabel + labelStart switchEndLabel addLineNumber lineNumberStart switchEndLabel assembleExpr False IInt (NmLocal fc $ UN $ Basic hashCodePositionVariableName) assembleConstructorSwitch returnType fc idrisObjectVariableIndex (hashPositionSwitchAlts hashPositionAndAlts) def where - conAltHashCodeExpr : FC -> (Int, NamedConAlt) -> Asm (Int, Int, NamedConAlt) + conAltHashCodeExpr : FC -> (Int, NamedConAlt) -> Core (Int, Int, NamedConAlt) conAltHashCodeExpr fc positionAndAlt@(position, MkNConAlt name _ _ _ _) = case hashCode (Str $ getIdrisConstructorClassName (jvmSimpleName name)) of - Just hashCodeValue => Pure (hashCodeValue, position, snd positionAndAlt) + Just hashCodeValue => pure (hashCodeValue, position, snd positionAndAlt) Nothing => asmCrash ("Constructor " ++ show name ++ " cannot be compiled to 'Switch'.") hashPositionSwitchAlts : List (Int, Int, NamedConAlt) -> List NamedConAlt @@ -1640,35 +1663,35 @@ mutual go acc ((_, position, (MkNConAlt name conInfo _ args expr)) :: alts) = go (MkNConAlt name conInfo (Just position) args expr :: acc) alts - assembleHashCodeSwitchCases : FC -> String -> Int -> Int -> String -> - (String, Int, List (Int, NamedConAlt)) -> Asm () - assembleHashCodeSwitchCases fc _ _ _ _ (_, _, []) = Throw fc "Empty cases" + assembleHashCodeSwitchCases : FC -> String -> Int -> Int -> String + -> (String, Int, List (Int, NamedConAlt)) -> Core () + assembleHashCodeSwitchCases fc _ _ _ _ (_, _, []) = throw $ GenericMsg fc "Empty cases" assembleHashCodeSwitchCases fc constantClass constantExprVariableIndex hashCodePositionVariableIndex switchEndLabel (label, _, positionAndAlts) = go label positionAndAlts where - switchBody : String -> String -> Int -> NamedConAlt -> Asm () + switchBody : String -> String -> Int -> NamedConAlt -> Core () switchBody label nextLabel position (MkNConAlt name _ _ _ _) = do scope <- getScope !getCurrentScopeIndex let lineNumberStart = fst $ lineNumbers scope - LabelStart label + labelStart label addLineNumber lineNumberStart label loadVar !getVariableTypes inferredStringType inferredStringType constantExprVariableIndex - Ldc $ StringConst $ getIdrisConstructorClassName (jvmSimpleName name) - InvokeMethod InvokeVirtual constantClass "equals" "(Ljava/lang/Object;)Z" False - Ifeq nextLabel - Iconst position + ldc $ StringConst $ getIdrisConstructorClassName (jvmSimpleName name) + invokeMethod InvokeVirtual constantClass "equals" "(Ljava/lang/Object;)Z" False + ifeq nextLabel + iconst position storeVar IInt IInt hashCodePositionVariableIndex - Goto switchEndLabel + goto switchEndLabel - go : String -> List (Int, NamedConAlt) -> Asm () - go _ [] = Pure () + go : String -> List (Int, NamedConAlt) -> Core () + go _ [] = pure () go label ((position, alt) :: []) = switchBody label switchEndLabel position alt go label ((position, alt) :: positionAndAlts) = do nextLabel <- newLabel switchBody label nextLabel position alt go nextLabel positionAndAlts - asmJavaLambda : FC -> InferredType -> NamedCExp -> NamedCExp -> NamedCExp -> Asm () + asmJavaLambda : {auto stateRef: Ref AsmState AsmState} -> FC -> InferredType -> NamedCExp -> NamedCExp -> NamedCExp -> Core () asmJavaLambda fc returnType functionType javaInterfaceType lambda = do assembleExpr False inferredLambdaType lambda lambdaType <- getJavaLambdaType fc [functionType, javaInterfaceType, lambda] @@ -1686,20 +1709,20 @@ mutual lambdaClassMethodName <- getLambdaImplementationMethodName "lambda" let lambdaMethodName = methodName lambdaClassMethodName let lambdaClassName = className lambdaClassMethodName - invokeDynamic lambdaClassName lambdaMethodName lambdaType.methodName invokeDynamicDescriptor + asmInvokeDynamic lambdaClassName lambdaMethodName lambdaType.methodName invokeDynamicDescriptor (getMethodDescriptor samType) implementationMethodDescriptor instantiatedMethodDescriptor asmCast lambdaType.javaInterface returnType let accessModifiers = [Public, Static, Synthetic] - CreateMethod accessModifiers "" lambdaClassName lambdaMethodName implementationMethodDescriptor + createMethod accessModifiers "" lambdaClassName lambdaMethodName implementationMethodDescriptor Nothing Nothing [] [] - MethodCodeStart - Aload 0 + methodCodeStart + aload 0 let arity = (cast {to=Int} $ length implementationParameterTypes) + 1 - typesByIndex <- LiftIo $ Map.fromList $ zip [0 .. arity - 1] + typesByIndex <- coreLift $ Map.fromList $ zip [0 .. arity - 1] (inferredLambdaType :: implementationParameterTypes) applyParameters typesByIndex 1 lambdaImplementationType.returnType implementationParameterTypes - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd where isIoAction : Bool isIoAction = Optimizer.isIoAction functionType @@ -1716,32 +1739,32 @@ mutual updateImplementationType _ functionType = if isIoAction then {parameterTypes $= dropWorldType} functionType else functionType - applyParameter : Map Int InferredType -> (isIoApplication: Bool) -> Int -> InferredType -> Asm () + applyParameter : Map Int InferredType -> (isIoApplication: Bool) -> Int -> InferredType -> Core () applyParameter typesByIndex isIoApplication index parameterType = do loadArgument - InvokeMethod InvokeInterface "java/util/function/Function" "apply" "(Ljava/lang/Object;)Ljava/lang/Object;" True - InvokeMethod InvokeStatic runtimeClass "unwrap" "(Ljava/lang/Object;)Ljava/lang/Object;" False + invokeMethod InvokeInterface "java/util/function/Function" "apply" "(Ljava/lang/Object;)Ljava/lang/Object;" True + invokeMethod InvokeStatic runtimeClass "unwrap" "(Ljava/lang/Object;)Ljava/lang/Object;" False where - loadArgument : Asm () + loadArgument : Core () loadArgument = if isIoApplication then do - Iconst 0 - InvokeMethod InvokeStatic "java/lang/Integer" "valueOf" "(I)Ljava/lang/Integer;" False + iconst 0 + invokeMethod InvokeStatic "java/lang/Integer" "valueOf" "(I)Ljava/lang/Integer;" False else loadVar typesByIndex parameterType inferredObjectType index - applyParameters : Map Int InferredType -> Int -> InferredType -> List InferredType -> Asm () + applyParameters : Map Int InferredType -> Int -> InferredType -> List InferredType -> Core () applyParameters typesByIndex index returnType [] = do when isIoAction $ applyParameter typesByIndex True index inferredObjectType asmCast inferredObjectType returnType - when (returnType == IVoid) Pop + when (returnType == IVoid) pop asmReturn returnType applyParameters typesByIndex index returnType (ty :: rest) = do applyParameter typesByIndex False index ty when (rest /= [] || isIoAction) $ asmCast inferredObjectType inferredLambdaType applyParameters typesByIndex (index + 1) returnType rest - jvmExtPrim : FC -> InferredType -> ExtPrim -> List NamedCExp -> Asm () + jvmExtPrim : {auto stateRef: Ref AsmState AsmState} -> FC -> InferredType -> ExtPrim -> List NamedCExp -> Core () jvmExtPrim fc returnType JvmInstanceMethodCall [ret, NmApp _ _ [functionNamePrimVal], fargs, world] = jvmExtPrim fc returnType JvmInstanceMethodCall [ret, functionNamePrimVal, fargs, world] jvmExtPrim _ returnType JvmInstanceMethodCall [ret, NmPrimVal fc (Str fn), fargs, world] = do @@ -1756,7 +1779,7 @@ mutual let isInterfaceInvocation = isInterfaceInvocation instanceType let invocationType = if isInterfaceInvocation then InvokeInterface else InvokeVirtual let methodDescriptor = getMethodDescriptor $ MkInferredFunctionType methodReturnType argTypes - InvokeMethod invocationType cname mname methodDescriptor isInterfaceInvocation + invokeMethod invocationType cname mname methodDescriptor isInterfaceInvocation asmCast methodReturnType returnType jvmExtPrim fc returnType JvmSuper [clazz, fargs, world] = do rootMethodName <- getRootMethodName @@ -1767,7 +1790,7 @@ mutual | _ => asmCrash ("super constructor should be called with a reference type but got " ++ show clazz) let functionNamePrimVal = NmPrimVal fc (Str (typeName ++ "." ++ "")) jvmExtPrim fc returnType JvmStaticMethodCall [NmErased fc, functionNamePrimVal, fargs, world] - else Aconstnull + else aconstnull jvmExtPrim fc returnType JvmStaticMethodCall [ret, NmApp _ _ [functionNamePrimVal], fargs, world] = jvmExtPrim fc returnType JvmStaticMethodCall [ret, functionNamePrimVal, fargs, world] jvmExtPrim _ returnType JvmStaticMethodCall [ret, NmPrimVal fc (Str fn), fargs, world] = do @@ -1777,17 +1800,17 @@ mutual let (_, mname) = break (/= '.') mnameWithDot let isConstructor = mname == "" when isConstructor $ do - New cname - Dup + new cname + dup let isSuper = mname == "" - when isSuper $ Aload 0 + when isSuper $ aload 0 traverse_ assembleParameter $ zip (map snd args) argTypes - methodReturnType <- if isSuper then Pure IVoid else tySpec ret + methodReturnType <- if isSuper then pure IVoid else tySpec ret let descriptorReturnType = if isConstructor then IVoid else methodReturnType let methodDescriptor = getMethodDescriptor $ MkInferredFunctionType descriptorReturnType argTypes let invocationType = if isConstructor || isSuper then InvokeSpecial else InvokeStatic let mname = if isSuper then "" else mname - InvokeMethod invocationType cname mname methodDescriptor False + invokeMethod invocationType cname mname methodDescriptor False asmCast methodReturnType returnType jvmExtPrim _ returnType SetInstanceField [ret, NmPrimVal fc (Str fn), fargs, world] = do (obj :: value :: []) <- getFArgs fargs @@ -1797,8 +1820,8 @@ mutual assembleExpr False (iref cname []) (snd obj) assembleExpr False fieldType (snd value) let (_, fieldName) = break (\c => c /= '.' && c /= '#' && c /= '=') fnameWithDot - Field PutField cname fieldName (getJvmTypeDescriptor fieldType) - Aconstnull + field PutField cname fieldName (getJvmTypeDescriptor fieldType) + aconstnull asmCast inferredObjectType returnType jvmExtPrim _ returnType SetStaticField [ret, NmPrimVal fc (Str fn), fargs, world] = do (value :: []) <- getFArgs fargs @@ -1807,8 +1830,8 @@ mutual let (cname, fnameWithDot) = break (== '.') fn assembleExpr False fieldType (snd value) let (_, fieldName) = break (\c => c /= '.' && c /= '#' && c /= '=') fnameWithDot - Field PutStatic cname fieldName (getJvmTypeDescriptor fieldType) - Aconstnull + field PutStatic cname fieldName (getJvmTypeDescriptor fieldType) + aconstnull asmCast inferredObjectType returnType jvmExtPrim _ returnType GetInstanceField [ret, NmPrimVal fc (Str fn), fargs, world] = do (obj :: []) <- getFArgs fargs @@ -1817,29 +1840,29 @@ mutual let (cname, fnameWithDot) = break (== '.') fn assembleExpr False (iref cname []) (snd obj) let (_, fieldName) = break (\c => c /= '.' && c /= '#') fnameWithDot - Field GetField cname fieldName (getJvmTypeDescriptor fieldType) + field GetField cname fieldName (getJvmTypeDescriptor fieldType) asmCast fieldType returnType jvmExtPrim _ returnType GetStaticField [ret, NmPrimVal fc (Str fn), fargs, world] = do fieldType <- tySpec ret let (cname, fnameWithDot) = break (== '.') fn let (_, fieldName) = break (\c => c /= '.' && c /= '#') fnameWithDot - Field GetStatic cname fieldName (getJvmTypeDescriptor fieldType) + field GetStatic cname fieldName (getJvmTypeDescriptor fieldType) asmCast fieldType returnType jvmExtPrim _ returnType NewArray [_, size, val, world] = do assembleExpr False IInt size assembleExpr False IUnknown val - InvokeMethod InvokeStatic arraysClass "create" "(ILjava/lang/Object;)Ljava/util/ArrayList;" False + invokeMethod InvokeStatic arraysClass "create" "(ILjava/lang/Object;)Ljava/util/ArrayList;" False asmCast arrayListType returnType jvmExtPrim _ returnType ArrayGet [_, arr, pos, world] = do assembleExpr False arrayListType arr assembleExpr False IInt pos - InvokeMethod InvokeVirtual arrayListClass "get" "(I)Ljava/lang/Object;" False + invokeMethod InvokeVirtual arrayListClass "get" "(I)Ljava/lang/Object;" False asmCast inferredObjectType returnType jvmExtPrim _ returnType ArraySet [_, arr, pos, val, world] = do assembleExpr False arrayListType arr assembleExpr False IInt pos assembleExpr False IUnknown val - InvokeMethod InvokeVirtual arrayListClass "set" "(ILjava/lang/Object;)Ljava/lang/Object;" False + invokeMethod InvokeVirtual arrayListClass "set" "(ILjava/lang/Object;)Ljava/lang/Object;" False asmCast inferredObjectType returnType jvmExtPrim _ returnType JvmNewArray [tyExpr, size, world] = do assembleExpr False IInt size @@ -1852,7 +1875,7 @@ mutual assembleExpr False IInt index assembleExpr False elemTy val storeArray elemTy - Aconstnull + aconstnull asmCast inferredObjectType returnType jvmExtPrim _ returnType JvmGetArray [tyExpr, index, arr, world] = do elemTy <- tySpec tyExpr @@ -1863,33 +1886,33 @@ mutual jvmExtPrim _ returnType JvmArrayLength [tyExpr, arr] = do elemTy <- tySpec tyExpr assembleExpr False (IArray elemTy) arr - Arraylength + arraylength asmCast IInt returnType jvmExtPrim _ returnType NewIORef [_, val, world] = do - New refClass - Dup + new refClass + dup assembleExpr False IUnknown val - InvokeMethod InvokeSpecial refClass "" "(Ljava/lang/Object;)V" False + invokeMethod InvokeSpecial refClass "" "(Ljava/lang/Object;)V" False asmCast refType returnType jvmExtPrim _ returnType ReadIORef [_, ref, world] = do assembleExpr False refType ref - InvokeMethod InvokeVirtual refClass "getValue" "()Ljava/lang/Object;" False + invokeMethod InvokeVirtual refClass "getValue" "()Ljava/lang/Object;" False asmCast inferredObjectType returnType jvmExtPrim _ returnType WriteIORef [_, ref, val, world] = do assembleExpr False refType ref assembleExpr False IUnknown val - InvokeMethod InvokeVirtual refClass "setValue" "(Ljava/lang/Object;)V" False - Aconstnull + invokeMethod InvokeVirtual refClass "setValue" "(Ljava/lang/Object;)V" False + aconstnull asmCast inferredObjectType returnType jvmExtPrim _ returnType SysOS [] = do - Field GetStatic idrisSystemClass "OS_NAME" "Ljava/lang/String;" + field GetStatic idrisSystemClass "OS_NAME" "Ljava/lang/String;" asmCast inferredStringType returnType jvmExtPrim _ returnType SysCodegen [] = do - Ldc $ StringConst "\"jvm\"" + ldc $ StringConst "\"jvm\"" asmCast inferredStringType returnType jvmExtPrim _ returnType VoidElim _ = do - Ldc $ StringConst "Error: Executed 'void'" - InvokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False + ldc $ StringConst "Error: Executed 'void'" + invokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False asmCast inferredObjectType returnType jvmExtPrim _ returnType JvmClassLiteral [ty] = do assembleClassLiteral !(tySpec ty) @@ -1897,23 +1920,23 @@ mutual jvmExtPrim _ returnType JvmInstanceOf [_, obj, ty] = do assembleExpr False IUnknown obj typeName <- getJvmReferenceTypeName !(tySpec ty) - InstanceOf typeName + instanceOf typeName asmCast IBool returnType jvmExtPrim _ returnType JvmRefEq [_, _, firstObj, secondObj] = - assembleExprBinaryBoolOp returnType IUnknown Ifacmpne firstObj secondObj + assembleExprBinaryBoolOp returnType IUnknown ifacmpne firstObj secondObj jvmExtPrim fc returnType JavaLambda [functionType, javaInterfaceType, lambda] = asmJavaLambda fc returnType functionType javaInterfaceType lambda jvmExtPrim _ returnType MakeFuture [_, action] = do assembleExpr False delayedType action - InvokeMethod InvokeStatic runtimeClass "fork" "(Lio/github/mmhelloworld/idrisjvm/runtime/Delayed;)Ljava/util/concurrent/ForkJoinTask;" False + invokeMethod InvokeStatic runtimeClass "fork" "(Lio/github/mmhelloworld/idrisjvm/runtime/Delayed;)Ljava/util/concurrent/ForkJoinTask;" False asmCast inferredForkJoinTaskType returnType jvmExtPrim _ returnType (Unknown name) _ = asmCrash $ "Can't compile unknown external directive " ++ show name - jvmExtPrim fc _ prim args = Throw fc $ "Unsupported external function " ++ show prim ++ "(" ++ + jvmExtPrim fc _ prim args = throw $ GenericMsg fc $ "Unsupported external function " ++ show prim ++ "(" ++ (show $ showNamedCExp 0 <$> args) ++ ")" -initializeFunctionState : Asm () +initializeFunctionState : {auto stateRef: Ref AsmState AsmState} -> Core () initializeFunctionState = do - lineNumberLabels <- LiftIo $ Map.newTreeMap {key=Int} {value=String} + lineNumberLabels <- coreLift $ Map.newTreeMap {key=Int} {value=String} updateState $ { scopeCounter := 0, currentScopeIndex := 0, @@ -1922,7 +1945,7 @@ initializeFunctionState = do lineNumberLabels := lineNumberLabels } updateCurrentFunction $ { dynamicVariableCounter := 0 } -assembleDefinition : Name -> FC -> Asm () +assembleDefinition : {auto stateRef: Ref AsmState AsmState} -> Name -> FC -> Core () assembleDefinition idrisName fc = do let jname = jvmName idrisName resetScope @@ -1944,16 +1967,16 @@ assembleDefinition idrisName fc = do let isField = arity == 0 && not (extractedFunctionLabel `isInfixOf` methodName) let classInitOrMethodName = if isField then "" else methodName when isField $ do - CreateField [Public, Static, Final] fileName declaringClassName methodName + createField [Public, Static, Final] fileName declaringClassName methodName "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" Nothing Nothing [] - FieldEnd - CreateMethod [Public, Static] fileName declaringClassName classInitOrMethodName descriptor Nothing Nothing [] [] + fieldEnd + createMethod [Public, Static] fileName declaringClassName classInitOrMethodName descriptor Nothing Nothing [] [] if (not isField) then do - MethodCodeStart - CreateLabel methodStartLabel - CreateLabel methodEndLabel - LabelStart methodStartLabel + methodCodeStart + createLabel methodStartLabel + createLabel methodEndLabel + labelStart methodStartLabel withScope $ do scopeIndex <- getCurrentScopeIndex scope <- getScope scopeIndex @@ -1962,47 +1985,30 @@ assembleDefinition idrisName fc = do updateScopeStartLabel scopeIndex methodStartLabel updateScopeEndLabel scopeIndex methodEndLabel assembleExpr True methodReturnType optimizedExpr - LabelStart methodEndLabel + labelStart methodEndLabel addLocalVariables 0 - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd else do withScope $ assembleExpr False delayedType optimizedExpr - Field PutStatic declaringClassName methodName "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" + field PutStatic declaringClassName methodName "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" -createMainMethod : String -> Jname -> Asm () +createMainMethod : {auto stateRef: Ref AsmState AsmState} -> String -> Jname -> Core () createMainMethod programName mainFunctionName = do function <- getFunction mainFunctionName let idrisMainClassMethodName = jvmClassMethodName function let mainClassName = className idrisMainClassMethodName - CreateMethod [Public, Static] "Main.idr" mainClassName "main" "([Ljava/lang/String;)V" Nothing Nothing [] [] - MethodCodeStart - Ldc $ StringConst programName - Aload 0 - InvokeMethod InvokeStatic runtimeClass "setProgramArgs" "(Ljava/lang/String;[Ljava/lang/String;)V" False - Field GetStatic mainClassName (methodName idrisMainClassMethodName) "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" - InvokeMethod InvokeVirtual "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "evaluate" + createMethod [Public, Static] "Main.idr" mainClassName "main" "([Ljava/lang/String;)V" Nothing Nothing [] [] + methodCodeStart + ldc $ StringConst programName + aload 0 + invokeMethod InvokeStatic runtimeClass "setProgramArgs" "(Ljava/lang/String;[Ljava/lang/String;)V" False + field GetStatic mainClassName (methodName idrisMainClassMethodName) "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" + invokeMethod InvokeVirtual "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "evaluate" "()Ljava/lang/Object;" False - Return - MaxStackAndLocal (-1) (-1) - MethodCodeEnd - -groupByClassName : String -> List Name -> List (List Name) -groupByClassName programName names = unsafePerformIO $ do - namesByClassName <- Map.newTreeMap {key=String} {value=List Name} - go1 namesByClassName names - Map.values {key=String} namesByClassName - where - go1 : Map String (List Name) -> List Name -> IO () - go1 namesByClassName values = go2 values where - go2 : List Name -> IO () - go2 [] = pure () - go2 (name :: names) = do - let jvmClassName = className $ getJvmClassMethodName programName name - existingNamesOpt <- Map.get namesByClassName jvmClassName - let newNames = maybe [name] ((::) name) $ nullableToMaybe existingNamesOpt - _ <- Map.put {key=String} {value=List Name} namesByClassName jvmClassName newNames - go2 names + return + maxStackAndLocal (-1) (-1) + methodCodeEnd assemble : AsmGlobalState -> Map String (FC, NamedDef) -> Name -> IO () assemble globalState fcAndDefinitionsByName name = do @@ -2011,23 +2017,13 @@ assemble globalState fcAndDefinitionsByName name = do Just (fc, def) => do programName <- AsmGlobalState.getProgramName globalState asmState <- createAsmState globalState name - ignore $ asm asmState $ do + ignore $ runAsm asmState $ \stateRef => do inferDef programName name fc def assembleDefinition name fc - scopes <- LiftIo $ ArrayList.new {elemTy=Scope} + scopes <- coreLift $ ArrayList.new {elemTy=Scope} updateCurrentFunction $ { scopes := (subtyping scopes), optimizedBody := emptyFunction } Nothing => pure () -assembleAsync : AsmGlobalState -> Map String (FC, NamedDef) -> List (List Name) -> IO () -assembleAsync _ _ [] = pure () -assembleAsync globalState fcAndDefinitionsByName (xs :: xss) = do - threadIds <- traverse forkAssemble xs - waitForFuturesToComplete threadIds - assembleAsync globalState fcAndDefinitionsByName xss - where - forkAssemble : Name -> IO ThreadID - forkAssemble name = fork $ assemble globalState fcAndDefinitionsByName name - getNameStrFcDef : (Name, FC, NamedDef) -> (String, FC, NamedDef) getNameStrFcDef (name, fc, def) = (jvmSimpleName name, fc, def) @@ -2038,8 +2034,8 @@ isForeignDef : (Name, FC, NamedDef) -> Bool isForeignDef (_, _, MkNmForeign _ _ _) = True isForeignDef _ = False -exportConstructor : SortedMap Namespace (List String) -> Map Int InferredType -> InferredType -> Int -> Jname -> - Name -> InferredFunctionType -> Asm () +exportConstructor : {auto stateRef: Ref AsmState AsmState} -> SortedMap Namespace (List String) -> Map Int InferredType + -> InferredType -> Int -> Jname -> Name -> InferredFunctionType -> Core () exportConstructor typeExports jvmArgumentTypesByIndex jvmReturnType arity jvmIdrisName idrisName idrisFunctionType = do function <- getCurrentFunction initializeFunctionState @@ -2047,9 +2043,9 @@ exportConstructor typeExports jvmArgumentTypesByIndex jvmReturnType arity jvmIdr let internalJname = function.idrisName when (shouldDebugFunction internalJname) $ logAsm $ "Assembling " ++ (className internalJname) ++ "." ++ (methodName internalJname) ++ "\n" ++ showNamedCExp 0 optimizedExpr - CreateLabel methodStartLabel - CreateLabel methodEndLabel - LabelStart methodStartLabel + createLabel methodStartLabel + createLabel methodEndLabel + labelStart methodStartLabel withScope $ do scopeIndex <- getCurrentScopeIndex scope <- getScope scopeIndex @@ -2062,16 +2058,16 @@ exportConstructor typeExports jvmArgumentTypesByIndex jvmReturnType arity jvmIdr let idrisMethodDescriptor = getMethodDescriptor idrisFunctionType programName <- getProgramName let qualifiedJvmIdrisName = getIdrisFunctionName programName (className jvmIdrisName) (methodName jvmIdrisName) - InvokeMethod InvokeStatic + invokeMethod InvokeStatic (className qualifiedJvmIdrisName) (methodName qualifiedJvmIdrisName) idrisMethodDescriptor False - InvokeMethod InvokeStatic (programName ++ "/PrimIO") "unsafePerformIO" "(Ljava/lang/Object;)Ljava/lang/Object;" False + invokeMethod InvokeStatic (programName ++ "/PrimIO") "unsafePerformIO" "(Ljava/lang/Object;)Ljava/lang/Object;" False asmCast (returnType idrisFunctionType) jvmReturnType asmReturn jvmReturnType - LabelStart methodEndLabel - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + labelStart methodEndLabel + maxStackAndLocal (-1) (-1) + methodCodeEnd -exportFunction : SortedMap Namespace (List String) -> MethodExport -> Asm () +exportFunction : {auto stateRef: Ref AsmState AsmState} -> SortedMap Namespace (List String) -> MethodExport -> Core () exportFunction typeExports (MkMethodExport jvmFunctionName idrisName type shouldPerformIO encloser modifiers annotations parameterAnnotations) = do let jvmClassName = encloser.name @@ -2079,7 +2075,7 @@ exportFunction typeExports (MkMethodExport jvmFunctionName idrisName type should let MkInferredFunctionType jvmReturnType jvmArgumentTypes = type let arity = length jvmArgumentTypes let arityInt = the Int $ cast $ length jvmArgumentTypes - jvmArgumentTypesByIndex <- LiftIo $ Map.fromList $ zip [0 .. (arityInt - 1)] jvmArgumentTypes + jvmArgumentTypesByIndex <- coreLift $ Map.fromList $ zip [0 .. (arityInt - 1)] jvmArgumentTypes let isInstance = not $ elem Static modifiers jvmArgumentTypesForSignature <- adjustArgumentsForInstanceMember idrisName isInstance jvmArgumentTypes let functionType = MkInferredFunctionType jvmReturnType jvmArgumentTypesForSignature @@ -2089,9 +2085,9 @@ exportFunction typeExports (MkMethodExport jvmFunctionName idrisName type should let asmParameterAnnotations = (\annotations => asmAnnotation <$> annotations) <$> parameterAnnotations let descriptor = getMethodDescriptor functionType let signature = Just $ getMethodSignature functionType - CreateMethod modifiers fileName jvmClassName jvmFunctionName descriptor signature Nothing asmAnnotations + createMethod modifiers fileName jvmClassName jvmFunctionName descriptor signature Nothing asmAnnotations asmParameterAnnotations - MethodCodeStart + methodCodeStart (_, MkNmFun idrisFunctionArgs _) <- getFcAndDefinition (jvmSimpleName idrisName) | _ => asmCrash ("Unknown idris function " ++ show idrisName) let idrisFunctionArity = length idrisFunctionArgs @@ -2108,45 +2104,45 @@ exportFunction typeExports (MkMethodExport jvmFunctionName idrisName type should programName <- getProgramName let qualifiedJvmIdrisName = getIdrisFunctionName programName (className jvmIdrisName) (methodName jvmIdrisName) - InvokeMethod InvokeStatic + invokeMethod InvokeStatic (className qualifiedJvmIdrisName) (methodName qualifiedJvmIdrisName) idrisMethodDescriptor False when shouldPerformIO $ - InvokeMethod InvokeStatic (programName ++ "/PrimIO") "unsafePerformIO" + invokeMethod InvokeStatic (programName ++ "/PrimIO") "unsafePerformIO" "(Ljava/lang/Object;)Ljava/lang/Object;" False toJava idrisName typeExports jvmReturnType (returnType idrisFunctionType) asmReturn jvmReturnType - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd else do programName <- getProgramName let qualifiedJvmIdrisName = getIdrisFunctionName programName (className jvmIdrisName) (methodName jvmIdrisName) - Field GetStatic (className qualifiedJvmIdrisName) (methodName qualifiedJvmIdrisName) + field GetStatic (className qualifiedJvmIdrisName) (methodName qualifiedJvmIdrisName) "Lio/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed;" - InvokeMethod InvokeVirtual "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "evaluate" + invokeMethod InvokeVirtual "io/github/mmhelloworld/idrisjvm/runtime/MemoizedDelayed" "evaluate" "()Ljava/lang/Object;" False toJava idrisName typeExports jvmReturnType (returnType idrisFunctionType) asmReturn jvmReturnType - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd -generateAccessors : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> - (accessorCreator: FieldExport -> Asm ()) -> Asm () +generateAccessors : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) + -> ClassExport -> (accessorCreator: FieldExport -> Core ()) -> Core () generateAccessors descriptorsByEncloser classExport accessorCreator = do let className = classExport.name let fields = getFields $ fromMaybe [] $ SortedMap.lookup classExport descriptorsByEncloser traverse_ accessorCreator fields -generateGetters : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateGetters : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateGetters descriptorsByEncloser classExport = generateAccessors descriptorsByEncloser classExport (createGetter classExport) -generateSetters : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateSetters : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateSetters descriptorsByEncloser classExport = generateAccessors descriptorsByEncloser classExport (createSetter classExport) -generateConstructor : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> - List FieldExport -> List Annotation -> List (List Annotation) -> Asm () +generateConstructor : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) + -> ClassExport -> List FieldExport -> List Annotation -> List (List Annotation) -> Core () generateConstructor descriptorsByEncloser classExport fields annotations parameterAnnotations = do let fieldTypes = FieldExport.type <$> fields let descriptor = getMethodDescriptor $ MkInferredFunctionType IVoid fieldTypes @@ -2154,61 +2150,62 @@ generateConstructor descriptorsByEncloser classExport fields annotations paramet let classType = iref classExport.name [] extendsTypeName <- getJvmReferenceTypeName classExport.extends let arity = the Int $ cast $ length fields - jvmArgumentTypesByIndex <- LiftIo $ Map.fromList $ zip [0 .. arity] (classType :: fieldTypes) + jvmArgumentTypesByIndex <- coreLift $ Map.fromList $ zip [0 .. arity] (classType :: fieldTypes) let asmAnnotations = asmAnnotation <$> annotations let asmParameterAnnotations = (\annotations => asmAnnotation <$> annotations) <$> parameterAnnotations - CreateMethod [Public] "generated.idr" classExport.name "" descriptor signature Nothing asmAnnotations + createMethod [Public] "generated.idr" classExport.name "" descriptor signature Nothing asmAnnotations asmParameterAnnotations - MethodCodeStart - CreateLabel methodStartLabel - CreateLabel methodEndLabel - LabelStart methodStartLabel - Aload 0 - InvokeMethod InvokeSpecial extendsTypeName "" "()V" False + methodCodeStart + createLabel methodStartLabel + createLabel methodEndLabel + labelStart methodStartLabel + aload 0 + invokeMethod InvokeSpecial extendsTypeName "" "()V" False assignFields jvmArgumentTypesByIndex fields - Return - LabelStart methodEndLabel - LocalVariable "this" (getJvmTypeDescriptor classType) Nothing methodStartLabel methodEndLabel 0 + return + labelStart methodEndLabel + localVariable "this" (getJvmTypeDescriptor classType) Nothing methodStartLabel methodEndLabel 0 traverse_ (uncurry addLocalVariable) $ zip [1 .. arity] fields - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd where - assignField : Map Int InferredType -> Int -> FieldExport -> Asm () - assignField jvmArgumentTypesByIndex varIndex field = do - let fieldType = field.type - Aload 0 + assignField : Map Int InferredType -> Int -> FieldExport -> Core () + assignField jvmArgumentTypesByIndex varIndex fieldExport = do + let fieldType = fieldExport.type + aload 0 loadVar jvmArgumentTypesByIndex fieldType fieldType varIndex - Field PutField classExport.name field.name (getJvmTypeDescriptor fieldType) + field PutField classExport.name fieldExport.name (getJvmTypeDescriptor fieldType) - assignFields : Map Int InferredType -> List FieldExport -> Asm () + assignFields : Map Int InferredType -> List FieldExport -> Core () assignFields jvmArgumentTypesByIndex fieldExports = do let arity = the Int $ cast $ length fieldExports let varIndexAndExports = zip [1 .. arity] fieldExports traverse_ (uncurry $ assignField jvmArgumentTypesByIndex) varIndexAndExports - addLocalVariable : Int -> FieldExport -> Asm () + addLocalVariable : Int -> FieldExport -> Core () addLocalVariable index field = do let fieldType = field.type - LocalVariable field.name (getJvmTypeDescriptor fieldType) Nothing methodStartLabel methodEndLabel index + localVariable field.name (getJvmTypeDescriptor fieldType) Nothing methodStartLabel methodEndLabel index getMatchingAnnotationProperty : String -> List AnnotationProperty -> Maybe AnnotationValue getMatchingAnnotationProperty name props = snd <$> find (\(currentName, value) => name == currentName) props -generateRequiredArgsConstructor : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> - List AnnotationProperty -> Asm () +generateRequiredArgsConstructor : {auto stateRef: Ref AsmState AsmState} + -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport + -> List AnnotationProperty -> Core () generateRequiredArgsConstructor descriptorsByEncloser classExport props = do let allFields = getFields $ fromMaybe [] $ SortedMap.lookup classExport descriptorsByEncloser let requiredFields@(_ :: _) = filter isRequiredField allFields - | [] => Pure () + | [] => pure () let annotations = getAnnotationValues $ fromMaybe (AnnArray []) $ getMatchingAnnotationProperty "annotations" props let parameterAnnotations = getParameterAnnotationValues $ fromMaybe (AnnArray []) $ getMatchingAnnotationProperty "parameterAnnotations" props generateConstructor descriptorsByEncloser classExport requiredFields annotations parameterAnnotations -generateAllArgsConstructor : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateAllArgsConstructor : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateAllArgsConstructor descriptorsByEncloser classExport = do let Just (MkAnnotation _ props) = findAllArgsConstructor classExport - | _ => Pure () + | _ => pure () let fields = getFields $ fromMaybe [] $ SortedMap.lookup classExport descriptorsByEncloser let excludedFields = getStringAnnotationValues $ snd $ fromMaybe ("exclude", AnnArray []) $ (find (\(name, value) => name == "exclude") props) @@ -2218,121 +2215,121 @@ generateAllArgsConstructor descriptorsByEncloser classExport = do getMatchingAnnotationProperty "parameterAnnotations" props generateConstructor descriptorsByEncloser classExport constructorFields annotations parameterAnnotations -generateNoArgsConstructor : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateNoArgsConstructor : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateNoArgsConstructor descriptorsByEncloser classExport = do let Just (MkAnnotation _ props) = findNoArgsConstructor classExport - | _ => Pure () + | _ => pure () let annotations = getAnnotationValues $ snd $ fromMaybe ("annotations", AnnArray []) $ (find (\(name, value) => name == "annotations") props) - CreateMethod [Public] "generated.idr" classExport.name "" "()V" Nothing Nothing [] [] - MethodCodeStart - Aload 0 + createMethod [Public] "generated.idr" classExport.name "" "()V" Nothing Nothing [] [] + methodCodeStart + aload 0 extendsTypeName <- getJvmReferenceTypeName classExport.extends - InvokeMethod InvokeSpecial extendsTypeName "" "()V" False - Return - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + invokeMethod InvokeSpecial extendsTypeName "" "()V" False + return + maxStackAndLocal (-1) (-1) + methodCodeEnd -generateHashCode : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateHashCode : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateHashCode descriptorsByEncloser classExport = do let fields = filter (not . isTransientField) $ getFields $ fromMaybe [] $ SortedMap.lookup classExport descriptorsByEncloser - CreateMethod [Public] "generated.idr" classExport.name "hashCode" "()I" Nothing Nothing [] [] - MethodCodeStart + createMethod [Public] "generated.idr" classExport.name "hashCode" "()I" Nothing Nothing [] [] + methodCodeStart let fieldsCount = the Int $ cast $ length fields - Iconst fieldsCount - Anewarray "java/lang/Object" + iconst fieldsCount + anewarray "java/lang/Object" traverse_ (uncurry loadField) $ zip [0 .. fieldsCount - 1] fields - InvokeMethod InvokeStatic "java/util/Objects" "hash" "([Ljava/lang/Object;)I" False - Ireturn - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + invokeMethod InvokeStatic "java/util/Objects" "hash" "([Ljava/lang/Object;)I" False + ireturn + maxStackAndLocal (-1) (-1) + methodCodeEnd where - loadField : Int -> FieldExport -> Asm () - loadField index field = do - Dup - Iconst index - Aload 0 - let fieldType = field.type - Field GetField classExport.name field.name (getJvmTypeDescriptor fieldType) + loadField : Int -> FieldExport -> Core () + loadField index fieldExport = do + dup + iconst index + aload 0 + let fieldType = fieldExport.type + field GetField classExport.name fieldExport.name (getJvmTypeDescriptor fieldType) asmCast fieldType inferredObjectType - Aastore + aastore -generateEquals : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateEquals : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateEquals descriptorsByEncloser classExport = do let fields = filter (not . isTransientField) $ getFields $ fromMaybe [] $ SortedMap.lookup classExport descriptorsByEncloser - CreateMethod [Public] "generated.idr" classExport.name "equals" "(Ljava/lang/Object;)Z" Nothing Nothing [] [] - MethodCodeStart - Aload 0 - Aload 1 + createMethod [Public] "generated.idr" classExport.name "equals" "(Ljava/lang/Object;)Z" Nothing Nothing [] [] + methodCodeStart + aload 0 + aload 1 refEqLabel <- newLabel - CreateLabel refEqLabel - Ifacmpne refEqLabel - Iconst 1 - Ireturn - LabelStart refEqLabel - Aload 1 + createLabel refEqLabel + ifacmpne refEqLabel + iconst 1 + ireturn + labelStart refEqLabel + aload 1 let className = classExport.name - InstanceOf className + instanceOf className instanceOfLabel <- newLabel - CreateLabel instanceOfLabel - Ifne instanceOfLabel - Iconst 0 - Ireturn - LabelStart instanceOfLabel - Aload 1 + createLabel instanceOfLabel + ifne instanceOfLabel + iconst 0 + ireturn + labelStart instanceOfLabel + aload 1 checkcast className - Astore 2 + astore 2 let fieldsCount = the Int $ cast $ length fields equalsLabel <- newLabel - CreateLabel equalsLabel + createLabel equalsLabel equalsFields equalsLabel fields - Iconst 1 + iconst 1 methodEndLabel <- newLabel - CreateLabel methodEndLabel - Goto methodEndLabel - LabelStart equalsLabel - Iconst 0 - LabelStart methodEndLabel - Ireturn - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + createLabel methodEndLabel + goto methodEndLabel + labelStart equalsLabel + iconst 0 + labelStart methodEndLabel + ireturn + maxStackAndLocal (-1) (-1) + methodCodeEnd where - equalsFields : String -> List FieldExport -> Asm () - equalsFields equalsLabel [] = Pure () - equalsFields equalsLabel (field :: rest) = do - let fieldType = field.type + equalsFields : String -> List FieldExport -> Core () + equalsFields equalsLabel [] = pure () + equalsFields equalsLabel (fieldExport :: rest) = do + let fieldType = fieldExport.type let className = classExport.name - Aload 0 - Field GetField className field.name (getJvmTypeDescriptor fieldType) + aload 0 + field GetField className fieldExport.name (getJvmTypeDescriptor fieldType) asmCast fieldType inferredObjectType - Aload 2 - Field GetField className field.name (getJvmTypeDescriptor fieldType) + aload 2 + field GetField className fieldExport.name (getJvmTypeDescriptor fieldType) asmCast fieldType inferredObjectType - InvokeMethod InvokeStatic "java/util/Objects" "equals" "(Ljava/lang/Object;Ljava/lang/Object;)Z" False - Ifeq equalsLabel + invokeMethod InvokeStatic "java/util/Objects" "equals" "(Ljava/lang/Object;Ljava/lang/Object;)Z" False + ifeq equalsLabel equalsFields equalsLabel rest -generateToString : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateToString : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateToString descriptorsByEncloser classExport = do let fields = getFields $ fromMaybe [] $ SortedMap.lookup classExport descriptorsByEncloser - CreateMethod [Public] "generated.idr" classExport.name "toString" "()Ljava/lang/String;" Nothing Nothing [] [] - MethodCodeStart - New "java/lang/StringBuilder" - Dup - InvokeMethod InvokeSpecial "java/lang/StringBuilder" "" "()V" False - Ldc $ StringConst classExport.name - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;" False + createMethod [Public] "generated.idr" classExport.name "toString" "()Ljava/lang/String;" Nothing Nothing [] [] + methodCodeStart + new "java/lang/StringBuilder" + dup + invokeMethod InvokeSpecial "java/lang/StringBuilder" "" "()V" False + ldc $ StringConst classExport.name + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;" False let hasFields = not $ isNil fields when hasFields $ do appendFields "{" fields - Iconst 125 -- '}' - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(C)Ljava/lang/StringBuilder;" False - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;" False - Areturn - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + iconst 125 -- '}' + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(C)Ljava/lang/StringBuilder;" False + invokeMethod InvokeVirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;" False + areturn + maxStackAndLocal (-1) (-1) + methodCodeEnd where getAppendParamType : InferredType -> InferredType getAppendParamType IChar = IChar @@ -2349,28 +2346,28 @@ generateToString descriptorsByEncloser classExport = do ty == iref "java/lang/StringBuffer" []) then ty else inferredObjectType - appendFields : String -> List FieldExport -> Asm () - appendFields _ [] = Pure () - appendFields prefixChar (field :: rest) = do - let fieldName = field.name - let fieldType = field.type + appendFields : String -> List FieldExport -> Core () + appendFields _ [] = pure () + appendFields prefixChar (fieldExport :: rest) = do + let fieldName = fieldExport.name + let fieldType = fieldExport.type let className = classExport.name - let isStringField = field.type == inferredStringType - Ldc $ StringConst (prefixChar ++ fieldName ++ "=" ++ if isStringField then "'" else "") - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;" False - Aload 0 - Field GetField className fieldName (getJvmTypeDescriptor fieldType) + let isStringField = fieldExport.type == inferredStringType + ldc $ StringConst (prefixChar ++ fieldName ++ "=" ++ if isStringField then "'" else "") + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;" False + aload 0 + field GetField className fieldName (getJvmTypeDescriptor fieldType) let appendParamType = getAppendParamType fieldType asmCast fieldType appendParamType let stringBuilderType = iref "java/lang/StringBuilder" [] let appendDescriptor = getMethodDescriptor $ MkInferredFunctionType stringBuilderType [appendParamType] - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" appendDescriptor False + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" appendDescriptor False when isStringField $ do - Iconst 39 -- single quote - InvokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(C)Ljava/lang/StringBuilder;" False + iconst 39 -- single quote + invokeMethod InvokeVirtual "java/lang/StringBuilder" "append" "(C)Ljava/lang/StringBuilder;" False appendFields ", " rest -generateDataClass : SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Asm () +generateDataClass : {auto stateRef: Ref AsmState AsmState} -> SortedMap ClassExport (List ExportDescriptor) -> ClassExport -> Core () generateDataClass descriptorsByEncloser classExport = do generateGetters descriptorsByEncloser classExport generateSetters descriptorsByEncloser classExport @@ -2393,40 +2390,40 @@ exportMemberIo globalState typeExports descriptorsByEncloser (MkMethodExportDesc let constructorIdrisName = NS (mkNamespace desc.encloser.name) (UN $ Basic (methodName jname ++ "")) programName <- AsmGlobalState.getProgramName globalState asmState <- createAsmStateJavaName globalState desc.encloser.name - ignore $ asm asmState $ do + ignore $ runAsm asmState $ \stateRef => do Just superCallExpr <- getSuperCallExpr expr | Nothing => asmCrash ("Constructor export for " ++ show idrisName ++ " should call 'super'") inferDef programName constructorIdrisName fc (MkNmFun args superCallExpr) resetScope loadFunction $ jvmName constructorIdrisName exportFunction typeExports desc - scopes <- LiftIo $ ArrayList.new {elemTy=Scope} + scopes <- coreLift $ ArrayList.new {elemTy=Scope} updateCurrentFunction $ { scopes := (subtyping scopes), optimizedBody := emptyFunction } _ => pure () else do asmState <- createAsmStateJavaName globalState desc.encloser.name - ignore $ asm asmState $ exportFunction typeExports desc + ignore $ runAsm asmState $ \stateRef => exportFunction typeExports desc exportMemberIo globalState typeExports descriptorsByEncloser (MkFieldExportDescriptor desc) = do asmState <- createAsmStateJavaName globalState desc.encloser.name - ignore $ asm asmState $ exportField desc + ignore $ runAsm asmState $ \stateRef => exportField desc exportMemberIo globalState _ descriptorsByEncloser (MkClassExportDescriptor classExport) = do asmState <- createAsmStateJavaName globalState classExport.name - ignore $ asm asmState $ exportClass classExport + ignore $ runAsm asmState $ \stateRef => exportClass classExport let hasDataAnnotation = isJust (findClassAnnotation "Data" classExport) - ignore $ asm asmState $ generateAllArgsConstructor descriptorsByEncloser classExport - ignore $ asm asmState $ generateNoArgsConstructor descriptorsByEncloser classExport + ignore $ runAsm asmState $ \stateRef => generateAllArgsConstructor descriptorsByEncloser classExport + ignore $ runAsm asmState $ \stateRef => generateNoArgsConstructor descriptorsByEncloser classExport when (not hasDataAnnotation) $ - ignore $ asm asmState $ + ignore $ runAsm asmState $ \stateRef => generateRequiredArgsConstructor descriptorsByEncloser classExport (maybe [] getAnnotationProperties $ findRequiredArgsConstructor classExport) - when hasDataAnnotation $ ignore $ asm asmState $ generateDataClass descriptorsByEncloser classExport + when hasDataAnnotation $ ignore $ runAsm asmState $ \stateRef => generateDataClass descriptorsByEncloser classExport when (not hasDataAnnotation && isJust (findClassAnnotation "Getter" classExport)) $ - ignore $ asm asmState $ generateGetters descriptorsByEncloser classExport + ignore $ runAsm asmState $ \stateRef => generateGetters descriptorsByEncloser classExport when (not hasDataAnnotation && isJust (findClassAnnotation "Setter" classExport)) $ - ignore $ asm asmState $ generateSetters descriptorsByEncloser classExport + ignore $ runAsm asmState $ \stateRef => generateSetters descriptorsByEncloser classExport when (not hasDataAnnotation && isJust (findClassAnnotation "EqualsAndHashCode" classExport)) $ do - ignore $ asm asmState $ generateEquals descriptorsByEncloser classExport - ignore $ asm asmState $ generateHashCode descriptorsByEncloser classExport + ignore $ runAsm asmState $ \stateRef => generateEquals descriptorsByEncloser classExport + ignore $ runAsm asmState $ \stateRef => generateHashCode descriptorsByEncloser classExport exportMemberIo _ _ _ _ = pure () groupByEncloser : List ExportDescriptor -> SortedMap ClassExport (List ExportDescriptor) @@ -2467,7 +2464,7 @@ groupByEncloser descriptors = exportTypeIo : AsmGlobalState -> String -> IO () exportTypeIo globalState name = do asmState <- createAsmStateJavaName globalState name - ignore $ asm asmState $ exportType name + ignore $ runAsm asmState $ \stateRef => exportType name exportTypes : AsmGlobalState -> SortedMap Namespace (List String) -> IO () exportTypes globalState typeExports = traverse_ (exportTypeIo globalState) $ concat $ values typeExports @@ -2484,8 +2481,9 @@ getExport : NoMangleMap -> Name -> Maybe (Name, String) getExport noMangleMap name = (\descriptor => (name, descriptor)) <$> isNoMangle noMangleMap name ||| Compile a TT expression to JVM bytecode -compileToJvmBytecode : Ref Ctxt Defs -> String -> String -> ClosedTerm -> Core () -compileToJvmBytecode c outputDirectory outputFile term = do +compileToJvmBytecode : {auto c : Ref Ctxt Defs} + -> {auto s : Ref Syn SyntaxInfo} -> String -> String -> ClosedTerm -> Core () +compileToJvmBytecode outputDirectory outputFile term = do noMangleMapRef <- initNoMangle ["jvm"] (const True) noMangleMap <- get NoMangleMap cdata <- getCompileDataWith ["jvm"] False Cases term @@ -2502,22 +2500,22 @@ compileToJvmBytecode c outputDirectory outputFile term = do definitionsByName <- coreLift $ Map.fromList nameStrDefs globalState <- coreLift $ newAsmGlobalState programName fcAndDefinitionsByName let names = fst <$> nameFcDefs - let namesByClassName = groupByClassName programName names coreLift $ do - assembleAsync globalState fcAndDefinitionsByName (transpose namesByClassName) + traverse_ (assemble globalState fcAndDefinitionsByName) names exportDefs globalState $ mapMaybe (getExport noMangleMap) (fst <$> allDefs) mainAsmState <- createAsmState globalState mainFunctionName let mainFunctionJname = jvmName mainFunctionName - _ <- runAsm mainAsmState $ createMainMethod programName mainFunctionJname + _ <- runAsm mainAsmState $ \stateRef => createMainMethod programName mainFunctionJname classCodeEnd globalState outputDirectory outputFile (className mainFunctionJname) ||| JVM bytecode implementation of the `compileExpr` interface. -compileExprJvm : Ref Ctxt Defs -> Ref Syn SyntaxInfo -> (tmpDir : String) -> (outDir: String) -> ClosedTerm -> - (outputFile : String) -> Core (Maybe String) -compileExprJvm c _ tmpDir outDir term outputFile +compileExprJvm : Ref Ctxt Defs + -> Ref Syn SyntaxInfo -> (tmpDir : String) -> (outDir: String) -> ClosedTerm + -> (outputFile : String) -> Core (Maybe String) +compileExprJvm _ _ tmpDir outDir term outputFile = do let outputDirectory = if outputFile == "" then "" else outDir when (outputDirectory /= "") $ ignore $ coreLift $ mkdirAll outputDirectory - compileToJvmBytecode c outputDirectory outputFile term + compileToJvmBytecode outputDirectory outputFile term pure $ Just outputDirectory ||| JVM bytecode implementation of the `executeExpr` interface. diff --git a/src/Compiler/Jvm/Export.idr b/src/Compiler/Jvm/Export.idr index 3c981ca43..524afbc2f 100644 --- a/src/Compiler/Jvm/Export.idr +++ b/src/Compiler/Jvm/Export.idr @@ -29,14 +29,14 @@ import Libraries.Utils.Path import System.FFI mutual - parseAnnotationTypeValue : Name -> String -> String -> JSON -> Asm AnnotationValue - parseAnnotationTypeValue functionName annotationName "int" (JNumber value) = Pure $ AnnInt $ cast value - parseAnnotationTypeValue functionName annotationName "boolean" (JBoolean value) = Pure $ AnnBoolean value + parseAnnotationTypeValue : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> String -> JSON -> Core AnnotationValue + parseAnnotationTypeValue functionName annotationName "int" (JNumber value) = pure $ AnnInt $ cast value + parseAnnotationTypeValue functionName annotationName "boolean" (JBoolean value) = pure $ AnnBoolean value parseAnnotationTypeValue functionName annotationName "char" (JString value) = - Pure $ AnnChar $ assert_total (prim__strHead value) - parseAnnotationTypeValue functionName annotationName "double" (JNumber value) = Pure $ AnnDouble value - parseAnnotationTypeValue functionName annotationName "String" (JString value) = Pure $ AnnString value - parseAnnotationTypeValue functionName annotationName "class" (JString value) = Pure $ AnnClass value + pure $ AnnChar $ assert_total (prim__strHead value) + parseAnnotationTypeValue functionName annotationName "double" (JNumber value) = pure $ AnnDouble value + parseAnnotationTypeValue functionName annotationName "String" (JString value) = pure $ AnnString value + parseAnnotationTypeValue functionName annotationName "class" (JString value) = pure $ AnnClass value parseAnnotationTypeValue functionName annotationName "enum" (JObject properties) = do let propertiesByName = SortedMap.fromList properties let Just (JString type) = lookup "type" properties @@ -45,16 +45,16 @@ mutual let Just (JString value) = lookup "value" properties | _ => asmCrash ("Expected 'string' enum value for annotation " ++ show annotationName ++ " in " ++ show functionName) - Pure $ AnnEnum type value + pure $ AnnEnum type value parseAnnotationTypeValue functionName annotationName "annotation" annotationJson = AnnAnnotation <$> parseAnnotation functionName annotationJson parseAnnotationTypeValue functionName annotationName type _ = asmCrash ("Unknown type " ++ show type ++ " for annotation " ++ annotationName ++ " in " ++ show functionName) - parseAnnotationValue : Name -> String -> JSON -> Asm AnnotationValue - parseAnnotationValue functionName annotationName (JNumber value) = Pure $ AnnInt $ cast value - parseAnnotationValue functionName annotationName (JString value) = Pure $ AnnString value - parseAnnotationValue functionName annotationName (JBoolean value) = Pure $ AnnBoolean value + parseAnnotationValue : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> JSON -> Core AnnotationValue + parseAnnotationValue functionName annotationName (JNumber value) = pure $ AnnInt $ cast value + parseAnnotationValue functionName annotationName (JString value) = pure $ AnnString value + parseAnnotationValue functionName annotationName (JBoolean value) = pure $ AnnBoolean value parseAnnotationValue functionName annotationName annotationJson@(JObject properties) = do let propertiesByName = SortedMap.fromList properties let Just (JString type) = lookup "type" propertiesByName @@ -63,27 +63,27 @@ mutual | _ => asmCrash ("Missing 'string' value for annotation " ++ annotationName ++ " in " ++ show functionName) parseAnnotationTypeValue functionName annotationName type value parseAnnotationValue functionName annotationName (JArray valuesJson) = - Pure $ AnnArray !(traverse (parseAnnotationValue functionName annotationName) valuesJson) + pure $ AnnArray !(traverse (parseAnnotationValue functionName annotationName) valuesJson) parseAnnotationValue functionName annotationName JNull = asmCrash ("Annotation property value cannot be null " ++ " for annotation " ++ show annotationName ++ " in function " ++ show functionName) - parseAnnotationProperty : Name -> String -> String -> JSON -> Asm AnnotationProperty + parseAnnotationProperty : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> String -> JSON -> Core AnnotationProperty parseAnnotationProperty functionName annotationName propertyName valueJson = do value <- parseAnnotationValue functionName annotationName valueJson - Pure (propertyName, value) + pure (propertyName, value) - parseAnnotation : Name -> JSON -> Asm Annotation + parseAnnotation : {auto stateRef: Ref AsmState AsmState} -> Name -> JSON -> Core Annotation parseAnnotation functionName (JObject [(annotationName, (JObject propertyNameAndValues))]) = do properties <- traverse (\(propertyName, value) => parseAnnotationProperty functionName annotationName propertyName value) propertyNameAndValues - Pure $ MkAnnotation annotationName properties + pure $ MkAnnotation annotationName properties parseAnnotation functionName (JObject [(annotationName, simplifiedValue)]) = parseAnnotation functionName (JObject [(annotationName, (JObject [("value", simplifiedValue)]))]) parseAnnotation functionName _ = asmCrash ("Expected a JSON object for parameter annotations in " ++ show functionName) -parseAnnotations : Name -> JSON -> Asm (List Annotation) +parseAnnotations : {auto stateRef: Ref AsmState AsmState} -> Name -> JSON -> Core (List Annotation) parseAnnotations functionName (JArray annotations) = traverse (parseAnnotation functionName) annotations parseAnnotations functionName _ = asmCrash ("Expected an array for parameter annotations in " ++ show functionName) @@ -109,30 +109,30 @@ record ExportArgument where type: InferredType annotations: List Annotation -parseArgument : Name -> List (String, JSON) -> Asm ExportArgument +parseArgument : {auto stateRef: Ref AsmState AsmState} -> Name -> List (String, JSON) -> Core ExportArgument parseArgument functionName keyAndValues = do let valuesByKey = SortedMap.fromList keyAndValues let Just (JString typeStr) = lookup "type" valuesByKey | _ => asmCrash $ "Expected 'string' argument type for " ++ show functionName let annotationsJson = fromMaybe (JArray []) $ lookup "annotations" valuesByKey annotations <- parseAnnotations functionName annotationsJson - Pure $ MkExportArgument (parse typeStr) annotations + pure $ MkExportArgument (parse typeStr) annotations -parseArgumentsJson : Name -> JSON -> Asm (List ExportArgument) +parseArgumentsJson : {auto stateRef: Ref AsmState AsmState} -> Name -> JSON -> Core (List ExportArgument) parseArgumentsJson functionName (JArray arguments) = go arguments where - go : List JSON -> Asm (List ExportArgument) - go [] = Pure [] + go : List JSON -> Core (List ExportArgument) + go [] = pure[] go ((JObject keyAndValues) :: rest) = do argument <- parseArgument functionName keyAndValues restArguments <- go rest - Pure (argument :: restArguments) + pure (argument :: restArguments) go _ = asmCrash ("Expected an argument object for foreign export function: " ++ show functionName) parseArgumentsJson functionName _ = asmCrash ("Expected an array of arguments for foreign export function: " ++ show functionName) export -loadJavaVar : Name -> Map Int InferredType -> Int -> InferredType -> SortedMap Namespace (List String) -> - InferredType -> Asm () +loadJavaVar : {auto stateRef: Ref AsmState AsmState} -> Name -> Map Int InferredType -> Int -> InferredType + -> SortedMap Namespace (List String) -> InferredType -> Core () loadJavaVar functionName typesByIndex varIndex idrisType typeExports jvmType@(IRef name _ _) = case findByNamespace typeExports functionName of Just exportedTypeNames => @@ -140,40 +140,40 @@ loadJavaVar functionName typesByIndex varIndex idrisType typeExports jvmType@(IR then do loadVar typesByIndex jvmType jvmType varIndex let descriptor = getMethodDescriptor $ MkInferredFunctionType idrisType [] - InvokeMethod InvokeVirtual name "toIdris" descriptor False + invokeMethod InvokeVirtual name "toIdris" descriptor False else loadVar typesByIndex jvmType idrisType varIndex Nothing => loadVar typesByIndex jvmType idrisType varIndex loadJavaVar _ typesByIndex varIndex idrisType _ jvmType = loadVar typesByIndex jvmType idrisType varIndex export -toJava : Name -> SortedMap Namespace (List String) -> InferredType -> InferredType -> Asm () +toJava : {auto stateRef: Ref AsmState AsmState} -> Name -> SortedMap Namespace (List String) -> InferredType -> InferredType -> Core () toJava functionName typeExports jvmType@(IRef name _ _) idrisType = case findByNamespace typeExports functionName of Just exportedTypeNames => if elem name exportedTypeNames then do let descriptor = getMethodDescriptor $ MkInferredFunctionType jvmType [idrisType] - InvokeMethod InvokeStatic name "toJava" descriptor False + invokeMethod InvokeStatic name "toJava" descriptor False else asmCast idrisType jvmType Nothing => asmCast idrisType jvmType toJava _ _ jvmType idrisType = asmCast idrisType jvmType export -loadArguments : SortedMap Namespace (List String) -> Map Int InferredType -> Name -> Int -> List InferredType -> Asm () +loadArguments : {auto stateRef: Ref AsmState AsmState} -> SortedMap Namespace (List String) -> Map Int InferredType -> Name -> Int -> List InferredType -> Core () loadArguments typeExports typesByIndex functionName arity idrisTypes = go 0 idrisTypes where - go : Int -> List InferredType -> Asm () + go : Int -> List InferredType -> Core () go n [] = if n == arity - then Pure () + then pure () else asmCrash ("JVM and Idris types do not match in foreign export for " ++ show functionName) go varIndex (idrisType :: rest) = do - Just jvmType <- nullableToMaybe <$> Map.get typesByIndex varIndex + Just jvmType <- coreLift $ nullableToMaybe <$> Map.get typesByIndex varIndex | Nothing => do -- World type only exists for Idris functions - Iconst 0 -- Load "world" for PrimIO functions - InvokeMethod InvokeStatic "java/lang/Integer" "valueOf" "(I)Ljava/lang/Integer;" False + iconst 0 -- Load "world" for PrimIO functions + invokeMethod InvokeStatic "java/lang/Integer" "valueOf" "(I)Ljava/lang/Integer;" False loadJavaVar functionName typesByIndex varIndex idrisType typeExports jvmType go (varIndex + 1) rest @@ -235,8 +235,8 @@ parseModifier _ "abstract" = Abstract parseModifier _ "transient" = Transient parseModifier name invalid = believe_me $ crash ("Invalid modifier " ++ invalid ++ " in export " ++ show name) -parseString : String -> JSON -> Asm String -parseString _ (JString value) = Pure value +parseString : {auto stateRef: Ref AsmState AsmState} -> String -> JSON -> Core String +parseString _ (JString value) = pure value parseString errorMessage _ = asmCrash errorMessage getEncloser : ExportDescriptor -> Maybe ClassExport @@ -253,9 +253,9 @@ parseModifiers : Name -> JSON -> List Access parseModifiers name (JArray modifiers) = (parseModifierJson name) <$> modifiers parseModifiers name invalid = believe_me $ crash ("Invalid modifiers " ++ show invalid ++ " in export " ++ show name) -parseClassFieldExport : Name -> ClassExport -> String -> JSON -> Asm FieldExport +parseClassFieldExport : {auto stateRef: Ref AsmState AsmState} -> Name -> ClassExport -> String -> JSON -> Core FieldExport parseClassFieldExport idrisName encloser fieldName (JString type) = - Pure $ MkFieldExport fieldName (parse type) encloser [Private] [] + pure $ MkFieldExport fieldName (parse type) encloser [Private] [] parseClassFieldExport idrisName encloser fieldName (JObject desc) = do let modifiersJson = fromMaybe (JArray [JString "private"]) $ lookup "modifiers" desc let modifiers = parseModifiers idrisName modifiersJson @@ -264,14 +264,14 @@ parseClassFieldExport idrisName encloser fieldName (JObject desc) = do type <- parseString ("Invalid type for " ++ fieldName ++ " in export " ++ show idrisName) typeJson let annotationsJson = fromMaybe (JArray []) $ lookup "annotations" desc annotations <- parseAnnotations idrisName annotationsJson - Pure $ MkFieldExport fieldName (parse type) encloser modifiers annotations + pure $ MkFieldExport fieldName (parse type) encloser modifiers annotations parseClassFieldExport idrisName encloser fieldName descriptor = asmCrash ("Expected a JSON string or object for field export in " ++ show idrisName ++ " but found: " ++ show descriptor) -parseClassFieldExports : Name -> ClassExport -> SortedMap String JSON -> Asm (List FieldExport) +parseClassFieldExports : {auto stateRef: Ref AsmState AsmState} -> Name -> ClassExport -> SortedMap String JSON -> Core (List FieldExport) parseClassFieldExports name encloser descriptor = case lookup "fields" descriptor of - Nothing => Pure [] + Nothing => pure[] Just (JObject nameAndValues) => traverse (uncurry $ parseClassFieldExport name encloser) nameAndValues Just descriptor => asmCrash ("Expected a JSON object for exported fields in " ++ show name ++ " but found: " ++ show descriptor) @@ -281,19 +281,18 @@ getModifiersAndName name acc [] = believe_me $ crash ("Missing exported function getModifiersAndName _ acc (functionName :: []) = (acc, functionName) getModifiersAndName name acc (modifier :: rest) = getModifiersAndName name (parseModifier name modifier :: acc) rest -parseClassExport : Name -> (parts : List String) -> SortedMap String JSON -> List Annotation -> - Asm (List ExportDescriptor) +parseClassExport : {auto stateRef: Ref AsmState AsmState} -> Name -> (parts : List String) -> SortedMap String JSON -> List Annotation -> Core (List ExportDescriptor) parseClassExport name parts descriptor annotations = do let isInterface = "interface" `elem` parts extends <- if isInterface - then Pure "java/lang/Object" + then pure"java/lang/Object" else case lookup "extends" descriptor of - Nothing => Pure "java/lang/Object" - Just (JString superName) => Pure superName + Nothing => pure"java/lang/Object" + Just (JString superName) => pure superName _ => asmCrash ("Invalid 'extends' for " ++ show name) let implementsKey = if isInterface then "extends" else "implements" implements <- case lookup implementsKey descriptor of - Nothing => Pure [] + Nothing => pure[] Just (JArray implementsJson) => traverse (parseString ("Expected a string value for '" ++ implementsKey ++ "' for " ++ show name)) implementsJson @@ -304,10 +303,10 @@ parseClassExport name parts descriptor annotations = do modifiers annotations let classExportDescriptor = MkClassExportDescriptor classExport fieldExportDescriptors <- parseClassFieldExports name classExport descriptor - Pure $ (classExportDescriptor :: (MkFieldExportDescriptor <$> fieldExportDescriptors)) + pure $ (classExportDescriptor :: (MkFieldExportDescriptor <$> fieldExportDescriptors)) -getReferenceTypeName : String -> InferredType -> Asm String -getReferenceTypeName _ (IRef name _ _) = Pure name +getReferenceTypeName : {auto stateRef: Ref AsmState AsmState} -> String -> InferredType -> Core String +getReferenceTypeName _ (IRef name _ _) = pure name getReferenceTypeName functionName _ = asmCrash ("Expected a reference type to export function " ++ functionName) makePublicByDefault : List Access -> List Access @@ -317,19 +316,19 @@ makePublicByDefault modifiers = then modifiers else (Public :: modifiers) -parseJvmReturnType : String -> SortedMap String JSON -> Asm InferredType +parseJvmReturnType : {auto stateRef: Ref AsmState AsmState} -> String -> SortedMap String JSON -> Core InferredType parseJvmReturnType functionName descriptor = do typeString <- parseString ("Invalid return type for function " ++ functionName) $ fromMaybe (JString "java/lang/Object") $ lookup "returnType" descriptor - Pure $ parse typeString + pure $ parse typeString stripLastChar : String -> String stripLastChar str = case length str of Z => str (S n) => substr 0 n str -parseMethodExport : Name -> (javaName: String) -> (nameParts: List String) -> - SortedMap String JSON -> List Annotation -> Asm MethodExport +parseMethodExport : {auto stateRef: Ref AsmState AsmState} -> Name -> (javaName: String) -> (nameParts: List String) + -> SortedMap String JSON -> List Annotation -> Core MethodExport parseMethodExport idrisName javaName parts descriptor annotations = do let argumentsJson = fromMaybe (JArray []) $ lookup "arguments" descriptor arguments <- parseArgumentsJson idrisName argumentsJson @@ -338,7 +337,7 @@ parseMethodExport idrisName javaName parts descriptor annotations = do let (modifiers, initialMethodName) = getModifiersAndName idrisName [] parts let shouldPerformIO = endsWith initialMethodName "!" let methodName = if shouldPerformIO then stripLastChar initialMethodName else initialMethodName - jvmReturnType <- if methodName == "" then Pure IVoid else parseJvmReturnType javaName descriptor + jvmReturnType <- if methodName == "" then pure IVoid else parseJvmReturnType javaName descriptor let functionType = MkInferredFunctionType jvmReturnType jvmArgumentTypes let adjustedModifiers = makePublicByDefault modifiers let isInstance = not $ elem Static modifiers @@ -355,26 +354,26 @@ parseMethodExport idrisName javaName parts descriptor annotations = do enclosingTypeParts@(_ :: _) => parseClassExport idrisName enclosingTypeParts SortedMap.empty [] | _ => asmCrash ("Unexpected 'enclosingType' for " ++ show javaName) - Pure $ MkMethodExport methodName idrisName functionType shouldPerformIO encloser adjustedModifiers annotations + pure $ MkMethodExport methodName idrisName functionType shouldPerformIO encloser adjustedModifiers annotations adjustedParameterAnnotations -parseFieldExport : Name -> (nameParts: List String) -> - SortedMap String JSON -> List Annotation -> Asm (List ExportDescriptor) +parseFieldExport : {auto stateRef: Ref AsmState AsmState} -> Name -> (nameParts: List String) + -> SortedMap String JSON -> List Annotation -> Core (List ExportDescriptor) parseFieldExport name parts descriptor annotations = do let (modifiers, fieldName) = getModifiersAndName name [] parts Just enclosingTypeName <- - traverse (parseString ("Invalid 'enclosingType' for " ++ show name)) $ lookup "enclosingType" descriptor + traverseOpt (parseString ("Invalid 'enclosingType' for " ++ show name)) $ lookup "enclosingType" descriptor | Nothing => asmCrash ("Missing 'enclosingType' for " ++ show name) [MkClassExportDescriptor encloser] <- case words enclosingTypeName of [] => asmCrash ("Missing enclosing type for " ++ show name) enclosingTypeParts@(_ :: _) => parseClassExport name enclosingTypeParts SortedMap.empty [] | _ => asmCrash ("Unexpected 'enclosingType' for " ++ show name) - Just typeString <- traverse (parseString ("Invalid type for field " ++ show name)) $ lookup "type" descriptor + Just typeString <- traverseOpt (parseString ("Invalid type for field " ++ show name)) $ lookup "type" descriptor | Nothing => asmCrash ("Missing type for " ++ show name) let type = parse typeString - Pure [MkFieldExportDescriptor $ MkFieldExport fieldName type encloser modifiers annotations] + pure[MkFieldExportDescriptor $ MkFieldExport fieldName type encloser modifiers annotations] -parseObjectExportDescriptor : Name -> String -> List (String, JSON) -> Asm (List ExportDescriptor) +parseObjectExportDescriptor : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> List (String, JSON) -> Core (List ExportDescriptor) parseObjectExportDescriptor idrisName javaName descriptorKeyAndValues = do let descriptor = SortedMap.fromList descriptorKeyAndValues let annotationsJson = fromMaybe (JArray []) $ lookup "annotations" descriptor @@ -387,12 +386,12 @@ parseObjectExportDescriptor idrisName javaName descriptorKeyAndValues = do ((isJust (lookup "returnType" descriptor) || elem "" parts), do methodExport <- parseMethodExport idrisName javaName parts descriptor annotations - Pure [MkMethodExportDescriptor methodExport]), + pure[MkMethodExportDescriptor methodExport]), (isJust $ lookup "type" descriptor, parseFieldExport idrisName parts descriptor annotations) ] (parseClassExport idrisName parts descriptor annotations) -parseJsonExport : Name -> String -> Asm (List ExportDescriptor) +parseJsonExport : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> Core (List ExportDescriptor) parseJsonExport functionName descriptor = case String.break (\c => c == '{') descriptor of ("", _) => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) (_, "") => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) @@ -401,7 +400,7 @@ parseJsonExport functionName descriptor = case String.break (\c => c == '{') des Just (JObject keyAndValues) => parseObjectExportDescriptor functionName name keyAndValues _ => asmCrash ("Invalid foreign export descriptor " ++ descriptor ++ " for " ++ show functionName) -parseMethodSimpleExport : Name -> String -> Asm MethodExport +parseMethodSimpleExport : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> Core MethodExport parseMethodSimpleExport functionName descriptor = case String.break (\c => c == '.') descriptor of ("", instanceMethodNameAndSig) => case words instanceMethodNameAndSig of [] => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) @@ -414,7 +413,7 @@ parseMethodSimpleExport functionName descriptor = case String.break (\c => c == let functionType = MkInferredFunctionType (parse (last types)) (instanceType :: (parse <$> (init types))) className <- getReferenceTypeName ("Invalid instance type in export for " ++ show functionName) instanceType let encloser = MkClassExport className functionName inferredObjectType [] [Public] [] - Pure $ MkMethodExport javaName functionName functionType shouldPerformIO encloser [Public] [] [] + pure $ MkMethodExport javaName functionName functionType shouldPerformIO encloser [Public] [] [] (className, staticMethodNameAndArgs) => case words staticMethodNameAndArgs of [] => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) (_ :: []) => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) @@ -423,9 +422,9 @@ parseMethodSimpleExport functionName descriptor = case String.break (\c => c == let javaName = if shouldPerformIO then stripLastChar javaName else javaName let functionType = MkInferredFunctionType (parse (last types)) (parse <$> (init types)) let encloser = MkClassExport className functionName inferredObjectType [] [Public] [] - Pure $ MkMethodExport javaName functionName functionType shouldPerformIO encloser [Public, Static] [] [] + pure $ MkMethodExport javaName functionName functionType shouldPerformIO encloser [Public, Static] [] [] -parseFieldSimpleExport : Name -> String -> Asm FieldExport +parseFieldSimpleExport : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> Core FieldExport parseFieldSimpleExport functionName descriptor = case String.break (\c => c == '#') descriptor of ("", instanceFieldNameAndSig) => case words instanceFieldNameAndSig of [] => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) @@ -435,13 +434,13 @@ parseFieldSimpleExport functionName descriptor = case String.break (\c => c == ' className <- getReferenceTypeName ("Invalid instance type in export for " ++ show functionName) (parse instanceType) let encloser = MkClassExport className functionName inferredObjectType [] [Public] [] - Pure $ MkFieldExport javaName (parse type) encloser [Public] [] + pure $ MkFieldExport javaName (parse type) encloser [Public] [] (className, staticFieldNameAndType) => case words staticFieldNameAndType of [] => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) (_ :: []) => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) (javaName :: type :: _) => do let encloser = MkClassExport className functionName inferredObjectType [] [Public] [] - Pure $ MkFieldExport javaName (parse type) encloser [Public, Static] [] + pure $ MkFieldExport javaName (parse type) encloser [Public, Static] [] %foreign jvm' "java/lang/Character" "isWhitespace" "char" "boolean" isWhitespace : Char -> Bool @@ -454,45 +453,45 @@ parseImport line = case words line of (type :: alias :: []) => Just (alias, type) _ => Nothing -parseImports : Name -> String -> Asm ExportDescriptor +parseImports : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> Core ExportDescriptor parseImports functionName descriptor = case String.break isWhitespace descriptor of ("", _) => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) (_, "") => asmCrash ("Invalid foreign export descriptor for " ++ show functionName) ("export", exportsDescriptor) => - Pure $ MkTypeExportDescriptor functionName (trim <$> (drop 1 $ lines exportsDescriptor)) + pure $ MkTypeExportDescriptor functionName (trim <$> (drop 1 $ lines exportsDescriptor)) (_, importsDescriptor) => - Pure $ MkImportDescriptor functionName $ SortedMap.fromList $ catMaybes $ + pure $ MkImportDescriptor functionName $ SortedMap.fromList $ catMaybes $ parseImport <$> (lines importsDescriptor) -parseExportDescriptor : Name -> String -> Asm (List ExportDescriptor) +parseExportDescriptor : {auto stateRef: Ref AsmState AsmState} -> Name -> String -> Core (List ExportDescriptor) parseExportDescriptor functionName descriptor = cond [ ("{" `isInfixOf` descriptor, parseJsonExport functionName descriptor), ("." `isInfixOf` descriptor, do methodExport <- parseMethodSimpleExport functionName descriptor - Pure [MkMethodExportDescriptor methodExport]), + pure[MkMethodExportDescriptor methodExport]), ("#" `isInfixOf` descriptor, do fieldExport <- parseFieldSimpleExport functionName descriptor - Pure $ [MkFieldExportDescriptor fieldExport]) + pure $ [MkFieldExportDescriptor fieldExport]) ] - (Pure [!(parseImports functionName descriptor)]) + (pure[!(parseImports functionName descriptor)]) export -adjustArgumentsForInstanceMember : Name -> (isInstance: Bool) -> List InferredType -> Asm (List InferredType) -adjustArgumentsForInstanceMember _ False argumentTypes = Pure argumentTypes -adjustArgumentsForInstanceMember _ _ (_ :: jvmArgumentTypes) = Pure jvmArgumentTypes +adjustArgumentsForInstanceMember : {auto stateRef: Ref AsmState AsmState} -> Name -> (isInstance: Bool) -> List InferredType -> Core (List InferredType) +adjustArgumentsForInstanceMember _ False argumentTypes = pure argumentTypes +adjustArgumentsForInstanceMember _ _ (_ :: jvmArgumentTypes) = pure jvmArgumentTypes adjustArgumentsForInstanceMember idrisName _ _ = asmCrash ("Expected first argument to be a reference type for instance member in " ++ show idrisName) export -createAccessorName : String -> String -> Asm String +createAccessorName : {auto stateRef: Ref AsmState AsmState} -> String -> String -> Core String createAccessorName pfix fieldName = case strM fieldName of - StrNil => asmCrash "Field name cannot be empty" - StrCons firstLetter rest => Pure (pfix ++ strCons (toUpper firstLetter) rest) + StrNil => asmCrash "field name cannot be empty" + StrCons firstLetter rest => pure (pfix ++ strCons (toUpper firstLetter) rest) export -createGetter : ClassExport -> FieldExport -> Asm () +createGetter : {auto stateRef: Ref AsmState AsmState} -> ClassExport -> FieldExport -> Core () createGetter classExport fieldExport = do let fieldName = fieldExport.name getterName <- createAccessorName "get" fieldName @@ -501,17 +500,17 @@ createGetter classExport fieldExport = do let isStatic = elem Static fieldExport.modifiers let getterModifiers = Public :: (if isStatic then [Static] else []) let className = classExport.name - CreateMethod getterModifiers "generated.idr" className getterName getterType Nothing Nothing [] [] - MethodCodeStart - when (not isStatic) $ Aload 0 + createMethod getterModifiers "generated.idr" className getterName getterType Nothing Nothing [] [] + methodCodeStart + when (not isStatic) $ aload 0 let instructionType = if isStatic then GetStatic else GetField - Field instructionType className fieldName (getJvmTypeDescriptor fieldType) + field instructionType className fieldName (getJvmTypeDescriptor fieldType) asmReturn fieldType - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + maxStackAndLocal (-1) (-1) + methodCodeEnd export -createSetter : ClassExport -> FieldExport -> Asm () +createSetter : {auto stateRef: Ref AsmState AsmState} -> ClassExport -> FieldExport -> Core () createSetter classExport fieldExport = do let fieldName = fieldExport.name setterName <- createAccessorName "set" fieldName @@ -522,46 +521,46 @@ createSetter classExport fieldExport = do let signature = Just $ getMethodSignature setterType let setterModifiers = Public :: (if isStatic then [Static] else []) let className = classExport.name - CreateMethod setterModifiers "generated.idr" className setterName descriptor signature Nothing [] [] - MethodCodeStart - CreateLabel methodStartLabel - CreateLabel methodEndLabel - LabelStart methodStartLabel - when (not isStatic) $ Aload 0 + createMethod setterModifiers "generated.idr" className setterName descriptor signature Nothing [] [] + methodCodeStart + createLabel methodStartLabel + createLabel methodEndLabel + labelStart methodStartLabel + when (not isStatic) $ aload 0 let arity = the Int $ if isStatic then 1 else 2 let parameterTypes = if isStatic then [fieldType] else [iref className [], fieldType] - jvmArgumentTypesByIndex <- LiftIo $ Map.fromList $ zip [0 .. arity - 1] parameterTypes + jvmArgumentTypesByIndex <- coreLift $ Map.fromList $ zip [0 .. arity - 1] parameterTypes let varIndex = the Int $ if isStatic then 0 else 1 loadVar jvmArgumentTypesByIndex fieldType fieldType varIndex let instructionType = if isStatic then PutStatic else PutField - Field instructionType className fieldName (getJvmTypeDescriptor fieldType) - Return - LabelStart methodEndLabel + field instructionType className fieldName (getJvmTypeDescriptor fieldType) + return + labelStart methodEndLabel let classDescriptor = getJvmTypeDescriptor $ iref classExport.name [] - LocalVariable "this" classDescriptor Nothing methodStartLabel methodEndLabel 0 + localVariable "this" classDescriptor Nothing methodStartLabel methodEndLabel 0 let signature = Just $ getSignature fieldType - LocalVariable fieldName (getJvmTypeDescriptor fieldType) signature methodStartLabel methodEndLabel 1 - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + localVariable fieldName (getJvmTypeDescriptor fieldType) signature methodStartLabel methodEndLabel 1 + maxStackAndLocal (-1) (-1) + methodCodeEnd mutual - getSuperCallExprList : List NamedCExp -> Asm (Maybe NamedCExp) - getSuperCallExprList [] = Pure Nothing - getSuperCallExprList (expr :: rest) = Pure (!(getSuperCallExpr expr) <|> !(getSuperCallExprList rest)) + getSuperCallExprList : {auto stateRef: Ref AsmState AsmState} -> List NamedCExp -> Core (Maybe NamedCExp) + getSuperCallExprList [] = pure Nothing + getSuperCallExprList (expr :: rest) = pure (!(getSuperCallExpr expr) <|> !(getSuperCallExprList rest)) - getSuperCallExprVect : Vect n NamedCExp -> Asm (Maybe NamedCExp) - getSuperCallExprVect [] = Pure Nothing - getSuperCallExprVect (expr :: rest) = Pure (!(getSuperCallExpr expr) <|> !(getSuperCallExprVect rest)) + getSuperCallExprVect : {auto stateRef: Ref AsmState AsmState} -> Vect n NamedCExp -> Core (Maybe NamedCExp) + getSuperCallExprVect [] = pure Nothing + getSuperCallExprVect (expr :: rest) = pure (!(getSuperCallExpr expr) <|> !(getSuperCallExprVect rest)) export - getSuperCallExpr : NamedCExp -> Asm (Maybe NamedCExp) - getSuperCallExpr expr@(NmExtPrim _ (NS _ n) args) = if isSuper n then Pure (Just expr) else getSuperCallExprList args + getSuperCallExpr : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core (Maybe NamedCExp) + getSuperCallExpr expr@(NmExtPrim _ (NS _ n) args) = if isSuper n then pure (Just expr) else getSuperCallExprList args getSuperCallExpr (NmLam _ _ expr) = getSuperCallExpr expr - getSuperCallExpr (NmLet _ _ value expr) = Pure (!(getSuperCallExpr value) <|> !(getSuperCallExpr expr)) + getSuperCallExpr (NmLet _ _ value expr) = pure (!(getSuperCallExpr value) <|> !(getSuperCallExpr expr)) getSuperCallExpr (NmApp _ (NmRef _ name) args) = do (_, MkNmFun _ def) <- getFcAndDefinition (jvmSimpleName name) | _ => getSuperCallExprList args - Pure (!(getSuperCallExpr def) <|> !(getSuperCallExprList args)) + pure (!(getSuperCallExpr def) <|> !(getSuperCallExprList args)) getSuperCallExpr (NmOp _ _ args) = getSuperCallExprVect args getSuperCallExpr (NmForce _ _ expr) = getSuperCallExpr expr getSuperCallExpr (NmDelay _ _ expr) = getSuperCallExpr expr @@ -569,7 +568,7 @@ mutual getSuperCallCaseExpr (expr :: (getSuperCallConAltExpr <$> alts)) deflt getSuperCallExpr (NmConstCase _ expr alts deflt) = getSuperCallCaseExpr (expr :: (getSuperCallConstAltExpr <$> alts)) deflt - getSuperCallExpr _ = Pure Nothing + getSuperCallExpr _ = pure Nothing getSuperCallConAltExpr : NamedConAlt -> NamedCExp getSuperCallConAltExpr (MkNConAlt _ _ _ _ expr) = expr @@ -577,9 +576,9 @@ mutual getSuperCallConstAltExpr : NamedConstAlt -> NamedCExp getSuperCallConstAltExpr (MkNConstAlt _ expr) = expr - getSuperCallCaseExpr : List NamedCExp -> Maybe NamedCExp -> Asm (Maybe NamedCExp) + getSuperCallCaseExpr : {auto stateRef: Ref AsmState AsmState} -> List NamedCExp -> Maybe NamedCExp -> Core (Maybe NamedCExp) getSuperCallCaseExpr alts Nothing = getSuperCallExprList alts - getSuperCallCaseExpr alts (Just deflt) = Pure (!(getSuperCallExprList alts) <|> !(getSuperCallExpr deflt)) + getSuperCallCaseExpr alts (Just deflt) = pure (!(getSuperCallExprList alts) <|> !(getSuperCallExpr deflt)) substituteTypeName : SortedMap String String -> String -> String substituteTypeName imports type = fromMaybe type $ SortedMap.lookup type imports @@ -699,7 +698,7 @@ parseExportDescriptors globalState descriptors = do go acc [] = pure acc go (imports, descriptors) ((idrisName, descriptor) :: rest) = do asmState <- createAsmState globalState idrisName - (exportDescriptors, _) <- asm asmState (parseExportDescriptor idrisName descriptor) + exportDescriptors <- runAsm asmState (\stateRef => parseExportDescriptor idrisName descriptor) case exportDescriptors of [MkImportDescriptor name currentImports] => let newImports = SortedMap.merge imports (SortedMap.singleton (getNamespace name) currentImports) @@ -751,58 +750,58 @@ isIdrisJvmAnnotation : Annotation -> Bool isIdrisJvmAnnotation (MkAnnotation name _) = name `elem` knownAnnotations export -exportClass : ClassExport -> Asm () +exportClass : {auto stateRef: Ref AsmState AsmState} -> ClassExport -> Core () exportClass (MkClassExport name _ extends implements modifiers annotations) = do - CreateClass [ComputeMaxs, ComputeFrames] + createClass [ComputeMaxs, ComputeFrames] let annotations = filter (not . isIdrisJvmAnnotation) annotations let signature = getSignature extends ++ concat (getSignature <$> implements) extendsTypeName <- getJvmReferenceTypeName extends implementsTypeNames <- traverse getJvmReferenceTypeName implements let asmAnnotations = asmAnnotation <$> annotations - ClassCodeStart javaClassFileVersion modifiers name (Just signature) extendsTypeName implementsTypeNames asmAnnotations + classCodeStart javaClassFileVersion modifiers name (Just signature) extendsTypeName implementsTypeNames asmAnnotations export -exportField : FieldExport -> Asm () +exportField : {auto stateRef: Ref AsmState AsmState} -> FieldExport -> Core () exportField (MkFieldExport fieldName type encloser modifiers annotations) = do let jvmClassName = encloser.name let asmAnnotations = asmAnnotation <$> annotations - CreateField modifiers "Unknown.idr" jvmClassName fieldName (getJvmTypeDescriptor type) Nothing Nothing asmAnnotations - FieldEnd + createField modifiers "Unknown.idr" jvmClassName fieldName (getJvmTypeDescriptor type) Nothing Nothing asmAnnotations + fieldEnd export -exportType : String -> Asm () +exportType : {auto stateRef: Ref AsmState AsmState} -> String -> Core () exportType name = do exportClass (MkClassExport name (UN $ Basic name) inferredObjectType [] [Public] []) - CreateField [Private, Final] "Unknown.idr" name "idrisValue" (getJvmTypeDescriptor inferredObjectType) + createField [Private, Final] "Unknown.idr" name "idrisValue" (getJvmTypeDescriptor inferredObjectType) Nothing Nothing [] - FieldEnd - - CreateMethod [Private] "Unknown.idr" name "" "(Ljava/lang/Object;)V" Nothing Nothing [] [] - MethodCodeStart - Aload 0 - InvokeMethod InvokeSpecial "java/lang/Object" "" "()V" False - Aload 0 - Aload 1 - Field PutField name "idrisValue" "Ljava/lang/Object;" - Return - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + fieldEnd + + createMethod [Private] "Unknown.idr" name "" "(Ljava/lang/Object;)V" Nothing Nothing [] [] + methodCodeStart + aload 0 + invokeMethod InvokeSpecial "java/lang/Object" "" "()V" False + aload 0 + aload 1 + field PutField name "idrisValue" "Ljava/lang/Object;" + return + maxStackAndLocal (-1) (-1) + methodCodeEnd let toJavaDescriptor = getMethodDescriptor $ MkInferredFunctionType (IRef name Class []) [inferredObjectType] - CreateMethod [Public, Static] "Unknown.idr" name "toJava" toJavaDescriptor Nothing Nothing [] [] - MethodCodeStart - New name - Dup - Aload 0 - InvokeMethod InvokeSpecial name "" "(Ljava/lang/Object;)V" False - Areturn - MaxStackAndLocal (-1) (-1) - MethodCodeEnd - - CreateMethod [Public] "Unknown.idr" name "toIdris" "()Ljava/lang/Object;" Nothing Nothing [] [] - MethodCodeStart - Aload 0 - Field GetField name "idrisValue" "Ljava/lang/Object;" - Areturn - MaxStackAndLocal (-1) (-1) - MethodCodeEnd + createMethod [Public, Static] "Unknown.idr" name "toJava" toJavaDescriptor Nothing Nothing [] [] + methodCodeStart + new name + dup + aload 0 + invokeMethod InvokeSpecial name "" "(Ljava/lang/Object;)V" False + areturn + maxStackAndLocal (-1) (-1) + methodCodeEnd + + createMethod [Public] "Unknown.idr" name "toIdris" "()Ljava/lang/Object;" Nothing Nothing [] [] + methodCodeStart + aload 0 + field GetField name "idrisValue" "Ljava/lang/Object;" + areturn + maxStackAndLocal (-1) (-1) + methodCodeEnd diff --git a/src/Compiler/Jvm/Foreign.idr b/src/Compiler/Jvm/Foreign.idr index 0a71e2947..775d5dc69 100644 --- a/src/Compiler/Jvm/Foreign.idr +++ b/src/Compiler/Jvm/Foreign.idr @@ -30,66 +30,65 @@ getArity arity (CFFun argument _) = getArity (arity + 1) argument getArity arity _ = arity export -parse : FC -> CFType -> Asm InferredType -parse _ CFUnit = Pure IVoid -parse _ CFInt = Pure IInt -parse _ CFInt8 = Pure IByte -parse _ CFInt16 = Pure IShort -parse _ CFInt32 = Pure IInt -parse _ CFInt64 = Pure ILong -parse _ CFUnsigned8 = Pure IInt -parse _ CFUnsigned16 = Pure IInt -parse _ CFUnsigned32 = Pure IInt -parse _ CFUnsigned64 = Pure ILong -parse _ CFString = Pure inferredStringType -parse _ CFDouble = Pure IDouble -parse _ CFInteger = Pure inferredBigIntegerType -parse _ CFChar = Pure IChar -parse _ CFWorld = Pure IInt +parse : {auto stateRef: Ref AsmState AsmState} -> FC -> CFType -> Core InferredType +parse _ CFUnit = pure IVoid +parse _ CFInt = pure IInt +parse _ CFInt8 = pure IByte +parse _ CFInt16 = pure IShort +parse _ CFInt32 = pure IInt +parse _ CFInt64 = pure ILong +parse _ CFUnsigned8 = pure IInt +parse _ CFUnsigned16 = pure IInt +parse _ CFUnsigned32 = pure IInt +parse _ CFUnsigned64 = pure ILong +parse _ CFString = pure inferredStringType +parse _ CFDouble = pure IDouble +parse _ CFInteger = pure inferredBigIntegerType +parse _ CFChar = pure IChar +parse _ CFWorld = pure IInt parse fc (CFIORes returnType) = parse fc returnType -parse fc (CFStruct name fields) = Pure $ iref name [] -parse fc (CFFun argument _) = Pure $ getFunctionInterface (getArity 1 argument) +parse fc (CFStruct name fields) = pure $ iref name [] +parse fc (CFFun argument _) = pure $ getFunctionInterface (getArity 1 argument) parse fc (CFUser name (ty :: _)) = if name == builtin "Pair" then case ty of CFStruct name _ => case words name of [] => asmCrash ("Invalid Java lambda type at " ++ show fc) - (javaInterfaceName :: _) => Pure $ IRef javaInterfaceName Interface [] - _ => Pure inferredObjectType - else if name == arrayName then Pure $ IArray !(parse fc ty) - else Pure inferredObjectType -parse _ ty = Pure inferredObjectType + (javaInterfaceName :: _) => pure $ IRef javaInterfaceName Interface [] + _ => pure inferredObjectType + else if name == arrayName then pure $ IArray !(parse fc ty) + else pure inferredObjectType +parse _ ty = pure inferredObjectType export -parseForeignFunctionDescriptor : FC -> List String -> List InferredType -> InferredType -> - Asm (String, String, InferredType, List InferredType) +parseForeignFunctionDescriptor : {auto stateRef: Ref AsmState AsmState} -> FC -> List String -> List InferredType -> InferredType -> Core (String, String, InferredType, List InferredType) parseForeignFunctionDescriptor fc (functionDescriptor :: descriptorParts) argumentTypes returnType = case String.break (== '(') functionDescriptor of (fn, "") => do className <- getClassName fn descriptorParts returnType argumentTypes - Pure (className, fn, returnType, argumentTypes) + pure (className, fn, returnType, argumentTypes) (fn, signature) => do let descriptors = toList $ String.split (== ' ') (assert_total $ strTail . fst $ break (== ')') signature) (argumentDeclarationTypesReversed, returnType) <- go [] descriptors let argumentDeclarationTypes = List.reverse argumentDeclarationTypesReversed className <- getClassName fn descriptorParts returnType argumentDeclarationTypes - Pure (className, fn, returnType, argumentDeclarationTypes) + pure (className, fn, returnType, argumentDeclarationTypes) where - getInstanceMemberClass : (errorMessage: Lazy String) -> List InferredType -> Asm String - getInstanceMemberClass errorMessage ((IRef className _ _) :: _) = Pure className - getInstanceMemberClass errorMessage _ = Throw fc errorMessage + getInstanceMemberClass : (errorMessage: Lazy String) -> List InferredType -> Core String + getInstanceMemberClass errorMessage ((IRef className _ _) :: _) = pure className + getInstanceMemberClass errorMessage _ = throw $ GenericMsg fc errorMessage - getDescriptorClassName : String -> Asm String + getDescriptorClassName : String -> Core String getDescriptorClassName memberName = case descriptorParts of - (className :: _) => Pure className - _ => Throw fc + (className :: _) => pure className + _ => throw $ GenericMsg fc ("Static member " ++ memberName ++ " must have an explicit class name in foreign descriptor") - getClassName : String -> List String -> InferredType -> List InferredType -> Asm String + getClassName : String -> List String -> InferredType -> List InferredType -> Core String getClassName memberName descriptorParts returnType argumentTypes = let arity = length argumentTypes in @@ -113,23 +112,25 @@ parseForeignFunctionDescriptor fc (functionDescriptor :: descriptorParts) argume if memberName == "" then case returnType of - IRef className _ _ => Pure className - _ => Throw fc ("Constructor must return a reference type") + IRef className _ _ => pure className + _ => throw $ GenericMsg fc ("Constructor must return a reference type") else getDescriptorClassName memberName - go : List InferredType -> List String -> Asm (List InferredType, InferredType) - go acc [] = Pure (acc, IUnknown) - go acc (returnTypeDesc :: []) = Pure (acc, parse returnTypeDesc) + go : List InferredType -> List String -> Core (List InferredType, InferredType) + go acc [] = pure (acc, IUnknown) + go acc (returnTypeDesc :: []) = pure (acc, parse returnTypeDesc) go acc (argument :: rest) = do let foreignType = parse argument go (foreignType :: acc) rest -parseForeignFunctionDescriptor fc descriptors _ _ = Throw fc $ "Invalid foreign descriptor: " ++ show descriptors +parseForeignFunctionDescriptor fc descriptors _ _ = + throw $ GenericMsg fc $ "Invalid foreign descriptor: " ++ show descriptors export -findJvmDescriptor : FC -> Name -> List String -> Asm (List String) +findJvmDescriptor : {auto stateRef: Ref AsmState AsmState} -> FC -> Name -> List String -> Core (List String) findJvmDescriptor fc name descriptors = case parseCC ["jvm"] descriptors of - Just ("jvm", descriptorParts) => Pure descriptorParts - _ => Throw fc $ "Cannot compile foreign function " ++ show name ++ " to JVM as JVM foreign descriptor is missing" + Just ("jvm", descriptorParts) => pure descriptorParts + _ => throw $ GenericMsg fc $ "Cannot compile foreign function " ++ show name ++ + " to JVM as JVM foreign descriptor is missing" export getArgumentIndices : (arity: Int) -> List String -> IO (Map String Int) @@ -150,10 +151,9 @@ isValidArgumentType : CFType -> Bool isValidArgumentType (CFUser (UN (Basic "Type")) _) = False isValidArgumentType _ = True -getIdrisJvmParameters : FC -> List CFType -> Asm (List (Nat, Bool, InferredType)) +getIdrisJvmParameters : {auto stateRef: Ref AsmState AsmState} -> FC -> List CFType -> Core (List (Nat, Bool, InferredType)) getIdrisJvmParameters fc idrisTypes = pure $ reverse !(go [] 0 idrisTypes) where - go : List (Nat, Bool, InferredType) -> Nat -> List CFType -> - Asm (List (Nat, Bool, InferredType)) + go : List (Nat, Bool, InferredType) -> Nat -> List CFType -> Core (List (Nat, Bool, InferredType)) go acc _ [] = pure acc go acc index (idrisType :: rest) = do jvmType <- parse fc idrisType @@ -166,18 +166,16 @@ getJvmType (_, _, jvmType) = jvmType shouldPassToForeign : (CFType, Nat, Bool, InferredType) -> Bool shouldPassToForeign (_, _, shouldPass, _) = shouldPass -getArgumentNameAndTypes : FC -> List InferredType -> List (Nat, Bool, InferredType) -> - Asm (List (String, InferredType)) +getArgumentNameAndTypes : {auto stateRef: Ref AsmState AsmState} -> FC -> List InferredType -> List (Nat, Bool, InferredType) -> Core (List (String, InferredType)) getArgumentNameAndTypes fc descriptorTypes params = reverse <$> go [] descriptorTypes params where - go : List (String, InferredType) -> List InferredType -> List (Nat, Bool, InferredType) -> - Asm (List (String, InferredType)) + go : List (String, InferredType) -> List InferredType -> List (Nat, Bool, InferredType) -> Core (List (String, InferredType)) go acc [] _ = pure acc -- Ignore any additional arguments from Idris - go acc _ [] = Throw fc "Foreign descriptor and Idris types do not match" + go acc _ [] = throw $ GenericMsg fc "Foreign descriptor and Idris types do not match" go acc (descriptorType :: descriptorTypes) ((index, _, _) :: rest) = go (("arg" ++ show index, descriptorType) :: acc) descriptorTypes rest export -inferForeign : String -> Name -> FC -> List String -> List CFType -> CFType -> Asm () +inferForeign : {auto stateRef: Ref AsmState AsmState} -> String -> Name -> FC -> List String -> List CFType -> CFType -> Core () inferForeign programName idrisName fc foreignDescriptors argumentTypes returnType = do resetScope let jname = jvmName idrisName @@ -201,7 +199,7 @@ inferForeign programName idrisName fc foreignDescriptors argumentTypes returnTyp argumentNameAndTypes <- getArgumentNameAndTypes fc jvmArgumentTypesFromDescriptor jvmArguments let methodReturnType = if isNilArity then delayedType else inferredObjectType let inferredFunctionType = MkInferredFunctionType methodReturnType (replicate arityNat inferredObjectType) - scopes <- LiftIo $ ArrayList.new {elemTy=Scope} + scopes <- coreLift $ ArrayList.new {elemTy=Scope} let extPrimName = NS (mkNamespace "") $ UN $ Basic $ getPrimMethodName (length argumentNameAndTypes) foreignFunctionName let externalFunctionBody = @@ -213,24 +211,24 @@ inferForeign programName idrisName fc foreignDescriptors argumentTypes returnTyp let functionBody = if isNilArity then NmDelay fc LLazy externalFunctionBody else externalFunctionBody let function = MkFunction jname inferredFunctionType (subtyping scopes) 0 jvmClassAndMethodName functionBody setCurrentFunction function - LiftIo $ AsmGlobalState.addFunction !getGlobalState jname function + coreLift $ AsmGlobalState.addFunction !getGlobalState jname function let parameterTypes = parameterTypes inferredFunctionType - argumentTypesByIndex <- LiftIo $ + argumentTypesByIndex <- coreLift $ if isNilArity then Map.newTreeMap {key=Int} {value=InferredType} else Map.fromList $ zip [0 .. arity - 1] parameterTypes - argumentTypesByName <- LiftIo $ Map.fromList $ zip argumentNames parameterTypes - argIndices <- LiftIo $ getArgumentIndices arity argumentNames + argumentTypesByName <- coreLift $ Map.fromList $ zip argumentNames parameterTypes + argIndices <- coreLift $ getArgumentIndices arity argumentNames let functionScope = MkScope scopeIndex Nothing argumentTypesByName argumentTypesByIndex argIndices argIndices methodReturnType arity (0, 0) ("", "") [] saveScope functionScope when isNilArity $ do let parentScopeIndex = scopeIndex scopeIndex <- newScopeIndex - variableTypes <- LiftIo $ Map.newTreeMap {key=String} {value=InferredType} - allVariableTypes <- LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} - variableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} - allVariableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} + variableTypes <- coreLift $ Map.newTreeMap {key=String} {value=InferredType} + allVariableTypes <- coreLift $ Map.newTreeMap {key=Int} {value=InferredType} + variableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} + allVariableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} let delayLambdaScope = MkScope scopeIndex (Just parentScopeIndex) variableTypes allVariableTypes variableIndices allVariableIndices IUnknown 0 (0, 0) ("", "") [] diff --git a/src/Compiler/Jvm/InferredType.idr b/src/Compiler/Jvm/InferredType.idr index d75336923..f3ef2115b 100644 --- a/src/Compiler/Jvm/InferredType.idr +++ b/src/Compiler/Jvm/InferredType.idr @@ -19,6 +19,7 @@ mutual | IArray InferredType | IVoid | IFunction JavaLambdaType | IUnknown + | TypeParam String public export record InferredFunctionType where @@ -63,6 +64,7 @@ mutual (IFunction javaLambdaType1) == (IFunction javaLambdaType2) = assert_total $ javaLambdaType1 == javaLambdaType2 IUnknown == IUnknown = True IVoid == IVoid = True + (TypeParam name1) == (TypeParam name2) = name1 == name2 _ == _ = False mutual @@ -92,6 +94,7 @@ mutual show (IFunction lambdaTy) = assert_total $ "Function " ++ show lambdaTy show IUnknown = "unknown" show IVoid = "void" + show (TypeParam name) = name export inferredObjectType : InferredType @@ -398,6 +401,7 @@ mutual createExtPrimTypeSpecFn implementationType] createExtPrimTypeSpec (IArray ty) = "[" ++ createExtPrimTypeSpec ty createExtPrimTypeSpec IUnknown = createExtPrimTypeSpec inferredObjectType + createExtPrimTypeSpec (TypeParam name) = name export isObjectType : InferredType -> Bool diff --git a/src/Compiler/Jvm/Math.idr b/src/Compiler/Jvm/Math.idr index 622276b35..0082e1ea6 100644 --- a/src/Compiler/Jvm/Math.idr +++ b/src/Compiler/Jvm/Math.idr @@ -1,103 +1,105 @@ module Compiler.Jvm.Math import Core.TT +import Core.Context +import Core.Core import Compiler.Jvm.Asm export -longDivideUnsigned : Asm () -longDivideUnsigned = InvokeMethod InvokeStatic "java/lang/Long" "divideUnsigned" "(JJ)J" False +longDivideUnsigned : {auto stateRef: Ref AsmState AsmState} -> Core () +longDivideUnsigned = invokeMethod InvokeStatic "java/lang/Long" "divideUnsigned" "(JJ)J" False export -longRemainderUnsigned : Asm () -longRemainderUnsigned = InvokeMethod InvokeStatic "java/lang/Long" "remainderUnsigned" "(JJ)J" False +longRemainderUnsigned : {auto stateRef: Ref AsmState AsmState} -> Core () +longRemainderUnsigned = invokeMethod InvokeStatic "java/lang/Long" "remainderUnsigned" "(JJ)J" False export -longCompareUnsigned : Asm () -longCompareUnsigned = InvokeMethod InvokeStatic "java/lang/Long" "compareUnsigned" "(JJ)I" False +longCompareUnsigned : {auto stateRef: Ref AsmState AsmState} -> Core () +longCompareUnsigned = invokeMethod InvokeStatic "java/lang/Long" "compareUnsigned" "(JJ)I" False export -integerDivideUnsigned : Asm () -integerDivideUnsigned = InvokeMethod InvokeStatic "java/lang/Integer" "divideUnsigned" "(II)I" False +integerDivideUnsigned : {auto stateRef: Ref AsmState AsmState} -> Core () +integerDivideUnsigned = invokeMethod InvokeStatic "java/lang/Integer" "divideUnsigned" "(II)I" False export -integerRemainderUnsigned : Asm () -integerRemainderUnsigned = InvokeMethod InvokeStatic "java/lang/Integer" "remainderUnsigned" "(II)I" False +integerRemainderUnsigned : {auto stateRef: Ref AsmState AsmState} -> Core () +integerRemainderUnsigned = invokeMethod InvokeStatic "java/lang/Integer" "remainderUnsigned" "(II)I" False export -integerCompareUnsigned : Asm () -integerCompareUnsigned = InvokeMethod InvokeStatic "java/lang/Integer" "compareUnsigned" "(II)I" False +integerCompareUnsigned : {auto stateRef: Ref AsmState AsmState} -> Core () +integerCompareUnsigned = invokeMethod InvokeStatic "java/lang/Integer" "compareUnsigned" "(II)I" False export -add : IntKind -> Asm () -add (Signed Unlimited) = InvokeMethod InvokeVirtual "java/math/BigInteger" "add" +add : {auto stateRef: Ref AsmState AsmState} -> IntKind -> Core () +add (Signed Unlimited) = invokeMethod InvokeVirtual "java/math/BigInteger" "add" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False -add (Signed (P 64)) = Ladd -add (Signed (P 32)) = Iadd -add (Signed (P n)) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("add" ++ show n) +add (Signed (P 64)) = ladd +add (Signed (P 32)) = iadd +add (Signed (P n)) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("add" ++ show n) "(II)I" False -add (Unsigned 64) = Ladd -add (Unsigned 32) = Iadd -add (Unsigned n) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("uadd" ++ show n) +add (Unsigned 64) = ladd +add (Unsigned 32) = iadd +add (Unsigned n) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("uadd" ++ show n) "(II)I" False export -sub : IntKind -> Asm () -sub (Signed Unlimited) = InvokeMethod InvokeVirtual "java/math/BigInteger" "subtract" +sub : {auto stateRef: Ref AsmState AsmState} -> IntKind -> Core () +sub (Signed Unlimited) = invokeMethod InvokeVirtual "java/math/BigInteger" "subtract" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False -sub (Signed (P 64)) = Lsub -sub (Signed (P 32)) = Isub -sub (Signed (P n)) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("sub" ++ show n) +sub (Signed (P 64)) = lsub +sub (Signed (P 32)) = isub +sub (Signed (P n)) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("sub" ++ show n) "(II)I" False -sub (Unsigned 64) = Lsub -sub (Unsigned 32) = Isub -sub (Unsigned n) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("usub" ++ show n) +sub (Unsigned 64) = lsub +sub (Unsigned 32) = isub +sub (Unsigned n) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("usub" ++ show n) "(II)I" False export -mul : IntKind -> Asm () -mul (Signed Unlimited) = InvokeMethod InvokeVirtual "java/math/BigInteger" "multiply" +mul : {auto stateRef: Ref AsmState AsmState} -> IntKind -> Core () +mul (Signed Unlimited) = invokeMethod InvokeVirtual "java/math/BigInteger" "multiply" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False -mul (Signed (P 64)) = Lmul -mul (Signed (P 32)) = Imul -mul (Signed (P n)) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("mul" ++ show n) +mul (Signed (P 64)) = lmul +mul (Signed (P 32)) = imul +mul (Signed (P n)) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("mul" ++ show n) "(II)I" False -mul (Unsigned 64) = Lmul -mul (Unsigned 32) = Imul -mul (Unsigned n) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("umul" ++ show n) +mul (Unsigned 64) = lmul +mul (Unsigned 32) = imul +mul (Unsigned n) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("umul" ++ show n) "(II)I" False export -div : IntKind -> Asm () -div (Signed Unlimited) = InvokeMethod InvokeVirtual "java/math/BigInteger" "divide" +div : {auto stateRef: Ref AsmState AsmState} -> IntKind -> Core () +div (Signed Unlimited) = invokeMethod InvokeVirtual "java/math/BigInteger" "divide" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False -div (Signed (P 64)) = Ldiv -div (Signed (P 32)) = Idiv -div (Signed (P n)) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("div" ++ show n) +div (Signed (P 64)) = ldiv +div (Signed (P 32)) = idiv +div (Signed (P n)) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("div" ++ show n) "(II)I" False div (Unsigned 64) = longDivideUnsigned div (Unsigned 32) = integerDivideUnsigned -div (Unsigned n) = Idiv +div (Unsigned n) = idiv export -mod : IntKind -> Asm () -mod (Signed Unlimited) = InvokeMethod InvokeVirtual "java/math/BigInteger" "remainder" +mod : {auto stateRef: Ref AsmState AsmState} -> IntKind -> Core () +mod (Signed Unlimited) = invokeMethod InvokeVirtual "java/math/BigInteger" "remainder" "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" False -mod (Signed (P 64)) = Lrem -mod (Signed (P n)) = Irem +mod (Signed (P 64)) = lrem +mod (Signed (P n)) = irem mod (Unsigned 64) = longRemainderUnsigned mod (Unsigned 32) = integerRemainderUnsigned -mod (Unsigned n) = Irem +mod (Unsigned n) = irem export -shl : IntKind -> Asm () +shl : {auto stateRef: Ref AsmState AsmState} -> IntKind -> Core () shl (Signed Unlimited) = do - InvokeMethod InvokeVirtual "java/math/BigInteger" "intValueExact" "()I" False - InvokeMethod InvokeVirtual "java/math/BigInteger" "shiftLeft" "(I)Ljava/math/BigInteger;" False -shl (Signed (P 64)) = do L2i; Lshl -shl (Signed (P 32)) = Ishl -shl (Signed (P n)) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("shl" ++ show n) + invokeMethod InvokeVirtual "java/math/BigInteger" "intValueExact" "()I" False + invokeMethod InvokeVirtual "java/math/BigInteger" "shiftLeft" "(I)Ljava/math/BigInteger;" False +shl (Signed (P 64)) = do l2i; lshl +shl (Signed (P 32)) = ishl +shl (Signed (P n)) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("shl" ++ show n) "(II)I" False -shl (Unsigned 64) = do L2i; Lshl -shl (Unsigned 32) = Ishl -shl (Unsigned n) = InvokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("ushl" ++ show n) +shl (Unsigned 64) = do l2i; lshl +shl (Unsigned 32) = ishl +shl (Unsigned n) = invokeMethod InvokeStatic "io/github/mmhelloworld/idrisjvm/runtime/IdrisMath" ("ushl" ++ show n) "(II)I" False diff --git a/src/Compiler/Jvm/MockAsm.idr b/src/Compiler/Jvm/MockAsm.idr deleted file mode 100644 index 918c8da7b..000000000 --- a/src/Compiler/Jvm/MockAsm.idr +++ /dev/null @@ -1,328 +0,0 @@ -module Compiler.Jvm.MockAsm - -import Compiler.Common -import Compiler.CompileExpr -import Compiler.Inline - -import Core.Context -import Core.Name -import Core.TT - -import Data.Maybe -import Libraries.Data.SortedMap -import Data.String -import Data.Vect - -import Compiler.Jvm.Asm -import Compiler.Jvm.InferredType -import Compiler.Jvm.Jname -import Compiler.Jvm.ShowUtil - -%foreign "jvm:toString(java/lang/Object java/lang/String),java/util/Objects" -prim_objectToString : AnyPtr -> PrimIO String - -export -objectToString : a -> String -objectToString value = unsafePerformIO $ primIO (prim_objectToString (believe_me value)) - -log : String -> IO () -log message = do - time <- currentTimeString - threadName <- getCurrentThreadName - putStrLn $ time ++ " [" ++ threadName ++ "]" ++ message - -export -mockRunAsm : AsmState -> Asm a -> IO (a, AsmState) -mockRunAsm state Aaload = assemble state $ log "aaload" -mockRunAsm state Aastore = assemble state $ log "aastore" -mockRunAsm state Aconstnull = assemble state $ log "aconstnull" -mockRunAsm state (Aload n) = assemble state $ - log $ "aload " ++ show n -mockRunAsm state (Anewarray desc) = assemble state $ - log $ "anewarray " ++ desc -mockRunAsm state Anewintarray = assemble state $ - log "anewintarray" -mockRunAsm state Anewbooleanarray = assemble state $ - log "anewbooleanarray" -mockRunAsm state Anewbytearray = assemble state $ - log "anewbytearray" -mockRunAsm state Anewchararray = assemble state $ - log "anewchararray" -mockRunAsm state Anewshortarray = assemble state $ - log "anewshortarray" -mockRunAsm state Anewlongarray = assemble state $ - log "anewlongarray" -mockRunAsm state Anewfloatarray = assemble state $ - log "anewfloatarray" -mockRunAsm state Anewdoublearray = assemble state $ - log "anewdoublearray" -mockRunAsm state Arraylength = assemble state $ log "arraylength" -mockRunAsm state Areturn = assemble state $ log "areturn" -mockRunAsm state (Astore n) = assemble state $ - log $ "astore " ++ show n -mockRunAsm state Baload = assemble state $ log "baload" -mockRunAsm state Bastore = assemble state $ log "bastore" -mockRunAsm state Caload = assemble state $ log "caload" -mockRunAsm state Castore = assemble state $ log "castore" -mockRunAsm state (Checkcast desc) = assemble state $ - log $ "checkcast " ++ desc -mockRunAsm state (ClassCodeStart version access className sig parent intf anns) = assemble state $ - log $ unwords [ - "classCodeStart", - show version, - show (show access), - className, - (fromMaybe "" sig), - parent] - -mockRunAsm state (CreateClass opts) = assemble state $ log $ "createClass " ++ show opts -mockRunAsm state (CreateField accs sourceFileName className fieldName desc sig fieldInitialValue annotations) = - assemble state $ do - let jaccs = sum $ accessNum <$> accs - log $ unwords [ - "createField", - show jaccs, - sourceFileName, - className, - fieldName, - desc, - fromMaybe "" sig, - (objectToString $ maybeToNullable (toJFieldInitialValue <$> fieldInitialValue))] - -mockRunAsm state (CreateLabel label) = assemble state $ pure () - -mockRunAsm state (CreateMethod accs sourceFileName className methodName desc sig exceptions anns paramAnns) = - let newState = { currentMethodName := Jqualified className methodName } state - in assemble newState $ do - log $ "**************** " ++ methodName ++ " ******************" - log $ unwords [ - "createMethod", - show accs, - sourceFileName, - className, - methodName, - desc] - -mockRunAsm state (CreateIdrisConstructorClass className isStringConstructor constructorParameterCount) = - assemble state $ log ("CreateIdrisConstructorClass " ++ className ++ " " ++ - show isStringConstructor ++ " " ++ show constructorParameterCount) - -mockRunAsm state D2i = assemble state $ log "d2i" -mockRunAsm state D2f = assemble state $ log "d2f" -mockRunAsm state D2l = assemble state $ log "d2l" -mockRunAsm state Dadd = assemble state $ log "dadd" -mockRunAsm state Dcmpl = assemble state $ log "dcmpl" -mockRunAsm state Dcmpg = assemble state $ log "dcmpg" -mockRunAsm state (Dconst n) = assemble state $ log $ "dconst " ++ show n -mockRunAsm state Daload = assemble state $ log "daload" -mockRunAsm state Dastore = assemble state $ log "dastore" -mockRunAsm state Ddiv = assemble state $ log "ddiv" - -mockRunAsm state (Debug message) = assemble state $ log message - -mockRunAsm state (Dload n) = - assemble state $ log $ "dload " ++ show n -mockRunAsm state Dmul = assemble state $ log "dmul" -mockRunAsm state Dneg = assemble state $ log "dneg" -mockRunAsm state Drem = assemble state $ log "drem" -mockRunAsm state Dreturn = assemble state $ log "dreturn" -mockRunAsm state (Dstore n) = - assemble state $ log $ "dstore " ++ show n -mockRunAsm state Dsub = assemble state $ log "dsub" -mockRunAsm state Dup = assemble state $ log "dup" -mockRunAsm state (Error err) = - assemble state $ log $ "error " ++ err -mockRunAsm state F2d = assemble state $ log "f2d" -mockRunAsm state Faload = assemble state $ log "faload" -mockRunAsm state Fastore = assemble state $ log "fastore" -mockRunAsm state (Fconst n) = - assemble state $ log $ "fconst " ++ show n -mockRunAsm state (Field finsType cname fname desc) = assemble state $ do - let finsTypeNum = fieldInsTypeNum finsType - log $ unwords [ - "field", - show finsTypeNum, - cname, - fname, - desc] - -mockRunAsm state FieldEnd = assemble state $ log "fieldEnd" - -mockRunAsm state (Fload n) = - assemble state $ log $ "fload " ++ show n - -mockRunAsm state (Frame frameType nLocal localSigs nStack stackSigs) = assemble state $ do - let ftypeNum = frameTypeNum frameType - log $ unwords [ - "frame", - show ftypeNum, - show nLocal, - show nStack] - -mockRunAsm state Freturn = assemble state $ log "freturn" -mockRunAsm state (Fstore n) = - assemble state $ log $ "fstore " ++ show n - -mockRunAsm state (Goto label) = - assemble state $ log $ "goto " ++ label - -mockRunAsm state I2b = assemble state $ log "i2b" -mockRunAsm state I2c = assemble state $ log "i2c" -mockRunAsm state I2d = assemble state $ log "i2d" -mockRunAsm state I2l = assemble state $ log "i2l" -mockRunAsm state I2s = assemble state $ log "i2s" -mockRunAsm state Iadd = assemble state $ log "iadd" -mockRunAsm state Iaload = assemble state $ log "iaload" -mockRunAsm state Iand = assemble state $ log "iand" -mockRunAsm state Iastore = assemble state $ log "iastore" -mockRunAsm state Ior = assemble state $ log "ior" -mockRunAsm state Ixor = assemble state $ log "ixor" -mockRunAsm state Icompl = assemble state $ log "icompl" -mockRunAsm state (Iconst n) = assemble state $ log $ "iconst " ++ show n -mockRunAsm state Idiv = assemble state $ log "idiv" -mockRunAsm state (Ifeq label) = - assemble state $ log $ "ifeq " ++ label -mockRunAsm state (Ifge label) = - assemble state $ log $ "ifge " ++ label -mockRunAsm state (Ifgt label) = - assemble state $ log $ "ifgt " ++ label -mockRunAsm state (Ificmpeq label) = - assemble state $ log $ "ificmpeq " ++ label -mockRunAsm state (Ificmpge label) = - assemble state $ log $ "ificmpge " ++ label -mockRunAsm state (Ificmpgt label) = - assemble state $ log $ "ificmpgt " ++ label -mockRunAsm state (Ificmple label) = - assemble state $ log $ "ificmple " ++ label -mockRunAsm state (Ificmplt label) = - assemble state $ log $ "ificmplt " ++ label -mockRunAsm state (Ifacmpne label) = - assemble state $ log $ "ifacmpne " ++ label -mockRunAsm state (Ificmpne label) = - assemble state $ log $ "ificmpne " ++ label -mockRunAsm state (Ifle label) = - assemble state $ log $ "ifle " ++ label -mockRunAsm state (Iflt label) = - assemble state $ log $ "iflt " ++ label -mockRunAsm state (Ifne label) = - assemble state $ log $ "ifne " ++ label -mockRunAsm state (Ifnonnull label) = - assemble state $ log $ "ifnonnull " ++ label -mockRunAsm state (Ifnull label) = - assemble state $ log $ "ifnull " ++ label -mockRunAsm state (Iload n) = - assemble state $ log $ "iload " ++ show n -mockRunAsm state Imul = assemble state $ log "imul" -mockRunAsm state Ineg = assemble state $ log "ineg" -mockRunAsm state (InstanceOf className) = - assemble state $ log $ "instanceOf " ++ className -mockRunAsm state (InvokeMethod invocType cname mname desc isIntf) = assemble state $ do - log $ unwords [ - "invokeMethod", - show invocType, - cname, - mname, - desc, - show isIntf] - -mockRunAsm state (InvokeDynamic mname desc handle bsmArgs) = assemble state $ do - jbsmArgs <- sequence $ toJbsmArg <$> bsmArgs - jhandle <- toJHandle handle - log $ unwords [ - "invokeDynamic", - mname, - desc, - (objectToString $ the Object $ believe_me jhandle), - (objectToString $ the Object $ believe_me jbsmArgs)] - -mockRunAsm state Irem = assemble state $ log "irem" -mockRunAsm state Ireturn = assemble state $ log "ireturn" -mockRunAsm state Ishl = assemble state $ log "ishl" -mockRunAsm state Ishr = assemble state $ log "ishr" -mockRunAsm state (Istore n) = assemble state $ log $ "istore " ++ show n -mockRunAsm state Isub = assemble state $ log "isub" -mockRunAsm state Iushr = assemble state $ log "iushr" -mockRunAsm state L2d = assemble state $ log "l2d" -mockRunAsm state L2i = assemble state $ log "l2i" -mockRunAsm state (LabelStart label) = assemble state $ log (label ++ ":") -mockRunAsm state Ladd = assemble state $ log "ladd" -mockRunAsm state Laload = assemble state $ log "laload" -mockRunAsm state Land = assemble state $ log "land" -mockRunAsm state Lastore = assemble state $ log "lastore" -mockRunAsm state Lcmp = assemble state $ log "lcmp" -mockRunAsm state Lcompl = assemble state $ log "lcompl" - -mockRunAsm state (Ldc (TypeConst ty)) = - assemble state $ log $ "ldcType " ++ ty -mockRunAsm state (Ldc constant) = assemble state $ do - log ("ldc " ++ (objectToString (constantToObject constant))) - -mockRunAsm state Ldiv = assemble state $ log "ldiv" - -mockRunAsm state (LineNumber lineNumber label) = assemble state $ - log $ unwords [ - "lineNumber", - show lineNumber, - label] - -mockRunAsm state (Lload n) = assemble state $ - log $ "lload " ++ show n -mockRunAsm state Lmul = assemble state $ log "lmul" -mockRunAsm state Lneg = assemble state $ log "lneg" - -mockRunAsm state (LocalVariable name descriptor signature startLabel endLabel index) = assemble state $ - log $ unwords [ - "localVariable", - name, - descriptor, - (fromMaybe "null" signature), - startLabel, - endLabel, - show index] -mockRunAsm state (LookupSwitch defaultLabel labels cases) = assemble state $ do - let jcases = integerValueOf <$> cases - log $ unwords [ - "lookupSwitch", - defaultLabel, - (objectToString (the Object $ believe_me labels)), - (objectToString (the Object $ believe_me jcases))] - -mockRunAsm state Lor = assemble state $ log "lor" - -mockRunAsm state Lrem = assemble state $ log "lrem" -mockRunAsm state Lreturn = assemble state $ log "lreturn" -mockRunAsm state Lshl = assemble state $ log "lshl" -mockRunAsm state Lshr = assemble state $ log "lshr" -mockRunAsm state (Lstore n) = assemble state $ - log $ "lstore " ++ show n -mockRunAsm state Lsub = assemble state $ log "lsub" -mockRunAsm state Lushr = assemble state $ log "lushr" -mockRunAsm state Lxor = assemble state $ log "lxor" -mockRunAsm state (MaxStackAndLocal stack local) = assemble state $ - log $ "maxStackAndLocal " ++ show stack ++ " " ++ show local -mockRunAsm state MethodCodeStart = assemble state $ - log "methodCodeStart" -mockRunAsm state MethodCodeEnd = assemble state $ do - log "methodCodeEnd" - log $ "**********************************" -mockRunAsm state (Multianewarray desc dims) = assemble state $ - log $ unwords ["multiANewArray", desc, show dims] -mockRunAsm state (New cname) = assemble state $ - log $ "asmNew " ++ cname -mockRunAsm state Pop = assemble state $ log "pop" -mockRunAsm state Pop2 = assemble state $ log "pop2" -mockRunAsm state Return = assemble state $ log "voidReturn" -mockRunAsm state Saload = assemble state $ log "saload" -mockRunAsm state Sastore = assemble state $ log "sastore" -mockRunAsm state (SourceInfo sourceFileName) - = assemble state $ log $ "sourceInfo " ++ sourceFileName -mockRunAsm state (LiftIo action) = assemble state action - -mockRunAsm state (Throw fc message) = pure (believe_me $ crash $ show fc ++ ": " ++ message, state) -mockRunAsm state GetState = pure (state, state) -mockRunAsm state (SetState newState) = pure ((), newState) - -mockRunAsm st (Pure value) = pure (value, st) -mockRunAsm st (Bind action f) = do - (result, nextSt) <- mockRunAsm st action - mockRunAsm nextSt $ f result diff --git a/src/Compiler/Jvm/Optimizer.idr b/src/Compiler/Jvm/Optimizer.idr index b43e3ea3f..9f7f5a0c4 100644 --- a/src/Compiler/Jvm/Optimizer.idr +++ b/src/Compiler/Jvm/Optimizer.idr @@ -8,6 +8,8 @@ import Compiler.TailRec import Control.Monad.Reader import Control.Monad.State +import Compiler.Common +import Core.CompileExpr import Core.Context import Core.Name import Core.Reflect @@ -27,7 +29,6 @@ import Compiler.Jvm.ExtPrim import Compiler.Jvm.Foreign import Compiler.Jvm.InferredType import Compiler.Jvm.Jname -import Compiler.Jvm.MockAsm import Compiler.Jvm.ShowUtil %hide Core.Name.Scoped.Scope @@ -47,10 +48,10 @@ namespace InferredPrimType getInferredType _ = IInt export -getFArgs : NamedCExp -> Asm (List (NamedCExp, NamedCExp)) +getFArgs : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core (List (NamedCExp, NamedCExp)) getFArgs (NmCon fc _ _ (Just 0) _) = pure [] getFArgs (NmCon fc _ _ (Just 1) [ty, val, rest]) = pure $ (ty, val) :: !(getFArgs rest) -getFArgs arg = Throw (getFC arg) ("Badly formed jvm call argument list " ++ show arg) +getFArgs arg = throw (GenericMsg (getFC arg) ("Badly formed jvm call argument list " ++ show arg)) getLineNumbers : FilePos -> FilePos -> (Int, Int) getLineNumbers (lineStart, _) (lineEnd, colEnd) = @@ -356,18 +357,18 @@ mutual markTailRecursionConstAlt : NamedConstAlt -> Reader (Jname, String) NamedConstAlt markTailRecursionConstAlt (MkNConstAlt constant caseBody) = MkNConstAlt constant <$> markTailRecursion caseBody -exitInferenceScope : Int -> Asm () +exitInferenceScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () exitInferenceScope scopeIndex = updateCurrentScopeIndex scopeIndex -enterInferenceScope : Int -> Int -> Asm () +enterInferenceScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Int -> Core () enterInferenceScope lineNumberStart lineNumberEnd = do parentScopeIndex <- getCurrentScopeIndex scopeIndex <- newScopeIndex parentScope <- getScope parentScopeIndex - variableTypes <- LiftIo $ Map.newTreeMap {key=String} {value=InferredType} - allVariableTypes <- LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} - variableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} - allVariableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} + variableTypes <- coreLift $ Map.newTreeMap {key=String} {value=InferredType} + allVariableTypes <- coreLift $ Map.newTreeMap {key=Int} {value=InferredType} + variableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} + allVariableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} let newScope = MkScope scopeIndex (Just parentScopeIndex) variableTypes allVariableTypes variableIndices allVariableIndices IUnknown (nextVariableIndex parentScope) (lineNumberStart, lineNumberEnd) ("", "") [] @@ -375,13 +376,13 @@ enterInferenceScope lineNumberStart lineNumberEnd = do saveScope newScope updateCurrentScopeIndex scopeIndex -createLambdaClosureScope : Int -> Int -> List String -> Scope -> Asm Scope +createLambdaClosureScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Int -> List String -> Scope -> Core Scope createLambdaClosureScope scopeIndex childScopeIndex closureVariables parentScope = do - lambdaClosureVariableIndices <- LiftIo $ Map.fromList $ getLambdaClosureVariableIndices [] 0 closureVariables - variableTypes <- LiftIo $ Map.newTreeMap {key=String} {value=InferredType} - allVariableTypes <- LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} - allVariableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} - Pure $ MkScope scopeIndex (Just $ index parentScope) variableTypes allVariableTypes + lambdaClosureVariableIndices <- coreLift $ Map.fromList $ getLambdaClosureVariableIndices [] 0 closureVariables + variableTypes <- coreLift $ Map.newTreeMap {key=String} {value=InferredType} + allVariableTypes <- coreLift $ Map.newTreeMap {key=Int} {value=InferredType} + allVariableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} + pure $ MkScope scopeIndex (Just $ index parentScope) variableTypes allVariableTypes lambdaClosureVariableIndices allVariableIndices IUnknown (cast $ length closureVariables) (lineNumbers parentScope) ("", "") [childScopeIndex] where @@ -390,17 +391,17 @@ createLambdaClosureScope scopeIndex childScopeIndex closureVariables parentScope getLambdaClosureVariableIndices acc index (var :: vars) = getLambdaClosureVariableIndices ((var, index) :: acc) (index + 1) vars -enterInferenceLambdaScope : Int -> Int -> Maybe Name -> NamedCExp -> Asm () +enterInferenceLambdaScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Int -> Maybe Name -> NamedCExp -> Core () enterInferenceLambdaScope lineNumberStart lineNumberEnd parameterName expr = do parentScopeIndex <- getCurrentScopeIndex scopeIndex <- newScopeIndex let boundVariables = maybe SortedSet.empty (flip SortedSet.insert SortedSet.empty . jvmSimpleName) parameterName let freeVariables = getFreeVariables boundVariables expr let usedVariables = filter (flip SortedSet.contains freeVariables) !(retrieveVariables parentScopeIndex) - variableTypes <- LiftIo $ Map.newTreeMap {key=String} {value=InferredType} - allVariableTypes <- LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} - variableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} - allVariableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} + variableTypes <- coreLift $ Map.newTreeMap {key=String} {value=InferredType} + allVariableTypes <- coreLift $ Map.newTreeMap {key=Int} {value=InferredType} + variableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} + allVariableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} newScope <- case usedVariables of nonEmptyUsedVariables@(_ :: _) => do parentScope <- getScope parentScopeIndex @@ -409,29 +410,30 @@ enterInferenceLambdaScope lineNumberStart lineNumberEnd parameterName expr = do parentScope saveScope closureScope let closureVariableCount = nextVariableIndex closureScope - Pure $ MkScope scopeIndex (Just lambdaParentScopeIndex) variableTypes allVariableTypes + pure $ MkScope scopeIndex (Just lambdaParentScopeIndex) variableTypes allVariableTypes variableIndices allVariableIndices IUnknown closureVariableCount (lineNumberStart, lineNumberEnd) ("", "") [] - [] => Pure $ MkScope scopeIndex Nothing variableTypes allVariableTypes variableIndices allVariableIndices + [] => pure $ MkScope scopeIndex Nothing variableTypes allVariableTypes variableIndices allVariableIndices IUnknown 0 (lineNumberStart, lineNumberEnd) ("", "") [] saveScope newScope updateCurrentScopeIndex scopeIndex -withInferenceScope : Int -> Int -> Asm result -> Asm result +withInferenceScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Int -> Core result -> Core result withInferenceScope lineNumberStart lineNumberEnd op = do scopeIndex <- getCurrentScopeIndex enterInferenceScope lineNumberStart lineNumberEnd result <- op exitInferenceScope scopeIndex - Pure result + pure result -withInferenceLambdaScope : Int -> Int -> Maybe Name -> NamedCExp -> Asm result -> Asm result +withInferenceLambdaScope : {auto stateRef: Ref AsmState AsmState} -> Int -> Int -> Maybe Name -> NamedCExp + -> Core result -> Core result withInferenceLambdaScope lineNumberStart lineNumberEnd parameterName expr op = do scopeIndex <- getCurrentScopeIndex enterInferenceLambdaScope lineNumberStart lineNumberEnd parameterName expr result <- op exitInferenceScope scopeIndex - Pure result + pure result public export data LambdaType = DelayedLambda | FunctionLambda | Function2Lambda | Function3Lambda | Function4Lambda | @@ -480,36 +482,36 @@ getLambdaImplementationMethodReturnType : LambdaType -> InferredType getLambdaImplementationMethodReturnType _ = inferredObjectType export -getConstantType : List NamedConstAlt -> Asm InferredType -getConstantType [] = Throw emptyFC "Unknown constant switch type" +getConstantType : {auto stateRef: Ref AsmState AsmState} -> List NamedConstAlt -> Core InferredType +getConstantType [] = throw $ GenericMsg emptyFC "Unknown constant switch type" getConstantType ((MkNConstAlt constant _) :: _) = case constant of - I _ => Pure IInt - I8 _ => Pure IInt - I16 _ => Pure IInt - I32 _ => Pure IInt - I64 _ => Pure ILong - B8 _ => Pure IInt - B16 _ => Pure IInt - B32 _ => Pure IInt - B64 _ => Pure ILong - Ch _ => Pure IInt - Str _ => Pure inferredStringType - BI _ => Pure inferredBigIntegerType - unsupportedConstant => Throw emptyFC $ "Unsupported constant switch " ++ show unsupportedConstant + I _ => pure IInt + I8 _ => pure IInt + I16 _ => pure IInt + I32 _ => pure IInt + I64 _ => pure ILong + B8 _ => pure IInt + B16 _ => pure IInt + B32 _ => pure IInt + B64 _ => pure ILong + Ch _ => pure IInt + Str _ => pure inferredStringType + BI _ => pure inferredBigIntegerType + unsupportedConstant => throw $ GenericMsg emptyFC ("Unsupported constant switch " ++ show unsupportedConstant) export -getIntConstantValue : FC -> Primitive.Constant -> Asm Int -getIntConstantValue _ (I i) = Pure i -getIntConstantValue _ (I8 i) = Pure (cast i) -getIntConstantValue _ (I16 i) = Pure (cast i) -getIntConstantValue _ (I32 i) = Pure (cast i) -getIntConstantValue _ (B8 i) = Pure (cast i) -getIntConstantValue _ (B16 i) = Pure (cast i) -getIntConstantValue _ (B32 i) = Pure (cast i) -getIntConstantValue _ (Ch c) = Pure $ ord c -getIntConstantValue _ WorldVal = Pure 0 -getIntConstantValue _ (PrT _) = Pure 0 -getIntConstantValue fc x = Throw fc ("Constant " ++ show x ++ " cannot be converted to integer.") +getIntConstantValue : {auto stateRef: Ref AsmState AsmState} -> FC -> Primitive.Constant -> Core Int +getIntConstantValue _ (I i) = pure i +getIntConstantValue _ (I8 i) = pure (cast i) +getIntConstantValue _ (I16 i) = pure (cast i) +getIntConstantValue _ (I32 i) = pure (cast i) +getIntConstantValue _ (B8 i) = pure (cast i) +getIntConstantValue _ (B16 i) = pure (cast i) +getIntConstantValue _ (B32 i) = pure (cast i) +getIntConstantValue _ (Ch c) = pure $ ord c +getIntConstantValue _ WorldVal = pure 0 +getIntConstantValue _ (PrT _) = pure 0 +getIntConstantValue fc x = throw $ GenericMsg fc ("Constant " ++ show x ++ " cannot be converted to integer.") getConstructorTag : ConInfo -> Maybe Int -> Int getConstructorTag conInfo tag = case conInfo of @@ -543,7 +545,7 @@ combineSwitchTypes defaultTy altTypes@(altTy :: rest) = maybe (go altTy rest) (f go prevTy [] = prevTy go prevTy (currTy :: rest) = if prevTy == currTy then go currTy rest else inferredObjectType -createNewVariable : (variablePrefix: String) -> InferredType -> Asm () +createNewVariable : {auto stateRef: Ref AsmState AsmState} -> (variablePrefix: String) -> InferredType -> Core () createNewVariable variablePrefix ty = do variable <- generateVariable variablePrefix ignore $ addVariableType variable ty @@ -560,39 +562,39 @@ voidTypeExpr : NamedCExp voidTypeExpr = NmCon emptyFC (UN (Basic "void")) TYCON Nothing [] export -getJavaLambdaType : FC -> List NamedCExp -> Asm JavaLambdaType +getJavaLambdaType : {auto stateRef: Ref AsmState AsmState} -> FC -> List NamedCExp -> Core JavaLambdaType getJavaLambdaType fc [functionType, javaInterfaceType, _] = do implementationType <- parseFunctionType functionType (interfaceTy, methodName, methodType) <- parseJavaInterfaceType javaInterfaceType - Pure $ MkJavaLambdaType interfaceTy methodName methodType implementationType + pure $ MkJavaLambdaType interfaceTy methodName methodType implementationType where - parseFunctionType: NamedCExp -> Asm InferredFunctionType + parseFunctionType : NamedCExp -> Core InferredFunctionType parseFunctionType functionType = do types <- go [] functionType case types of [] => asmCrash ("Invalid Java lambda at " ++ show fc ++ ": " ++ show functionType) - (returnType :: argTypes) => Pure $ MkInferredFunctionType returnType (reverse argTypes) + (returnType :: argTypes) => pure $ MkInferredFunctionType returnType (reverse argTypes) where - go : List InferredType -> NamedCExp -> Asm (List InferredType) + go : List InferredType -> NamedCExp -> Core (List InferredType) go acc (NmCon _ (UN (Basic "->")) _ _ [argTy, lambdaTy]) = do argInferredTy <- tySpec argTy restInferredTypes <- go acc lambdaTy - Pure (restInferredTypes ++ (argInferredTy :: acc)) + pure (restInferredTypes ++ (argInferredTy :: acc)) go acc (NmLam fc arg expr) = go acc expr go acc expr@(NmApp _ (NmRef _ name) [arg]) = go (IInt :: acc) (if name == primio "PrimIO" then arg else expr) - go acc expr = Pure (!(tySpec expr) :: acc) + go acc expr = pure (!(tySpec expr) :: acc) - throwExpectedStructAtPos : Asm a + throwExpectedStructAtPos : Core a throwExpectedStructAtPos = asmCrash ("Expected a struct containing interface name and method separated by space at " ++ show fc) - throwExpectedStruct : String -> Asm a + throwExpectedStruct : String -> Core a throwExpectedStruct name = asmCrash ("Expected a struct containing interface name and method separated by space at " ++ show fc ++ " but found " ++ name) - parseJavaInterfaceType : NamedCExp -> Asm (InferredType, String, InferredFunctionType) + parseJavaInterfaceType : NamedCExp -> Core (InferredType, String, InferredFunctionType) parseJavaInterfaceType expr@(NmCon _ name _ _ [interfaceType, methodTypeExp]) = if name == builtin "Pair" then case interfaceType of @@ -601,7 +603,7 @@ getJavaLambdaType fc [functionType, javaInterfaceType, _] = then case words namePartsStr of (interfaceName :: methodName :: _) => do methodType <- parseFunctionType methodTypeExp - Pure (IRef interfaceName Interface [], methodName, methodType) + pure (IRef interfaceName Interface [], methodName, methodType) _ => asmCrash ("Expected interface name and method separated by space at " ++ show fc ++ ": " ++ namePartsStr) else throwExpectedStruct namePartsStr @@ -618,7 +620,7 @@ getJavaLambdaType fc [functionType, javaInterfaceType, _] = getJavaLambdaType fc exprs = asmCrash ("Invalid Java lambda at " ++ show fc ++ ": " ++ show exprs) mutual - inferExpr : InferredType -> NamedCExp -> Asm InferredType + inferExpr : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> Core InferredType inferExpr exprTy (NmDelay _ _ expr) = inferExprLam AppliedLambdaUnknown Nothing Nothing expr inferExpr exprTy expr@(NmLocal _ var) = addVariableType (jvmSimpleName var) exprTy inferExpr exprTy (NmRef _ name) = pure exprTy @@ -634,9 +636,9 @@ mutual inferExpr exprTy (NmExtPrim fc fn args) = inferExtPrim fc exprTy (toPrim fn) args inferExpr exprTy (NmForce _ _ expr) = do ignore $ inferExpr delayedType expr - Pure inferredObjectType + pure inferredObjectType - inferExpr exprTy (NmConCase _ sc [] Nothing) = Pure IUnknown + inferExpr exprTy (NmConCase _ sc [] Nothing) = pure IUnknown inferExpr exprTy (NmConCase _ sc [] (Just def)) = do inferConstructorSwitchExpr sc inferExpr exprTy def @@ -651,10 +653,10 @@ mutual createNewVariable "hashCodePosition" IInt let sortedAlts = if hasTypeCase then alts else sortConCases alts altTypes <- traverse (inferExprConAlt exprTy) sortedAlts - defaultTy <- traverse (inferExprWithNewScope exprTy) def - Pure $ combineSwitchTypes defaultTy altTypes + defaultTy <- traverseOpt (inferExprWithNewScope exprTy) def + pure $ combineSwitchTypes defaultTy altTypes - inferExpr exprTy (NmConstCase fc sc [] Nothing) = Pure IUnknown + inferExpr exprTy (NmConstCase fc sc [] Nothing) = pure IUnknown inferExpr exprTy (NmConstCase fc sc [] (Just expr)) = inferExpr exprTy expr inferExpr exprTy (NmConstCase fc sc alts def) = do constantType <- getConstantType alts @@ -666,17 +668,17 @@ mutual ignore $ addVariableType hashCodePositionVariable IInt sortedAlts <- sortConstCases constantType alts altTypes <- traverse (inferExprConstAlt exprTy) sortedAlts - defaultTy <- traverse (inferExprWithNewScope exprTy) def - Pure $ combineSwitchTypes defaultTy altTypes + defaultTy <- traverseOpt (inferExprWithNewScope exprTy) def + pure $ combineSwitchTypes defaultTy altTypes where getConstant : NamedConstAlt -> Primitive.Constant getConstant (MkNConstAlt constant _) = constant - sortConstCases : InferredType -> List NamedConstAlt -> Asm (List NamedConstAlt) + sortConstCases : InferredType -> List NamedConstAlt -> Core (List NamedConstAlt) sortConstCases IInt alts = do constValues <- traverse (getIntConstantValue fc . getConstant) alts - Pure $ fst <$> (sortBy (comparing snd) $ zip alts constValues) - sortConstCases _ alts = Pure alts + pure $ fst <$> (sortBy (comparing snd) $ zip alts constValues) + sortConstCases _ alts = pure alts inferExpr _ (NmPrimVal fc (I _)) = pure IInt inferExpr _ (NmPrimVal fc (I8 _)) = pure IInt @@ -695,7 +697,7 @@ mutual inferExpr exprTy (NmErased fc) = pure exprTy inferExpr exprTy (NmCrash fc msg) = pure exprTy - inferConstructorSwitchExpr : NamedCExp -> Asm () + inferConstructorSwitchExpr : {auto stateRef: Ref AsmState AsmState} -> NamedCExp -> Core () inferConstructorSwitchExpr (NmLocal _ var) = do let idrisObjectVariable = jvmSimpleName var ignore $ addVariableType idrisObjectVariable idrisObjectType @@ -704,55 +706,55 @@ mutual ignore $ inferExpr idrisObjectType sc ignore $ addVariableType idrisObjectVariable idrisObjectType - inferExprConstAlt : InferredType -> NamedConstAlt -> Asm InferredType + inferExprConstAlt : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedConstAlt -> Core InferredType inferExprConstAlt returnType (MkNConstAlt _ expr) = inferExprWithNewScope returnType expr - inferExprWithNewScope : InferredType -> NamedCExp -> Asm InferredType + inferExprWithNewScope : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> Core InferredType inferExprWithNewScope returnType expr = do let fc = getFC expr let (lineStart, lineEnd) = getLineNumbers (startPos (toNonEmptyFC fc)) (endPos (toNonEmptyFC fc)) withInferenceScope lineStart lineEnd $ inferExpr returnType expr - inferConCaseExpr : InferredType -> List Name -> NamedCExp -> Asm InferredType + inferConCaseExpr : {auto stateRef: Ref AsmState AsmState} -> InferredType -> List Name -> NamedCExp -> Core InferredType inferConCaseExpr exprTy args expr = do traverse_ inferArg args inferExpr exprTy expr where - inferArg : Name -> Asm () + inferArg : Name -> Core () inferArg var = let variableName = jvmSimpleName var in when (used variableName expr) $ createVariable variableName - inferExprConAlt : InferredType -> NamedConAlt -> Asm InferredType + inferExprConAlt : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedConAlt -> Core InferredType inferExprConAlt exprTy (MkNConAlt _ _ _ args expr) = do - let fc = getFC expr - let (lineStart, lineEnd) = getLineNumbers (startPos (toNonEmptyFC fc)) (endPos (toNonEmptyFC fc)) - withInferenceScope lineStart lineEnd $ inferConCaseExpr exprTy args expr + let fc = getFC expr + let (lineStart, lineEnd) = getLineNumbers (startPos (toNonEmptyFC fc)) (endPos (toNonEmptyFC fc)) + withInferenceScope lineStart lineEnd $ inferConCaseExpr exprTy args expr - inferParameter : (NamedCExp, InferredType) -> Asm InferredType + inferParameter : {auto stateRef: Ref AsmState AsmState} -> (NamedCExp, InferredType) -> Core InferredType inferParameter (param, ty) = inferExpr ty param - inferBinaryOp : InferredType -> NamedCExp -> NamedCExp -> Asm InferredType + inferBinaryOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> NamedCExp -> Core InferredType inferBinaryOp ty x y = do ignore $ inferExpr ty x ignore $ inferExpr ty y pure ty - inferBoolOp : InferredType -> NamedCExp -> NamedCExp -> Asm InferredType + inferBoolOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> NamedCExp -> Core InferredType inferBoolOp ty x y = do ignore $ inferExpr ty x ignore $ inferExpr ty y pure IBool - inferUnaryOp : InferredType -> NamedCExp -> Asm InferredType + inferUnaryOp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> Core InferredType inferUnaryOp ty x = do ignore $ inferExpr ty x - Pure ty + pure ty - inferExtPrimArg : (NamedCExp, InferredType) -> Asm InferredType + inferExtPrimArg : {auto stateRef: Ref AsmState AsmState} -> (NamedCExp, InferredType) -> Core InferredType inferExtPrimArg (arg, ty) = inferExpr ty arg - inferExtPrim : FC -> InferredType -> ExtPrim -> List NamedCExp -> Asm InferredType + inferExtPrim : {auto stateRef: Ref AsmState AsmState} -> FC -> InferredType -> ExtPrim -> List NamedCExp -> Core InferredType inferExtPrim fc returnType GetStaticField descriptors = inferExtPrim fc returnType JvmStaticMethodCall descriptors inferExtPrim fc returnType SetStaticField descriptors = inferExtPrim fc returnType JvmStaticMethodCall descriptors inferExtPrim fc returnType GetInstanceField descriptors = inferExtPrim fc returnType JvmStaticMethodCall descriptors @@ -829,54 +831,55 @@ mutual ignore $ inferExpr delayedType action pure inferredForkJoinTaskType inferExtPrim _ returnType (Unknown name) _ = asmCrash $ "Can't compile unknown external directive " ++ show name - inferExtPrim fc _ prim args = Throw fc $ "Unsupported external function " ++ show prim ++ "(" ++ + inferExtPrim fc _ prim args = throw $ GenericMsg fc $ "Unsupported external function " ++ show prim ++ "(" ++ (show $ showNamedCExp 0 <$> args) ++ ")" - inferExprLamWithParameterType : Maybe (Name, InferredType) -> (parameterValueExpr: Maybe (Asm ())) -> - NamedCExp -> Asm InferredType + inferExprLamWithParameterType : {auto stateRef: Ref AsmState AsmState} -> Maybe (Name, InferredType) + -> (parameterValueExpr: Maybe (Core ())) -> NamedCExp -> Core InferredType inferExprLamWithParameterType parameterNameAndType parameterValueExpr expr = do let hasParameterValue = isJust parameterValueExpr let (_, lineStart, lineEnd) = getSourceLocation expr let jvmParameterNameAndType = (\(name, ty) => (jvmSimpleName name, ty)) <$> parameterNameAndType let lambdaType = getLambdaTypeByParameter (fst <$> parameterNameAndType) lambdaBodyReturnType <- withInferenceLambdaScope lineStart lineEnd (fst <$> parameterNameAndType) expr $ do - traverse_ createAndAddVariable jvmParameterNameAndType - maybe (Pure ()) id parameterValueExpr + ignore $ traverseOpt createAndAddVariable jvmParameterNameAndType + maybe (pure ()) id parameterValueExpr lambdaBodyReturnType <- inferExpr IUnknown expr currentScope <- getScope !getCurrentScopeIndex saveScope $ { returnType := lambdaBodyReturnType } currentScope - Pure lambdaBodyReturnType - Pure $ if hasParameterValue + pure lambdaBodyReturnType + pure $ if hasParameterValue then lambdaBodyReturnType else getLambdaInterfaceType lambdaType where - createAndAddVariable : (String, InferredType) -> Asm () + createAndAddVariable : (String, InferredType) -> Core () createAndAddVariable (name, ty) = do createVariable name ignore $ addVariableType name ty - inferExprLamWithParameterType1 : (isCached : Bool) -> Maybe Name -> NamedCExp -> Asm InferredType - inferExprLamWithParameterType1 True _ _ = Pure inferredLambdaType + inferExprLamWithParameterType1 : {auto stateRef: Ref AsmState AsmState} -> (isCached : Bool) -> Maybe Name + -> NamedCExp -> Core InferredType + inferExprLamWithParameterType1 True _ _ = pure inferredLambdaType inferExprLamWithParameterType1 False parameterName expr = inferExprLamWithParameterType ((\name => (name, inferredObjectType)) <$> parameterName) Nothing expr - inferExprLam : AppliedLambdaType -> (parameterValue: Maybe NamedCExp) -> (parameterName : Maybe Name) -> - NamedCExp -> Asm InferredType + inferExprLam : {auto stateRef: Ref AsmState AsmState} -> AppliedLambdaType -> (parameterValue: Maybe NamedCExp) + -> (parameterName : Maybe Name) -> NamedCExp -> Core InferredType inferExprLam appliedLambdaType parameterValue@(Just value) (Just parameterName) lambdaBody = do valueType <- if appliedLambdaType == AppliedLambdaSwitch then case lambdaBody of (NmConstCase _ _ alts _) => getConstantType alts - (NmConCase _ _ _ _) => Pure idrisObjectType - _ => Pure IUnknown + (NmConCase _ _ _ _) => pure idrisObjectType + _ => pure IUnknown else if appliedLambdaType == AppliedLambdaLet - then Pure inferredObjectType - else Pure IUnknown + then pure inferredObjectType + else pure IUnknown let shouldGenerateVariable = parameterName == extractedMethodArgumentName generatedJvmVariableName <- if shouldGenerateVariable - then Pure $ jvmSimpleName parameterName ++ show !newDynamicVariableIndex - else Pure $ jvmSimpleName parameterName + then pure $ jvmSimpleName parameterName ++ show !newDynamicVariableIndex + else pure $ jvmSimpleName parameterName let generatedVariableName = if shouldGenerateVariable then UN $ Basic generatedJvmVariableName @@ -889,7 +892,7 @@ mutual then substituteVariableSubMethodBody valueExpr lambdaBody else lambdaBody) where - inferValue : Scope -> Bool -> String -> InferredType -> Asm () + inferValue : Scope -> Bool -> String -> InferredType -> Core () inferValue enclosingScope shouldGenerateVariable variableName valueType = do lambdaScopeIndex <- getCurrentScopeIndex updateCurrentScopeIndex (index enclosingScope) @@ -920,7 +923,7 @@ mutual inferExprLamWithParameterType1 (maybe False ((==) b) p0) p0 expr inferExprLam _ _ p0 expr = inferExprLamWithParameterType1 False p0 expr - inferExprLet : FC -> InferredType -> (x : Name) -> NamedCExp -> NamedCExp -> Asm InferredType + inferExprLet : {auto stateRef: Ref AsmState AsmState} -> FC -> InferredType -> (x : Name) -> NamedCExp -> NamedCExp -> Core InferredType inferExprLet fc exprTy var value expr = do let (lineStart, lineEnd) = getLineNumbers (startPos (toNonEmptyFC fc)) (endPos (toNonEmptyFC fc)) let varName = jvmSimpleName var @@ -931,15 +934,15 @@ mutual let (_, lineStart, lineEnd) = getSourceLocation expr withInferenceScope lineStart lineEnd $ inferExpr exprTy expr - inferSelfTailCallParameter : Map Int InferredType -> Map Int String -> (NamedCExp, Int) -> Asm () + inferSelfTailCallParameter : {auto stateRef: Ref AsmState AsmState} -> Map Int InferredType -> Map Int String -> (NamedCExp, Int) -> Core () inferSelfTailCallParameter types argumentNameByIndices (arg, index) = do - optTy <- LiftIo $ Map.get types index + optTy <- coreLift $ Map.get types index let variableType = fromMaybe IUnknown $ nullableToMaybe optTy ty <- inferExpr variableType arg - optName <- LiftIo $ Map.get {value=String} argumentNameByIndices index - maybe (Pure ()) (doAddVariableType ty) $ nullableToMaybe optName + optName <- coreLift $ Map.get {value=String} argumentNameByIndices index + maybe (pure ()) (doAddVariableType ty) $ nullableToMaybe optName where - doAddVariableType : InferredType -> String -> Asm () + doAddVariableType : InferredType -> String -> Core () doAddVariableType ty name = do ignore $ addVariableType name ty case arg of @@ -949,43 +952,43 @@ mutual when (index /= valueVariableIndex) $ createNewVariable "tailRecArg" ty _ => createNewVariable "tailRecArg" ty - inferExprApp : InferredType -> NamedCExp -> Asm InferredType + inferExprApp : {auto stateRef: Ref AsmState AsmState} -> InferredType -> NamedCExp -> Core InferredType inferExprApp exprTy app@(NmApp _ (NmRef _ (UN (Basic "$idrisTailRec"))) args) = case args of - [] => Pure exprTy + [] => pure exprTy args@(_ :: argsTail) => do types <- retrieveVariableTypesAtScope !getCurrentScopeIndex - argumentNameByIndices <- LiftIo $ Map.transpose $ variableIndices !(getScope 0) + argumentNameByIndices <- coreLift $ Map.transpose $ variableIndices !(getScope 0) traverse_ (inferSelfTailCallParameter types argumentNameByIndices) $ zip args [0 .. the Int $ cast $ length argsTail] - Pure exprTy + pure exprTy inferExprApp exprTy (NmApp _ (NmRef _ idrisName) args) = do let functionName = jvmName idrisName functionType <- case !(findFunctionType functionName) of - Just ty => Pure ty - Nothing => Pure $ MkInferredFunctionType inferredObjectType $ replicate (length args) inferredObjectType + Just ty => pure ty + Nothing => pure $ MkInferredFunctionType inferredObjectType $ replicate (length args) inferredObjectType let argsWithTypes = zip args (parameterTypes functionType) traverse_ inferParameter argsWithTypes - Pure $ returnType functionType + pure $ returnType functionType inferExprApp exprTy (NmApp _ lambdaVariable args) = do ignore $ inferExpr inferredLambdaType lambdaVariable let argsWithTypes = zip args (replicate (length args) IUnknown) traverse_ inferParameter argsWithTypes pure IUnknown - inferExprApp _ _ = Throw emptyFC "Not a function application" + inferExprApp _ _ = throw $ GenericMsg emptyFC "Not a function application" - inferExprCon : InferredType -> String -> Name -> List NamedCExp -> Asm InferredType + inferExprCon : {auto stateRef: Ref AsmState AsmState} -> InferredType -> String -> Name -> List NamedCExp -> Core InferredType inferExprCon exprTy fileName name args = do let argsWithTypes = zip args (replicate (length args) inferredObjectType) traverse_ inferParameter argsWithTypes pure idrisObjectType - inferExprCast : InferredType -> InferredType -> NamedCExp -> Asm InferredType + inferExprCast : {auto stateRef: Ref AsmState AsmState} -> InferredType -> InferredType -> NamedCExp -> Core InferredType inferExprCast sourceType targetType expr = do ignore $ inferExpr sourceType expr pure targetType - inferExprOp : PrimFn arity -> Vect arity NamedCExp -> Asm InferredType + inferExprOp : {auto stateRef: Ref AsmState AsmState} -> PrimFn arity -> Vect arity NamedCExp -> Core InferredType inferExprOp (Add ty) [x, y] = inferBinaryOp (getInferredType ty) x y inferExprOp (Sub ty) [x, y] = inferBinaryOp (getInferredType ty) x y inferExprOp (Mul ty) [x, y] = inferBinaryOp (getInferredType ty) x y @@ -1048,18 +1051,18 @@ mutual ignore $ inferExpr IUnknown a ignore $ inferExpr IUnknown b ignore $ inferExpr IUnknown x - Pure IUnknown + pure IUnknown inferExprOp Crash [_, msg] = do ignore $ inferExpr inferredStringType msg - Pure IUnknown - inferExprOp op _ = Throw emptyFC ("Unsupported primitive function " ++ show op) + pure IUnknown + inferExprOp op _ = throw $ GenericMsg emptyFC ("Unsupported primitive function " ++ show op) export %inline emptyFunction : NamedCExp emptyFunction = NmCrash emptyFC "uninitialized function" -showScopes : Int -> Asm () +showScopes : {auto stateRef: Ref AsmState AsmState} -> Int -> Core () showScopes n = do scope <- getScope n logAsm $ show scope @@ -1103,28 +1106,28 @@ optimize programName allDefs = in toNameFcDef <$> tailCallOptimizedDefs export -inferDef : String -> Name -> FC -> NamedDef -> Asm () +inferDef : {auto stateRef: Ref AsmState AsmState} -> String -> Name -> FC -> NamedDef -> Core () inferDef programName idrisName fc (MkNmFun args expr) = do let jname = jvmName idrisName let jvmClassAndMethodName = getIdrisFunctionName programName (className jname) (methodName jname) let argumentNames = jvmSimpleName <$> args let arity = length args let arityInt = the Int $ cast arity - argIndices <- LiftIo $ getArgumentIndices arityInt argumentNames + argIndices <- coreLift $ getArgumentIndices arityInt argumentNames let initialArgumentTypes = replicate arity inferredObjectType let inferredFunctionType = MkInferredFunctionType inferredObjectType initialArgumentTypes - argumentTypesByName <- LiftIo $ Map.fromList $ zip argumentNames initialArgumentTypes - scopes <- LiftIo $ ArrayList.new {elemTy=Scope} + argumentTypesByName <- coreLift $ Map.fromList $ zip argumentNames initialArgumentTypes + scopes <- coreLift $ ArrayList.new {elemTy=Scope} let function = MkFunction jname inferredFunctionType (subtyping scopes) 0 jvmClassAndMethodName emptyFunction setCurrentFunction function - LiftIo $ AsmGlobalState.addFunction !getGlobalState jname function + coreLift $ AsmGlobalState.addFunction !getGlobalState jname function updateCurrentFunction $ { optimizedBody := expr } resetScope scopeIndex <- newScopeIndex let (_, lineStart, lineEnd) = getSourceLocation expr - allVariableTypes <- LiftIo $ Map.newTreeMap {key=Int} {value=InferredType} - allVariableIndices <- LiftIo $ Map.newTreeMap {key=String} {value=Int} + allVariableTypes <- coreLift $ Map.newTreeMap {key=Int} {value=InferredType} + allVariableIndices <- coreLift $ Map.newTreeMap {key=String} {value=Int} let functionScope = MkScope scopeIndex Nothing argumentTypesByName allVariableTypes argIndices allVariableIndices IUnknown arityInt (lineStart, lineEnd) ("", "") [] @@ -1133,13 +1136,13 @@ inferDef programName idrisName fc (MkNmFun args expr) = do retTy <- inferExpr IUnknown expr updateScopeVariableTypes arity updateCurrentFunction $ { inferredFunctionType := inferredFunctionType } - when (shouldDebugFunction jname) $ showScopes (scopeCounter !GetState - 1) + when (shouldDebugFunction jname) $ showScopes (scopeCounter !getState - 1) where - getArgumentTypes : List String -> Asm (List InferredType) + getArgumentTypes : List String -> Core (List InferredType) getArgumentTypes argumentNames = do argumentIndicesByName <- getVariableIndicesByName 0 argumentTypesByIndex <- getVariableTypesAtScope 0 - LiftIo $ go argumentIndicesByName argumentTypesByIndex argumentNames + coreLift $ go argumentIndicesByName argumentTypesByIndex argumentNames where go : Map String Int -> Map Int InferredType -> List String -> IO (List InferredType) go argumentIndicesByName argumentTypesByIndex argumentNames = do @@ -1162,8 +1165,4 @@ inferDef programName n fc (MkNmError expr) = inferDef programName n fc (MkNmFun inferDef programName idrisName fc def@(MkNmForeign foreignDescriptors argumentTypes returnType) = inferForeign programName idrisName fc foreignDescriptors argumentTypes returnType -inferDef _ _ _ _ = Pure () - -export -asm : AsmState -> Asm a -> IO (a, AsmState) -asm = if shouldDebugAsm then mockRunAsm else runAsm +inferDef _ _ _ _ = pure () diff --git a/src/Compiler/Jvm/Variable.idr b/src/Compiler/Jvm/Variable.idr index 2a0bfb506..77d52762e 100644 --- a/src/Compiler/Jvm/Variable.idr +++ b/src/Compiler/Jvm/Variable.idr @@ -1,5 +1,6 @@ module Compiler.Jvm.Variable +import Core.Context import Core.Core import Core.FC @@ -26,126 +27,121 @@ getVarIndex types index = go 0 0 where let nextPos = if isTwoWordTy then pos + 2 else succ pos go nextPos (succ currVarIndex) -opWithWordSize : Map Int InferredType -> (Int -> Asm ()) -> Int -> Asm () +opWithWordSize : {auto stateRef: Ref AsmState AsmState} -> Map Int InferredType -> (Int -> Core ()) -> Int -> Core () opWithWordSize types op var = do - newPos <- LiftIo $ getVarIndex types var + newPos <- coreLift $ getVarIndex types var op newPos -boxDouble : Asm () -boxDouble = InvokeMethod InvokeStatic "java/lang/Double" "valueOf" "(D)Ljava/lang/Double;" False +boxDouble : {auto stateRef: Ref AsmState AsmState} -> Core () +boxDouble = invokeMethod InvokeStatic "java/lang/Double" "valueOf" "(D)Ljava/lang/Double;" False -boxFloat : Asm () -boxFloat = InvokeMethod InvokeStatic "java/lang/Float" "valueOf" "(F)Ljava/lang/Float;" False +boxFloat : {auto stateRef: Ref AsmState AsmState} -> Core () +boxFloat = invokeMethod InvokeStatic "java/lang/Float" "valueOf" "(F)Ljava/lang/Float;" False -boxBool : Asm () -boxBool = InvokeMethod InvokeStatic "java/lang/Boolean" "valueOf" "(Z)Ljava/lang/Boolean;" False +boxBool : {auto stateRef: Ref AsmState AsmState} -> Core () +boxBool = invokeMethod InvokeStatic "java/lang/Boolean" "valueOf" "(Z)Ljava/lang/Boolean;" False -boxByte : Asm () -boxByte = InvokeMethod InvokeStatic "java/lang/Byte" "valueOf" "(B)Ljava/lang/Byte;" False +boxByte : {auto stateRef: Ref AsmState AsmState} -> Core () +boxByte = invokeMethod InvokeStatic "java/lang/Byte" "valueOf" "(B)Ljava/lang/Byte;" False -boxChar : Asm () -boxChar = InvokeMethod InvokeStatic "java/lang/Character" "valueOf" "(C)Ljava/lang/Character;" False +boxChar : {auto stateRef: Ref AsmState AsmState} -> Core () +boxChar = invokeMethod InvokeStatic "java/lang/Character" "valueOf" "(C)Ljava/lang/Character;" False -boxInt : Asm () -boxInt = InvokeMethod InvokeStatic "java/lang/Integer" "valueOf" "(I)Ljava/lang/Integer;" False +boxInt : {auto stateRef: Ref AsmState AsmState} -> Core () +boxInt = invokeMethod InvokeStatic "java/lang/Integer" "valueOf" "(I)Ljava/lang/Integer;" False -boxShort : Asm () -boxShort = InvokeMethod InvokeStatic "java/lang/Short" "valueOf" "(S)Ljava/lang/Short;" False +boxShort : {auto stateRef: Ref AsmState AsmState} -> Core () +boxShort = invokeMethod InvokeStatic "java/lang/Short" "valueOf" "(S)Ljava/lang/Short;" False -boxLong : Asm () -boxLong = InvokeMethod InvokeStatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;" False +boxLong : {auto stateRef: Ref AsmState AsmState} -> Core () +boxLong = invokeMethod InvokeStatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;" False -unboxBool : Asm () -unboxBool = InvokeMethod InvokeVirtual "java/lang/Boolean" "booleanValue" "()Z" False +unboxBool : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxBool = invokeMethod InvokeVirtual "java/lang/Boolean" "booleanValue" "()Z" False -unboxByte : Asm () -unboxByte = InvokeMethod InvokeVirtual "java/lang/Byte" "byteValue" "()B" False +unboxByte : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxByte = invokeMethod InvokeVirtual "java/lang/Byte" "byteValue" "()B" False -unboxInt : Asm () -unboxInt = InvokeMethod InvokeVirtual "java/lang/Integer" "intValue" "()I" False +unboxInt : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxInt = invokeMethod InvokeVirtual "java/lang/Integer" "intValue" "()I" False -unboxChar : Asm () -unboxChar = InvokeMethod InvokeVirtual "java/lang/Character" "charValue" "()C" False +unboxChar : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxChar = invokeMethod InvokeVirtual "java/lang/Character" "charValue" "()C" False -unboxShort : Asm () -unboxShort = InvokeMethod InvokeVirtual "java/lang/Short" "shortValue" "()S" False +unboxShort : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxShort = invokeMethod InvokeVirtual "java/lang/Short" "shortValue" "()S" False -unboxLong : Asm () -unboxLong = InvokeMethod InvokeVirtual "java/lang/Long" "longValue" "()J" False +unboxLong : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxLong = invokeMethod InvokeVirtual "java/lang/Long" "longValue" "()J" False -unboxDouble : Asm () -unboxDouble = InvokeMethod InvokeVirtual "java/lang/Double" "doubleValue" "()D" False +unboxDouble : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxDouble = invokeMethod InvokeVirtual "java/lang/Double" "doubleValue" "()D" False -unboxFloat : Asm () -unboxFloat = InvokeMethod InvokeVirtual "java/lang/Float" "floatValue" "()F" False +unboxFloat : {auto stateRef: Ref AsmState AsmState} -> Core () +unboxFloat = invokeMethod InvokeVirtual "java/lang/Float" "floatValue" "()F" False %inline export conversionClass : String conversionClass = "io/github/mmhelloworld/idrisjvm/runtime/Conversion" -boolObjToBool : Asm () -boolObjToBool = InvokeMethod InvokeStatic conversionClass "toBoolean" "(Ljava/lang/Object;)Z" False +boolObjToBool : {auto stateRef: Ref AsmState AsmState} -> Core () +boolObjToBool = invokeMethod InvokeStatic conversionClass "toBoolean" "(Ljava/lang/Object;)Z" False -boolToInt : Asm () -boolToInt = InvokeMethod InvokeStatic conversionClass "boolToInt1" "(Z)I" False +boolToInt : {auto stateRef: Ref AsmState AsmState} -> Core () +boolToInt = invokeMethod InvokeStatic conversionClass "boolToInt1" "(Z)I" False -objToInt : Asm () -objToInt = InvokeMethod InvokeStatic conversionClass "toInt" "(Ljava/lang/Object;)I" False +objToInt : {auto stateRef: Ref AsmState AsmState} -> Core () +objToInt = invokeMethod InvokeStatic conversionClass "toInt" "(Ljava/lang/Object;)I" False -objToChar : Asm () -objToChar = InvokeMethod InvokeStatic conversionClass "toChar" "(Ljava/lang/Object;)C" False +objToChar : {auto stateRef: Ref AsmState AsmState} -> Core () +objToChar = invokeMethod InvokeStatic conversionClass "toChar" "(Ljava/lang/Object;)C" False -objToBoolean : Asm () -objToBoolean = InvokeMethod InvokeStatic conversionClass "toBoolean" "(Ljava/lang/Object;)Z" False +objToBoolean : {auto stateRef: Ref AsmState AsmState} -> Core () +objToBoolean = invokeMethod InvokeStatic conversionClass "toBoolean" "(Ljava/lang/Object;)Z" False -objToByte : Asm () -objToByte = InvokeMethod InvokeStatic conversionClass "toByte" "(Ljava/lang/Object;)B" False +objToByte : {auto stateRef: Ref AsmState AsmState} -> Core () +objToByte = invokeMethod InvokeStatic conversionClass "toByte" "(Ljava/lang/Object;)B" False -charObjToChar : Asm () -charObjToChar = do Checkcast "java/lang/Character"; unboxChar +charObjToChar : {auto stateRef: Ref AsmState AsmState} -> Core () +charObjToChar = do checkcast "java/lang/Character"; unboxChar -objToShort : Asm () -objToShort = InvokeMethod InvokeStatic conversionClass "toShort" "(Ljava/lang/Object;)S" False +objToShort : {auto stateRef: Ref AsmState AsmState} -> Core () +objToShort = invokeMethod InvokeStatic conversionClass "toShort" "(Ljava/lang/Object;)S" False -objToLong : Asm () -objToLong = InvokeMethod InvokeStatic conversionClass "toLong" "(Ljava/lang/Object;)J" False +objToLong : {auto stateRef: Ref AsmState AsmState} -> Core () +objToLong = invokeMethod InvokeStatic conversionClass "toLong" "(Ljava/lang/Object;)J" False -objToFloat : Asm () -objToFloat = InvokeMethod InvokeStatic conversionClass "toFloat" "(Ljava/lang/Object;)F" False +objToFloat : {auto stateRef: Ref AsmState AsmState} -> Core () +objToFloat = invokeMethod InvokeStatic conversionClass "toFloat" "(Ljava/lang/Object;)F" False -objToDouble : Asm () -objToDouble = InvokeMethod InvokeStatic conversionClass "toDouble" "(Ljava/lang/Object;)D" False +objToDouble : {auto stateRef: Ref AsmState AsmState} -> Core () +objToDouble = invokeMethod InvokeStatic conversionClass "toDouble" "(Ljava/lang/Object;)D" False export -checkcast : String -> Asm () -checkcast "java/lang/Object" = pure () -checkcast cname = Checkcast cname - -export -asmCast : (sourceType: InferredType) -> (targetType: InferredType) -> Asm () +asmCast : {auto stateRef: Ref AsmState AsmState} -> (sourceType: InferredType) -> (targetType: InferredType) -> Core () asmCast ty1@(IRef class1 _ _) ty2@(IRef class2 _ _) = when (class1 /= class2) (checkcast class2) asmCast IUnknown ty@(IRef clazz _ _) = checkcast clazz -asmCast IBool IBool = Pure () -asmCast IByte IByte = Pure () -asmCast IChar IChar = Pure () -asmCast IShort IShort = Pure () -asmCast IInt IBool = Pure () -asmCast IInt IInt = Pure () -asmCast ILong ILong = Pure () -asmCast IFloat IFloat = Pure () -asmCast IDouble IDouble = Pure () -asmCast (IArray _) (IArray _) = Pure () +asmCast IBool IBool = pure () +asmCast IByte IByte = pure () +asmCast IChar IChar = pure () +asmCast IShort IShort = pure () +asmCast IInt IBool = pure () +asmCast IInt IInt = pure () +asmCast ILong ILong = pure () +asmCast IFloat IFloat = pure () +asmCast IDouble IDouble = pure () +asmCast (IArray _) (IArray _) = pure () asmCast IBool IInt = boolToInt -asmCast IInt IChar = I2c -asmCast IInt IByte = I2b -asmCast IInt IShort = I2s -asmCast IFloat IDouble = F2d -asmCast IDouble IFloat = D2f +asmCast IInt IChar = i2c +asmCast IInt IByte = i2b +asmCast IInt IShort = i2s +asmCast IFloat IDouble = f2d +asmCast IDouble IFloat = d2f asmCast ty IBool = objToBoolean @@ -173,8 +169,8 @@ asmCast IShort ty = boxShort asmCast IInt ty = if ty == inferredBigIntegerType then do - I2l - InvokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False + i2l + invokeMethod InvokeStatic "java/math/BigInteger" "valueOf" "(J)Ljava/math/BigInteger;" False else boxInt asmCast ILong ty = boxLong @@ -183,95 +179,96 @@ asmCast IFloat ty = boxFloat asmCast IDouble ty = boxDouble -asmCast (IRef _ _ _) arr@(IArray _) = Checkcast $ getJvmTypeDescriptor arr -asmCast (IArray _) (IRef clazz _ _) = Checkcast clazz +asmCast (IRef _ _ _) arr@(IArray _) = checkcast $ getJvmTypeDescriptor arr +asmCast (IArray _) (IRef clazz _ _) = checkcast clazz -asmCast _ IVoid = Pure () -asmCast IVoid IVoid = Pure () -asmCast IVoid (IRef _ _ _) = Aconstnull -asmCast IVoid IUnknown = Aconstnull -asmCast ty IUnknown = Pure () +asmCast _ IVoid = pure () +asmCast IVoid IVoid = pure () +asmCast IVoid (IRef _ _ _) = aconstnull +asmCast IVoid IUnknown = aconstnull +asmCast ty IUnknown = pure () -asmCast ty1 ty2 = Throw emptyFC $ "Cannot convert from " ++ show ty1 ++ " to " ++ show ty2 +asmCast ty1 ty2 = throw $ GenericMsg emptyFC $ "Cannot convert from " ++ show ty1 ++ " to " ++ show ty2 -loadAndBox : (Int -> Asm ()) -> Asm () -> Map Int InferredType -> Int -> Asm () +loadAndBox : {auto stateRef: Ref AsmState AsmState} -> (Int -> Core ()) -> Core () -> Map Int InferredType + -> Int -> Core () loadAndBox loadOp boxOp sourceLocTys var = let op = \index => do loadOp index; boxOp in opWithWordSize sourceLocTys op var -loadAndBoxBool : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxBool ty = loadAndBox Iload boxBool +loadAndBoxBool : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxBool ty = loadAndBox iload boxBool -loadAndBoxByte : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxByte ty = loadAndBox Iload boxByte +loadAndBoxByte : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxByte ty = loadAndBox iload boxByte -loadAndBoxChar : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxChar ty = loadAndBox Iload boxChar +loadAndBoxChar : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxChar ty = loadAndBox iload boxChar -loadAndBoxShort : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxShort ty = loadAndBox Iload boxShort +loadAndBoxShort : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxShort ty = loadAndBox iload boxShort -loadAndBoxInt : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxInt ty = loadAndBox Iload boxInt +loadAndBoxInt : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxInt ty = loadAndBox iload boxInt -loadAndBoxLong : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxLong ty = loadAndBox Lload boxLong +loadAndBoxLong : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxLong ty = loadAndBox lload boxLong -loadAndBoxFloat : Map Int InferredType -> Int -> Asm () -loadAndBoxFloat = loadAndBox Fload boxFloat +loadAndBoxFloat : {auto stateRef: Ref AsmState AsmState} -> Map Int InferredType -> Int -> Core () +loadAndBoxFloat = loadAndBox fload boxFloat -loadAndBoxDouble : InferredType -> Map Int InferredType -> Int -> Asm () -loadAndBoxDouble ty = loadAndBox Dload boxDouble +loadAndBoxDouble : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () +loadAndBoxDouble ty = loadAndBox dload boxDouble -loadAndUnboxBool : InferredType -> Map Int InferredType -> Int -> Asm () +loadAndUnboxBool : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () loadAndUnboxBool ty sourceLocTys var = - let loadInstr = \index => do Aload index; boolObjToBool + let loadInstr = \index => do aload index; boolObjToBool in opWithWordSize sourceLocTys loadInstr var -loadAndUnboxByte : InferredType -> Map Int InferredType -> Int -> Asm () +loadAndUnboxByte : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () loadAndUnboxByte ty sourceLocTys var = - let loadInstr = \index => do Aload index; objToByte + let loadInstr = \index => do aload index; objToByte in opWithWordSize sourceLocTys loadInstr var -loadAndUnboxChar : InferredType -> Map Int InferredType -> Int -> Asm () +loadAndUnboxChar : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () loadAndUnboxChar ty sourceLocTys var = - let loadInstr = \index => do Aload index; objToChar + let loadInstr = \index => do aload index; objToChar in opWithWordSize sourceLocTys loadInstr var -loadAndUnboxShort : InferredType -> Map Int InferredType -> Int -> Asm () +loadAndUnboxShort : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () loadAndUnboxShort ty sourceLocTys var = - let loadInstr = \index => do Aload index; objToShort + let loadInstr = \index => do aload index; objToShort in opWithWordSize sourceLocTys loadInstr var -loadAndUnboxInt : InferredType -> Map Int InferredType -> Int -> Asm () +loadAndUnboxInt : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () loadAndUnboxInt ty sourceLocTys var = - let loadInstr = \index => do Aload index; objToInt + let loadInstr = \index => do aload index; objToInt in opWithWordSize sourceLocTys loadInstr var -loadAndUnboxDouble : InferredType -> Map Int InferredType -> Int -> Asm () +loadAndUnboxDouble : {auto stateRef: Ref AsmState AsmState} -> InferredType -> Map Int InferredType -> Int -> Core () loadAndUnboxDouble ty sourceLocTys var = - let loadInstr = \index => do Aload index; objToDouble + let loadInstr = \index => do aload index; objToDouble in opWithWordSize sourceLocTys loadInstr var export -loadVar : Map Int InferredType -> (srcTy: InferredType) -> (targetTy: InferredType) -> Int -> Asm () -loadVar sourceLocTys IBool IBool var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IByte IByte var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IChar IChar var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IShort IShort var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IBool IInt var = opWithWordSize sourceLocTys (\var => do Iload var; boolToInt) var -loadVar sourceLocTys IByte IInt var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IChar IInt var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IShort IInt var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IInt IInt var = opWithWordSize sourceLocTys Iload var -loadVar sourceLocTys IInt IChar var = opWithWordSize sourceLocTys (\var => do Iload var; I2c) var -loadVar sourceLocTys IInt IByte var = opWithWordSize sourceLocTys (\var => do Iload var; I2b) var -loadVar sourceLocTys IInt IShort var = opWithWordSize sourceLocTys (\var => do Iload var; I2s) var -loadVar sourceLocTys ILong ILong var = opWithWordSize sourceLocTys Lload var -loadVar sourceLocTys IFloat IFloat var = opWithWordSize sourceLocTys Fload var -loadVar sourceLocTys IFloat IDouble var = opWithWordSize sourceLocTys (\var => do Fload var; F2d) var -loadVar sourceLocTys IDouble IDouble var = opWithWordSize sourceLocTys Dload var -loadVar sourceLocTys IDouble IFloat var = opWithWordSize sourceLocTys (\var => do Dload var; D2f) var -loadVar sourceLocTys ty1@(IArray _) ty2@(IArray _) var = opWithWordSize sourceLocTys Aload var +loadVar : {auto stateRef: Ref AsmState AsmState} -> Map Int InferredType -> (srcTy: InferredType) -> (targetTy: InferredType) -> Int -> Core () +loadVar sourceLocTys IBool IBool var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IByte IByte var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IChar IChar var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IShort IShort var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IBool IInt var = opWithWordSize sourceLocTys (\var => do iload var; boolToInt) var +loadVar sourceLocTys IByte IInt var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IChar IInt var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IShort IInt var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IInt IInt var = opWithWordSize sourceLocTys iload var +loadVar sourceLocTys IInt IChar var = opWithWordSize sourceLocTys (\var => do iload var; i2c) var +loadVar sourceLocTys IInt IByte var = opWithWordSize sourceLocTys (\var => do iload var; i2b) var +loadVar sourceLocTys IInt IShort var = opWithWordSize sourceLocTys (\var => do iload var; i2s) var +loadVar sourceLocTys ILong ILong var = opWithWordSize sourceLocTys lload var +loadVar sourceLocTys IFloat IFloat var = opWithWordSize sourceLocTys fload var +loadVar sourceLocTys IFloat IDouble var = opWithWordSize sourceLocTys (\var => do fload var; f2d) var +loadVar sourceLocTys IDouble IDouble var = opWithWordSize sourceLocTys dload var +loadVar sourceLocTys IDouble IFloat var = opWithWordSize sourceLocTys (\var => do dload var; d2f) var +loadVar sourceLocTys ty1@(IArray _) ty2@(IArray _) var = opWithWordSize sourceLocTys aload var loadVar sourceLocTys IBool ty var = loadAndBoxBool ty sourceLocTys var loadVar sourceLocTys IByte ty var = loadAndBoxByte ty sourceLocTys var @@ -296,59 +293,59 @@ loadVar sourceLocTys ty IShort var = loadAndUnboxShort ty sourceLocTys var loadVar sourceLocTys ty IInt var = loadAndUnboxInt ty sourceLocTys var loadVar sourceLocTys ty ILong var = - let loadInstr = \index => do Aload index; objToLong + let loadInstr = \index => do aload index; objToLong in opWithWordSize sourceLocTys loadInstr var loadVar sourceLocTys _ (IRef "java/math/BigInteger" _ _) var = let loadInstr = \index => do - Aload index - InvokeMethod InvokeStatic conversionClass "toInteger" "(Ljava/lang/Object;)Ljava/math/BigInteger;" False + aload index + invokeMethod InvokeStatic conversionClass "toInteger" "(Ljava/lang/Object;)Ljava/math/BigInteger;" False in opWithWordSize sourceLocTys loadInstr var loadVar sourceLocTys ty IFloat var = - let loadInstr = \index => do Aload index; objToFloat + let loadInstr = \index => do aload index; objToFloat in opWithWordSize sourceLocTys loadInstr var loadVar sourceLocTys ty IDouble var = loadAndUnboxDouble ty sourceLocTys var loadVar sourceLocTys _ arr@(IArray _) var = - let loadInstr = \index => do Aload index; checkcast $ getJvmTypeDescriptor arr + let loadInstr = \index => do aload index; checkcast $ getJvmTypeDescriptor arr in opWithWordSize sourceLocTys loadInstr var loadVar sourceLocTys IUnknown ty2@(IRef _ _ _) var = - let loadInstr = \index => do Aload index; asmCast IUnknown ty2 + let loadInstr = \index => do aload index; asmCast IUnknown ty2 in opWithWordSize sourceLocTys loadInstr var -loadVar sourceLocTys (IArray _) (IRef _ _ _) var = opWithWordSize sourceLocTys Aload var -loadVar sourceLocTys (IArray _) IUnknown var = opWithWordSize sourceLocTys Aload var +loadVar sourceLocTys (IArray _) (IRef _ _ _) var = opWithWordSize sourceLocTys aload var +loadVar sourceLocTys (IArray _) IUnknown var = opWithWordSize sourceLocTys aload var -loadVar sourceLocTys (IRef _ _ _) IUnknown var = opWithWordSize sourceLocTys Aload var -loadVar sourceLocTys IUnknown IUnknown var = opWithWordSize sourceLocTys Aload var +loadVar sourceLocTys (IRef _ _ _) IUnknown var = opWithWordSize sourceLocTys aload var +loadVar sourceLocTys IUnknown IUnknown var = opWithWordSize sourceLocTys aload var loadVar sourceLocTys ty1@(IRef _ _ _) ty2@(IRef _ _ _) var = - let loadInstr = \index => do Aload index; asmCast ty1 ty2 + let loadInstr = \index => do aload index; asmCast ty1 ty2 in opWithWordSize sourceLocTys loadInstr var -loadVar sourceLocTys ty1 ty2 var = Throw emptyFC ("Cannot load variable " ++ show var ++ " of type " ++ show ty1 ++ +loadVar sourceLocTys ty1 ty2 var = throw $ GenericMsg emptyFC ("Cannot load variable " ++ show var ++ " of type " ++ show ty1 ++ " to type " ++ show ty2) -storeVarWithWordSize : (Int -> Asm ()) -> Int -> Asm () +storeVarWithWordSize : {auto stateRef: Ref AsmState AsmState} -> (Int -> Core ()) -> Int -> Core () storeVarWithWordSize storeOp var = opWithWordSize !getVariableTypes storeOp var -boxStore : Asm () -> Int -> Asm () -boxStore boxOp var = storeVarWithWordSize (\index => do boxOp; Astore index) var +boxStore : {auto stateRef: Ref AsmState AsmState} -> Core () -> Int -> Core () +boxStore boxOp var = storeVarWithWordSize (\index => do boxOp; astore index) var export -storeVar : (srcTy: InferredType) -> (targetTy: InferredType) -> Int -> Asm () -storeVar IBool IBool var = do types <- getVariableTypes; opWithWordSize types Istore var -storeVar IByte IByte var = do types <- getVariableTypes; opWithWordSize types Istore var -storeVar IChar IChar var = do types <- getVariableTypes; opWithWordSize types Istore var -storeVar IShort IShort var = do types <- getVariableTypes; opWithWordSize types Istore var -storeVar IInt IInt var = do types <- getVariableTypes; opWithWordSize types Istore var -storeVar ILong ILong var = do types <- getVariableTypes; opWithWordSize types Lstore var -storeVar IFloat IFloat var = do types <- getVariableTypes; opWithWordSize types Fstore var -storeVar IDouble IDouble var = do types <- getVariableTypes; opWithWordSize types Dstore var -storeVar (IArray _) (IArray _) var = do types <- getVariableTypes; opWithWordSize types Astore var +storeVar : {auto stateRef: Ref AsmState AsmState} -> (srcTy: InferredType) -> (targetTy: InferredType) -> Int -> Core () +storeVar IBool IBool var = do types <- getVariableTypes; opWithWordSize types istore var +storeVar IByte IByte var = do types <- getVariableTypes; opWithWordSize types istore var +storeVar IChar IChar var = do types <- getVariableTypes; opWithWordSize types istore var +storeVar IShort IShort var = do types <- getVariableTypes; opWithWordSize types istore var +storeVar IInt IInt var = do types <- getVariableTypes; opWithWordSize types istore var +storeVar ILong ILong var = do types <- getVariableTypes; opWithWordSize types lstore var +storeVar IFloat IFloat var = do types <- getVariableTypes; opWithWordSize types fstore var +storeVar IDouble IDouble var = do types <- getVariableTypes; opWithWordSize types dstore var +storeVar (IArray _) (IArray _) var = do types <- getVariableTypes; opWithWordSize types astore var storeVar IBool ty var = boxStore boxBool var storeVar IByte ty var = boxStore boxByte var @@ -359,28 +356,28 @@ storeVar ILong ty var = boxStore boxLong var storeVar IFloat ty var = boxStore boxFloat var storeVar IDouble ty var = boxStore boxDouble var -storeVar ty IBool var = storeVarWithWordSize (\index => do asmCast ty IBool; Istore index) var +storeVar ty IBool var = storeVarWithWordSize (\index => do asmCast ty IBool; istore index) var -storeVar ty IByte var = storeVarWithWordSize (\index => do asmCast ty IByte; Istore index) var +storeVar ty IByte var = storeVarWithWordSize (\index => do asmCast ty IByte; istore index) var -storeVar ty IChar var = storeVarWithWordSize (\index => do asmCast ty IChar; Istore index) var +storeVar ty IChar var = storeVarWithWordSize (\index => do asmCast ty IChar; istore index) var -storeVar ty IShort var = storeVarWithWordSize (\index => do asmCast ty IShort; Istore index) var +storeVar ty IShort var = storeVarWithWordSize (\index => do asmCast ty IShort; istore index) var -storeVar ty IInt var = storeVarWithWordSize (\index => do asmCast ty IInt; Istore index) var +storeVar ty IInt var = storeVarWithWordSize (\index => do asmCast ty IInt; istore index) var -storeVar ty ILong var = storeVarWithWordSize (\index => do asmCast ty ILong; Lstore index) var +storeVar ty ILong var = storeVarWithWordSize (\index => do asmCast ty ILong; lstore index) var -storeVar ty IFloat var = storeVarWithWordSize (\index => do asmCast ty IFloat; Fstore index) var +storeVar ty IFloat var = storeVarWithWordSize (\index => do asmCast ty IFloat; fstore index) var -storeVar ty IDouble var = storeVarWithWordSize (\index => do asmCast ty IDouble; Dstore index) var +storeVar ty IDouble var = storeVarWithWordSize (\index => do asmCast ty IDouble; dstore index) var storeVar ty arr@(IArray elemTy) var = - storeVarWithWordSize (\index => do checkcast $ getJvmTypeDescriptor arr; Astore index) var + storeVarWithWordSize (\index => do checkcast $ getJvmTypeDescriptor arr; astore index) var storeVar ty targetTy@(IRef _ _ _) var = do types <- getVariableTypes asmCast ty targetTy - opWithWordSize types Astore var + opWithWordSize types astore var -storeVar _ _ var = opWithWordSize !getVariableTypes Astore var +storeVar _ _ var = opWithWordSize !getVariableTypes astore var