[JS IR] Fix backend to make it possible lower partially loaded IR

This commit is contained in:
Roman Artemev
2021-09-28 18:21:49 +03:00
committed by TeamCityServer
parent 2ca74174d3
commit ebf17188cb
3 changed files with 169 additions and 149 deletions
@@ -79,7 +79,8 @@ class InlineClassLowering(val context: CommonBackendContext) {
var delegatingCtorCall: IrDelegatingConstructorCall? = null var delegatingCtorCall: IrDelegatingConstructorCall? = null
var setMemberField: IrSetField? = null var setMemberField: IrSetField? = null
initFunction.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { initFunction.body = irConstructor.body?.let { body ->
context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
val origParameterSymbol = irConstructor.valueParameters.single().symbol val origParameterSymbol = irConstructor.valueParameters.single().symbol
statements += context.createIrBuilder(initFunction.symbol).irBlockBody(initFunction) { statements += context.createIrBuilder(initFunction.symbol).irBlockBody(initFunction) {
val builder = this val builder = this
@@ -88,7 +89,7 @@ class InlineClassLowering(val context: CommonBackendContext) {
type = klass.defaultType, type = klass.defaultType,
) )
(irConstructor.body as IrBlockBody).deepCopyWithSymbols(initFunction).statements.forEach { statement -> (body as IrBlockBody).deepCopyWithSymbols(initFunction).statements.forEach { statement ->
+statement.transformStatement(object : IrElementTransformerVoid() { +statement.transformStatement(object : IrElementTransformerVoid() {
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
delegatingCtorCall = expression.deepCopyWithSymbols(irConstructor) delegatingCtorCall = expression.deepCopyWithSymbols(irConstructor)
@@ -127,10 +128,13 @@ class InlineClassLowering(val context: CommonBackendContext) {
+irReturn(unboxedInlineClassValue()) +irReturn(unboxedInlineClassValue())
}.statements }.statements
} }
}
if (irConstructor.body != null) {
irConstructor.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { irConstructor.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
statements += delegatingCtorCall!! delegatingCtorCall?.let { statements += it }
statements += setMemberField!! setMemberField?.let { statements += it }
}
} }
return listOf(irConstructor, initFunction) return listOf(irConstructor, initFunction)
@@ -142,7 +146,8 @@ class InlineClassLowering(val context: CommonBackendContext) {
val irClass = irConstructor.parentAsClass val irClass = irConstructor.parentAsClass
// Copied and adapted from Kotlin/Native InlineClassTransformer // Copied and adapted from Kotlin/Native InlineClassTransformer
staticMethod.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { staticMethod.body = irConstructor.body?.let { constructorBody ->
context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
statements += context.createIrBuilder(staticMethod.symbol).irBlockBody(staticMethod) { statements += context.createIrBuilder(staticMethod.symbol).irBlockBody(staticMethod) {
// Secondary ctors of inline class must delegate to some other constructors. // Secondary ctors of inline class must delegate to some other constructors.
@@ -152,7 +157,7 @@ class InlineClassLowering(val context: CommonBackendContext) {
irConstructor.valueParameters[it.index].symbol irConstructor.valueParameters[it.index].symbol
} }
(irConstructor.body as IrBlockBody).statements.forEach { statement -> (constructorBody as IrBlockBody).statements.forEach { statement ->
+statement.transformStatement(object : IrElementTransformerVoid() { +statement.transformStatement(object : IrElementTransformerVoid() {
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
expression.transformChildrenVoid() expression.transformChildrenVoid()
@@ -208,15 +213,15 @@ class InlineClassLowering(val context: CommonBackendContext) {
}.statements }.statements
} }
} }
}
private fun transformMethodBodyFlat(function: IrSimpleFunction, staticMethod: IrSimpleFunction) { private fun transformMethodBodyFlat(function: IrSimpleFunction, staticMethod: IrSimpleFunction) {
// TODO: Support fake-overridden methods without boxing // TODO: Support fake-overridden methods without boxing
if (function.isStaticMethodOfClass || !function.isReal) return // TODO error() if (function.isStaticMethodOfClass || !function.isReal) return // TODO error()
val functionBody = function.body
// Move function body to static method, transforming value parameters and nested declarations // Move function body to static method, transforming value parameters and nested declarations
staticMethod.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { staticMethod.body = function.body?.let { functionBody ->
context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
statements.addAll((functionBody as IrBlockBody).statements) statements.addAll((functionBody as IrBlockBody).statements)
transformChildrenVoid(object : IrElementTransformerVoid() { transformChildrenVoid(object : IrElementTransformerVoid() {
@@ -266,6 +271,7 @@ class InlineClassLowering(val context: CommonBackendContext) {
}) })
} }
} }
}
private fun delegateToStaticMethod(function: IrSimpleFunction, staticMethod: IrSimpleFunction): IrBlockBody { private fun delegateToStaticMethod(function: IrSimpleFunction, staticMethod: IrSimpleFunction): IrBlockBody {
// Delegate original function to static implementation // Delegate original function to static implementation
@@ -394,7 +394,9 @@ class EnumClassCreateInitializerLowering(val context: JsCommonBackendContext) :
irClass.enumEntries.forEach { entry -> irClass.enumEntries.forEach { entry ->
entry.correspondingField?.let { instanceField -> entry.correspondingField?.let { instanceField ->
+irSetField(null, instanceField, entry.initializerExpression!!.expression.deepCopyWithSymbols(it)) entry.initializerExpression?.let { initializer ->
+irSetField(null, instanceField, initializer.expression.deepCopyWithSymbols(it))
}
} }
} }
@@ -124,14 +124,26 @@ class SecondaryConstructorLowering(val context: JsIrBackendContext) : Declaratio
private fun generateInitBody(constructor: IrConstructor, irClass: IrClass, delegate: IrSimpleFunction) { private fun generateInitBody(constructor: IrConstructor, irClass: IrClass, delegate: IrSimpleFunction) {
val thisParam = delegate.valueParameters.last() val thisParam = delegate.valueParameters.last()
val oldThisReceiver = irClass.thisReceiver!! val oldThisReceiver = irClass.thisReceiver!!
val constructorBody = constructor.body!! val constructorBody = constructor.body
val oldValueParameters = constructor.valueParameters + oldThisReceiver val oldValueParameters = constructor.valueParameters + oldThisReceiver
// TODO: replace parameters as well // TODO: replace parameters as well
if (constructorBody != null) {
delegate.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { delegate.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
statements += (constructorBody.deepCopyWithSymbols(delegate) as IrStatementContainer).statements statements += (constructorBody.deepCopyWithSymbols(delegate) as IrStatementContainer).statements
statements += JsIrBuilder.buildReturn(delegate.symbol, JsIrBuilder.buildGetValue(thisParam.symbol), context.irBuiltIns.nothingType) statements += JsIrBuilder.buildReturn(
transformChildrenVoid(ThisUsageReplaceTransformer(constructor.symbol, delegate.symbol, oldValueParameters.zip(delegate.valueParameters).toMap())) delegate.symbol,
JsIrBuilder.buildGetValue(thisParam.symbol),
context.irBuiltIns.nothingType
)
transformChildrenVoid(
ThisUsageReplaceTransformer(
constructor.symbol,
delegate.symbol,
oldValueParameters.zip(delegate.valueParameters).toMap()
)
)
}
} }
} }