JVM: inline (!) some DescriptorAsmUtils methods into the inliner
Easier to work with it that way
This commit is contained in:
+25
-37
@@ -22,10 +22,8 @@ import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import java.util.*
|
||||
@@ -44,7 +42,6 @@ class AnonymousObjectTransformer(
|
||||
private var constructor: MethodNode? = null
|
||||
private lateinit var sourceMap: SMAP
|
||||
private lateinit var sourceMapper: SourceMapper
|
||||
private val languageVersionSettings = inliningContext.state.languageVersionSettings
|
||||
|
||||
// TODO: use IrTypeMapper in the IR backend
|
||||
private val typeMapper: KotlinTypeMapperBase = state.typeMapper
|
||||
@@ -107,7 +104,7 @@ class AnonymousObjectTransformer(
|
||||
return if (isCapturedFieldName(name)) {
|
||||
null
|
||||
} else {
|
||||
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
|
||||
classBuilder.newField(NO_ORIGIN, access, name, desc, signature, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,29 +346,9 @@ class AnonymousObjectTransformer(
|
||||
parentRemapper: FieldRemapper,
|
||||
constructorAdditionalFakeParams: List<CapturedParamInfo>
|
||||
) {
|
||||
val descTypes = ArrayList<Type>()
|
||||
|
||||
val constructorParams = constructorInlineBuilder.buildParameters()
|
||||
val capturedIndexes = IntArray(constructorParams.parameters.size)
|
||||
var index = 0
|
||||
var size = 0
|
||||
|
||||
//complex processing cause it could have super constructor call params
|
||||
for (info in constructorParams) {
|
||||
if (!info.isSkipped) { //not inlined
|
||||
if (info.isCaptured || info is CapturedParamInfo) {
|
||||
capturedIndexes[index] = size
|
||||
index++
|
||||
}
|
||||
|
||||
if (size != 0) { //skip this
|
||||
descTypes.add(info.type)
|
||||
}
|
||||
size += info.type.size
|
||||
}
|
||||
}
|
||||
|
||||
val constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *descTypes.toTypedArray())
|
||||
val constructorParamTypes = constructorParams.filter { !it.isSkipped }.map { it.type }.drop(1)
|
||||
val constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *constructorParamTypes.toTypedArray())
|
||||
//TODO for inline method make public class
|
||||
transformationInfo.newConstructorDescriptor = constructorDescriptor
|
||||
val constructorVisitor = classBuilder.newMethod(
|
||||
@@ -380,14 +357,28 @@ class AnonymousObjectTransformer(
|
||||
|
||||
val newBodyStartLabel = Label()
|
||||
constructorVisitor.visitLabel(newBodyStartLabel)
|
||||
//initialize captured fields
|
||||
val newFieldsWithSkipped = getNewFieldsToGenerate(allCapturedBuilder.listCaptured())
|
||||
val fieldInfoWithSkipped = transformToFieldInfo(Type.getObjectType(transformationInfo.newClassName), newFieldsWithSkipped)
|
||||
|
||||
val capturedFieldInitializer = InstructionAdapter(constructorVisitor)
|
||||
fieldInfoWithSkipped.forEachIndexed { paramIndex, fieldInfo ->
|
||||
if (!newFieldsWithSkipped[paramIndex].skip) {
|
||||
DescriptorAsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer)
|
||||
//initialize captured fields
|
||||
val capturedIndexes = IntArray(constructorParams.parameters.size)
|
||||
var index = 0
|
||||
var size = 0
|
||||
for (info in constructorParams) {
|
||||
if (!info.isSkipped) { //not inlined
|
||||
if (info.isCaptured || info is CapturedParamInfo) {
|
||||
capturedIndexes[index] = size
|
||||
index++
|
||||
}
|
||||
size += info.type.size
|
||||
}
|
||||
}
|
||||
for ((paramIndex, info) in allCapturedBuilder.listCaptured().filter { it.functionalArgument !is LambdaInfo }.withIndex()) {
|
||||
if (!info.isSkipInConstructor) {
|
||||
val desc = info.type.descriptor
|
||||
val access = AsmUtil.NO_FLAG_PACKAGE_PRIVATE or Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL
|
||||
classBuilder.newField(NO_ORIGIN, access, info.newFieldName, desc, null, null)
|
||||
constructorVisitor.visitVarInsn(Opcodes.ALOAD, 0)
|
||||
constructorVisitor.visitVarInsn(info.type.getOpcode(Opcodes.ILOAD), capturedIndexes[paramIndex])
|
||||
constructorVisitor.visitFieldInsn(Opcodes.PUTFIELD, transformationInfo.newClassName, info.newFieldName, desc)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +408,7 @@ class AnonymousObjectTransformer(
|
||||
|
||||
val first = intermediateMethodNode.instructions.first
|
||||
val oldStartLabel = (first as? LabelNode)?.label
|
||||
intermediateMethodNode.accept(object : MethodBodyVisitor(capturedFieldInitializer) {
|
||||
intermediateMethodNode.accept(object : MethodBodyVisitor(constructorVisitor) {
|
||||
override fun visitLocalVariable(
|
||||
name: String, desc: String, signature: String?, start: Label, end: Label, index: Int
|
||||
) {
|
||||
@@ -430,9 +421,6 @@ class AnonymousObjectTransformer(
|
||||
}
|
||||
})
|
||||
constructorVisitor.visitEnd()
|
||||
DescriptorAsmUtil.genClosureFields(
|
||||
toNameTypePair(filterSkipped(newFieldsWithSkipped)), classBuilder
|
||||
)
|
||||
}
|
||||
|
||||
private fun getMethodParametersWithCaptured(capturedBuilder: ParametersBuilder, sourceNode: MethodNode): Parameters {
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.openapi.util.Pair
|
||||
import org.jetbrains.kotlin.codegen.FieldInfo
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class NewJavaField(val name: String, val type: Type, val skip: Boolean)
|
||||
|
||||
fun getNewFieldsToGenerate(params: List<CapturedParamInfo>): List<NewJavaField> {
|
||||
return params.filter {
|
||||
//not inlined
|
||||
it.functionalArgument !is LambdaInfo
|
||||
}.map {
|
||||
NewJavaField(it.newFieldName, it.type, it.isSkipInConstructor)
|
||||
}
|
||||
}
|
||||
|
||||
fun transformToFieldInfo(lambdaType: Type, newFields: List<NewJavaField>): List<FieldInfo> {
|
||||
return newFields.map { field ->
|
||||
FieldInfo.createForHiddenField(lambdaType, field.type, field.name)
|
||||
}
|
||||
}
|
||||
|
||||
fun filterSkipped(fields: List<NewJavaField>): List<NewJavaField> {
|
||||
return fields.filter { !it.skip }
|
||||
}
|
||||
|
||||
fun toNameTypePair(fields: List<NewJavaField>): List<Pair<String, Type>> = fields.map { Pair(it.name, it.type) }
|
||||
Reference in New Issue
Block a user