[JS IR BE] Fix boolean and/or generation
This commit is contained in:
+14
-6
@@ -7,15 +7,13 @@ package org.jetbrains.kotlin.ir.backend.js.lower.calls
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransformer {
|
||||
@@ -47,10 +45,12 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
|
||||
}
|
||||
|
||||
irBuiltIns.booleanType.let {
|
||||
add(it, OperatorNames.AND, intrinsics.jsBitAnd)
|
||||
add(it, OperatorNames.OR, intrinsics.jsBitOr)
|
||||
// These operators are not short-circuit -- using bitwise operators '&', '|', '^' followed by coercion to boolean
|
||||
add(it, OperatorNames.AND) { call -> toBoolean(irCall(call, intrinsics.jsBitAnd, dispatchReceiverAsFirstArgument = true)) }
|
||||
add(it, OperatorNames.OR) { call -> toBoolean(irCall(call, intrinsics.jsBitOr, dispatchReceiverAsFirstArgument = true)) }
|
||||
add(it, OperatorNames.XOR) { call -> toBoolean(irCall(call, intrinsics.jsBitXor, dispatchReceiverAsFirstArgument = true)) }
|
||||
|
||||
add(it, OperatorNames.NOT, intrinsics.jsNot)
|
||||
add(it, OperatorNames.XOR, intrinsics.jsBitXor)
|
||||
}
|
||||
|
||||
for (type in primitiveNumbers) {
|
||||
@@ -231,6 +231,14 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
|
||||
}
|
||||
}
|
||||
|
||||
private fun booleanNegate(e: IrExpression) =
|
||||
JsIrBuilder.buildCall(intrinsics.jsNot, irBuiltIns.booleanType).apply {
|
||||
putValueArgument(0, e)
|
||||
}
|
||||
|
||||
private fun toBoolean(e: IrExpression) =
|
||||
booleanNegate(booleanNegate(e))
|
||||
|
||||
private fun toInt32(e: IrExpression) =
|
||||
JsIrBuilder.buildCall(intrinsics.jsBitOr, irBuiltIns.intType).apply {
|
||||
putValueArgument(0, e)
|
||||
|
||||
+5
@@ -6791,6 +6791,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/regression/typeChecks"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("booleanOperatorsTypes.kt")
|
||||
public void testBooleanOperatorsTypes() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/typeChecks/booleanOperatorsTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyVarargInConstructorCall.kt")
|
||||
public void testEmptyVarargInConstructorCall() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/typeChecks/emptyVarargInConstructorCall.kt");
|
||||
|
||||
+5
@@ -6826,6 +6826,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/regression/typeChecks"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("booleanOperatorsTypes.kt")
|
||||
public void testBooleanOperatorsTypes() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/typeChecks/booleanOperatorsTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyVarargInConstructorCall.kt")
|
||||
public void testEmptyVarargInConstructorCall() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/typeChecks/emptyVarargInConstructorCall.kt");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
|
||||
package foo
|
||||
|
||||
fun check(x: Any?) {
|
||||
x as Boolean
|
||||
}
|
||||
|
||||
fun tests(x: Boolean, y: Boolean) {
|
||||
check(x)
|
||||
check(!x)
|
||||
check(x or y)
|
||||
check(x and y)
|
||||
check(x xor y)
|
||||
check(x.not())
|
||||
check(x || y)
|
||||
check(x && y)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
tests(false, false)
|
||||
tests(false, true)
|
||||
tests(true, false)
|
||||
tests(true, true)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user