All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.backend.wasm.ir2wasm.WasmModuleCodegenContextImpl.kt Maven / Gradle / Ivy

/*
 * Copyright 2010-2020 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.backend.wasm.WasmBackendContext
import org.jetbrains.kotlin.wasm.ir.*
import org.jetbrains.kotlin.backend.wasm.lower.WasmSignature
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.isNothing
import org.jetbrains.kotlin.ir.util.isFunction
import org.jetbrains.kotlin.ir.util.parentAsClass


class WasmModuleCodegenContextImpl(
    override val backendContext: WasmBackendContext,
    private val wasmFragment: WasmCompiledModuleFragment
) : WasmModuleCodegenContext {
    private val typeTransformer =
        WasmTypeTransformer(this, backendContext.irBuiltIns)

    override fun transformType(irType: IrType): WasmType {
        return with(typeTransformer) { irType.toWasmValueType() }
    }

    override fun transformBoxedType(irType: IrType): WasmType {
        return with(typeTransformer) { irType.toBoxedInlineClassType() }
    }

    override fun transformValueParameterType(irValueParameter: IrValueParameter): WasmType {
        return with(typeTransformer) {
            if (context.backendContext.inlineClassesUtils.shouldValueParameterBeBoxed(irValueParameter)) {
                irValueParameter.type.toBoxedInlineClassType()
            } else {
                irValueParameter.type.toWasmValueType()
            }
        }
    }

    override fun transformResultType(irType: IrType): WasmType? {
        return with(typeTransformer) { irType.toWasmResultType() }
    }

    override fun transformBlockResultType(irType: IrType): WasmType? {
        return with(typeTransformer) { irType.toWasmBlockResultType() }
    }

    override fun referenceStringLiteral(string: String): WasmSymbol {
        wasmFragment.stringLiterals.add(string)
        return wasmFragment.stringLiteralId.reference(string)
    }

    override fun generateTypeInfo(irClass: IrClassSymbol, typeInfo: ConstantDataElement) {
        wasmFragment.typeInfo.define(irClass, typeInfo)
    }

    override fun setStartFunction(wasmFunction: WasmFunction) {
        wasmFragment.startFunction = wasmFunction
    }

    override fun addExport(wasmExport: WasmExport<*>) {
        wasmFragment.exports += wasmExport
    }

    override fun registerVirtualFunction(irFunction: IrSimpleFunctionSymbol) {
        wasmFragment.virtualFunctions += irFunction
    }

    override fun registerInterface(irInterface: IrClassSymbol) {
        wasmFragment.interfaces += irInterface
    }

    override fun registerClass(irClass: IrClassSymbol) {
        wasmFragment.classes += irClass
    }

    override fun defineFunction(irFunction: IrFunctionSymbol, wasmFunction: WasmFunction) {
        wasmFragment.functions.define(irFunction, wasmFunction)
    }

    override fun defineGlobal(irField: IrFieldSymbol, wasmGlobal: WasmGlobal) {
        wasmFragment.globals.define(irField, wasmGlobal)
    }

    override fun defineStructType(irClass: IrClassSymbol, wasmStruct: WasmStructDeclaration) {
        wasmFragment.structTypes.define(irClass, wasmStruct)
    }

    override fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
        wasmFragment.runtimeTypes.define(irClass, wasmGlobal)
    }

    override fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType) {
        wasmFragment.functionTypes.define(irFunction, wasmFunctionType)
    }

    private val classMetadataCache = mutableMapOf()
    override fun getClassMetadata(irClass: IrClassSymbol): ClassMetadata =
        classMetadataCache.getOrPut(irClass) {
            val superClass = irClass.owner.getSuperClass(backendContext.irBuiltIns)
            val superClassMetadata = superClass?.let { getClassMetadata(it.symbol) }
            ClassMetadata(
                irClass.owner,
                superClassMetadata,
                backendContext.irBuiltIns
            )
        }

    override fun referenceFunction(irFunction: IrFunctionSymbol): WasmSymbol =
        wasmFragment.functions.reference(irFunction)

    override fun referenceGlobal(irField: IrFieldSymbol): WasmSymbol =
        wasmFragment.globals.reference(irField)

    override fun referenceStructType(irClass: IrClassSymbol): WasmSymbol {
        val type = irClass.defaultType
        require(!type.isNothing()) {
            "Can't reference Nothing type"
        }
        return wasmFragment.structTypes.reference(irClass)
    }

    override fun referenceClassRTT(irClass: IrClassSymbol): WasmSymbol =
        wasmFragment.runtimeTypes.reference(irClass)

    override fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol =
        wasmFragment.functionTypes.reference(irFunction)

    override fun referenceClassId(irClass: IrClassSymbol): WasmSymbol =
        wasmFragment.classIds.reference(irClass)

    override fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol {
        // HACK to substitute kotlin.Function5 with kotlin.wasm.internal.Function5
        val defaultType = irInterface.defaultType
        if (defaultType.isFunction()) {
            val n = irInterface.owner.typeParameters.size - 1
            return wasmFragment.interfaceId.reference(backendContext.wasmSymbols.functionN(n))
        }
        return wasmFragment.interfaceId.reference(irInterface)
    }

    override fun referenceVirtualFunctionId(irFunction: IrSimpleFunctionSymbol): WasmSymbol {
        if (irFunction.owner.modality == Modality.ABSTRACT)
            error("Abstract functions are not stored in table")
        return wasmFragment.virtualFunctionId.reference(irFunction)
    }

    override fun referenceSignatureId(signature: WasmSignature): WasmSymbol {
        wasmFragment.signatures.add(signature)
        return wasmFragment.signatureId.reference(signature)
    }

    override fun getStructFieldRef(field: IrField): WasmSymbol {
        val klass = field.parentAsClass
        val metadata = getClassMetadata(klass.symbol)
        val fieldId = metadata.fields.indexOf(field)
        return WasmSymbol(fieldId)
    }

    override fun addJsFun(importName: String, jsCode: String) {
        wasmFragment.jsFuns +=
            WasmCompiledModuleFragment.JsCodeSnippet(importName = importName, jsCode = jsCode)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy