Use IR for override checks. (#3339)
This commit is contained in:
+3
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.allParameters
|
|||||||
import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
||||||
import org.jetbrains.kotlin.backend.common.pop
|
import org.jetbrains.kotlin.backend.common.pop
|
||||||
import org.jetbrains.kotlin.backend.common.push
|
import org.jetbrains.kotlin.backend.common.push
|
||||||
|
import org.jetbrains.kotlin.backend.konan.ir.isOverridable
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -220,12 +221,12 @@ private class ExportedElement(val kind: ElementKind,
|
|||||||
val llvmFunction = owner.codegen.llvmFunction(irFunction)
|
val llvmFunction = owner.codegen.llvmFunction(irFunction)
|
||||||
// If function is virtual, we need to resolve receiver properly.
|
// If function is virtual, we need to resolve receiver properly.
|
||||||
val bridge = if (!DescriptorUtils.isTopLevelDeclaration(function) && !function.isExtension &&
|
val bridge = if (!DescriptorUtils.isTopLevelDeclaration(function) && !function.isExtension &&
|
||||||
function.isOverridable) {
|
irFunction.isOverridable) {
|
||||||
// We need LLVMGetElementType() as otherwise type is function pointer.
|
// We need LLVMGetElementType() as otherwise type is function pointer.
|
||||||
generateFunction(owner.codegen, LLVMGetElementType(llvmFunction.type)!!, cname) {
|
generateFunction(owner.codegen, LLVMGetElementType(llvmFunction.type)!!, cname) {
|
||||||
val receiver = param(0)
|
val receiver = param(0)
|
||||||
val numParams = LLVMCountParams(llvmFunction)
|
val numParams = LLVMCountParams(llvmFunction)
|
||||||
val args = (0..numParams - 1).map { index -> param(index) }
|
val args = (0 .. numParams - 1).map { index -> param(index) }
|
||||||
val callee = lookupVirtualImpl(receiver, irFunction)
|
val callee = lookupVirtualImpl(receiver, irFunction)
|
||||||
val result = call(callee, args, exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
val result = call(callee, args, exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
||||||
ret(result)
|
ret(result)
|
||||||
|
|||||||
@@ -3558,6 +3558,7 @@ dynamicTest("produce_dynamic") {
|
|||||||
"RO property is 42\n" +
|
"RO property is 42\n" +
|
||||||
"RW property is 239\n" +
|
"RW property is 239\n" +
|
||||||
"enum100 = 100\n" +
|
"enum100 = 100\n" +
|
||||||
|
"enum42 = 42\n" +
|
||||||
"object = 42\n" +
|
"object = 42\n" +
|
||||||
"singleton = I am single\n" +
|
"singleton = I am single\n" +
|
||||||
"mutable = foo\n" +
|
"mutable = foo\n" +
|
||||||
|
|||||||
@@ -49,6 +49,17 @@ enum class Enum(val code: Int) {
|
|||||||
HUNDRED(100)
|
HUNDRED(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface Interface {
|
||||||
|
fun foo(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class EnumWithInterface : Interface {
|
||||||
|
ZERO
|
||||||
|
;
|
||||||
|
override fun foo(): Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
// Object.
|
// Object.
|
||||||
interface Codeable {
|
interface Codeable {
|
||||||
fun asCode(): Int
|
fun asCode(): Int
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ int main(void) {
|
|||||||
T_(kotlin_Unit) nullableUnit = __ createNullableUnit();
|
T_(kotlin_Unit) nullableUnit = __ createNullableUnit();
|
||||||
T_(kotlin_Int) nullableIntNull = { .pinned = 0 };
|
T_(kotlin_Int) nullableIntNull = { .pinned = 0 };
|
||||||
T_(kotlin_Unit) nullableUnitNull = { .pinned = 0 };
|
T_(kotlin_Unit) nullableUnitNull = { .pinned = 0 };
|
||||||
|
T_(EnumWithInterface) enum2 = __ kotlin.root.EnumWithInterface.ZERO.get();
|
||||||
|
|
||||||
const char* string1 = __ kotlin.root.getString();
|
const char* string1 = __ kotlin.root.getString();
|
||||||
const char* string2 = __ kotlin.root.Singleton.toString(singleton);
|
const char* string2 = __ kotlin.root.Singleton.toString(singleton);
|
||||||
@@ -48,6 +49,7 @@ int main(void) {
|
|||||||
printf("RW property is %d\n", __ kotlin.root.Child.get_rwProperty(child));
|
printf("RW property is %d\n", __ kotlin.root.Child.get_rwProperty(child));
|
||||||
|
|
||||||
printf("enum100 = %d\n", __ kotlin.root.Enum.get_code(enum1));
|
printf("enum100 = %d\n", __ kotlin.root.Enum.get_code(enum1));
|
||||||
|
printf("enum42 = %d\n", __ kotlin.root.EnumWithInterface.foo(enum2));
|
||||||
|
|
||||||
printf("object = %d\n", __ kotlin.root.Codeable.asCode(object1));
|
printf("object = %d\n", __ kotlin.root.Codeable.asCode(object1));
|
||||||
|
|
||||||
@@ -76,6 +78,7 @@ int main(void) {
|
|||||||
__ DisposeStablePointer(enum1.pinned);
|
__ DisposeStablePointer(enum1.pinned);
|
||||||
__ DisposeStablePointer(object1.pinned);
|
__ DisposeStablePointer(object1.pinned);
|
||||||
__ DisposeStablePointer(nullableInt.pinned);
|
__ DisposeStablePointer(nullableInt.pinned);
|
||||||
|
__ DisposeStablePointer(enum2.pinned);
|
||||||
|
|
||||||
__ kotlin.root.setCErrorHandler(&errorHandler);
|
__ kotlin.root.setCErrorHandler(&errorHandler);
|
||||||
__ kotlin.root.throwException();
|
__ kotlin.root.throwException();
|
||||||
|
|||||||
Reference in New Issue
Block a user