269 JavaAdapterBytecodeGenerator(final Class<?> superClass, final List<Class<?>> interfaces,
270 final ClassLoader commonLoader, final boolean classOverride) throws AdaptationException {
271 assert superClass != null && !superClass.isInterface();
272 assert interfaces != null;
273
274 this.superClass = superClass;
275 this.interfaces = interfaces;
276 this.classOverride = classOverride;
277 this.commonLoader = commonLoader;
278 cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
279 @Override
280 protected String getCommonSuperClass(final String type1, final String type2) {
281 // We need to override ClassWriter.getCommonSuperClass to use this factory's commonLoader as a class
282 // loader to find the common superclass of two types when needed.
283 return JavaAdapterBytecodeGenerator.this.getCommonSuperClass(type1, type2);
284 }
285 };
286 superClassName = Type.getInternalName(superClass);
287 generatedClassName = getGeneratedClassName(superClass, interfaces);
288
289 cw.visit(Opcodes.V1_7, ACC_PUBLIC | ACC_SUPER, generatedClassName, null, superClassName, getInternalTypeNames(interfaces));
290 generateField(GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
291 generateField(DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
292
293 gatherMethods(superClass);
294 gatherMethods(interfaces);
295 if (abstractMethodNames.size() == 1) {
296 samName = abstractMethodNames.iterator().next();
297 generateField(CALL_THIS_FIELD_NAME, OBJECT_TYPE_DESCRIPTOR);
298 generateField(IS_FUNCTION_FIELD_NAME, BOOLEAN_TYPE_DESCRIPTOR);
299 } else {
300 samName = null;
301 }
302 if(classOverride) {
303 generateClassInit();
304 }
305 autoConvertibleFromFunction = generateConstructors();
306 generateMethods();
307 generateSuperMethods();
308 if (hasExplicitFinalizer) {
309 generateFinalizerMethods();
1014 return emitSuperCall(mv, null, INIT, methodDesc, true);
1015 }
1016
1017 private int emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc) {
1018 return emitSuperCall(mv, owner, name, methodDesc, false);
1019 }
1020
1021 private int emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc, final boolean constructor) {
1022 mv.visitVarInsn(ALOAD, 0);
1023 int nextParam = 1;
1024 final Type methodType = Type.getMethodType(methodDesc);
1025 for(final Type t: methodType.getArgumentTypes()) {
1026 mv.load(nextParam, t);
1027 nextParam += t.getSize();
1028 }
1029
1030 // default method - non-abstract, interface method
1031 if (!constructor && Modifier.isInterface(owner.getModifiers())) {
1032 // we should call default method on the immediate "super" type - not on (possibly)
1033 // the indirectly inherited interface class!
1034 mv.invokespecial(Type.getInternalName(findInvokespecialOwnerFor(owner)), name, methodDesc, false);
1035 } else {
1036 mv.invokespecial(superClassName, name, methodDesc, false);
1037 }
1038 return nextParam;
1039 }
1040
1041 private void generateFinalizerMethods() {
1042 generateFinalizerDelegate();
1043 generateFinalizerOverride();
1044 }
1045
1046 private void generateFinalizerDelegate() {
1047 // Generate a delegate that will be invoked from the no-permission trampoline. Note it can be private, as we'll
1048 // refer to it with a MethodHandle constant pool entry in the overridden finalize() method (see
1049 // generateFinalizerOverride()).
1050 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PRIVATE | ACC_STATIC,
1051 FINALIZER_DELEGATE_NAME, FINALIZER_DELEGATE_METHOD_DESCRIPTOR, null, null));
1052
1053 // Simply invoke super.finalize()
1054 mv.visitVarInsn(ALOAD, 0);
|
269 JavaAdapterBytecodeGenerator(final Class<?> superClass, final List<Class<?>> interfaces,
270 final ClassLoader commonLoader, final boolean classOverride) throws AdaptationException {
271 assert superClass != null && !superClass.isInterface();
272 assert interfaces != null;
273
274 this.superClass = superClass;
275 this.interfaces = interfaces;
276 this.classOverride = classOverride;
277 this.commonLoader = commonLoader;
278 cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
279 @Override
280 protected String getCommonSuperClass(final String type1, final String type2) {
281 // We need to override ClassWriter.getCommonSuperClass to use this factory's commonLoader as a class
282 // loader to find the common superclass of two types when needed.
283 return JavaAdapterBytecodeGenerator.this.getCommonSuperClass(type1, type2);
284 }
285 };
286 superClassName = Type.getInternalName(superClass);
287 generatedClassName = getGeneratedClassName(superClass, interfaces);
288
289 cw.visit(Opcodes.V1_8, ACC_PUBLIC | ACC_SUPER, generatedClassName, null, superClassName, getInternalTypeNames(interfaces));
290 generateField(GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
291 generateField(DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
292
293 gatherMethods(superClass);
294 gatherMethods(interfaces);
295 if (abstractMethodNames.size() == 1) {
296 samName = abstractMethodNames.iterator().next();
297 generateField(CALL_THIS_FIELD_NAME, OBJECT_TYPE_DESCRIPTOR);
298 generateField(IS_FUNCTION_FIELD_NAME, BOOLEAN_TYPE_DESCRIPTOR);
299 } else {
300 samName = null;
301 }
302 if(classOverride) {
303 generateClassInit();
304 }
305 autoConvertibleFromFunction = generateConstructors();
306 generateMethods();
307 generateSuperMethods();
308 if (hasExplicitFinalizer) {
309 generateFinalizerMethods();
1014 return emitSuperCall(mv, null, INIT, methodDesc, true);
1015 }
1016
1017 private int emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc) {
1018 return emitSuperCall(mv, owner, name, methodDesc, false);
1019 }
1020
1021 private int emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc, final boolean constructor) {
1022 mv.visitVarInsn(ALOAD, 0);
1023 int nextParam = 1;
1024 final Type methodType = Type.getMethodType(methodDesc);
1025 for(final Type t: methodType.getArgumentTypes()) {
1026 mv.load(nextParam, t);
1027 nextParam += t.getSize();
1028 }
1029
1030 // default method - non-abstract, interface method
1031 if (!constructor && Modifier.isInterface(owner.getModifiers())) {
1032 // we should call default method on the immediate "super" type - not on (possibly)
1033 // the indirectly inherited interface class!
1034 final Class<?> superType = findInvokespecialOwnerFor(owner);
1035 mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(superType), name, methodDesc,
1036 Modifier.isInterface(superType.getModifiers()));
1037 } else {
1038 mv.invokespecial(superClassName, name, methodDesc, false);
1039 }
1040 return nextParam;
1041 }
1042
1043 private void generateFinalizerMethods() {
1044 generateFinalizerDelegate();
1045 generateFinalizerOverride();
1046 }
1047
1048 private void generateFinalizerDelegate() {
1049 // Generate a delegate that will be invoked from the no-permission trampoline. Note it can be private, as we'll
1050 // refer to it with a MethodHandle constant pool entry in the overridden finalize() method (see
1051 // generateFinalizerOverride()).
1052 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PRIVATE | ACC_STATIC,
1053 FINALIZER_DELEGATE_NAME, FINALIZER_DELEGATE_METHOD_DESCRIPTOR, null, null));
1054
1055 // Simply invoke super.finalize()
1056 mv.visitVarInsn(ALOAD, 0);
|