[JVM_IR] Follow old backend in bridge visibility and varargs marking.
The old backend makes bridges for protected and package-private methods public. Also, for bridges for vararg methods, the vararg marker is not on the bridge. These differences seem minor but are visible via reflection, so we might as well follow the old backend.
This commit is contained in:
committed by
Alexander Udalov
parent
326768e8b5
commit
0279068214
+2
-3
@@ -149,8 +149,7 @@ class FunctionCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
val isVararg = valueParameters.lastOrNull()?.varargElementType != null
|
||||
val isBridge = origin == IrDeclarationOrigin.BRIDGE || origin == IrDeclarationOrigin.BRIDGE_SPECIAL
|
||||
val isVararg = valueParameters.lastOrNull()?.varargElementType != null && !isBridge()
|
||||
val modalityFlag = when ((this as? IrSimpleFunction)?.modality) {
|
||||
Modality.FINAL -> when {
|
||||
origin == JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER -> 0
|
||||
@@ -172,7 +171,7 @@ class FunctionCodegen(
|
||||
(if (isStatic) Opcodes.ACC_STATIC else 0) or
|
||||
(if (isVararg) Opcodes.ACC_VARARGS else 0) or
|
||||
(if (isExternal) Opcodes.ACC_NATIVE else 0) or
|
||||
(if (isBridge) Opcodes.ACC_BRIDGE else 0) or
|
||||
(if (isBridge()) Opcodes.ACC_BRIDGE else 0) or
|
||||
(if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
|
||||
(if (isStrict) Opcodes.ACC_STRICT else 0) or
|
||||
(if (isSynchronized) Opcodes.ACC_SYNCHRONIZED else 0)
|
||||
|
||||
+1
-1
@@ -362,7 +362,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
private fun mapOverriddenSpecialBuiltinIfNeeded(caller: IrFunction, callee: IrFunction, superCall: Boolean): JvmMethodSignature? {
|
||||
// Do not remap special builtin methods when called from a bridge. The bridges are there to provide the
|
||||
// remapped name or signature and forward to the actually declared method.
|
||||
if (caller.origin == IrDeclarationOrigin.BRIDGE || caller.origin == IrDeclarationOrigin.BRIDGE_SPECIAL) return null
|
||||
if (caller.isBridge()) return null
|
||||
// Do not remap calls to static replacements of inline class methods, since they have completely different signatures.
|
||||
if (callee.isStaticInlineClassReplacement) return null
|
||||
val overriddenSpecialBuiltinFunction =
|
||||
|
||||
+3
-52
@@ -168,21 +168,16 @@ fun IrDeclarationWithVisibility.getVisibilityAccessFlag(kind: OwnerKind? = null)
|
||||
}
|
||||
|
||||
private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?): Int? {
|
||||
// if (JvmCodegenUtil.isNonIntrinsicPrivateCompanionObjectInInterface(memberDescriptor)) {
|
||||
// return ACC_PUBLIC
|
||||
// }
|
||||
if (this is IrClass && DescriptorVisibilities.isPrivate(visibility) && isCompanion && hasInterfaceParent()) {
|
||||
// TODO: non-intrinsic
|
||||
return Opcodes.ACC_PUBLIC
|
||||
}
|
||||
|
||||
// if (memberDescriptor is FunctionDescriptor && isInlineClassWrapperConstructor(memberDescriptor, kind))
|
||||
if (this is IrConstructor && parentAsClass.isInline && kind === OwnerKind.IMPLEMENTATION) {
|
||||
return Opcodes.ACC_PRIVATE
|
||||
}
|
||||
|
||||
// if (memberDescriptor.isEffectivelyInlineOnly()) {
|
||||
if (this is IrFunction && isReifiable()) {
|
||||
if (this is IrFunction && (isReifiable() || isBridge())) {
|
||||
return Opcodes.ACC_PUBLIC
|
||||
}
|
||||
|
||||
@@ -190,58 +185,20 @@ private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?):
|
||||
return Opcodes.ACC_PRIVATE
|
||||
}
|
||||
|
||||
// if (memberVisibility === Visibilities.LOCAL && memberDescriptor is CallableMemberDescriptor) {
|
||||
if (visibility === DescriptorVisibilities.LOCAL && this is IrFunction) {
|
||||
return Opcodes.ACC_PUBLIC
|
||||
}
|
||||
|
||||
// if (isEnumEntry(memberDescriptor)) {
|
||||
if (this is IrClass && this.kind === ClassKind.ENUM_ENTRY) {
|
||||
return AsmUtil.NO_FLAG_PACKAGE_PRIVATE
|
||||
}
|
||||
|
||||
// These ones should be public anyway after ToArrayLowering.
|
||||
// if (memberDescriptor.isToArrayFromCollection()) {
|
||||
// return ACC_PUBLIC
|
||||
// }
|
||||
|
||||
// if (memberDescriptor is ConstructorDescriptor && isAnonymousObject(memberDescriptor.containingDeclaration)) {
|
||||
// return getVisibilityAccessFlagForAnonymous(memberDescriptor.containingDeclaration as ClassDescriptor)
|
||||
// }
|
||||
// if (this is IrConstructor && parentAsClass.isAnonymousObject) {
|
||||
// return parentAsClass.getVisibilityAccessFlagForAnonymous()
|
||||
// }
|
||||
|
||||
// TODO: when is this applicable?
|
||||
// if (memberDescriptor is SyntheticJavaPropertyDescriptor) {
|
||||
// return getVisibilityAccessFlag((memberDescriptor as SyntheticJavaPropertyDescriptor).getMethod)
|
||||
// }
|
||||
|
||||
|
||||
// if (memberDescriptor is PropertyAccessorDescriptor) {
|
||||
// val property = memberDescriptor.correspondingProperty
|
||||
// if (property is SyntheticJavaPropertyDescriptor) {
|
||||
// val method = (if (memberDescriptor === property.getGetter())
|
||||
// (property as SyntheticJavaPropertyDescriptor).getMethod
|
||||
// else
|
||||
// (property as SyntheticJavaPropertyDescriptor).setMethod)
|
||||
// ?: error("No get/set method in SyntheticJavaPropertyDescriptor: $property")
|
||||
// return getVisibilityAccessFlag(method)
|
||||
// }
|
||||
// }
|
||||
if (this is IrField && correspondingPropertySymbol?.owner?.isExternal == true) {
|
||||
val method = correspondingPropertySymbol?.owner?.getter ?: correspondingPropertySymbol?.owner?.setter
|
||||
?: error("No get/set method in SyntheticJavaPropertyDescriptor: ${ir2string(correspondingPropertySymbol?.owner)}")
|
||||
return method.getVisibilityAccessFlag()
|
||||
}
|
||||
|
||||
// if (memberDescriptor is CallableDescriptor && memberVisibility === Visibilities.PROTECTED) {
|
||||
// for (overridden in DescriptorUtils.getAllOverriddenDescriptors(memberDescriptor as CallableDescriptor)) {
|
||||
// if (isJvmInterface(overridden.containingDeclaration)) {
|
||||
// return ACC_PUBLIC
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (this is IrSimpleFunction && visibility === DescriptorVisibilities.PROTECTED &&
|
||||
allOverridden().any { it.parentAsClass.isJvmInterface }
|
||||
) {
|
||||
@@ -256,14 +213,6 @@ private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?):
|
||||
return AsmUtil.NO_FLAG_PACKAGE_PRIVATE
|
||||
}
|
||||
|
||||
// Should be taken care of in IR
|
||||
// if (memberDescriptor is AccessorForCompanionObjectInstanceFieldDescriptor) {
|
||||
// return NO_FLAG_PACKAGE_PRIVATE
|
||||
// }
|
||||
|
||||
// return if (memberDescriptor is ConstructorDescriptor && isEnumEntry(containingDeclaration)) {
|
||||
// NO_FLAG_PACKAGE_PRIVATE
|
||||
// } else null
|
||||
if (this is IrConstructor && parentAsClass.kind === ClassKind.ENUM_ENTRY) {
|
||||
return AsmUtil.NO_FLAG_PACKAGE_PRIVATE
|
||||
}
|
||||
@@ -303,6 +252,8 @@ fun IrFunction.isInlineOnly() =
|
||||
|
||||
fun IrFunction.isReifiable() = typeParameters.any { it.isReified }
|
||||
|
||||
internal fun IrFunction.isBridge() = origin == IrDeclarationOrigin.BRIDGE || origin == IrDeclarationOrigin.BRIDGE_SPECIAL
|
||||
|
||||
// Borrowed with modifications from ImplementationBodyCodegen.java
|
||||
|
||||
private val KOTLIN_MARKER_INTERFACES: Map<FqName, String> = run {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
abstract class A<T> {
|
||||
protected abstract fun doIt(vararg args: T): String
|
||||
fun test() = doIt()
|
||||
}
|
||||
|
||||
class B : A<Void>() {
|
||||
override fun doIt(vararg args: Void): String = "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class A {
|
||||
// source: 'varargsBridge.kt'
|
||||
public method <init>(): void
|
||||
protected varargs abstract @org.jetbrains.annotations.NotNull method doIt(@org.jetbrains.annotations.NotNull p0: java.lang.Object[]): java.lang.String
|
||||
public final @org.jetbrains.annotations.NotNull method test(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class B {
|
||||
// source: 'varargsBridge.kt'
|
||||
public method <init>(): void
|
||||
protected varargs @org.jetbrains.annotations.NotNull method doIt(@org.jetbrains.annotations.NotNull p0: java.lang.Void[]): java.lang.String
|
||||
public synthetic bridge method doIt(p0: java.lang.Object[]): java.lang.String
|
||||
}
|
||||
+5
@@ -179,6 +179,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargsBridge.kt")
|
||||
public void testVarargsBridge() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/varargsBridge.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+5
@@ -179,6 +179,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargsBridge.kt")
|
||||
public void testVarargsBridge() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/varargsBridge.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user