[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, diagnosticsReporter = diagnosticsReporter,
incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER], incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER],
lookupTracker = lookupTracker, lookupTracker = lookupTracker,
useWasmPlatform = arguments.wasm,
) )
} else { } else {
compileModuleToAnalyzedFirWithPsi( compileModuleToAnalyzedFirWithPsi(
@@ -519,6 +520,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
diagnosticsReporter = diagnosticsReporter, diagnosticsReporter = diagnosticsReporter,
incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER], incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER],
lookupTracker = lookupTracker, lookupTracker = lookupTracker,
useWasmPlatform = arguments.wasm,
) )
} }
@@ -550,7 +552,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
outputKlibPath = outputKlibPath, outputKlibPath = outputKlibPath,
messageCollector = messageCollector, messageCollector = messageCollector,
diagnosticsReporter = diagnosticsReporter, 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.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.utils.metadataVersion import org.jetbrains.kotlin.utils.metadataVersion
import org.jetbrains.kotlin.wasm.resolve.WasmPlatformAnalyzerServices
import java.io.File import java.io.File
import java.nio.file.Paths import java.nio.file.Paths
@@ -60,6 +63,7 @@ inline fun <F> compileModuleToAnalyzedFir(
noinline isCommonSource: (F) -> Boolean, noinline isCommonSource: (F) -> Boolean,
noinline fileBelongsToModule: (F, String) -> Boolean, noinline fileBelongsToModule: (F, String) -> Boolean,
buildResolveAndCheckFir: (FirSession, List<F>) -> ModuleCompilerAnalyzedOutput, buildResolveAndCheckFir: (FirSession, List<F>) -> ModuleCompilerAnalyzedOutput,
useWasmPlatform: Boolean,
): List<ModuleCompilerAnalyzedOutput> { ): List<ModuleCompilerAnalyzedOutput> {
// FIR // FIR
val extensionRegistrars = FirExtensionRegistrar.getInstances(moduleStructure.project) val extensionRegistrars = FirExtensionRegistrar.getInstances(moduleStructure.project)
@@ -67,7 +71,10 @@ inline fun <F> compileModuleToAnalyzedFir(
val mainModuleName = moduleStructure.compilerConfiguration.get(CommonConfigurationKeys.MODULE_NAME)!! val mainModuleName = moduleStructure.compilerConfiguration.get(CommonConfigurationKeys.MODULE_NAME)!!
val escapedMainModuleName = Name.special("<$mainModuleName>") 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) { val dependencyList = DependencyListForCliModule.build(binaryModuleData) {
dependencies(libraries.map { Paths.get(it).toAbsolutePath() }) dependencies(libraries.map { Paths.get(it).toAbsolutePath() })
friendDependencies(friendLibraries.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 resolvedLibraries = moduleStructure.allDependencies
val sessionsWithSources = prepareJsSessions(
files, moduleStructure.compilerConfiguration, escapedMainModuleName, val sessionsWithSources = if (useWasmPlatform) {
resolvedLibraries, dependencyList, extensionRegistrars, prepareWasmSessions(
isCommonSource = isCommonSource, files, moduleStructure.compilerConfiguration, escapedMainModuleName,
fileBelongsToModule = fileBelongsToModule, resolvedLibraries, dependencyList, extensionRegistrars,
lookupTracker, isCommonSource = isCommonSource,
icData = incrementalDataProvider?.let(::KlibIcData), 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 { val outputs = sessionsWithSources.map {
buildResolveAndCheckFir(it.session, it.files) buildResolveAndCheckFir(it.session, it.files)
@@ -128,6 +147,7 @@ fun compileModuleToAnalyzedFirWithPsi(
diagnosticsReporter: BaseDiagnosticsCollector, diagnosticsReporter: BaseDiagnosticsCollector,
incrementalDataProvider: IncrementalDataProvider?, incrementalDataProvider: IncrementalDataProvider?,
lookupTracker: LookupTracker?, lookupTracker: LookupTracker?,
useWasmPlatform: Boolean,
): AnalyzedFirWithPsiOutput { ): AnalyzedFirWithPsiOutput {
val output = compileModuleToAnalyzedFir( val output = compileModuleToAnalyzedFir(
moduleStructure, moduleStructure,
@@ -141,6 +161,7 @@ fun compileModuleToAnalyzedFirWithPsi(
buildResolveAndCheckFir = { session, files -> buildResolveAndCheckFir = { session, files ->
buildResolveAndCheckFirFromKtFiles(session, files, diagnosticsReporter) buildResolveAndCheckFirFromKtFiles(session, files, diagnosticsReporter)
}, },
useWasmPlatform = useWasmPlatform,
) )
return AnalyzedFirWithPsiOutput(output, ktFiles) return AnalyzedFirWithPsiOutput(output, ktFiles)
} }
@@ -154,6 +175,7 @@ fun compileModulesToAnalyzedFirWithLightTree(
diagnosticsReporter: BaseDiagnosticsCollector, diagnosticsReporter: BaseDiagnosticsCollector,
incrementalDataProvider: IncrementalDataProvider?, incrementalDataProvider: IncrementalDataProvider?,
lookupTracker: LookupTracker?, lookupTracker: LookupTracker?,
useWasmPlatform: Boolean,
): AnalyzedFirOutput { ): AnalyzedFirOutput {
val output = compileModuleToAnalyzedFir( val output = compileModuleToAnalyzedFir(
moduleStructure, moduleStructure,
@@ -167,6 +189,7 @@ fun compileModulesToAnalyzedFirWithLightTree(
buildResolveAndCheckFir = { session, files -> buildResolveAndCheckFir = { session, files ->
buildResolveAndCheckFirViaLightTree(session, files, diagnosticsReporter, null) buildResolveAndCheckFirViaLightTree(session, files, diagnosticsReporter, null)
}, },
useWasmPlatform = useWasmPlatform,
) )
return AnalyzedFirOutput(output) return AnalyzedFirOutput(output)
} }
@@ -275,7 +298,8 @@ fun serializeFirKlib(
outputKlibPath: String, outputKlibPath: String,
messageCollector: MessageCollector, messageCollector: MessageCollector,
diagnosticsReporter: BaseDiagnosticsCollector, diagnosticsReporter: BaseDiagnosticsCollector,
jsOutputName: String? jsOutputName: String?,
useWasmPlatform: Boolean,
) { ) {
val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult) val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult)
val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles) val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles)
@@ -295,7 +319,8 @@ fun serializeFirKlib(
containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors, containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = jsOutputName, 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.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.WasmPlatform
import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.platform.konan.NativePlatforms import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.wasm.resolve.WasmPlatformAnalyzerServices
val isCommonSourceForPsi: (KtFile) -> Boolean = { it.isCommonSource == true } val isCommonSourceForPsi: (KtFile) -> Boolean = { it.isCommonSource == true }
val fileBelongsToModuleForPsi: (KtFile, String) -> Boolean = { file, moduleName -> file.hmppModuleName == moduleName } 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) * 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 * Number of created sessions is always one, in this mode modules are compiled against compiled
@@ -76,6 +76,7 @@ abstract class FirAbstractInvalidationTest(
diagnosticsReporter = diagnosticsReporter, diagnosticsReporter = diagnosticsReporter,
incrementalDataProvider = null, incrementalDataProvider = null,
lookupTracker = null, lookupTracker = null,
useWasmPlatform = false,
) )
val fir2IrActualizedResult = transformFirToIr(moduleStructure, analyzedOutput.output, diagnosticsReporter) val fir2IrActualizedResult = transformFirToIr(moduleStructure, analyzedOutput.output, diagnosticsReporter)
@@ -92,7 +93,8 @@ abstract class FirAbstractInvalidationTest(
outputKlibPath = outputKlibFile.absolutePath, outputKlibPath = outputKlibFile.absolutePath,
messageCollector = messageCollector, messageCollector = messageCollector,
diagnosticsReporter = diagnosticsReporter, diagnosticsReporter = diagnosticsReporter,
jsOutputName = moduleName jsOutputName = moduleName,
useWasmPlatform = false,
) )
if (messageCollector.hasErrors()) { if (messageCollector.hasErrors()) {