[Wasm] Support Wasm K2 frontend in CLI (KT-57230)

This commit is contained in:
Svyatoslav Kuzmich
2023-07-26 16:25:58 +02:00
committed by Space Team
parent 85ee2d71d2
commit 75142230b6
4 changed files with 93 additions and 13 deletions
@@ -509,6 +509,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
diagnosticsReporter = diagnosticsReporter,
incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER],
lookupTracker = lookupTracker,
useWasmPlatform = arguments.wasm,
)
} else {
compileModuleToAnalyzedFirWithPsi(
@@ -519,6 +520,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
diagnosticsReporter = diagnosticsReporter,
incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER],
lookupTracker = lookupTracker,
useWasmPlatform = arguments.wasm,
)
}
@@ -550,7 +552,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
outputKlibPath = outputKlibPath,
messageCollector = messageCollector,
diagnosticsReporter = diagnosticsReporter,
jsOutputName = arguments.irPerModuleOutputName
jsOutputName = arguments.irPerModuleOutputName,
useWasmPlatform = arguments.wasm
)
}
@@ -40,13 +40,16 @@ import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.utils.metadataVersion
import org.jetbrains.kotlin.wasm.resolve.WasmPlatformAnalyzerServices
import java.io.File
import java.nio.file.Paths
@@ -60,6 +63,7 @@ inline fun <F> compileModuleToAnalyzedFir(
noinline isCommonSource: (F) -> Boolean,
noinline fileBelongsToModule: (F, String) -> Boolean,
buildResolveAndCheckFir: (FirSession, List<F>) -> ModuleCompilerAnalyzedOutput,
useWasmPlatform: Boolean,
): List<ModuleCompilerAnalyzedOutput> {
// FIR
val extensionRegistrars = FirExtensionRegistrar.getInstances(moduleStructure.project)
@@ -67,7 +71,10 @@ inline fun <F> compileModuleToAnalyzedFir(
val mainModuleName = moduleStructure.compilerConfiguration.get(CommonConfigurationKeys.MODULE_NAME)!!
val escapedMainModuleName = Name.special("<$mainModuleName>")
val binaryModuleData = BinaryModuleData.initialize(escapedMainModuleName, JsPlatforms.defaultJsPlatform, JsPlatformAnalyzerServices)
val platform = if (useWasmPlatform) WasmPlatforms.Default else JsPlatforms.defaultJsPlatform
val platformAnalyzerServices = if (useWasmPlatform) WasmPlatformAnalyzerServices else JsPlatformAnalyzerServices
val binaryModuleData = BinaryModuleData.initialize(escapedMainModuleName, platform, platformAnalyzerServices)
val dependencyList = DependencyListForCliModule.build(binaryModuleData) {
dependencies(libraries.map { Paths.get(it).toAbsolutePath() })
friendDependencies(friendLibraries.map { Paths.get(it).toAbsolutePath() })
@@ -75,14 +82,26 @@ inline fun <F> compileModuleToAnalyzedFir(
}
val resolvedLibraries = moduleStructure.allDependencies
val sessionsWithSources = prepareJsSessions(
files, moduleStructure.compilerConfiguration, escapedMainModuleName,
resolvedLibraries, dependencyList, extensionRegistrars,
isCommonSource = isCommonSource,
fileBelongsToModule = fileBelongsToModule,
lookupTracker,
icData = incrementalDataProvider?.let(::KlibIcData),
)
val sessionsWithSources = if (useWasmPlatform) {
prepareWasmSessions(
files, moduleStructure.compilerConfiguration, escapedMainModuleName,
resolvedLibraries, dependencyList, extensionRegistrars,
isCommonSource = isCommonSource,
fileBelongsToModule = fileBelongsToModule,
lookupTracker,
icData = incrementalDataProvider?.let(::KlibIcData),
)
} else {
prepareJsSessions(
files, moduleStructure.compilerConfiguration, escapedMainModuleName,
resolvedLibraries, dependencyList, extensionRegistrars,
isCommonSource = isCommonSource,
fileBelongsToModule = fileBelongsToModule,
lookupTracker,
icData = incrementalDataProvider?.let(::KlibIcData),
)
}
val outputs = sessionsWithSources.map {
buildResolveAndCheckFir(it.session, it.files)
@@ -128,6 +147,7 @@ fun compileModuleToAnalyzedFirWithPsi(
diagnosticsReporter: BaseDiagnosticsCollector,
incrementalDataProvider: IncrementalDataProvider?,
lookupTracker: LookupTracker?,
useWasmPlatform: Boolean,
): AnalyzedFirWithPsiOutput {
val output = compileModuleToAnalyzedFir(
moduleStructure,
@@ -141,6 +161,7 @@ fun compileModuleToAnalyzedFirWithPsi(
buildResolveAndCheckFir = { session, files ->
buildResolveAndCheckFirFromKtFiles(session, files, diagnosticsReporter)
},
useWasmPlatform = useWasmPlatform,
)
return AnalyzedFirWithPsiOutput(output, ktFiles)
}
@@ -154,6 +175,7 @@ fun compileModulesToAnalyzedFirWithLightTree(
diagnosticsReporter: BaseDiagnosticsCollector,
incrementalDataProvider: IncrementalDataProvider?,
lookupTracker: LookupTracker?,
useWasmPlatform: Boolean,
): AnalyzedFirOutput {
val output = compileModuleToAnalyzedFir(
moduleStructure,
@@ -167,6 +189,7 @@ fun compileModulesToAnalyzedFirWithLightTree(
buildResolveAndCheckFir = { session, files ->
buildResolveAndCheckFirViaLightTree(session, files, diagnosticsReporter, null)
},
useWasmPlatform = useWasmPlatform,
)
return AnalyzedFirOutput(output)
}
@@ -275,7 +298,8 @@ fun serializeFirKlib(
outputKlibPath: String,
messageCollector: MessageCollector,
diagnosticsReporter: BaseDiagnosticsCollector,
jsOutputName: String?
jsOutputName: String?,
useWasmPlatform: Boolean,
) {
val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult)
val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles)
@@ -295,7 +319,8 @@ fun serializeFirKlib(
containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = jsOutputName,
serializeSingleFile = fir2KlibSerializer::serializeSingleFirFile
serializeSingleFile = fir2KlibSerializer::serializeSingleFirFile,
builtInsPlatform = if (useWasmPlatform) BuiltInsPlatform.WASM else BuiltInsPlatform.JS,
)
}
@@ -24,15 +24,18 @@ import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.WasmPlatform
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.wasm.resolve.WasmPlatformAnalyzerServices
val isCommonSourceForPsi: (KtFile) -> Boolean = { it.isCommonSource == true }
val fileBelongsToModuleForPsi: (KtFile, String) -> Boolean = { file, moduleName -> file.hmppModuleName == moduleName }
@@ -189,6 +192,53 @@ fun <F> prepareNativeSessions(
}
}
/**
* Creates library session and sources session for Wasm platform
* Number of created session depends on mode of MPP:
* - disabled
* - legacy (one platform and one common module)
* - HMPP (multiple number of modules)
*/
fun <F> prepareWasmSessions(
files: List<F>,
configuration: CompilerConfiguration,
rootModuleName: Name,
resolvedLibraries: List<KotlinLibrary>,
libraryList: DependencyListForCliModule,
extensionRegistrars: List<FirExtensionRegistrar>,
isCommonSource: (F) -> Boolean,
fileBelongsToModule: (F, String) -> Boolean,
lookupTracker: LookupTracker?,
icData: KlibIcData?,
): List<SessionWithSources<F>> {
return prepareSessions(
files, configuration, rootModuleName, WasmPlatforms.Default, WasmPlatformAnalyzerServices,
metadataCompilationMode = false, libraryList, isCommonSource, fileBelongsToModule,
createLibrarySession = { sessionProvider ->
FirWasmSessionFactory.createLibrarySession(
rootModuleName,
resolvedLibraries,
sessionProvider,
libraryList.moduleDataProvider,
extensionRegistrars,
configuration.languageVersionSettings,
registerExtraComponents = {},
)
}
) { _, moduleData, sessionProvider, sessionConfigurator ->
FirWasmSessionFactory.createModuleBasedSession(
moduleData,
sessionProvider,
extensionRegistrars,
configuration.languageVersionSettings,
lookupTracker,
icData = icData,
registerExtraComponents = {},
init = sessionConfigurator,
)
}
}
/**
* Creates library session and sources session for Common platform (for metadata compilation)
* Number of created sessions is always one, in this mode modules are compiled against compiled
@@ -76,6 +76,7 @@ abstract class FirAbstractInvalidationTest(
diagnosticsReporter = diagnosticsReporter,
incrementalDataProvider = null,
lookupTracker = null,
useWasmPlatform = false,
)
val fir2IrActualizedResult = transformFirToIr(moduleStructure, analyzedOutput.output, diagnosticsReporter)
@@ -92,7 +93,8 @@ abstract class FirAbstractInvalidationTest(
outputKlibPath = outputKlibFile.absolutePath,
messageCollector = messageCollector,
diagnosticsReporter = diagnosticsReporter,
jsOutputName = moduleName
jsOutputName = moduleName,
useWasmPlatform = false,
)
if (messageCollector.hasErrors()) {