Moved NativePtr from interop to konan.internal

This commit is contained in:
Igor Chevdar
2017-04-26 12:56:24 +03:00
parent 0750626c29
commit adc1faa6c5
9 changed files with 75 additions and 36 deletions
@@ -1,24 +1,13 @@
package kotlinx.cinterop package kotlinx.cinterop
import konan.internal.getNativeNullPtr
import konan.internal.Intrinsic import konan.internal.Intrinsic
class NativePtr private constructor() { typealias NativePtr = konan.internal.NativePtr
@Intrinsic external operator fun plus(offset: Long): NativePtr
@Intrinsic external fun toLong(): Long
override fun equals(other: Any?) = (other is NativePtr) && konan.internal.areEqualByValue(this, other)
override fun hashCode() = this.toLong().hashCode()
override fun toString() = this.toLong().toString() // TODO: format as hex.
}
inline val nativeNullPtr: NativePtr inline val nativeNullPtr: NativePtr
get() = getNativeNullPtr() get() = getNativeNullPtr()
@Intrinsic external fun getNativeNullPtr(): NativePtr
fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument") fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument")
/** /**
@@ -30,28 +30,22 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
private val cPointerName = "CPointer" private val cPointerName = "CPointer"
private val nativePointedName = "NativePointed" private val nativePointedName = "NativePointed"
private val nativePtrName = "NativePtr"
internal class InteropBuiltIns(builtIns: KonanBuiltIns) { internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
object FqNames { object FqNames {
val packageName = FqName("kotlinx.cinterop") val packageName = FqName("kotlinx.cinterop")
val nativePtr = packageName.child(Name.identifier(nativePtrName)).toUnsafe()
val cPointer = packageName.child(Name.identifier(cPointerName)).toUnsafe() val cPointer = packageName.child(Name.identifier(cPointerName)).toUnsafe()
val nativePointed = packageName.child(Name.identifier(nativePointedName)).toUnsafe() val nativePointed = packageName.child(Name.identifier(nativePointedName)).toUnsafe()
} }
private val packageScope = builtIns.builtInsModule.getPackage(FqNames.packageName).memberScope private val packageScope = builtIns.builtInsModule.getPackage(FqNames.packageName).memberScope
val getNativeNullPtr = packageScope.getContributedFunctions("getNativeNullPtr").single()
val getPointerSize = packageScope.getContributedFunctions("getPointerSize").single() val getPointerSize = packageScope.getContributedFunctions("getPointerSize").single()
val nullableInteropValueTypes = listOf(ValueType.C_POINTER, ValueType.NATIVE_POINTED) val nullableInteropValueTypes = listOf(ValueType.C_POINTER, ValueType.NATIVE_POINTED)
private val nativePtr = packageScope.getContributedClassifier(nativePtrName) as ClassDescriptor
private val nativePointed = packageScope.getContributedClassifier(nativePointedName) as ClassDescriptor private val nativePointed = packageScope.getContributedClassifier(nativePointedName) as ClassDescriptor
val cPointer = this.packageScope.getContributedClassifier(cPointerName) as ClassDescriptor val cPointer = this.packageScope.getContributedClassifier(cPointerName) as ClassDescriptor
@@ -125,7 +119,7 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
private val primitives = listOf( private val primitives = listOf(
builtIns.byte, builtIns.short, builtIns.int, builtIns.long, builtIns.byte, builtIns.short, builtIns.int, builtIns.long,
builtIns.float, builtIns.double, builtIns.float, builtIns.double,
nativePtr builtIns.nativePtr
) )
val readPrimitive = primitives.map { val readPrimitive = primitives.map {
@@ -136,10 +130,6 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
nativeMemUtils.unsubstitutedMemberScope.getContributedFunctions("put" + it.name).single() nativeMemUtils.unsubstitutedMemberScope.getContributedFunctions("put" + it.name).single()
}.toSet() }.toSet()
val nativePtrPlusLong = nativePtr.unsubstitutedMemberScope.getContributedFunctions("plus").single()
val nativePtrToLong = nativePtr.unsubstitutedMemberScope.getContributedFunctions("toLong").single()
val bitsToFloat = packageScope.getContributedFunctions("bitsToFloat").single() val bitsToFloat = packageScope.getContributedFunctions("bitsToFloat").single()
val bitsToDouble = packageScope.getContributedFunctions("bitsToDouble").single() val bitsToDouble = packageScope.getContributedFunctions("bitsToDouble").single()
@@ -17,13 +17,16 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.PlatformConfigurator import org.jetbrains.kotlin.resolve.PlatformConfigurator
import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
val STDLIB_MODULE_NAME = Name.special("<stdlib>") val STDLIB_MODULE_NAME = Name.special("<stdlib>")
@@ -32,9 +35,31 @@ fun ModuleDescriptor.isStdlib(): Boolean {
return name == STDLIB_MODULE_NAME return name == STDLIB_MODULE_NAME
} }
private val nativePtrName = "NativePtr"
class KonanBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManager) { class KonanBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManager) {
override fun getClassDescriptorFactories() = override fun getClassDescriptorFactories() =
super.getClassDescriptorFactories() + KonanBuiltInClassDescriptorFactory(storageManager, builtInsModule) super.getClassDescriptorFactories() + KonanBuiltInClassDescriptorFactory(storageManager, builtInsModule)
object FqNames {
val packageName = FqName("konan.internal")
val nativePtr = packageName.child(Name.identifier(nativePtrName)).toUnsafe()
}
private val packageScope by lazy { builtInsModule.getPackage(FqNames.packageName).memberScope }
val nativePtr by lazy { packageScope.getContributedClassifier(nativePtrName) as ClassDescriptor }
val nativePtrPlusLong by lazy { nativePtr.unsubstitutedMemberScope.getContributedFunctions("plus").single() }
val nativePtrToLong by lazy { nativePtr.unsubstitutedMemberScope.getContributedFunctions("toLong").single() }
val getNativeNullPtr by lazy { packageScope.getContributedFunctions("getNativeNullPtr").single() }
private fun MemberScope.getContributedClassifier(name: String) =
this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
private fun MemberScope.getContributedFunctions(name: String) =
this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
} }
object KonanPlatform : TargetPlatform("Konan") { object KonanPlatform : TargetPlatform("Konan") {
@@ -41,7 +41,7 @@ enum class ValueType(val classFqName: FqNameUnsafe, val isNullable: Boolean = fa
DOUBLE(KotlinBuiltIns.FQ_NAMES._double), DOUBLE(KotlinBuiltIns.FQ_NAMES._double),
UNBOUND_CALLABLE_REFERENCE(FqNameUnsafe("konan.internal.UnboundCallableReference")), UNBOUND_CALLABLE_REFERENCE(FqNameUnsafe("konan.internal.UnboundCallableReference")),
NATIVE_PTR(InteropBuiltIns.FqNames.nativePtr), NATIVE_PTR(KonanBuiltIns.FqNames.nativePtr),
NATIVE_POINTED(InteropBuiltIns.FqNames.nativePointed, isNullable = true), NATIVE_POINTED(InteropBuiltIns.FqNames.nativePointed, isNullable = true),
C_POINTER(InteropBuiltIns.FqNames.cPointer, isNullable = true) C_POINTER(InteropBuiltIns.FqNames.cPointer, isNullable = true)
@@ -1799,13 +1799,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
val resumePoints = mutableListOf<LLVMBasicBlockRef>() val resumePoints = mutableListOf<LLVMBasicBlockRef>()
using (SuspendableExpressionScope(resumePoints)) { using (SuspendableExpressionScope(resumePoints)) {
codegen.condBr(codegen.icmpEq(suspensionPointId, kIntPtrZero), bbStart, bbDispatch) codegen.condBr(codegen.icmpEq(suspensionPointId, kNullInt8Ptr), bbStart, bbDispatch)
codegen.positionAtEnd(bbStart) codegen.positionAtEnd(bbStart)
val result = evaluateExpression(expression.result) val result = evaluateExpression(expression.result)
codegen.appendingTo(bbDispatch) { codegen.appendingTo(bbDispatch) {
codegen.indirectBr(codegen.intToPtr(suspensionPointId, int8TypePtr), resumePoints) codegen.indirectBr(suspensionPointId, resumePoints)
} }
return result return result
} }
@@ -1815,7 +1815,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
val bbResume: LLVMBasicBlockRef): InnerScopeImpl() { val bbResume: LLVMBasicBlockRef): InnerScopeImpl() {
override fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef { override fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef {
if (descriptor == suspensionPointId) if (descriptor == suspensionPointId)
return codegen.ptrToInt(codegen.blockAddress(bbResume), LLVMInt64Type()!!) // TODO: intptr. return codegen.blockAddress(bbResume)
return super.genGetValue(descriptor) return super.genGetValue(descriptor)
} }
} }
@@ -1979,10 +1979,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
codegen.store(args[2], pointer) codegen.store(args[2], pointer)
codegen.theUnitInstanceRef.llvm codegen.theUnitInstanceRef.llvm
} }
interop.nativePtrPlusLong -> codegen.gep(args[0], args[1]) context.builtIns.nativePtrPlusLong -> codegen.gep(args[0], args[1])
interop.getNativeNullPtr -> kNullInt8Ptr context.builtIns.getNativeNullPtr -> kNullInt8Ptr
interop.getPointerSize -> Int32(LLVMPointerSize(codegen.llvmTargetData)).llvm interop.getPointerSize -> Int32(LLVMPointerSize(codegen.llvmTargetData)).llvm
interop.nativePtrToLong -> { context.builtIns.nativePtrToLong -> {
val intPtrValue = codegen.ptrToInt(args.single(), codegen.intPtrType) val intPtrValue = codegen.ptrToInt(args.single(), codegen.intPtrType)
val resultType = codegen.getLLVMType(descriptor.returnType!!) val resultType = codegen.getLLVMType(descriptor.returnType!!)
@@ -146,7 +146,7 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
override fun IrExpression.useAs(type: KotlinType): IrExpression { override fun IrExpression.useAs(type: KotlinType): IrExpression {
val interop = context.interopBuiltIns val interop = context.interopBuiltIns
if (this.isNullConst() && interop.nullableInteropValueTypes.any { type.isRepresentedAs(it) }) { if (this.isNullConst() && interop.nullableInteropValueTypes.any { type.isRepresentedAs(it) }) {
return IrCallImpl(startOffset, endOffset, interop.getNativeNullPtr).uncheckedCast(type) return IrCallImpl(startOffset, endOffset, context.builtIns.getNativeNullPtr).uncheckedCast(type)
} }
val actualType = when (this) { val actualType = when (this) {
@@ -60,6 +60,7 @@ internal class InteropLowering(val context: Context) : FileLoweringPass {
private class InteropTransformer(val context: Context, val irFile: IrFile) : IrBuildingTransformer(context) { private class InteropTransformer(val context: Context, val irFile: IrFile) : IrBuildingTransformer(context) {
val interop = context.interopBuiltIns val interop = context.interopBuiltIns
val konanBuiltins = context.builtIns
private fun MemberScope.getSingleContributedFunction(name: String, private fun MemberScope.getSingleContributedFunction(name: String,
predicate: (SimpleFunctionDescriptor) -> Boolean) = predicate: (SimpleFunctionDescriptor) -> Boolean) =
@@ -119,7 +120,7 @@ private class InteropTransformer(val context: Context, val irFile: IrFile) : IrB
val elementType = array.type.arguments.single().type val elementType = array.type.arguments.single().type
val elementSize = sizeOf(elementType) ?: return null val elementSize = sizeOf(elementType) ?: return null
val resultRawPtr = irCall(interop.nativePtrPlusLong).apply { val resultRawPtr = irCall(konanBuiltins.nativePtrPlusLong).apply {
dispatchReceiver = irCall(interop.cPointerGetRawValue).apply { dispatchReceiver = irCall(interop.cPointerGetRawValue).apply {
extensionReceiver = array extensionReceiver = array
} }
@@ -89,8 +89,7 @@ abstract internal class CoroutineImpl(
// label == -1 when coroutine cannot be started (it is just a factory object) or has already finished execution // label == -1 when coroutine cannot be started (it is just a factory object) or has already finished execution
// label == 0 in initial part of the coroutine // label == 0 in initial part of the coroutine
// TODO: use IntPtr. protected var label: NativePtr = if (completion != null) NativePtr.NULL else NativePtr.NULL + (-1L)
protected var label: Long = if (completion != null) 0L else -1L
private val _context: CoroutineContext? = completion?.context private val _context: CoroutineContext? = completion?.context
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package konan.internal
@Intrinsic external fun getNativeNullPtr(): NativePtr
class NativePtr private constructor() {
companion object {
val NULL = getNativeNullPtr()
}
@Intrinsic external operator fun plus(offset: Long): NativePtr
@Intrinsic external fun toLong(): Long
override fun equals(other: Any?) = (other is NativePtr) && konan.internal.areEqualByValue(this, other)
override fun hashCode() = this.toLong().hashCode()
override fun toString() = "0x${this.toLong().toString(16)}"
}