Place interop part 1 phase after callable reference lowering

#KT-35223 Fixed
This commit is contained in:
Svyatoslav Scherbina
2020-01-27 19:29:44 +03:00
committed by SvyatoslavScherbina
parent 983c43c736
commit f989ba0f55
7 changed files with 83 additions and 19 deletions
@@ -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",
@@ -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
@@ -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()
@@ -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 }
+10
View File
@@ -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()
+16
View File
@@ -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;