Changeset 2273


Ignore:
Timestamp:
Jan 22, 2007, 7:45:22 PM (14 years ago)
Author:
yura
Message:

For methods with Int, String and Object (except arrays) in argument and result ClassWrap? must work.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • to-imperative/trunk/java/org/refal/plus/wrapgen/WrapGen.java

    r2268 r2273  
    99import org.objectweb.asm.MethodVisitor;
    1010import org.objectweb.asm.Opcodes;
     11import org.objectweb.asm.Type;
    1112
    12 public class WrapGen extends ClassAdapter {
    13         public String name;
     13public class WrapGen extends ClassAdapter
     14{
     15        Type oldType;
     16        String oldName;
     17        String newName;
    1418
    15         public WrapGen (ClassVisitor cv) {
     19        public WrapGen (ClassVisitor cv)
     20        {
    1621                super(cv);
    1722        }
    1823       
    19         public void visit (int version, int access, String name, String signature, String superName, String[] interfaces) {
    20                 this.name = "org/refal/plus/javawrap/"+name;
    21                 super.visit(version, access, this.name, signature, name, null);
     24        public void visit (int version, int access, String name, String signature, String superName, String[] interfaces)
     25        {
     26                this.oldName = name;
     27                this.oldType = Type.getType("L"+name+";");
     28                this.newName = "org/refal/plus/javawrap/"+this.oldName;
     29                super.visit(version, access, this.newName, signature, this.oldName, null);
    2230        }
    23 
    24         public void visitSource (String file, String debug) {
     31       
     32        public void visitSource (String file, String debug)
     33        {
    2534                super.visitSource(null, null);
    2635        }
    2736
    28         public FieldVisitor visitField (int access, String name, String desc, String signature, Object value) {
     37        public FieldVisitor visitField (int access, String name, String desc, String signature, Object value)
     38        {
    2939                return null;
    3040        }
    3141       
    32         public MethodVisitor visitMethod (int access, String name, String desc, String signature, String[] exceptions) {
     42        public MethodVisitor visitMethod (int access, String name, String desc, String signature, String[] exceptions)
     43        {
    3344                if ((access & Opcodes.ACC_PUBLIC)==0)
    3445                        return null;
    35                 MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, name, desc, signature, new String[] {"org/refal/plus/RefalException"});
     46                Type[] argTypes = Type.getArgumentTypes(desc);
     47                Type retType = Type.getReturnType(desc);
     48               
     49                boolean isStatic = (access&Opcodes.ACC_STATIC)!=0;
     50                boolean isVoid = retType==Type.VOID_TYPE;
     51               
     52                int newArgs = (isStatic?0:1)+argTypes.length+(isVoid?0:1);
     53                Type[] newArgTypes = new Type[newArgs];
     54                {
     55                        int i;
     56                        for (i = 0; i < (isStatic?0:1)+argTypes.length; i++)
     57                                newArgTypes[i] = Type.getType("Lorg/refal/plus/Expr;");
     58                        if (! isVoid)
     59                                newArgTypes[i] = Type.getType("Lorg/refal/plus/Result;");
     60                }
     61                String newDesc = Type.getMethodDescriptor(Type.VOID_TYPE, newArgTypes);
     62                MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, name, newDesc, signature, new String[] {"org/refal/plus/RefalException"});
     63               
    3664                mv.visitCode();
    37                 mv.visitInsn(Opcodes.ACONST_NULL);
    38                 mv.visitInsn(Opcodes.ARETURN);
     65                if (! isVoid)
     66                        mv.visitVarInsn(Opcodes.ALOAD, (isStatic?0:1)+argTypes.length);
     67
     68                if (! isStatic)
     69                {
     70                        mv.visitVarInsn(Opcodes.ALOAD, 0);
     71                        putArgToStack(mv, this.oldType);
     72                }
     73                for (int i = 0; i < argTypes.length; i++)
     74                {
     75                        mv.visitVarInsn(Opcodes.ALOAD, (isStatic?0:1)+i);
     76                        putArgToStack(mv, argTypes[i]);
     77                }
     78                mv.visitMethodInsn(isStatic?Opcodes.INVOKESTATIC:Opcodes.INVOKEVIRTUAL, this.oldName, name, desc);
     79               
     80                if (! isVoid)
     81                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Result", "assign", "(Ljava/lang/Object;)V");
     82                mv.visitInsn(Opcodes.RETURN);
     83
    3984                mv.visitMaxs(0,0);
    4085                mv.visitEnd();         
    4186                return null;
    4287        }
     88       
     89        void putArgToStack (MethodVisitor mv, Type type)
     90        {
     91                if (type.equals(Type.INT_TYPE))
     92                {
     93                        mv.visitInsn(Opcodes.ICONST_0);
     94                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Expr", "at", "(I)Ljava/lang/Object;");
     95                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
     96                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "intValue", "()I");
     97                }
     98                else if (type.equals(Type.getType("Ljava/lang/String;")))
     99                {
     100                        mv.visitInsn(Opcodes.ICONST_0);
     101                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Expr", "at", "(I)Ljava/lang/Object;");
     102                        mv.visitTypeInsn(Opcodes.CHECKCAST, "org/refal/plus/Word");
     103                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Word", "toString", "()Ljava/lang/String;");
     104                }
     105                else if (type.getSort() == Type.ARRAY)
     106                {
     107                        mv.visitInsn(Opcodes.POP);
     108                        mv.visitInsn(Opcodes.ACONST_NULL);
     109                }
     110                else
     111                {
     112                        mv.visitInsn(Opcodes.ICONST_0);
     113                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Expr", "at", "(I)Ljava/lang/Object;");
     114                        mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
     115                }
     116        }
    43117
    44         public static void main(String[] args) throws Exception {
     118        public static void main(String[] args) throws Exception
     119        {
    45120                String in = args[0];
    46121                FileInputStream ins = new FileInputStream(in);
     
    49124                WrapGen wg = new WrapGen(cw);
    50125                cr.accept(wg, 0);
    51                 FileOutputStream outs = new FileOutputStream(wg.name.replaceFirst(".*/", "")+".class");
     126                FileOutputStream outs = new FileOutputStream(wg.newName.replaceFirst(".*/", "")+".class");
    52127                outs.write(cw.toByteArray());
    53128        }
Note: See TracChangeset for help on using the changeset viewer.