Simplify working with values in interop
* Access primitive interop array elements and struct fields without `.value` * Simplify C*Var* interop types names
This commit is contained in:
committed by
SvyatoslavScherbina
parent
f94a47518a
commit
50c3be3fc2
File diff suppressed because it is too large
Load Diff
+11
-11
@@ -287,9 +287,9 @@ internal class NativeIndexImpl(val library: NativeLibrary) : NativeIndex() {
|
|||||||
|
|
||||||
fun indexDeclaration(info: CXIdxDeclInfo): Unit {
|
fun indexDeclaration(info: CXIdxDeclInfo): Unit {
|
||||||
val cursor = info.cursor.readValue()
|
val cursor = info.cursor.readValue()
|
||||||
val entityInfo = info.entityInfo.pointed!!
|
val entityInfo = info.entityInfo!!.pointed
|
||||||
val entityName = entityInfo.name.value?.toKString()
|
val entityName = entityInfo.name?.toKString()
|
||||||
val kind = entityInfo.kind.value
|
val kind = entityInfo.kind
|
||||||
|
|
||||||
if (!this.library.includesDeclaration(cursor)) {
|
if (!this.library.includesDeclaration(cursor)) {
|
||||||
return
|
return
|
||||||
@@ -361,18 +361,18 @@ private fun indexDeclarations(library: NativeLibrary, nativeIndex: NativeIndexIm
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
with(callbacks) {
|
with(callbacks) {
|
||||||
abortQuery.value = null
|
abortQuery = null
|
||||||
diagnostic.value = null
|
diagnostic = null
|
||||||
enteredMainFile.value = null
|
enteredMainFile = null
|
||||||
ppIncludedFile.value = null
|
ppIncludedFile = null
|
||||||
importedASTFile.value = null
|
importedASTFile = null
|
||||||
startedTranslationUnit.value = null
|
startedTranslationUnit = null
|
||||||
indexDeclaration.value = staticCFunction { clientData, info ->
|
indexDeclaration = staticCFunction { clientData, info ->
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val nativeIndex = StableObjPtr.fromValue(clientData!!).get() as NativeIndexImpl
|
val nativeIndex = StableObjPtr.fromValue(clientData!!).get() as NativeIndexImpl
|
||||||
nativeIndex.indexDeclaration(info!!.pointed)
|
nativeIndex.indexDeclaration(info!!.pointed)
|
||||||
}
|
}
|
||||||
indexEntityReference.value = null
|
indexEntityReference = null
|
||||||
}
|
}
|
||||||
|
|
||||||
clang_indexTranslationUnit(indexAction, clientData,
|
clang_indexTranslationUnit(indexAction, clientData,
|
||||||
|
|||||||
+3
-3
@@ -20,9 +20,9 @@ import clang.*
|
|||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal val CValue<CXType>.kind: CXTypeKind get() = this.useContents { kind.value }
|
internal val CValue<CXType>.kind: CXTypeKind get() = this.useContents { kind }
|
||||||
|
|
||||||
internal val CValue<CXCursor>.kind: CXCursorKind get() = this.useContents { kind.value }
|
internal val CValue<CXCursor>.kind: CXCursorKind get() = this.useContents { kind }
|
||||||
|
|
||||||
internal fun CValue<CXString>.convertAndDispose(): String {
|
internal fun CValue<CXString>.convertAndDispose(): String {
|
||||||
try {
|
try {
|
||||||
@@ -137,7 +137,7 @@ internal fun CValue<CXCursor>.isLeaf(): Boolean {
|
|||||||
return !hasChildren
|
return !hasChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun List<String>.toNativeStringArray(placement: NativePlacement): CArrayPointer<CPointerVar<CInt8Var>> {
|
internal fun List<String>.toNativeStringArray(placement: NativePlacement): CArrayPointer<CPointerVar<ByteVar>> {
|
||||||
return placement.allocArray(this.size) { index ->
|
return placement.allocArray(this.size) { index ->
|
||||||
this.value = this@toNativeStringArray[index].cstr.getPointer(placement)
|
this.value = this@toNativeStringArray[index].cstr.getPointer(placement)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.cinterop
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Byte> CPointer<ByteVarOf<T>>.get(index: Int): T =
|
||||||
|
interpretPointed<ByteVarOf<T>>(this.rawValue + index * 1L).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Byte> CPointer<ByteVarOf<T>>.set(index: Int, value: T) {
|
||||||
|
interpretPointed<ByteVarOf<T>>(this.rawValue + index * 1L).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$Byte")
|
||||||
|
operator fun <T : ByteVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * 1L)
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Short> CPointer<ShortVarOf<T>>.get(index: Int): T =
|
||||||
|
interpretPointed<ShortVarOf<T>>(this.rawValue + index * 2L).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Short> CPointer<ShortVarOf<T>>.set(index: Int, value: T) {
|
||||||
|
interpretPointed<ShortVarOf<T>>(this.rawValue + index * 2L).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$Short")
|
||||||
|
operator fun <T : ShortVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * 2L)
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Int> CPointer<IntVarOf<T>>.get(index: Int): T =
|
||||||
|
interpretPointed<IntVarOf<T>>(this.rawValue + index * 4L).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Int> CPointer<IntVarOf<T>>.set(index: Int, value: T) {
|
||||||
|
interpretPointed<IntVarOf<T>>(this.rawValue + index * 4L).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$Int")
|
||||||
|
operator fun <T : IntVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * 4L)
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Long> CPointer<LongVarOf<T>>.get(index: Int): T =
|
||||||
|
interpretPointed<LongVarOf<T>>(this.rawValue + index * 8L).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Long> CPointer<LongVarOf<T>>.set(index: Int, value: T) {
|
||||||
|
interpretPointed<LongVarOf<T>>(this.rawValue + index * 8L).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$Long")
|
||||||
|
operator fun <T : LongVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * 8L)
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Float> CPointer<FloatVarOf<T>>.get(index: Int): T =
|
||||||
|
interpretPointed<FloatVarOf<T>>(this.rawValue + index * 4L).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Float> CPointer<FloatVarOf<T>>.set(index: Int, value: T) {
|
||||||
|
interpretPointed<FloatVarOf<T>>(this.rawValue + index * 4L).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$Float")
|
||||||
|
operator fun <T : FloatVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * 4L)
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Double> CPointer<DoubleVarOf<T>>.get(index: Int): T =
|
||||||
|
interpretPointed<DoubleVarOf<T>>(this.rawValue + index * 8L).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : Double> CPointer<DoubleVarOf<T>>.set(index: Int, value: T) {
|
||||||
|
interpretPointed<DoubleVarOf<T>>(this.rawValue + index * 8L).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$Double")
|
||||||
|
operator fun <T : DoubleVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * 8L)
|
||||||
|
|
||||||
|
/* Generated by:
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function gen {
|
||||||
|
echo '@Suppress("FINAL_UPPER_BOUND")'
|
||||||
|
echo "operator fun <T : $1> CPointer<${1}VarOf<T>>.get(index: Int): T ="
|
||||||
|
echo " interpretPointed<${1}VarOf<T>>(this.rawValue + index * ${2}L).value"
|
||||||
|
echo
|
||||||
|
echo '@Suppress("FINAL_UPPER_BOUND")'
|
||||||
|
echo "operator fun <T : $1> CPointer<${1}VarOf<T>>.set(index: Int, value: T) {"
|
||||||
|
echo " interpretPointed<${1}VarOf<T>>(this.rawValue + index * ${2}L).value = value"
|
||||||
|
echo '}'
|
||||||
|
echo
|
||||||
|
echo '@Suppress("FINAL_UPPER_BOUND")'
|
||||||
|
echo "@JvmName(\"plus\\\$$1\")"
|
||||||
|
echo "operator fun <T : ${1}Var> CPointer<T>?.plus(index: Int): CPointer<T>? ="
|
||||||
|
echo " interpretCPointer(this.rawValue + index * ${2}L)"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
gen Byte 1
|
||||||
|
gen Short 2
|
||||||
|
gen Int 4
|
||||||
|
gen Long 8
|
||||||
|
gen Float 4
|
||||||
|
gen Double 8
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -174,7 +174,7 @@ typealias COpaquePointer = CPointer<out CPointed> // FIXME
|
|||||||
/**
|
/**
|
||||||
* The variable containing a [COpaquePointer].
|
* The variable containing a [COpaquePointer].
|
||||||
*/
|
*/
|
||||||
typealias COpaquePointerVar = CPointerVarWithValueMappedTo<COpaquePointer>
|
typealias COpaquePointerVar = CPointerVarOf<COpaquePointer>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The C data variable located in memory.
|
* The C data variable located in memory.
|
||||||
@@ -238,89 +238,89 @@ abstract class CEnumVar : CPrimitiveVar()
|
|||||||
// these classes are not supposed to be used directly, instead the typealiases are provided.
|
// these classes are not supposed to be used directly, instead the typealiases are provided.
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND")
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
class CInt8VarWithValueMappedTo<T : Byte>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
class ByteVarOf<T : Byte>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
||||||
companion object : Type(1)
|
companion object : Type(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND")
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
class CInt16VarWithValueMappedTo<T : Short>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
class ShortVarOf<T : Short>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
||||||
companion object : Type(2)
|
companion object : Type(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND")
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
class CInt32VarWithValueMappedTo<T : Int>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
class IntVarOf<T : Int>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
||||||
companion object : Type(4)
|
companion object : Type(4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND")
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
class CInt64VarWithValueMappedTo<T : Long>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
class LongVarOf<T : Long>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
||||||
companion object : Type(8)
|
companion object : Type(8)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND")
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
class CFloat32VarWithValueMappedTo<T : Float>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
class FloatVarOf<T : Float>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
||||||
companion object : Type(4)
|
companion object : Type(4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND")
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
class CFloat64VarWithValueMappedTo<T : Double>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
class DoubleVarOf<T : Double>(override val rawPtr: NativePtr) : CPrimitiveVar() {
|
||||||
companion object : Type(8)
|
companion object : Type(8)
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias CInt8Var = CInt8VarWithValueMappedTo<Byte>
|
typealias ByteVar = ByteVarOf<Byte>
|
||||||
typealias CInt16Var = CInt16VarWithValueMappedTo<Short>
|
typealias ShortVar = ShortVarOf<Short>
|
||||||
typealias CInt32Var = CInt32VarWithValueMappedTo<Int>
|
typealias IntVar = IntVarOf<Int>
|
||||||
typealias CInt64Var = CInt64VarWithValueMappedTo<Long>
|
typealias LongVar = LongVarOf<Long>
|
||||||
typealias CFloat32Var = CFloat32VarWithValueMappedTo<Float>
|
typealias FloatVar = FloatVarOf<Float>
|
||||||
typealias CFloat64Var = CFloat64VarWithValueMappedTo<Double>
|
typealias DoubleVar = DoubleVarOf<Double>
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
||||||
var <T : Byte> CInt8VarWithValueMappedTo<T>.value: T
|
var <T : Byte> ByteVarOf<T>.value: T
|
||||||
get() = nativeMemUtils.getByte(this) as T
|
get() = nativeMemUtils.getByte(this) as T
|
||||||
set(value) = nativeMemUtils.putByte(this, value)
|
set(value) = nativeMemUtils.putByte(this, value)
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
||||||
var <T : Short> CInt16VarWithValueMappedTo<T>.value: T
|
var <T : Short> ShortVarOf<T>.value: T
|
||||||
get() = nativeMemUtils.getShort(this) as T
|
get() = nativeMemUtils.getShort(this) as T
|
||||||
set(value) = nativeMemUtils.putShort(this, value)
|
set(value) = nativeMemUtils.putShort(this, value)
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
||||||
var <T : Int> CInt32VarWithValueMappedTo<T>.value: T
|
var <T : Int> IntVarOf<T>.value: T
|
||||||
get() = nativeMemUtils.getInt(this) as T
|
get() = nativeMemUtils.getInt(this) as T
|
||||||
set(value) = nativeMemUtils.putInt(this, value)
|
set(value) = nativeMemUtils.putInt(this, value)
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
||||||
var <T : Long> CInt64VarWithValueMappedTo<T>.value: T
|
var <T : Long> LongVarOf<T>.value: T
|
||||||
get() = nativeMemUtils.getLong(this) as T
|
get() = nativeMemUtils.getLong(this) as T
|
||||||
set(value) = nativeMemUtils.putLong(this, value)
|
set(value) = nativeMemUtils.putLong(this, value)
|
||||||
|
|
||||||
// TODO: ensure native floats have the appropriate binary representation
|
// TODO: ensure native floats have the appropriate binary representation
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
||||||
var <T : Float> CFloat32VarWithValueMappedTo<T>.value: T
|
var <T : Float> FloatVarOf<T>.value: T
|
||||||
get() = nativeMemUtils.getFloat(this) as T
|
get() = nativeMemUtils.getFloat(this) as T
|
||||||
set(value) = nativeMemUtils.putFloat(this, value)
|
set(value) = nativeMemUtils.putFloat(this, value)
|
||||||
|
|
||||||
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
@Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST")
|
||||||
var <T : Double> CFloat64VarWithValueMappedTo<T>.value: T
|
var <T : Double> DoubleVarOf<T>.value: T
|
||||||
get() = nativeMemUtils.getDouble(this) as T
|
get() = nativeMemUtils.getDouble(this) as T
|
||||||
set(value) = nativeMemUtils.putDouble(this, value)
|
set(value) = nativeMemUtils.putDouble(this, value)
|
||||||
|
|
||||||
|
|
||||||
class CPointerVarWithValueMappedTo<T : CPointer<*>>(override val rawPtr: NativePtr) : CVariable {
|
class CPointerVarOf<T : CPointer<*>>(override val rawPtr: NativePtr) : CVariable {
|
||||||
companion object : CVariable.Type(pointerSize.toLong(), pointerSize)
|
companion object : CVariable.Type(pointerSize.toLong(), pointerSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The C data variable containing the pointer to `T`.
|
* The C data variable containing the pointer to `T`.
|
||||||
*/
|
*/
|
||||||
typealias CPointerVar<T> = CPointerVarWithValueMappedTo<CPointer<T>>
|
typealias CPointerVar<T> = CPointerVarOf<CPointer<T>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of this variable.
|
* The value of this variable.
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline var <P : CPointer<*>> CPointerVarWithValueMappedTo<P>.value: P?
|
inline var <P : CPointer<*>> CPointerVarOf<P>.value: P?
|
||||||
get() = interpretCPointer<CPointed>(nativeMemUtils.getNativePtr(this)) as P?
|
get() = interpretCPointer<CPointed>(nativeMemUtils.getNativePtr(this)) as P?
|
||||||
set(value) = nativeMemUtils.putNativePtr(this, value.rawValue)
|
set(value) = nativeMemUtils.putNativePtr(this, value.rawValue)
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ inline var <P : CPointer<*>> CPointerVarWithValueMappedTo<P>.value: P?
|
|||||||
*
|
*
|
||||||
* @param T must not be abstract
|
* @param T must not be abstract
|
||||||
*/
|
*/
|
||||||
inline var <reified T : CPointed, reified P : CPointer<T>> CPointerVarWithValueMappedTo<P>.pointed: T?
|
inline var <reified T : CPointed, reified P : CPointer<T>> CPointerVarOf<P>.pointed: T?
|
||||||
get() = this.value?.pointed
|
get() = this.value?.pointed
|
||||||
set(value) {
|
set(value) {
|
||||||
this.value = value?.ptr as P?
|
this.value = value?.ptr as P?
|
||||||
@@ -346,6 +346,20 @@ inline operator fun <reified T : CVariable> CPointer<T>.get(index: Long): T {
|
|||||||
|
|
||||||
inline operator fun <reified T : CVariable> CPointer<T>.get(index: Int): T = this.get(index.toLong())
|
inline operator fun <reified T : CVariable> CPointer<T>.get(index: Int): T = this.get(index.toLong())
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.get(index: Int): T? =
|
||||||
|
interpretPointed<CPointerVarOf<T>>(this.rawValue + index * pointerSize.toLong()).value
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.set(index: Int, value: T?) {
|
||||||
|
interpretPointed<CPointerVarOf<T>>(this.rawValue + index * pointerSize.toLong()).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FINAL_UPPER_BOUND")
|
||||||
|
@JvmName("plus\$CPointer")
|
||||||
|
operator fun <T : CPointerVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
|
||||||
|
interpretCPointer(this.rawValue + index * pointerSize.toLong())
|
||||||
|
|
||||||
typealias CArrayPointer<T> = CPointer<T>
|
typealias CArrayPointer<T> = CPointer<T>
|
||||||
typealias CArrayPointerVar<T> = CPointerVar<T>
|
typealias CArrayPointerVar<T> = CPointerVar<T>
|
||||||
|
|
||||||
@@ -397,4 +411,4 @@ typealias CFunctionPointer<T> = CPointer<CFunction<T>>
|
|||||||
* The variable containing a [CFunctionPointer].
|
* The variable containing a [CFunctionPointer].
|
||||||
* TODO: remove.
|
* TODO: remove.
|
||||||
*/
|
*/
|
||||||
typealias CFunctionPointerVar<T> = CPointerVarWithValueMappedTo<CFunctionPointer<T>>
|
typealias CFunctionPointerVar<T> = CPointerVarOf<CFunctionPointer<T>>
|
||||||
@@ -117,7 +117,7 @@ inline fun <reified T : CVariable> NativePlacement.allocArray(length: Int,
|
|||||||
fun <T : CPointed> NativePlacement.allocArrayOfPointersTo(elements: List<T?>): CArrayPointer<CPointerVar<T>> {
|
fun <T : CPointed> NativePlacement.allocArrayOfPointersTo(elements: List<T?>): CArrayPointer<CPointerVar<T>> {
|
||||||
val res = allocArray<CPointerVar<T>>(elements.size)
|
val res = allocArray<CPointerVar<T>>(elements.size)
|
||||||
elements.forEachIndexed { index, value ->
|
elements.forEachIndexed { index, value ->
|
||||||
res[index].value = value?.ptr
|
res[index] = value?.ptr
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ fun <T : CPointed> NativePlacement.allocArrayOfPointersTo(vararg elements: T?) =
|
|||||||
* Allocates C array of given values.
|
* Allocates C array of given values.
|
||||||
*/
|
*/
|
||||||
inline fun <reified T : CPointer<*>>
|
inline fun <reified T : CPointer<*>>
|
||||||
NativePlacement.allocArrayOf(vararg elements: T?): CArrayPointer<CPointerVarWithValueMappedTo<T>> {
|
NativePlacement.allocArrayOf(vararg elements: T?): CArrayPointer<CPointerVarOf<T>> {
|
||||||
|
|
||||||
return allocArrayOf(listOf(*elements))
|
return allocArrayOf(listOf(*elements))
|
||||||
}
|
}
|
||||||
@@ -141,27 +141,27 @@ inline fun <reified T : CPointer<*>>
|
|||||||
* Allocates C array of given values.
|
* Allocates C array of given values.
|
||||||
*/
|
*/
|
||||||
inline fun <reified T : CPointer<*>>
|
inline fun <reified T : CPointer<*>>
|
||||||
NativePlacement.allocArrayOf(elements: List<T?>): CArrayPointer<CPointerVarWithValueMappedTo<T>> {
|
NativePlacement.allocArrayOf(elements: List<T?>): CArrayPointer<CPointerVarOf<T>> {
|
||||||
|
|
||||||
val res = allocArray<CPointerVarWithValueMappedTo<T>>(elements.size)
|
val res = allocArray<CPointerVarOf<T>>(elements.size)
|
||||||
elements.forEachIndexed { index, value ->
|
elements.forEachIndexed { index, value ->
|
||||||
res[index].value = value
|
res[index] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NativePlacement.allocArrayOf(elements: ByteArray): CArrayPointer<CInt8Var> {
|
fun NativePlacement.allocArrayOf(elements: ByteArray): CArrayPointer<ByteVar> {
|
||||||
val result = allocArray<CInt8Var>(elements.size)
|
val result = allocArray<ByteVar>(elements.size)
|
||||||
nativeMemUtils.putByteArray(elements, result.pointed, elements.size)
|
nativeMemUtils.putByteArray(elements, result.pointed, elements.size)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NativePlacement.allocArrayOf(vararg elements: Float): CArrayPointer<CFloat32Var> {
|
fun NativePlacement.allocArrayOf(vararg elements: Float): CArrayPointer<FloatVar> {
|
||||||
val res = allocArray<CFloat32Var>(elements.size)
|
val res = allocArray<FloatVar>(elements.size)
|
||||||
var index = 0
|
var index = 0
|
||||||
for (element in elements) {
|
for (element in elements) {
|
||||||
res[index++].value = element
|
res[index++] = element
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ fun <T : CVariable> CValues<T>.getBytes(): ByteArray = memScoped {
|
|||||||
val result = ByteArray(size)
|
val result = ByteArray(size)
|
||||||
|
|
||||||
nativeMemUtils.getByteArray(
|
nativeMemUtils.getByteArray(
|
||||||
source = this@getBytes.placeTo(memScope).reinterpret<CInt8Var>().pointed,
|
source = this@getBytes.placeTo(memScope).reinterpret<ByteVar>().pointed,
|
||||||
dest = result,
|
dest = result,
|
||||||
length = result.size
|
length = result.size
|
||||||
)
|
)
|
||||||
@@ -246,28 +246,28 @@ inline fun <reified T : CVariable> createValues(count: Int, initializer: T.(inde
|
|||||||
array[0].readValues(count)
|
array[0].readValues(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cValuesOf(vararg elements: Byte): CValues<CInt8Var> = object : CValues<CInt8Var>() {
|
fun cValuesOf(vararg elements: Byte): CValues<ByteVar> = object : CValues<ByteVar>() {
|
||||||
override fun getPointer(placement: NativePlacement) = placement.allocArrayOf(elements)
|
override fun getPointer(placement: NativePlacement) = placement.allocArrayOf(elements)
|
||||||
override val size get() = 1 * elements.size
|
override val size get() = 1 * elements.size
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: optimize other [cValuesOf] methods:
|
// TODO: optimize other [cValuesOf] methods:
|
||||||
|
|
||||||
fun cValuesOf(vararg elements: Short): CValues<CInt16Var> =
|
fun cValuesOf(vararg elements: Short): CValues<ShortVar> =
|
||||||
createValues(elements.size) { index -> this.value = elements[index] }
|
createValues(elements.size) { index -> this.value = elements[index] }
|
||||||
|
|
||||||
fun cValuesOf(vararg elements: Int): CValues<CInt32Var> =
|
fun cValuesOf(vararg elements: Int): CValues<IntVar> =
|
||||||
createValues(elements.size) { index -> this.value = elements[index] }
|
createValues(elements.size) { index -> this.value = elements[index] }
|
||||||
|
|
||||||
fun cValuesOf(vararg elements: Long): CValues<CInt64Var> =
|
fun cValuesOf(vararg elements: Long): CValues<LongVar> =
|
||||||
createValues(elements.size) { index -> this.value = elements[index] }
|
createValues(elements.size) { index -> this.value = elements[index] }
|
||||||
|
|
||||||
fun cValuesOf(vararg elements: Float): CValues<CFloat32Var> = object : CValues<CFloat32Var>() {
|
fun cValuesOf(vararg elements: Float): CValues<FloatVar> = object : CValues<FloatVar>() {
|
||||||
override fun getPointer(placement: NativePlacement) = placement.allocArrayOf(*elements)
|
override fun getPointer(placement: NativePlacement) = placement.allocArrayOf(*elements)
|
||||||
override val size get() = 4 * elements.size
|
override val size get() = 4 * elements.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cValuesOf(vararg elements: Double): CValues<CFloat64Var> =
|
fun cValuesOf(vararg elements: Double): CValues<DoubleVar> =
|
||||||
createValues(elements.size) { index -> this.value = elements[index] }
|
createValues(elements.size) { index -> this.value = elements[index] }
|
||||||
|
|
||||||
fun <T : CPointed> cValuesOf(vararg elements: CPointer<T>?): CValues<CPointerVar<T>> =
|
fun <T : CPointed> cValuesOf(vararg elements: CPointer<T>?): CValues<CPointerVar<T>> =
|
||||||
@@ -288,17 +288,17 @@ fun <T : CPointed> List<CPointer<T>?>.toCValues() = this.toTypedArray().toCValue
|
|||||||
*
|
*
|
||||||
* @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String].
|
* @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String].
|
||||||
*/
|
*/
|
||||||
val String.cstr: CValues<CInt8Var>
|
val String.cstr: CValues<ByteVar>
|
||||||
get() {
|
get() {
|
||||||
val bytes = encodeToUtf8(this)
|
val bytes = encodeToUtf8(this)
|
||||||
|
|
||||||
return object : CValues<CInt8Var>() {
|
return object : CValues<ByteVar>() {
|
||||||
override val size get() = bytes.size + 1
|
override val size get() = bytes.size + 1
|
||||||
|
|
||||||
override fun getPointer(placement: NativePlacement): CPointer<CInt8Var> {
|
override fun getPointer(placement: NativePlacement): CPointer<ByteVar> {
|
||||||
val result = placement.allocArray<CInt8Var>(bytes.size + 1)
|
val result = placement.allocArray<ByteVar>(bytes.size + 1)
|
||||||
nativeMemUtils.putByteArray(bytes, result.pointed, bytes.size)
|
nativeMemUtils.putByteArray(bytes, result.pointed, bytes.size)
|
||||||
result[bytes.size].value = 0.toByte()
|
result[bytes.size] = 0.toByte()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,11 +309,11 @@ val String.cstr: CValues<CInt8Var>
|
|||||||
*
|
*
|
||||||
* @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string.
|
* @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string.
|
||||||
*/
|
*/
|
||||||
fun CPointer<CInt8Var>.toKString(): String {
|
fun CPointer<ByteVar>.toKString(): String {
|
||||||
val nativeBytes = this
|
val nativeBytes = this
|
||||||
|
|
||||||
var length = 0
|
var length = 0
|
||||||
while (nativeBytes[length].value != 0.toByte()) {
|
while (nativeBytes[length] != 0.toByte()) {
|
||||||
++length
|
++length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,25 +32,25 @@ object nativeMemUtils {
|
|||||||
|
|
||||||
// TODO: optimize
|
// TODO: optimize
|
||||||
fun getByteArray(source: NativePointed, dest: ByteArray, length: Int) {
|
fun getByteArray(source: NativePointed, dest: ByteArray, length: Int) {
|
||||||
val sourceArray = source.reinterpret<CInt8Var>().ptr
|
val sourceArray = source.reinterpret<ByteVar>().ptr
|
||||||
for (index in 0 .. length - 1) {
|
for (index in 0 .. length - 1) {
|
||||||
dest[index] = sourceArray[index].value
|
dest[index] = sourceArray[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: optimize
|
// TODO: optimize
|
||||||
fun putByteArray(source: ByteArray, dest: NativePointed, length: Int) {
|
fun putByteArray(source: ByteArray, dest: NativePointed, length: Int) {
|
||||||
val destArray = dest.reinterpret<CInt8Var>().ptr
|
val destArray = dest.reinterpret<ByteVar>().ptr
|
||||||
for (index in 0 .. length - 1) {
|
for (index in 0 .. length - 1) {
|
||||||
destArray[index].value = source[index]
|
destArray[index] = source[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: optimize
|
// TODO: optimize
|
||||||
fun zeroMemory(dest: NativePointed, length: Int): Unit {
|
fun zeroMemory(dest: NativePointed, length: Int): Unit {
|
||||||
val destArray = dest.reinterpret<CInt8Var>().ptr
|
val destArray = dest.reinterpret<ByteVar>().ptr
|
||||||
for (index in 0 .. length - 1) {
|
for (index in 0 .. length - 1) {
|
||||||
destArray[index].value = 0
|
destArray[index] = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,3 +28,7 @@ external fun <R : Number> Number.signExtend(): R
|
|||||||
|
|
||||||
@Intrinsic
|
@Intrinsic
|
||||||
external fun <R : Number> Number.narrow(): R
|
external fun <R : Number> Number.narrow(): R
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FILE)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
internal annotation class JvmName(val name: String)
|
||||||
@@ -15,52 +15,52 @@ const val FFI_TYPE_KIND_DOUBLE: FfiTypeKind = 6
|
|||||||
const val FFI_TYPE_KIND_POINTER: FfiTypeKind = 7
|
const val FFI_TYPE_KIND_POINTER: FfiTypeKind = 7
|
||||||
|
|
||||||
private tailrec fun convertArgument(
|
private tailrec fun convertArgument(
|
||||||
argument: Any?, isVariadic: Boolean, location: NativePointed,
|
argument: Any?, isVariadic: Boolean, location: COpaquePointer,
|
||||||
additionalPlacement: NativePlacement
|
additionalPlacement: NativePlacement
|
||||||
): FfiTypeKind = when (argument) {
|
): FfiTypeKind = when (argument) {
|
||||||
is CValuesRef<*>? -> {
|
is CValuesRef<*>? -> {
|
||||||
location.reinterpret<CPointerVar<*>>().value = argument?.getPointer(additionalPlacement)
|
location.reinterpret<CPointerVar<*>>()[0] = argument?.getPointer(additionalPlacement)
|
||||||
FFI_TYPE_KIND_POINTER
|
FFI_TYPE_KIND_POINTER
|
||||||
}
|
}
|
||||||
|
|
||||||
is String -> {
|
is String -> {
|
||||||
location.reinterpret<CPointerVar<*>>().value = argument.cstr.getPointer(additionalPlacement)
|
location.reinterpret<CPointerVar<*>>()[0] = argument.cstr.getPointer(additionalPlacement)
|
||||||
FFI_TYPE_KIND_POINTER
|
FFI_TYPE_KIND_POINTER
|
||||||
}
|
}
|
||||||
|
|
||||||
is Int -> {
|
is Int -> {
|
||||||
location.reinterpret<CInt32Var>().value = argument
|
location.reinterpret<IntVar>()[0] = argument
|
||||||
FFI_TYPE_KIND_SINT32
|
FFI_TYPE_KIND_SINT32
|
||||||
}
|
}
|
||||||
|
|
||||||
is Long -> {
|
is Long -> {
|
||||||
location.reinterpret<CInt64Var>().value = argument
|
location.reinterpret<LongVar>()[0] = argument
|
||||||
FFI_TYPE_KIND_SINT64
|
FFI_TYPE_KIND_SINT64
|
||||||
}
|
}
|
||||||
|
|
||||||
is Byte -> if (isVariadic) {
|
is Byte -> if (isVariadic) {
|
||||||
convertArgument(argument.toInt(), isVariadic, location, additionalPlacement)
|
convertArgument(argument.toInt(), isVariadic, location, additionalPlacement)
|
||||||
} else {
|
} else {
|
||||||
location.reinterpret<CInt8Var>().value = argument
|
location.reinterpret<ByteVar>()[0] = argument
|
||||||
FFI_TYPE_KIND_SINT8
|
FFI_TYPE_KIND_SINT8
|
||||||
}
|
}
|
||||||
|
|
||||||
is Short -> if (isVariadic) {
|
is Short -> if (isVariadic) {
|
||||||
convertArgument(argument.toInt(), isVariadic, location, additionalPlacement)
|
convertArgument(argument.toInt(), isVariadic, location, additionalPlacement)
|
||||||
} else {
|
} else {
|
||||||
location.reinterpret<CInt16Var>().value = argument
|
location.reinterpret<ShortVar>()[0] = argument
|
||||||
FFI_TYPE_KIND_SINT16
|
FFI_TYPE_KIND_SINT16
|
||||||
}
|
}
|
||||||
|
|
||||||
is Double -> {
|
is Double -> {
|
||||||
location.reinterpret<CFloat64Var>().value = argument
|
location.reinterpret<DoubleVar>()[0] = argument
|
||||||
FFI_TYPE_KIND_DOUBLE
|
FFI_TYPE_KIND_DOUBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
is Float -> if (isVariadic) {
|
is Float -> if (isVariadic) {
|
||||||
convertArgument(argument.toDouble(), isVariadic, location, additionalPlacement)
|
convertArgument(argument.toDouble(), isVariadic, location, additionalPlacement)
|
||||||
} else {
|
} else {
|
||||||
location.reinterpret<CFloat32Var>().value = argument
|
location.reinterpret<FloatVar>()[0] = argument
|
||||||
FFI_TYPE_KIND_FLOAT
|
FFI_TYPE_KIND_FLOAT
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,19 +76,19 @@ fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKin
|
|||||||
val totalArgumentsNumber = fixedArguments.size + variadicArguments.size
|
val totalArgumentsNumber = fixedArguments.size + variadicArguments.size
|
||||||
|
|
||||||
// All supported arguments take at most 8 bytes each:
|
// All supported arguments take at most 8 bytes each:
|
||||||
val argumentsStorage = argumentsPlacement.allocArray<CInt64Var>(totalArgumentsNumber)
|
val argumentsStorage = argumentsPlacement.allocArray<LongVar>(totalArgumentsNumber)
|
||||||
val arguments = argumentsPlacement.allocArray<CPointerVar<*>>(totalArgumentsNumber)
|
val arguments = argumentsPlacement.allocArray<CPointerVar<*>>(totalArgumentsNumber)
|
||||||
val types = argumentsPlacement.allocArray<CPointerVar<*>>(totalArgumentsNumber)
|
val types = argumentsPlacement.allocArray<CPointerVar<*>>(totalArgumentsNumber)
|
||||||
|
|
||||||
var index = 0
|
var index = 0
|
||||||
|
|
||||||
inline fun addArgument(argument: Any?, isVariadic: Boolean) {
|
inline fun addArgument(argument: Any?, isVariadic: Boolean) {
|
||||||
val storage = argumentsStorage[index]
|
val storage = (argumentsStorage + index)!!
|
||||||
val typeKind = convertArgument(argument, isVariadic = isVariadic,
|
val typeKind = convertArgument(argument, isVariadic = isVariadic,
|
||||||
location = storage, additionalPlacement = argumentsPlacement)
|
location = storage, additionalPlacement = argumentsPlacement)
|
||||||
|
|
||||||
types[index].value = interpretCPointer<COpaque>(nativeNullPtr + typeKind.toLong())
|
types[index] = interpretCPointer<COpaque>(nativeNullPtr + typeKind.toLong())
|
||||||
arguments[index].value = storage.ptr
|
arguments[index] = storage
|
||||||
|
|
||||||
++index
|
++index
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-16
@@ -312,7 +312,7 @@ class StubGenerator(
|
|||||||
override fun argToJni(name: String) = name
|
override fun argToJni(name: String) = name
|
||||||
override fun argFromJni(name: String) = name
|
override fun argFromJni(name: String) = name
|
||||||
|
|
||||||
override fun constructPointedType(valueType: String) = "${varTypeName}WithValueMappedTo<$valueType>"
|
override fun constructPointedType(valueType: String) = "${varTypeName}Of<$valueType>"
|
||||||
}
|
}
|
||||||
|
|
||||||
class Enum(val className: String, val baseType: String) : TypeInfo() {
|
class Enum(val className: String, val baseType: String) : TypeInfo() {
|
||||||
@@ -335,7 +335,7 @@ class StubGenerator(
|
|||||||
override val jniType: String
|
override val jniType: String
|
||||||
get() = "NativePtr"
|
get() = "NativePtr"
|
||||||
|
|
||||||
override fun constructPointedType(valueType: String) = "CPointerVarWithValueMappedTo<$valueType>"
|
override fun constructPointedType(valueType: String) = "CPointerVarOf<$valueType>"
|
||||||
}
|
}
|
||||||
|
|
||||||
class ByRef(val pointed: String) : TypeInfo() {
|
class ByRef(val pointed: String) : TypeInfo() {
|
||||||
@@ -355,17 +355,17 @@ class StubGenerator(
|
|||||||
|
|
||||||
private fun mirror(type: PrimitiveType): TypeMirror.ByValue {
|
private fun mirror(type: PrimitiveType): TypeMirror.ByValue {
|
||||||
val varTypeName = when (type) {
|
val varTypeName = when (type) {
|
||||||
is CharType -> "CInt8Var"
|
is CharType -> "ByteVar"
|
||||||
is IntegerType -> when (type.size) {
|
is IntegerType -> when (type.size) {
|
||||||
1 -> "CInt8Var"
|
1 -> "ByteVar"
|
||||||
2 -> "CInt16Var"
|
2 -> "ShortVar"
|
||||||
4 -> "CInt32Var"
|
4 -> "IntVar"
|
||||||
8 -> "CInt64Var"
|
8 -> "LongVar"
|
||||||
else -> TODO(type.toString())
|
else -> TODO(type.toString())
|
||||||
}
|
}
|
||||||
is FloatingType -> when (type.size) {
|
is FloatingType -> when (type.size) {
|
||||||
4 -> "CFloat32Var"
|
4 -> "FloatVar"
|
||||||
8 -> "CFloat64Var"
|
8 -> "DoubleVar"
|
||||||
else -> TODO(type.toString())
|
else -> TODO(type.toString())
|
||||||
}
|
}
|
||||||
else -> TODO(type.toString())
|
else -> TODO(type.toString())
|
||||||
@@ -614,16 +614,20 @@ class StubGenerator(
|
|||||||
val offset = field.offset / 8
|
val offset = field.offset / 8
|
||||||
val fieldRefType = mirror(field.type)
|
val fieldRefType = mirror(field.type)
|
||||||
if (field.type.unwrapTypedefs() is ArrayType) {
|
if (field.type.unwrapTypedefs() is ArrayType) {
|
||||||
// FIXME:
|
val type = (fieldRefType as TypeMirror.ByValue).valueTypeName
|
||||||
val nullableType = fieldRefType.argType
|
|
||||||
assert (nullableType.endsWith('?'))
|
|
||||||
val type = nullableType.substring(0, nullableType.length - 1)
|
|
||||||
|
|
||||||
out("val ${field.name.asSimpleName()}: $type")
|
out("val ${field.name.asSimpleName()}: $type")
|
||||||
out(" get() = arrayMemberAt($offset)")
|
out(" get() = arrayMemberAt($offset)")
|
||||||
} else {
|
} else {
|
||||||
out("val ${field.name.asSimpleName()}: ${fieldRefType.pointedTypeName}")
|
if (fieldRefType is TypeMirror.ByValue) {
|
||||||
out(" get() = memberAt($offset)")
|
val pointedTypeName = fieldRefType.pointedTypeName
|
||||||
|
out("var ${field.name.asSimpleName()}: ${fieldRefType.argType}")
|
||||||
|
out(" get() = memberAt<$pointedTypeName>($offset).value")
|
||||||
|
out(" set(value) { memberAt<$pointedTypeName>($offset).value = value }")
|
||||||
|
} else {
|
||||||
|
out("val ${field.name.asSimpleName()}: ${fieldRefType.pointedTypeName}")
|
||||||
|
out(" get() = memberAt($offset)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out("")
|
out("")
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
@@ -1046,7 +1050,7 @@ class StubGenerator(
|
|||||||
block("override fun invoke(function: $kotlinFunctionType, args: CArrayPointer<COpaquePointerVar>, ret: COpaquePointer)") {
|
block("override fun invoke(function: $kotlinFunctionType, args: CArrayPointer<COpaquePointerVar>, ret: COpaquePointer)") {
|
||||||
val args = type.parameterTypes.mapIndexed { i, paramType ->
|
val args = type.parameterTypes.mapIndexed { i, paramType ->
|
||||||
val pointedTypeName = mirror(paramType).pointedTypeName
|
val pointedTypeName = mirror(paramType).pointedTypeName
|
||||||
val ref = "args[$i].value!!.reinterpret<$pointedTypeName>().pointed"
|
val ref = "args[$i]!!.reinterpret<$pointedTypeName>().pointed"
|
||||||
when (paramType.unwrapTypedefs()) {
|
when (paramType.unwrapTypedefs()) {
|
||||||
is RecordType -> ref
|
is RecordType -> ref
|
||||||
else -> "$ref.value"
|
else -> "$ref.value"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fun main(args: Array<String>) = memScoped {
|
|||||||
println("module=" + module.rawValue)
|
println("module=" + module.rawValue)
|
||||||
|
|
||||||
val paramTypes = allocArrayOf(LLVMInt32Type(), LLVMInt32Type())
|
val paramTypes = allocArrayOf(LLVMInt32Type(), LLVMInt32Type())
|
||||||
val retType = LLVMFunctionType(LLVMInt32Type(), paramTypes[0].ptr, 2, 0)
|
val retType = LLVMFunctionType(LLVMInt32Type(), paramTypes, 2, 0)
|
||||||
|
|
||||||
val sum = LLVMAddFunction(module, "sum", retType)
|
val sum = LLVMAddFunction(module, "sum", retType)
|
||||||
val entry = LLVMAppendBasicBlock(sum, "entry")
|
val entry = LLVMAppendBasicBlock(sum, "entry")
|
||||||
@@ -30,7 +30,7 @@ fun main(args: Array<String>) = memScoped {
|
|||||||
val tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp")
|
val tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp")
|
||||||
LLVMBuildRet(builder, tmp)
|
LLVMBuildRet(builder, tmp)
|
||||||
val engineRef = alloc<LLVMExecutionEngineRefVar>()
|
val engineRef = alloc<LLVMExecutionEngineRefVar>()
|
||||||
val errorRef = allocPointerTo<CInt8Var>()
|
val errorRef = allocPointerTo<ByteVar>()
|
||||||
LLVMInitializeNativeTarget()
|
LLVMInitializeNativeTarget()
|
||||||
errorRef.value = null
|
errorRef.value = null
|
||||||
if (LLVMCreateExecutionEngineForModule(engineRef.ptr, module, errorRef.ptr) != 0) {
|
if (LLVMCreateExecutionEngineForModule(engineRef.ptr, module, errorRef.ptr) != 0) {
|
||||||
@@ -50,7 +50,7 @@ fun main(args: Array<String>) = memScoped {
|
|||||||
LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0),
|
LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0),
|
||||||
LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0))
|
LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0))
|
||||||
|
|
||||||
val runRes = LLVMRunFunction(engineRef.value, sum, 2, args[0].ptr)
|
val runRes = LLVMRunFunction(engineRef.value, sum, 2, args)
|
||||||
println(LLVMGenericValueToInt(runRes, 0))
|
println(LLVMGenericValueToInt(runRes, 0))
|
||||||
if (LLVMWriteBitcodeToFile(module, "/tmp/sum.bc") != 0) {
|
if (LLVMWriteBitcodeToFile(module, "/tmp/sum.bc") != 0) {
|
||||||
println("error writing bitcode to file, skipping")
|
println("error writing bitcode to file, skipping")
|
||||||
|
|||||||
+2
-2
@@ -80,11 +80,11 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
|
|||||||
val interpretCPointer = packageScope.getContributedFunctions("interpretCPointer").single()
|
val interpretCPointer = packageScope.getContributedFunctions("interpretCPointer").single()
|
||||||
|
|
||||||
val arrayGetByIntIndex = packageScope.getContributedFunctions("get").single {
|
val arrayGetByIntIndex = packageScope.getContributedFunctions("get").single {
|
||||||
KotlinBuiltIns.isInt(it.valueParameters.single().type)
|
KotlinBuiltIns.isInt(it.valueParameters.single().type) && it.isInline
|
||||||
}
|
}
|
||||||
|
|
||||||
val arrayGetByLongIndex = packageScope.getContributedFunctions("get").single {
|
val arrayGetByLongIndex = packageScope.getContributedFunctions("get").single {
|
||||||
KotlinBuiltIns.isLong(it.valueParameters.single().type)
|
KotlinBuiltIns.isLong(it.valueParameters.single().type) && it.isInline
|
||||||
}
|
}
|
||||||
|
|
||||||
val allocUninitializedArrayWithIntLength = packageScope.getContributedFunctions("allocArray").single {
|
val allocUninitializedArrayWithIntLength = packageScope.getContributedFunctions("allocArray").single {
|
||||||
|
|||||||
+5
-5
@@ -40,7 +40,7 @@ internal fun globalHash(data: ByteArray, retValPlacement: NativePlacement): Glob
|
|||||||
public fun base64Encode(data: ByteArray): String {
|
public fun base64Encode(data: ByteArray): String {
|
||||||
memScoped {
|
memScoped {
|
||||||
val resultSize = 4 * data.size / 3 + 3 + 1
|
val resultSize = 4 * data.size / 3 + 3 + 1
|
||||||
val result = allocArray<CInt8Var>(resultSize)
|
val result = allocArray<ByteVar>(resultSize)
|
||||||
val bytes = allocArrayOf(data)
|
val bytes = allocArrayOf(data)
|
||||||
EncodeBase64(bytes, data.size, result, resultSize)
|
EncodeBase64(bytes, data.size, result, resultSize)
|
||||||
// TODO: any better way to do that without two copies?
|
// TODO: any better way to do that without two copies?
|
||||||
@@ -51,14 +51,14 @@ public fun base64Encode(data: ByteArray): String {
|
|||||||
public fun base64Decode(encoded: String): ByteArray {
|
public fun base64Decode(encoded: String): ByteArray {
|
||||||
memScoped {
|
memScoped {
|
||||||
val bufferSize: Int = 3 * encoded.length / 4
|
val bufferSize: Int = 3 * encoded.length / 4
|
||||||
val result = allocArray<CInt8Var>(bufferSize)
|
val result = allocArray<ByteVar>(bufferSize)
|
||||||
val resultSize = allocArray<uint32_tVar>(1)
|
val resultSize = allocArray<uint32_tVar>(1)
|
||||||
resultSize[0].value = bufferSize
|
resultSize[0] = bufferSize
|
||||||
val errorCode = DecodeBase64(encoded, encoded.length, result, resultSize)
|
val errorCode = DecodeBase64(encoded, encoded.length, result, resultSize)
|
||||||
if (errorCode != 0) throw Error("Non-zero exit code of DecodeBase64: ${errorCode}")
|
if (errorCode != 0) throw Error("Non-zero exit code of DecodeBase64: ${errorCode}")
|
||||||
val realSize = resultSize[0].value!!
|
val realSize = resultSize[0]
|
||||||
val bytes = ByteArray(realSize)
|
val bytes = ByteArray(realSize)
|
||||||
nativeMemUtils.getByteArray(result[0], bytes, realSize)
|
nativeMemUtils.getByteArray(result.pointed, bytes, realSize)
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -92,7 +92,7 @@ internal fun emitLLVM(context: Context) {
|
|||||||
|
|
||||||
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
||||||
memScoped {
|
memScoped {
|
||||||
val errorRef = allocPointerTo<CInt8Var>()
|
val errorRef = allocPointerTo<ByteVar>()
|
||||||
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
||||||
if (LLVMVerifyModule(
|
if (LLVMVerifyModule(
|
||||||
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr) == 1) {
|
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr) == 1) {
|
||||||
|
|||||||
+2
-2
@@ -171,7 +171,7 @@ internal fun RuntimeAware.isObjectType(type: LLVMTypeRef): Boolean {
|
|||||||
/**
|
/**
|
||||||
* Reads [size] bytes contained in this array.
|
* Reads [size] bytes contained in this array.
|
||||||
*/
|
*/
|
||||||
internal fun CArrayPointer<CInt8Var>.getBytes(size: Long) =
|
internal fun CArrayPointer<ByteVar>.getBytes(size: Long) =
|
||||||
(0 .. size-1).map { this[it].value }.toByteArray()
|
(0 .. size-1).map { this[it].value }.toByteArray()
|
||||||
|
|
||||||
internal fun getFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef {
|
internal fun getFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef {
|
||||||
@@ -220,7 +220,7 @@ fun getStructElements(type: LLVMTypeRef): List<LLVMTypeRef> {
|
|||||||
|
|
||||||
fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped {
|
fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped {
|
||||||
val bufRef = alloc<LLVMMemoryBufferRefVar>()
|
val bufRef = alloc<LLVMMemoryBufferRefVar>()
|
||||||
val errorRef = allocPointerTo<CInt8Var>()
|
val errorRef = allocPointerTo<ByteVar>()
|
||||||
|
|
||||||
val res = LLVMCreateMemoryBufferWithContentsOfFile(path, bufRef.ptr, errorRef.ptr)
|
val res = LLVMCreateMemoryBufferWithContentsOfFile(path, bufRef.ptr, errorRef.ptr)
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
|||||||
+5
-5
@@ -83,7 +83,7 @@ class MetadataReader(file: File) : Closeable {
|
|||||||
init {
|
init {
|
||||||
memScoped {
|
memScoped {
|
||||||
val bufRef = alloc<LLVMMemoryBufferRefVar>()
|
val bufRef = alloc<LLVMMemoryBufferRefVar>()
|
||||||
val errorRef = allocPointerTo<CInt8Var>()
|
val errorRef = allocPointerTo<ByteVar>()
|
||||||
val res = LLVMCreateMemoryBufferWithContentsOfFile(file.toString(), bufRef.ptr, errorRef.ptr)
|
val res = LLVMCreateMemoryBufferWithContentsOfFile(file.toString(), bufRef.ptr, errorRef.ptr)
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
throw Error(errorRef.value?.toKString())
|
throw Error(errorRef.value?.toKString())
|
||||||
@@ -103,7 +103,7 @@ class MetadataReader(file: File) : Closeable {
|
|||||||
|
|
||||||
fun string(node: LLVMValueRef): String {
|
fun string(node: LLVMValueRef): String {
|
||||||
memScoped {
|
memScoped {
|
||||||
val len = alloc<CInt32Var>()
|
val len = alloc<IntVar>()
|
||||||
val str1 = LLVMGetMDString(node, len.ptr)!!
|
val str1 = LLVMGetMDString(node, len.ptr)!!
|
||||||
val str = str1.toKString()
|
val str = str1.toKString()
|
||||||
return str
|
return str
|
||||||
@@ -121,7 +121,7 @@ class MetadataReader(file: File) : Closeable {
|
|||||||
|
|
||||||
//return Pair(nodeCount, nodeArray[0].value!!)
|
//return Pair(nodeCount, nodeArray[0].value!!)
|
||||||
for (index in 0..nodeCount-1) {
|
for (index in 0..nodeCount-1) {
|
||||||
result.add(nodeArray[index].value!!)
|
result.add(nodeArray[index]!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.toTypedArray<LLVMValueRef>()
|
return result.toTypedArray<LLVMValueRef>()
|
||||||
@@ -134,7 +134,7 @@ class MetadataReader(file: File) : Closeable {
|
|||||||
|
|
||||||
LLVMGetNamedMetadataOperands(llvmModule, name, nodeArray)
|
LLVMGetNamedMetadataOperands(llvmModule, name, nodeArray)
|
||||||
|
|
||||||
return Pair(nodeCount, nodeArray[0].value!!)
|
return Pair(nodeCount, nodeArray[0]!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ class MetadataReader(file: File) : Closeable {
|
|||||||
|
|
||||||
LLVMGetMDNodeOperands(metadataNode, operandArray)
|
LLVMGetMDNodeOperands(metadataNode, operandArray)
|
||||||
|
|
||||||
return Array(operandCount, {index -> operandArray[index].value!!})
|
return Array(operandCount, {index -> operandArray[index]!!})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ fun main(args: Array<String>) {
|
|||||||
val statBuf = nativeHeap.alloc<statStruct>()
|
val statBuf = nativeHeap.alloc<statStruct>()
|
||||||
val res = stat("/", statBuf.ptr)
|
val res = stat("/", statBuf.ptr)
|
||||||
println(res)
|
println(res)
|
||||||
println(statBuf.st_uid.value)
|
println(statBuf.st_uid)
|
||||||
}
|
}
|
||||||
@@ -4,17 +4,17 @@ fun main(args: Array<String>) {
|
|||||||
memScoped {
|
memScoped {
|
||||||
val count = 5
|
val count = 5
|
||||||
|
|
||||||
val values = allocArray<CInt32Var>(count)
|
val values = allocArray<IntVar>(count)
|
||||||
values[0].value = 14
|
values[0] = 14
|
||||||
values[1].value = 12
|
values[1] = 12
|
||||||
values[2].value = 9
|
values[2] = 9
|
||||||
values[3].value = 13
|
values[3] = 13
|
||||||
values[4].value = 8
|
values[4] = 8
|
||||||
|
|
||||||
cstdlib.qsort(values, count.toLong(), CInt32Var.size, staticCFunction(::comparator))
|
cstdlib.qsort(values, count.toLong(), IntVar.size, staticCFunction(::comparator))
|
||||||
|
|
||||||
for (i in 0 .. count - 1) {
|
for (i in 0 .. count - 1) {
|
||||||
print(values[i].value)
|
print(values[i])
|
||||||
print(" ")
|
print(" ")
|
||||||
}
|
}
|
||||||
println()
|
println()
|
||||||
@@ -22,8 +22,8 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun comparator(a: COpaquePointer?, b: COpaquePointer?): Int {
|
private fun comparator(a: COpaquePointer?, b: COpaquePointer?): Int {
|
||||||
val aValue = a!!.reinterpret<CInt32Var>().pointed.value
|
val aValue = a!!.reinterpret<IntVar>()[0]
|
||||||
val bValue = b!!.reinterpret<CInt32Var>().pointed.value
|
val bValue = b!!.reinterpret<IntVar>()[0]
|
||||||
|
|
||||||
return (aValue - bValue)
|
return (aValue - bValue)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ fun main(args: Array<String>) {
|
|||||||
"a", "b".cstr, (-1).toByte(), 2.toShort(), 3, Long.MAX_VALUE, 0.1.toFloat(), 0.2)
|
"a", "b".cstr, (-1).toByte(), 2.toShort(), 3, Long.MAX_VALUE, 0.1.toFloat(), 0.2)
|
||||||
|
|
||||||
memScoped {
|
memScoped {
|
||||||
val aVar = alloc<CInt32Var>()
|
val aVar = alloc<IntVar>()
|
||||||
val bVar = alloc<CInt32Var>()
|
val bVar = alloc<IntVar>()
|
||||||
val sscanfResult = sscanf("42", "%d%d", aVar.ptr, bVar.ptr)
|
val sscanfResult = sscanf("42", "%d%d", aVar.ptr, bVar.ptr)
|
||||||
printf("%d %d\n", sscanfResult, aVar.value)
|
printf("%d %d\n", sscanfResult, aVar.value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ fun main(args: Array<String>) {
|
|||||||
memScoped {
|
memScoped {
|
||||||
|
|
||||||
val bufferLength = 100L
|
val bufferLength = 100L
|
||||||
val buffer = allocArray<CInt8Var>(bufferLength)
|
val buffer = allocArray<ByteVar>(bufferLength)
|
||||||
val serverAddr = alloc<sockaddr_in>()
|
val serverAddr = alloc<sockaddr_in>()
|
||||||
|
|
||||||
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
|
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
|
||||||
@@ -20,9 +20,9 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
with(serverAddr) {
|
with(serverAddr) {
|
||||||
memset(this.ptr, 0, sockaddr_in.size)
|
memset(this.ptr, 0, sockaddr_in.size)
|
||||||
sin_family.value = AF_INET.narrow()
|
sin_family = AF_INET.narrow()
|
||||||
sin_addr.s_addr.value = htons(0).toInt()
|
sin_addr.s_addr = htons(0).toInt()
|
||||||
sin_port.value = htons(port)
|
sin_port = htons(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
|
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ fun initialize() {
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
// initialize and run program
|
// initialize and run program
|
||||||
memScoped {
|
memScoped {
|
||||||
val argc = alloc<CInt32Var>().apply { value = 0 }
|
val argc = alloc<IntVar>().apply { value = 0 }
|
||||||
glutInit(argc.ptr, null) // TODO: pass real args
|
glutInit(argc.ptr, null) // TODO: pass real args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ fun main(args: Array<String>) {
|
|||||||
try {
|
try {
|
||||||
memScoped {
|
memScoped {
|
||||||
val bufferLength = 64 * 1024
|
val bufferLength = 64 * 1024
|
||||||
val buffer = allocArray<CInt8Var>(bufferLength)
|
val buffer = allocArray<ByteVar>(bufferLength)
|
||||||
|
|
||||||
for (i in 1..count) {
|
for (i in 1..count) {
|
||||||
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ class GitDiff(val repository: GitRepository, val handle: CPointer<git_diff>) {
|
|||||||
|
|
||||||
class GifDiffDelta(val diff: GitDiff, val handle: CPointer<git_diff_delta>) {
|
class GifDiffDelta(val diff: GitDiff, val handle: CPointer<git_diff_delta>) {
|
||||||
|
|
||||||
val status get() = handle.pointed.status.value
|
val status get() = handle.pointed.status
|
||||||
val newPath get() = handle.pointed.new_file.path.value!!.toKString()
|
val newPath get() = handle.pointed.new_file.path!!.toKString()
|
||||||
val oldPath get() = handle.pointed.old_file.path.value!!.toKString()
|
val oldPath get() = handle.pointed.old_file.path!!.toKString()
|
||||||
|
|
||||||
fun status(): String {
|
fun status(): String {
|
||||||
return when (status) {
|
return when (status) {
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ class GitRepository(val location: String) {
|
|||||||
fun remotes(): List<GitRemote> = memScoped {
|
fun remotes(): List<GitRemote> = memScoped {
|
||||||
val remoteList = alloc<git_strarray>()
|
val remoteList = alloc<git_strarray>()
|
||||||
git_remote_list(remoteList.ptr, handle).errorCheck()
|
git_remote_list(remoteList.ptr, handle).errorCheck()
|
||||||
val size = remoteList.count.value.toInt()
|
val size = remoteList.count.toInt()
|
||||||
val list = ArrayList<GitRemote>(size)
|
val list = ArrayList<GitRemote>(size)
|
||||||
for (index in 0..size - 1) {
|
for (index in 0..size - 1) {
|
||||||
val array = remoteList.strings.value!!
|
val array = remoteList.strings!!
|
||||||
val name = array[index].value!!.toKString()
|
val name = array[index]!!.toKString()
|
||||||
val remotePtr = allocPointerTo<git_remote>()
|
val remotePtr = allocPointerTo<git_remote>()
|
||||||
git_remote_lookup(remotePtr.ptr, handle, name).errorCheck()
|
git_remote_lookup(remotePtr.ptr, handle, name).errorCheck()
|
||||||
list.add(GitRemote(this@GitRepository, remotePtr.value!!))
|
list.add(GitRemote(this@GitRepository, remotePtr.value!!))
|
||||||
|
|||||||
@@ -40,5 +40,5 @@ fun Int.errorCheck() {
|
|||||||
|
|
||||||
class GitException : Exception(run {
|
class GitException : Exception(run {
|
||||||
val err = giterr_last()
|
val err = giterr_last()
|
||||||
err!!.pointed.message.value!!.toKString()
|
err!!.pointed.message!!.toKString()
|
||||||
})
|
})
|
||||||
@@ -40,13 +40,13 @@ class CUrl(val url: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CPointer<CInt8Var>.toKString(length: Int): String {
|
fun CPointer<ByteVar>.toKString(length: Int): String {
|
||||||
val bytes = ByteArray(length)
|
val bytes = ByteArray(length)
|
||||||
nativeMemUtils.getByteArray(pointed, bytes, length)
|
nativeMemUtils.getByteArray(pointed, bytes, length)
|
||||||
return kotlin.text.fromUtf8Array(bytes, 0, bytes.size)
|
return kotlin.text.fromUtf8Array(bytes, 0, bytes.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun header_callback(buffer: CPointer<CInt8Var>?, size: size_t, nitems: size_t, userdata: COpaquePointer?): size_t {
|
fun header_callback(buffer: CPointer<ByteVar>?, size: size_t, nitems: size_t, userdata: COpaquePointer?): size_t {
|
||||||
if (buffer == null) return 0
|
if (buffer == null) return 0
|
||||||
val header = buffer.toKString((size * nitems).toInt()).trim()
|
val header = buffer.toKString((size * nitems).toInt()).trim()
|
||||||
if (userdata != null) {
|
if (userdata != null) {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ fun initialize() {
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
// initialize and run program
|
// initialize and run program
|
||||||
memScoped {
|
memScoped {
|
||||||
val argc = alloc<CInt32Var>().apply { value = 0 }
|
val argc = alloc<IntVar>().apply { value = 0 }
|
||||||
glutInit(argc.ptr, null) // TODO: pass real args
|
glutInit(argc.ptr, null) // TODO: pass real args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ fun main(args: Array<String>) {
|
|||||||
memScoped {
|
memScoped {
|
||||||
|
|
||||||
val bufferLength = 100L
|
val bufferLength = 100L
|
||||||
val buffer = allocArray<CInt8Var>(bufferLength)
|
val buffer = allocArray<ByteVar>(bufferLength)
|
||||||
val serverAddr = alloc<sockaddr_in>()
|
val serverAddr = alloc<sockaddr_in>()
|
||||||
|
|
||||||
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
|
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
|
||||||
@@ -36,9 +36,9 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
with(serverAddr) {
|
with(serverAddr) {
|
||||||
memset(this.ptr, 0, sockaddr_in.size)
|
memset(this.ptr, 0, sockaddr_in.size)
|
||||||
sin_family.value = AF_INET.narrow()
|
sin_family = AF_INET.narrow()
|
||||||
sin_addr.s_addr.value = htons(0).toInt()
|
sin_addr.s_addr = htons(0).toInt()
|
||||||
sin_port.value = htons(port)
|
sin_port = htons(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
|
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
|
||||||
|
|||||||
+40
-40
@@ -544,34 +544,34 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
val x = (width - moveButtonsWidth - ROTATE_BUTTON_SIZE) / 2 - MOVE_BUTTON_SIZE
|
val x = (width - moveButtonsWidth - ROTATE_BUTTON_SIZE) / 2 - MOVE_BUTTON_SIZE
|
||||||
val y2 = (gamePadHeight - 2 * MOVE_BUTTON_SIZE - BUTTONS_MARGIN) / 2
|
val y2 = (gamePadHeight - 2 * MOVE_BUTTON_SIZE - BUTTONS_MARGIN) / 2
|
||||||
leftRect = arena.alloc<SDL_Rect>()
|
leftRect = arena.alloc<SDL_Rect>()
|
||||||
leftRect.w.value = MOVE_BUTTON_SIZE
|
leftRect.w = MOVE_BUTTON_SIZE
|
||||||
leftRect.h.value = MOVE_BUTTON_SIZE
|
leftRect.h = MOVE_BUTTON_SIZE
|
||||||
leftRect.x.value = x
|
leftRect.x = x
|
||||||
leftRect.y.value = height - gamePadHeight + y2 + MOVE_BUTTON_SIZE + BUTTONS_MARGIN
|
leftRect.y = height - gamePadHeight + y2 + MOVE_BUTTON_SIZE + BUTTONS_MARGIN
|
||||||
|
|
||||||
downRect = arena.alloc<SDL_Rect>()
|
downRect = arena.alloc<SDL_Rect>()
|
||||||
downRect.w.value = MOVE_BUTTON_SIZE
|
downRect.w = MOVE_BUTTON_SIZE
|
||||||
downRect.h.value = MOVE_BUTTON_SIZE
|
downRect.h = MOVE_BUTTON_SIZE
|
||||||
downRect.x.value = x + MOVE_BUTTON_SIZE + BUTTONS_MARGIN
|
downRect.x = x + MOVE_BUTTON_SIZE + BUTTONS_MARGIN
|
||||||
downRect.y.value = leftRect.y.value
|
downRect.y = leftRect.y
|
||||||
|
|
||||||
dropRect = arena.alloc<SDL_Rect>()
|
dropRect = arena.alloc<SDL_Rect>()
|
||||||
dropRect.w.value = MOVE_BUTTON_SIZE
|
dropRect.w = MOVE_BUTTON_SIZE
|
||||||
dropRect.h.value = MOVE_BUTTON_SIZE
|
dropRect.h = MOVE_BUTTON_SIZE
|
||||||
dropRect.x.value = downRect.x.value
|
dropRect.x = downRect.x
|
||||||
dropRect.y.value = height - gamePadHeight + y2
|
dropRect.y = height - gamePadHeight + y2
|
||||||
|
|
||||||
rightRect = arena.alloc<SDL_Rect>()
|
rightRect = arena.alloc<SDL_Rect>()
|
||||||
rightRect.w.value = MOVE_BUTTON_SIZE
|
rightRect.w = MOVE_BUTTON_SIZE
|
||||||
rightRect.h.value = MOVE_BUTTON_SIZE
|
rightRect.h = MOVE_BUTTON_SIZE
|
||||||
rightRect.x.value = x + 2 * MOVE_BUTTON_SIZE + 2 * BUTTONS_MARGIN
|
rightRect.x = x + 2 * MOVE_BUTTON_SIZE + 2 * BUTTONS_MARGIN
|
||||||
rightRect.y.value = height - gamePadHeight + y2 + MOVE_BUTTON_SIZE + BUTTONS_MARGIN
|
rightRect.y = height - gamePadHeight + y2 + MOVE_BUTTON_SIZE + BUTTONS_MARGIN
|
||||||
|
|
||||||
rotateRect = arena.alloc<SDL_Rect>()
|
rotateRect = arena.alloc<SDL_Rect>()
|
||||||
rotateRect.w.value = ROTATE_BUTTON_SIZE
|
rotateRect.w = ROTATE_BUTTON_SIZE
|
||||||
rotateRect.h.value = ROTATE_BUTTON_SIZE
|
rotateRect.h = ROTATE_BUTTON_SIZE
|
||||||
rotateRect.x.value = x + moveButtonsWidth
|
rotateRect.x = x + moveButtonsWidth
|
||||||
rotateRect.y.value = height - gamePadHeight + y2 - BUTTONS_MARGIN
|
rotateRect.y = height - gamePadHeight + y2 - BUTTONS_MARGIN
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCommandAt(x: Int, y: Int): UserCommand? {
|
fun getCommandAt(x: Int, y: Int): UserCommand? {
|
||||||
@@ -586,8 +586,8 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun inside(rect: SDL_Rect, x: Int, y: Int): Boolean {
|
private fun inside(rect: SDL_Rect, x: Int, y: Int): Boolean {
|
||||||
return x >= stretch(rect.x.value) && x <= stretch(rect.x.value + rect.w.value)
|
return x >= stretch(rect.x) && x <= stretch(rect.x + rect.w)
|
||||||
&& y >= stretch(rect.y.value) && y <= stretch(rect.y.value + rect.h.value)
|
&& y >= stretch(rect.y) && y <= stretch(rect.y + rect.h)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
@@ -629,8 +629,8 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
SDL_Quit()
|
SDL_Quit()
|
||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
displayWidth = displayMode.w.value
|
displayWidth = displayMode.w
|
||||||
displayHeight = displayMode.h.value
|
displayHeight = displayMode.h
|
||||||
}
|
}
|
||||||
fieldWidth = width * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
fieldWidth = width * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
||||||
fieldHeight = height * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
fieldHeight = height * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
||||||
@@ -889,10 +889,10 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
private fun fillRect(rect: SDL_Rect) {
|
private fun fillRect(rect: SDL_Rect) {
|
||||||
memScoped {
|
memScoped {
|
||||||
val stretchedRect = alloc<SDL_Rect>()
|
val stretchedRect = alloc<SDL_Rect>()
|
||||||
stretchedRect.w.value = stretch(rect.w.value)
|
stretchedRect.w = stretch(rect.w)
|
||||||
stretchedRect.h.value = stretch(rect.h.value)
|
stretchedRect.h = stretch(rect.h)
|
||||||
stretchedRect.x.value = stretch(rect.x.value)
|
stretchedRect.x = stretch(rect.x)
|
||||||
stretchedRect.y.value = stretch(rect.y.value)
|
stretchedRect.y = stretch(rect.y)
|
||||||
SDL_RenderFillRect(renderer, stretchedRect.ptr.reinterpret())
|
SDL_RenderFillRect(renderer, stretchedRect.ptr.reinterpret())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -901,14 +901,14 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
memScoped {
|
memScoped {
|
||||||
val srcRect = alloc<SDL_Rect>()
|
val srcRect = alloc<SDL_Rect>()
|
||||||
val destRect = alloc<SDL_Rect>()
|
val destRect = alloc<SDL_Rect>()
|
||||||
srcRect.w.value = width
|
srcRect.w = width
|
||||||
srcRect.h.value = height
|
srcRect.h = height
|
||||||
srcRect.x.value = srcX
|
srcRect.x = srcX
|
||||||
srcRect.y.value = srcY
|
srcRect.y = srcY
|
||||||
destRect.w.value = stretch(width)
|
destRect.w = stretch(width)
|
||||||
destRect.h.value = stretch(height)
|
destRect.h = stretch(height)
|
||||||
destRect.x.value = stretch(destX)
|
destRect.x = stretch(destX)
|
||||||
destRect.y.value = stretch(destY)
|
destRect.y = stretch(destY)
|
||||||
SDL_RenderCopy(renderer, texture, srcRect.ptr.reinterpret(), destRect.ptr.reinterpret())
|
SDL_RenderCopy(renderer, texture, srcRect.ptr.reinterpret(), destRect.ptr.reinterpret())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -918,12 +918,12 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
memScoped {
|
memScoped {
|
||||||
val event = alloc<SDL_Event>()
|
val event = alloc<SDL_Event>()
|
||||||
while (SDL_PollEvent(event.ptr.reinterpret()) != 0) {
|
while (SDL_PollEvent(event.ptr.reinterpret()) != 0) {
|
||||||
val eventType = event.type.value
|
val eventType = event.type
|
||||||
when (eventType) {
|
when (eventType) {
|
||||||
SDL_QUIT -> commands.add(UserCommand.EXIT)
|
SDL_QUIT -> commands.add(UserCommand.EXIT)
|
||||||
SDL_KEYDOWN -> {
|
SDL_KEYDOWN -> {
|
||||||
val keyboardEvent = event.ptr.reinterpret<SDL_KeyboardEvent>().pointed
|
val keyboardEvent = event.ptr.reinterpret<SDL_KeyboardEvent>().pointed
|
||||||
when (keyboardEvent.keysym.scancode.value) {
|
when (keyboardEvent.keysym.scancode) {
|
||||||
SDL_SCANCODE_LEFT -> commands.add(UserCommand.LEFT)
|
SDL_SCANCODE_LEFT -> commands.add(UserCommand.LEFT)
|
||||||
SDL_SCANCODE_RIGHT -> commands.add(UserCommand.RIGHT)
|
SDL_SCANCODE_RIGHT -> commands.add(UserCommand.RIGHT)
|
||||||
SDL_SCANCODE_DOWN -> commands.add(UserCommand.DOWN)
|
SDL_SCANCODE_DOWN -> commands.add(UserCommand.DOWN)
|
||||||
@@ -934,8 +934,8 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
}
|
}
|
||||||
SDL_MOUSEBUTTONDOWN -> if (gamePadButtons != null) {
|
SDL_MOUSEBUTTONDOWN -> if (gamePadButtons != null) {
|
||||||
val mouseEvent = event.ptr.reinterpret<SDL_MouseButtonEvent>().pointed
|
val mouseEvent = event.ptr.reinterpret<SDL_MouseButtonEvent>().pointed
|
||||||
val x = mouseEvent.x.value
|
val x = mouseEvent.x
|
||||||
val y = mouseEvent.y.value
|
val y = mouseEvent.y
|
||||||
val command = gamePadButtons.getCommandAt(x, y)
|
val command = gamePadButtons.getCommandAt(x, y)
|
||||||
if (command != null)
|
if (command != null)
|
||||||
commands.add(command)
|
commands.add(command)
|
||||||
|
|||||||
Reference in New Issue
Block a user