[JS IR BE] Support 1.3 coroutines in backend
This commit is contained in:
+2
-2
@@ -64,7 +64,7 @@ class InitializersLowering(
|
|||||||
val irFieldInitializer = declaration.initializer?.expression ?: return
|
val irFieldInitializer = declaration.initializer?.expression ?: return
|
||||||
|
|
||||||
val receiver =
|
val receiver =
|
||||||
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
|
if (!declaration.isStatic) // TODO isStaticField
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
||||||
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
|
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
|
||||||
@@ -79,7 +79,7 @@ class InitializersLowering(
|
|||||||
null, null
|
null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DescriptorUtils.isStaticDeclaration(declaration.descriptor)) {
|
if (declaration.isStatic) {
|
||||||
staticInitializerStatements.add(irSetField)
|
staticInitializerStatements.add(irSetField)
|
||||||
} else {
|
} else {
|
||||||
instanceInitializerStatements.add(irSetField)
|
instanceInitializerStatements.add(irSetField)
|
||||||
|
|||||||
+61
-39
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.ir.Ir
|
|||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
@@ -44,23 +45,34 @@ class JsIrBackendContext(
|
|||||||
val module: ModuleDescriptor,
|
val module: ModuleDescriptor,
|
||||||
override val irBuiltIns: IrBuiltIns,
|
override val irBuiltIns: IrBuiltIns,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
irModuleFragment: IrModuleFragment
|
irModuleFragment: IrModuleFragment,
|
||||||
|
val configuration: CompilerConfiguration
|
||||||
) : CommonBackendContext {
|
) : CommonBackendContext {
|
||||||
|
|
||||||
override val builtIns = module.builtIns
|
override val builtIns = module.builtIns
|
||||||
|
|
||||||
val internalPackageFragmentDescriptor = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
|
val internalPackageFragmentDescriptor = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
|
||||||
val implicitDeclarationFile = IrFileImpl(object : SourceManager.FileEntry {
|
private val implicitDeclarationFile by lazy {
|
||||||
override val name = "<implicitDeclarations>"
|
IrFileImpl(object : SourceManager.FileEntry {
|
||||||
override val maxOffset = UNDEFINED_OFFSET
|
override val name = "<implicitDeclarations>"
|
||||||
|
override val maxOffset = UNDEFINED_OFFSET
|
||||||
|
|
||||||
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int) =
|
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int) =
|
||||||
SourceRangeInfo("", UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
SourceRangeInfo(
|
||||||
|
"",
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET
|
||||||
|
)
|
||||||
|
|
||||||
override fun getLineNumber(offset: Int) = UNDEFINED_OFFSET
|
override fun getLineNumber(offset: Int) = UNDEFINED_OFFSET
|
||||||
override fun getColumnNumber(offset: Int) = UNDEFINED_OFFSET
|
override fun getColumnNumber(offset: Int) = UNDEFINED_OFFSET
|
||||||
}, internalPackageFragmentDescriptor).also {
|
}, internalPackageFragmentDescriptor).also {
|
||||||
irModuleFragment.files += it
|
irModuleFragment.files += it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val sharedVariablesManager =
|
override val sharedVariablesManager =
|
||||||
@@ -68,31 +80,36 @@ class JsIrBackendContext(
|
|||||||
override val declarationFactory = JsDeclarationFactory()
|
override val declarationFactory = JsDeclarationFactory()
|
||||||
override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
// TODO
|
// TODO
|
||||||
ReflectionTypes(module, FqName("kotlin.reflect"))
|
ReflectionTypes(module, REFLECT_PACKAGE_FQNAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val internalPackageName = FqName("kotlin.js")
|
companion object {
|
||||||
private val internalPackage = module.getPackage(internalPackageName)
|
private val INTRINSICS_PACKAGE_NAME = Name.identifier("intrinsics")
|
||||||
|
private val COROUTINE_SUSPENDED_NAME = Name.identifier("COROUTINE_SUSPENDED")
|
||||||
|
private val COROUTINE_CONTEXT_NAME = Name.identifier("coroutineContext")
|
||||||
|
private val COROUTINE_IMPL_NAME = Name.identifier("CoroutineImpl")
|
||||||
|
private val CONTINUATION_NAME = Name.identifier("Continuation")
|
||||||
|
// TODO: what is more clear way reference this getter?
|
||||||
|
private val CONTINUATION_CONTEXT_GETTER_NAME = Name.special("<get-context>")
|
||||||
|
private val CONTINUATION_CONTEXT_PROPERTY_NAME = Name.identifier("context")
|
||||||
|
|
||||||
// TODO: replace it with appropriate package name once we migrate to 1.3 coroutines
|
private val REFLECT_PACKAGE_FQNAME = FqName.fromSegments(listOf("kotlin", "reflect"))
|
||||||
private val coroutinePackageNameSrting_12 = "kotlin.coroutines.experimental"
|
private val JS_PACKAGE_FQNAME = FqName.fromSegments(listOf("kotlin", "js"))
|
||||||
private val coroutinePackageNameSrting_13 = "kotlin.coroutines"
|
private val JS_INTERNAL_PACKAGE_FQNAME = JS_PACKAGE_FQNAME.child(Name.identifier("internal"))
|
||||||
|
private val COROUTINE_PACKAGE_FQNAME_12 = FqName.fromSegments(listOf("kotlin", "coroutines", "experimental"))
|
||||||
|
private val COROUTINE_PACKAGE_FQNAME_13 = FqName.fromSegments(listOf("kotlin", "coroutines"))
|
||||||
|
private val COROUTINE_PACKAGE_FQNAME = COROUTINE_PACKAGE_FQNAME_13
|
||||||
|
private val COROUTINE_INTRINSICS_PACKAGE_FQNAME = COROUTINE_PACKAGE_FQNAME.child(INTRINSICS_PACKAGE_NAME)
|
||||||
|
|
||||||
private val INTRINSICS_PACKAGE_NAME = Name.identifier("intrinsics")
|
// TODO: due to name clash those weird suffix is required, remove it once `NameGenerator` is implemented
|
||||||
private val COROUTINE_SUSPENDED_NAME = Name.identifier("COROUTINE_SUSPENDED")
|
private val COROUTINE_SUSPEND_OR_RETURN_JS_NAME = "suspendCoroutineUninterceptedOrReturnJS"
|
||||||
private val COROUTINE_CONTEXT_NAME = Name.identifier("coroutineContext")
|
private val GET_COROUTINE_CONTEXT_NAME = "getCoroutineContext"
|
||||||
private val COROUTINE_IMPL_NAME = Name.identifier("CoroutineImpl")
|
}
|
||||||
private val CONTINUATION_NAME = Name.identifier("Continuation")
|
|
||||||
|
|
||||||
// TODO: what is more clear way reference this getter?
|
private val internalPackage = module.getPackage(JS_PACKAGE_FQNAME)
|
||||||
private val CONTINUATION_CONTEXT_GETTER_NAME = Name.special("<get-context>")
|
|
||||||
private val CONTINUATION_CONTEXT_PROPERTY_NAME = Name.identifier("context")
|
|
||||||
|
|
||||||
private val coroutinePackageName = FqName(coroutinePackageNameSrting_12)
|
private val coroutinePackage = module.getPackage(COROUTINE_PACKAGE_FQNAME)
|
||||||
private val coroutineIntrinsicsPackageName = coroutinePackageName.child(INTRINSICS_PACKAGE_NAME)
|
private val coroutineIntrinsicsPackage = module.getPackage(COROUTINE_INTRINSICS_PACKAGE_FQNAME)
|
||||||
|
|
||||||
private val coroutinePackage = module.getPackage(coroutinePackageName)
|
|
||||||
private val coroutineIntrinsicsPackage = module.getPackage(coroutineIntrinsicsPackageName)
|
|
||||||
|
|
||||||
val enumEntryToGetInstanceFunction = mutableMapOf<IrEnumEntrySymbol, IrSimpleFunctionSymbol>()
|
val enumEntryToGetInstanceFunction = mutableMapOf<IrEnumEntrySymbol, IrSimpleFunctionSymbol>()
|
||||||
|
|
||||||
@@ -106,19 +123,24 @@ class JsIrBackendContext(
|
|||||||
)
|
)
|
||||||
val contextGetter =
|
val contextGetter =
|
||||||
continuation.owner.declarations.filterIsInstance<IrFunction>().atMostOne { it.descriptor.name == CONTINUATION_CONTEXT_GETTER_NAME }
|
continuation.owner.declarations.filterIsInstance<IrFunction>().atMostOne { it.descriptor.name == CONTINUATION_CONTEXT_GETTER_NAME }
|
||||||
?: continuation.owner.declarations.filterIsInstance<IrProperty>().atMostOne { it.descriptor.name == CONTINUATION_CONTEXT_PROPERTY_NAME }?.getter!!
|
?: continuation.owner.declarations.filterIsInstance<IrProperty>().atMostOne { it.descriptor.name == CONTINUATION_CONTEXT_PROPERTY_NAME }?.getter!!
|
||||||
return contextGetter.symbol
|
return contextGetter.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val coroutineGetContextJs = symbolTable.referenceSimpleFunction(getInternalFunctions(GET_COROUTINE_CONTEXT_NAME).single())
|
||||||
|
|
||||||
val coroutineContextProperty: PropertyDescriptor
|
val coroutineContextProperty: PropertyDescriptor
|
||||||
get() {
|
get() {
|
||||||
val vars = internalPackage.memberScope.getContributedVariables(
|
val vars = coroutinePackage.memberScope.getContributedVariables(
|
||||||
COROUTINE_CONTEXT_NAME,
|
COROUTINE_CONTEXT_NAME,
|
||||||
NoLookupLocation.FROM_BACKEND
|
NoLookupLocation.FROM_BACKEND
|
||||||
)
|
)
|
||||||
return vars.single()
|
return vars.single()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val coroutineSuspendOrReturn =
|
||||||
|
symbolTable.referenceSimpleFunction(getInternalFunctions(COROUTINE_SUSPEND_OR_RETURN_JS_NAME).single())
|
||||||
|
|
||||||
val intrinsics = JsIntrinsics(irBuiltIns, this)
|
val intrinsics = JsIntrinsics(irBuiltIns, this)
|
||||||
|
|
||||||
private val operatorMap = referenceOperators()
|
private val operatorMap = referenceOperators()
|
||||||
@@ -130,14 +152,11 @@ class JsIrBackendContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val primitiveCompanionObjects = PrimitiveType.NUMBER_TYPES
|
val primitiveCompanionObjects = PrimitiveType.NUMBER_TYPES
|
||||||
|
.asSequence()
|
||||||
.filter { it.name != "LONG" && it.name != "CHAR" } // skip due to they have own explicit companions
|
.filter { it.name != "LONG" && it.name != "CHAR" } // skip due to they have own explicit companions
|
||||||
.map {
|
.map {
|
||||||
it.typeName to symbolTable.lazyWrapper.referenceClass(
|
it.typeName to symbolTable.lazyWrapper.referenceClass(
|
||||||
getClass(
|
getClass(JS_INTERNAL_PACKAGE_FQNAME.child(Name.identifier("${it.typeName.identifier}CompanionObject")))
|
||||||
internalPackageName
|
|
||||||
.child(Name.identifier("internal"))
|
|
||||||
.child(Name.identifier("${it.typeName.identifier}CompanionObject"))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
@@ -186,16 +205,19 @@ class JsIrBackendContext(
|
|||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
override val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
|
override val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
override val coroutineImpl = symbolTable.referenceClass(getInternalClass(COROUTINE_IMPL_NAME.identifier))
|
override val coroutineImpl = symbolTable.referenceClass(findClass(coroutinePackage.memberScope, COROUTINE_IMPL_NAME.identifier))
|
||||||
override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction(
|
override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction(
|
||||||
coroutineIntrinsicsPackage.memberScope.getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND).filterNot { it.isExpect }.single().getter!!
|
coroutineIntrinsicsPackage.memberScope.getContributedVariables(
|
||||||
|
COROUTINE_SUSPENDED_NAME,
|
||||||
|
NoLookupLocation.FROM_BACKEND
|
||||||
|
).filterNot { it.isExpect }.single().getter!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldGenerateHandlerParameterForDefaultBodyFun() = true
|
override fun shouldGenerateHandlerParameterForDefaultBodyFun() = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val coroutineImplLabelProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("label")!! }
|
val coroutineImplLabelProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("state")!! }
|
||||||
val coroutineImplResultSymbol by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("result")!! }
|
val coroutineImplResultSymbol by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("result")!! }
|
||||||
val coroutineImplExceptionProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exception")!! }
|
val coroutineImplExceptionProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exception")!! }
|
||||||
val coroutineImplExceptionStateProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exceptionState")!! }
|
val coroutineImplExceptionStateProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exceptionState")!! }
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
|||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.SuspendFunctionsLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.SuspendFunctionsLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.FunctionInlining
|
import org.jetbrains.kotlin.ir.backend.js.lower.inline.FunctionInlining
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWithReifiedTypeParametersLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWithReifiedTypeParametersLowering
|
||||||
@@ -55,7 +56,8 @@ fun compile(
|
|||||||
analysisResult.moduleDescriptor,
|
analysisResult.moduleDescriptor,
|
||||||
psi2IrContext.irBuiltIns,
|
psi2IrContext.irBuiltIns,
|
||||||
psi2IrContext.symbolTable,
|
psi2IrContext.symbolTable,
|
||||||
moduleFragment
|
moduleFragment,
|
||||||
|
configuration
|
||||||
)
|
)
|
||||||
|
|
||||||
ExternalDependenciesGenerator(psi2IrContext.moduleDescriptor, psi2IrContext.symbolTable, psi2IrContext.irBuiltIns)
|
ExternalDependenciesGenerator(psi2IrContext.moduleDescriptor, psi2IrContext.symbolTable, psi2IrContext.irBuiltIns)
|
||||||
@@ -68,6 +70,8 @@ fun compile(
|
|||||||
|
|
||||||
MoveExternalDeclarationsToSeparatePlace().lower(moduleFragment.files)
|
MoveExternalDeclarationsToSeparatePlace().lower(moduleFragment.files)
|
||||||
|
|
||||||
|
moduleFragment.files.forEach(CoroutineIntrinsicLowering(context)::lower)
|
||||||
|
|
||||||
context.performInlining(moduleFragment)
|
context.performInlining(moduleFragment)
|
||||||
|
|
||||||
context.lower(moduleFragment)
|
context.lower(moduleFragment)
|
||||||
|
|||||||
@@ -266,4 +266,57 @@ fun IrClass.simpleFunctions(): List<IrSimpleFunction> = this.declarations.flatMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO extract to common place?
|
||||||
|
fun irCall(
|
||||||
|
call: IrCall,
|
||||||
|
newSymbol: IrFunctionSymbol,
|
||||||
|
dispatchReceiverAsFirstArgument: Boolean = false,
|
||||||
|
firstArgumentAsDispatchReceiver: Boolean = false
|
||||||
|
): IrCall =
|
||||||
|
call.run {
|
||||||
|
IrCallImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
type,
|
||||||
|
newSymbol,
|
||||||
|
newSymbol.descriptor,
|
||||||
|
typeArgumentsCount,
|
||||||
|
origin
|
||||||
|
).apply {
|
||||||
|
copyTypeAndValueArgumentsFrom(
|
||||||
|
call,
|
||||||
|
dispatchReceiverAsFirstArgument,
|
||||||
|
firstArgumentAsDispatchReceiver
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO extract to common place?
|
||||||
|
private fun IrCall.copyTypeAndValueArgumentsFrom(
|
||||||
|
call: IrCall,
|
||||||
|
dispatchReceiverAsFirstArgument: Boolean = false,
|
||||||
|
firstArgumentAsDispatchReceiver: Boolean = false
|
||||||
|
) {
|
||||||
|
copyTypeArgumentsFrom(call)
|
||||||
|
|
||||||
|
var toValueArgumentIndex = 0
|
||||||
|
var fromValueArgumentIndex = 0
|
||||||
|
|
||||||
|
when {
|
||||||
|
dispatchReceiverAsFirstArgument -> {
|
||||||
|
putValueArgument(toValueArgumentIndex++, call.dispatchReceiver)
|
||||||
|
}
|
||||||
|
firstArgumentAsDispatchReceiver -> {
|
||||||
|
dispatchReceiver = call.getValueArgument(fromValueArgumentIndex++)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
dispatchReceiver = call.dispatchReceiver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionReceiver = call.extensionReceiver
|
||||||
|
|
||||||
|
while (fromValueArgumentIndex < call.valueArgumentsCount) {
|
||||||
|
putValueArgument(toValueArgumentIndex++, call.getValueArgument(fromValueArgumentIndex++))
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-58
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.utils.isSubtypeOfClass
|
|||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.ir.irCall
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.ConversionNames
|
import org.jetbrains.kotlin.ir.backend.js.utils.ConversionNames
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||||
@@ -649,68 +650,10 @@ fun translateEqualsForNullableString(rhs: IrType): EqualityLoweringType = when {
|
|||||||
else -> RuntimeFunctionCall
|
else -> RuntimeFunctionCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun IrType.isNullableJsNumber(): Boolean = isNullablePrimitiveType() && !isNullableLong() && !isNullableChar()
|
private fun IrType.isNullableJsNumber(): Boolean = isNullablePrimitiveType() && !isNullableLong() && !isNullableChar()
|
||||||
|
|
||||||
private fun IrType.isJsNumber(): Boolean = isPrimitiveType() && !isLong() && !isChar()
|
private fun IrType.isJsNumber(): Boolean = isPrimitiveType() && !isLong() && !isChar()
|
||||||
|
|
||||||
|
|
||||||
// TODO extract to common place?
|
|
||||||
fun irCall(
|
|
||||||
call: IrCall,
|
|
||||||
newSymbol: IrFunctionSymbol,
|
|
||||||
dispatchReceiverAsFirstArgument: Boolean = false,
|
|
||||||
firstArgumentAsDispatchReceiver: Boolean = false
|
|
||||||
): IrCall =
|
|
||||||
call.run {
|
|
||||||
IrCallImpl(
|
|
||||||
startOffset,
|
|
||||||
endOffset,
|
|
||||||
type,
|
|
||||||
newSymbol,
|
|
||||||
newSymbol.descriptor,
|
|
||||||
typeArgumentsCount,
|
|
||||||
origin
|
|
||||||
).apply {
|
|
||||||
copyTypeAndValueArgumentsFrom(
|
|
||||||
call,
|
|
||||||
dispatchReceiverAsFirstArgument,
|
|
||||||
firstArgumentAsDispatchReceiver
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO extract to common place?
|
|
||||||
private fun IrCall.copyTypeAndValueArgumentsFrom(
|
|
||||||
call: IrCall,
|
|
||||||
dispatchReceiverAsFirstArgument: Boolean = false,
|
|
||||||
firstArgumentAsDispatchReceiver: Boolean = false
|
|
||||||
) {
|
|
||||||
copyTypeArgumentsFrom(call)
|
|
||||||
|
|
||||||
var toValueArgumentIndex = 0
|
|
||||||
var fromValueArgumentIndex = 0
|
|
||||||
|
|
||||||
when {
|
|
||||||
dispatchReceiverAsFirstArgument -> {
|
|
||||||
putValueArgument(toValueArgumentIndex++, call.dispatchReceiver)
|
|
||||||
}
|
|
||||||
firstArgumentAsDispatchReceiver -> {
|
|
||||||
dispatchReceiver = call.getValueArgument(fromValueArgumentIndex++)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
dispatchReceiver = call.dispatchReceiver
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extensionReceiver = call.extensionReceiver
|
|
||||||
|
|
||||||
while (fromValueArgumentIndex < call.valueArgumentsCount) {
|
|
||||||
putValueArgument(toValueArgumentIndex++, call.getValueArgument(fromValueArgumentIndex++))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MemberToTransformer.op(type: IrType, name: Name, v: IrSimpleFunctionSymbol) {
|
private fun MemberToTransformer.op(type: IrType, name: Name, v: IrSimpleFunctionSymbol) {
|
||||||
op(type, name, v = { irCall(it, v, dispatchReceiverAsFirstArgument = true) })
|
op(type, name, v = { irCall(it, v, dispatchReceiverAsFirstArgument = true) })
|
||||||
}
|
}
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.ir.backend.js.lower.coroutines
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
|
||||||
|
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.ir.irCall
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
|
class CoroutineIntrinsicLowering(val context: JsIrBackendContext): FileLoweringPass {
|
||||||
|
private val languageVersion = context.configuration.languageVersionSettings
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
val call = super.visitCall(expression)
|
||||||
|
return when {
|
||||||
|
expression.descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersion) ->
|
||||||
|
irCall(expression, context.coroutineSuspendOrReturn)
|
||||||
|
expression.descriptor.isBuiltInIntercepted(languageVersion) ->
|
||||||
|
error("Intercepted should not be used with release coroutines")
|
||||||
|
expression.symbol.owner == context.intrinsics.jsCoroutineContext.owner ->
|
||||||
|
irCall(expression, context.coroutineGetContextJs)
|
||||||
|
else -> call
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -148,7 +148,20 @@ class SimpleNameGenerator : NameGenerator {
|
|||||||
|
|
||||||
if (declaration.kind == ClassKind.OBJECT || declaration.name.isSpecial || declaration.visibility == Visibilities.LOCAL) {
|
if (declaration.kind == ClassKind.OBJECT || declaration.name.isSpecial || declaration.visibility == Visibilities.LOCAL) {
|
||||||
nameDeclarator = context.staticContext.rootScope::declareFreshName
|
nameDeclarator = context.staticContext.rootScope::declareFreshName
|
||||||
|
val parent = declaration.parent
|
||||||
|
when (parent) {
|
||||||
|
is IrDeclaration -> nameBuilder.append(getNameForDeclaration(parent, context))
|
||||||
|
is IrPackageFragment -> nameBuilder.append(parent.fqName.asString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove asap `NameGenerator` is implemented
|
||||||
|
(declaration.parent as? IrPackageFragment)?.let {
|
||||||
|
if (declaration.isInline && it.fqName.asString() != "kotlin") {
|
||||||
|
nameBuilder.append("_FIX")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
is IrConstructor -> {
|
is IrConstructor -> {
|
||||||
nameBuilder.append(getNameForDeclaration(declaration.parent as IrClass, context))
|
nameBuilder.append(getNameForDeclaration(declaration.parent as IrClass, context))
|
||||||
@@ -158,6 +171,7 @@ class SimpleNameGenerator : NameGenerator {
|
|||||||
nameDeclarator = context.currentScope::declareFreshName
|
nameDeclarator = context.currentScope::declareFreshName
|
||||||
}
|
}
|
||||||
is IrSimpleFunction -> {
|
is IrSimpleFunction -> {
|
||||||
|
|
||||||
nameBuilder.append(declaration.name.asString())
|
nameBuilder.append(declaration.name.asString())
|
||||||
declaration.extensionReceiverParameter?.let { nameBuilder.append("_\$${it.type.render()}") }
|
declaration.extensionReceiverParameter?.let { nameBuilder.append("_\$${it.type.render()}") }
|
||||||
declaration.typeParameters.forEach { nameBuilder.append("_${it.name.asString()}") }
|
declaration.typeParameters.forEach { nameBuilder.append("_${it.name.asString()}") }
|
||||||
|
|||||||
Reference in New Issue
Block a user