[Wasm] Require location for buildCall and fix all usages

This commit is contained in:
Zalim Bashorov
2022-12-06 19:34:15 +01:00
parent a24119858f
commit 61440c74d5
5 changed files with 57 additions and 41 deletions
@@ -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)
}
@@ -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")
}
}
}
@@ -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)
@@ -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)
}
@@ -112,7 +112,7 @@ abstract class WasmExpressionBuilder {
buildBrInstr(WasmOp.BR_IF, absoluteBlockLevel)
}
fun buildCall(symbol: WasmSymbol<WasmFunction>, location: SourceLocation = SourceLocation.TBDLocation) {
fun buildCall(symbol: WasmSymbol<WasmFunction>, location: SourceLocation) {
buildInstr(WasmOp.CALL, location, WasmImmediate.FuncIdx(symbol))
}