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

📄 rmic.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            // interface hash is fourth arg            code.visitFieldInsn              (C.GETSTATIC, classInternalName, "interfaceHash",               Type.LONG_TYPE.getDescriptor());            code.visitMethodInsn              (C.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(C.DUP);            code.visitVarInsn(C.ASTORE, var.get("call"));            Label beginArgumentTryBlock = new Label();            code.visitLabel(beginArgumentTryBlock);            // ObjectOutput out = call.getOutputStream();            code.visitMethodInsn              (C.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(C.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                  (C.INVOKEINTERFACE,                   Type.getInternalName(ObjectOutput.class),                   writeMethod(sig[j]),                   Type.getMethodDescriptor                   (Type.VOID_TYPE,                    new Type[] { Type.getType(argCls) }));              }            // pop ObjectOutput            code.visitInsn(C.POP);            Label iohandler = new Label();            Label endArgumentTryBlock = new Label();            code.visitJumpInsn(C.GOTO, endArgumentTryBlock);            code.visitLabel(iohandler);            // throw new MarshalException(msg, ioexception);            code.visitVarInsn(C.ASTORE, var.allocate("exception"));            code.visitTypeInsn(C.NEW, typeArg(MarshalException.class));            code.visitInsn(C.DUP);            code.visitLdcInsn("error marshalling arguments");            code.visitVarInsn(C.ALOAD, var.deallocate("exception"));            code.visitMethodInsn              (C.INVOKESPECIAL,               Type.getInternalName(MarshalException.class),               "<init>",               Type.getMethodDescriptor               (Type.VOID_TYPE,                new Type[] { Type.getType(String.class),                             Type.getType(Exception.class) }));            code.visitInsn(C.ATHROW);            code.visitLabel(endArgumentTryBlock);            code.visitTryCatchBlock              (beginArgumentTryBlock, iohandler, iohandler,               Type.getInternalName(IOException.class));            // this.ref.invoke(call)            code.visitVarInsn(C.ALOAD, var.get("this"));            code.visitFieldInsn              (C.GETFIELD, Type.getInternalName(RemoteObject.class),               "ref", Type.getDescriptor(RemoteRef.class));            code.visitVarInsn(C.ALOAD, var.get("call"));            code.visitMethodInsn              (C.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(C.ALOAD, var.get("call"));                code.visitMethodInsn                  (C.INVOKEINTERFACE,                   Type.getInternalName(RemoteCall.class),                   "getInputStream",                   Type.getMethodDescriptor                   (Type.getType(ObjectInput.class), new Type[] {}));                Class readCls =                  returntype.isPrimitive() ? returntype : Object.class;                code.visitMethodInsn                  (C.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(C.CHECKCAST, typeArg(returntype));                // leave result on stack for return              }            // this.ref.done(call)            code.visitVarInsn(C.ALOAD, var.get("this"));            code.visitFieldInsn              (C.GETFIELD,               Type.getInternalName(RemoteObject.class),               "ref",               Type.getDescriptor(RemoteRef.class));            code.visitVarInsn(C.ALOAD, var.deallocate("call"));            code.visitMethodInsn              (C.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(C.ASTORE, var.allocate("exception"));            // throw new UnmarshalException(msg, e)            code.visitTypeInsn(C.NEW, typeArg(UnmarshalException.class));            code.visitInsn(C.DUP);            code.visitLdcInsn("error unmarshalling return");            code.visitVarInsn(C.ALOAD, var.deallocate("exception"));            code.visitMethodInsn              (C.INVOKESPECIAL,               Type.getInternalName(UnmarshalException.class),               "<init>",               Type.getMethodDescriptor               (Type.VOID_TYPE,                new Type[] { Type.getType(String.class),                             Type.getType(Exception.class) }));            code.visitInsn(C.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(C.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(C.ASTORE, var.allocate("exception"));            code.visitTypeInsn(C.NEW, typeArg(UnexpectedException.class));            code.visitInsn(C.DUP);            code.visitLdcInsn(msg);            code.visitVarInsn(C.ALOAD, var.deallocate("exception"));            code.visitMethodInsn              (C.INVOKESPECIAL,               Type.getInternalName(UnexpectedException.class),               "<init>",               Type.getMethodDescriptor               (Type.VOID_TYPE,                new Type [] { Type.getType(String.class),                              Type.getType(Exception.class) }));            code.visitInsn(C.ATHROW);            code.visitTryCatchBlock              (methodTryBegin, rethrowHandler, generalHandler,               Type.getInternalName(Exception.class));          }        code.visitMaxs(-1, -1);      }    stub.visitEnd();    byte[] classData = stub.toByteArray();    if (file.exists())      file.delete();    if (file.getParentFile() != null)      file.getParentFile().mkdirs();    FileOutputStream fos = new FileOutputStream(file);    fos.write(classData);    fos.flush();    fos.close();  }  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)      System.out.println("[Generating class " + skelname + "]");    final ClassWriter skel = new ClassWriter(true);    classInternalName = skelname.replace('.', '/');    skel.visit      (C.V1_1, C.ACC_PUBLIC + C.ACC_FINAL,       classInternalName, Type.getInternalName(Object.class),       new String[] { Type.getType(Skeleton.class).getInternalName() }, null);    skel.visitField      (C.ACC_PRIVATE + C.ACC_STATIC + C.ACC_FINAL, "interfaceHash",       Type.LONG_TYPE.getDescriptor(),       new Long(RMIHashes.getInterfaceHash(clazz)),       null);    skel.visitField      (C.ACC_PRIVATE + C.ACC_STATIC + C.ACC_FINAL, "operations",       Type.getDescriptor(Operation[].class), null, null);    CodeVisitor clinit = skel.visitMethod      (C.ACC_STATIC, "<clinit>",       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);    fillOperationArray(clinit);    clinit.visitInsn(C.RETURN);    clinit.visitMaxs(-1, -1);    // no arg public constructor    CodeVisitor init = skel.visitMethod      (C.ACC_PUBLIC, "<init>",       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);    init.visitVarInsn(C.ALOAD, 0);    init.visitMethodInsn      (C.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>",       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));    init.visitInsn(C.RETURN);    init.visitMaxs(-1, -1);    /*     * public Operation[] getOperations()     * returns a clone of the operations array     */    CodeVisitor getOp = skel.visitMethod      (C.ACC_PUBLIC, "getOperations",       Type.getMethodDescriptor       (Type.getType(Operation[].class), new Type[] {}),       null, null);    getOp.visitFieldInsn      (C.GETSTATIC, classInternalName, "operations",       Type.getDescriptor(Operation[].class));    getOp.visitMethodInsn      (C.INVOKEVIRTUAL, Type.getInternalName(Object.class),       "clone", Type.getMethodDescriptor(Type.getType(Object.class),                                         new Type[] {}));    getOp.visitTypeInsn(C.CHECKCAST, typeArg(Operation[].class));    getOp.visitInsn(C.ARETURN);    getOp.visitMaxs(-1, -1);    // public void dispatch(Remote, RemoteCall, int opnum, long hash)    CodeVisitor dispatch = skel.visitMethod      (C.ACC_PUBLIC,       "dispatch",       Type.getMethodDescriptor       (Type.VOID_TYPE,        new Type[] { Type.getType(Remote.class),                     Type.getType(RemoteCall.class),                     Type.INT_TYPE, Type.LONG_TYPE }),       new String[] { Type.getInternalName(Exception.class) },       null);    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(C.ILOAD, var.get("opnum"));    Label nonNegativeOpnum = new Label();    Label opnumSet = new Label();    dispatch.visitJumpInsn(C.IFGE, nonNegativeOpnum);    for (int i = 0; i < remotemethods.length; i++)      {        // assign opnum if hash matches supplied hash        dispatch.visitVarInsn(C.LLOAD, var.get("hash"));        dispatch.visitLdcInsn(new Long(remotemethods[i].hash));        Label notIt = new Label();        dispatch.visitInsn(C.LCMP);        dispatch.visitJumpInsn(C.IFNE, notIt);        // opnum = <opnum>        dispatch.visitLdcInsn(new Integer(i));        dispatch.visitVarInsn(C.ISTORE, var.get("opnum"));        dispatch.visitJumpInsn(C.GOTO, opnumSet);        dispatch.visitLabel(notIt);      }    // throw new SkeletonMismatchException    Label mismatch = new Label();    dispatch.visitJumpInsn(C.GOTO, mismatch);    dispatch.visitLabel(nonNegativeOpnum);    // if opnum is already set, check that the hash matches the interface    dispatch.visitVarInsn(C.LLOAD, var.get("hash"));    dispatch.visitFieldInsn      (C.GETSTATIC, classInternalName,       "interfaceHash", Type.LONG_TYPE.getDescriptor());    dispatch.visitInsn(C.LCMP);    dispatch.visitJumpInsn(C.IFEQ, opnumSet);    dispatch.visitLabel(mismatch);

⌨️ 快捷键说明

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