translator: add multifile translation, kotlib with fixs, fix bytearrays, add tests for bytearray

This commit is contained in:
Alexey Stepanov
2016-07-20 14:11:34 +03:00
parent da99860c98
commit 2c42b7680e
10 changed files with 66 additions and 168 deletions
+1 -1
View File
@@ -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
+21 -2
View File
@@ -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<String>) {
@@ -9,8 +12,19 @@ fun main(args: Array<String>) {
return
}
val analyzedFiles = ArrayList<String>();
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<String>) {
return
}
println(FileTranslator(state, files[0]).generateCode())
files.forEach {
FileTranslator(state, it).addDeclarations()
}
println(ProjectTranslator(state).generateCode())
}
@@ -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()
}
}
}
@@ -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()
}
}
}
@@ -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<String, ClassCodegen>()
var objects = HashMap<String, ObjectCodegen>()
var properties = HashMap<String, PropertyCodegen>()
val codeBuilder = LLVMBuilder(arm)
}
fun parseAndAnalyze(sources: List<String>, disposer: Disposable, arm: Boolean = false): TranslationState {
@@ -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)
@@ -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)
@@ -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
}
@@ -0,0 +1 @@
bytearray_1(123) == 123
@@ -0,0 +1,5 @@
fun bytearray_1(x: Byte): Byte {
val z = ByteArray(10)
z.set(1, x)
return z.get(1)
}