Use IR for override checks. (#3339)

This commit is contained in:
Nikolay Igotti
2019-09-13 14:00:49 +03:00
committed by GitHub
parent 454400a4a2
commit 4f0a3b7a13
4 changed files with 18 additions and 2 deletions
@@ -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.pop
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.builtins.UnsignedType
import org.jetbrains.kotlin.descriptors.*
@@ -220,12 +221,12 @@ private class ExportedElement(val kind: ElementKind,
val llvmFunction = owner.codegen.llvmFunction(irFunction)
// If function is virtual, we need to resolve receiver properly.
val bridge = if (!DescriptorUtils.isTopLevelDeclaration(function) && !function.isExtension &&
function.isOverridable) {
irFunction.isOverridable) {
// We need LLVMGetElementType() as otherwise type is function pointer.
generateFunction(owner.codegen, LLVMGetElementType(llvmFunction.type)!!, cname) {
val receiver = param(0)
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 result = call(callee, args, exceptionHandler = ExceptionHandler.Caller, verbatim = true)
ret(result)
+1
View File
@@ -3558,6 +3558,7 @@ dynamicTest("produce_dynamic") {
"RO property is 42\n" +
"RW property is 239\n" +
"enum100 = 100\n" +
"enum42 = 42\n" +
"object = 42\n" +
"singleton = I am single\n" +
"mutable = foo\n" +
@@ -49,6 +49,17 @@ enum class Enum(val code: Int) {
HUNDRED(100)
}
interface Interface {
fun foo(): Int
}
enum class EnumWithInterface : Interface {
ZERO
;
override fun foo(): Int = 42
}
// Object.
interface Codeable {
fun asCode(): Int
@@ -25,6 +25,7 @@ int main(void) {
T_(kotlin_Unit) nullableUnit = __ createNullableUnit();
T_(kotlin_Int) nullableIntNull = { .pinned = 0 };
T_(kotlin_Unit) nullableUnitNull = { .pinned = 0 };
T_(EnumWithInterface) enum2 = __ kotlin.root.EnumWithInterface.ZERO.get();
const char* string1 = __ kotlin.root.getString();
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("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));
@@ -76,6 +78,7 @@ int main(void) {
__ DisposeStablePointer(enum1.pinned);
__ DisposeStablePointer(object1.pinned);
__ DisposeStablePointer(nullableInt.pinned);
__ DisposeStablePointer(enum2.pinned);
__ kotlin.root.setCErrorHandler(&errorHandler);
__ kotlin.root.throwException();