[JS IR] Introduce the GENERATE_INLINE_ANONYMOUS_FUNCTIONS feature flag
This commit is contained in:
+6
@@ -178,6 +178,12 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-Xir-new-ir2js", description = "New fragment-based ir2js")
|
||||
var irNewIr2Js: Boolean by FreezableVar(true)
|
||||
|
||||
@Argument(
|
||||
value = "-Xir-generate-inline-anonymous-functions",
|
||||
description = "Lambda expressions that capture values are translated into in-line anonymous JavaScript functions"
|
||||
)
|
||||
var irGenerateInlineAnonymousFunctions: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xinclude",
|
||||
valueDescription = "<path>",
|
||||
|
||||
@@ -163,6 +163,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
configurationJs.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
||||
configurationJs.put(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME, arguments.renderInternalDiagnosticNames)
|
||||
configurationJs.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, arguments.irPropertyLazyInitialization)
|
||||
configurationJs.put(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS, arguments.irGenerateInlineAnonymousFunctions)
|
||||
|
||||
if (!checkKotlinPackageUsage(environmentForJS.configuration, sourcesFiles)) return ExitCode.COMPILATION_ERROR
|
||||
|
||||
|
||||
+8
-2
@@ -28,12 +28,16 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
|
||||
val generateInlineAnonymousFunctions: Boolean
|
||||
get() = context.configuration.getBoolean(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS)
|
||||
|
||||
/**
|
||||
* A factory that creates [IrFunctionExpression] for lambdas being constructed.
|
||||
*
|
||||
@@ -121,7 +125,8 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
|
||||
|
||||
val closureUsageAnalyser = ClosureUsageAnalyser()
|
||||
|
||||
irFile.acceptChildrenVoid(closureUsageAnalyser) // TODO: Only do this if lambda inlining is enabled with a feature flag!
|
||||
if (generateInlineAnonymousFunctions)
|
||||
irFile.acceptChildrenVoid(closureUsageAnalyser)
|
||||
|
||||
val callableReferenceClassTransformer = CallableReferenceClassTransformer(
|
||||
ctorToFactoryMap,
|
||||
@@ -317,8 +322,9 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
|
||||
// This allows us to avoid allocating a new object each time the lambda is created.
|
||||
liftLambda(ctorToFreeFunctionMap, lambdaInfo)
|
||||
} else if (
|
||||
generateInlineAnonymousFunctions
|
||||
// If the lambda constructor is called from more than one place, don't inline.
|
||||
closureUsageAnalyser.getLambdaConstructorCalls(lambdaClass.primaryConstructor!!.symbol).size == 1
|
||||
&& closureUsageAnalyser.getLambdaConstructorCalls(lambdaClass.primaryConstructor!!.symbol).size == 1
|
||||
// In-line anonymous functions that capture variables declared in loops are dangerous.
|
||||
// See https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
|
||||
&& !closureUsageAnalyser.lambdaCapturesVariablesDeclaredInLoops(lambdaClass)
|
||||
|
||||
+2
@@ -17,6 +17,8 @@ where advanced options include:
|
||||
Print declarations' reachability info to stdout during performing DCE
|
||||
-Xir-dce-runtime-diagnostic={log|exception}
|
||||
Enable runtime diagnostics when performing DCE instead of removing declarations
|
||||
-Xir-generate-inline-anonymous-functions
|
||||
Lambda expressions that capture values are translated into in-line anonymous JavaScript functions
|
||||
-Xir-minimized-member-names Perform minimization for names of members
|
||||
-Xir-module-name=<name> Specify a compilation module name for IR backend
|
||||
-Xir-new-ir2js New fragment-based ir2js
|
||||
|
||||
+5
@@ -112,6 +112,11 @@ object JsEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
||||
applicability = DirectiveApplicability.Global
|
||||
)
|
||||
|
||||
val GENERATE_INLINE_ANONYMOUS_FUNCTIONS by directive(
|
||||
description = "translate lambdas into in-line anonymous functions",
|
||||
applicability = DirectiveApplicability.Global
|
||||
)
|
||||
|
||||
val SAFE_EXTERNAL_BOOLEAN by directive(
|
||||
description = "",
|
||||
applicability = DirectiveApplicability.Global
|
||||
|
||||
+4
@@ -120,6 +120,10 @@ fun createCompilerConfiguration(module: TestModule, configurators: List<Abstract
|
||||
configuration.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, true)
|
||||
}
|
||||
|
||||
if (JsEnvironmentConfigurationDirectives.GENERATE_INLINE_ANONYMOUS_FUNCTIONS in module.directives) {
|
||||
configuration.put(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS, true)
|
||||
}
|
||||
|
||||
if (module.frontendKind == FrontendKinds.FIR) {
|
||||
configuration[CommonConfigurationKeys.USE_FIR] = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user