diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt index 79c6423eccd..e0b221bb6de 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt @@ -166,7 +166,7 @@ class BodyGenerator( } override fun visitConst(expression: IrConst<*>): Unit = - generateConstExpression(expression, body, context) + generateConstExpression(expression, body, context, functionContext.irFunction.fileOrNull?.fileEntry) override fun visitGetField(expression: IrGetField) { val field: IrField = expression.symbol.owner @@ -907,15 +907,5 @@ class BodyGenerator( return false } - private fun IrExpression.getSourceLocation(): SourceLocation { - val fileEntry = functionContext.irFunction.fileEntry - val path = fileEntry.name - val startLine = fileEntry.getLineNumber(startOffset) - val startColumn = fileEntry.getColumnNumber(startOffset) - - if (startLine < 0 || startColumn < 0) return SourceLocation.NoLocation - - return SourceLocation.Location(path, startLine, startColumn) - } - + private fun IrExpression.getSourceLocation() = getSourceLocation(functionContext.irFunction.fileOrNull?.fileEntry) } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt index f890b2281cf..84b291daf00 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.backend.js.utils.isJsExport import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName @@ -28,6 +29,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.parentOrNull import org.jetbrains.kotlin.wasm.ir.* +import org.jetbrains.kotlin.wasm.ir.source.location.withLocation class DeclarationGenerator( val context: WasmModuleCodegenContext, @@ -454,7 +456,7 @@ class DeclarationGenerator( check(initValue is IrConst<*> && initValue.kind !is IrConstKind.String) { "Static field initializer should be string or const" } - generateConstExpression(initValue, wasmExpressionGenerator, context) + generateConstExpression(initValue, wasmExpressionGenerator, context, declaration.fileOrNull?.fileEntry) } else { generateDefaultInitializerForType(wasmType, wasmExpressionGenerator) } @@ -493,30 +495,31 @@ fun IrFunction.isExported(): Boolean = isJsExport() -fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmModuleCodegenContext) { - when (val kind = expression.kind) { - is IrConstKind.Null -> { - val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType - body.buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(bottomType)) +fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmModuleCodegenContext, fileEntry: IrFileEntry?) = + withLocation(expression.getSourceLocation(fileEntry)) { + when (val kind = expression.kind) { + is IrConstKind.Null -> { + val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType + body.buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(bottomType)) + } + is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0) + is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt()) + is IrConstKind.Short -> body.buildConstI32(kind.valueOf(expression).toInt()) + is IrConstKind.Int -> body.buildConstI32(kind.valueOf(expression)) + is IrConstKind.Long -> body.buildConstI64(kind.valueOf(expression)) + is IrConstKind.Char -> body.buildConstI32(kind.valueOf(expression).code) + is IrConstKind.Float -> body.buildConstF32(kind.valueOf(expression)) + is IrConstKind.Double -> body.buildConstF64(kind.valueOf(expression)) + is IrConstKind.String -> { + val stringValue = kind.valueOf(expression) + val (literalAddress, literalPoolId) = context.referenceStringLiteralAddressAndId(stringValue) + body.commentGroupStart { "const string: \"$stringValue\"" } + body.buildConstI32Symbol(literalPoolId) + body.buildConstI32Symbol(literalAddress) + body.buildConstI32(stringValue.length) + body.buildCall(context.referenceFunction(context.backendContext.wasmSymbols.stringGetLiteral), location) + body.commentGroupEnd() + } + else -> error("Unknown constant kind") } - is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0) - is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt()) - is IrConstKind.Short -> body.buildConstI32(kind.valueOf(expression).toInt()) - is IrConstKind.Int -> body.buildConstI32(kind.valueOf(expression)) - is IrConstKind.Long -> body.buildConstI64(kind.valueOf(expression)) - is IrConstKind.Char -> body.buildConstI32(kind.valueOf(expression).code) - is IrConstKind.Float -> body.buildConstF32(kind.valueOf(expression)) - is IrConstKind.Double -> body.buildConstF64(kind.valueOf(expression)) - is IrConstKind.String -> { - val stringValue = kind.valueOf(expression) - val (literalAddress, literalPoolId) = context.referenceStringLiteralAddressAndId(stringValue) - body.commentGroupStart { "const string: \"$stringValue\"" } - body.buildConstI32Symbol(literalPoolId) - body.buildConstI32Symbol(literalAddress) - body.buildConstI32(stringValue.length) - body.buildCall(context.referenceFunction(context.backendContext.wasmSymbols.stringGetLiteral)) - body.commentGroupEnd() - } - else -> error("Unknown constant kind") - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt index b3652dd575c..ec2b9ae66c6 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.getPackageFragment import org.jetbrains.kotlin.wasm.ir.* +import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) { val functions = @@ -165,7 +166,7 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) { val masterInitFunction = WasmFunction.Defined("__init", WasmSymbol(masterInitFunctionType)) with(WasmIrExpressionBuilder(masterInitFunction.instructions)) { initFunctions.sortedBy { it.priority }.forEach { - buildCall(WasmSymbol(it.function)) + buildCall(WasmSymbol(it.function), SourceLocation.NoLocation) } } exports += WasmExport.Function("__init", masterInitFunction) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/locationUtils.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/locationUtils.kt new file mode 100644 index 00000000000..321287b72b2 --- /dev/null +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/locationUtils.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.wasm.ir2wasm + +import org.jetbrains.kotlin.ir.IrFileEntry +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation + +fun IrExpression.getSourceLocation(fileEntry: IrFileEntry?): SourceLocation { + if (fileEntry == null) return SourceLocation.NoLocation + + val path = fileEntry.name + val startLine = fileEntry.getLineNumber(startOffset) + val startColumn = fileEntry.getColumnNumber(startOffset) + + if (startLine < 0 || startColumn < 0) return SourceLocation.NoLocation + + return SourceLocation.Location(path, startLine, startColumn) +} diff --git a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt index 24245e8bdf5..4519bbb088f 100644 --- a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt +++ b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt @@ -112,7 +112,7 @@ abstract class WasmExpressionBuilder { buildBrInstr(WasmOp.BR_IF, absoluteBlockLevel) } - fun buildCall(symbol: WasmSymbol, location: SourceLocation = SourceLocation.TBDLocation) { + fun buildCall(symbol: WasmSymbol, location: SourceLocation) { buildInstr(WasmOp.CALL, location, WasmImmediate.FuncIdx(symbol)) }