From e645de1e7c96d146fa8a64594226e44caf5286b2 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Wed, 20 Jul 2016 12:52:47 +0300 Subject: [PATCH] translator: add ByteArray, kotlib, fix test for kotlib --- translator/run_tests.sh | 2 + .../kotlinnative/kotlib/Arrays/ByteArray.kt | 41 +++++++++ .../src/main/resources/kotllib/ByteArray.ll | 89 +++++++++++++++++++ .../src/main/resources/kotllib/array_c.ll | 51 +++++++++++ 4 files changed, 183 insertions(+) create mode 100644 translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt create mode 100644 translator/src/main/resources/kotllib/ByteArray.ll create mode 100644 translator/src/main/resources/kotllib/array_c.ll diff --git a/translator/run_tests.sh b/translator/run_tests.sh index d54bb8303de..f88f4b25362 100755 --- a/translator/run_tests.sh +++ b/translator/run_tests.sh @@ -30,6 +30,8 @@ for i in $( ls "$DIRECTORY/input"); do clang-3.6 -S -emit-llvm $DIRECTORY/linked/main.c -o $DIRECTORY/linked/main.ll -Wno-implicit-function-declaration rm -f $DIRECTORY/linked/main.c + cp /home/user/Kotlin/carkot/translator/src/main/resources/kotllib/* $DIRECTORY/linked/ + if [ -f "$DIRECTORY/c/$TEST.c" ] then clang-3.6 -S -emit-llvm "$DIRECTORY/c/$TEST.c" -o $DIRECTORY/linked/$TEST"_c.ll" -Wno-implicit-function-declaration diff --git a/translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt b/translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt new file mode 100644 index 00000000000..9dab25db4fa --- /dev/null +++ b/translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt @@ -0,0 +1,41 @@ +external fun malloc(size: Int): Byte +external fun malloc_array(size: Int): Int +external fun kotlinclib_get_byte(src: Int, index: Int): Byte +external fun kotlinclib_set_byte(src: Int, index: Int, value: Byte) + + +class ByteArray(var size: Int) { + val data: Int + + /** Returns the number of elements in the array. */ + //val size: Int + + init { + this.data = malloc_array(this.size) + } + + /** Returns the array element at the given [index]. This method can be called using the index operator. */ + fun get(index: Int): Byte { + return kotlinclib_get_byte(this.data, index) + } + + + /** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */ + fun set(index: Int, value: Byte) { + kotlinclib_set_byte(this.data, index, value) + } + + + fun clone(): ByteArray { + val newInstance = ByteArray(this.size) + var index = 0 + while (index < this.size) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance + } + +} \ No newline at end of file diff --git a/translator/src/main/resources/kotllib/ByteArray.ll b/translator/src/main/resources/kotllib/ByteArray.ll new file mode 100644 index 00000000000..b9635298d52 --- /dev/null +++ b/translator/src/main/resources/kotllib/ByteArray.ll @@ -0,0 +1,89 @@ +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) +declare i8* @malloc(i32) +%class.ByteArray = type { i32, i32 } +define void @ByteArray(%class.ByteArray* %classvariable.this, i32 %size) +{ +%classvariable.this.addr = alloca %class.ByteArray, align 4 +%size.addr = alloca i32, align 4 +store i32 %size, i32* %size.addr, align 4 +%var1 = load i32* %size.addr, align 4 +%var2 = getelementptr inbounds %class.ByteArray* %classvariable.this.addr, i32 0, i32 0 +store i32 %var1, i32* %var2, align 4 +%var3 = bitcast %class.ByteArray* %classvariable.this to i8* +%var4 = bitcast %class.ByteArray* %classvariable.this.addr to i8* +call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var3, i8* %var4, i64 8, i32 4, i1 false) +%var5 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1 +%var6 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0 +%var7 = load i32* %var6, align 4 +%var8 = call i32 @malloc_array(i32 %var7) +%var9 = alloca i32, align 4 +store i32 %var8, i32* %var9, align 4 +%var10 = load i32* %var5, align 4 +%var11 = load i32* %var9, align 4 +store i32 %var11, i32* %var5, align 4 +ret void +} +define i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %index) +{ +%index.addr = alloca i32, align 4 +store i32 %index, i32* %index.addr, align 4 +%var12 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1 +%var13 = load i32* %var12, align 4 +%var14 = load i32* %index.addr, align 4 +%var15 = call i8 @kotlinclib_get_byte(i32 %var13, i32 %var14) +%var16 = alloca i8, align 1 +store i8 %var15, i8* %var16, align 1 +%var17 = load i8* %var16, align 1 +ret i8 %var17 +} +define void @ByteArray.clone(%class.ByteArray* %instance, %class.ByteArray* %classvariable.this) +{ +%var18 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0 +%var19 = load i32* %var18, align 4 +%var21 = call i8* @malloc(i32 8) +%var20 = bitcast i8* %var21 to %class.ByteArray* +call void @ByteArray(%class.ByteArray* %var20, i32 %var19) +%managed.index.1 = alloca i32, align 4 +store i32 0, i32* %managed.index.1, align 4 +br label %label.while.1 +label.while.1: +%var22 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0 +%var23 = load i32* %managed.index.1, align 4 +%var24 = load i32* %var22, align 4 +%var25 = icmp slt i32 %var23, %var24 +br i1 %var25, label %label.while.2, label %label.while.3 +label.while.2: +%var26 = load i32* %managed.index.1, align 4 +%var27 = call i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %var26) +%var28 = alloca i8, align 1 +store i8 %var27, i8* %var28, align 1 +%var29 = load i32* %managed.index.1, align 4 +%var30 = load i8* %var28, align 1 +call void @ByteArray.set(%class.ByteArray* %var20, i32 %var29, i8 %var30) +%var31 = load i32* %managed.index.1, align 4 +%var32 = add nsw i32 %var31, 1 +%var33 = load i32* %managed.index.1, align 4 +store i32 %var32, i32* %managed.index.1, align 4 +br label %label.while.1 +label.while.3: +%var34 = bitcast %class.ByteArray* %var20 to i8* +%var35 = bitcast %class.ByteArray* %instance to i8* +call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var35, i8* %var34, i64 8, i32 4, i1 false) +ret void +} +define void @ByteArray.set(%class.ByteArray* %classvariable.this, i32 %index, i8 %value) +{ +%index.addr = alloca i32, align 4 +store i32 %index, i32* %index.addr, align 4 +%value.addr = alloca i8, align 1 +store i8 %value, i8* %value.addr, align 1 +%var36 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1 +%var37 = load i32* %var36, align 4 +%var38 = load i32* %index.addr, align 4 +%var39 = load i8* %value.addr, align 1 +call void @kotlinclib_set_byte(i32 %var37, i32 %var38, i8 %var39) +ret void +} +declare i8 @kotlinclib_get_byte(i32 %src, i32 %index) +declare i32 @malloc_array(i32 %size) +declare void @kotlinclib_set_byte(i32 %src, i32 %index, i8 %value) \ No newline at end of file diff --git a/translator/src/main/resources/kotllib/array_c.ll b/translator/src/main/resources/kotllib/array_c.ll new file mode 100644 index 00000000000..7d5bf7bc460 --- /dev/null +++ b/translator/src/main/resources/kotllib/array_c.ll @@ -0,0 +1,51 @@ +declare i8* @malloc(i32) #1 + +define i32 @malloc_array(i32 %x) #0 { + %1 = alloca i32, align 4 + store i32 %x, i32* %1, align 4 + %2 = load i32* %1, align 4 + %3 = call i8* @malloc(i32 %2) + %4 = ptrtoint i8* %3 to i32 + ret i32 %4 +} + +; Function Attrs: nounwind uwtable +define signext i8 @kotlinclib_get_byte(i32 %data, i32 %index) { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %ptr = alloca i8*, align 8 + store i32 %data, i32* %1, align 4 + store i32 %index, i32* %2, align 4 + %3 = load i32* %1, align 4 + %4 = sext i32 %3 to i64 + %5 = inttoptr i64 %4 to i8* + store i8* %5, i8** %ptr, align 8 + %6 = load i8** %ptr, align 8 + %7 = load i32* %2, align 4 + %8 = sext i32 %7 to i64 + %9 = getelementptr inbounds i8* %6, i64 %8 + %10 = load i8* %9, align 1 + ret i8 %10 +} + +; Function Attrs: nounwind uwtable +define void @kotlinclib_set_byte(i32 %data, i32 %index, i8 signext %value) { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i8, align 1 + %ptr = alloca i8*, align 8 + store i32 %data, i32* %1, align 4 + store i32 %index, i32* %2, align 4 + store i8 %value, i8* %3, align 1 + %4 = load i32* %1, align 4 + %5 = sext i32 %4 to i64 + %6 = inttoptr i64 %5 to i8* + store i8* %6, i8** %ptr, align 8 + %7 = load i8* %3, align 1 + %8 = load i8** %ptr, align 8 + %9 = load i32* %2, align 4 + %10 = sext i32 %9 to i64 + %11 = getelementptr inbounds i8* %8, i64 %10 + store i8 %7, i8* %11, align 1 + ret void +} \ No newline at end of file