[JS IR BE] Add ranges to runtime, rangeTo for primitive numbers

This commit is contained in:
Svyatoslav Kuzmich
2018-07-03 15:29:33 +03:00
parent 4c38899a2a
commit 1abb4f42ac
93 changed files with 59 additions and 99 deletions
@@ -122,6 +122,8 @@ class JsIntrinsics(
val jsCompareTo = getInternalFunction("compareTo")
val jsEquals = getInternalFunction("equals")
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
val longConstructor =
context.symbolTable.referenceConstructor(context.getClass(FqName("kotlin.Long")).constructors.single())
@@ -115,6 +115,10 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
op(it, ConversionNames.TO_SHORT, ::useDispatchReceiver)
op(it, ConversionNames.TO_LONG, intrinsics.jsToLong)
}
for (type in primitiveNumbers) {
op(type, Name.identifier("rangeTo"), ::transformRangeTo)
}
}
symbolToTransformer.run {
@@ -287,6 +291,19 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
return call.dispatchReceiver!!
}
private fun transformRangeTo(call: IrCall): IrExpression {
if (call.valueArgumentsCount != 1) return call
return with(call.symbol.owner.valueParameters[0].type) {
when {
isByte() || isShort() || isInt() ->
irCall(call, intrinsics.jsNumberRangeToNumber, dispatchReceiverAsFirstArgument = true)
isLong() ->
irCall(call, intrinsics.jsNumberRangeToLong, dispatchReceiverAsFirstArgument = true)
else -> call
}
}
}
private fun transformEqeqOperator(call: IrCall): IrExpression {
val lhs = call.getValueArgument(0)!!
val rhs = call.getValueArgument(1)!!
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: NATIVE
class StrList : List<String?> {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class A : Collection<Char> {
override val size: Int
get() = throw UnsupportedOperationException()
-1
View File
@@ -1,2 +1 @@
// IGNORE_BACKEND: JS_IR
fun box() = if (4 as? Unit != null) "Fail" else "OK"
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class IntRange {
operator fun contains(a: Int) = (1..2).contains(a)
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun test(str: String): String {
var s = ""
for (i in 1..3) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
var s = "OK"
for (i in 1..3) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
var r = ""
for (i in 1..1) {
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
var index = 0
interface IterableIterator : Iterator<Int> {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val x = 2
return when(x) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class MyRange1() : ClosedRange<Int> {
override val start: Int
get() = 0
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
package demo2
fun print(o : Any?) {}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
package demo2
fun print(o : Any?) {}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun test() = 239
fun box() = if(test() in 239..240) "OK" else "fail"
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun test1(): String {
var r = ""
for (i in 1..2) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
//KT-3869 Loops and finally: outer finally block not run
class MyString {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
//test for appropriate
class MyString {
-1
View File
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
//KT-1038 Cannot compile lazy iterators
class YieldingIterator<T>(val yieldingFunction : ()->T?) : Iterator<T>
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
fun IntRange.forEach(body : (Int) -> Unit) {
for(i in this) {
body(i)
-1
View File
@@ -1,4 +1,3 @@
// 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: JS_IR
fun test1(): Boolean {
test1@ for(i in 1..2) {
continue@test1
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
-1
View File
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
public abstract class FList<T>() {
public abstract val head: T
public abstract val tail: FList<T>
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// KT-5869
operator fun <T> Iterator<T>.iterator(): Iterator<T> = this
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
val range = 1 .. 3
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun IntRange.contains(s: String): Boolean = true
fun box(): String {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
var result = 0
val intRange: IntProgression = 1..3
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
var result = 0
val intRange = 1..3
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
var result = 0
for (i: Int? in 1..3) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
private object EmptyMap : Map<Any, Nothing> {
override val size: Int get() = 0
override fun isEmpty(): Boolean = true
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
private object EmptyStringMap : Map<String, Nothing> {
override val size: Int get() = 0
override fun isEmpty(): Boolean = true
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: NATIVE
interface Container {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: NATIVE
class A : Map<String, String> {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: NATIVE
var result = ""
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
open class A1 {
open val size: Int = 56
}
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: NATIVE
open class A0<E> : MutableList<E> {
@@ -1,5 +1,4 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// IGNORE_BACKEND: JS_IR
val x = 1
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// FILE: 1.kt
package test
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// FILE: 1.kt
package test
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// FILE: 1.kt
package test
@@ -22,6 +22,16 @@ private val runtimeSources = listOfKtFilesFrom(
"libraries/stdlib/js/src/kotlin/core.kt",
"core/builtins/native/kotlin/Number.kt",
"core/builtins/native/kotlin/Comparable.kt",
"core/builtins/src/kotlin/internal/InternalAnnotations.kt",
"core/builtins/src/kotlin/internal/progressionUtil.kt",
"core/builtins/src/kotlin/Iterators.kt",
"core/builtins/src/kotlin/ProgressionIterators.kt",
"core/builtins/src/kotlin/Progressions.kt",
"core/builtins/src/kotlin/Range.kt",
"core/builtins/src/kotlin/Ranges.kt",
"core/builtins/src/kotlin/Unit.kt",
"core/builtins/native/kotlin/Collections.kt",
"core/builtins/native/kotlin/Iterator.kt",
"libraries/stdlib/js/irRuntime",
BasicBoxTest.COMMON_FILES_DIR_PATH
)
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1117
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1125
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1236
package foo
@@ -86,4 +85,4 @@ fun box(): String {
assertEquals(":return:", global)
return "OK"
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1112
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1114
// http://youtrack.jetbrains.com/issue/KT-5257
// JS: for with continue with label fails on runtime
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1112
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1113
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1110
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1110
var c = 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1109
// see KT-7683
// WhenTranslator must recognize KtWhenConditionInRange for when statement
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1122
// see KT-7683
// WhenTranslator must recognize KtWhenConditionInRange for custom classes that implement ClosedRange
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1230
// EXPECTED_REACHABLE_NODES: 1112
// see KT-7683
// WhenTranslator must recognize KtWhenConditionInRange and produce faster code when matched expression is Int
package foo
@@ -31,4 +30,4 @@ fun get(value: Int): Int {
invocationCount++
return value
}
var invocationCount = 0
var invocationCount = 0
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1131
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1115
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1152
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1114
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1125
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1116
package foo
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1229
// EXPECTED_REACHABLE_NODES: 1112
package foo
fun box(): String {
@@ -32,4 +31,4 @@ fun box(): String {
assertEquals(sum - skipOuter - skipInner, sumInner, "sumInner")
return "OK"
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1114
package foo
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1115
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1146
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1146
package foo
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1108
fun box(): String {
var log = ""
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1115
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1113
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1113
package foo
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1114
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1108
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1110
package foo
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1228
// EXPECTED_REACHABLE_NODES: 1110
package foo
operator fun Int.component1(): Int {
@@ -21,4 +20,4 @@ fun box(): String {
if (s != "b") return "s != 'b', it: $s"
return "OK"
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1113
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1143
package foo
+1 -2
View File
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1226
// EXPECTED_REACHABLE_NODES: 1108
package foo
fun box(): String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1108
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1108
package foo
+1 -3
View File
@@ -1,6 +1,4 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1226
package foo
// EXPECTED_REACHABLE_NODES: 1108
fun box(): String {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1108
package foo
+6 -1
View File
@@ -55,10 +55,15 @@ open class UnsupportedOperationException(message: String?, cause: Throwable?) :
constructor(cause: Throwable?) : this(null, cause)
}
open class NoSuchElementException(message: String?, cause: Throwable?) : RuntimeException(message, cause) {
constructor() : this(null, null)
constructor(message: String?) : this(message, null)
}
// TODO: fix function names to satisfy style convention (depends on built-in names)
fun THROW_CCE() {
throw ClassCastException()
}
fun THROW_NPE() {
throw NullPointerException()
}
}
+15
View File
@@ -0,0 +1,15 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package kotlin.js
// Creates IntRange for {Byte, Short, Int}.rangeTo(x: {Byte, Short, Int})
fun numberRangeToNumber(start: dynamic, endInclusive: dynamic) =
IntRange(start, endInclusive)
// Create LongRange for {Byte, Short, Int}.rangeTo(x: Long)
// Long.rangeTo(x: *) should be implemented in Long class
fun numberRangeToLong(start: dynamic, endInclusive: dynamic) =
LongRange(numberToLong(start), endInclusive)