Commit Graph

1166 Commits

Author SHA1 Message Date
Vasily Levchenko 0887dfabae CODEGEN: coercion fixed
- do not let evaluateWhen ignore case when there're no result expected.
2016-11-28 19:32:37 +03:00
Vasily Levchenko 90d705aae2 kotlin-compiler: 1.1-20161128.112645-274 2016-11-28 19:24:18 +03:00
Alexander Gorshenev 5627688390 A million element byte array segfaults 2016-11-28 20:15:15 +04:00
Konstantin Anisimov 725512ad96 CODEGEN: enable interfaces in translator 2016-11-28 16:14:04 +03:00
Konstantin Anisimov bb665ccc70 TEST: enable interface test 2016-11-28 16:14:04 +03:00
Nikolay Igotti e800e8acd6 Use primary constructor in ArrayList. 2016-11-28 15:41:03 +03:00
Nikolay Igotti 3d2166410c TEST: Coercion to Unit and ++/-- tests. (#87) 2016-11-27 11:22:54 +03:00
Nikolay Igotti 29c0eda720 Array list, implementation by @elizarov (#84) 2016-11-26 16:30:15 +03:00
Vasily Levchenko f4529298e4 CODEGEN: more logging and verification 2016-11-26 14:16:47 +03:00
Konstantin Anisimov ce19f73172 RUNTIME: missed operators implemented:
- Kotlin_Int_toChar
- Kotlin_Long_xor_Long
- Kotlin_Long_ushr_Long

(cherry picked from commit 7222a8effe6ae23c7ce9784fc65225282876fde4)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov 87c8a9f895 CODEGEN: fix initialization and workarounds for object initialization with companion objects and etc.
(cherry picked from commit ae9e493ee92a3730a5ad82e072ab7eed32a8cc27)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov 4717e99ac2 TEST: companion and init0 tests
(cherry picked from commit f8e80249e9f986ae58a52a57173d2cb0b68a653b)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov 8496a0f2a9 CODEGEN: naive implementation of string_concatination (not tested)
(cherry picked from commit 8e0e9480d7cbec6e640f1b5a8a15af0d2f1bc278)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov 7a0d0ec5a7 CODEGEN: emprovements:
- fixed stop on non body functions
- IMPLICIT_CAST implemented
- naive extension function implementation

(cherry picked from commit 3d3b51b0fca3980012e77f47feded5030f0d7901)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov 1b1360c77e TEST: extension function generation
(cherry picked from commit 27b8c962b2b12883150166c83c19b950c9091334)
2016-11-25 23:37:49 +03:00
Vasily Levchenko 9c9d75f6b8 CODEGEN: make TODO more informative
(cherry picked from commit b28a5732bb6c1f278efb48efd08319cc5e4f5e75)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov d88ff9ac08 CODEGEN: buggy fixing:
visitReturn - shouldn't emit anything, just pass execution to evaluateReturn
evaluateThrow - should ends with unreachable statement
evaluateReturn - should actually emit ret instruction only for non-Unit return type of statement

(cherry picked from commit 0221353f05fa20826c817a9195210825535193c4)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov c05b8c6411 CODEGEN: IMPLICIT_COERCION_TO_UNIT implementation and analyze each branch separately
(cherry picked from commit 649f47c990fe297e7e622e27e71c1ae10d16b329)
2016-11-25 23:37:49 +03:00
Konstantin Anisimov a93b7ab886 LOGGER: dump ir to string (partly)
(cherry picked from commit 674f32e46c78dac18877497651f6b27e1eed1dcc)
2016-11-25 23:37:49 +03:00
Vasily Levchenko 50b2646329 .gitignore: *.kt.exe 2016-11-24 21:00:38 +03:00
Vasily Levchenko 4806cf8fe1 TEST: executables has .kt.exe extension 2016-11-24 20:59:56 +03:00
Alexander Gorshenev 268e3b26c0 A couple of new tests
for boxing
    and for body assignment in an interface
2016-11-24 17:46:16 +04:00
Vasily Levchenko 2a0d01191a CODEGEN: primary/secondary constructor fields initialization
for code:
--------8<--------
>cat ../backend.native/tests/codegen/object/fields1.kt
class B(val a:Int, b:Int) {
    constructor(pos:Int):this(1, pos) {}
    val pos = b + 1
}

fun primaryConstructorCall(a:Int, b:Int) = B(a, b).pos

fun secondaryConstructorCall(a:Int) = B(a).pos
--------8<--------
translator generates:
--------8<--------
; ModuleID = '../backend.native/tests/codegen/object/fields1.kt.bc'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
...
define i8* @"kfun:B.<init>(Int;Int)"(i8*, i32, i32) {                          ;primary constructor
entry:
  %this = alloca i8*
  store i8* %0, i8** %this
  %a = alloca i32
  store i32 %1, i32* %a
  %b = alloca i32
  store i32 %2, i32* %b
  %tmp_0 = load i8*, i8** %this
  %tmp_2 = load i8*, i8** %this
  %tmp_1 = call i8* @"kfun:kotlin.Any.<init>()"(i8* %tmp_2)
  %tmp_3 = bitcast i8* %tmp_0 to %struct.ObjHeader*
  %tmp_4 = getelementptr %struct.ObjHeader, %struct.ObjHeader* %tmp_3, i32 1
  %tmp_5 = bitcast %struct.ObjHeader* %tmp_4 to %"kclass:B"*
  %tmp_6 = getelementptr inbounds %"kclass:B", %"kclass:B"* %tmp_5, i32 0, i32 0
  %tmp_7 = load i32, i32* %a
  store i32 %tmp_7, i32* %tmp_6
  %tmp_8 = bitcast i8* %tmp_0 to %struct.ObjHeader*
  %tmp_9 = getelementptr %struct.ObjHeader, %struct.ObjHeader* %tmp_8, i32 1
  %tmp_10 = bitcast %struct.ObjHeader* %tmp_9 to %"kclass:B"*
  %tmp_11 = getelementptr inbounds %"kclass:B", %"kclass:B"* %tmp_10, i32 0, i32 1
  %tmp_13 = load i32, i32* %b
  %tmp_12 = call i32 @Kotlin_Int_plus_Int(i32 %tmp_13, i32 1)
  store i32 %tmp_12, i32* %tmp_11                                 ; <-- store b + 1 value to pos field
  ret i8* %tmp_0
}

...

define i8* @"kfun:B.<init>(Int)"(i8*, i32) {                      ;secondary constructor
entry:
  %this = alloca i8*
  store i8* %0, i8** %this
  %pos = alloca i32
  store i32 %1, i32* %pos
  %tmp_0 = load i8*, i8** %this
  %tmp_3 = load i32, i32* %pos
  %tmp_4 = load i8*, i8** %this
  %tmp_1 = call i8* @"kfun:B.<init>(Int;Int)"(i8* %tmp_4, i32 1, i32 %tmp_3) ; call primary constructor
  ret i8* %tmp_0
}

--------8<--------
2016-11-24 15:52:34 +03:00
Vasily Levchenko 48ee81548e TEST: primary/secondary constructor fields initialization 2016-11-24 15:52:34 +03:00
Konstantin Anisimov 62917fd171 .gitignore: added some test suite artifacts 2016-11-24 14:39:14 +03:00
Nikolay Igotti af1ef9f653 More collections. (#80) 2016-11-23 13:08:55 +03:00
Svyatoslav Scherbina 46ff436fb3 backend: use fancy type names for LLVM C API 2016-11-23 15:41:49 +07:00
Vasily Levchenko f3dab21718 CODEGEN: don't generate getters/setters and other functions with descriptor.modality == Modality.ABSTRACT
(cherry picked from commit 0ca5bc071f64a5eb68f49896c8b5b28952ec6126)
2016-11-23 10:18:52 +03:00
SvyatoslavScherbina 8cdbf790ec Merge pull request #82 from JetBrains/interop-ng
The new interop (again)
2016-11-23 14:10:50 +07:00
Svyatoslav Scherbina c988175431 Review feedback: move kotlin_.cinterop package to kotlinx 2016-11-23 11:40:17 +07:00
Konstantin Anisimov bd715df0d6 CODEGEN: construction body evaluation
for code:
--------8<--------
> cat ../backend.native/tests/codegen/object/initialization.kt
open class A(val a:Int, val b:Int)

open class B(val c:Int, d:Int):A(c, d)

open class C(i:Int, j:Int):B(i + j, 42)

class D (i: Int, j:Int) : C(i, j){
   constructor(i: Int, j:Int, k:Int) : this(i, j) {
      foo(i)
   }
   constructor():this(1, 2)
}

fun foo(i:Int) : Unit {}

fun foo(i:Int, j:Int):Int {
   val c = D(i, j)
   return c.c
}
--------8<--------

folowing code is generated:
--------8<--------
; ModuleID = '../backend.native/tests/codegen/object/initialization.kt.bc'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
...

define i8* @"kfun:C.<init>(Int;Int)"(i8*, i32, i32) {
entry:
  %this = alloca i8*
  store i8* %0, i8** %this
  %i = alloca i32
  store i32 %1, i32* %i
  %j = alloca i32
  store i32 %2, i32* %j
  %tmp_0 = load i8*, i8** %this
  %tmp_3 = load i32, i32* %i
  %tmp_4 = load i32, i32* %j
  %tmp_2 = call i32 @Kotlin_Int_plus_Int(i32 %tmp_3, i32 %tmp_4)
  %tmp_6 = load i8*, i8** %this
  %tmp_1 = call i8* @"kfun:B.<init>(Int;Int)"(i8* %tmp_6, i32 %tmp_2, i32 42)
  ret i8* %tmp_0
}

define i8* @"kfun:D.<init>(Int;Int)"(i8*, i32, i32) {
entry:
  %this = alloca i8*
  store i8* %0, i8** %this
  %i = alloca i32
  store i32 %1, i32* %i
  %j = alloca i32
  store i32 %2, i32* %j
  %tmp_0 = load i8*, i8** %this
  %tmp_2 = load i32, i32* %i
  %tmp_3 = load i32, i32* %j
  %tmp_4 = load i8*, i8** %this
  %tmp_1 = call i8* @"kfun:C.<init>(Int;Int)"(i8* %tmp_4, i32 %tmp_2, i32 %tmp_3)
  ret i8* %tmp_0
}

define i8* @"kfun:D.<init>(Int;Int;Int)"(i8*, i32, i32, i32) {
entry:
  %this = alloca i8*
  store i8* %0, i8** %this
  %i = alloca i32
  store i32 %1, i32* %i
  %j = alloca i32
  store i32 %2, i32* %j
  %k = alloca i32
  store i32 %3, i32* %k
  %tmp_0 = load i8*, i8** %this
  %tmp_2 = load i32, i32* %i
  %tmp_3 = load i32, i32* %j
  %tmp_4 = load i8*, i8** %this
  %tmp_1 = call i8* @"kfun:D.<init>(Int;Int)"(i8* %tmp_4, i32 %tmp_2, i32 %tmp_3)
  %tmp_5 = load i32, i32* %i
  call void @"kfun:foo(Int)"(i32 %tmp_5)
  ret i8* %tmp_0
}

--------8<--------
2016-11-22 21:13:25 +03:00
Vasily Levchenko 81742556a6 TEST: constructor body test 2016-11-22 21:13:25 +03:00
Konstantin Anisimov 4d24d735de CODEGEN: Support for "Throw" implemented
for code
--------8<--------
fun main(args : Array<String>) {
    val cond = 1
    if (cond == 2) throw RuntimeException()
    if (cond == 3) throw NoSuchElementException("no such element")
    if (cond == 4) throw Error("error happens")

    println("Done")
}
--------8<--------
translator generates following: code
--------8<--------
; ModuleID = 'backend.native/tests/runtime/basic/throw0.kt.bc'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"

...

define void @"kfun:main(Array<String>)"(i8*) {
entry:
  %args = alloca i8*
  store i8* %0, i8** %args
  %cond = alloca i32
  store i32 1, i32* %cond
  %tmp_1 = load i32, i32* %cond
  %tmp_0 = icmp eq i32 %tmp_1, 2
  br i1 %tmp_0, label %label_1, label %label_0

label_0:                                          ; preds = %label_1, %entry
  %tmp_7 = load i32, i32* %cond
  %tmp_6 = icmp eq i32 %tmp_7, 3
  br i1 %tmp_6, label %label_3, label %label_2

label_1:                                          ; preds = %entry
  %tmp_4 = call i8* @AllocInstance(%struct.TypeInfo* @"ktype:kotlin.RuntimeException", i32 1)
  %tmp_41 = call i8* @"kfun:kotlin.RuntimeException.<init>()"(i8* %tmp_4)
  %tmp_5 = bitcast i8* %tmp_41 to %struct.ObjHeader*
  call void @ThrowException(%struct.ObjHeader* %tmp_5) ; <------- throwing RuntimeException
  br label %label_0

label_2:                                          ; preds = %label_3, %label_0
  %tmp_14 = load i32, i32* %cond
  %tmp_13 = icmp eq i32 %tmp_14, 4
  br i1 %tmp_13, label %label_5, label %label_4

label_3:                                          ; preds = %label_0
  %tmp_10 = call i8* @AllocInstance(%struct.TypeInfo* @"ktype:kotlin.NoSuchElementException", i32 1)
  %tmp_102 = call i8* @"kfun:kotlin.NoSuchElementException.<init>(String)"(i8* %tmp_10, i8* @"kstr:2E869yDM+y/5vqQYAKDPRI+j44w=")
  %tmp_12 = bitcast i8* %tmp_102 to %struct.ObjHeader*
  call void @ThrowException(%struct.ObjHeader* %tmp_12)
  br label %label_2

label_4:                                          ; preds = %label_5, %label_2
  call void @Kotlin_io_Console_println(i8* @"kstr:6bRQ0UvCNj0pLITxfPrVz71YpFg=")
  ret void

label_5:                                          ; preds = %label_2
  %tmp_17 = call i8* @AllocInstance(%struct.TypeInfo* @"ktype:kotlin.Error", i32 1)
  %tmp_173 = call i8* @"kfun:kotlin.Error.<init>(String)"(i8* %tmp_17, i8* @"kstr:7YdnBMJy09naL/RsuOEV6Im2kOg=")
  %tmp_19 = bitcast i8* %tmp_173 to %struct.ObjHeader*
  call void @ThrowException(%struct.ObjHeader* %tmp_19)
  br label %label_4
}
--------8<--------
2016-11-22 14:36:09 +03:00
Nikolay Igotti 81811e8c3a TEST: throw keyword support. 2016-11-22 14:36:09 +03:00
Svyatoslav Scherbina 453a360707 Interop/Runtime: add minor code improvements 2016-11-22 16:47:05 +07:00
Svyatoslav Scherbina 950bc62c7b Review feedback, part 1 2016-11-22 16:45:31 +07:00
Svyatoslav Scherbina a58d682d40 Interop: remove old version 2016-11-22 13:19:49 +07:00
Svyatoslav Scherbina 183f6a6d2f Interop/Indexer: update prebuilts with new interop versions
also port Interop/Runtime/libcallbacks to new interop
2016-11-22 13:19:49 +07:00
Svyatoslav Scherbina c5f00c3301 InteropExample: port to new interop 2016-11-22 13:19:49 +07:00
Svyatoslav Scherbina 8a486d7fae backend: partially port code to new interop 2016-11-22 13:02:07 +07:00
Svyatoslav Scherbina f0df5f9435 Interop: implement new version 2016-11-22 13:02:07 +07:00
Svyatoslav Scherbina 3095044420 build: use Kotlin 1.1-M02 to build all Kotlin JVM sources 2016-11-22 13:01:14 +07:00
Svyatoslav Scherbina 8a66de216d Interop: rework String auto conversion
use memScoped
2016-11-22 13:01:04 +07:00
Svyatoslav Scherbina 53884f8da6 Interop/StubGenerator: add minor code improvements 2016-11-22 13:01:04 +07:00
Konstantin Anisimov 0cd4512dd5 CODEGEN: Support for "null" constant implemented
for code:
--------8<--------
> cat ../backend.native/tests/codegen/basics/null_check.kt
//--- Test "eqeq" -------------------------------------------------------------//

fun check_eqeq(a: Any?) = a == null

fun null_check_eqeq1() : Boolean {
  return check_eqeq(Any())
}

fun null_check_eqeq2() : Boolean {
  return check_eqeq(null)
}

//--- Test "eqeqeq" -----------------------------------------------------------//

fun check_eqeqeq(a: Any?) = a === null

fun null_check_eqeqeq1() : Boolean {
  return check_eqeqeq(Any())
}

fun null_check_eqeqeq2() : Boolean {
  return check_eqeqeq(null)
}

--------8<--------

code generator produces, following code:

--------8<--------
> llvm-dis-mp-3.8 ../backend.native/tests/codegen/basics/null_check.kt.bc -o -
; ModuleID = '../backend.native/tests/codegen/basics/null_check.kt.bc'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
...
define i1 @"kfun:check_eqeq(Any?)"(i8*) {
entry:
  %a = alloca i8*
  store i8* %0, i8** %a
  %tmp_1 = load i8*, i8** %a
  %tmp_3 = alloca i1
  %tmp_4 = icmp eq i8* %tmp_1, null
  br i1 %tmp_4, label %label_1, label %label_0

label_0:                                          ; preds = %entry
  %tmp_7 = bitcast i8* %tmp_1 to i8**
  %tmp_8 = load i8*, i8** %tmp_7
  %tmp_9 = bitcast i8* %tmp_8 to %struct.TypeInfo*
  %tmp_10 = call i8* @LookupOpenMethod(%struct.TypeInfo* %tmp_9, i64 5922905592022884074)
  %tmp_11 = bitcast i8* %tmp_10 to i1 (i8*, i8*)*
  %tmp_6 = call i1 %tmp_11(i8* %tmp_1, i8* null)
  store i1 %tmp_6, i1* %tmp_3
  br label %label_2

label_1:                                          ; preds = %entry
  %tmp_5 = icmp eq i8* %tmp_1, null
  store i1 %tmp_5, i1* %tmp_3
  br label %label_2

label_2:                                          ; preds = %label_1, %label_0
  %tmp_0 = load i1, i1* %tmp_3
  ret i1 %tmp_0
}

define i1 @"kfun:null_check_eqeq1()"() {
entry:
  %tmp_1 = call i8* @AllocInstance(%struct.TypeInfo* @"ktype:kotlin.Any", i32 1)
  %tmp_11 = call i8* @"kfun:kotlin.Any.<init>()"(i8* %tmp_1)
  %tmp_0 = call i1 @"kfun:check_eqeq(Any?)"(i8* %tmp_11)
  ret i1 %tmp_0
}

declare i8* @"kfun:kotlin.Any.<init>()"(i8*)

define i1 @"kfun:null_check_eqeq2()"() {
entry:
  %tmp_0 = call i1 @"kfun:check_eqeq(Any?)"(i8* null)
  ret i1 %tmp_0
}

define i1 @"kfun:check_eqeqeq(Any?)"(i8*) {
entry:
  %a = alloca i8*
  store i8* %0, i8** %a
  %tmp_1 = load i8*, i8** %a
  %tmp_0 = icmp eq i8* %tmp_1, null
  ret i1 %tmp_0
}

define i1 @"kfun:null_check_eqeqeq1()"() {
entry:
  %tmp_1 = call i8* @AllocInstance(%struct.TypeInfo* @"ktype:kotlin.Any", i32 1)
  %tmp_11 = call i8* @"kfun:kotlin.Any.<init>()"(i8* %tmp_1)
  %tmp_0 = call i1 @"kfun:check_eqeqeq(Any?)"(i8* %tmp_11)
  ret i1 %tmp_0
}

define i1 @"kfun:null_check_eqeqeq2()"() {
entry:
  %tmp_0 = call i1 @"kfun:check_eqeqeq(Any?)"(i8* null)
  ret i1 %tmp_0
}
...
--------8<--------
2016-11-21 21:08:36 +03:00
Konstantin Anisimov df358e8bd4 TEST: Tests for "null" constant added 2016-11-21 21:08:36 +03:00
Vasily Levchenko cf466e0cd7 codegen: fix implementation of branch generation to generate 'ternary' operator
for code:
--------8<--------
> cat ../backend.native/tests/runtime/basic/hello4.kt
fun main(args : Array<String>) {
    val x = 2
    println(if (x == 2) "Hello" else "Привет")
    println(if (x == 3) "Bye" else "Пока")
 }
--------8<--------
code generator produces:
--------8<--------
> llvm-dis-mp-3.8 ../backend.native/tests/runtime/basic/hello4.kt.bc -o -
; ModuleID = '../backend.native/tests/runtime/basic/hello4.kt.bc'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"

...
define void @"kfun:main(Array<String>)"(i8*) {
entry:
  %args = alloca i8*
  store i8* %0, i8** %args
  %x = alloca i32
  store i32 2, i32* %x
  %tmp_1 = alloca i8*                             ; allocation of temporal variable (0)
  %tmp_3 = load i32, i32* %x
  %tmp_2 = icmp eq i32 %tmp_3, 2
  br i1 %tmp_2, label %label_2, label %label_1

label_0:                                          ; preds = %label_2, %label_1
  %tmp_0 = load i8*, i8** %tmp_1                  ; load value from tmp_1 (2)
  call void @Kotlin_io_Console_println(i8* %tmp_0)
  %tmp_8 = alloca i8*
  %tmp_10 = load i32, i32* %x
  %tmp_9 = icmp eq i32 %tmp_10, 3
  br i1 %tmp_9, label %label_5, label %label_4

label_1:                                          ; preds = %entry  store value to tmp_1 (1)
  store i8* @"kstr:KAWujn4S8YITX5L7kIQ7sQgNO+g=", i8** %tmp_1
  br label %label_0

label_2:                                          ; preds = %entry
  store i8* @"kstr:9/+ei3uy4Jtwk1pdeF4MxdnQq/A=", i8** %tmp_1
  br label %label_0

label_3:                                          ; preds = %label_5, %label_4
  %tmp_7 = load i8*, i8** %tmp_8
  call void @Kotlin_io_Console_println(i8* %tmp_7)
  ret void

label_4:                                          ; preds = %label_0
  store i8* @"kstr:q9lt9dN14ItE52B0fKxQuwMq4cc=", i8** %tmp_8
  br label %label_3

label_5:                                          ; preds = %label_0
  store i8* @"kstr:95JCQGTQyhp9FO/gWI8QwFLSjmk=", i8** %tmp_8
  br label %label_3
}

...
--------8<--------
2016-11-21 20:36:40 +03:00
Nikolay Igotti c54e786c33 TEST: Ternary operator test. 2016-11-21 20:36:40 +03:00
Vasily Levchenko ce059ac54b kotlin-compiler: .1-20161121.132728-268 2016-11-21 18:41:46 +03:00
Alexander Gorshenev 1e87dfeb8b link test 2016-11-21 15:30:08 +04:00