[Wasm] Use more specific types in generateExpression and generateStatement
Also, rename: `generateStatement` -> `generateAsStatement`
This commit is contained in:
+20
-15
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.wasm.utils.*
|
|||||||
import org.jetbrains.kotlin.backend.wasm.utils.isCanonical
|
import org.jetbrains.kotlin.backend.wasm.utils.isCanonical
|
||||||
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.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.PrimaryConstructorLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.PrimaryConstructorLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.erasedUpperBound
|
import org.jetbrains.kotlin.ir.backend.js.utils.erasedUpperBound
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
|
import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
|
||||||
@@ -53,27 +54,31 @@ class BodyGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generates code for the given IR element. Leaves something on the stack unless expression was of the type Void.
|
// Generates code for the given IR element. Leaves something on the stack unless expression was of the type Void.
|
||||||
internal fun generateExpression(elem: IrElement) {
|
internal fun generateExpression(expression: IrExpression) {
|
||||||
assert(elem is IrExpression || elem is IrVariable) { "Unsupported statement kind" }
|
expression.acceptVoid(this)
|
||||||
|
|
||||||
elem.acceptVoid(this)
|
if (expression.type.isNothing()) {
|
||||||
|
|
||||||
if (elem is IrExpression && elem.type.isNothing()) {
|
|
||||||
// TODO Ideally, we should generate unreachable only for specific cases and preferable on declaration site.
|
// TODO Ideally, we should generate unreachable only for specific cases and preferable on declaration site.
|
||||||
body.buildUnreachableAfterNothingType()
|
body.buildUnreachableAfterNothingType()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates code for the given IR element but *never* leaves anything on the stack.
|
// Generates code for the given IR element but *never* leaves anything on the stack.
|
||||||
private fun generateStatement(statement: IrElement) {
|
private fun generateAsStatement(statement: IrExpression) {
|
||||||
assert(statement is IrExpression || statement is IrVariable) { "Unsupported statement kind" }
|
|
||||||
|
|
||||||
generateExpression(statement)
|
generateExpression(statement)
|
||||||
if (statement is IrExpression && statement.type != wasmSymbols.voidType) {
|
if (statement.type != wasmSymbols.voidType) {
|
||||||
body.buildDrop()
|
body.buildDrop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun generateStatement(statement: IrStatement) {
|
||||||
|
when(statement) {
|
||||||
|
is IrExpression -> generateAsStatement(statement)
|
||||||
|
is IrVariable -> statement.acceptVoid(this)
|
||||||
|
else -> error("Unsupported node type: ${statement::class.simpleName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
error("Unexpected element of type ${element::class}")
|
error("Unexpected element of type ${element::class}")
|
||||||
}
|
}
|
||||||
@@ -161,7 +166,7 @@ class BodyGenerator(
|
|||||||
when (expression.operator) {
|
when (expression.operator) {
|
||||||
IrTypeOperator.REINTERPRET_CAST -> generateExpression(expression.argument)
|
IrTypeOperator.REINTERPRET_CAST -> generateExpression(expression.argument)
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> {
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> {
|
||||||
generateStatement(expression.argument)
|
generateAsStatement(expression.argument)
|
||||||
body.buildGetUnit()
|
body.buildGetUnit()
|
||||||
}
|
}
|
||||||
else -> assert(false) { "Other types of casts must be lowered" }
|
else -> assert(false) { "Other types of casts must be lowered" }
|
||||||
@@ -654,7 +659,7 @@ class BodyGenerator(
|
|||||||
private fun visitFunctionReturn(expression: IrReturn) {
|
private fun visitFunctionReturn(expression: IrReturn) {
|
||||||
val returnType = expression.returnTargetSymbol.owner.returnType(backendContext)
|
val returnType = expression.returnTargetSymbol.owner.returnType(backendContext)
|
||||||
if (returnType == irBuiltIns.unitType && expression.returnTargetSymbol.owner != unitGetInstance) {
|
if (returnType == irBuiltIns.unitType && expression.returnTargetSymbol.owner != unitGetInstance) {
|
||||||
generateStatement(expression.value)
|
generateAsStatement(expression.value)
|
||||||
} else {
|
} else {
|
||||||
if (isGetUnitFunction) {
|
if (isGetUnitFunction) {
|
||||||
generateExpression(expression.value)
|
generateExpression(expression.value)
|
||||||
@@ -674,12 +679,12 @@ class BodyGenerator(
|
|||||||
val actualType = expression.type
|
val actualType = expression.type
|
||||||
|
|
||||||
if (expectedType == wasmSymbols.voidType) {
|
if (expectedType == wasmSymbols.voidType) {
|
||||||
generateStatement(expression)
|
generateAsStatement(expression)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedType.isUnit() && !actualType.isUnit()) {
|
if (expectedType.isUnit() && !actualType.isUnit()) {
|
||||||
generateStatement(expression)
|
generateAsStatement(expression)
|
||||||
body.buildGetUnit()
|
body.buildGetUnit()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -817,7 +822,7 @@ class BodyGenerator(
|
|||||||
body.buildBlock("CONTINUE_$label") { wasmContinueBlock ->
|
body.buildBlock("CONTINUE_$label") { wasmContinueBlock ->
|
||||||
functionContext.defineLoopLevel(loop, LoopLabelType.BREAK, wasmBreakBlock)
|
functionContext.defineLoopLevel(loop, LoopLabelType.BREAK, wasmBreakBlock)
|
||||||
functionContext.defineLoopLevel(loop, LoopLabelType.CONTINUE, wasmContinueBlock)
|
functionContext.defineLoopLevel(loop, LoopLabelType.CONTINUE, wasmContinueBlock)
|
||||||
loop.body?.let { generateStatement(it) }
|
loop.body?.let { generateAsStatement(it) }
|
||||||
}
|
}
|
||||||
generateExpression(loop.condition)
|
generateExpression(loop.condition)
|
||||||
body.buildBrIf(wasmLoop)
|
body.buildBrIf(wasmLoop)
|
||||||
@@ -845,7 +850,7 @@ class BodyGenerator(
|
|||||||
body.buildInstr(WasmOp.I32_EQZ)
|
body.buildInstr(WasmOp.I32_EQZ)
|
||||||
body.buildBrIf(wasmBreakBlock)
|
body.buildBrIf(wasmBreakBlock)
|
||||||
loop.body?.let {
|
loop.body?.let {
|
||||||
generateStatement(it)
|
generateAsStatement(it)
|
||||||
}
|
}
|
||||||
body.buildBr(wasmLoop)
|
body.buildBr(wasmLoop)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user