From 826c524a9b6454e1bc786fc725203b959c5922cd Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Thu, 26 Jul 2018 16:15:37 +0300 Subject: [PATCH] [JS IE BE] Lower string equality method/operators --- .../js/lower/IntrinsicifyCallsLowering.kt | 57 ++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt index 688a1ff201e..f6eccf5682f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt @@ -125,7 +125,8 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL symbolToTransformer.run { add(irBuiltIns.eqeqeqSymbol, intrinsics.jsEqeqeq) add(irBuiltIns.eqeqSymbol, ::transformEqeqOperator) - // TODO: implement it a right way + + // ieee754equals can only be applied in between statically known Floats or Doubles add(irBuiltIns.ieee754equalsFunByOperandType, intrinsics.jsEqeqeq) add(irBuiltIns.booleanNotSymbol, intrinsics.jsNot) @@ -515,17 +516,19 @@ fun shouldReplaceCompareToWithRuntimeCall(call: IrCall): Boolean { /* Equality translation table: -| | JsN | JsN? | Long | Long? | Bool | Bool? | Other | Other? | -|----------------|------|------|------|-------|------|-------|-------|--------| -| JsN | === | === | == | == | === | === | K.eq | K.eq | -| JsN? | === | == | == | == | === | K.eq | K.eq | K.eq | -| Long | == | == | K.eq | K.eq | === | === | K.eq | K.eq | -| Long? | == | == | K.eq | K.eq | === | K.eq | K.eq | K.eq | -| Bool | === | === | === | === | === | === | K.eq | K.eq | -| Bool? | === | K.eq | === | K.eq | === | == | K.eq | K.eq | -| Other with .eq | .eq | .eq | .eq | .eq | .eq | .eq | .eq | .eq | -| Other w/o .eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | -| Other? | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | +| | JsN | JsN? | Long | Long? | Bool | Bool? | String | String? | Other | Other? | +|----------------|------|------|------|-------|------|-------|--------|---------|-------|--------| +| JsN | === | === | == | == | === | === | === | === | K.eq | K.eq | +| JsN? | === | == | == | == | === | K.eq | === | K.eq | K.eq | K.eq | +| Long | == | == | K.eq | K.eq | === | === | === | === | K.eq | K.eq | +| Long? | == | == | K.eq | K.eq | === | K.eq | === | K.eq | K.eq | K.eq | +| Bool | === | === | === | === | === | === | === | === | K.eq | K.eq | +| Bool? | === | K.eq | === | K.eq | === | == | === | K.eq | K.eq | K.eq | +| String | === | === | === | === | === | === | === | === | K.eq | K.eq | +| String? | === | K.eq | === | K.eq | === | K.eq | === | == | K.eq | K.eq | +| Other with .eq | .eq | .eq | .eq | .eq | .eq | .eq | .eq | .eq | .eq | .eq | +| Other w/o .eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | +| Other? | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | K.eq | JsNumber -- type lowered to JS Number @@ -548,6 +551,8 @@ fun translateEquals(lhs: IrType, rhs: IrType): EqualityLoweringType = when { lhs.isNullableLong() -> translateEqualsForNullableLong(rhs) lhs.isBoolean() -> translateEqualsForBoolean(rhs) lhs.isNullableBoolean() -> translateEqualsForNullableBoolean(rhs) + lhs.isString() -> translateEqualsForString(rhs) + lhs.isNullableString() -> translateEqualsForNullableString(rhs) lhs.isNullable() -> RuntimeFunctionCall else -> RuntimeOrMethodCall } @@ -556,6 +561,7 @@ fun translateEqualsForJsNumber(rhs: IrType): EqualityLoweringType = when { rhs.isJsNumber() || rhs.isNullableJsNumber() -> IdentityOperator rhs.isLong() || rhs.isNullableLong() -> EqualityOperator rhs.isBoolean() || rhs.isNullableBoolean() -> IdentityOperator + rhs.isString() || rhs.isNullableString() -> IdentityOperator else -> RuntimeFunctionCall } @@ -563,7 +569,7 @@ fun translateEqualsForNullableJsNumber(rhs: IrType): EqualityLoweringType = when rhs.isJsNumber() -> IdentityOperator rhs.isNullableJsNumber() -> EqualityOperator rhs.isLong() || rhs.isNullableLong() -> EqualityOperator - rhs.isBoolean() -> IdentityOperator + rhs.isBoolean() || rhs.isString() -> IdentityOperator else -> RuntimeFunctionCall } @@ -571,6 +577,7 @@ fun translateEqualsForLong(rhs: IrType): EqualityLoweringType = when { rhs.isJsNumber() || rhs.isNullableJsNumber() -> EqualityOperator rhs.isLong() || rhs.isNullableLong() -> RuntimeFunctionCall rhs.isBoolean() || rhs.isNullableBoolean() -> IdentityOperator + rhs.isString() || rhs.isNullableString() -> IdentityOperator else -> RuntimeFunctionCall } @@ -578,6 +585,7 @@ fun translateEqualsForNullableLong(rhs: IrType): EqualityLoweringType = when { rhs.isJsNumber() || rhs.isNullableJsNumber() -> EqualityOperator rhs.isLong() || rhs.isNullableLong() -> RuntimeFunctionCall rhs.isBoolean() -> IdentityOperator + rhs.isString() -> IdentityOperator else -> RuntimeFunctionCall } @@ -585,6 +593,7 @@ fun translateEqualsForBoolean(rhs: IrType): EqualityLoweringType = when { rhs.isJsNumber() || rhs.isNullableJsNumber() -> IdentityOperator rhs.isLong() || rhs.isNullableLong() -> IdentityOperator rhs.isBoolean() || rhs.isNullableBoolean() -> IdentityOperator + rhs.isString() || rhs.isNullableString() -> IdentityOperator else -> RuntimeFunctionCall } @@ -595,9 +604,31 @@ fun translateEqualsForNullableBoolean(rhs: IrType): EqualityLoweringType = when rhs.isNullableLong() -> RuntimeFunctionCall rhs.isBoolean() -> IdentityOperator rhs.isNullableBoolean() -> EqualityOperator + rhs.isString() -> IdentityOperator else -> RuntimeFunctionCall } +fun translateEqualsForString(rhs: IrType): EqualityLoweringType = when { + rhs.isJsNumber() || rhs.isNullableJsNumber() -> IdentityOperator + rhs.isLong() || rhs.isNullableLong() -> IdentityOperator + rhs.isBoolean() || rhs.isNullableBoolean() -> IdentityOperator + rhs.isString() || rhs.isNullableString() -> IdentityOperator + else -> RuntimeFunctionCall +} + +fun translateEqualsForNullableString(rhs: IrType): EqualityLoweringType = when { + rhs.isJsNumber() -> IdentityOperator + rhs.isNullableJsNumber() -> RuntimeFunctionCall + rhs.isLong() -> IdentityOperator + rhs.isNullableLong() -> RuntimeFunctionCall + rhs.isBoolean() -> IdentityOperator + rhs.isNullableBoolean() -> RuntimeFunctionCall + rhs.isString() -> IdentityOperator + rhs.isNullableString() -> EqualityOperator + else -> RuntimeFunctionCall +} + + private fun IrType.isNullableJsNumber(): Boolean = isNullablePrimitiveType() && !isNullableLong() && !isNullableChar()