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"
|
description = "Special operations processing after inlining"
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val interopPart1Phase = makeKonanModuleLoweringPhase(
|
|
||||||
::InteropLoweringPart1,
|
|
||||||
name = "InteropPart1",
|
|
||||||
description = "Interop lowering, part 1",
|
|
||||||
prerequisite = setOf(inlinePhase)
|
|
||||||
)
|
|
||||||
|
|
||||||
/* IrFile phases */
|
/* IrFile phases */
|
||||||
|
|
||||||
internal val lateinitPhase = makeKonanFileLoweringPhase(
|
internal val lateinitPhase = makeKonanFileLoweringPhase(
|
||||||
@@ -246,6 +239,13 @@ internal val callableReferencePhase = makeKonanFileLoweringPhase(
|
|||||||
prerequisite = setOf(delegationPhase) // TODO: make weak dependency on `testProcessorPhase`
|
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(
|
internal val interopPart2Phase = makeKonanFileLoweringPhase(
|
||||||
::InteropLoweringPart2,
|
::InteropLoweringPart2,
|
||||||
name = "InteropPart2",
|
name = "InteropPart2",
|
||||||
|
|||||||
+1
-1
@@ -315,7 +315,6 @@ internal val allLoweringsPhase = namedIrModulePhase(
|
|||||||
inlinePhase then
|
inlinePhase then
|
||||||
provisionalFunctionExpressionPhase then
|
provisionalFunctionExpressionPhase then
|
||||||
lowerAfterInlinePhase then
|
lowerAfterInlinePhase then
|
||||||
interopPart1Phase then
|
|
||||||
performByIrFile(
|
performByIrFile(
|
||||||
name = "IrLowerByFile",
|
name = "IrLowerByFile",
|
||||||
description = "IR Lowering by file",
|
description = "IR Lowering by file",
|
||||||
@@ -336,6 +335,7 @@ internal val allLoweringsPhase = namedIrModulePhase(
|
|||||||
enumClassPhase then
|
enumClassPhase then
|
||||||
delegationPhase then
|
delegationPhase then
|
||||||
callableReferencePhase then
|
callableReferencePhase then
|
||||||
|
interopPart1Phase then
|
||||||
interopPart2Phase then
|
interopPart2Phase then
|
||||||
varargPhase then
|
varargPhase then
|
||||||
compileTimeEvaluatePhase then
|
compileTimeEvaluatePhase then
|
||||||
|
|||||||
+16
-1
@@ -649,10 +649,25 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
|
|||||||
val initMethodInfo = initMethod.getExternalObjCMethodInfo()!!
|
val initMethodInfo = initMethod.getExternalObjCMethodInfo()!!
|
||||||
return builder.at(expression).run {
|
return builder.at(expression).run {
|
||||||
val classPtr = getObjCClass(constructedClass.symbol)
|
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 {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
expression.transformChildrenVoid()
|
expression.transformChildrenVoid()
|
||||||
|
|
||||||
|
|||||||
-10
@@ -166,16 +166,6 @@ internal fun KonanBackendContext.report(declaration: IrDeclaration, message: Str
|
|||||||
if (isError) throw KonanCompilationException()
|
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>) {
|
fun IrFunctionAccessExpression.addArguments(args: Map<IrValueParameter, IrExpression>) {
|
||||||
val unhandledParameters = args.keys.toMutableSet()
|
val unhandledParameters = args.keys.toMutableSet()
|
||||||
fun getArg(parameter: IrValueParameter) = args[parameter]?.also { unhandledParameters -= parameter }
|
fun getArg(parameter: IrValueParameter) = args[parameter]?.also { unhandledParameters -= parameter }
|
||||||
|
|||||||
@@ -239,3 +239,13 @@ int getCustomStringValue(CustomString* str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern BOOL customStringDeallocated;
|
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()
|
testExportObjCClass()
|
||||||
testCustomString()
|
testCustomString()
|
||||||
testLocalizedStrings()
|
testLocalizedStrings()
|
||||||
|
testConstructorReturnsNull()
|
||||||
|
testCallableReferences()
|
||||||
|
|
||||||
assertEquals(2, ForwardDeclaredEnum.TWO.value)
|
assertEquals(2, ForwardDeclaredEnum.TWO.value)
|
||||||
|
|
||||||
@@ -481,6 +483,37 @@ fun testLocalizedStrings() {
|
|||||||
assertEquals("Plural: 5 apples", string)
|
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
|
private val Any.objCClassName: String
|
||||||
get() = object_getClassName(this)!!.toKString()
|
get() = object_getClassName(this)!!.toKString()
|
||||||
|
|
||||||
|
|||||||
@@ -320,3 +320,19 @@ BOOL customStringDeallocated = NO;
|
|||||||
customStringDeallocated = YES;
|
customStringDeallocated = YES;
|
||||||
}
|
}
|
||||||
@end;
|
@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