Set type of inliner's fake variable slots to int by storing 0
Otherwise, D8 drops the whole LVT. #KT-28309 Fixed
This commit is contained in:
@@ -620,6 +620,7 @@ public class FunctionCodegen {
|
||||
isReleaseCoroutines);
|
||||
}
|
||||
|
||||
Label methodEntry = null;
|
||||
Label methodEnd;
|
||||
|
||||
int functionFakeIndex = -1;
|
||||
@@ -649,14 +650,14 @@ public class FunctionCodegen {
|
||||
functionDescriptor.getValueParameters(), isStaticMethod(context.getContextKind(), functionDescriptor)
|
||||
);
|
||||
if (context.isInlineMethodContext()) {
|
||||
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
functionFakeIndex = newFakeTempIndex(mv, frameMap);
|
||||
}
|
||||
|
||||
if (context instanceof InlineLambdaContext) {
|
||||
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
lambdaFakeIndex = newFakeTempIndex(mv, frameMap);
|
||||
}
|
||||
|
||||
Label methodEntry = new Label();
|
||||
methodEntry = new Label();
|
||||
mv.visitLabel(methodEntry);
|
||||
context.setMethodStartLabel(methodEntry);
|
||||
|
||||
@@ -708,10 +709,11 @@ public class FunctionCodegen {
|
||||
|
||||
//TODO: it's best to move all below logic to 'generateLocalVariableTable' method
|
||||
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
|
||||
assert methodEntry != null : "methodEntry is not initialized";
|
||||
mv.visitLocalVariable(
|
||||
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + typeMapper.mapAsmMethod(functionDescriptor).getName(),
|
||||
Type.INT_TYPE.getDescriptor(), null,
|
||||
methodBegin, methodEnd,
|
||||
methodEntry, methodEnd,
|
||||
functionFakeIndex);
|
||||
}
|
||||
|
||||
@@ -728,14 +730,22 @@ public class FunctionCodegen {
|
||||
functionName = inlineArgumentDescriptor.getContainingDeclaration().getName().asString();
|
||||
}
|
||||
}
|
||||
assert methodEntry != null : "methodEntry is not initialized";
|
||||
mv.visitLocalVariable(
|
||||
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + "-" + functionName + "-" + lambdaLocalName,
|
||||
Type.INT_TYPE.getDescriptor(), null,
|
||||
methodBegin, methodEnd,
|
||||
methodEntry, methodEnd,
|
||||
lambdaFakeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private static int newFakeTempIndex(@NotNull MethodVisitor mv, FrameMap frameMap) {
|
||||
int fakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
mv.visitLdcInsn(0);
|
||||
mv.visitVarInsn(ISTORE, fakeIndex);
|
||||
return fakeIndex;
|
||||
}
|
||||
|
||||
private static boolean isCompatibilityStubInDefaultImpls(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodContext context,
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Range<T>(val min: T, val max: T)
|
||||
|
||||
class Sprite
|
||||
|
||||
class A {
|
||||
private fun calcSpriteSizeRange(layoutSize: Int,
|
||||
sprites: Map<Long, Sprite>,
|
||||
minMargin: Int,
|
||||
range: Range<Int>)
|
||||
: Pair<Range<Int>, Int> {
|
||||
val count = sprites.count()
|
||||
var spriteBounds = layoutSize / count.toFloat()
|
||||
require(spriteBounds * count <= layoutSize) {
|
||||
val result = spriteBounds * count <= layoutSize
|
||||
"Algorithm incorrect: $spriteBounds * " +
|
||||
"$count == $result <= $layoutSize"
|
||||
}
|
||||
val adjustedMargin = minMargin + (minMargin / count.toFloat())
|
||||
spriteBounds -= adjustedMargin
|
||||
var size = spriteBounds
|
||||
require((size * count) + minMargin * (count + 1)
|
||||
<= layoutSize) {
|
||||
val result = size * count + minMargin * (count + 1)
|
||||
"Algorithm incorrect: $size * $count + " +
|
||||
"$minMargin * ($count + 1) == $result <= $layoutSize"
|
||||
}
|
||||
size = kotlin.math.min(size, range.max.toFloat())
|
||||
require(size > 0) {
|
||||
"Maximum palantir size ${size.toInt()} > 0."
|
||||
}
|
||||
val minSize =
|
||||
if (range.min > size) {
|
||||
size
|
||||
} else {
|
||||
range.min.toFloat()
|
||||
}
|
||||
val margin = (layoutSize - (size * count)) / (count + 1)
|
||||
val adjustedRange = Range(minSize.toInt(), size.toInt())
|
||||
val requiredSize =
|
||||
calcRequiredLayoutSize(count, adjustedRange.max, margin.toInt())
|
||||
require(requiredSize <= layoutSize) {
|
||||
"requiredSize <= layoutSize -> " +
|
||||
"$requiredSize <= $layoutSize"
|
||||
}
|
||||
|
||||
return Pair(adjustedRange, margin.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
fun calcRequiredLayoutSize(count: Int, max: Int, toInt: Int) = 0
|
||||
|
||||
// 2 ISTORE 10
|
||||
@@ -1948,6 +1948,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inline/finallyMarkers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineArgumentSlots.kt")
|
||||
public void testInlineArgumentSlots() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inline/inlineArgumentSlots.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineReturnsNothing1.kt")
|
||||
public void testInlineReturnsNothing1() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt");
|
||||
|
||||
Reference in New Issue
Block a user