From 5068a99b6991700ec7ee603c1c64b932e60ea77b Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 19 Sep 2016 18:19:57 +0300 Subject: [PATCH] Interop: improve types and runtime * add some utility methods * add "placements" * fix "==" implementation for native pointers --- .../src/kotlin_native/interop/Types.kt | 57 +++++++++++++++++++ .../src/kotlin_native/interop/Utils.kt | 10 +++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/experiments/Interop/Runtime/src/kotlin_native/interop/Types.kt b/experiments/Interop/Runtime/src/kotlin_native/interop/Types.kt index c8629633839..1b2533eb85e 100644 --- a/experiments/Interop/Runtime/src/kotlin_native/interop/Types.kt +++ b/experiments/Interop/Runtime/src/kotlin_native/interop/Types.kt @@ -1,10 +1,23 @@ package kotlin_native.interop +import java.io.Closeable + // TODO: what about equals/hashCode? open class NativeRef(val ptr: NativePtr) { open class Type(val byPtr: (NativePtr) -> T) open class TypeWithSize(val size: Int, byPtr: (NativePtr) -> T) : NativeRef.Type(byPtr) + + final override fun equals(other: Any?): Boolean{ + if (this === other) return true + if (other !is NativeRef) return false + + return ptr == other.ptr + } + + final override fun hashCode(): Int{ + return ptr.hashCode() + } } fun NativePtr?.asRef(type: NativeRef.Type) = this?.let { type.byPtr(this) } @@ -138,4 +151,48 @@ class CString private constructor(internal val array: NativeArray) : Na } return String(bytes) // TODO: encoding } + + fun asCharPtr() = array[0] +} + +class __va_list_tag(ptr: NativePtr) : NativeRef(ptr) // FIXME + +interface Placement { + fun alloc(size: Int): NativePtr +} + +object heap : Placement { + override fun alloc(size: Int) = bridge.malloc(size) + + fun free(ptr: NativePtr) = bridge.free(ptr) + + fun free(ref: NativeRef) = free(ref.ptr) +} + +// TODO: implement optimally +class Arena : Placement, Closeable { + + private val allocatedChunks = mutableListOf() + + override fun alloc(size: Int): NativePtr { + val res = heap.alloc(size) + try { + allocatedChunks.add(res) + return res + } catch (e: Throwable) { + heap.free(res) + throw e + } + } + + fun clear() { + allocatedChunks.forEach { + heap.free(it) + } + + allocatedChunks.clear() + } + + override fun close() = clear() + } \ No newline at end of file diff --git a/experiments/Interop/Runtime/src/kotlin_native/interop/Utils.kt b/experiments/Interop/Runtime/src/kotlin_native/interop/Utils.kt index a8ce8a3b0a6..cc60ae9571f 100644 --- a/experiments/Interop/Runtime/src/kotlin_native/interop/Utils.kt +++ b/experiments/Interop/Runtime/src/kotlin_native/interop/Utils.kt @@ -2,12 +2,12 @@ package kotlin_native.interop fun malloc(type: NativeRef.TypeWithSize) = type.byPtr(bridge.malloc(type.size)) -fun malloc(type: NativeRef.TypeWithSize, action: (T) -> R): R { +inline fun malloc(type: NativeRef.TypeWithSize, action: (T) -> R): R { val ref = malloc(type) try { return action(ref) } finally { - bridge.free(ref.ptr) + free(ref) } } @@ -42,4 +42,8 @@ fun CString.Companion.fromString(str: String?): CString? { nativeBytes[len].value = 0 return CString.fromArray(nativeBytes) -} \ No newline at end of file +} + +fun NativeArray.asCString() = CString.fromArray(this) +fun Int8Box.asCString() = CString.fromArray(NativeArray.byRefToFirstElem(this, Int8Box)) +fun String.toCString() = CString.fromString(this) \ No newline at end of file