Support basic reification in IR
This commit is contained in:
+35
-13
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.codegen.AsmUtil.*
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
|
||||
import org.jetbrains.kotlin.codegen.StackValue.*
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.OperationKind.AS
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.OperationKind.SAFE_AS
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||
@@ -658,12 +660,14 @@ class ExpressionCodegen(
|
||||
|
||||
fun newArrayInstruction(arrayType: KotlinType) {
|
||||
if (KotlinBuiltIns.isArray(arrayType)) {
|
||||
val elementJetType = arrayType.arguments[0].type
|
||||
// putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
// elementJetType,
|
||||
// ReifiedTypeInliner.OperationKind.NEW_ARRAY
|
||||
// )
|
||||
mv.newarray(boxType(elementJetType.asmType))
|
||||
val elementKotlinType = arrayType.arguments[0].type
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
elementKotlinType,
|
||||
ReifiedTypeInliner.OperationKind.NEW_ARRAY,
|
||||
mv,
|
||||
this
|
||||
)
|
||||
mv.newarray(boxType(elementKotlinType.asmType))
|
||||
} else {
|
||||
val type = typeMapper.mapType(arrayType)
|
||||
mv.newarray(correctElementType(type))
|
||||
@@ -672,7 +676,11 @@ class ExpressionCodegen(
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: BlockInfo): StackValue {
|
||||
val owner = expression.returnTargetSymbol.owner
|
||||
val isNonLocalReturn = owner != irFunction
|
||||
//TODO: should be owner != irFunction
|
||||
val isNonLocalReturn = state.typeMapper.mapFunctionName(
|
||||
owner.descriptor,
|
||||
OwnerKind.IMPLEMENTATION
|
||||
) != state.typeMapper.mapFunctionName(irFunction.descriptor, OwnerKind.IMPLEMENTATION)
|
||||
if (isNonLocalReturn && state.isInlineDisabled) {
|
||||
//TODO: state.diagnostics.report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE.on(expression))
|
||||
genThrow(
|
||||
@@ -829,7 +837,8 @@ class ExpressionCodegen(
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: BlockInfo): StackValue {
|
||||
val asmType = expression.typeOperand.toKotlinType().asmType
|
||||
val kotlinType = expression.typeOperand.toKotlinType()
|
||||
val asmType = kotlinType.asmType
|
||||
when (expression.operator) {
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> {
|
||||
val result = expression.argument.accept(this, data)
|
||||
@@ -848,17 +857,30 @@ class ExpressionCodegen(
|
||||
StackValue.putUnitInstance(mv)
|
||||
}
|
||||
val boxedType = boxType(asmType)
|
||||
generateAsCast(
|
||||
mv, expression.typeOperand.toKotlinType(), boxedType, expression.operator == IrTypeOperator.SAFE_CAST,
|
||||
state.languageVersionSettings.isReleaseCoroutines()
|
||||
)
|
||||
|
||||
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
kotlinType, if (IrTypeOperator.SAFE_CAST == expression.operator) SAFE_AS else AS, mv, this
|
||||
)
|
||||
v.checkcast(boxedType)
|
||||
} else {
|
||||
generateAsCast(
|
||||
mv, kotlinType, boxedType, expression.operator == IrTypeOperator.SAFE_CAST,
|
||||
state.languageVersionSettings.isReleaseCoroutines()
|
||||
)
|
||||
}
|
||||
return onStack(boxedType)
|
||||
}
|
||||
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> {
|
||||
gen(expression.argument, OBJECT_TYPE, data)
|
||||
val type = boxType(asmType)
|
||||
generateIsCheck(mv, expression.typeOperand.toKotlinType(), type, state.languageVersionSettings.isReleaseCoroutines())
|
||||
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS, mv, this)
|
||||
v.instanceOf(type)
|
||||
} else {
|
||||
generateIsCheck(mv, kotlinType, type, state.languageVersionSettings.isReleaseCoroutines())
|
||||
}
|
||||
if (IrTypeOperator.NOT_INSTANCEOF == expression.operator) {
|
||||
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(mv)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
typealias ArrayS = Array<String>
|
||||
|
||||
fun testArray() {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: A.java
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun bar(block: () -> String) : String {
|
||||
return block()
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun doCall(f: () -> Any) = f()
|
||||
|
||||
fun test1() {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class TestClass {
|
||||
companion object {
|
||||
inline operator fun <T> invoke(task: () -> T) = task()
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class TestClass {
|
||||
inline operator fun <T> invoke(task: () -> T) = task()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
object ExtProvider {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun <T> outer(command: () -> T) : T = command()
|
||||
|
||||
inline fun <K> inner(action: () -> K): K = action()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun bar1(): String {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> Any?.check(): Boolean {
|
||||
return this is T
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
inline fun <R, T> foo(x : R?, block : (R?) -> T) : T {
|
||||
return block(x)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
inline fun <R, T> foo(x : R?, y : R?, block : (R?) -> T) : T {
|
||||
if (x == null) {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun runNoInline(f: () -> Unit) = f()
|
||||
|
||||
fun test() {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun test(list: List<String>) {
|
||||
val result = mutableListOf<String>()
|
||||
use1 { list.forEach { result.add(it) } }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun test(s: ()->Int){
|
||||
var i = 0;
|
||||
i = s()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// For mutable collections and related types (e.g., MutableList, MutableListIterator)
|
||||
// 'as?' should be generated as a single 'safeAs...' intrinsic call
|
||||
// without instanceof or 'is...'.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun test(s: ()->Int){
|
||||
var i = 0;
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun test(s: ()->Int){
|
||||
var i = 0;
|
||||
try {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: test.kt
|
||||
|
||||
fun test1() {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: test.kt
|
||||
|
||||
fun test1(): String {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> Any?.isa() = this is T
|
||||
|
||||
// 1 INSTANCEOF
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> isNullable() = null is T
|
||||
|
||||
// 1 INSTANCEOF
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
val nonConstFlag = true
|
||||
|
||||
inline fun <T, R> calc(value : T, fn: (T) -> R) : R = fn(value)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> Any?.foo() = this as T
|
||||
|
||||
inline fun <reified Y> Any?.foo2() = foo<Y?>()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> Any?.foo() = this as T?
|
||||
|
||||
inline fun <reified Y> Any?.foo2() = foo<Y?>()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> Any?.foo() = this is T
|
||||
|
||||
inline fun <reified Y> Any?.foo2() = foo<Y?>()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun <reified T> Any?.foo() = this is T?
|
||||
|
||||
inline fun <reified Y> Any?.foo2() = foo<Y?>()
|
||||
|
||||
Reference in New Issue
Block a user