[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 = override fun visitConst(expression: IrConst<*>): Unit =
generateConstExpression(expression, body, context) generateConstExpression(expression, body, context, functionContext.irFunction.fileOrNull?.fileEntry)
override fun visitGetField(expression: IrGetField) { override fun visitGetField(expression: IrGetField) {
val field: IrField = expression.symbol.owner val field: IrField = expression.symbol.owner
@@ -907,15 +907,5 @@ class BodyGenerator(
return false return false
} }
private fun IrExpression.getSourceLocation(): SourceLocation { private fun IrExpression.getSourceLocation() = getSourceLocation(functionContext.irFunction.fileOrNull?.fileEntry)
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)
}
} }
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement 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.isJsExport
import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName 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.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.parentOrNull import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.wasm.ir.* import org.jetbrains.kotlin.wasm.ir.*
import org.jetbrains.kotlin.wasm.ir.source.location.withLocation
class DeclarationGenerator( class DeclarationGenerator(
val context: WasmModuleCodegenContext, val context: WasmModuleCodegenContext,
@@ -454,7 +456,7 @@ class DeclarationGenerator(
check(initValue is IrConst<*> && initValue.kind !is IrConstKind.String) { check(initValue is IrConst<*> && initValue.kind !is IrConstKind.String) {
"Static field initializer should be string or const" "Static field initializer should be string or const"
} }
generateConstExpression(initValue, wasmExpressionGenerator, context) generateConstExpression(initValue, wasmExpressionGenerator, context, declaration.fileOrNull?.fileEntry)
} else { } else {
generateDefaultInitializerForType(wasmType, wasmExpressionGenerator) generateDefaultInitializerForType(wasmType, wasmExpressionGenerator)
} }
@@ -493,30 +495,31 @@ fun IrFunction.isExported(): Boolean =
isJsExport() isJsExport()
fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmModuleCodegenContext) { fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmModuleCodegenContext, fileEntry: IrFileEntry?) =
when (val kind = expression.kind) { withLocation(expression.getSourceLocation(fileEntry)) {
is IrConstKind.Null -> { when (val kind = expression.kind) {
val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType is IrConstKind.Null -> {
body.buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(bottomType)) 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.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.getPackageFragment import org.jetbrains.kotlin.ir.util.getPackageFragment
import org.jetbrains.kotlin.wasm.ir.* import org.jetbrains.kotlin.wasm.ir.*
import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) { class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
val functions = val functions =
@@ -165,7 +166,7 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
val masterInitFunction = WasmFunction.Defined("__init", WasmSymbol(masterInitFunctionType)) val masterInitFunction = WasmFunction.Defined("__init", WasmSymbol(masterInitFunctionType))
with(WasmIrExpressionBuilder(masterInitFunction.instructions)) { with(WasmIrExpressionBuilder(masterInitFunction.instructions)) {
initFunctions.sortedBy { it.priority }.forEach { initFunctions.sortedBy { it.priority }.forEach {
buildCall(WasmSymbol(it.function)) buildCall(WasmSymbol(it.function), SourceLocation.NoLocation)
} }
} }
exports += WasmExport.Function("__init", masterInitFunction) 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) 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)) buildInstr(WasmOp.CALL, location, WasmImmediate.FuncIdx(symbol))
} }