Obtain class file version from GenerationState

This commit is contained in:
Michael Bogdanov
2016-04-12 14:44:14 +03:00
committed by Mikhael Bogdanov
parent 77a386a266
commit 96f892d60c
15 changed files with 25 additions and 19 deletions
@@ -150,7 +150,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
}
v.defineClass(element,
V1_6,
state.getClassFileVersion(),
ACC_FINAL | ACC_SUPER | visibilityFlag,
asmType.getInternalName(),
sw.makeJavaGenericSignature(),
@@ -211,7 +211,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
v.defineClass(
myClass, V1_6,
myClass,
state.getClassFileVersion(),
access,
signature.getName(),
signature.getJavaGenericSignature(),
@@ -49,7 +49,7 @@ class InterfaceImplBodyCodegen(
override fun generateDeclaration() {
v.defineClass(
myClass, V1_6, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
myClass, state.classFileVersion, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
typeMapper.mapDefaultImpls(descriptor).internalName,
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
)
@@ -134,7 +134,7 @@ class MultifileClassCodegen(
J_L_OBJECT
state.factory.newVisitor(declarationOrigin, facadeClassType, files).apply {
defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES,
defineClass(singleSourceFile, state.classFileVersion, FACADE_CLASS_ATTRIBUTES,
facadeClassType.internalName, null, superClassForFacade, ArrayUtil.EMPTY_STRING_ARRAY)
if (singleSourceFile != null) {
visitSource(singleSourceFile.name, null)
@@ -64,7 +64,7 @@ class MultifileClassPartCodegen(
private val staticInitClassBuilder = ClassBuilderOnDemand {
state.factory.newVisitor(MultifileClass(file, packageFragment), staticInitClassType, file).apply {
defineClass(file, Opcodes.V1_6, STATE_INITIALIZER_CLASS_ATTRIBUTES,
defineClass(file, state.classFileVersion, STATE_INITIALIZER_CLASS_ATTRIBUTES,
staticInitClassType.internalName, null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY)
visitSource(file.name, null)
@@ -119,7 +119,7 @@ class MultifileClassPartCodegen(
}
override fun generateDeclaration() {
v.defineClass(element, Opcodes.V1_6, partClassAttributes, partType.internalName, null, superClassInternalName, ArrayUtil.EMPTY_STRING_ARRAY)
v.defineClass(element, state.classFileVersion, partClassAttributes, partType.internalName, null, superClassInternalName, ArrayUtil.EMPTY_STRING_ARRAY)
v.visitSource(element.name, null)
generatePropertyMetadataArrayFieldIfNeeded(partType)
@@ -62,7 +62,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
@Override
protected void generateDeclaration() {
v.defineClass(element, V1_6,
v.defineClass(element, state.getClassFileVersion(),
ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
packagePartType.getInternalName(),
null,
@@ -82,7 +82,7 @@ class PropertyReferenceCodegen(
override fun generateDeclaration() {
v.defineClass(
element,
V1_6,
state.classFileVersion,
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForClass(classDescriptor),
asmType.internalName,
null,
@@ -97,7 +97,7 @@ public class SamWrapperCodegen {
ClassBuilder cv = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), asmType, file);
cv.defineClass(file,
V1_6,
state.getClassFileVersion(),
ACC_FINAL | ACC_SUPER | visibility,
asmType.getInternalName(),
null,
@@ -89,7 +89,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
@Override
protected void generateDeclaration() {
v.defineClass(scriptDeclaration,
V1_6,
state.getClassFileVersion(),
ACC_PUBLIC | ACC_SUPER,
classAsmType.getInternalName(),
null,
@@ -65,7 +65,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
createClassReader().accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version, name);
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, inliningContext.state);
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces);
}
@@ -261,7 +261,7 @@ public class InlineCodegen extends CallGenerator {
}
});
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId);
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId, state);
}
assert functionDescriptor instanceof DeserializedSimpleFunctionDescriptor : "Not a deserialized function: " + functionDescriptor;
@@ -287,7 +287,8 @@ public class InlineCodegen extends CallGenerator {
}
});
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId);
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId, state);
}
@NotNull
@@ -82,7 +82,8 @@ public class InlineCodegenUtil {
byte[] classData,
final String methodName,
final String methodDescriptor,
ClassId classId
ClassId classId,
final @NotNull GenerationState state
) {
ClassReader cr = new ClassReader(classData);
final MethodNode[] node = new MethodNode[1];
@@ -94,7 +95,7 @@ public class InlineCodegenUtil {
cr.accept(new ClassVisitor(API) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
assertVersionNotGreaterThanJava6(version, name);
assertVersionNotGreaterThanGeneratedOne(version, name, state);
}
@Override
@@ -140,9 +141,9 @@ public class InlineCodegenUtil {
return new SMAPAndMethodNode(node[0], smap);
}
public static void assertVersionNotGreaterThanJava6(int version, String internalName) {
public static void assertVersionNotGreaterThanGeneratedOne(int version, String internalName, @NotNull GenerationState state) {
// TODO: report a proper diagnostic
if (version > Opcodes.V1_6 && !"true".equals(System.getProperty("kotlin.skip.bytecode.version.check"))) {
if (version > state.getClassFileVersion() && !"true".equals(System.getProperty("kotlin.skip.bytecode.version.check"))) {
throw new UnsupportedOperationException(
"Cannot inline bytecode of class " + internalName + " which has version " + version + ". " +
"This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")"
@@ -66,7 +66,7 @@ class WhenMappingTransformer(
val fieldNode = transformationInfo.fieldNode
classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version, name)
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, state)
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
}
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.Opcodes
import java.io.File
class GenerationState @JvmOverloads constructor(
@@ -157,6 +158,8 @@ class GenerationState @JvmOverloads constructor(
val rootContext: CodegenContext<*> = RootContext(this)
val classFileVersion: Int = Opcodes.V1_6
init {
this.interceptedBuilderFactory = builderFactory
.wrapWith(
@@ -46,7 +46,7 @@ public class MappingClassesForWhenByEnumCodegen {
ClassBuilder cb = state.getFactory().newVisitor(JvmDeclarationOrigin.NO_ORIGIN, mappingsClass, srcFile);
cb.defineClass(
srcFile,
V1_6,
state.getClassFileVersion(),
ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_SYNTHETIC,
mappingsClass.getInternalName(),
null,