Generate as check for inline classes using wrapper
Should be improved when inline class is based on non-null reference
This commit is contained in:
@@ -4322,29 +4322,29 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
KtExpression left = expression.getLeft();
|
KtExpression left = expression.getLeft();
|
||||||
IElementType opToken = expression.getOperationReference().getReferencedNameElementType();
|
IElementType opToken = expression.getOperationReference().getReferencedNameElementType();
|
||||||
|
|
||||||
KotlinType rightType = bindingContext.get(TYPE, expression.getRight());
|
KotlinType rightKotlinType = bindingContext.get(TYPE, expression.getRight());
|
||||||
assert rightType != null;
|
assert rightKotlinType != null;
|
||||||
|
|
||||||
StackValue value = genQualified(receiver, left);
|
StackValue value = genQualified(receiver, left);
|
||||||
|
|
||||||
return StackValue.operation(boxType(asmType(rightType)), v -> {
|
Type boxedRightType = boxType(typeMapper.mapTypeAsDeclaration(rightKotlinType));
|
||||||
value.put(boxType(value.type), null, v);
|
return StackValue.operation(boxedRightType, rightKotlinType, v -> {
|
||||||
|
value.put(boxType(value.type), value.kotlinType, v);
|
||||||
|
|
||||||
if (value.type == Type.VOID_TYPE) {
|
if (value.type == Type.VOID_TYPE) {
|
||||||
StackValue.putUnitInstance(v);
|
StackValue.putUnitInstance(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean safeAs = opToken == KtTokens.AS_SAFE;
|
boolean safeAs = opToken == KtTokens.AS_SAFE;
|
||||||
Type type = boxType(asmType(rightType));
|
if (TypeUtils.isReifiedTypeParameter(rightKotlinType)) {
|
||||||
if (TypeUtils.isReifiedTypeParameter(rightType)) {
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightKotlinType,
|
||||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightType,
|
|
||||||
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
|
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
|
||||||
: ReifiedTypeInliner.OperationKind.AS);
|
: ReifiedTypeInliner.OperationKind.AS);
|
||||||
v.checkcast(type);
|
v.checkcast(boxedRightType);
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodegenUtilKt.generateAsCast(v, rightType, type, safeAs);
|
CodegenUtilKt.generateAsCast(v, rightKotlinType, boxedRightType, safeAs);
|
||||||
|
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// !LANGUAGE: +InlineClasses
|
||||||
|
|
||||||
|
inline class UInt(val s: Int)
|
||||||
|
|
||||||
|
fun test(a1: Any, a2: UInt?, a3: Any?, a4: Any?): Int {
|
||||||
|
val b1 = a1 as UInt
|
||||||
|
val b2 = a2 as UInt
|
||||||
|
val b3 = (a3 as UInt?) as UInt
|
||||||
|
val b4 = (a4 as? UInt) as UInt
|
||||||
|
return b1.s + b2.s + b3.s + b4.s
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val u1 = UInt(1)
|
||||||
|
val u2 = UInt(2)
|
||||||
|
if (test(u1, u2, u1, u2) != 6) return "fail"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// !LANGUAGE: +InlineClasses
|
||||||
|
|
||||||
|
inline class UInt(val u: Int)
|
||||||
|
|
||||||
|
fun test(a1: Any, a2: UInt?, a3: Any?, a4: Any?) {
|
||||||
|
val b1 = a1 as UInt // checkcast, unbox
|
||||||
|
val b2 = a2 as UInt // unbox
|
||||||
|
val b3 = a3 as UInt? // checkcast
|
||||||
|
val b4 = a4 as? UInt // instanceof, checkcast
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3 CHECKCAST UInt
|
||||||
|
// 2 INVOKEVIRTUAL UInt.unbox
|
||||||
|
|
||||||
|
// 1 INSTANCEOF UInt
|
||||||
|
|
||||||
|
// 0 intValue
|
||||||
Generated
+6
@@ -10449,6 +10449,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("checkCastToInlineClass.kt")
|
||||||
|
public void testCheckCastToInlineClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkCastToInlineClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
||||||
public void testCheckForInstanceOfInlineClass() throws Exception {
|
public void testCheckForInstanceOfInlineClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
||||||
|
|||||||
+6
@@ -10449,6 +10449,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("checkCastToInlineClass.kt")
|
||||||
|
public void testCheckCastToInlineClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkCastToInlineClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
||||||
public void testCheckForInstanceOfInlineClass() throws Exception {
|
public void testCheckForInstanceOfInlineClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
||||||
|
|||||||
@@ -1914,6 +1914,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("asCastForInlineClass.kt")
|
||||||
|
public void testAsCastForInlineClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/asCastForInlineClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("boxResultAfterConstructorCall.kt")
|
@TestMetadata("boxResultAfterConstructorCall.kt")
|
||||||
public void testBoxResultAfterConstructorCall() throws Exception {
|
public void testBoxResultAfterConstructorCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxResultAfterConstructorCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxResultAfterConstructorCall.kt");
|
||||||
|
|||||||
+6
@@ -10449,6 +10449,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("checkCastToInlineClass.kt")
|
||||||
|
public void testCheckCastToInlineClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkCastToInlineClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
||||||
public void testCheckForInstanceOfInlineClass() throws Exception {
|
public void testCheckForInstanceOfInlineClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
||||||
|
|||||||
+6
@@ -11433,6 +11433,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("checkCastToInlineClass.kt")
|
||||||
|
public void testCheckCastToInlineClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkCastToInlineClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
@TestMetadata("checkForInstanceOfInlineClass.kt")
|
||||||
public void testCheckForInstanceOfInlineClass() throws Exception {
|
public void testCheckForInstanceOfInlineClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkForInstanceOfInlineClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user