Skip to content

Commit b377873

Browse files
authored
Simplify invokedynamic calls (#50)
1 parent 4c01f5d commit b377873

File tree

1 file changed

+34
-36
lines changed
  • idris-jvm-core/src/main/idris/IdrisJvm/Core

1 file changed

+34
-36
lines changed

idris-jvm-core/src/main/idris/IdrisJvm/Core/Common.idr

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,14 @@ unboxDouble = InvokeMethod InvokeVirtual "java/lang/Double" "doubleValue" "()D"
8787
unboxFloat : Asm ()
8888
unboxFloat = InvokeMethod InvokeVirtual "java/lang/Float" "floatValue" "()F" False
8989

90+
repeatString : Nat -> String -> String
91+
repeatString n s = concat (replicate n s)
92+
93+
repeatObjectDesc : Nat -> String
94+
repeatObjectDesc n = repeatString n "Ljava/lang/Object;"
95+
9096
sig : Nat -> String
91-
sig nArgs = "(" ++ argTypes ++ ")Ljava/lang/Object;" where
92-
argTypes : String
93-
argTypes = concat (replicate nArgs "Ljava/lang/Object;")
97+
sig nArgs = "(" ++ repeatObjectDesc nArgs ++ ")Ljava/lang/Object;"
9498

9599
metafactoryDesc : Descriptor
96100
metafactoryDesc =
@@ -107,53 +111,46 @@ metafactoryDesc =
107111
lambdaDesc : Descriptor
108112
lambdaDesc = "([Ljava/lang/Object;)Ljava/lang/Object;"
109113

110-
invokeDynamic : ClassName -> MethodName -> Asm ()
111-
invokeDynamic cname lambda = InvokeDynamic "apply" ("()" ++ rtFuncSig) metafactoryHandle metafactoryArgs where
112-
metafactoryHandle = MkHandle HInvokeStatic "java/lang/invoke/LambdaMetafactory" "metafactory" metafactoryDesc False
114+
invokeDynamic : ClassName -> MethodName -> Nat -> Asm ()
115+
invokeDynamic cname lambda nArgs =
116+
InvokeDynamic "call" desc metafactoryHandle metafactoryArgs
117+
where
118+
desc : String
119+
desc = "(" ++ repeatObjectDesc nArgs ++ ")" ++ rtThunkSig
113120

114-
lambdaHandle : Handle
115-
lambdaHandle = MkHandle HInvokeStatic cname lambda lambdaDesc False
121+
metafactoryHandle = MkHandle HInvokeStatic "java/lang/invoke/LambdaMetafactory" "metafactory" metafactoryDesc False
116122

117-
metafactoryArgs = [ BsmArgGetType lambdaDesc
118-
, BsmArgHandle lambdaHandle
119-
, BsmArgGetType lambdaDesc
120-
]
123+
lambdaHandle : Handle
124+
lambdaHandle = MkHandle HInvokeStatic cname lambda (sig nArgs) False
121125

122-
storeArgIntoArray : Int -> Int -> Asm ()
123-
storeArgIntoArray lhs rhs = do
124-
Dup
125-
Iconst lhs
126-
Aload rhs
127-
Aastore
126+
metafactoryArgs = [ BsmArgGetType "()Ljava/lang/Object;"
127+
, BsmArgHandle lambdaHandle
128+
, BsmArgGetType "()Ljava/lang/Object;"
129+
]
128130

129-
loadArgsFromArray : Nat -> Asm ()
130-
loadArgsFromArray nArgs = case isLTE 1 nArgs of
131-
Yes prf => sequence_ (map (loadArg . cast) [0 .. (Nat.(-) nArgs 1)])
131+
loadArgsForLambdaTargetMethod : Nat -> Asm ()
132+
loadArgsForLambdaTargetMethod nArgs = case isLTE 1 nArgs of
133+
Yes prf => sequence_ (map (Aload . cast) [0 .. (Nat.(-) nArgs 1)])
132134
No contra => Pure ()
133-
where
134-
loadArg : Int -> Asm ()
135-
loadArg n = do Aload 0; Iconst n; Aaload
136135

137136
createThunkForLambda : JMethodName -> List LVar -> (MethodName -> Asm ()) -> Asm ()
138137
createThunkForLambda caller args lambdaCode = do
139138
let nArgs = List.length args
140139
let cname = jmethClsName caller
141140
lambdaIndex <- FreshLambdaIndex cname
142141
let lambdaMethodName = sep "$" ["lambda", jmethName caller, show lambdaIndex]
143-
invokeDynamic cname lambdaMethodName
144-
lambdaCode lambdaMethodName
145-
Iconst $ cast nArgs
146-
Anewarray "java/lang/Object"
147142
let argNums = map locIndex args
148-
sequence_ . map (uncurry storeArgIntoArray) $ List.zip [0.. (cast $ List.length argNums)] argNums
149-
InvokeMethod InvokeStatic (rtClassSig "Runtime") "thunk" createThunkSig False
143+
sequence_ . map Aload $ argNums
144+
invokeDynamic cname lambdaMethodName nArgs
145+
lambdaCode lambdaMethodName
150146

151147
createLambda : JMethodName -> ClassName -> MethodName -> Nat -> Asm ()
152148
createLambda (MkJMethodName cname fname) callerCname lambdaMethodName nArgs = do
153-
CreateMethod [Private, Static, Synthetic] callerCname lambdaMethodName lambdaDesc Nothing Nothing [] []
149+
let desc = sig nArgs
150+
CreateMethod [Private, Static, Synthetic] callerCname lambdaMethodName desc Nothing Nothing [] []
154151
MethodCodeStart
155-
loadArgsFromArray nArgs
156-
InvokeMethod InvokeStatic cname fname (sig nArgs) False -- invoke the target method
152+
loadArgsForLambdaTargetMethod nArgs
153+
InvokeMethod InvokeStatic cname fname desc False -- invoke the target method
157154
Areturn
158155
MaxStackAndLocal (-1) (-1)
159156
MethodCodeEnd
@@ -166,10 +163,11 @@ createThunk caller@(MkJMethodName callerCname _) fname args = do
166163

167164
createParLambda : JMethodName -> ClassName -> MethodName -> Nat -> Asm ()
168165
createParLambda (MkJMethodName cname fname) callerCname lambdaMethodName nArgs = do
169-
CreateMethod [Private, Static, Synthetic] callerCname lambdaMethodName lambdaDesc Nothing Nothing [] []
166+
let desc = sig nArgs
167+
CreateMethod [Private, Static, Synthetic] callerCname lambdaMethodName desc Nothing Nothing [] []
170168
MethodCodeStart
171-
loadArgsFromArray nArgs
172-
InvokeMethod InvokeStatic cname fname (sig nArgs) False -- invoke the target method
169+
loadArgsForLambdaTargetMethod nArgs
170+
InvokeMethod InvokeStatic cname fname desc False -- invoke the target method
173171
Astore 1
174172
Aload 1
175173
InvokeMethod InvokeVirtual "java/lang/Object" "getClass" "()Ljava/lang/Class;" False

0 commit comments

Comments
 (0)