From f0f94623f45d2978d40c4569a0a035e305b91118 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Wed, 23 Feb 2022 17:04:35 +0100 Subject: [PATCH] [WASM] Implement data class hashCode and toString for arrays --- .../kotlin/backend/wasm/WasmSymbols.kt | 23 +++++++++-- .../backend/wasm/lower/BuiltInsLowering.kt | 41 +++++++++++-------- .../box/dataClasses/toString/arrayParams.kt | 1 - 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt index f48d63a2c1a..8657ffde302 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt @@ -17,10 +17,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classifierOrFail -import org.jetbrains.kotlin.ir.types.defaultType -import org.jetbrains.kotlin.ir.types.typeWith +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.render @@ -205,6 +202,24 @@ class WasmSymbols( val arraysCopyInto = findFunctions(collectionsPackage.memberScope, Name.identifier("copyInto")) .map { symbolTable.referenceSimpleFunction(it) } + private val contentToString: List = + findFunctions(collectionsPackage.memberScope, Name.identifier("contentToString")) + .map { symbolTable.referenceSimpleFunction(it) } + + private val contentHashCode: List = + findFunctions(collectionsPackage.memberScope, Name.identifier("contentHashCode")) + .map { symbolTable.referenceSimpleFunction(it) } + + private fun findOverloadForReceiver(arrayType: IrType, overloadsList: List): IrSimpleFunctionSymbol = + overloadsList.first { + val receiverType = it.owner.extensionReceiverParameter?.type + receiverType != null && arrayType.isNullable() == receiverType.isNullable() && arrayType.classOrNull == receiverType.classOrNull + } + + fun findContentToStringOverload(arrayType: IrType): IrSimpleFunctionSymbol = findOverloadForReceiver(arrayType, contentToString) + + fun findContentHashCodeOverload(arrayType: IrType): IrSimpleFunctionSymbol = findOverloadForReceiver(arrayType, contentHashCode) + private val getProgressionLastElementSymbols = irBuiltIns.findFunctions(Name.identifier("getProgressionLastElement"), "kotlin", "internal") diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt index 5f761f3669b..c6450b1c9f3 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt @@ -13,19 +13,14 @@ import org.jetbrains.kotlin.backend.wasm.WasmBackendContext import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.ir.backend.js.utils.isEqualsInheritedFromAny -import org.jetbrains.kotlin.ir.builders.irCall -import org.jetbrains.kotlin.ir.builders.irCallConstructor -import org.jetbrains.kotlin.ir.builders.irComposite -import org.jetbrains.kotlin.ir.builders.irInt +import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.interpreter.toIrConst -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classFqName -import org.jetbrains.kotlin.ir.types.getClass -import org.jetbrains.kotlin.ir.types.isNullable +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.parentOrNull @@ -112,17 +107,27 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { putValueArgument(0, call.getValueArgument(0)!!) } - irBuiltins.dataClassArrayMemberHashCodeSymbol -> { - // TODO: Implement - return builder.irComposite { - +call.getValueArgument(0)!! - +irInt(7777) + irBuiltins.dataClassArrayMemberHashCodeSymbol, irBuiltins.dataClassArrayMemberToStringSymbol -> { + val argument = call.getValueArgument(0)!! + val argumentType = argument.type + val overloadSymbol: IrSimpleFunctionSymbol + val returnType: IrType + if (symbol == irBuiltins.dataClassArrayMemberHashCodeSymbol) { + overloadSymbol = symbols.findContentHashCodeOverload(argumentType) + returnType = irBuiltins.intType + } else { + overloadSymbol = symbols.findContentToStringOverload(argumentType) + returnType = irBuiltins.stringType } - } - irBuiltins.dataClassArrayMemberToStringSymbol -> { - // TODO: Implement - return builder.irCall(symbols.anyNtoString).apply { - putValueArgument(0, call.getValueArgument(0)) + + return builder.irCall( + overloadSymbol, + returnType, + ).apply { + extensionReceiver = argument + if (argumentType.classOrNull == irBuiltins.arrayClass) { + putTypeArgument(0, argumentType.getArrayElementType(irBuiltins)) + } } } in symbols.startCoroutineUninterceptedOrReturnIntrinsics -> { diff --git a/compiler/testData/codegen/box/dataClasses/toString/arrayParams.kt b/compiler/testData/codegen/box/dataClasses/toString/arrayParams.kt index 12ffe402956..8da643e530e 100644 --- a/compiler/testData/codegen/box/dataClasses/toString/arrayParams.kt +++ b/compiler/testData/codegen/box/dataClasses/toString/arrayParams.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: WASM // WASM_MUTE_REASON: IGNORED_IN_JS // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6