diff --git a/translator/run_tests.sh b/translator/run_tests.sh index 6fbb3352676..ec0b32640a5 100755 --- a/translator/run_tests.sh +++ b/translator/run_tests.sh @@ -30,7 +30,7 @@ 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 ./src/main/resources/kotllib/* $DIRECTORY/linked/ + cp ./src/main/resources/kotlib/linked/* $DIRECTORY/linked/ if [ -f "$DIRECTORY/c/$TEST.c" ] then diff --git a/translator/src/main/kotlin/main.kt b/translator/src/main/kotlin/main.kt index 74d15cdca22..31356ea1e8f 100644 --- a/translator/src/main/kotlin/main.kt +++ b/translator/src/main/kotlin/main.kt @@ -1,6 +1,9 @@ import com.intellij.openapi.util.Disposer import org.kotlinnative.translator.FileTranslator +import org.kotlinnative.translator.ProjectTranslator import org.kotlinnative.translator.parseAndAnalyze +import java.io.File +import java.util.* fun main(args: Array) { @@ -9,8 +12,19 @@ fun main(args: Array) { return } + val analyzedFiles = ArrayList(); + + val kotlib = ClassLoader.getSystemClassLoader().getResources("kotlib/kotlin") + for (resourse in kotlib) { + for (app in File(resourse.toURI()).listFiles()) { + analyzedFiles.add(app.absoluteFile.toString()) + } + } + + analyzedFiles.addAll(args.toList()) + val disposer = Disposer.newDisposable() - val state = parseAndAnalyze(args.asList(), disposer, arm = false) + val state = parseAndAnalyze(analyzedFiles, disposer, arm = false) val files = state.environment.getSourceFiles() if (files.isEmpty()) { @@ -18,6 +32,11 @@ fun main(args: Array) { return } - println(FileTranslator(state, files[0]).generateCode()) + + files.forEach { + FileTranslator(state, it).addDeclarations() + } + + println(ProjectTranslator(state).generateCode()) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index 147bc6430e1..ffd8f50188c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -1,19 +1,12 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.psi.* -import org.kotlinnative.translator.llvm.LLVMBuilder class FileTranslator(val state: TranslationState, val file: KtFile) { - private var codeBuilder = LLVMBuilder(state.arm) + private var codeBuilder = state.codeBuilder - fun generateCode(): String { - codeBuilder.clean() - generateFileBody() - return codeBuilder.toString() - } - - private fun generateFileBody() { + fun addDeclarations() { for (declaration in file.declarations) { when (declaration) { is KtNamedFunction -> { @@ -35,21 +28,6 @@ class FileTranslator(val state: TranslationState, val file: KtFile) { } } - for (property in state.properties.values) { - property.generate() - } - - for (objectCodegen in state.objects.values) { - objectCodegen.generate() - } - - for (clazz in state.classes.values) { - clazz.generate() - } - - for (function in state.functions.values) { - function.generate() - } } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt new file mode 100644 index 00000000000..b77299d4f1d --- /dev/null +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt @@ -0,0 +1,34 @@ +package org.kotlinnative.translator + +import org.jetbrains.kotlin.psi.* +import org.kotlinnative.translator.llvm.LLVMBuilder + +class ProjectTranslator(val state: TranslationState) { + private var codeBuilder = state.codeBuilder + + fun generateCode(): String { + codeBuilder.clean() + generateProjectBody() + return codeBuilder.toString() + } + + private fun generateProjectBody() { + for (property in state.properties.values) { + property.generate() + } + + for (objectCodegen in state.objects.values) { + objectCodegen.generate() + } + + for (clazz in state.classes.values) { + clazz.generate() + } + + for (function in state.functions.values) { + function.generate() + } + } + +} + diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index 8ba47443cb8..c91cb42c4a8 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.utils.PathUtil import org.kotlinnative.translator.exceptions.TranslationException +import org.kotlinnative.translator.llvm.LLVMBuilder import org.kotlinnative.translator.llvm.LLVMVariable import java.util.* @@ -28,6 +29,7 @@ class TranslationState(val environment: KotlinCoreEnvironment, val bindingContex var classes = HashMap() var objects = HashMap() var properties = HashMap() + val codeBuilder = LLVMBuilder(arm) } fun parseAndAnalyze(sources: List, disposer: Disposable, arm: Boolean = false): TranslationState { diff --git a/translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt b/translator/src/main/resources/kotlib/kotlin/ByteArray.kt similarity index 96% rename from translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt rename to translator/src/main/resources/kotlib/kotlin/ByteArray.kt index 9dab25db4fa..0626e5bb6f0 100644 --- a/translator/src/main/kotlin/org/kotlinnative/kotlib/Arrays/ByteArray.kt +++ b/translator/src/main/resources/kotlib/kotlin/ByteArray.kt @@ -1,4 +1,3 @@ -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) diff --git a/translator/src/main/resources/kotllib/ByteArray.ll b/translator/src/main/resources/kotllib/ByteArray.ll deleted file mode 100644 index b9635298d52..00000000000 --- a/translator/src/main/resources/kotllib/ByteArray.ll +++ /dev/null @@ -1,89 +0,0 @@ -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 deleted file mode 100644 index 7d5bf7bc460..00000000000 --- a/translator/src/main/resources/kotllib/array_c.ll +++ /dev/null @@ -1,51 +0,0 @@ -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 diff --git a/translator/src/test/kotlin/tests/input/bytearray_1.txt b/translator/src/test/kotlin/tests/input/bytearray_1.txt new file mode 100644 index 00000000000..87c37413a31 --- /dev/null +++ b/translator/src/test/kotlin/tests/input/bytearray_1.txt @@ -0,0 +1 @@ +bytearray_1(123) == 123 diff --git a/translator/src/test/kotlin/tests/kotlin/bytearray_1.kt b/translator/src/test/kotlin/tests/kotlin/bytearray_1.kt new file mode 100644 index 00000000000..941707bae88 --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/bytearray_1.kt @@ -0,0 +1,5 @@ +fun bytearray_1(x: Byte): Byte { + val z = ByteArray(10) + z.set(1, x) + return z.get(1) +} \ No newline at end of file