Place interop part 1 phase after callable reference lowering
#KT-35223 Fixed
This commit is contained in:
committed by
SvyatoslavScherbina
parent
983c43c736
commit
f989ba0f55
+7
-7
@@ -110,13 +110,6 @@ internal val lowerAfterInlinePhase = makeKonanModuleOpPhase(
|
||||
description = "Special operations processing after inlining"
|
||||
)
|
||||
|
||||
internal val interopPart1Phase = makeKonanModuleLoweringPhase(
|
||||
::InteropLoweringPart1,
|
||||
name = "InteropPart1",
|
||||
description = "Interop lowering, part 1",
|
||||
prerequisite = setOf(inlinePhase)
|
||||
)
|
||||
|
||||
/* IrFile phases */
|
||||
|
||||
internal val lateinitPhase = makeKonanFileLoweringPhase(
|
||||
@@ -246,6 +239,13 @@ internal val callableReferencePhase = makeKonanFileLoweringPhase(
|
||||
prerequisite = setOf(delegationPhase) // TODO: make weak dependency on `testProcessorPhase`
|
||||
)
|
||||
|
||||
internal val interopPart1Phase = makeKonanFileLoweringPhase(
|
||||
::InteropLoweringPart1,
|
||||
name = "InteropPart1",
|
||||
description = "Interop lowering, part 1",
|
||||
prerequisite = setOf(inlinePhase)
|
||||
)
|
||||
|
||||
internal val interopPart2Phase = makeKonanFileLoweringPhase(
|
||||
::InteropLoweringPart2,
|
||||
name = "InteropPart2",
|
||||
|
||||
+1
-1
@@ -315,7 +315,6 @@ internal val allLoweringsPhase = namedIrModulePhase(
|
||||
inlinePhase then
|
||||
provisionalFunctionExpressionPhase then
|
||||
lowerAfterInlinePhase then
|
||||
interopPart1Phase then
|
||||
performByIrFile(
|
||||
name = "IrLowerByFile",
|
||||
description = "IR Lowering by file",
|
||||
@@ -336,6 +335,7 @@ internal val allLoweringsPhase = namedIrModulePhase(
|
||||
enumClassPhase then
|
||||
delegationPhase then
|
||||
callableReferencePhase then
|
||||
interopPart1Phase then
|
||||
interopPart2Phase then
|
||||
varargPhase then
|
||||
compileTimeEvaluatePhase then
|
||||
|
||||
+16
-1
@@ -649,10 +649,25 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
|
||||
val initMethodInfo = initMethod.getExternalObjCMethodInfo()!!
|
||||
return builder.at(expression).run {
|
||||
val classPtr = getObjCClass(constructedClass.symbol)
|
||||
irForceNotNull(callAllocAndInit(classPtr, initMethodInfo, arguments, expression, initMethod))
|
||||
ensureObjCReferenceNotNull(callAllocAndInit(classPtr, initMethodInfo, arguments, expression, initMethod))
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.ensureObjCReferenceNotNull(expression: IrExpression): IrExpression =
|
||||
if (!expression.type.containsNull()) {
|
||||
expression
|
||||
} else {
|
||||
irBlock(resultType = expression.type) {
|
||||
val temp = irTemporary(expression)
|
||||
+irIfThen(
|
||||
context.irBuiltIns.unitType,
|
||||
irEqeqeq(irGet(temp), irNull()),
|
||||
irCall(symbols.ThrowNullPointerException)
|
||||
)
|
||||
+irGet(temp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid()
|
||||
|
||||
|
||||
-10
@@ -166,16 +166,6 @@ internal fun KonanBackendContext.report(declaration: IrDeclaration, message: Str
|
||||
if (isError) throw KonanCompilationException()
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irForceNotNull(expression: IrExpression): IrExpression {
|
||||
if (!expression.type.containsNull()) {
|
||||
return expression
|
||||
}
|
||||
|
||||
return irCall(context.irBuiltIns.checkNotNullSymbol, expression.type.makeNotNull()).apply {
|
||||
putValueArgument(0, expression)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrFunctionAccessExpression.addArguments(args: Map<IrValueParameter, IrExpression>) {
|
||||
val unhandledParameters = args.keys.toMutableSet()
|
||||
fun getArg(parameter: IrValueParameter) = args[parameter]?.also { unhandledParameters -= parameter }
|
||||
|
||||
@@ -239,3 +239,13 @@ int getCustomStringValue(CustomString* str) {
|
||||
}
|
||||
|
||||
extern BOOL customStringDeallocated;
|
||||
|
||||
@interface TestConstructorReturnsNull : NSObject
|
||||
- (instancetype)init;
|
||||
@end;
|
||||
|
||||
@interface TestCallableReferences : NSObject
|
||||
@property int value;
|
||||
- (int)instanceMethod;
|
||||
+ (int)classMethod:(int)first :(int)second;
|
||||
@end;
|
||||
@@ -31,6 +31,8 @@ fun run() {
|
||||
testExportObjCClass()
|
||||
testCustomString()
|
||||
testLocalizedStrings()
|
||||
testConstructorReturnsNull()
|
||||
testCallableReferences()
|
||||
|
||||
assertEquals(2, ForwardDeclaredEnum.TWO.value)
|
||||
|
||||
@@ -481,6 +483,37 @@ fun testLocalizedStrings() {
|
||||
assertEquals("Plural: 5 apples", string)
|
||||
}
|
||||
|
||||
fun testConstructorReturnsNull() {
|
||||
assertFailsWith<NullPointerException>() {
|
||||
TestConstructorReturnsNull()
|
||||
}
|
||||
}
|
||||
|
||||
fun testCallableReferences() {
|
||||
val createTestCallableReferences = ::TestCallableReferences
|
||||
assertEquals("<init>", createTestCallableReferences.name)
|
||||
val testCallableReferences: Any = createTestCallableReferences()
|
||||
assertTrue(testCallableReferences is TestCallableReferences)
|
||||
|
||||
val valueRef: kotlin.reflect.KMutableProperty0<Int> = testCallableReferences::value
|
||||
assertEquals("value", valueRef.name)
|
||||
assertEquals(0, valueRef())
|
||||
valueRef.set(42)
|
||||
assertEquals(42, valueRef())
|
||||
|
||||
val classMethodRef = (TestCallableReferences)::classMethod
|
||||
assertEquals("classMethod", classMethodRef.name)
|
||||
assertEquals(3, classMethodRef(1, 2))
|
||||
|
||||
val instanceMethodRef = TestCallableReferences::instanceMethod
|
||||
assertEquals("instanceMethod", instanceMethodRef.name)
|
||||
assertEquals(42, instanceMethodRef(testCallableReferences))
|
||||
|
||||
val boundInstanceMethodRef = testCallableReferences::instanceMethod
|
||||
assertEquals("instanceMethod", boundInstanceMethodRef.name)
|
||||
assertEquals(42, boundInstanceMethodRef())
|
||||
}
|
||||
|
||||
private val Any.objCClassName: String
|
||||
get() = object_getClassName(this)!!.toKString()
|
||||
|
||||
|
||||
@@ -320,3 +320,19 @@ BOOL customStringDeallocated = NO;
|
||||
customStringDeallocated = YES;
|
||||
}
|
||||
@end;
|
||||
|
||||
@implementation TestConstructorReturnsNull
|
||||
- (instancetype)init {
|
||||
return nil;
|
||||
}
|
||||
@end;
|
||||
|
||||
@implementation TestCallableReferences
|
||||
- (int)instanceMethod {
|
||||
return self.value;
|
||||
}
|
||||
|
||||
+ (int)classMethod:(int)first :(int)second {
|
||||
return first + second;
|
||||
}
|
||||
@end;
|
||||
Reference in New Issue
Block a user