Skip to content

Commit 77c87da

Browse files
committed
Implement better indy and LDC for DynamicConstant
1 parent 63650d1 commit 77c87da

File tree

10 files changed

+57
-30
lines changed

10 files changed

+57
-30
lines changed

Kores

Submodule Kores updated 47 files

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ buildscript {
1818
}
1919

2020
group 'com.koresframework'
21-
version '4.2.1.bytecode'
21+
version '4.2.2.bytecode'
2222

2323
apply from: project(":Kores").file("gradle/common.gradle")
2424

@@ -59,7 +59,7 @@ dependencies {
5959
// with runtime dependency pointing to Kores published version
6060
//compile project(":Kores")
6161
compileOnly project(":Kores")
62-
runtimeOnly "com.koresframework:kores:4.2.1.base"
62+
runtimeOnly "com.koresframework:kores:4.2.2.base"
6363
implementation 'com.github.jonathanxd:bytecode-disassembler:2.4.1'
6464
implementation "org.ow2.asm:asm:9.2"
6565
implementation "org.ow2.asm:asm-analysis:9.2"

src/main/kotlin/com/koresframework/kores/bytecode/processor/processors/ConcatProcessor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ object ConcatProcessor : Processor<Concat> {
242242
)
243243
)
244244
.bootstrapArgs(bootstrapArgs)
245-
.dynamicMethod(
245+
.dynamicDescriptor(
246246
DynamicMethodSpec(
247247
"makeConcatWithConstants",
248248
TypeSpec(typeOf<String>(), types),

src/main/kotlin/com/koresframework/kores/bytecode/processor/processors/InvokeDynamicProcessor.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ object InvokeDynamicProcessor : Processor<InvokeDynamicBase> {
5050

5151
val mvHelper = METHOD_VISITOR.require(data)
5252

53-
val dynamicMethod = part.dynamicMethod
53+
val dynamicDescriptor = part.dynamicDescriptor
5454

55-
processorManager.process(ArgumentsHolder::class.java, part.dynamicMethod, data)
55+
if (dynamicDescriptor is ArgumentsHolder) {
56+
processorManager.process(ArgumentsHolder::class.java, dynamicDescriptor, data)
57+
}
5658

57-
val specification = dynamicMethod
59+
val specification = dynamicDescriptor
5860

5961
if (part is InvokeDynamicBase.LambdaMethodRefBase) {
6062
if (part is InvokeDynamicBase.LambdaLocalCodeBase) {
@@ -70,7 +72,7 @@ object InvokeDynamicProcessor : Processor<InvokeDynamicBase> {
7072
mvHelper.methodVisitor
7173
)
7274

73-
if (!part.dynamicMethod.typeSpec.returnType.`is`(Void.TYPE) && IN_EXPRESSION.require(data) == 0) {
75+
if (!part.type.`is`(Void.TYPE) && IN_EXPRESSION.require(data) == 0) {
7476
mvHelper.methodVisitor.visitInsn(Opcodes.POP)
7577
}
7678
}

src/main/kotlin/com/koresframework/kores/bytecode/processor/processors/LiteralProcessor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import org.objectweb.asm.Opcodes
4040
object LiteralProcessor : Processor<Literal> {
4141

4242
override fun process(part: Literal, data: TypedData, processorManager: ProcessorManager<*>) {
43-
LiteralUtil.visitLiteral(part, METHOD_VISITOR.require(data).methodVisitor)
43+
LiteralUtil.visitLiteral(part, METHOD_VISITOR.require(data).methodVisitor, data)
4444

4545
if (IN_EXPRESSION.require(data) == 0) {
4646
METHOD_VISITOR.require(data).methodVisitor.visitInsn(Opcodes.POP)

src/main/kotlin/com/koresframework/kores/bytecode/processor/processors/Util.kt

+9-2
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ import com.koresframework.kores.bytecode.processor.*
3535
import com.koresframework.kores.bytecode.util.ReflectType
3636
import com.koresframework.kores.bytecode.util.allInnerTypes
3737
import com.koresframework.kores.bytecode.util.allTypes
38-
import com.koresframework.kores.common.getNewName
39-
import com.koresframework.kores.common.getNewNameBasedOnNameList
4038
import com.koresframework.kores.factory.*
4139
import com.koresframework.kores.type.*
4240
import com.koresframework.kores.util.conversion.access
4341
import com.github.jonathanxd.iutils.data.TypedData
4442
import com.github.jonathanxd.iutils.kt.add
4543
import com.github.jonathanxd.iutils.kt.require
44+
import com.koresframework.kores.common.*
45+
import com.koresframework.kores.util.typeDesc
4646
import java.lang.reflect.Type
4747

4848
object Util {
@@ -51,6 +51,13 @@ object Util {
5151
spec.copy(returnType = resolveType(spec.returnType, data),
5252
parameterTypes = spec.parameterTypes.map { resolveType(it, data) })
5353

54+
fun resolveTypeDesc(desc: DynamicDescriptor, data: TypedData): String =
55+
when (desc) {
56+
is DynamicMethodSpec -> resolveType(desc.typeSpec, data).typeDesc
57+
is DynamicTypeSpec -> resolveType(desc.type, data).typeDesc
58+
}
59+
60+
5461
fun resolveType(koresType: ReflectType, data: TypedData): KoresType {
5562

5663
val type by lazy {

src/main/kotlin/com/koresframework/kores/bytecode/util/LiteralUtil.kt

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
*/
2828
package com.koresframework.kores.bytecode.util
2929

30+
import com.github.jonathanxd.iutils.data.TypedData
3031
import com.koresframework.kores.Types
3132
import com.koresframework.kores.common.Stack
3233
import com.koresframework.kores.literal.Literal
@@ -40,7 +41,7 @@ import org.objectweb.asm.Type
4041

4142
object LiteralUtil {
4243

43-
fun visitLiteral(num: Literal, mv: MethodVisitor) {
44+
fun visitLiteral(num: Literal, mv: MethodVisitor, data: TypedData) {
4445
val value = num.value
4546

4647
if (num == Stack)
@@ -58,6 +59,12 @@ object LiteralUtil {
5859

5960
mv.visitInsn(Opcodes.ICONST_0)
6061

62+
} else if (num is Literals.DynamicConstantLiteral) {
63+
val constantDynamic = MethodInvocationUtil.run {
64+
num.spec.toConstantDynamic(data)
65+
}
66+
67+
mv.visitLdcInsn(constantDynamic)
6168
} else if (num.type.`is`(Types.STRING)) {
6269

6370
mv.visitLdcInsn((value as String).substring(1, value.length - 1))
@@ -92,7 +99,7 @@ object LiteralUtil {
9299

93100
if (type.isPrimitive) {
94101
val wrapperType = type.wrapperType
95-
?: throw IllegalArgumentException("Primitive type '$type' has no wrapper version.")
102+
?: throw IllegalArgumentException("Primitive type '$type' has no wrapper version.")
96103

97104
val wrapperTypeSpec = wrapperType.internalName
98105
val classType = Types.CLASS.typeDesc

src/main/kotlin/com/koresframework/kores/bytecode/util/MethodInvocationUtil.kt

+13-10
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ package com.koresframework.kores.bytecode.util
2929

3030
import com.koresframework.kores.base.*
3131
import com.koresframework.kores.bytecode.processor.processors.Util
32-
import com.koresframework.kores.type.KoresType
3332
import com.koresframework.kores.type.internalName
3433
import com.koresframework.kores.type.javaSpecName
3534
import com.koresframework.kores.util.TypeResolver
@@ -38,6 +37,7 @@ import com.koresframework.kores.util.toTypeSpec
3837
import com.koresframework.kores.util.typeDesc
3938
import com.github.jonathanxd.iutils.data.TypedData
4039
import com.github.jonathanxd.iutils.description.DescriptionUtil
40+
import com.koresframework.kores.bytecode.util.MethodInvocationUtil.toHandle
4141
import com.koresframework.kores.common.*
4242
import com.koresframework.kores.type.isInterface
4343
import org.objectweb.asm.*
@@ -98,15 +98,15 @@ object MethodInvocationUtil {
9898

9999
fun visitBootstrapInvocation(
100100
bootstrap: InvokeDynamicBase,
101-
spec: DynamicMethodSpec,
101+
spec: DynamicDescriptor,
102102
data: TypedData,
103103
mv: MethodVisitor
104104
) {
105105
val handle = MethodInvocationUtil.toHandle(bootstrap, data)
106106

107107
mv.visitInvokeDynamicInsn(
108108
spec.name,
109-
Util.resolveType(spec.typeSpec, data).typeDesc,
109+
Util.resolveTypeDesc(spec, data),
110110
handle,
111111
*MethodInvocationUtil.toAsmArguments(bootstrap, data)
112112
)
@@ -156,12 +156,7 @@ object MethodInvocationUtil {
156156
arg.toHandle(data)
157157
}
158158
is DynamicConstantSpec -> {
159-
ConstantDynamic(
160-
arg.constantName,
161-
Util.resolveType(arg.type, data).typeDesc,
162-
arg.bootstrapMethod.toHandle(data),
163-
*toAsmArguments(arg.bootstrapArgs, data)
164-
)
159+
arg.toConstantDynamic(data)
165160
}
166161
is TypeSpec -> {
167162

@@ -181,6 +176,14 @@ object MethodInvocationUtil {
181176
return asmArgs
182177
}
183178

179+
fun DynamicConstantSpec.toConstantDynamic(data: TypedData): ConstantDynamic =
180+
ConstantDynamic(
181+
this.constantName,
182+
Util.resolveType(this.type, data).typeDesc,
183+
this.bootstrapMethod.toHandle(data),
184+
*toAsmArguments(this.bootstrapArgs, data)
185+
)
186+
184187
fun MethodInvokeHandleSpec.toHandle(data: TypedData): Handle =
185188
Handle(
186189
InvokeTypeUtil.toAsm_H(this.invokeType),
@@ -238,7 +241,7 @@ object MethodInvocationUtil {
238241

239242
return InvokeDynamic(
240243
bootstrap = methodInvokeSpec,
241-
dynamicMethod = dynamicMethod,
244+
dynamicDescriptor = dynamicMethod,
242245
bootstrapArgs = MethodInvocationUtil.bsmArgsFromAsm(args, typeResolver)
243246
)
244247
}

src/test/java/com/koresframework/kores/test/asm/IndyTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ public static MethodDeclaration makeCM2(TypeRef typeDeclaration) {
226226
Collections.singletonList("value")
227227
);
228228

229+
methodSource.add(VariableFactory.variable(Types.STRING, "a", Literals.DYNAMIC_CONSTANT(someConst)));
230+
229231
InvokeDynamic bootstrapInvocation = DynamicInvocationFactory.invokeDynamic(
230232
new MethodInvokeSpec(InvokeType.INVOKE_STATIC, BOOTSTRAP_SPEC),
231233
new DynamicMethodSpec("helloWorld", Factories.typeSpec(Types.STRING, Types.STRING),

src/test/resources/disassembled/IndyTest_IndyTest_Generated_Result.class.disassembled

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
md5: 37e5ffe09ed6cae08690bbba4a449943
1+
md5: 9bf625c763e5cbee0e733ae2b5527e09
22

33
version: Java 16 (60)
44
access: ACC_PUBLIC (33)
@@ -39,14 +39,19 @@ public class fullName.IndyTest_Generated extends java.lang.Object {
3939
!parameter[name: x, access: (0)]
4040
public java.lang.String check(int) {
4141
desc: (I)Ljava/lang/String;
42-
maxStack: 2, maxLocals: 2
42+
maxStack: 2, maxLocals: 3
4343
Label_0:
4444
LINE 1 -> Label_0
4545
getstatic java.lang.System.out (type: java.io.PrintStream)
4646
ldc "Invoke Dynamic Bootstrap ->" // type: java.lang.String
4747
invokevirtual java.io.PrintStream.println(java.lang.Object)void (ownerIsInterface: false)
4848
Label_1:
4949
LINE 2 -> Label_1
50+
ldc some : Ljava/lang/String; com/koresframework/kores/test/asm/IndyTest.constantBootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/String; (6) [value] // type: org.objectweb.asm.ConstantDynamic
51+
Label_2:
52+
astore 2
53+
Label_3:
54+
LINE 3 -> Label_3
5055
ldc "World" // type: java.lang.String
5156
invokedynamic helloWorld(java.lang.String)java.lang.String [
5257
// Bootstrap method
@@ -56,8 +61,8 @@ public class fullName.IndyTest_Generated extends java.lang.Object {
5661
]
5762
]
5863
pop
59-
Label_2:
60-
LINE 3 -> Label_2
64+
Label_4:
65+
LINE 4 -> Label_4
6166
ldc "World" // type: java.lang.String
6267
invokedynamic helloWorld(java.lang.String)java.lang.String [
6368
// Bootstrap method
@@ -67,10 +72,11 @@ public class fullName.IndyTest_Generated extends java.lang.Object {
6772
]
6873
]
6974
areturn
70-
Label_3:
75+
Label_5:
7176
LocalVariables {
72-
index: 1, name: x, start: Label_0, end: Label_3, type: int, signature: null
73-
index: 0, name: this, start: Label_0, end: Label_3, type: fullName.IndyTest_Generated, signature: null
77+
index: 2, name: a, start: Label_2, end: Label_5, type: java.lang.String, signature: null
78+
index: 1, name: x, start: Label_0, end: Label_5, type: int, signature: null
79+
index: 0, name: this, start: Label_0, end: Label_5, type: fullName.IndyTest_Generated, signature: null
7480
}
7581
}
7682

0 commit comments

Comments
 (0)