List of usage examples for org.objectweb.asm MethodVisitor visitMaxs
public void visitMaxs(final int maxStack, final int maxLocals)
From source file:fr.insalyon.citi.golo.compiler.JavaBytecodeUnionGenerator.java
License:Apache License
private void makeValuedConstructor(ClassWriter cw, Union.Value value) { MethodVisitor mv = cw.visitMethod(ACC_PROTECTED, "<init>", argsSignature(value.getMembers().size()) + "V", null, null);//from w w w .j a va 2 s .c o m mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, value.getUnion().getPackageAndClass().toJVMType(), "<init>", "()V", false); int idx = 1; for (String member : value.getMembers()) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, idx++); mv.visitFieldInsn(PUTFIELD, value.getPackageAndClass().toJVMType(), member, "Ljava/lang/Object;"); } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:fr.insalyon.citi.golo.runtime.adapters.JavaBytecodeAdapterGenerator.java
License:Apache License
private void makeFrontendOverrides(ClassWriter classWriter, AdapterDefinition adapterDefinition) { for (Method method : getAllVirtualMethods(adapterDefinition)) { int access = isPublic(method.getModifiers()) ? ACC_PUBLIC : ACC_PROTECTED; if (method.isVarArgs()) { access = access & ACC_VARARGS; }/*from ww w .j a va2 s . c o m*/ String name = method.getName(); String descriptor = Type.getMethodDescriptor(method); Class<?>[] exceptionTypes = method.getExceptionTypes(); String[] exceptions = new String[exceptionTypes.length]; for (int i = 0; i < exceptionTypes.length; i++) { exceptions[i] = Type.getInternalName(exceptionTypes[i]); } MethodVisitor methodVisitor = classWriter.visitMethod(access, name, descriptor, null, exceptions); methodVisitor.visitCode(); Class<?>[] parameterTypes = method.getParameterTypes(); Type[] indyTypes = new Type[parameterTypes.length + 1]; indyTypes[0] = Type.getType(Object.class); methodVisitor.visitVarInsn(ALOAD, 0); int argIndex = 1; for (int i = 0; i < parameterTypes.length; i++) { argIndex = loadArgument(methodVisitor, parameterTypes[i], argIndex); indyTypes[i + 1] = Type.getType(parameterTypes[i]); } methodVisitor.visitInvokeDynamicInsn(method.getName(), Type.getMethodDescriptor(Type.getReturnType(method), indyTypes), ADAPTER_HANDLE); makeReturn(methodVisitor, method.getReturnType()); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); } }
From source file:fr.insalyon.citi.golo.runtime.adapters.JavaBytecodeAdapterGenerator.java
License:Apache License
private void makeConstructors(ClassWriter classWriter, AdapterDefinition adapterDefinition) { try {//from ww w . ja v a 2s. co m Class<?> parentClass = Class.forName(adapterDefinition.getParent(), true, adapterDefinition.getClassLoader()); for (Constructor constructor : parentClass.getDeclaredConstructors()) { if (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor.getModifiers())) { Class[] parameterTypes = constructor.getParameterTypes(); Type[] adapterParameterTypes = new Type[parameterTypes.length + 1]; adapterParameterTypes[0] = Type.getType(AdapterDefinition.class); for (int i = 1; i < adapterParameterTypes.length; i++) { adapterParameterTypes[i] = Type.getType(parameterTypes[i - 1]); } String descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, adapterParameterTypes); MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", descriptor, null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitFieldInsn(PUTFIELD, jvmType(adapterDefinition.getName()), DEFINITION_FIELD, "Lfr/insalyon/citi/golo/runtime/adapters/AdapterDefinition;"); methodVisitor.visitVarInsn(ALOAD, 0); int argIndex = 2; for (Class parameterType : parameterTypes) { argIndex = loadArgument(methodVisitor, parameterType, argIndex); } methodVisitor.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(parentClass), "<init>", Type.getConstructorDescriptor(constructor)); methodVisitor.visitInsn(RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); } } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } }
From source file:fr.liglab.adele.cilia.dependency.ProxyGenerator.java
License:Apache License
/** * Generates a delegated method./*from w ww. j a v a2 s . co m*/ * * @param cw the class writer * @param method the method object to delegate * @param className the generated class name * @param itfName the internal specification class name */ private static void generateDelegator(ClassWriter cw, Method method, String className, String itfName) { String methodName = method.getName(); String desc = Type.getMethodDescriptor(method); String[] exceptions = getInternalClassNames(method.getExceptionTypes()); int modifiers = method.getModifiers() & ~(Modifier.ABSTRACT | Modifier.NATIVE | Modifier.SYNCHRONIZED); Type[] types = Type.getArgumentTypes(method); int freeRoom = 1; for (int t = 0; t < types.length; t++) { freeRoom = freeRoom + types[t].getSize(); } MethodVisitor mv = cw.visitMethod(modifiers, methodName, desc, null, exceptions); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, DEPENDENCY, DEPENDENCY_DESC); // The dependency is on the stack. mv.visitMethodInsn(INVOKEVIRTUAL, DEPENDENCY_INTERNAL_NAME, "getService", // Call getService "()Ljava/lang/Object;"); // The service object is on the stack. int varSvc = freeRoom; freeRoom = freeRoom + 1; // Object Reference. mv.visitVarInsn(ASTORE, varSvc); // Store the service object. Label notNull = new Label(); Label isNull = new Label(); mv.visitVarInsn(ALOAD, varSvc); // Load the service mv.visitJumpInsn(IFNONNULL, notNull); // If not null go to not null // Null branch - throw the exception mv.visitLabel(isNull); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitLdcInsn("No service available"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); // End of the null branch // Not null, go one the execution mv.visitLabel(notNull); // Invoke the method on the service object. mv.visitVarInsn(ALOAD, varSvc); // Push argument on the stack. int i = 1; // Arguments. (non static method) for (int t = 0; t < types.length; t++) { mv.visitVarInsn(types[t].getOpcode(ILOAD), i); i = i + types[t].getSize(); } // Invocation mv.visitMethodInsn(INVOKEINTERFACE, itfName, methodName, desc); // Return the result Type returnType = Type.getReturnType(desc); if (returnType.getSort() != Type.VOID) { mv.visitInsn(returnType.getOpcode(IRETURN)); } else { mv.visitInsn(RETURN); } // End of the method. mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:fr.liglab.adele.cilia.dependency.ProxyGenerator.java
License:Apache License
/** * Generates the constructors. The constructor receives a dependency * and set the {@link ProxyGenerator#DEPENDENCY} field. * * @param cw the class writer/*from w ww. j a va 2 s . c om*/ * @param className the generated class name. */ private static void generateConstructor(ClassWriter cw, String className, String parent) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", '(' + DEPENDENCY_DESC + ")V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); // Load this mv.visitInsn(DUP); // Dup mv.visitMethodInsn(INVOKESPECIAL, parent, "<init>", "()V"); // Call super mv.visitVarInsn(ALOAD, 1); // Load the argument mv.visitFieldInsn(PUTFIELD, className, DEPENDENCY, DEPENDENCY_DESC); // Assign the dependency field mv.visitInsn(RETURN); // Return void mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:global.namespace.neuron.di.internal.ProxyClassVisitor.java
License:Apache License
private void insertConstructor() { final MethodVisitor mv = cv.visitMethod(ACC_PRIVATE_SYNTHETIC, CONSTRUCTOR_NAME, ACCEPTS_NOTHING_AND_RETURNS_VOID_DESC, null, null); mv.visitCode();//from w w w .j a v a 2 s . c o m mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, superName, CONSTRUCTOR_NAME, ACCEPTS_NOTHING_AND_RETURNS_VOID_DESC, false); for (final Method method : bindableMethods) { if (0 == (method.getModifiers() & ACC_ABSTRACT)) { final Class<?> declaringClass = method.getDeclaringClass(); final boolean isInterface = declaringClass.isInterface(); final String owner = getInternalName(declaringClass); final String name = method.getName(); final String desc = getMethodDescriptor(method); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0); mv.visitInvokeDynamicInsn("get", "(" + proxyDesc + ")" + dependencyProviderDesc, metaFactoryHandle, acceptsNothingAndReturnsObjectType, new Handle(H_INVOKESPECIAL, owner, name, desc, isInterface), acceptsNothingAndReturnsObjectType); mv.visitFieldInsn(PUTFIELD, proxyName, name + PROVIDER, dependencyProviderDesc); } } mv.visitInsn(RETURN); mv.visitMaxs(-1, -1); mv.visitEnd(); }
From source file:global.namespace.neuron.di.internal.ProxyClassVisitor.java
License:Apache License
private void insertMethods() { for (final Method method : bindableMethods) { new Object() { final int access = method.getModifiers() & ~ACC_ABSTRACT_NATIVE | ACC_SYNTHETIC; final String name = method.getName(); final String desc = getMethodDescriptor(method); final Class<?> returnType = method.getReturnType(); final String returnTypeName = getInternalName(returnType); final String returnTypeDesc = getDescriptor(returnType); final Class<?> boxedReturnType = boxed(returnType); final String boxedReturnTypeName = getInternalName(boxedReturnType); final String boxedReturnTypeDesc = getDescriptor(boxedReturnType); final int returnOpCode = returnOpCode(method); {/*from ww w.j a v a 2s .c om*/ generateProxyField(); generateProxyCallMethod(); } void generateProxyField() { cv.visitField(ACC_PRIVATE_SYNTHETIC, name + PROVIDER, dependencyProviderDesc, null, null) .visitEnd(); } void generateProxyCallMethod() { final MethodVisitor mv = beginMethod(name); mv.visitFieldInsn(GETFIELD, proxyName, name + PROVIDER, dependencyProviderDesc); mv.visitMethodInsn(INVOKEINTERFACE, dependencyProviderName, "get", ACCEPTS_NOTHING_AND_RETURNS_OBJECT_DESC, true); if (!boxedReturnType.isAssignableFrom(Object.class)) { mv.visitTypeInsn(CHECKCAST, boxedReturnType.isArray() ? boxedReturnTypeDesc : boxedReturnTypeName); } if (boxedReturnType != returnType) { assert !returnType.isArray(); mv.visitMethodInsn(INVOKEVIRTUAL, boxedReturnTypeName, returnTypeName.concat("Value"), "()".concat(returnTypeDesc), false); } endMethod(mv); } MethodVisitor beginMethod(final String name) { final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); return mv; } void endMethod(final MethodVisitor mv) { mv.visitInsn(returnOpCode); mv.visitMaxs(-1, -1); mv.visitEnd(); } }; } }
From source file:gnu.classpath.tools.rmic.ClassRmicCompiler.java
License:Open Source License
private static void generateClassForNamer(ClassVisitor cls) { MethodVisitor cv = cls.visitMethod(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, forName,/*from w w w .ja v a 2 s. c om*/ Type.getMethodDescriptor(Type.getType(Class.class), new Type[] { Type.getType(String.class) }), null, null); Label start = new Label(); cv.visitLabel(start); cv.visitVarInsn(Opcodes.ALOAD, 0); cv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Class.class), "forName", Type.getMethodDescriptor(Type.getType(Class.class), new Type[] { Type.getType(String.class) })); cv.visitInsn(Opcodes.ARETURN); Label handler = new Label(); cv.visitLabel(handler); cv.visitVarInsn(Opcodes.ASTORE, 1); cv.visitTypeInsn(Opcodes.NEW, typeArg(NoClassDefFoundError.class)); cv.visitInsn(Opcodes.DUP); cv.visitVarInsn(Opcodes.ALOAD, 1); cv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(ClassNotFoundException.class), "getMessage", Type.getMethodDescriptor(Type.getType(String.class), new Type[] {})); cv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(NoClassDefFoundError.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); cv.visitInsn(Opcodes.ATHROW); cv.visitTryCatchBlock(start, handler, handler, Type.getInternalName(ClassNotFoundException.class)); cv.visitMaxs(-1, -1); }
From source file:gnu.classpath.tools.rmic.ClassRmicCompiler.java
License:Open Source License
private void generateStub() throws IOException { stubname = fullclassname + "_Stub"; String stubclassname = classname + "_Stub"; File file = new File((destination == null ? "." : destination) + File.separator + stubname.replace('.', File.separatorChar) + ".class"); if (verbose)//from w w w.j ava 2 s . com System.out.println("[Generating class " + stubname + "]"); final ClassWriter stub = new ClassWriter(true); classInternalName = stubname.replace('.', '/'); final String superInternalName = Type.getType(RemoteStub.class).getInternalName(); String[] remoteInternalNames = internalNameArray((Class[]) mRemoteInterfaces.toArray(new Class[] {})); stub.visit(Opcodes.V1_2, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, classInternalName, null, superInternalName, remoteInternalNames); if (need12Stubs) { stub.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "serialVersionUID", Type.LONG_TYPE.getDescriptor(), null, new Long(2L)); } if (need11Stubs) { stub.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "interfaceHash", Type.LONG_TYPE.getDescriptor(), null, new Long(RMIHashes.getInterfaceHash(clazz))); if (need12Stubs) { stub.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, "useNewInvoke", Type.BOOLEAN_TYPE.getDescriptor(), null, null); } stub.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "operations", Type.getDescriptor(Operation[].class), null, null); } // Set of method references. if (need12Stubs) { for (int i = 0; i < remotemethods.length; i++) { Method m = remotemethods[i].meth; String slotName = "$method_" + m.getName() + "_" + i; stub.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, slotName, Type.getDescriptor(Method.class), null, null); } } MethodVisitor clinit = stub.visitMethod(Opcodes.ACC_STATIC, "<clinit>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null); if (need11Stubs) { fillOperationArray(clinit); if (!need12Stubs) clinit.visitInsn(Opcodes.RETURN); } if (need12Stubs) { // begin of try Label begin = new Label(); // beginning of catch Label handler = new Label(); clinit.visitLabel(begin); // Initialize the methods references. if (need11Stubs) { /* * RemoteRef.class.getMethod("invoke", new Class[] { * Remote.class, Method.class, Object[].class, long.class }) */ generateClassConstant(clinit, RemoteRef.class); clinit.visitLdcInsn("invoke"); generateClassArray(clinit, new Class[] { Remote.class, Method.class, Object[].class, long.class }); clinit.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Class.class), "getMethod", Type.getMethodDescriptor(Type.getType(Method.class), new Type[] { Type.getType(String.class), Type.getType(Class[].class) })); // useNewInvoke = true clinit.visitInsn(Opcodes.ICONST_1); clinit.visitFieldInsn(Opcodes.PUTSTATIC, classInternalName, "useNewInvoke", Type.BOOLEAN_TYPE.getDescriptor()); } generateStaticMethodObjs(clinit); // jump past handler clinit.visitInsn(Opcodes.RETURN); clinit.visitLabel(handler); if (need11Stubs) { // useNewInvoke = false clinit.visitInsn(Opcodes.ICONST_0); clinit.visitFieldInsn(Opcodes.PUTSTATIC, classInternalName, "useNewInvoke", Type.BOOLEAN_TYPE.getDescriptor()); clinit.visitInsn(Opcodes.RETURN); } else { // throw NoSuchMethodError clinit.visitTypeInsn(Opcodes.NEW, typeArg(NoSuchMethodError.class)); clinit.visitInsn(Opcodes.DUP); clinit.visitLdcInsn("stub class initialization failed"); clinit.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(NoSuchMethodError.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); clinit.visitInsn(Opcodes.ATHROW); } clinit.visitTryCatchBlock(begin, handler, handler, Type.getInternalName(NoSuchMethodException.class)); } clinit.visitMaxs(-1, -1); generateClassForNamer(stub); // Constructors if (need11Stubs) { // no arg public constructor MethodVisitor code = stub.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null); code.visitVarInsn(Opcodes.ALOAD, 0); code.visitMethodInsn(Opcodes.INVOKESPECIAL, superInternalName, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {})); code.visitInsn(Opcodes.RETURN); code.visitMaxs(-1, -1); } // public RemoteRef constructor MethodVisitor constructor = stub.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(RemoteRef.class) }), null, null); constructor.visitVarInsn(Opcodes.ALOAD, 0); constructor.visitVarInsn(Opcodes.ALOAD, 1); constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, superInternalName, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(RemoteRef.class) })); constructor.visitInsn(Opcodes.RETURN); constructor.visitMaxs(-1, -1); // Method implementations for (int i = 0; i < remotemethods.length; i++) { Method m = remotemethods[i].meth; Class[] sig = m.getParameterTypes(); Class returntype = m.getReturnType(); Class[] except = sortExceptions((Class[]) remotemethods[i].exceptions.toArray(new Class[0])); MethodVisitor code = stub.visitMethod(Opcodes.ACC_PUBLIC, m.getName(), Type.getMethodDescriptor(Type.getType(returntype), typeArray(sig)), null, internalNameArray(typeArray(except))); final Variables var = new Variables(); // this and parameters are the declared vars var.declare("this"); for (int j = 0; j < sig.length; j++) var.declare(param(m, j), size(sig[j])); Label methodTryBegin = new Label(); code.visitLabel(methodTryBegin); if (need12Stubs) { Label oldInvoke = new Label(); if (need11Stubs) { // if not useNewInvoke jump to old invoke code.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "useNewInvoke", Type.getDescriptor(boolean.class)); code.visitJumpInsn(Opcodes.IFEQ, oldInvoke); } // this.ref code.visitVarInsn(Opcodes.ALOAD, var.get("this")); code.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class), "ref", Type.getDescriptor(RemoteRef.class)); // "this" is first arg to invoke code.visitVarInsn(Opcodes.ALOAD, var.get("this")); // method object is second arg to invoke String methName = "$method_" + m.getName() + "_" + i; code.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, methName, Type.getDescriptor(Method.class)); // args to remote method are third arg to invoke if (sig.length == 0) code.visitInsn(Opcodes.ACONST_NULL); else { // create arg Object[] (with boxed primitives) and push it code.visitLdcInsn(new Integer(sig.length)); code.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Object.class)); var.allocate("argArray"); code.visitVarInsn(Opcodes.ASTORE, var.get("argArray")); for (int j = 0; j < sig.length; j++) { int size = size(sig[j]); int insn = loadOpcode(sig[j]); Class box = sig[j].isPrimitive() ? box(sig[j]) : null; code.visitVarInsn(Opcodes.ALOAD, var.get("argArray")); code.visitLdcInsn(new Integer(j)); // put argument on stack if (box != null) { code.visitTypeInsn(Opcodes.NEW, typeArg(box)); code.visitInsn(Opcodes.DUP); code.visitVarInsn(insn, var.get(param(m, j))); code.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(box), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(sig[j]) })); } else code.visitVarInsn(insn, var.get(param(m, j))); code.visitInsn(Opcodes.AASTORE); } code.visitVarInsn(Opcodes.ALOAD, var.deallocate("argArray")); } // push remote operation opcode code.visitLdcInsn(new Long(remotemethods[i].hash)); code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(RemoteRef.class), "invoke", Type.getMethodDescriptor(Type.getType(Object.class), new Type[] { Type.getType(Remote.class), Type.getType(Method.class), Type.getType(Object[].class), Type.LONG_TYPE })); if (!returntype.equals(Void.TYPE)) { int retcode = returnOpcode(returntype); Class boxCls = returntype.isPrimitive() ? box(returntype) : null; code.visitTypeInsn(Opcodes.CHECKCAST, typeArg(boxCls == null ? returntype : boxCls)); if (returntype.isPrimitive()) { // unbox code.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getType(boxCls).getInternalName(), unboxMethod(returntype), Type.getMethodDescriptor(Type.getType(returntype), new Type[] {})); } code.visitInsn(retcode); } else code.visitInsn(Opcodes.RETURN); if (need11Stubs) code.visitLabel(oldInvoke); } if (need11Stubs) { // this.ref.newCall(this, operations, index, interfaceHash) code.visitVarInsn(Opcodes.ALOAD, var.get("this")); code.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class), "ref", Type.getDescriptor(RemoteRef.class)); // "this" is first arg to newCall code.visitVarInsn(Opcodes.ALOAD, var.get("this")); // operations is second arg to newCall code.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "operations", Type.getDescriptor(Operation[].class)); // method index is third arg code.visitLdcInsn(new Integer(i)); // interface hash is fourth arg code.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "interfaceHash", Type.LONG_TYPE.getDescriptor()); code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(RemoteRef.class), "newCall", Type.getMethodDescriptor(Type.getType(RemoteCall.class), new Type[] { Type.getType(RemoteObject.class), Type.getType(Operation[].class), Type.INT_TYPE, Type.LONG_TYPE })); // store call object on stack and leave copy on stack var.allocate("call"); code.visitInsn(Opcodes.DUP); code.visitVarInsn(Opcodes.ASTORE, var.get("call")); Label beginArgumentTryBlock = new Label(); code.visitLabel(beginArgumentTryBlock); // ObjectOutput out = call.getOutputStream(); code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(RemoteCall.class), "getOutputStream", Type.getMethodDescriptor(Type.getType(ObjectOutput.class), new Type[] {})); for (int j = 0; j < sig.length; j++) { // dup the ObjectOutput code.visitInsn(Opcodes.DUP); // get j'th arg to remote method code.visitVarInsn(loadOpcode(sig[j]), var.get(param(m, j))); Class argCls = sig[j].isPrimitive() ? sig[j] : Object.class; // out.writeFoo code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(ObjectOutput.class), writeMethod(sig[j]), Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(argCls) })); } // pop ObjectOutput code.visitInsn(Opcodes.POP); Label iohandler = new Label(); Label endArgumentTryBlock = new Label(); code.visitJumpInsn(Opcodes.GOTO, endArgumentTryBlock); code.visitLabel(iohandler); // throw new MarshalException(msg, ioexception); code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception")); code.visitTypeInsn(Opcodes.NEW, typeArg(MarshalException.class)); code.visitInsn(Opcodes.DUP); code.visitLdcInsn("error marshalling arguments"); code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception")); code.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(MarshalException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class), Type.getType(Exception.class) })); code.visitInsn(Opcodes.ATHROW); code.visitLabel(endArgumentTryBlock); code.visitTryCatchBlock(beginArgumentTryBlock, iohandler, iohandler, Type.getInternalName(IOException.class)); // this.ref.invoke(call) code.visitVarInsn(Opcodes.ALOAD, var.get("this")); code.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class), "ref", Type.getDescriptor(RemoteRef.class)); code.visitVarInsn(Opcodes.ALOAD, var.get("call")); code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(RemoteRef.class), "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(RemoteCall.class) })); // handle return value boolean needcastcheck = false; Label beginReturnTryCatch = new Label(); code.visitLabel(beginReturnTryCatch); int returncode = returnOpcode(returntype); if (!returntype.equals(Void.TYPE)) { // call.getInputStream() code.visitVarInsn(Opcodes.ALOAD, var.get("call")); code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(RemoteCall.class), "getInputStream", Type.getMethodDescriptor(Type.getType(ObjectInput.class), new Type[] {})); Class readCls = returntype.isPrimitive() ? returntype : Object.class; code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(ObjectInput.class), readMethod(returntype), Type.getMethodDescriptor(Type.getType(readCls), new Type[] {})); boolean castresult = false; if (!returntype.isPrimitive()) { if (!returntype.equals(Object.class)) castresult = true; else needcastcheck = true; } if (castresult) code.visitTypeInsn(Opcodes.CHECKCAST, typeArg(returntype)); // leave result on stack for return } // this.ref.done(call) code.visitVarInsn(Opcodes.ALOAD, var.get("this")); code.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class), "ref", Type.getDescriptor(RemoteRef.class)); code.visitVarInsn(Opcodes.ALOAD, var.deallocate("call")); code.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(RemoteRef.class), "done", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(RemoteCall.class) })); // return; or return result; code.visitInsn(returncode); // exception handler Label handler = new Label(); code.visitLabel(handler); code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception")); // throw new UnmarshalException(msg, e) code.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class)); code.visitInsn(Opcodes.DUP); code.visitLdcInsn("error unmarshalling return"); code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception")); code.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(UnmarshalException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class), Type.getType(Exception.class) })); code.visitInsn(Opcodes.ATHROW); Label endReturnTryCatch = new Label(); // catch IOException code.visitTryCatchBlock(beginReturnTryCatch, handler, handler, Type.getInternalName(IOException.class)); if (needcastcheck) { // catch ClassNotFoundException code.visitTryCatchBlock(beginReturnTryCatch, handler, handler, Type.getInternalName(ClassNotFoundException.class)); } } Label rethrowHandler = new Label(); code.visitLabel(rethrowHandler); // rethrow declared exceptions code.visitInsn(Opcodes.ATHROW); boolean needgeneral = true; for (int j = 0; j < except.length; j++) { if (except[j] == Exception.class) needgeneral = false; } for (int j = 0; j < except.length; j++) { code.visitTryCatchBlock(methodTryBegin, rethrowHandler, rethrowHandler, Type.getInternalName(except[j])); } if (needgeneral) { // rethrow unchecked exceptions code.visitTryCatchBlock(methodTryBegin, rethrowHandler, rethrowHandler, Type.getInternalName(RuntimeException.class)); Label generalHandler = new Label(); code.visitLabel(generalHandler); String msg = "undeclared checked exception"; // throw new java.rmi.UnexpectedException(msg, e) code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception")); code.visitTypeInsn(Opcodes.NEW, typeArg(UnexpectedException.class)); code.visitInsn(Opcodes.DUP); code.visitLdcInsn(msg); code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception")); code.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(UnexpectedException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class), Type.getType(Exception.class) })); code.visitInsn(Opcodes.ATHROW); code.visitTryCatchBlock(methodTryBegin, rethrowHandler, generalHandler, Type.getInternalName(Exception.class)); } code.visitMaxs(-1, -1); } stub.visitEnd(); byte[] classData = stub.toByteArray(); if (!noWrite) { if (file.exists()) file.delete(); if (file.getParentFile() != null) file.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(file); fos.write(classData); fos.flush(); fos.close(); } }
From source file:gnu.classpath.tools.rmic.ClassRmicCompiler.java
License:Open Source License
private void generateSkel() throws IOException { skelname = fullclassname + "_Skel"; String skelclassname = classname + "_Skel"; File file = new File(destination == null ? "" : destination + File.separator + skelname.replace('.', File.separatorChar) + ".class"); if (verbose)// w w w . ja v a 2s .c om System.out.println("[Generating class " + skelname + "]"); final ClassWriter skel = new ClassWriter(true); classInternalName = skelname.replace('.', '/'); skel.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, classInternalName, Type.getInternalName(Object.class), null, new String[] { Type.getType(Skeleton.class).getInternalName() }); skel.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "interfaceHash", Type.LONG_TYPE.getDescriptor(), null, new Long(RMIHashes.getInterfaceHash(clazz))); skel.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "operations", Type.getDescriptor(Operation[].class), null, null); MethodVisitor clinit = skel.visitMethod(Opcodes.ACC_STATIC, "<clinit>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null); fillOperationArray(clinit); clinit.visitInsn(Opcodes.RETURN); clinit.visitMaxs(-1, -1); // no arg public constructor MethodVisitor init = skel.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null); init.visitVarInsn(Opcodes.ALOAD, 0); init.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {})); init.visitInsn(Opcodes.RETURN); init.visitMaxs(-1, -1); /* * public Operation[] getOperations() * returns a clone of the operations array */ MethodVisitor getOp = skel.visitMethod(Opcodes.ACC_PUBLIC, "getOperations", Type.getMethodDescriptor(Type.getType(Operation[].class), new Type[] {}), null, null); getOp.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "operations", Type.getDescriptor(Operation[].class)); getOp.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Object.class), "clone", Type.getMethodDescriptor(Type.getType(Object.class), new Type[] {})); getOp.visitTypeInsn(Opcodes.CHECKCAST, typeArg(Operation[].class)); getOp.visitInsn(Opcodes.ARETURN); getOp.visitMaxs(-1, -1); // public void dispatch(Remote, RemoteCall, int opnum, long hash) MethodVisitor dispatch = skel.visitMethod(Opcodes.ACC_PUBLIC, "dispatch", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(Remote.class), Type.getType(RemoteCall.class), Type.INT_TYPE, Type.LONG_TYPE }), null, new String[] { Type.getInternalName(Exception.class) }); Variables var = new Variables(); var.declare("this"); var.declare("remoteobj"); var.declare("remotecall"); var.declare("opnum"); var.declareWide("hash"); /* * if opnum >= 0 * XXX it is unclear why there is handling of negative opnums */ dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum")); Label nonNegativeOpnum = new Label(); Label opnumSet = new Label(); dispatch.visitJumpInsn(Opcodes.IFGE, nonNegativeOpnum); for (int i = 0; i < remotemethods.length; i++) { // assign opnum if hash matches supplied hash dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash")); dispatch.visitLdcInsn(new Long(remotemethods[i].hash)); Label notIt = new Label(); dispatch.visitInsn(Opcodes.LCMP); dispatch.visitJumpInsn(Opcodes.IFNE, notIt); // opnum = <opnum> dispatch.visitLdcInsn(new Integer(i)); dispatch.visitVarInsn(Opcodes.ISTORE, var.get("opnum")); dispatch.visitJumpInsn(Opcodes.GOTO, opnumSet); dispatch.visitLabel(notIt); } // throw new SkeletonMismatchException Label mismatch = new Label(); dispatch.visitJumpInsn(Opcodes.GOTO, mismatch); dispatch.visitLabel(nonNegativeOpnum); // if opnum is already set, check that the hash matches the interface dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash")); dispatch.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "interfaceHash", Type.LONG_TYPE.getDescriptor()); dispatch.visitInsn(Opcodes.LCMP); dispatch.visitJumpInsn(Opcodes.IFEQ, opnumSet); dispatch.visitLabel(mismatch); dispatch.visitTypeInsn(Opcodes.NEW, typeArg(SkeletonMismatchException.class)); dispatch.visitInsn(Opcodes.DUP); dispatch.visitLdcInsn("interface hash mismatch"); dispatch.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(SkeletonMismatchException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); dispatch.visitInsn(Opcodes.ATHROW); // opnum has been set dispatch.visitLabel(opnumSet); dispatch.visitVarInsn(Opcodes.ALOAD, var.get("remoteobj")); dispatch.visitTypeInsn(Opcodes.CHECKCAST, typeArg(clazz)); dispatch.visitVarInsn(Opcodes.ASTORE, var.get("remoteobj")); Label deflt = new Label(); Label[] methLabels = new Label[remotemethods.length]; for (int i = 0; i < methLabels.length; i++) methLabels[i] = new Label(); // switch on opnum dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum")); dispatch.visitTableSwitchInsn(0, remotemethods.length - 1, deflt, methLabels); // Method dispatch for (int i = 0; i < remotemethods.length; i++) { dispatch.visitLabel(methLabels[i]); Method m = remotemethods[i].meth; generateMethodSkel(dispatch, m, var); } dispatch.visitLabel(deflt); dispatch.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class)); dispatch.visitInsn(Opcodes.DUP); dispatch.visitLdcInsn("invalid method number"); dispatch.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(UnmarshalException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); dispatch.visitInsn(Opcodes.ATHROW); dispatch.visitMaxs(-1, -1); skel.visitEnd(); byte[] classData = skel.toByteArray(); if (!noWrite) { if (file.exists()) file.delete(); if (file.getParentFile() != null) file.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(file); fos.write(classData); fos.flush(); fos.close(); } }