Minor. Reformat code
This commit is contained in:
+15
-22
@@ -83,8 +83,7 @@ class AnonymousObjectTransformer(
|
|||||||
throw RuntimeException("Lambda, SAM or anonymous object should have only one constructor")
|
throw RuntimeException("Lambda, SAM or anonymous object should have only one constructor")
|
||||||
}
|
}
|
||||||
constructor = node
|
constructor = node
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
methodsToTransform.add(node)
|
methodsToTransform.add(node)
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
@@ -94,8 +93,7 @@ class AnonymousObjectTransformer(
|
|||||||
addUniqueField(name)
|
addUniqueField(name)
|
||||||
return if (isCapturedFieldName(name)) {
|
return if (isCapturedFieldName(name)) {
|
||||||
null
|
null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
|
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,16 +109,14 @@ class AnonymousObjectTransformer(
|
|||||||
if (!inliningContext.isInliningLambda) {
|
if (!inliningContext.isInliningLambda) {
|
||||||
sourceMapper = if (debugInfo != null && !debugInfo!!.isEmpty()) {
|
sourceMapper = if (debugInfo != null && !debugInfo!!.isEmpty()) {
|
||||||
SourceMapper.createFromSmap(SMAPParser.parse(debugInfo!!))
|
SourceMapper.createFromSmap(SMAPParser.parse(debugInfo!!))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//seems we can't do any clever mapping cause we don't know any about original class name
|
//seems we can't do any clever mapping cause we don't know any about original class name
|
||||||
IdenticalSourceMapper
|
IdenticalSourceMapper
|
||||||
}
|
}
|
||||||
if (sourceInfo != null && !GENERATE_SMAP) {
|
if (sourceInfo != null && !GENERATE_SMAP) {
|
||||||
classBuilder.visitSource(sourceInfo!!, debugInfo)
|
classBuilder.visitSource(sourceInfo!!, debugInfo)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (sourceInfo != null) {
|
if (sourceInfo != null) {
|
||||||
classBuilder.visitSource(sourceInfo!!, debugInfo)
|
classBuilder.visitSource(sourceInfo!!, debugInfo)
|
||||||
}
|
}
|
||||||
@@ -172,8 +168,7 @@ class AnonymousObjectTransformer(
|
|||||||
SourceMapper.flushToClassBuilder(sourceMapper, classBuilder)
|
SourceMapper.flushToClassBuilder(sourceMapper, classBuilder)
|
||||||
|
|
||||||
val visitor = classBuilder.visitor
|
val visitor = classBuilder.visitor
|
||||||
innerClassNodes.forEach {
|
innerClassNodes.forEach { node ->
|
||||||
node ->
|
|
||||||
visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access)
|
visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +253,8 @@ class AnonymousObjectTransformer(
|
|||||||
isConstructor: Boolean
|
isConstructor: Boolean
|
||||||
): InlineResult {
|
): InlineResult {
|
||||||
val typeParametersToReify = inliningContext.root.inlineMethodReifier.reifyInstructions(sourceNode)
|
val typeParametersToReify = inliningContext.root.inlineMethodReifier.reifyInstructions(sourceNode)
|
||||||
val parameters = if (isConstructor) capturedBuilder.buildParameters() else getMethodParametersWithCaptured(capturedBuilder, sourceNode)
|
val parameters =
|
||||||
|
if (isConstructor) capturedBuilder.buildParameters() else getMethodParametersWithCaptured(capturedBuilder, sourceNode)
|
||||||
|
|
||||||
val remapper = RegeneratedLambdaFieldRemapper(
|
val remapper = RegeneratedLambdaFieldRemapper(
|
||||||
oldObjectType.internalName, transformationInfo.newClassName, parameters,
|
oldObjectType.internalName, transformationInfo.newClassName, parameters,
|
||||||
@@ -420,8 +416,7 @@ class AnonymousObjectTransformer(
|
|||||||
//load captured parameters and patch instruction list
|
//load captured parameters and patch instruction list
|
||||||
// NB: there is also could be object fields
|
// NB: there is also could be object fields
|
||||||
val toDelete = arrayListOf<AbstractInsnNode>()
|
val toDelete = arrayListOf<AbstractInsnNode>()
|
||||||
constructor.findCapturedFieldAssignmentInstructions().
|
constructor.findCapturedFieldAssignmentInstructions().forEach { fieldNode ->
|
||||||
forEach { fieldNode ->
|
|
||||||
val fieldName = fieldNode.name
|
val fieldName = fieldNode.name
|
||||||
val parameterAload = fieldNode.previous as VarInsnNode
|
val parameterAload = fieldNode.previous as VarInsnNode
|
||||||
val varIndex = parameterAload.`var`
|
val varIndex = parameterAload.`var`
|
||||||
@@ -456,8 +451,7 @@ class AnonymousObjectTransformer(
|
|||||||
parameterInfo.lambda = info
|
parameterInfo.lambda = info
|
||||||
if (capturedParams.contains(parameterInfo.index)) {
|
if (capturedParams.contains(parameterInfo.index)) {
|
||||||
parameterInfo.isCaptured = true
|
parameterInfo.isCaptured = true
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//otherwise it's super constructor parameter
|
//otherwise it's super constructor parameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +460,8 @@ class AnonymousObjectTransformer(
|
|||||||
//TODO: some of such parameters could be skipped - we should perform additional analysis
|
//TODO: some of such parameters could be skipped - we should perform additional analysis
|
||||||
val capturedLambdasToInline = HashMap<String, LambdaInfo>() //captured var of inlined parameter
|
val capturedLambdasToInline = HashMap<String, LambdaInfo>() //captured var of inlined parameter
|
||||||
val allRecapturedParameters = ArrayList<CapturedParamDesc>()
|
val allRecapturedParameters = ArrayList<CapturedParamDesc>()
|
||||||
val addCapturedNotAddOuter = parentFieldRemapper.isRoot || parentFieldRemapper is InlinedLambdaRemapper && parentFieldRemapper.parent!!.isRoot
|
val addCapturedNotAddOuter =
|
||||||
|
parentFieldRemapper.isRoot || parentFieldRemapper is InlinedLambdaRemapper && parentFieldRemapper.parent!!.isRoot
|
||||||
val alreadyAdded = HashMap<String, CapturedParamInfo>()
|
val alreadyAdded = HashMap<String, CapturedParamInfo>()
|
||||||
for (info in capturedLambdas) {
|
for (info in capturedLambdas) {
|
||||||
if (addCapturedNotAddOuter) {
|
if (addCapturedNotAddOuter) {
|
||||||
@@ -501,8 +496,8 @@ class AnonymousObjectTransformer(
|
|||||||
|
|
||||||
if (parentFieldRemapper is InlinedLambdaRemapper && !capturedLambdas.isEmpty() && !addCapturedNotAddOuter) {
|
if (parentFieldRemapper is InlinedLambdaRemapper && !capturedLambdas.isEmpty() && !addCapturedNotAddOuter) {
|
||||||
//lambda with non InlinedLambdaRemapper already have outer
|
//lambda with non InlinedLambdaRemapper already have outer
|
||||||
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
|
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper
|
||||||
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
|
?: throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
|
||||||
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
|
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
|
||||||
val desc = CapturedParamDesc(ownerType, AsmUtil.THIS, ownerType)
|
val desc = CapturedParamDesc(ownerType, AsmUtil.THIS, ownerType)
|
||||||
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, AsmUtil.CAPTURED_THIS_FIELD/*outer lambda/object*/, false)
|
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, AsmUtil.CAPTURED_THIS_FIELD/*outer lambda/object*/, false)
|
||||||
@@ -522,16 +517,14 @@ class AnonymousObjectTransformer(
|
|||||||
private fun shouldRenameThis0(parentFieldRemapper: FieldRemapper, values: Collection<LambdaInfo>): Boolean {
|
private fun shouldRenameThis0(parentFieldRemapper: FieldRemapper, values: Collection<LambdaInfo>): Boolean {
|
||||||
return if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
return if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
||||||
values.any { it.capturedVars.any { isThis0(it.fieldName) } }
|
values.any { it.capturedVars.any { isThis0(it.fieldName) } }
|
||||||
}
|
} else false
|
||||||
else false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
||||||
if (AsmUtil.CAPTURED_THIS_FIELD == oldName) {
|
if (AsmUtil.CAPTURED_THIS_FIELD == oldName) {
|
||||||
return if (!originalField) {
|
return if (!originalField) {
|
||||||
oldName
|
oldName
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
||||||
addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX)
|
addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -133,8 +133,7 @@ class IntervalMetaInfo<T : SplittableInterval<T>>(private val processor: Coverin
|
|||||||
val split = interval.split(by, keepStart)
|
val split = interval.split(by, keepStart)
|
||||||
if (!keepStart) {
|
if (!keepStart) {
|
||||||
remapStartLabel(split.newPart.startLabel, split.patchedPart)
|
remapStartLabel(split.newPart.startLabel, split.patchedPart)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
remapEndLabel(split.newPart.endLabel, split.patchedPart)
|
remapEndLabel(split.newPart.endLabel, split.patchedPart)
|
||||||
}
|
}
|
||||||
addNewInterval(split.newPart)
|
addNewInterval(split.newPart)
|
||||||
@@ -191,15 +190,16 @@ class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInt
|
|||||||
val oldEnd = endLabel
|
val oldEnd = endLabel
|
||||||
node.end = splitBy.startLabel
|
node.end = splitBy.startLabel
|
||||||
Pair(splitBy.endLabel, oldEnd)
|
Pair(splitBy.endLabel, oldEnd)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val oldStart = startLabel
|
val oldStart = startLabel
|
||||||
node.start = splitBy.endLabel
|
node.start = splitBy.endLabel
|
||||||
Pair(oldStart, splitBy.startLabel)
|
Pair(oldStart, splitBy.startLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return SplitPair(this, LocalVarNodeWrapper(
|
return SplitPair(
|
||||||
|
this, LocalVarNodeWrapper(
|
||||||
LocalVariableNode(node.name, node.desc, node.signature, newPartInterval.first, newPartInterval.second, node.index)
|
LocalVariableNode(node.name, node.desc, node.signature, newPartInterval.first, newPartInterval.second, node.index)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -29,8 +29,10 @@ internal class FictitiousArrayConstructor(arrayClass: ClassDescriptor) : SimpleF
|
|||||||
fun create(arrayConstructor: ConstructorDescriptor): FictitiousArrayConstructor {
|
fun create(arrayConstructor: ConstructorDescriptor): FictitiousArrayConstructor {
|
||||||
val arrayClass = arrayConstructor.constructedClass
|
val arrayClass = arrayConstructor.constructedClass
|
||||||
return FictitiousArrayConstructor(arrayClass).apply {
|
return FictitiousArrayConstructor(arrayClass).apply {
|
||||||
this.initialize(null, null, arrayConstructor.typeParameters, arrayConstructor.valueParameters, arrayClass.defaultType,
|
this.initialize(
|
||||||
Modality.FINAL, Visibilities.PUBLIC)
|
null, null, arrayConstructor.typeParameters, arrayConstructor.valueParameters, arrayClass.defaultType,
|
||||||
|
Modality.FINAL, Visibilities.PUBLIC
|
||||||
|
)
|
||||||
this.isInline = true
|
this.isInline = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ inline fun <K, V> SLRUMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
|
|||||||
val answer = defaultValue()
|
val answer = defaultValue()
|
||||||
put(key, answer)
|
put(key, answer)
|
||||||
answer
|
answer
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-11
@@ -55,7 +55,6 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
if (!(startIns instanceof LabelNode)) {
|
if (!(startIns instanceof LabelNode)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
AbstractInsnNode end = endInsExclusive;
|
AbstractInsnNode end = endInsExclusive;
|
||||||
while (end != startIns && end instanceof LabelNode) {
|
while (end != startIns && end instanceof LabelNode) {
|
||||||
@@ -78,7 +77,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasFinallyBlocks(inlineFunTryBlockInfo)) {
|
if (hasFinallyBlocks(inlineFunTryBlockInfo)) {
|
||||||
new InternalFinallyBlockInliner(inlineFun, inlineFunTryBlockInfo, localVars, finallyParamOffset).processInlineFunFinallyBlocks();
|
new InternalFinallyBlockInliner(inlineFun, inlineFunTryBlockInfo, localVars, finallyParamOffset)
|
||||||
|
.processInlineFunFinallyBlocks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,10 +88,12 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
|
|
||||||
//lambdaTryCatchBlockNodes is number of TryCatchBlockNodes that was inlined with lambdas into function
|
//lambdaTryCatchBlockNodes is number of TryCatchBlockNodes that was inlined with lambdas into function
|
||||||
//due to code generation specific they placed before function TryCatchBlockNodes
|
//due to code generation specific they placed before function TryCatchBlockNodes
|
||||||
private InternalFinallyBlockInliner(@NotNull MethodNode inlineFun,
|
private InternalFinallyBlockInliner(
|
||||||
|
@NotNull MethodNode inlineFun,
|
||||||
@NotNull List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo,
|
@NotNull List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo,
|
||||||
@NotNull List<LocalVarNodeWrapper> localVariableInfo,
|
@NotNull List<LocalVarNodeWrapper> localVariableInfo,
|
||||||
int finallyParamOffset) {
|
int finallyParamOffset
|
||||||
|
) {
|
||||||
super(finallyParamOffset);
|
super(finallyParamOffset);
|
||||||
this.inlineFun = inlineFun;
|
this.inlineFun = inlineFun;
|
||||||
for (TryCatchBlockNodeInfo block : inlineFunTryBlockInfo) {
|
for (TryCatchBlockNodeInfo block : inlineFunTryBlockInfo) {
|
||||||
@@ -166,7 +168,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
List<TryCatchBlockNodeInfo> clusterBlocks = clusterToFindFinally.getBlocks();
|
List<TryCatchBlockNodeInfo> clusterBlocks = clusterToFindFinally.getBlocks();
|
||||||
TryCatchBlockNodeInfo nodeWithDefaultHandlerIfExists = clusterBlocks.get(clusterBlocks.size() - 1);
|
TryCatchBlockNodeInfo nodeWithDefaultHandlerIfExists = clusterBlocks.get(clusterBlocks.size() - 1);
|
||||||
|
|
||||||
FinallyBlockInfo finallyInfo = findFinallyBlockBody(nodeWithDefaultHandlerIfExists, getTryBlocksMetaInfo().getAllIntervals());
|
FinallyBlockInfo finallyInfo =
|
||||||
|
findFinallyBlockBody(nodeWithDefaultHandlerIfExists, getTryBlocksMetaInfo().getAllIntervals());
|
||||||
if (finallyInfo == null) continue;
|
if (finallyInfo == null) continue;
|
||||||
|
|
||||||
if (nodeWithDefaultHandlerIfExists.getOnlyCopyNotProcess()) {
|
if (nodeWithDefaultHandlerIfExists.getOnlyCopyNotProcess()) {
|
||||||
@@ -253,7 +256,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
if (isFinallyMarker(currentIns.getNext())) {
|
if (isFinallyMarker(currentIns.getNext())) {
|
||||||
Integer constant = getConstant(currentIns);
|
Integer constant = getConstant(currentIns);
|
||||||
finallyBlockCopy.visitLdcInsn(constant + depthShift);
|
finallyBlockCopy.visitLdcInsn(constant + depthShift);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
currentIns.accept(finallyBlockCopy); //VISIT
|
currentIns.accept(finallyBlockCopy); //VISIT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,7 +290,9 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private static Set<LabelNode> rememberOriginalLabelNodes(@NotNull FinallyBlockInfo finallyInfo) {
|
private static Set<LabelNode> rememberOriginalLabelNodes(@NotNull FinallyBlockInfo finallyInfo) {
|
||||||
Set<LabelNode> labelsInsideFinally = new HashSet<>();
|
Set<LabelNode> labelsInsideFinally = new HashSet<>();
|
||||||
for (AbstractInsnNode currentIns = finallyInfo.startIns; currentIns != finallyInfo.endInsExclusive; currentIns = currentIns.getNext()) {
|
for (AbstractInsnNode currentIns = finallyInfo.startIns;
|
||||||
|
currentIns != finallyInfo.endInsExclusive;
|
||||||
|
currentIns = currentIns.getNext()) {
|
||||||
if (currentIns instanceof LabelNode) {
|
if (currentIns instanceof LabelNode) {
|
||||||
labelsInsideFinally.add((LabelNode) currentIns);
|
labelsInsideFinally.add((LabelNode) currentIns);
|
||||||
}
|
}
|
||||||
@@ -326,7 +332,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
tryCatchBlockNode.type);
|
tryCatchBlockNode.type);
|
||||||
|
|
||||||
|
|
||||||
assert inlineFun.instructions.indexOf(additionalTryCatchBlock.start) <= inlineFun.instructions.indexOf(additionalTryCatchBlock.end);
|
assert inlineFun.instructions.indexOf(additionalTryCatchBlock.start) <=
|
||||||
|
inlineFun.instructions.indexOf(additionalTryCatchBlock.end);
|
||||||
|
|
||||||
tryBlocksMetaInfo.addNewInterval(new TryCatchBlockNodeInfo(additionalTryCatchBlock, true));
|
tryBlocksMetaInfo.addNewInterval(new TryCatchBlockNodeInfo(additionalTryCatchBlock, true));
|
||||||
}
|
}
|
||||||
@@ -350,7 +357,10 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
TryCatchBlockNodeInfo startNode = startBlockPositions.next().getNodeInfo();
|
TryCatchBlockNodeInfo startNode = startBlockPositions.next().getNodeInfo();
|
||||||
TryCatchBlockNodeInfo endNode = endBlockPosition.getNodeInfo();
|
TryCatchBlockNodeInfo endNode = endBlockPosition.getNodeInfo();
|
||||||
|
|
||||||
assert Objects.equal(startNode.getType(), endNode.getType()) : "Different handler types : " + startNode.getType() + " " + endNode.getType();
|
assert Objects.equal(startNode.getType(), endNode.getType()) : "Different handler types : " +
|
||||||
|
startNode.getType() +
|
||||||
|
" " +
|
||||||
|
endNode.getType();
|
||||||
|
|
||||||
getTryBlocksMetaInfo()
|
getTryBlocksMetaInfo()
|
||||||
.split(endNode, new SimpleInterval((LabelNode) endNode.getNode().end.getLabel().info,
|
.split(endNode, new SimpleInterval((LabelNode) endNode.getNode().end.getLabel().info,
|
||||||
@@ -427,7 +437,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (afterStartBlock) {
|
if (afterStartBlock) {
|
||||||
if (block.getNode().type == null && (firstLabelInChain(tryCatchBlock.getNode().start) == firstLabelInChain(block.getNode().start) &&
|
if (block.getNode().type == null &&
|
||||||
|
(firstLabelInChain(tryCatchBlock.getNode().start) == firstLabelInChain(block.getNode().start) &&
|
||||||
firstLabelInChain(tryCatchBlock.getNode().end) == firstLabelInChain(block.getNode().end)
|
firstLabelInChain(tryCatchBlock.getNode().end) == firstLabelInChain(block.getNode().end)
|
||||||
|| defaultHandler == firstLabelInChain(block.getNode().handler))) {
|
|| defaultHandler == firstLabelInChain(block.getNode().handler))) {
|
||||||
sameDefaultHandler.add(block); //first is tryCatchBlock if no catch clauses
|
sameDefaultHandler.add(block); //first is tryCatchBlock if no catch clauses
|
||||||
@@ -545,5 +556,4 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
String text = getNodeText(inlineFun);
|
String text = getNodeText(inlineFun);
|
||||||
System.out.println(text);
|
System.out.println(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ class LocalVarRemapper(private val params: Parameters, private val additionalShi
|
|||||||
if (!info.isSkippedOrRemapped) {
|
if (!info.isSkippedOrRemapped) {
|
||||||
remapValues[shift] = StackValue.local(realSize, AsmTypes.OBJECT_TYPE)
|
remapValues[shift] = StackValue.local(realSize, AsmTypes.OBJECT_TYPE)
|
||||||
realSize += info.getType().size
|
realSize += info.getType().size
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
remapValues[shift] = if (info.isRemapped) info.remapValue else null
|
remapValues[shift] = if (info.isRemapped) info.remapValue else null
|
||||||
if (CapturedParamInfo.isSynthetic(info)) {
|
if (CapturedParamInfo.isSynthetic(info)) {
|
||||||
realSize += info.getType().size
|
realSize += info.getType().size
|
||||||
@@ -59,12 +58,10 @@ class LocalVarRemapper(private val params: Parameters, private val additionalShi
|
|||||||
}
|
}
|
||||||
if (info.isRemapped) {
|
if (info.isRemapped) {
|
||||||
return RemapInfo(info, remapped, REMAPPED)
|
return RemapInfo(info, remapped, REMAPPED)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
remappedIndex = (remapped as StackValue.Local).index
|
remappedIndex = (remapped as StackValue.Local).index
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//captured params are not used directly in this inlined method, they are used in closure
|
//captured params are not used directly in this inlined method, they are used in closure
|
||||||
//except captured ones for default lambdas, they are generated in default body
|
//except captured ones for default lambdas, they are generated in default body
|
||||||
remappedIndex = actualParamsSize - params.argsSizeOnStack + index
|
remappedIndex = actualParamsSize - params.argsSizeOnStack + index
|
||||||
@@ -115,8 +112,7 @@ class LocalVarRemapper(private val params: Parameters, private val additionalShi
|
|||||||
if (remapInfo.parameterInfo != null && !isStore) {
|
if (remapInfo.parameterInfo != null && !isStore) {
|
||||||
StackValue.coerce(value.type, remapInfo.parameterInfo.type, mv)
|
StackValue.coerce(value.type, remapInfo.parameterInfo.type, mv)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
assert(remapInfo.parameterInfo != null) { "Non local value should have parameter info" }
|
assert(remapInfo.parameterInfo != null) { "Non local value should have parameter info" }
|
||||||
value!!.put(remapInfo.parameterInfo!!.type, mv)
|
value!!.put(remapInfo.parameterInfo!!.type, mv)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,5 +86,4 @@ public class MaxLocalsCalculator extends MethodVisitor {
|
|||||||
maxLocals = nextFreeSlotNumber;
|
maxLocals = nextFreeSlotNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -61,6 +61,7 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class MaxStackFrameSizeAndLocalsCalculator extends MaxLocalsCalculator {
|
public class MaxStackFrameSizeAndLocalsCalculator extends MaxLocalsCalculator {
|
||||||
private static final int[] FRAME_SIZE_CHANGE_BY_OPCODE;
|
private static final int[] FRAME_SIZE_CHANGE_BY_OPCODE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// copy-pasted from org.jetbrains.org.objectweb.asm.Frame
|
// copy-pasted from org.jetbrains.org.objectweb.asm.Frame
|
||||||
int i;
|
int i;
|
||||||
@@ -418,6 +419,7 @@ public class MaxStackFrameSizeAndLocalsCalculator extends MaxLocalsCalculator {
|
|||||||
|
|
||||||
private int outputStackMax = 0;
|
private int outputStackMax = 0;
|
||||||
private int inputStackSize = 0;
|
private int inputStackSize = 0;
|
||||||
|
|
||||||
public LabelWrapper(Label label) {
|
public LabelWrapper(Label label) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,8 +120,7 @@ class MethodInliner(
|
|||||||
visitor
|
visitor
|
||||||
} else MethodBodyVisitor(visitor)
|
} else MethodBodyVisitor(visitor)
|
||||||
)
|
)
|
||||||
}
|
} catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
|
||||||
throw wrapException(e, transformedNode, "couldn't inline method call")
|
throw wrapException(e, transformedNode, "couldn't inline method call")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,8 +202,7 @@ class MethodInliner(
|
|||||||
ReifiedTypeInliner.putNeedClassReificationMarker(mv)
|
ReifiedTypeInliner.putNeedClassReificationMarker(mv)
|
||||||
result.reifiedTypeParametersUsages.mergeAll(transformResult.reifiedTypeParametersUsages)
|
result.reifiedTypeParametersUsages.mergeAll(transformResult.reifiedTypeParametersUsages)
|
||||||
}
|
}
|
||||||
}
|
} else if (!transformationInfo!!.wasAlreadyRegenerated) {
|
||||||
else if (!transformationInfo!!.wasAlreadyRegenerated) {
|
|
||||||
result.addNotChangedClass(oldClassName)
|
result.addNotChangedClass(oldClassName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,8 +288,7 @@ class MethodInliner(
|
|||||||
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||||
else if (info is DefaultLambda) {
|
else if (info is DefaultLambda) {
|
||||||
NestedSourceMapper(sourceMapper.parent!!, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
NestedSourceMapper(sourceMapper.parent!!, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||||
}
|
} else InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
|
||||||
else InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
|
|
||||||
|
|
||||||
val inliner = MethodInliner(
|
val inliner = MethodInliner(
|
||||||
info.node.node, lambdaParameters, inliningContext.subInlineLambda(info),
|
info.node.node, lambdaParameters, inliningContext.subInlineLambda(info),
|
||||||
@@ -315,8 +312,7 @@ class MethodInliner(
|
|||||||
addInlineMarker(this, false)
|
addInlineMarker(this, false)
|
||||||
childSourceMapper.endMapping()
|
childSourceMapper.endMapping()
|
||||||
inlineOnlySmapSkipper?.markCallSiteLineNumber(remappingMethodAdapter)
|
inlineOnlySmapSkipper?.markCallSiteLineNumber(remappingMethodAdapter)
|
||||||
}
|
} else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
|
||||||
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
|
|
||||||
//TODO add proper message
|
//TODO add proper message
|
||||||
assert(transformationInfo is AnonymousObjectTransformationInfo) {
|
assert(transformationInfo is AnonymousObjectTransformationInfo) {
|
||||||
"<init> call doesn't correspond to object transformation info for '$owner.$name': $transformationInfo"
|
"<init> call doesn't correspond to object transformation info for '$owner.$name': $transformationInfo"
|
||||||
@@ -366,16 +362,14 @@ class MethodInliner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
transformationInfo = null
|
transformationInfo = null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
||||||
}
|
}
|
||||||
}
|
} else if ((!inliningContext.isInliningLambda || isDefaultLambdaWithReification(inliningContext.lambdaInfo!!)) &&
|
||||||
else if ((!inliningContext.isInliningLambda || isDefaultLambdaWithReification(inliningContext.lambdaInfo!!)) &&
|
ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))
|
||||||
ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))) {
|
) {
|
||||||
//we shouldn't process here content of inlining lambda it should be reified at external level except default lambdas
|
//we shouldn't process here content of inlining lambda it should be reified at external level except default lambdas
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,18 +451,19 @@ class MethodInliner(
|
|||||||
if (DEFAULT_LAMBDA_FAKE_CALL == owner) {
|
if (DEFAULT_LAMBDA_FAKE_CALL == owner) {
|
||||||
val index = name.substringAfter(DEFAULT_LAMBDA_FAKE_CALL).toInt()
|
val index = name.substringAfter(DEFAULT_LAMBDA_FAKE_CALL).toInt()
|
||||||
val lambda = getLambdaIfExists(index) as DefaultLambda
|
val lambda = getLambdaIfExists(index) as DefaultLambda
|
||||||
lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach {
|
lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach { (_, captured) ->
|
||||||
(_, captured) ->
|
|
||||||
val originalBoundReceiverType = lambda.originalBoundReceiverType
|
val originalBoundReceiverType = lambda.originalBoundReceiverType
|
||||||
if (lambda.isBoundCallableReference && AsmUtil.isPrimitive(originalBoundReceiverType)) {
|
if (lambda.isBoundCallableReference && AsmUtil.isPrimitive(originalBoundReceiverType)) {
|
||||||
StackValue.onStack(originalBoundReceiverType!!).put(captured.type, InstructionAdapter(this))
|
StackValue.onStack(originalBoundReceiverType!!).put(captured.type, InstructionAdapter(this))
|
||||||
}
|
}
|
||||||
super.visitFieldInsn(
|
super.visitFieldInsn(
|
||||||
Opcodes.PUTSTATIC, captured.containingLambdaName, CAPTURED_FIELD_FOLD_PREFIX + captured.fieldName, captured.type.descriptor
|
Opcodes.PUTSTATIC,
|
||||||
|
captured.containingLambdaName,
|
||||||
|
CAPTURED_FIELD_FOLD_PREFIX + captured.fieldName,
|
||||||
|
captured.type.descriptor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,23 +527,21 @@ class MethodInliner(
|
|||||||
val sourceValue = frame.getStack(firstParameterIndex)
|
val sourceValue = frame.getStack(firstParameterIndex)
|
||||||
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, true, instructions, sources, toDelete)
|
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, true, instructions, sources, toDelete)
|
||||||
invokeCalls.add(InvokeCall(lambdaInfo, currentFinallyDeep))
|
invokeCalls.add(InvokeCall(lambdaInfo, currentFinallyDeep))
|
||||||
}
|
} else if (isSamWrapperConstructorCall(owner, name)) {
|
||||||
else if (isSamWrapperConstructorCall(owner, name)) {
|
|
||||||
recordTransformation(SamWrapperTransformationInfo(owner, inliningContext, isAlreadyRegenerated(owner)))
|
recordTransformation(SamWrapperTransformationInfo(owner, inliningContext, isAlreadyRegenerated(owner)))
|
||||||
}
|
} else if (isAnonymousConstructorCall(owner, name)) {
|
||||||
else if (isAnonymousConstructorCall(owner, name)) {
|
|
||||||
val lambdaMapping = HashMap<Int, LambdaInfo>()
|
val lambdaMapping = HashMap<Int, LambdaInfo>()
|
||||||
|
|
||||||
var offset = 0
|
var offset = 0
|
||||||
var capturesAnonymousObjectThatMustBeRegenerated = false
|
var capturesAnonymousObjectThatMustBeRegenerated = false
|
||||||
for (i in 0 until paramCount) {
|
for (i in 0 until paramCount) {
|
||||||
val sourceValue = frame.getStack(firstParameterIndex + i)
|
val sourceValue = frame.getStack(firstParameterIndex + i)
|
||||||
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, false, instructions, sources, toDelete
|
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(
|
||||||
|
sourceValue, false, instructions, sources, toDelete
|
||||||
)
|
)
|
||||||
if (lambdaInfo != null) {
|
if (lambdaInfo != null) {
|
||||||
lambdaMapping.put(offset, lambdaInfo)
|
lambdaMapping.put(offset, lambdaInfo)
|
||||||
}
|
} else if (i < argTypes.size && isAnonymousClassThatMustBeRegenerated(argTypes[i])) {
|
||||||
else if (i < argTypes.size && isAnonymousClassThatMustBeRegenerated(argTypes[i])) {
|
|
||||||
capturesAnonymousObjectThatMustBeRegenerated = true
|
capturesAnonymousObjectThatMustBeRegenerated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,8 +554,7 @@ class MethodInliner(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
awaitClassReification = false
|
awaitClassReification = false
|
||||||
}
|
} else if (inliningContext.isInliningLambda && ReifiedTypeInliner.isOperationReifiedMarker(cur)) {
|
||||||
else if (inliningContext.isInliningLambda && ReifiedTypeInliner.isOperationReifiedMarker(cur)) {
|
|
||||||
val reificationArgument = cur.reificationArgument
|
val reificationArgument = cur.reificationArgument
|
||||||
val parameterName = reificationArgument!!.parameterName
|
val parameterName = reificationArgument!!.parameterName
|
||||||
result.reifiedTypeParametersUsages.addUsedReifiedParameter(parameterName)
|
result.reifiedTypeParametersUsages.addUsedReifiedParameter(parameterName)
|
||||||
@@ -580,8 +572,7 @@ class MethodInliner(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
awaitClassReification = false
|
awaitClassReification = false
|
||||||
}
|
} else if (isWhenMappingAccess(className, fieldInsnNode.name)) {
|
||||||
else if (isWhenMappingAccess(className, fieldInsnNode.name)) {
|
|
||||||
recordTransformation(
|
recordTransformation(
|
||||||
WhenMappingTransformationInfo(
|
WhenMappingTransformationInfo(
|
||||||
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
|
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
|
||||||
@@ -590,7 +581,13 @@ class MethodInliner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur.opcode == Opcodes.POP -> getLambdaIfExistsAndMarkInstructions(frame.top()!!, true, instructions, sources, toDelete)?.let {
|
cur.opcode == Opcodes.POP -> getLambdaIfExistsAndMarkInstructions(
|
||||||
|
frame.top()!!,
|
||||||
|
true,
|
||||||
|
instructions,
|
||||||
|
sources,
|
||||||
|
toDelete
|
||||||
|
)?.let {
|
||||||
toDelete.add(cur)
|
toDelete.add(cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,9 +602,11 @@ class MethodInliner(
|
|||||||
val fieldInsn = cur as FieldInsnNode
|
val fieldInsn = cur as FieldInsnNode
|
||||||
if (isCapturedFieldName(fieldInsn.name) &&
|
if (isCapturedFieldName(fieldInsn.name) &&
|
||||||
nodeRemapper is InlinedLambdaRemapper &&
|
nodeRemapper is InlinedLambdaRemapper &&
|
||||||
nodeRemapper.originalLambdaInternalName == fieldInsn.owner) {
|
nodeRemapper.originalLambdaInternalName == fieldInsn.owner
|
||||||
|
) {
|
||||||
val stackTransformations = mutableSetOf<AbstractInsnNode>()
|
val stackTransformations = mutableSetOf<AbstractInsnNode>()
|
||||||
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(frame.peek(1)!!, false, instructions, sources, stackTransformations)
|
val lambdaInfo =
|
||||||
|
getLambdaIfExistsAndMarkInstructions(frame.peek(1)!!, false, instructions, sources, stackTransformations)
|
||||||
if (lambdaInfo != null && stackTransformations.all { it is VarInsnNode }) {
|
if (lambdaInfo != null && stackTransformations.all { it is VarInsnNode }) {
|
||||||
assert(lambdaInfo.lambdaClassType.internalName == nodeRemapper.originalLambdaInternalName) {
|
assert(lambdaInfo.lambdaClassType.internalName == nodeRemapper.originalLambdaInternalName) {
|
||||||
"Wrong bytecode template for contract template: ${lambdaInfo.lambdaClassType.internalName} != ${nodeRemapper.originalLambdaInternalName}"
|
"Wrong bytecode template for contract template: ${lambdaInfo.lambdaClassType.internalName} != ${nodeRemapper.originalLambdaInternalName}"
|
||||||
@@ -619,16 +618,14 @@ class MethodInliner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//given frame is <tt>null</tt> if and only if the corresponding instruction cannot be reached (dead code).
|
//given frame is <tt>null</tt> if and only if the corresponding instruction cannot be reached (dead code).
|
||||||
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
|
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
|
||||||
if (cur.type == AbstractInsnNode.LABEL) {
|
if (cur.type == AbstractInsnNode.LABEL) {
|
||||||
//NB: Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
|
//NB: Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
|
||||||
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
|
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
|
||||||
//but as result all this labels will be merged into one (see KT-5863)
|
//but as result all this labels will be merged into one (see KT-5863)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
toDelete.add(cur)
|
toDelete.add(cur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -758,8 +755,7 @@ class MethodInliner(
|
|||||||
private fun preprocessNodeBeforeInline(node: MethodNode, labelOwner: LabelOwner) {
|
private fun preprocessNodeBeforeInline(node: MethodNode, labelOwner: LabelOwner) {
|
||||||
try {
|
try {
|
||||||
FixStackWithLabelNormalizationMethodTransformer().transform("fake", node)
|
FixStackWithLabelNormalizationMethodTransformer().transform("fake", node)
|
||||||
}
|
} catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
|
||||||
throw wrapException(e, node, "couldn't inline method call")
|
throw wrapException(e, node, "couldn't inline method call")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -911,8 +907,7 @@ class MethodInliner(
|
|||||||
private fun wrapException(originalException: Throwable, node: MethodNode, errorSuffix: String): RuntimeException {
|
private fun wrapException(originalException: Throwable, node: MethodNode, errorSuffix: String): RuntimeException {
|
||||||
return if (originalException is InlineException) {
|
return if (originalException is InlineException) {
|
||||||
InlineException("$errorPrefix: $errorSuffix", originalException)
|
InlineException("$errorPrefix: $errorSuffix", originalException)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
InlineException("$errorPrefix: $errorSuffix\nCause: ${node.nodeText}", originalException)
|
InlineException("$errorPrefix: $errorSuffix\nCause: ${node.nodeText}", originalException)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -971,8 +966,7 @@ class MethodInliner(
|
|||||||
if (returnInsn.opcode != Opcodes.RETURN) {
|
if (returnInsn.opcode != Opcodes.RETURN) {
|
||||||
returnVariableSize = if (returnInsn.opcode == Opcodes.LRETURN || returnInsn.opcode == Opcodes.DRETURN) {
|
returnVariableSize = if (returnInsn.opcode == Opcodes.LRETURN || returnInsn.opcode == Opcodes.DRETURN) {
|
||||||
2
|
2
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1028,8 +1022,7 @@ class MethodInliner(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
return analyzer.analyze("fake", node)
|
return analyzer.analyze("fake", node)
|
||||||
}
|
} catch (e: AnalyzerException) {
|
||||||
catch (e: AnalyzerException) {
|
|
||||||
throw RuntimeException(e)
|
throw RuntimeException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,8 +1034,7 @@ class MethodInliner(
|
|||||||
// INTRINSICS_CLASS_NAME.checkParameterIsNotNull(...)
|
// INTRINSICS_CLASS_NAME.checkParameterIsNotNull(...)
|
||||||
private fun removeClosureAssertions(node: MethodNode) {
|
private fun removeClosureAssertions(node: MethodNode) {
|
||||||
val toDelete = arrayListOf<AbstractInsnNode>()
|
val toDelete = arrayListOf<AbstractInsnNode>()
|
||||||
InsnSequence(node.instructions).filterIsInstance<MethodInsnNode>().forEach {
|
InsnSequence(node.instructions).filterIsInstance<MethodInsnNode>().forEach { methodInsnNode ->
|
||||||
methodInsnNode ->
|
|
||||||
if (methodInsnNode.name == "checkParameterIsNotNull" && methodInsnNode.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME) {
|
if (methodInsnNode.name == "checkParameterIsNotNull" && methodInsnNode.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME) {
|
||||||
val prev = methodInsnNode.previous
|
val prev = methodInsnNode.previous
|
||||||
assert(Opcodes.LDC == prev?.opcode) { "'checkParameterIsNotNull' should go after LDC but $prev" }
|
assert(Opcodes.LDC == prev?.opcode) { "'checkParameterIsNotNull' should go after LDC but $prev" }
|
||||||
@@ -1077,8 +1069,7 @@ class MethodInliner(
|
|||||||
|
|
||||||
private fun getCapturedFieldAccessChain(aload0: VarInsnNode): List<AbstractInsnNode> {
|
private fun getCapturedFieldAccessChain(aload0: VarInsnNode): List<AbstractInsnNode> {
|
||||||
val lambdaAccessChain = mutableListOf<AbstractInsnNode>(aload0).apply {
|
val lambdaAccessChain = mutableListOf<AbstractInsnNode>(aload0).apply {
|
||||||
addAll(InsnSequence(aload0.next, null).filter { it.isMeaningful }.takeWhile {
|
addAll(InsnSequence(aload0.next, null).filter { it.isMeaningful }.takeWhile { insnNode ->
|
||||||
insnNode ->
|
|
||||||
insnNode is FieldInsnNode && "this$0" == insnNode.name
|
insnNode is FieldInsnNode && "this$0" == insnNode.name
|
||||||
}.toList())
|
}.toList())
|
||||||
}
|
}
|
||||||
@@ -1086,7 +1077,8 @@ class MethodInliner(
|
|||||||
return lambdaAccessChain.apply {
|
return lambdaAccessChain.apply {
|
||||||
last().getNextMeaningful().takeIf { insn -> insn is FieldInsnNode }?.also {
|
last().getNextMeaningful().takeIf { insn -> insn is FieldInsnNode }?.also {
|
||||||
//captured field access
|
//captured field access
|
||||||
insn -> add(insn)
|
insn ->
|
||||||
|
add(insn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1170,9 +1162,11 @@ class MethodInliner(
|
|||||||
//generate finally block before nonLocalReturn flag/return/goto
|
//generate finally block before nonLocalReturn flag/return/goto
|
||||||
val label = LabelNode()
|
val label = LabelNode()
|
||||||
instructions.insert(insnNode, label)
|
instructions.insert(insnNode, label)
|
||||||
result.add(PointForExternalFinallyBlocks(
|
result.add(
|
||||||
|
PointForExternalFinallyBlocks(
|
||||||
getInstructionToInsertFinallyBefore(insnNode, isLocalReturn), getReturnType(insnNode.opcode), label
|
getInstructionToInsertFinallyBefore(insnNode, isLocalReturn), getReturnType(insnNode.opcode), label
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
insnNode = insnNode.next
|
insnNode = insnNode.next
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ private fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
|
|||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (processSwap && insnNode.opcode == Opcodes.SWAP) {
|
||||||
else if (processSwap && insnNode.opcode == Opcodes.SWAP) {
|
|
||||||
val swapFrame = frames[insnList.indexOf(insnNode)] ?: return null
|
val swapFrame = frames[insnList.indexOf(insnNode)] ?: return null
|
||||||
val dispatchReceiver = swapFrame.top()!!
|
val dispatchReceiver = swapFrame.top()!!
|
||||||
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete)?.let {
|
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete)?.let {
|
||||||
@@ -111,8 +110,7 @@ fun MethodNode.remove(instructions: Collection<AbstractInsnNode>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun MethodNode.findCapturedFieldAssignmentInstructions(): Sequence<FieldInsnNode> {
|
fun MethodNode.findCapturedFieldAssignmentInstructions(): Sequence<FieldInsnNode> {
|
||||||
return InsnSequence(instructions).filterIsInstance<FieldInsnNode>().
|
return InsnSequence(instructions).filterIsInstance<FieldInsnNode>().filter { fieldNode ->
|
||||||
filter { fieldNode ->
|
|
||||||
//filter captured field assignment
|
//filter captured field assignment
|
||||||
// aload 0
|
// aload 0
|
||||||
// aload x
|
// aload x
|
||||||
|
|||||||
@@ -28,10 +28,12 @@ class ParametersBuilder private constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
|
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
|
||||||
return addParameter(ParameterInfo(
|
return addParameter(
|
||||||
|
ParameterInfo(
|
||||||
type, skipped, nextParameterOffset, remapValue,
|
type, skipped, nextParameterOffset, remapValue,
|
||||||
if (parameterIndex == -1) nextValueParameterIndex else parameterIndex + valueParamFirstIndex
|
if (parameterIndex == -1) nextValueParameterIndex else parameterIndex + valueParamFirstIndex
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCapturedParam(original: CapturedParamInfo, newFieldName: String): CapturedParamInfo {
|
fun addCapturedParam(original: CapturedParamInfo, newFieldName: String): CapturedParamInfo {
|
||||||
@@ -94,8 +96,7 @@ class ParametersBuilder private constructor() {
|
|||||||
return Parameters(params.map { param ->
|
return Parameters(params.map { param ->
|
||||||
if (param is CapturedParamInfo) {
|
if (param is CapturedParamInfo) {
|
||||||
param.cloneWithNewDeclarationIndex(nextDeclarationIndex++)
|
param.cloneWithNewDeclarationIndex(nextDeclarationIndex++)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
param
|
param
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
|||||||
|
|
||||||
class PropertyReferenceInfo(
|
class PropertyReferenceInfo(
|
||||||
val target: VariableDescriptor,
|
val target: VariableDescriptor,
|
||||||
val getFunction: FunctionDescriptor)
|
val getFunction: FunctionDescriptor
|
||||||
|
)
|
||||||
+4
-3
@@ -66,11 +66,12 @@ class RegeneratedLambdaFieldRemapper(
|
|||||||
var fromParent = false
|
var fromParent = false
|
||||||
val field = findFieldInSuper(fin) ?:
|
val field = findFieldInSuper(fin) ?:
|
||||||
//search in parent
|
//search in parent
|
||||||
findFieldInSuper(FieldInsnNode(
|
findFieldInSuper(
|
||||||
|
FieldInsnNode(
|
||||||
Opcodes.GETSTATIC, originalLambdaInternalName, AsmUtil.CAPTURED_THIS_FIELD,
|
Opcodes.GETSTATIC, originalLambdaInternalName, AsmUtil.CAPTURED_THIS_FIELD,
|
||||||
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
|
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
|
||||||
))?.also { fromParent = true } ?:
|
)
|
||||||
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
|
)?.also { fromParent = true } ?: throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
|
||||||
|
|
||||||
|
|
||||||
val result = StackValue.field(
|
val result = StackValue.field(
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ class ReificationArgument(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun reify(replacementAsmType: Type, kotlinType: KotlinType) =
|
fun reify(replacementAsmType: Type, kotlinType: KotlinType) =
|
||||||
Pair(Type.getType("[".repeat(arrayDepth) + replacementAsmType), TypeUtils.makeNullableIfNeeded(kotlinType.arrayOf(arrayDepth), nullable))
|
Pair(
|
||||||
|
Type.getType("[".repeat(arrayDepth) + replacementAsmType),
|
||||||
|
TypeUtils.makeNullableIfNeeded(kotlinType.arrayOf(arrayDepth), nullable)
|
||||||
|
)
|
||||||
|
|
||||||
private fun KotlinType.arrayOf(arrayDepth: Int): KotlinType {
|
private fun KotlinType.arrayOf(arrayDepth: Int): KotlinType {
|
||||||
val builtins = this.builtIns
|
val builtins = this.builtIns
|
||||||
@@ -140,15 +143,15 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?,
|
|||||||
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
||||||
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
||||||
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
|
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
|
||||||
}) {
|
}
|
||||||
|
) {
|
||||||
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
||||||
instructions.remove(insn.previous!!) // PUSH type parameter
|
instructions.remove(insn.previous!!) // PUSH type parameter
|
||||||
instructions.remove(insn) // INVOKESTATIC marker method
|
instructions.remove(insn) // INVOKESTATIC marker method
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val newReificationArgument = reificationArgument.combine(mapping.reificationArgument!!)
|
val newReificationArgument = reificationArgument.combine(mapping.reificationArgument!!)
|
||||||
instructions.set(insn.previous!!, LdcInsnNode(newReificationArgument.asString()))
|
instructions.set(insn.previous!!, LdcInsnNode(newReificationArgument.asString()))
|
||||||
return mapping.reificationArgument.parameterName
|
return mapping.reificationArgument.parameterName
|
||||||
@@ -232,8 +235,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?,
|
|||||||
next3.desc = getSpecialEnumFunDescriptor(parameter, true)
|
next3.desc = getSpecialEnumFunDescriptor(parameter, true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
} else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) {
|
||||||
else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) {
|
|
||||||
instructions.remove(next1)
|
instructions.remove(next1)
|
||||||
instructions.remove(next2)
|
instructions.remove(next2)
|
||||||
val desc = getSpecialEnumFunDescriptor(parameter, false)
|
val desc = getSpecialEnumFunDescriptor(parameter, false)
|
||||||
@@ -261,7 +263,8 @@ val MethodInsnNode.reificationArgument: ReificationArgument?
|
|||||||
return ReificationArgument(parameterName, nullable, arrayDepth)
|
return ReificationArgument(parameterName, nullable, arrayDepth)
|
||||||
}
|
}
|
||||||
|
|
||||||
val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
|
val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind?
|
||||||
|
get() =
|
||||||
previous?.previous?.intConstant?.let {
|
previous?.previous?.intConstant?.let {
|
||||||
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||||
}
|
}
|
||||||
@@ -275,7 +278,12 @@ class TypeParameterMappings() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addParameterMappingForFurtherReification(name: String, type: KotlinType, reificationArgument: ReificationArgument, isReified: Boolean) {
|
fun addParameterMappingForFurtherReification(
|
||||||
|
name: String,
|
||||||
|
type: KotlinType,
|
||||||
|
reificationArgument: ReificationArgument,
|
||||||
|
isReified: Boolean
|
||||||
|
) {
|
||||||
mappingsByName[name] = TypeParameterMapping(
|
mappingsByName[name] = TypeParameterMapping(
|
||||||
name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified
|
name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
|
|||||||
@NotNull String superName,
|
@NotNull String superName,
|
||||||
@NotNull String[] interfaces
|
@NotNull String[] interfaces
|
||||||
) {
|
) {
|
||||||
super.defineClass(origin, version, access, remapper.mapType(name), remapper.mapSignature(signature, false), remapper.mapType(superName), remapper.mapTypes(interfaces));
|
super.defineClass(origin, version, access, remapper.mapType(name), remapper.mapSignature(signature, false),
|
||||||
|
remapper.mapType(superName), remapper.mapTypes(interfaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) {
|
|||||||
|
|
||||||
private fun createLineNumberSequence(node: MethodNode, classSMAP: SMAP): Sequence<RangeMapping> {
|
private fun createLineNumberSequence(node: MethodNode, classSMAP: SMAP): Sequence<RangeMapping> {
|
||||||
return InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map { lineNumber ->
|
return InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map { lineNumber ->
|
||||||
val index = classSMAP.intervals.binarySearch(RangeMapping(lineNumber.line, lineNumber.line, 1), Comparator {
|
val index = classSMAP.intervals.binarySearch(RangeMapping(lineNumber.line, lineNumber.line, 1), Comparator { value, key ->
|
||||||
value, key ->
|
|
||||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||||
})
|
})
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ import org.jetbrains.org.objectweb.asm.ClassReader
|
|||||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
|
||||||
class SamWrapperTransformationInfo(override val oldClassName: String, private val inliningContext: InliningContext, private val alreadyRegenerated: Boolean): TransformationInfo {
|
class SamWrapperTransformationInfo(
|
||||||
|
override val oldClassName: String,
|
||||||
|
private val inliningContext: InliningContext,
|
||||||
|
private val alreadyRegenerated: Boolean
|
||||||
|
) : TransformationInfo {
|
||||||
override val nameGenerator: NameGenerator
|
override val nameGenerator: NameGenerator
|
||||||
get() = object : NameGenerator("stub") {
|
get() = object : NameGenerator("stub") {
|
||||||
override fun getGeneratorClass(): String {
|
override fun getGeneratorClass(): String {
|
||||||
|
|||||||
@@ -52,7 +52,11 @@ class WhenMappingTransformationInfo(
|
|||||||
|
|
||||||
override fun canRemoveAfterTransformation(): Boolean = true
|
override fun canRemoveAfterTransformation(): Boolean = true
|
||||||
|
|
||||||
override fun createTransformer(inliningContext: InliningContext, sameModule: Boolean, continuationClassName: String?): ObjectTransformer<*> =
|
override fun createTransformer(
|
||||||
|
inliningContext: InliningContext,
|
||||||
|
sameModule: Boolean,
|
||||||
|
continuationClassName: String?
|
||||||
|
): ObjectTransformer<*> =
|
||||||
WhenMappingTransformer(this, inliningContext)
|
WhenMappingTransformer(this, inliningContext)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ class TryCatchBlockNodeInfo(
|
|||||||
val oldEnd = endLabel
|
val oldEnd = endLabel
|
||||||
node.end = splitBy.startLabel
|
node.end = splitBy.startLabel
|
||||||
Pair(splitBy.endLabel, oldEnd)
|
Pair(splitBy.endLabel, oldEnd)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val oldStart = startLabel
|
val oldStart = startLabel
|
||||||
node.start = splitBy.endLabel
|
node.start = splitBy.endLabel
|
||||||
Pair(oldStart, splitBy.startLabel)
|
Pair(oldStart, splitBy.startLabel)
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ private data class Condition(
|
|||||||
val varIndex = varInsNode?.`var` ?: 0
|
val varIndex = varInsNode?.`var` ?: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun extractDefaultLambdaOffsetAndDescriptor(jvmSignature: JvmMethodSignature, functionDescriptor: FunctionDescriptor): Map<Int, ValueParameterDescriptor> {
|
fun extractDefaultLambdaOffsetAndDescriptor(
|
||||||
|
jvmSignature: JvmMethodSignature,
|
||||||
|
functionDescriptor: FunctionDescriptor
|
||||||
|
): Map<Int, ValueParameterDescriptor> {
|
||||||
val valueParameters = jvmSignature.valueParameters
|
val valueParameters = jvmSignature.valueParameters
|
||||||
val containingDeclaration = functionDescriptor.containingDeclaration
|
val containingDeclaration = functionDescriptor.containingDeclaration
|
||||||
val kind =
|
val kind =
|
||||||
@@ -74,8 +77,7 @@ fun expandMaskConditionsAndUpdateVariableNodes(
|
|||||||
if (isMaskIndex(it.`var`)) {
|
if (isMaskIndex(it.`var`)) {
|
||||||
/*if slot for default mask is updated than we occurred in actual function body*/
|
/*if slot for default mask is updated than we occurred in actual function body*/
|
||||||
return@takeWhile it.opcode == Opcodes.ILOAD
|
return@takeWhile it.opcode == Opcodes.ILOAD
|
||||||
}
|
} else if (methodHandlerIndex == it.`var`) {
|
||||||
else if (methodHandlerIndex == it.`var`) {
|
|
||||||
return@takeWhile it.opcode == Opcodes.ALOAD
|
return@takeWhile it.opcode == Opcodes.ALOAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,8 @@ fun expandMaskConditionsAndUpdateVariableNodes(
|
|||||||
val conditions = maskProcessingHeader.filterIsInstance<VarInsnNode>().mapNotNull {
|
val conditions = maskProcessingHeader.filterIsInstance<VarInsnNode>().mapNotNull {
|
||||||
if (isMaskIndex(it.`var`) &&
|
if (isMaskIndex(it.`var`) &&
|
||||||
it.next?.next?.opcode == Opcodes.IAND &&
|
it.next?.next?.opcode == Opcodes.IAND &&
|
||||||
it.next.next.next?.opcode == Opcodes.IFEQ) {
|
it.next.next.next?.opcode == Opcodes.IFEQ
|
||||||
|
) {
|
||||||
val jumpInstruction = it.next?.next?.next as JumpInsnNode
|
val jumpInstruction = it.next?.next?.next as JumpInsnNode
|
||||||
Condition(
|
Condition(
|
||||||
masks[it.`var` - maskStartIndex],
|
masks[it.`var` - maskStartIndex],
|
||||||
@@ -94,15 +97,14 @@ fun expandMaskConditionsAndUpdateVariableNodes(
|
|||||||
jumpInstruction,
|
jumpInstruction,
|
||||||
jumpInstruction.label.previous as VarInsnNode
|
jumpInstruction.label.previous as VarInsnNode
|
||||||
)
|
)
|
||||||
}
|
} else if (methodHandlerIndex == it.`var` &&
|
||||||
else if (methodHandlerIndex == it.`var` &&
|
|
||||||
it.next?.opcode == Opcodes.IFNULL &&
|
it.next?.opcode == Opcodes.IFNULL &&
|
||||||
it.next.next?.opcode == Opcodes.NEW) {
|
it.next.next?.opcode == Opcodes.NEW
|
||||||
|
) {
|
||||||
//Always delete method handle for now
|
//Always delete method handle for now
|
||||||
//This logic should be updated when method handles would be supported
|
//This logic should be updated when method handles would be supported
|
||||||
Condition(0, 0, it, it.next as JumpInsnNode, null)
|
Condition(0, 0, it, it.next as JumpInsnNode, null)
|
||||||
}
|
} else null
|
||||||
else null
|
|
||||||
}.toList()
|
}.toList()
|
||||||
|
|
||||||
val toDelete = linkedSetOf<AbstractInsnNode>()
|
val toDelete = linkedSetOf<AbstractInsnNode>()
|
||||||
@@ -166,14 +168,16 @@ private fun extractDefaultLambdasInfo(
|
|||||||
addAll(InsnSequence(instanceInstuction, varAssignmentInstruction.next).toList())
|
addAll(InsnSequence(instanceInstuction, varAssignmentInstruction.next).toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
val needReification = instanceCreation.previous.takeIf { isNeedClassReificationMarker(it) }?.let { toDelete.add(it) } != null
|
val needReification =
|
||||||
|
instanceCreation.previous.takeIf { isNeedClassReificationMarker(it) }?.let { toDelete.add(it) } != null
|
||||||
Triple(Type.getObjectType(instanceInstuction.owner), Type.getArgumentTypes(instanceInstuction.desc), needReification)
|
Triple(Type.getObjectType(instanceInstuction.owner), Type.getArgumentTypes(instanceInstuction.desc), needReification)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FieldInsnNode -> {
|
is FieldInsnNode -> {
|
||||||
toDelete.addAll(InsnSequence(instanceInstuction, varAssignmentInstruction.next).toList())
|
toDelete.addAll(InsnSequence(instanceInstuction, varAssignmentInstruction.next).toList())
|
||||||
|
|
||||||
val needReification = instanceInstuction.previous.takeIf { isNeedClassReificationMarker(it) }?.let { toDelete.add(it) } != null
|
val needReification =
|
||||||
|
instanceInstuction.previous.takeIf { isNeedClassReificationMarker(it) }?.let { toDelete.add(it) } != null
|
||||||
|
|
||||||
Triple(Type.getObjectType(instanceInstuction.owner), emptyArray<Type>(), needReification)
|
Triple(Type.getObjectType(instanceInstuction.owner), emptyArray<Type>(), needReification)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -469,8 +469,10 @@ internal fun isAfterSuspendMarker(insn: AbstractInsnNode) = isSuspendMarker(insn
|
|||||||
internal fun isReturnsUnitMarker(insn: AbstractInsnNode) = isSuspendMarker(insn, INLINE_MARKER_RETURNS_UNIT)
|
internal fun isReturnsUnitMarker(insn: AbstractInsnNode) = isSuspendMarker(insn, INLINE_MARKER_RETURNS_UNIT)
|
||||||
internal fun isFakeContinuationMarker(insn: AbstractInsnNode) =
|
internal fun isFakeContinuationMarker(insn: AbstractInsnNode) =
|
||||||
insn.previous != null && isSuspendMarker(insn.previous, INLINE_MARKER_FAKE_CONTINUATION) && insn.opcode == Opcodes.ACONST_NULL
|
insn.previous != null && isSuspendMarker(insn.previous, INLINE_MARKER_FAKE_CONTINUATION) && insn.opcode == Opcodes.ACONST_NULL
|
||||||
|
|
||||||
internal fun isBeforeFakeContinuationConstructorCallMarker(insn: AbstractInsnNode) =
|
internal fun isBeforeFakeContinuationConstructorCallMarker(insn: AbstractInsnNode) =
|
||||||
isSuspendMarker(insn, INLINE_MARKER_BEFORE_FAKE_CONTINUATION_CONSTRUCTOR_CALL)
|
isSuspendMarker(insn, INLINE_MARKER_BEFORE_FAKE_CONTINUATION_CONSTRUCTOR_CALL)
|
||||||
|
|
||||||
internal fun isAfterFakeContinuationConstructorCallMarker(insn: AbstractInsnNode) =
|
internal fun isAfterFakeContinuationConstructorCallMarker(insn: AbstractInsnNode) =
|
||||||
isSuspendMarker(insn, INLINE_MARKER_AFTER_FAKE_CONTINUATION_CONSTRUCTOR_CALL)
|
isSuspendMarker(insn, INLINE_MARKER_AFTER_FAKE_CONTINUATION_CONSTRUCTOR_CALL)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user