⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmic.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        // instantiate operation and leave a copy on the stack        clinit.visitTypeInsn(C.NEW, typeArg(Operation.class));        clinit.visitInsn(C.DUP);        clinit.visitLdcInsn(desc.toString());        clinit.visitMethodInsn          (C.INVOKESPECIAL,           Type.getInternalName(Operation.class),           "<init>",           Type.getMethodDescriptor           (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));        // store in operations array        clinit.visitInsn(C.AASTORE);      }  }  private void generateStaticMethodObjs(CodeVisitor clinit)  {    for (int i = 0; i < remotemethods.length; i++)      {        Method m = remotemethods[i].meth;        /*         * $method_<i>m.getName()</i>_<i>i</i> =         *   <i>m.getDeclaringClass()</i>.class.getMethod         *     (m.getName(), m.getParameterType())         */        String methodVar = "$method_" + m.getName() + "_" + i;        generateClassConstant(clinit, m.getDeclaringClass());        clinit.visitLdcInsn(m.getName());        generateClassArray(clinit, m.getParameterTypes());        clinit.visitMethodInsn          (C.INVOKEVIRTUAL,           Type.getInternalName(Class.class),           "getMethod",           Type.getMethodDescriptor           (Type.getType(Method.class),            new Type[] { Type.getType(String.class),                         Type.getType(Class[].class) }));        clinit.visitFieldInsn          (C.PUTSTATIC, classInternalName, methodVar,           Type.getDescriptor(Method.class));      }  }  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)      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      (C.V1_2, C.ACC_PUBLIC + C.ACC_FINAL, classInternalName,       superInternalName, remoteInternalNames, null);    if (need12Stubs)      {        stub.visitField          (C.ACC_PRIVATE + C.ACC_STATIC + C.ACC_FINAL, "serialVersionUID",           Type.LONG_TYPE.getDescriptor(), new Long(2L), null);      }    if (need11Stubs)      {        stub.visitField          (C.ACC_PRIVATE + C.ACC_STATIC + C.ACC_FINAL,           "interfaceHash", Type.LONG_TYPE.getDescriptor(),           new Long(RMIHashes.getInterfaceHash(clazz)), null);        if (need12Stubs)          {            stub.visitField              (C.ACC_PRIVATE + C.ACC_STATIC, "useNewInvoke",               Type.BOOLEAN_TYPE.getDescriptor(), null, null);          }        stub.visitField          (C.ACC_PRIVATE + C.ACC_STATIC + C.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              (C.ACC_PRIVATE + C.ACC_STATIC, slotName,               Type.getDescriptor(Method.class), null, null);          }      }    CodeVisitor clinit = stub.visitMethod      (C.ACC_STATIC, "<clinit>",       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);    if (need11Stubs)      {        fillOperationArray(clinit);        if (! need12Stubs)          clinit.visitInsn(C.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              (C.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(C.ICONST_1);            clinit.visitFieldInsn              (C.PUTSTATIC, classInternalName, "useNewInvoke",               Type.BOOLEAN_TYPE.getDescriptor());          }        generateStaticMethodObjs(clinit);        // jump past handler        clinit.visitInsn(C.RETURN);        clinit.visitLabel(handler);        if (need11Stubs)          {            // useNewInvoke = false            clinit.visitInsn(C.ICONST_0);            clinit.visitFieldInsn              (C.PUTSTATIC, classInternalName, "useNewInvoke",               Type.BOOLEAN_TYPE.getDescriptor());            clinit.visitInsn(C.RETURN);          }        else          {            // throw NoSuchMethodError            clinit.visitTypeInsn(C.NEW, typeArg(NoSuchMethodError.class));            clinit.visitInsn(C.DUP);            clinit.visitLdcInsn("stub class initialization failed");            clinit.visitMethodInsn              (C.INVOKESPECIAL,               Type.getInternalName(NoSuchMethodError.class),               "<init>",               Type.getMethodDescriptor               (Type.VOID_TYPE,                new Type[] { Type.getType(String.class) }));            clinit.visitInsn(C.ATHROW);          }        clinit.visitTryCatchBlock          (begin, handler, handler,           Type.getInternalName(NoSuchMethodException.class));      }    clinit.visitMaxs(-1, -1);    generateClassForNamer(stub);    // Constructors    if (need11Stubs)      {        // no arg public constructor        CodeVisitor code = stub.visitMethod          (C.ACC_PUBLIC, "<init>",           Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}),           null, null);        code.visitVarInsn(C.ALOAD, 0);        code.visitMethodInsn          (C.INVOKESPECIAL, superInternalName, "<init>",           Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));        code.visitInsn(C.RETURN);        code.visitMaxs(-1, -1);      }    // public RemoteRef constructor    CodeVisitor constructor = stub.visitMethod      (C.ACC_PUBLIC, "<init>",       Type.getMethodDescriptor       (Type.VOID_TYPE, new Type[] {Type.getType(RemoteRef.class)}),       null, null);    constructor.visitVarInsn(C.ALOAD, 0);    constructor.visitVarInsn(C.ALOAD, 1);    constructor.visitMethodInsn      (C.INVOKESPECIAL, superInternalName, "<init>",       Type.getMethodDescriptor       (Type.VOID_TYPE, new Type[] {Type.getType(RemoteRef.class)}));    constructor.visitInsn(C.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]));        CodeVisitor code = stub.visitMethod          (C.ACC_PUBLIC,           m.getName(),           Type.getMethodDescriptor(Type.getType(returntype), typeArray(sig)),           internalNameArray(typeArray(except)),           null);        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                  (C.GETSTATIC, classInternalName, "useNewInvoke",                   Type.getDescriptor(boolean.class));                code.visitJumpInsn(C.IFEQ, oldInvoke);              }            // this.ref            code.visitVarInsn(C.ALOAD, var.get("this"));            code.visitFieldInsn              (C.GETFIELD, Type.getInternalName(RemoteObject.class),               "ref", Type.getDescriptor(RemoteRef.class));            // "this" is first arg to invoke            code.visitVarInsn(C.ALOAD, var.get("this"));            // method object is second arg to invoke            String methName = "$method_" + m.getName() + "_" + i;            code.visitFieldInsn              (C.GETSTATIC, classInternalName, methName,               Type.getDescriptor(Method.class));            // args to remote method are third arg to invoke            if (sig.length == 0)              code.visitInsn(C.ACONST_NULL);            else              {                // create arg Object[] (with boxed primitives) and push it                code.visitLdcInsn(new Integer(sig.length));                code.visitTypeInsn(C.ANEWARRAY, typeArg(Object.class));                var.allocate("argArray");                code.visitVarInsn(C.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(C.ALOAD, var.get("argArray"));                    code.visitLdcInsn(new Integer(j));                    // put argument on stack                    if (box != null)                      {                        code.visitTypeInsn(C.NEW, typeArg(box));                        code.visitInsn(C.DUP);                        code.visitVarInsn(insn, var.get(param(m, j)));                        code.visitMethodInsn                          (C.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(C.AASTORE);                  }                code.visitVarInsn(C.ALOAD, var.deallocate("argArray"));              }            // push remote operation opcode            code.visitLdcInsn(new Long(remotemethods[i].hash));            code.visitMethodInsn              (C.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                  (C.CHECKCAST, typeArg(boxCls == null ? returntype : boxCls));                if (returntype.isPrimitive())                  {                    // unbox                    code.visitMethodInsn                      (C.INVOKEVIRTUAL,                       Type.getType(boxCls).getInternalName(),                       unboxMethod(returntype),                       Type.getMethodDescriptor                       (Type.getType(returntype), new Type[] {}));                  }                code.visitInsn(retcode);              }            else              code.visitInsn(C.RETURN);            if (need11Stubs)              code.visitLabel(oldInvoke);          }        if (need11Stubs)          {            // this.ref.newCall(this, operations, index, interfaceHash)            code.visitVarInsn(C.ALOAD, var.get("this"));            code.visitFieldInsn              (C.GETFIELD,               Type.getInternalName(RemoteObject.class),               "ref",               Type.getDescriptor(RemoteRef.class));            // "this" is first arg to newCall            code.visitVarInsn(C.ALOAD, var.get("this"));            // operations is second arg to newCall            code.visitFieldInsn              (C.GETSTATIC, classInternalName, "operations",               Type.getDescriptor(Operation[].class));            // method index is third arg            code.visitLdcInsn(new Integer(i));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -