Alloc arrays, fix RTTI for Any (#49)
This commit is contained in:
+17
@@ -42,8 +42,25 @@ private val intrinsicTypes = setOf(
|
||||
"kotlin.Float", "kotlin.Double"
|
||||
)
|
||||
|
||||
private val arrayTypes = setOf(
|
||||
"kotlin.Array",
|
||||
"kotlin.ByteArray",
|
||||
"kotlin.CharArray",
|
||||
"kotlin.ShortArray",
|
||||
"kotlin.IntArray",
|
||||
"kotlin.LongArray",
|
||||
"kotlin.FloatArray",
|
||||
"kotlin.DoubleArray",
|
||||
"kotlin.BooleanArray"
|
||||
)
|
||||
|
||||
internal val ClassDescriptor.isIntrinsic: Boolean
|
||||
get() = this.fqNameSafe.asString() in intrinsicTypes
|
||||
|
||||
|
||||
internal val ClassDescriptor.isArray: Boolean
|
||||
get() = this.fqNameSafe.asString() in arrayTypes
|
||||
|
||||
|
||||
internal val ClassDescriptor.isInterface: Boolean
|
||||
get() = (this.kind == ClassKind.INTERFACE)
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val
|
||||
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
|
||||
|
||||
val allocInstanceFunction = importRtFunction("AllocInstance")
|
||||
val allocArrayFunction = importRtFunction("AllocArrayInstance")
|
||||
|
||||
fun dispose() {
|
||||
LLVMDisposeBuilder(llvmBuilder)
|
||||
|
||||
+15
-4
@@ -2,6 +2,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
|
||||
|
||||
import kotlin_native.interop.*
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.isArray
|
||||
import org.jetbrains.kotlin.backend.konan.isInterface
|
||||
import org.jetbrains.kotlin.backend.konan.isIntrinsic
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
@@ -19,7 +20,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
|
||||
fun emitLLVM(module: IrModuleFragment, runtimeFile: String, outFile: String) {
|
||||
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||
val runtime = Runtime(runtimeFile) // TODO: dispose
|
||||
@@ -407,9 +407,20 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
private fun evaluateConstructorCall(variableName: String, callee: IrCall, args: MutableList<LLVMOpaqueValue?>): LLVMOpaqueValue? {
|
||||
logger.log("evaluateConstructorCall : $variableName = ${ir2string(callee)}")
|
||||
memScoped {
|
||||
val params = allocNativeArrayOf(LLVMOpaqueValue, generator.typeInfoValue((callee.descriptor as ClassConstructorDescriptor).containingDeclaration), Int32(1).getLlvmValue())
|
||||
val thisValue = LLVMBuildCall(context.llvmBuilder, context.allocInstanceFunction, params[0], 2, variableName)
|
||||
|
||||
val containingClass = (callee.descriptor as ClassConstructorDescriptor).containingDeclaration
|
||||
val typeInfo = generator.typeInfoValue(containingClass)
|
||||
val allocHint = Int32(1).getLlvmValue()
|
||||
val thisValue = if (containingClass.isArray) {
|
||||
assert(args.size == 1 && LLVMTypeOf(args[0]) == LLVMInt32Type())
|
||||
val size = args[0]
|
||||
val params = allocNativeArrayOf(LLVMOpaqueValue, typeInfo, allocHint, size)
|
||||
LLVMBuildCall(
|
||||
context.llvmBuilder, context.allocArrayFunction, params[0], 3, variableName)
|
||||
} else {
|
||||
val params = allocNativeArrayOf(LLVMOpaqueValue, typeInfo, allocHint)
|
||||
LLVMBuildCall(
|
||||
context.llvmBuilder, context.allocInstanceFunction, params[0], 2, variableName)
|
||||
}
|
||||
val constructorParams: MutableList<LLVMOpaqueValue?> = mutableListOf()
|
||||
constructorParams += thisValue
|
||||
constructorParams += args
|
||||
|
||||
+14
-6
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
|
||||
|
||||
@@ -137,11 +138,16 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
}
|
||||
|
||||
private val arrayClasses = mapOf(
|
||||
"kotlin.Array" to -pointerSize,
|
||||
"kotlin.ByteArray" to -1,
|
||||
"kotlin.CharArray" to -2,
|
||||
"kotlin.IntArray" to -4,
|
||||
"kotlin.String" to -1
|
||||
"kotlin.Array" to -pointerSize,
|
||||
"kotlin.ByteArray" to -1,
|
||||
"kotlin.CharArray" to -2,
|
||||
"kotlin.ShortArray" to -2,
|
||||
"kotlin.IntArray" to -4,
|
||||
"kotlin.LongArray" to -8,
|
||||
"kotlin.FloatArray" to -4,
|
||||
"kotlin.DoubleArray" to -8,
|
||||
"kotlin.BooleanArray" to -1,
|
||||
"kotlin.String" to -1
|
||||
)
|
||||
|
||||
private fun getInstanceSize(classType: LLVMOpaqueType?, className: FqName) : Int {
|
||||
@@ -160,7 +166,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
val size = getInstanceSize(classType, className)
|
||||
|
||||
val superType = classDesc.getSuperClassOrAny().llvmTypeInfoPtr
|
||||
val superTypeOrNull = classDesc.getSuperClassNotAny()
|
||||
val superType = if (superTypeOrNull != null) superTypeOrNull.llvmTypeInfoPtr
|
||||
else NullPointer(runtime.typeInfoType)
|
||||
|
||||
val interfaces = classDesc.implementedInterfaces.map { it.llvmTypeInfoPtr }
|
||||
val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className",
|
||||
|
||||
@@ -186,12 +186,16 @@ task hello3(type: RunKonanTest) {
|
||||
source = "runtime/basic/hello3.kt"
|
||||
} */
|
||||
|
||||
|
||||
task tostring0(type: RunKonanTest) {
|
||||
goldValue = "127\n255\n239\nA\n1122334455\n112233445566778899\n1E+27\n1E-300\ntrue\nfalse\n"
|
||||
source = "runtime/basic/tostring0.kt"
|
||||
}
|
||||
|
||||
task array0(type: RunKonanTest) {
|
||||
goldValue = "5\n6\n7\n8\n9\n10\n11\n12\n13\n"
|
||||
source = "runtime/basic/array0.kt"
|
||||
}
|
||||
|
||||
task if_else(type: UnitKonanTest) {
|
||||
source = "codegen/branching/if_else.kt"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
fun main(args : Array<String>) {
|
||||
// Create instances of all array types.
|
||||
val byteArray = ByteArray(5)
|
||||
println(byteArray.size.toString())
|
||||
|
||||
val charArray = CharArray(6)
|
||||
println(charArray.size.toString())
|
||||
|
||||
val shortArray = ShortArray(7)
|
||||
println(shortArray.size.toString())
|
||||
|
||||
val intArray = IntArray(8)
|
||||
println(intArray.size.toString())
|
||||
|
||||
val longArray = LongArray(9)
|
||||
println(longArray.size.toString())
|
||||
|
||||
val floatArray = FloatArray(10)
|
||||
println(floatArray.size.toString())
|
||||
|
||||
val doubleArray = FloatArray(11)
|
||||
println(doubleArray.size.toString())
|
||||
|
||||
val booleanArray = BooleanArray(12)
|
||||
println(booleanArray.size.toString())
|
||||
|
||||
val stringArray = Array<String>(13)
|
||||
println(stringArray.size.toString())
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Assert.h"
|
||||
#include "Exceptions.h"
|
||||
#include "Memory.h"
|
||||
#include "Natives.h"
|
||||
#include "Types.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
// TODO: those must be compiler intrinsics afterwards.
|
||||
|
||||
// Array.kt
|
||||
KRef Kotlin_Array_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *ArrayAddressOfElementAt(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_Array_set(ArrayHeader* obj, KInt index, KRef value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*ArrayAddressOfElementAt(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_Array_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
array->type_info(), array->count_).GetPlace();
|
||||
memcpy(
|
||||
ArrayAddressOfElementAt(result, 0),
|
||||
ArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_Array_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
// Arrays.kt
|
||||
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *ByteArrayAddressOfElementAt(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_ByteArray_set(ArrayHeader* obj, KInt index, KByte value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*ByteArrayAddressOfElementAt(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_ByteArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theByteArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_ByteArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KChar Kotlin_CharArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KChar>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_CharArray_set(ArrayHeader* obj, KInt index, KChar value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KChar>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_CharArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theCharArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_CharArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KShort Kotlin_ShortArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KShort>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_ShortArray_set(ArrayHeader* obj, KInt index, KShort value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KShort>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_ShortArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theShortArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_ShortArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KInt Kotlin_IntArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KInt>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_IntArray_set(ArrayHeader* obj, KInt index, KInt value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KInt>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_IntArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theIntArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KLong Kotlin_LongArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KLong>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_LongArray_set(ArrayHeader* obj, KInt index, KLong value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KLong>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_LongArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theLongArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_LongArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KFloat Kotlin_FloatArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KFloat>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_FloatArray_set(ArrayHeader* obj, KInt index, KFloat value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KFloat>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_FloatArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theFloatArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_FloatArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KDouble Kotlin_DoubleArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KDouble>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_DoubleArray_set(ArrayHeader* obj, KInt index, KDouble value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KDouble>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_DoubleArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theDoubleArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_DoubleArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KBoolean Kotlin_BooleanArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *PrimitiveArrayAddressOfElementAt<KBoolean>(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_BooleanArray_set(ArrayHeader* obj, KInt index, KBoolean value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*PrimitiveArrayAddressOfElementAt<KBoolean>(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_BooleanArray_clone(const ArrayHeader* array) {
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theBooleanArrayTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_BooleanArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -85,12 +85,11 @@ inline void* AddressOfElementAt(ArrayHeader* obj, int32_t index) {
|
||||
obj->type_info()->instanceSize_ * index;
|
||||
}
|
||||
|
||||
inline uint32_t ArraySizeBytes(const ArrayHeader* obj) {
|
||||
inline uint32_t ArrayDataSizeBytes(const ArrayHeader* obj) {
|
||||
// Instance size is negative.
|
||||
return -obj->type_info()->instanceSize_ * obj->count_;
|
||||
}
|
||||
|
||||
|
||||
// Those two operations are implemented by translator when storing references
|
||||
// to objects.
|
||||
inline void AddRef(ContainerHeader* header) {
|
||||
@@ -259,7 +258,8 @@ extern "C" {
|
||||
|
||||
void InitMemory();
|
||||
void* AllocInstance(const TypeInfo* type_info, PlacementHint hint);
|
||||
void* AllocArrayInstance(const TypeInfo* type_info, PlacementHint hint, uint32_t elements);
|
||||
void* AllocArrayInstance(
|
||||
const TypeInfo* type_info, PlacementHint hint, uint32_t elements);
|
||||
int IsInstance(const ObjHeader* obj, const TypeInfo* type_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
extern "C" {
|
||||
|
||||
// Any.kt
|
||||
KBool Kotlin_Any_equals(KConstRef thiz, KConstRef other) {
|
||||
KBoolean Kotlin_Any_equals(KConstRef thiz, KConstRef other) {
|
||||
return thiz == other;
|
||||
}
|
||||
|
||||
@@ -26,120 +26,6 @@ KString Kotlin_Any_toString(KConstRef thiz) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Arrays.kt
|
||||
// TODO: those must be compiler intrinsics afterwards.
|
||||
KRef Kotlin_Array_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *ArrayAddressOfElementAt(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_Array_set(ArrayHeader* obj, KInt index, KRef value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*ArrayAddressOfElementAt(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_Array_clone(const ArrayHeader* array) {
|
||||
uint32_t length = ArraySizeBytes(array);
|
||||
ArrayHeader* result = ArrayContainer(theArrayTypeInfo, length).GetPlace();
|
||||
memcpy(
|
||||
ArrayAddressOfElementAt(result, 0),
|
||||
ArrayAddressOfElementAt(array, 0),
|
||||
length);
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_Array_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *ByteArrayAddressOfElementAt(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_ByteArray_set(ArrayHeader* obj, KInt index, KByte value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*ByteArrayAddressOfElementAt(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_ByteArray_clone(const ArrayHeader* array) {
|
||||
uint32_t length = ArraySizeBytes(array);
|
||||
ArrayHeader* result = ArrayContainer(theByteArrayTypeInfo, length).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
length);
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_ByteArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KChar Kotlin_CharArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *CharArrayAddressOfElementAt(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_CharArray_set(ArrayHeader* obj, KInt index, KChar value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*CharArrayAddressOfElementAt(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_CharArray_clone(const ArrayHeader* array) {
|
||||
uint32_t length = ArraySizeBytes(array);
|
||||
ArrayHeader* result = ArrayContainer(theCharArrayTypeInfo, length).GetPlace();
|
||||
memcpy(
|
||||
CharArrayAddressOfElementAt(result, 0),
|
||||
CharArrayAddressOfElementAt(array, 0),
|
||||
length);
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_CharArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
KInt Kotlin_IntArray_get(const ArrayHeader* obj, KInt index) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return *IntArrayAddressOfElementAt(obj, index);
|
||||
}
|
||||
|
||||
void Kotlin_IntArray_set(ArrayHeader* obj, KInt index, KInt value) {
|
||||
if (static_cast<uint32_t>(index) >= obj->count_) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
*IntArrayAddressOfElementAt(obj, index) = value;
|
||||
}
|
||||
|
||||
ArrayHeader* Kotlin_IntArray_clone(const ArrayHeader* array) {
|
||||
uint32_t length = ArraySizeBytes(array);
|
||||
ArrayHeader* result = ArrayContainer(theIntArrayTypeInfo, length).GetPlace();
|
||||
memcpy(
|
||||
IntArrayAddressOfElementAt(result, 0),
|
||||
IntArrayAddressOfElementAt(array, 0),
|
||||
length);
|
||||
return result;
|
||||
}
|
||||
|
||||
KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* array) {
|
||||
return array->count_;
|
||||
}
|
||||
|
||||
// io/Console.kt
|
||||
void Kotlin_io_Console_print(KString message) {
|
||||
RuntimeAssert(message->type_info() == theStringTypeInfo, "Must use a string");
|
||||
@@ -192,13 +78,13 @@ KInt Kotlin_String_getStringLength(KString thiz) {
|
||||
|
||||
KString Kotlin_String_fromUtf8Array(const ArrayHeader* array) {
|
||||
RuntimeAssert(array->type_info() == theByteArrayTypeInfo, "Must use a byte array");
|
||||
uint32_t length = ArraySizeBytes(array);
|
||||
// TODO: support full UTF-8.
|
||||
ArrayHeader* result = ArrayContainer(theStringTypeInfo, length).GetPlace();
|
||||
ArrayHeader* result = ArrayContainer(
|
||||
theStringTypeInfo, array->count_).GetPlace();
|
||||
memcpy(
|
||||
ByteArrayAddressOfElementAt(result, 0),
|
||||
ByteArrayAddressOfElementAt(array, 0),
|
||||
length);
|
||||
ArrayDataSizeBytes(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -220,7 +106,7 @@ KString Kotlin_String_plusImpl(KString thiz, KString other) {
|
||||
return result;
|
||||
}
|
||||
|
||||
KBool Kotlin_String_equals(KString thiz, KConstRef other) {
|
||||
KBoolean Kotlin_String_equals(KString thiz, KConstRef other) {
|
||||
if (other == nullptr || other->type_info() != theStringTypeInfo) return 0;
|
||||
const ArrayHeader* otherString = reinterpret_cast<const ArrayHeader*>(other);
|
||||
return thiz->count_ == otherString->count_ &&
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
|
||||
typedef uint8_t KBool;
|
||||
typedef uint8_t KBoolean;
|
||||
typedef uint8_t KByte;
|
||||
typedef uint16_t KChar;
|
||||
// Note that it is signed.
|
||||
@@ -28,21 +28,15 @@ inline const KByte* ByteArrayAddressOfElementAt(
|
||||
return reinterpret_cast<const KByte*>(obj + 1) + index;
|
||||
}
|
||||
|
||||
inline KChar* CharArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
|
||||
return reinterpret_cast<KChar*>(obj + 1) + index;
|
||||
template <typename T>
|
||||
inline T* PrimitiveArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
|
||||
return reinterpret_cast<T*>(obj + 1) + index;
|
||||
}
|
||||
|
||||
inline const KChar* CharArrayAddressOfElementAt(
|
||||
template <typename T>
|
||||
inline const T* PrimitiveArrayAddressOfElementAt(
|
||||
const ArrayHeader* obj, KInt index) {
|
||||
return reinterpret_cast<const KChar*>(obj + 1) + index;
|
||||
}
|
||||
|
||||
inline KInt* IntArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
|
||||
return reinterpret_cast<KInt*>(obj + 1) + index;
|
||||
}
|
||||
|
||||
inline const KInt* IntArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) {
|
||||
return reinterpret_cast<const KInt*>(obj + 1) + index;
|
||||
return reinterpret_cast<const T*>(obj + 1) + index;
|
||||
}
|
||||
|
||||
inline KRef* ArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
|
||||
@@ -58,7 +52,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Any.kt
|
||||
KBool Kotlin_Any_equals(KConstRef thiz, KConstRef other);
|
||||
KBoolean Kotlin_Any_equals(KConstRef thiz, KConstRef other);
|
||||
KInt Kotlin_Any_hashCode(KConstRef thiz);
|
||||
KString Kotlin_Any_toString(KConstRef thiz);
|
||||
|
||||
@@ -95,7 +89,7 @@ KString Kotlin_Int_toString(KInt value);
|
||||
|
||||
// String.kt
|
||||
KInt Kotlin_String_hashCode(KString thiz);
|
||||
KBool Kotlin_String_equals(KString thiz, KConstRef other);
|
||||
KBoolean Kotlin_String_equals(KString thiz, KConstRef other);
|
||||
KInt Kotlin_String_compareTo(KString thiz, KString other);
|
||||
KChar Kotlin_String_get(KString thiz, KInt index);
|
||||
KString Kotlin_String_fromUtf8Array(const ArrayHeader* array);
|
||||
|
||||
@@ -67,7 +67,7 @@ KString Kotlin_Double_toString(KDouble value) {
|
||||
return makeString(cstring);
|
||||
}
|
||||
|
||||
KString Kotlin_Boolean_toString(KBool value) {
|
||||
KString Kotlin_Boolean_toString(KBoolean value) {
|
||||
return makeString(value ? "true" : "false");
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,14 @@ extern "C" {
|
||||
|
||||
extern const TypeInfo* theAnyTypeInfo;
|
||||
extern const TypeInfo* theCloneableTypeInfo;
|
||||
extern const TypeInfo* theArrayTypeInfo;
|
||||
extern const TypeInfo* theByteArrayTypeInfo;
|
||||
extern const TypeInfo* theCharArrayTypeInfo;
|
||||
extern const TypeInfo* theShortArrayTypeInfo;
|
||||
extern const TypeInfo* theIntArrayTypeInfo;
|
||||
extern const TypeInfo* theLongArrayTypeInfo;
|
||||
extern const TypeInfo* theFloatArrayTypeInfo;
|
||||
extern const TypeInfo* theDoubleArrayTypeInfo;
|
||||
extern const TypeInfo* theBooleanArrayTypeInfo;
|
||||
extern const TypeInfo* theStringTypeInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package kotlin
|
||||
|
||||
// TODO: remove that, as RTTI shall be per instantiation.
|
||||
@ExportTypeInfo("theArrayTypeInfo")
|
||||
class Array<T> : Cloneable {
|
||||
// Constructors are handled with compiler magic.
|
||||
private constructor() {}
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -3,7 +3,7 @@ package kotlin
|
||||
@ExportTypeInfo("theByteArrayTypeInfo")
|
||||
class ByteArray : Cloneable {
|
||||
// Constructors are handled with compiler magic.
|
||||
private constructor() {}
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
@@ -24,7 +24,7 @@ class ByteArray : Cloneable {
|
||||
@ExportTypeInfo("theCharArrayTypeInfo")
|
||||
class CharArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
private constructor() {}
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
@@ -42,10 +42,31 @@ class CharArray : Cloneable {
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
|
||||
@ExportTypeInfo("theShortArrayTypeInfo")
|
||||
class ShortArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@SymbolName("Kotlin_ShortArray_get")
|
||||
external public operator fun get(index: Int): Short
|
||||
|
||||
@SymbolName("Kotlin_ShortArray_set")
|
||||
external public operator fun set(index: Int, value: Short): Unit
|
||||
|
||||
@SymbolName("Kotlin_ShortArray_clone")
|
||||
external public override fun clone(): Any
|
||||
|
||||
@SymbolName("Kotlin_ShortArray_getArrayLength")
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
|
||||
@ExportTypeInfo("theIntArrayTypeInfo")
|
||||
class IntArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
private constructor() {}
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
@@ -54,11 +75,95 @@ class IntArray : Cloneable {
|
||||
external public operator fun get(index: Int): Char
|
||||
|
||||
@SymbolName("Kotlin_IntArray_set")
|
||||
external public operator fun set(index: Int, value: Char): Unit
|
||||
external public operator fun set(index: Int, value: Int): Unit
|
||||
|
||||
@SymbolName("Kotlin_IntArray_clone")
|
||||
external public override fun clone(): Any
|
||||
|
||||
@SymbolName("Kotlin_IntArray_getArrayLength")
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
|
||||
@ExportTypeInfo("theLongArrayTypeInfo")
|
||||
class LongArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@SymbolName("Kotlin_LongArray_get")
|
||||
external public operator fun get(index: Int): Char
|
||||
|
||||
@SymbolName("Kotlin_LongArray_set")
|
||||
external public operator fun set(index: Int, value: Long): Unit
|
||||
|
||||
@SymbolName("Kotlin_LongArray_clone")
|
||||
external public override fun clone(): Any
|
||||
|
||||
@SymbolName("Kotlin_LongArray_getArrayLength")
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
|
||||
@ExportTypeInfo("theFloatArrayTypeInfo")
|
||||
class FloatArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@SymbolName("Kotlin_FloatArray_get")
|
||||
external public operator fun get(index: Int): Char
|
||||
|
||||
@SymbolName("Kotlin_FloatArray_set")
|
||||
external public operator fun set(index: Int, value: Float): Unit
|
||||
|
||||
@SymbolName("Kotlin_FloatArray_clone")
|
||||
external public override fun clone(): Any
|
||||
|
||||
@SymbolName("Kotlin_FloatArray_getArrayLength")
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
|
||||
@ExportTypeInfo("theDoubleArrayTypeInfo")
|
||||
class DoubleArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@SymbolName("Kotlin_DoubleArray_get")
|
||||
external public operator fun get(index: Int): Char
|
||||
|
||||
@SymbolName("Kotlin_DoubleArray_set")
|
||||
external public operator fun set(index: Int, value: Double): Unit
|
||||
|
||||
@SymbolName("Kotlin_DoubleArray_clone")
|
||||
external public override fun clone(): Any
|
||||
|
||||
@SymbolName("Kotlin_DoubleArray_getArrayLength")
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
|
||||
@ExportTypeInfo("theBooleanArrayTypeInfo")
|
||||
class BooleanArray : Cloneable {
|
||||
// Constructors are handled with the compiler magic.
|
||||
public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@SymbolName("Kotlin_BooleanArray_get")
|
||||
external public operator fun get(index: Int): Char
|
||||
|
||||
@SymbolName("Kotlin_BooleanArray_set")
|
||||
external public operator fun set(index: Int, value: Boolean): Unit
|
||||
|
||||
@SymbolName("Kotlin_BooleanArray_clone")
|
||||
external public override fun clone(): Any
|
||||
|
||||
@SymbolName("Kotlin_BooleanArray_getArrayLength")
|
||||
external private fun getArrayLength(): Int
|
||||
}
|
||||
@@ -841,12 +841,12 @@ public class Float : Number(), Comparable<Float> {
|
||||
/**
|
||||
* A constant holding the smallest *positive* nonzero value of Float.
|
||||
*/
|
||||
//public val MIN_VALUE: Float
|
||||
//public const val MIN_VALUE: Float
|
||||
|
||||
/**
|
||||
* A constant holding the largest positive finite value of Float.
|
||||
*/
|
||||
//public val MAX_VALUE: Float
|
||||
//public const val MAX_VALUE: Float
|
||||
|
||||
/**
|
||||
* A constant holding the positive infinity value of Float.
|
||||
@@ -856,12 +856,12 @@ public class Float : Number(), Comparable<Float> {
|
||||
/**
|
||||
* A constant holding the negative infinity value of Float.
|
||||
*/
|
||||
//public val NEGATIVE_INFINITY: Float
|
||||
//public const val NEGATIVE_INFINITY: Float
|
||||
|
||||
/**
|
||||
* A constant holding the "not a number" value of Float.
|
||||
*/
|
||||
//public val NaN: Float
|
||||
//public const val NaN: Float
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1045,27 +1045,27 @@ public class Double : Number(), Comparable<Double> {
|
||||
/**
|
||||
* A constant holding the smallest *positive* nonzero value of Double.
|
||||
*/
|
||||
//public val MIN_VALUE: Double
|
||||
//public const val MIN_VALUE: Double
|
||||
|
||||
/**
|
||||
* A constant holding the largest positive finite value of Double.
|
||||
*/
|
||||
//public val MAX_VALUE: Double
|
||||
//public const val MAX_VALUE: Double
|
||||
|
||||
/**
|
||||
* A constant holding the positive infinity value of Double.
|
||||
*/
|
||||
// public val POSITIVE_INFINITY: Double
|
||||
// public const val POSITIVE_INFINITY: Double
|
||||
|
||||
/**
|
||||
* A constant holding the negative infinity value of Double.
|
||||
*/
|
||||
// public val NEGATIVE_INFINITY: Double
|
||||
// public const val NEGATIVE_INFINITY: Double
|
||||
|
||||
/**
|
||||
* A constant holding the "not a number" value of Double.
|
||||
*/
|
||||
// public val NaN: Double
|
||||
// public const val NaN: Double
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user