Move the rest of intrinsics under TypedIntrinsic annotation (#2500)

* Create interface between codegen and intrinsics generator
* No more @Intrinsic annotation
This commit is contained in:
Sergey Bogolepov
2018-12-26 23:16:20 +07:00
committed by GitHub
parent 3bc87ab5f6
commit 0d62143c20
18 changed files with 498 additions and 429 deletions
@@ -16,54 +16,55 @@
package kotlinx.cinterop
import kotlin.native.internal.Intrinsic
import kotlin.native.internal.TypedIntrinsic
import kotlin.native.internal.IntrinsicType
import kotlin.native.internal.ExportForCompiler
@Intrinsic external operator fun <R> CPointer<CFunction<() -> R>>.invoke(): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <R> CPointer<CFunction<() -> R>>.invoke(): R
@Intrinsic external operator fun <P1, R> CPointer<CFunction<(P1) -> R>>.invoke(p1: P1): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, R> CPointer<CFunction<(P1) -> R>>.invoke(p1: P1): R
@Intrinsic external operator fun <P1, P2, R> CPointer<CFunction<(P1, P2) -> R>>.invoke(p1: P1, p2: P2): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, R> CPointer<CFunction<(P1, P2) -> R>>.invoke(p1: P1, p2: P2): R
@Intrinsic external operator fun <P1, P2, P3, R> CPointer<CFunction<(P1, P2, P3) -> R>>.invoke(p1: P1, p2: P2, p3: P3): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, R> CPointer<CFunction<(P1, P2, P3) -> R>>.invoke(p1: P1, p2: P2, p3: P3): R
@Intrinsic external operator fun <P1, P2, P3, P4, R> CPointer<CFunction<(P1, P2, P3, P4) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, R> CPointer<CFunction<(P1, P2, P3, P4) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, R> CPointer<CFunction<(P1, P2, P3, P4, P5) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, R> CPointer<CFunction<(P1, P2, P3, P4, P5) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21): R
@Intrinsic external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21, p22: P22): R
@TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, R> CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21, p22: P22): R
@ExportForCompiler
private fun invokeImplUnitRet(ptr: COpaquePointer, vararg args: Any?): Unit = memScoped {
@@ -26,32 +26,32 @@ internal inline val pointerSize: Int
get() = getPointerSize()
@PublishedApi
@TypedIntrinsic(IntrinsicType.GET_POINTER_SIZE)
@TypedIntrinsic(IntrinsicType.INTEROP_GET_POINTER_SIZE)
internal external fun getPointerSize(): Int
// TODO: do not use singleton because it leads to init-check on any access.
@PublishedApi
internal object nativeMemUtils {
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getByte(mem: NativePointed): Byte
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putByte(mem: NativePointed, value: Byte)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getByte(mem: NativePointed): Byte
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putByte(mem: NativePointed, value: Byte)
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getShort(mem: NativePointed): Short
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putShort(mem: NativePointed, value: Short)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getShort(mem: NativePointed): Short
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putShort(mem: NativePointed, value: Short)
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getInt(mem: NativePointed): Int
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putInt(mem: NativePointed, value: Int)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getInt(mem: NativePointed): Int
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putInt(mem: NativePointed, value: Int)
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getLong(mem: NativePointed): Long
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putLong(mem: NativePointed, value: Long)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getLong(mem: NativePointed): Long
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putLong(mem: NativePointed, value: Long)
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getFloat(mem: NativePointed): Float
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putFloat(mem: NativePointed, value: Float)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getFloat(mem: NativePointed): Float
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putFloat(mem: NativePointed, value: Float)
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getDouble(mem: NativePointed): Double
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putDouble(mem: NativePointed, value: Double)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getDouble(mem: NativePointed): Double
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putDouble(mem: NativePointed, value: Double)
@TypedIntrinsic(IntrinsicType.READ_PRIMITIVE) external fun getNativePtr(mem: NativePointed): NativePtr
@TypedIntrinsic(IntrinsicType.WRITE_PRIMITIVE) external fun putNativePtr(mem: NativePointed, value: NativePtr)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getNativePtr(mem: NativePointed): NativePtr
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putNativePtr(mem: NativePointed, value: NativePtr)
// TODO: optimize
fun getByteArray(source: NativePointed, dest: ByteArray, length: Int) {
@@ -154,7 +154,7 @@ private external fun malloc(size: Long, align: Int): NativePtr
@SymbolName("Kotlin_interop_free")
private external fun cfree(ptr: NativePtr)
@TypedIntrinsic(IntrinsicType.READ_BITS)
@TypedIntrinsic(IntrinsicType.INTEROP_READ_BITS)
external fun readBits(ptr: NativePtr, offset: Long, size: Int, signed: Boolean): Long
@TypedIntrinsic(IntrinsicType.WRITE_BITS)
@TypedIntrinsic(IntrinsicType.INTEROP_WRITE_BITS)
external fun writeBits(ptr: NativePtr, offset: Long, size: Int, value: Long)
@@ -62,48 +62,48 @@ internal fun CPointer<*>.cPointerToString() = "CPointer(raw=$rawValue)"
* @param function must be *static*, i.e. an (unbound) reference to a Kotlin function or
* a closure which doesn't capture any variable
*/
@Intrinsic external fun <R> staticCFunction(@VolatileLambda function: () -> R): CPointer<CFunction<() -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <R> staticCFunction(@VolatileLambda function: () -> R): CPointer<CFunction<() -> R>>
@Intrinsic external fun <P1, R> staticCFunction(@VolatileLambda function: (P1) -> R): CPointer<CFunction<(P1) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, R> staticCFunction(@VolatileLambda function: (P1) -> R): CPointer<CFunction<(P1) -> R>>
@Intrinsic external fun <P1, P2, R> staticCFunction(@VolatileLambda function: (P1, P2) -> R): CPointer<CFunction<(P1, P2) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, R> staticCFunction(@VolatileLambda function: (P1, P2) -> R): CPointer<CFunction<(P1, P2) -> R>>
@Intrinsic external fun <P1, P2, P3, R> staticCFunction(@VolatileLambda function: (P1, P2, P3) -> R): CPointer<CFunction<(P1, P2, P3) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, R> staticCFunction(@VolatileLambda function: (P1, P2, P3) -> R): CPointer<CFunction<(P1, P2, P3) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4) -> R): CPointer<CFunction<(P1, P2, P3, P4) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4) -> R): CPointer<CFunction<(P1, P2, P3, P4) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R>>
@Intrinsic external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R>>
@TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun <P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, R> staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R): CPointer<CFunction<(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R>>
@@ -17,33 +17,35 @@
package kotlinx.cinterop
import kotlin.native.internal.Intrinsic
import kotlin.native.internal.TypedIntrinsic
import kotlin.native.internal.IntrinsicType
internal fun decodeFromUtf8(bytes: ByteArray): String = bytes.stringFromUtf8()
fun encodeToUtf8(str: String): ByteArray = str.toUtf8()
@Intrinsic
@TypedIntrinsic(IntrinsicType.INTEROP_BITS_TO_FLOAT)
external fun bitsToFloat(bits: Int): Float
@Intrinsic
@TypedIntrinsic(IntrinsicType.INTEROP_BITS_TO_DOUBLE)
external fun bitsToDouble(bits: Long): Double
// TODO: deprecate.
@Intrinsic
@TypedIntrinsic(IntrinsicType.INTEROP_SIGN_EXTEND)
external fun <R : Number> Number.signExtend(): R
// TODO: deprecate.
@Intrinsic
@TypedIntrinsic(IntrinsicType.INTEROP_NARROW)
external fun <R : Number> Number.narrow(): R
@Intrinsic external fun <R : Any> Byte.convert(): R
@Intrinsic external fun <R : Any> Short.convert(): R
@Intrinsic external fun <R : Any> Int.convert(): R
@Intrinsic external fun <R : Any> Long.convert(): R
@Intrinsic external fun <R : Any> UByte.convert(): R
@Intrinsic external fun <R : Any> UShort.convert(): R
@Intrinsic external fun <R : Any> UInt.convert(): R
@Intrinsic external fun <R : Any> ULong.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> Byte.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> Short.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> Int.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> Long.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> UByte.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> UShort.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> UInt.convert(): R
@TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external fun <R : Any> ULong.convert(): R
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FILE)
@Retention(AnnotationRetention.SOURCE)
@@ -44,7 +44,7 @@ fun optional(): Nothing = throw RuntimeException("Do not call me!!!")
"Add @OverrideInit to constructor to make it override Objective-C initializer",
level = DeprecationLevel.WARNING
)
@kotlin.native.internal.Intrinsic
@TypedIntrinsic(IntrinsicType.OBJC_INIT_BY)
external fun <T : ObjCObjectBase> T.initBy(constructorCall: T): T
@kotlin.native.internal.ExportForCompiler
@@ -54,33 +54,10 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns, vararg konanPrimitives:
val typeOf = packageScope.getContributedFunctions("typeOf").single()
val bitsToFloat = packageScope.getContributedFunctions("bitsToFloat").single()
val bitsToDouble = packageScope.getContributedFunctions("bitsToDouble").single()
val staticCFunction = packageScope.getContributedFunctions("staticCFunction").toSet()
val concurrentPackageScope = builtIns.builtInsModule.getPackage(FqName("kotlin.native.concurrent")).memberScope
val executeFunction = concurrentPackageScope.getContributedClass("Worker")
.unsubstitutedMemberScope.getContributedFunctions("execute").single()
val executeImplFunction = concurrentPackageScope.getContributedFunctions("executeImpl").single()
val signExtend = packageScope.getContributedFunctions("signExtend").single()
val narrow = packageScope.getContributedFunctions("narrow").single()
val convert = packageScope.getContributedFunctions("convert").toSet()
val cFunctionPointerInvokes = packageScope.getContributedFunctions(OperatorNameConventions.INVOKE.asString())
.filter {
val extensionReceiverParameter = it.extensionReceiverParameter
it.isOperator &&
extensionReceiverParameter != null &&
TypeUtils.getClassDescriptor(extensionReceiverParameter.type) == cPointer
}.toSet()
private fun KonanBuiltIns.getUnsignedClass(unsignedType: UnsignedType): ClassDescriptor =
this.builtInsModule.findClassAcrossModuleDependencies(unsignedType.classId)!!
@@ -76,10 +76,6 @@ internal fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction {
}
// TODO: don't forget to remove descriptor access here.
internal val FunctionDescriptor.isIntrinsic: Boolean
get() = this.descriptor.isIntrinsic
// TODO: Merge with `isIntrinsic`
internal val FunctionDescriptor.isTypedIntrinsic: Boolean
get() = this.descriptor.isTypedIntrinsic
@@ -240,7 +240,6 @@ fun CallableMemberDescriptor.findSourceFile(): SourceFile {
}
internal val TypedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic")
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
private val symbolNameAnnotation = FqName("kotlin.native.SymbolName")
private val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod")
private val frozenAnnotation = FqName("kotlin.native.internal.Frozen")
@@ -251,9 +250,6 @@ internal val DeclarationDescriptor.isFrozen: Boolean
// RTTI is used for non-reference type box or Objective-C object wrapper:
&& (!this.defaultType.binaryTypeIsReference() || this.isObjCClass()))
internal val FunctionDescriptor.isIntrinsic: Boolean
get() = this.annotations.hasAnnotation(intrinsicAnnotation)
internal val FunctionDescriptor.isTypedIntrinsic: Boolean
get() = this.annotations.hasAnnotation(TypedIntrinsic)
@@ -269,11 +265,9 @@ fun CallableMemberDescriptor.externalSymbolOrThrow(): String? {
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
return getAnnotationValue(it)!!
}
if (this.annotations.hasAnnotation(intrinsicAnnotation)) return null
if (this.annotations.hasAnnotation(objCMethodAnnotation)) return null
if (this.annotations.hasAnnotation(TypedIntrinsic)) return null
throw Error("external function ${this} must have @TypedIntrinsic, @SymbolName, @Intrinsic or @ObjCMethod annotation")
throw Error("external function ${this} must have @TypedIntrinsic, @SymbolName or @ObjCMethod annotation")
}
@@ -3,15 +3,16 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.cValuesOf
import llvm.*
import org.jetbrains.kotlin.backend.konan.descriptors.TypedIntrinsic
import org.jetbrains.kotlin.backend.konan.descriptors.isTypedIntrinsic
import org.jetbrains.kotlin.backend.konan.reportCompilationError
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrVararg
import org.jetbrains.kotlin.ir.expressions.getTypeArgument
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.name.Name
private enum class IntrinsicType {
internal enum class IntrinsicType {
PLUS,
MINUS,
TIMES,
@@ -49,46 +50,123 @@ private enum class IntrinsicType {
OBJC_GET_MESSENGER_STRET,
OBJC_GET_OBJC_CLASS,
OBJC_GET_RECEIVER_OR_SUPER,
OBJC_INIT_BY,
// Other
GET_CLASS_TYPE_INFO,
READ_BITS,
WRITE_BITS,
CREATE_UNINITIALIZED_INSTANCE,
LIST_OF_INTERNAL,
IDENTITY,
IMMUTABLE_BLOB,
INIT_INSTANCE,
// Coroutines
GET_CONTINUATION,
RETURN_IF_SUSPEND,
// Interop
READ_PRIMITIVE,
WRITE_PRIMITIVE,
GET_POINTER_SIZE,
NATIVE_PTR_TO_LONG,
NATIVE_PTR_PLUS_LONG,
GET_NATIVE_NULL_PTR
INTEROP_READ_BITS,
INTEROP_WRITE_BITS,
INTEROP_READ_PRIMITIVE,
INTEROP_WRITE_PRIMITIVE,
INTEROP_GET_POINTER_SIZE,
INTEROP_NATIVE_PTR_TO_LONG,
INTEROP_NATIVE_PTR_PLUS_LONG,
INTEROP_GET_NATIVE_NULL_PTR,
INTEROP_CONVERT,
INTEROP_BITS_TO_FLOAT,
INTEROP_BITS_TO_DOUBLE,
INTEROP_SIGN_EXTEND,
INTEROP_NARROW,
INTEROP_STATIC_C_FUNCTION,
INTEROP_FUNPTR_INVOKE,
// Worker
WORKER_EXECUTE
}
internal class IntrinsicGenerator(private val codegen: CodeGenerator,
private val lifetimeCalculator: (IrElement) -> Lifetime,
private val continuationProvider: () -> LLVMValueRef,
private val exceptionHandlerProvider: () -> ExceptionHandler) {
// Explicit and single interface between Intrinsic Generator and IrToBitcode.
internal interface IntrinsicGeneratorEnvironment {
val codegen: CodeGenerator
val functionGenerationContext: FunctionGenerationContext
val continuation: LLVMValueRef
val exceptionHandler: ExceptionHandler
fun calculateLifetime(element: IrElement): Lifetime
fun evaluateCall(function: IrFunction, args: List<LLVMValueRef>, resultLifetime: Lifetime): LLVMValueRef
fun evaluateExplicitArgs(expression: IrMemberAccessExpression): List<LLVMValueRef>
fun evaluateExpression(value: IrExpression): LLVMValueRef
}
internal fun tryGetIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicType? =
if (callSite.symbol.owner.isTypedIntrinsic) getIntrinsicType(callSite) else null
private fun getIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicType {
val function = callSite.symbol.owner
val annotation = function.descriptor.annotations.findAnnotation(TypedIntrinsic)!!
val value = annotation.allValueArguments.getValue(Name.identifier("kind")).value as String
return IntrinsicType.valueOf(value)
}
internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnvironment) {
private val codegen = environment.codegen
private val context = codegen.context
private val IrCall.llvmReturnType: LLVMTypeRef
get() = LLVMGetReturnType(codegen.getLlvmFunctionType(symbol.owner))!!
private fun getIntrinsicType(callSite: IrCall): IntrinsicType {
/**
* Some intrinsics have to be processed before evaluation of their arguments.
* So this method looks at [callSite] and if it is call to "special" intrinsic
* processes it. Otherwise it returns null.
*/
fun tryEvaluateSpecialCall(callSite: IrFunctionAccessExpression): LLVMValueRef? {
val function = callSite.symbol.owner
val annotation = function.descriptor.annotations.findAnnotation(TypedIntrinsic)!!
val value = annotation.allValueArguments[Name.identifier("kind")]!!.value as String
return IntrinsicType.valueOf(value)
if (!function.isTypedIntrinsic) {
return null
}
val intrinsicType = getIntrinsicType(callSite)
return when (intrinsicType) {
IntrinsicType.IMMUTABLE_BLOB -> {
@Suppress("UNCHECKED_CAST")
val arg = callSite.getValueArgument(0) as IrConst<String>
context.llvm.staticData.createImmutableBlob(arg)
}
IntrinsicType.OBJC_INIT_BY -> {
val receiver = environment.evaluateExpression(callSite.extensionReceiver!!)
val irConstructorCall = callSite.getValueArgument(0) as IrCall
val constructorDescriptor = irConstructorCall.symbol.owner as IrConstructor
val constructorArgs = environment.evaluateExplicitArgs(irConstructorCall)
val args = listOf(receiver) + constructorArgs
environment.evaluateCall(constructorDescriptor, args, Lifetime.IRRELEVANT)
receiver
}
IntrinsicType.INIT_INSTANCE -> {
val callee = callSite as IrCall
val initializer = callee.getValueArgument(1) as IrCall
val thiz = environment.evaluateExpression(callee.getValueArgument(0)!!)
environment.evaluateCall(
initializer.symbol.owner,
listOf(thiz) + environment.evaluateExplicitArgs(initializer),
environment.calculateLifetime(initializer)
)
codegen.theUnitInstanceRef.llvm
}
else -> null
}
}
fun evaluateCall(callSite: IrCall, args: List<LLVMValueRef>, generationContext: FunctionGenerationContext): LLVMValueRef =
generationContext.evaluateCall(callSite, args)
fun evaluateCall(callSite: IrCall, args: List<LLVMValueRef>): LLVMValueRef =
environment.functionGenerationContext.evaluateCall(callSite, args)
// Assuming that we checked for `TypedIntrinsic` annotation presence.
private fun FunctionGenerationContext.evaluateCall(callSite: IrCall, args: List<LLVMValueRef>): LLVMValueRef =
when (getIntrinsicType(callSite)) {
when (val intrinsicType = getIntrinsicType(callSite)) {
IntrinsicType.PLUS -> emitPlus(args)
IntrinsicType.MINUS -> emitMinus(args)
IntrinsicType.TIMES -> emitTimes(args)
@@ -126,22 +204,42 @@ internal class IntrinsicGenerator(private val codegen: CodeGenerator,
IntrinsicType.OBJC_GET_OBJC_CLASS -> emitGetObjCClass(callSite)
IntrinsicType.OBJC_GET_RECEIVER_OR_SUPER -> emitGetReceiverOrSuper(args)
IntrinsicType.GET_CLASS_TYPE_INFO -> emitGetClassTypeInfo(callSite)
IntrinsicType.READ_BITS -> emitReadBits(args)
IntrinsicType.WRITE_BITS -> emitWriteBits(args)
IntrinsicType.READ_PRIMITIVE -> emitReadPrimitive(callSite, args)
IntrinsicType.WRITE_PRIMITIVE -> emitWritePrimitive(callSite, args)
IntrinsicType.GET_POINTER_SIZE -> emitGetPointerSize()
IntrinsicType.INTEROP_READ_BITS -> emitReadBits(args)
IntrinsicType.INTEROP_WRITE_BITS -> emitWriteBits(args)
IntrinsicType.INTEROP_READ_PRIMITIVE -> emitReadPrimitive(callSite, args)
IntrinsicType.INTEROP_WRITE_PRIMITIVE -> emitWritePrimitive(callSite, args)
IntrinsicType.INTEROP_GET_POINTER_SIZE -> emitGetPointerSize()
IntrinsicType.CREATE_UNINITIALIZED_INSTANCE -> emitCreateUninitializedInstance(callSite)
IntrinsicType.NATIVE_PTR_TO_LONG -> emitNativePtrToLong(callSite, args)
IntrinsicType.NATIVE_PTR_PLUS_LONG -> emitNativePtrPlusLong(args)
IntrinsicType.GET_NATIVE_NULL_PTR -> emitGetNativeNullPtr()
IntrinsicType.INTEROP_NATIVE_PTR_TO_LONG -> emitNativePtrToLong(callSite, args)
IntrinsicType.INTEROP_NATIVE_PTR_PLUS_LONG -> emitNativePtrPlusLong(args)
IntrinsicType.INTEROP_GET_NATIVE_NULL_PTR -> emitGetNativeNullPtr()
IntrinsicType.LIST_OF_INTERNAL -> emitListOfInternal(callSite, args)
IntrinsicType.IDENTITY -> emitIdentity(args)
IntrinsicType.GET_CONTINUATION -> emitGetContinuation()
IntrinsicType.RETURN_IF_SUSPEND,
IntrinsicType.INTEROP_BITS_TO_FLOAT,
IntrinsicType.INTEROP_BITS_TO_DOUBLE,
IntrinsicType.INTEROP_SIGN_EXTEND,
IntrinsicType.INTEROP_NARROW,
IntrinsicType.INTEROP_STATIC_C_FUNCTION,
IntrinsicType.INTEROP_FUNPTR_INVOKE,
IntrinsicType.INTEROP_CONVERT,
IntrinsicType.WORKER_EXECUTE ->
reportNonLoweredIntrinsic(intrinsicType)
IntrinsicType.INIT_INSTANCE,
IntrinsicType.OBJC_INIT_BY,
IntrinsicType.IMMUTABLE_BLOB ->
reportSpecialIntrinsic(intrinsicType)
}
private fun reportSpecialIntrinsic(intrinsicType: IntrinsicType): Nothing =
context.reportCompilationError("$intrinsicType should be handled by `tryEvaluateSpecialCall`")
private fun reportNonLoweredIntrinsic(intrinsicType: IntrinsicType): Nothing =
context.reportCompilationError("Intrinsic of type $intrinsicType should be handled by previos lowering phase")
private fun FunctionGenerationContext.emitGetContinuation(): LLVMValueRef =
continuationProvider()
environment.continuation
private fun FunctionGenerationContext.emitIdentity(args: List<LLVMValueRef>): LLVMValueRef =
args.single()
@@ -181,7 +279,7 @@ internal class IntrinsicGenerator(private val codegen: CodeGenerator,
val typeParameterT = context.ir.symbols.createUninitializedInstance.descriptor.typeParameters[0]
val enumClass = callSite.getTypeArgument(typeParameterT)!!
val enumIrClass = enumClass.getClass()!!
return allocInstance(enumIrClass, lifetimeCalculator(callSite))
return allocInstance(enumIrClass, environment.calculateLifetime(callSite))
}
private fun FunctionGenerationContext.emitGetPointerSize(): LLVMValueRef =
@@ -320,7 +418,7 @@ internal class IntrinsicGenerator(private val codegen: CodeGenerator,
private fun FunctionGenerationContext.emitGetObjCClass(callSite: IrCall): LLVMValueRef {
val descriptor = callSite.descriptor.original
val typeArgument = callSite.getTypeArgument(descriptor.typeParameters.single())
return getObjCClass(typeArgument!!.getClass()!!, exceptionHandlerProvider())
return getObjCClass(typeArgument!!.getClass()!!, environment.exceptionHandler)
}
private fun FunctionGenerationContext.emitObjCGetMessenger(args: List<LLVMValueRef>, isStret: Boolean): LLVMValueRef {
@@ -477,7 +575,7 @@ internal class IntrinsicGenerator(private val codegen: CodeGenerator,
private fun FunctionGenerationContext.emitThrowIfZero(divider: LLVMValueRef) {
ifThen(icmpEq(divider, Zero(divider.type).llvm)) {
val throwArithExc = codegen.llvmFunction(context.ir.symbols.throwArithmeticException.owner)
call(throwArithExc, emptyList(), Lifetime.GLOBAL, exceptionHandlerProvider())
call(throwArithExc, emptyList(), Lifetime.GLOBAL, environment.exceptionHandler)
unreachable()
}
}
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
private val threadLocalAnnotationFqName = FqName("kotlin.native.ThreadLocal")
private val sharedAnnotationFqName = FqName("kotlin.native.SharedImmutable")
@@ -297,9 +296,33 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
// TODO: consider eliminating mutable state
private var currentCodeContext: CodeContext = TopLevelCodeContext
private val intrinsicGenerator = IntrinsicGenerator(codegen,
::resultLifetime, ::getContinuation, { currentCodeContext.exceptionHandler })
private val intrinsicGeneratorEnvironment = object : IntrinsicGeneratorEnvironment {
override val codegen: CodeGenerator
get() = this@CodeGeneratorVisitor.codegen
override val functionGenerationContext: FunctionGenerationContext
get() = this@CodeGeneratorVisitor.functionGenerationContext
override fun calculateLifetime(element: IrElement): Lifetime =
resultLifetime(element)
override val continuation: LLVMValueRef
get() = getContinuation()
override val exceptionHandler: ExceptionHandler
get() = currentCodeContext.exceptionHandler
override fun evaluateCall(function: IrFunction, args: List<LLVMValueRef>, resultLifetime: Lifetime): LLVMValueRef =
evaluateSimpleFunctionCall(function, args, resultLifetime)
override fun evaluateExplicitArgs(expression: IrMemberAccessExpression): List<LLVMValueRef> =
this@CodeGeneratorVisitor.evaluateExplicitArgs(expression)
override fun evaluateExpression(value: IrExpression): LLVMValueRef =
this@CodeGeneratorVisitor.evaluateExpression(value)
}
private val intrinsicGenerator = IntrinsicGenerator(intrinsicGeneratorEnvironment)
/**
* Fake [CodeContext] that doesn't support any operation.
@@ -1803,50 +1826,11 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
return codegen.theUnitInstanceRef.llvm
}
// TODO: should be unified with other intrinsics
private fun evaluateSpecialIntrinsicCall(expression: IrFunctionAccessExpression): LLVMValueRef? {
val function = expression.symbol.owner
if (function.isIntrinsic) {
when (function.descriptor) {
context.interopBuiltIns.objCObjectInitBy -> {
val receiver = evaluateExpression(expression.extensionReceiver!!)
val irConstructorCall = expression.getValueArgument(0) as IrCall
val constructorDescriptor = irConstructorCall.symbol.owner as ClassConstructorDescriptor
val constructorArgs = evaluateExplicitArgs(irConstructorCall)
val args = listOf(receiver) + constructorArgs
callDirect(constructorDescriptor, args, Lifetime.IRRELEVANT)
return receiver
}
context.immutableBlobOf -> {
@Suppress("UNCHECKED_CAST")
val arg = expression.getValueArgument(0) as IrConst<String>
return context.llvm.staticData.createImmutableBlob(arg)
}
context.ir.symbols.initInstance.descriptor -> {
val callee = expression as IrCall
val initializer = callee.getValueArgument(1) as IrCall
val thiz = evaluateExpression(callee.getValueArgument(0)!!)
evaluateSimpleFunctionCall(
initializer.symbol.owner,
listOf(thiz) + evaluateExplicitArgs(initializer),
resultLifetime(initializer)
)
return codegen.theUnitInstanceRef.llvm
}
}
}
return null
}
//-------------------------------------------------------------------------//
private fun evaluateCall(value: IrFunctionAccessExpression): LLVMValueRef {
context.log{"evaluateCall : ${ir2string(value)}"}
evaluateSpecialIntrinsicCall(value)?.let { return it }
intrinsicGenerator.tryEvaluateSpecialCall(value)?.let { return it }
val args = evaluateExplicitArgs(value)
@@ -2103,8 +2087,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
args + getContinuation()
else args
return when {
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args, functionGenerationContext)
function.isIntrinsic -> context.reportCompilationError("Unexpected @Intrinsic function: ${function.name.asString()}")
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args)
function.origin == IrDeclarationOrigin.IR_BUILTINS_STUB -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded)
function is ConstructorDescriptor -> evaluateConstructorCall(callee, argsWithContinuationIfNeeded)
else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner)
@@ -398,7 +398,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
}
val llvmFunction = if (descriptor.isExternal) {
if (descriptor.isTypedIntrinsic || descriptor.isIntrinsic || descriptor.isObjCBridgeBased()) {
if (descriptor.isTypedIntrinsic || descriptor.isObjCBridgeBased()) {
return
}
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenDescriptors
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType
import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
@@ -774,235 +776,232 @@ private class InteropTransformer(val context: Context, val irFile: IrFile) : IrB
fun reportError(message: String): Nothing = context.reportCompilationError(message, irFile, expression)
val intrinsicType = tryGetIntrinsicType(expression)
if (intrinsicType != null) {
return when (intrinsicType) {
IntrinsicType.INTEROP_BITS_TO_FLOAT -> {
val argument = expression.getValueArgument(0)
if (argument is IrConst<*> && argument.kind == IrConstKind.Int) {
val floatValue = kotlinx.cinterop.bitsToFloat(argument.value as Int)
builder.irFloat(floatValue)
} else {
expression
}
}
IntrinsicType.INTEROP_BITS_TO_DOUBLE -> {
val argument = expression.getValueArgument(0)
if (argument is IrConst<*> && argument.kind == IrConstKind.Long) {
val doubleValue = kotlinx.cinterop.bitsToDouble(argument.value as Long)
builder.irDouble(doubleValue)
} else {
expression
}
}
IntrinsicType.INTEROP_STATIC_C_FUNCTION -> {
val irCallableReference = unwrapStaticFunctionArgument(expression.getValueArgument(0)!!)
if (irCallableReference == null || irCallableReference.getArguments().isNotEmpty()) {
context.reportCompilationError(
"${descriptor.fqNameSafe} must take an unbound, non-capturing function or lambda",
irFile, expression
)
// TODO: should probably be reported during analysis.
}
val targetSymbol = irCallableReference.symbol
val target = targetSymbol.owner
val signatureTypes = target.allParameters.map { it.type } + target.returnType
signatureTypes.forEachIndexed { index, type ->
type.ensureSupportedInCallbacks(
isReturnType = (index == signatureTypes.lastIndex),
reportError = ::reportError
)
}
descriptor.typeParameters.forEachIndexed { index, typeParameterDescriptor ->
val typeArgument = expression.getTypeArgument(typeParameterDescriptor)!!.toKotlinType()
val signatureType = signatureTypes[index].toKotlinType()
if (typeArgument.constructor != signatureType.constructor ||
typeArgument.isMarkedNullable != signatureType.isMarkedNullable) {
context.reportCompilationError(
"C function signature element mismatch: expected '$signatureType', got '$typeArgument'",
irFile, expression
)
}
}
IrFunctionReferenceImpl(
builder.startOffset, builder.endOffset,
expression.type,
targetSymbol, target.descriptor,
typeArgumentsCount = 0)
}
IntrinsicType.INTEROP_FUNPTR_INVOKE -> {
// Replace by `invokeImpl${type}Ret`:
val returnType =
expression.getTypeArgument(descriptor.typeParameters.single { it.name.asString() == "R" })!!
returnType.checkCTypeNullability(::reportError)
val invokeImpl = symbols.interopInvokeImpls[returnType.getClass()?.descriptor] ?:
context.reportCompilationError(
"Invocation of C function pointer with return type '${returnType.toKotlinType()}' is not supported yet",
irFile, expression
)
builder.irCall(invokeImpl).apply {
putValueArgument(0, expression.extensionReceiver)
val varargParameter = invokeImpl.owner.valueParameters[1]
val varargArgument = IrVarargImpl(
startOffset, endOffset, varargParameter.type, varargParameter.varargElementType!!
).apply {
descriptor.valueParameters.forEach {
this.addElement(expression.getValueArgument(it)!!)
}
}
putValueArgument(varargParameter.index, varargArgument)
}
}
IntrinsicType.INTEROP_SIGN_EXTEND, IntrinsicType.INTEROP_NARROW -> {
val integerTypePredicates = arrayOf(
IrType::isByte, IrType::isShort, IrType::isInt, IrType::isLong
)
val receiver = expression.extensionReceiver!!
val typeOperand = expression.getSingleTypeArgument()
val kotlinTypeOperand = typeOperand.toKotlinType()
val receiverTypeIndex = integerTypePredicates.indexOfFirst { it(receiver.type) }
val typeOperandIndex = integerTypePredicates.indexOfFirst { it(typeOperand) }
val receiverKotlinType = receiver.type.toKotlinType()
if (receiverTypeIndex == -1) {
context.reportCompilationError("Receiver's type $receiverKotlinType is not an integer type",
irFile, receiver)
}
if (typeOperandIndex == -1) {
context.reportCompilationError("Type argument $kotlinTypeOperand is not an integer type",
irFile, expression)
}
when (intrinsicType) {
IntrinsicType.INTEROP_SIGN_EXTEND -> if (receiverTypeIndex > typeOperandIndex) {
context.reportCompilationError("unable to sign extend $receiverKotlinType to $kotlinTypeOperand",
irFile, expression)
}
IntrinsicType.INTEROP_NARROW -> if (receiverTypeIndex < typeOperandIndex) {
context.reportCompilationError("unable to narrow $receiverKotlinType to $kotlinTypeOperand",
irFile, expression)
}
else -> throw Error()
}
val receiverClass = symbols.integerClasses.single {
receiver.type.isSubtypeOf(it.owner.defaultType)
}
val targetClass = symbols.integerClasses.single {
typeOperand.isSubtypeOf(it.owner.defaultType)
}
val conversionSymbol = receiverClass.functions.single {
it.descriptor.name == Name.identifier("to${targetClass.owner.name}")
}
builder.irCall(conversionSymbol).apply {
dispatchReceiver = receiver
}
}
IntrinsicType.INTEROP_CONVERT -> {
val integerClasses = symbols.allIntegerClasses
val typeOperand = expression.getTypeArgument(0)!!
val receiverType = expression.symbol.owner.extensionReceiverParameter!!.type
val source = receiverType.classifierOrFail as IrClassSymbol
assert(source in integerClasses)
if (typeOperand is IrSimpleType && typeOperand.classifier in integerClasses && !typeOperand.hasQuestionMark) {
val target = typeOperand.classifier as IrClassSymbol
val valueToConvert = expression.extensionReceiver!!
if (source in symbols.signedIntegerClasses && target in symbols.unsignedIntegerClasses) {
// Default Kotlin signed-to-unsigned widening integer conversions don't follow C rules.
val signedTarget = symbols.unsignedToSignedOfSameBitWidth[target]!!
val widened = builder.irConvertInteger(source, signedTarget, valueToConvert)
builder.irConvertInteger(signedTarget, target, widened)
} else {
builder.irConvertInteger(source, target, valueToConvert)
}
} else {
context.reportCompilationError(
"unable to convert ${receiverType.toKotlinType()} to ${typeOperand.toKotlinType()}",
irFile,
expression
)
}
}
IntrinsicType.OBJC_INIT_BY -> {
val intrinsic = interop.objCObjectInitBy.name
val argument = expression.getValueArgument(0)!!
val constructedClass =
((argument as? IrCall)?.descriptor as? ClassConstructorDescriptor)?.constructedClass
if (constructedClass == null) {
context.reportCompilationError("Argument of '$intrinsic' must be a constructor call",
irFile, argument)
}
val extensionReceiver = expression.extensionReceiver!!
if (extensionReceiver !is IrGetValue ||
extensionReceiver.descriptor != constructedClass.thisAsReceiverParameter) {
context.reportCompilationError("Receiver of '$intrinsic' must be a 'this' of the constructed class",
irFile, extensionReceiver)
}
expression
}
IntrinsicType.WORKER_EXECUTE -> {
val irCallableReference = unwrapStaticFunctionArgument(expression.getValueArgument(2)!!)
if (irCallableReference == null || irCallableReference.getArguments().isNotEmpty()) {
context.reportCompilationError(
"${descriptor.fqNameSafe} must take an unbound, non-capturing function or lambda",
irFile, expression
)
}
val targetSymbol = irCallableReference.symbol
val target = targetSymbol.descriptor
val jobPointer = IrFunctionReferenceImpl(
builder.startOffset, builder.endOffset,
symbols.executeImpl.owner.valueParameters[3].type,
targetSymbol, target,
typeArgumentsCount = 0)
builder.irCall(symbols.executeImpl).apply {
putValueArgument(0, expression.dispatchReceiver)
putValueArgument(1, expression.getValueArgument(0))
putValueArgument(2, expression.getValueArgument(1))
putValueArgument(3, jobPointer)
}
}
else -> expression
}
}
return when (descriptor) {
interop.cPointerRawValue.getter ->
// Replace by the intrinsic call to be handled by code generator:
builder.irCall(symbols.interopCPointerGetRawValue).apply {
extensionReceiver = expression.dispatchReceiver
}
interop.bitsToFloat -> {
val argument = expression.getValueArgument(0)
if (argument is IrConst<*> && argument.kind == IrConstKind.Int) {
val floatValue = kotlinx.cinterop.bitsToFloat(argument.value as Int)
builder.irFloat(floatValue)
} else {
expression
}
}
interop.bitsToDouble -> {
val argument = expression.getValueArgument(0)
if (argument is IrConst<*> && argument.kind == IrConstKind.Long) {
val doubleValue = kotlinx.cinterop.bitsToDouble(argument.value as Long)
builder.irDouble(doubleValue)
} else {
expression
}
}
in interop.staticCFunction -> {
val irCallableReference = unwrapStaticFunctionArgument(expression.getValueArgument(0)!!)
if (irCallableReference == null || irCallableReference.getArguments().isNotEmpty()) {
context.reportCompilationError(
"${descriptor.fqNameSafe} must take an unbound, non-capturing function or lambda",
irFile, expression
)
// TODO: should probably be reported during analysis.
}
val targetSymbol = irCallableReference.symbol
val target = targetSymbol.owner
val signatureTypes = target.allParameters.map { it.type } + target.returnType
signatureTypes.forEachIndexed { index, type ->
type.ensureSupportedInCallbacks(
isReturnType = (index == signatureTypes.lastIndex),
reportError = ::reportError
)
}
descriptor.typeParameters.forEachIndexed { index, typeParameterDescriptor ->
val typeArgument = expression.getTypeArgument(typeParameterDescriptor)!!.toKotlinType()
val signatureType = signatureTypes[index].toKotlinType()
if (typeArgument.constructor != signatureType.constructor ||
typeArgument.isMarkedNullable != signatureType.isMarkedNullable) {
context.reportCompilationError(
"C function signature element mismatch: expected '$signatureType', got '$typeArgument'",
irFile, expression
)
}
}
IrFunctionReferenceImpl(
builder.startOffset, builder.endOffset,
expression.type,
targetSymbol, target.descriptor,
typeArgumentsCount = 0)
}
interop.executeFunction -> {
val irCallableReference = unwrapStaticFunctionArgument(expression.getValueArgument(2)!!)
if (irCallableReference == null || irCallableReference.getArguments().isNotEmpty()) {
context.reportCompilationError(
"${descriptor.fqNameSafe} must take an unbound, non-capturing function or lambda",
irFile, expression
)
}
val targetSymbol = irCallableReference.symbol
val target = targetSymbol.descriptor
val jobPointer = IrFunctionReferenceImpl(
builder.startOffset, builder.endOffset,
symbols.executeImpl.owner.valueParameters[3].type,
targetSymbol, target,
typeArgumentsCount = 0)
builder.irCall(symbols.executeImpl).apply {
putValueArgument(0, expression.dispatchReceiver)
putValueArgument(1, expression.getValueArgument(0))
putValueArgument(2, expression.getValueArgument(1))
putValueArgument(3, jobPointer)
}
}
interop.signExtend, interop.narrow -> {
val integerTypePredicates = arrayOf(
IrType::isByte, IrType::isShort, IrType::isInt, IrType::isLong
)
val receiver = expression.extensionReceiver!!
val typeOperand = expression.getSingleTypeArgument()
val kotlinTypeOperand = typeOperand.toKotlinType()
val receiverTypeIndex = integerTypePredicates.indexOfFirst { it(receiver.type) }
val typeOperandIndex = integerTypePredicates.indexOfFirst { it(typeOperand) }
val receiverKotlinType = receiver.type.toKotlinType()
if (receiverTypeIndex == -1) {
context.reportCompilationError("Receiver's type $receiverKotlinType is not an integer type",
irFile, receiver)
}
if (typeOperandIndex == -1) {
context.reportCompilationError("Type argument $kotlinTypeOperand is not an integer type",
irFile, expression)
}
when (descriptor) {
interop.signExtend -> if (receiverTypeIndex > typeOperandIndex) {
context.reportCompilationError("unable to sign extend $receiverKotlinType to $kotlinTypeOperand",
irFile, expression)
}
interop.narrow -> if (receiverTypeIndex < typeOperandIndex) {
context.reportCompilationError("unable to narrow $receiverKotlinType to $kotlinTypeOperand",
irFile, expression)
}
else -> throw Error()
}
val receiverClass = symbols.integerClasses.single {
receiver.type.isSubtypeOf(it.owner.defaultType)
}
val targetClass = symbols.integerClasses.single {
typeOperand.isSubtypeOf(it.owner.defaultType)
}
val conversionSymbol = receiverClass.functions.single {
it.descriptor.name == Name.identifier("to${targetClass.owner.name}")
}
builder.irCall(conversionSymbol).apply {
dispatchReceiver = receiver
}
}
in interop.convert -> {
val integerClasses = symbols.allIntegerClasses
val typeOperand = expression.getTypeArgument(0)!!
val receiverType = expression.symbol.owner.extensionReceiverParameter!!.type
val source = receiverType.classifierOrFail as IrClassSymbol
assert(source in integerClasses)
if (typeOperand is IrSimpleType && typeOperand.classifier in integerClasses && !typeOperand.hasQuestionMark) {
val target = typeOperand.classifier as IrClassSymbol
val valueToConvert = expression.extensionReceiver!!
if (source in symbols.signedIntegerClasses && target in symbols.unsignedIntegerClasses) {
// Default Kotlin signed-to-unsigned widening integer conversions don't follow C rules.
val signedTarget = symbols.unsignedToSignedOfSameBitWidth[target]!!
val widened = builder.irConvertInteger(source, signedTarget, valueToConvert)
builder.irConvertInteger(signedTarget, target, widened)
} else {
builder.irConvertInteger(source, target, valueToConvert)
}
} else {
context.reportCompilationError(
"unable to convert ${receiverType.toKotlinType()} to ${typeOperand.toKotlinType()}",
irFile,
expression
)
}
}
in interop.cFunctionPointerInvokes -> {
// Replace by `invokeImpl${type}Ret`:
val returnType =
expression.getTypeArgument(descriptor.typeParameters.single { it.name.asString() == "R" })!!
returnType.checkCTypeNullability(::reportError)
val invokeImpl = symbols.interopInvokeImpls[returnType.getClass()?.descriptor] ?:
context.reportCompilationError(
"Invocation of C function pointer with return type '${returnType.toKotlinType()}' is not supported yet",
irFile, expression
)
builder.irCall(invokeImpl).apply {
putValueArgument(0, expression.extensionReceiver)
val varargParameter = invokeImpl.owner.valueParameters[1]
val varargArgument = IrVarargImpl(
startOffset, endOffset, varargParameter.type, varargParameter.varargElementType!!
).apply {
descriptor.valueParameters.forEach {
this.addElement(expression.getValueArgument(it)!!)
}
}
putValueArgument(varargParameter.index, varargArgument)
}
}
interop.objCObjectInitBy -> {
val intrinsic = interop.objCObjectInitBy.name
val argument = expression.getValueArgument(0)!!
val constructedClass =
((argument as? IrCall)?.descriptor as? ClassConstructorDescriptor)?.constructedClass
if (constructedClass == null) {
context.reportCompilationError("Argument of '$intrinsic' must be a constructor call",
irFile, argument)
}
val extensionReceiver = expression.extensionReceiver!!
if (extensionReceiver !is IrGetValue ||
extensionReceiver.descriptor != constructedClass.thisAsReceiverParameter) {
context.reportCompilationError("Receiver of '$intrinsic' must be a 'this' of the constructed class",
irFile, extensionReceiver)
}
expression
}
else -> expression
}
}
@@ -82,5 +82,5 @@ private external fun ImmutableBlob.asCPointerImpl(offset: Int): kotlin.native.in
* One element still represent one byte in the output data.
* This is the only way to create ImmutableBlob for now.
*/
@Intrinsic
@TypedIntrinsic(IntrinsicType.IMMUTABLE_BLOB)
public external fun immutableBlobOf(vararg elements: Short): ImmutableBlob
@@ -8,6 +8,8 @@ package kotlin.native.concurrent
import kotlin.native.internal.ExportForCppRuntime
import kotlin.native.internal.Frozen
import kotlin.native.internal.VolatileLambda
import kotlin.native.internal.IntrinsicType
import kotlin.native.internal.TypedIntrinsic
import kotlinx.cinterop.*
/**
@@ -69,6 +71,7 @@ public inline class Worker @PublishedApi internal constructor(val id: Int) {
* @return the future with the computation result of [job]
*/
@Suppress("UNUSED_PARAMETER")
@TypedIntrinsic(IntrinsicType.WORKER_EXECUTE)
public fun <T1, T2> execute(mode: TransferMode, producer: () -> T1, @VolatileLambda job: (T1) -> T2): Future<T2> =
/*
* This function is a magical operation, handled by lowering in the compiler, and replaced with call to
@@ -22,6 +22,6 @@ internal external fun <T> getContinuation(): Continuation<T>
internal inline suspend fun getCoroutineContext(): CoroutineContext =
getContinuation<Any?>().context
@Intrinsic
@TypedIntrinsic(IntrinsicType.RETURN_IF_SUSPEND)
@PublishedApi
internal external suspend fun <T> returnIfSuspended(@Suppress("UNUSED_PARAMETER") argument: Any?): T
@@ -35,27 +35,43 @@ class IntrinsicType {
const val REINTERPRET = "REINTERPRET"
const val ARE_EQUAL_BY_VALUE = "ARE_EQUAL_BY_VALUE"
const val IEEE_754_EQUALS = "IEEE_754_EQUALS"
// ObjC related stuff
const val OBJC_GET_MESSENGER = "OBJC_GET_MESSENGER"
const val OBJC_GET_MESSENGER_STRET = "OBJC_GET_MESSENGER_STRET"
const val OBJC_GET_OBJC_CLASS = "OBJC_GET_OBJC_CLASS"
const val OBJC_GET_RECEIVER_OR_SUPER = "OBJC_GET_RECEIVER_OR_SUPER"
const val OBJC_INIT_BY = "OBJC_INIT_BY"
// Other
const val GET_CLASS_TYPE_INFO = "GET_CLASS_TYPE_INFO"
const val READ_BITS = "READ_BITS"
const val WRITE_BITS = "WRITE_BITS"
const val INTEROP_READ_BITS = "INTEROP_READ_BITS"
const val INTEROP_WRITE_BITS = "INTEROP_WRITE_BITS"
const val CREATE_UNINITIALIZED_INSTANCE = "CREATE_UNINITIALIZED_INSTANCE"
const val LIST_OF_INTERNAL = "LIST_OF_INTERNAL"
const val IDENTITY = "IDENTITY"
const val IMMUTABLE_BLOB = "IMMUTABLE_BLOB"
const val INIT_INSTANCE = "INIT_INSTANCE"
const val GET_CONTINUATION = "GET_CONTINUATION"
const val RETURN_IF_SUSPEND = "RETURN_IF_SUSPEND"
// Interop
const val READ_PRIMITIVE = "READ_PRIMITIVE"
const val WRITE_PRIMITIVE = "WRITE_PRIMITIVE"
const val GET_POINTER_SIZE = "GET_POINTER_SIZE"
const val NATIVE_PTR_TO_LONG = "NATIVE_PTR_TO_LONG"
const val NATIVE_PTR_PLUS_LONG = "NATIVE_PTR_PLUS_LONG"
const val GET_NATIVE_NULL_PTR = "GET_NATIVE_NULL_PTR"
const val INTEROP_READ_PRIMITIVE = "INTEROP_READ_PRIMITIVE"
const val INTEROP_WRITE_PRIMITIVE = "INTEROP_WRITE_PRIMITIVE"
const val INTEROP_GET_POINTER_SIZE = "INTEROP_GET_POINTER_SIZE"
const val INTEROP_NATIVE_PTR_TO_LONG = "INTEROP_NATIVE_PTR_TO_LONG"
const val INTEROP_NATIVE_PTR_PLUS_LONG = "INTEROP_NATIVE_PTR_PLUS_LONG"
const val INTEROP_GET_NATIVE_NULL_PTR = "INTEROP_GET_NATIVE_NULL_PTR"
const val INTEROP_CONVERT = "INTEROP_CONVERT"
const val INTEROP_BITS_TO_FLOAT = "INTEROP_BITS_TO_FLOAT"
const val INTEROP_BITS_TO_DOUBLE = "INTEROP_BITS_TO_DOUBLE"
const val INTEROP_SIGN_EXTEND = "INTEROP_SIGN_EXTEND"
const val INTEROP_NARROW = "INTEROP_NARROW"
const val INTEROP_STATIC_C_FUNCTION = "INTEROP_STATIC_C_FUNCTION"
const val INTEROP_FUNPTR_INVOKE = "INTEROP_FUNPTR_INVOKE"
// Worker
const val WORKER_EXECUTE = "WORKER_EXECUTE"
}
}
@@ -7,7 +7,7 @@
package kotlin.native.internal
@TypedIntrinsic(IntrinsicType.GET_NATIVE_NULL_PTR)
@TypedIntrinsic(IntrinsicType.INTEROP_GET_NATIVE_NULL_PTR)
external fun getNativeNullPtr(): NativePtr
class NativePtr @PublishedApi internal constructor(private val value: NonNullNativePtr?) {
@@ -15,10 +15,10 @@ class NativePtr @PublishedApi internal constructor(private val value: NonNullNat
val NULL = getNativeNullPtr()
}
@TypedIntrinsic(IntrinsicType.NATIVE_PTR_PLUS_LONG)
@TypedIntrinsic(IntrinsicType.INTEROP_NATIVE_PTR_PLUS_LONG)
external operator fun plus(offset: Long): NativePtr
@TypedIntrinsic(IntrinsicType.NATIVE_PTR_TO_LONG)
@TypedIntrinsic(IntrinsicType.INTEROP_NATIVE_PTR_TO_LONG)
external fun toLong(): Long
override fun equals(other: Any?) = (other is NativePtr) && kotlin.native.internal.areEqualByValue(this, other)
@@ -120,7 +120,7 @@ fun <T: Enum<T>> valuesForEnum(values: Array<T>): Array<T> {
@TypedIntrinsic(IntrinsicType.CREATE_UNINITIALIZED_INSTANCE)
internal external fun <T> createUninitializedInstance(): T
@Intrinsic
@TypedIntrinsic(IntrinsicType.INIT_INSTANCE)
internal external fun initInstance(thiz: Any, constructorCall: Any): Unit
fun checkProgressionStep(step: Int) = if (step > 0) step else throw IllegalArgumentException("Step must be positive, was: $step.")