Changeset 2292


Ignore:
Timestamp:
Jan 26, 2007, 8:57:25 PM (14 years ago)
Author:
yura
Message:
  • valueOf(String) in Word class
  • class RFIFile for reading/writing rfi-files from Java
  • arguments/result of primitive data and arrays are supported.
Location:
to-imperative/trunk/java/org/refal/plus
Files:
1 added
2 edited

Legend:

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

    r2284 r2292  
    5959    public boolean boolValue()
    6060    {
    61                 return Boolean.parseBoolean(str);
    62         }
     61        return Boolean.parseBoolean(str);
     62    }
    6363
    64         public static Word valueOf(boolean b)
    65         {
    66                 String s = Boolean.toString(b);
    67                 return new Word(Character.toUpperCase(s.charAt(0)) + s.substring(1));
    68         }
     64    public static Word valueOf(boolean b)
     65    {
     66        String s = Boolean.toString(b);
     67        return new Word(Character.toUpperCase(s.charAt(0)) + s.substring(1));
     68    }
     69
     70    public static Word valueOf(String s)
     71    {
     72        return new Word(s);
     73    }
    6974}
  • to-imperative/trunk/java/org/refal/plus/wrapgen/WrapGen.java

    r2289 r2292  
    1414import org.objectweb.asm.Type;
    1515
     16import org.refal.plus.wrapgen.RFIFile;
     17
    1618public class WrapGen extends ClassAdapter
    1719{
    18         Type oldType;
    19         String oldName;
    20         String newName;
    21         public String rfi;
    22 
    23         public WrapGen (ClassVisitor cv)
    24         {
     20        static final int S = 0;
     21        static final int E = 1;
     22        static final int Void = -1;
     23
     24        private Type oldType;
     25        private String oldName;
     26        private String newName;
     27        private RFIFile rfiFile;
     28
     29        public WrapGen (ClassVisitor cv) {
    2530                super(cv);
    2631        }
    27        
    28         public static Integer TEST3 (int[] x)
    29         {
    30                 int res = 0;
    31                 for(int i = 0; i < x.length; i++)
    32                         res += x[i];
    33                 return new Integer(res);
    34         }
    35 
    36         public String TEST1 (String[][] x)
    37         {
    38                 return "";
    39         }
    40        
    41         public String[] TEST2 (String[][] x)
    42         {
    43                 return null;
    44         }
    45 
    46         public void visit (int version, int access, String name, String signature, String superName, String[] interfaces)
    47         {
     32
     33        public void visit (int version, int access, String name, String signature, String superName, String[] interfaces) {
    4834                this.oldName = name;
    4935                this.oldType = Type.getType("L"+name+";");
    5036                this.newName = "org/refal/plus/wrappers/"+this.oldName;
    51                 this.rfi = "";
     37
     38                (new File(this.newName.substring(0, this.newName.lastIndexOf('/')))).mkdirs();
     39                this.rfiFile = new RFIFile(this.newName+".rfi");
     40
    5241                super.visit(version, access, this.newName, signature, this.oldName, null);
    5342        }
    54        
    55         public void visitSource (String file, String debug)
    56         {
     43
     44        public void visitSource (String file, String debug) {
    5745                super.visitSource(null, null);
    5846        }
    5947
    60         public FieldVisitor visitField (int access, String name, String desc, String signature, Object value)
    61         {
     48        public FieldVisitor visitField (int access, String name, String desc, String signature, Object value) {
    6249                return null;
    6350        }
    64        
    65         public MethodVisitor visitMethod (int access, String name, String desc, String signature, String[] exceptions)
    66         {
     51
     52        public MethodVisitor visitMethod (int access, String name, String desc, String signature, String[] exceptions) {
    6753                if ((access & Opcodes.ACC_PUBLIC)==0 || name.equals("<init>"))
    6854                        return null;
     55
     56                Type retType = Type.getReturnType(desc);
    6957                Type[] argTypes = Type.getArgumentTypes(desc);
    70                 Type retType = Type.getReturnType(desc);
    71                
    7258                boolean isStatic = (access&Opcodes.ACC_STATIC)!=0;
    7359                boolean isVoid = retType==Type.VOID_TYPE;
    74                
    75                 int newArgs = (isStatic?0:1)+argTypes.length+(isVoid?0:1);
    76                 Type[] newArgTypes = new Type[newArgs];
    77                 {
    78                         int i;
    79                         for (i = 0; i < (isStatic?0:1)+argTypes.length; i++)
    80                                 newArgTypes[i] = Type.getType("Lorg/refal/plus/Expr;");
    81                         if (! isVoid)
    82                                 newArgTypes[i] = Type.getType("Lorg/refal/plus/Result;");
    83                 }
     60
     61                RFIFile.RefalFunction refFun = this.rfiFile.getRefalFuncion(isStatic, name, retType, argTypes);
     62                if (refFun == null)
     63                        return null;
     64
     65                Type[] newArgTypes = new Type[refFun.argTypes.length+(isVoid?0:1)];
     66                for (int i = 0; i < refFun.argTypes.length; i++)
     67                        newArgTypes[i] = Type.getType("Lorg/refal/plus/Expr;");
     68                if (! isVoid)
     69                        newArgTypes[newArgTypes.length-1] = Type.getType("Lorg/refal/plus/Result;");
    8470                String newDesc = Type.getMethodDescriptor(Type.VOID_TYPE, newArgTypes);
    8571                MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, name, newDesc, signature, new String[] {"org/refal/plus/RefalException"});
    86                
     72
    8773                mv.visitCode();
     74                if (! isStatic)
     75                        putArgToStack(mv, this.oldType, refFun.argTypes[0], 0);
     76                for (int i = 0; i < argTypes.length; i++)
     77                        putArgToStack(mv, argTypes[i], refFun.argTypes[(isStatic?0:1)+i], (isStatic?0:1)+i);
     78                mv.visitMethodInsn(isStatic?Opcodes.INVOKESTATIC:Opcodes.INVOKEVIRTUAL, this.oldName, name, desc);
    8879                if (! isVoid)
    89                         mv.visitVarInsn(Opcodes.ALOAD, (isStatic?0:1)+argTypes.length);
    90                
    91                 this.rfi = this.rfi+"$func "+name;
    92                 if (! isStatic)
    93                         putArgToStack(mv, this.oldType, 0);
    94                 for (int i = 0; i < argTypes.length; i++)
    95                         putArgToStack(mv, argTypes[i], (isStatic?0:1)+i);
    96                 mv.visitMethodInsn(isStatic?Opcodes.INVOKESTATIC:Opcodes.INVOKEVIRTUAL, this.oldName, name, desc);
    97                
    98                 this.rfi = this.rfi+" = ";
    99                 if (! isVoid)
    100                         if (retType.getSort()==Type.ARRAY)
     80                        getResFromStack(mv, retType, refFun.retType, refFun.argTypes.length);
     81                mv.visitInsn(Opcodes.RETURN);
     82                mv.visitMaxs(0,0);
     83                mv.visitEnd();
     84
     85                return null;
     86        }
     87
     88        private void getResFromStack (MethodVisitor mv, Type type, int refType, int argNum) {
     89                mv.visitVarInsn(Opcodes.ALOAD, argNum);
     90                mv.visitInsn(Opcodes.SWAP);
     91                switch (refType) {
     92                case WrapGen.S:
     93                        convertFrom(mv, type);
     94                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Result", "assign", "(Ljava/lang/Object;)V");
     95                        break;
     96                //case WrapGen.E:
     97                //      mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Result", "assign", "([Ljava/lang/Object;)V");
     98                //      break;
     99                }
     100        }
     101
     102        private void convertFrom (MethodVisitor mv, Type type) {
     103                switch (type.getSort()) {
     104                case Type.BOOLEAN:
     105                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/refal/plus/Word", "valueOf", "(B)Lorg/refal/plus/Word;");
     106                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Object");
     107                        break;
     108                case Type.CHAR:
     109                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/math/Character", "charValue", "(C)Ljava/math/Character;");
     110                        break;
     111                case Type.INT:
     112                        mv.visitInsn(Opcodes.I2L);
     113                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/math/BigInteger", "valueOf", "(J)Ljava/math/BigInteger;");
     114                        break;
     115                case Type.LONG:
     116                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/math/BigInteger", "valueOf", "(J)Ljava/math/BigInteger;");
     117                        break;
     118                default:
     119                        if (type.equals(Type.getType("Ljava/lang/String;")))
    101120                        {
    102                                 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Result", "assign", "([Ljava/lang/Object;)V");
    103                                 this.rfi = this.rfi+"(e)";
     121                                mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/refal/plus/Word", "valueOf", "(Ljava/lang/String;)Lorg/refal/plus/Word;");
     122                                mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Object");
    104123                        }
    105124                        else
    106                         {
    107                                 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Result", "assign", "(Ljava/lang/Object;)V");
    108                                 this.rfi = this.rfi+"s";
    109                         }
    110                 this.rfi = this.rfi+"; // "+name+" "+desc+"\n";
    111                 mv.visitInsn(Opcodes.RETURN);
    112 
    113                 mv.visitMaxs(0,0);
    114                 mv.visitEnd();         
    115                 return null;
    116         }
    117        
    118         void putArgToStack (MethodVisitor mv, Type type, int argNum)
    119         {
     125                                mv.visitTypeInsn(Opcodes.CHECKCAST, type.getSort()==Type.ARRAY?type.getDescriptor():type.getInternalName());
     126                        break;
     127                }
     128
     129        }
     130
     131        private void putArgToStack (MethodVisitor mv, Type type, int refType, int argNum) {
    120132                mv.visitVarInsn(Opcodes.ALOAD, argNum);
    121                 if (type.getSort()!=Type.ARRAY)
    122                 {
     133                switch (refType) {
     134                case WrapGen.S:
    123135                        mv.visitInsn(Opcodes.ICONST_0);
    124136                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Expr", "at", "(I)Ljava/lang/Object;");
    125                         this.rfi = this.rfi+" s";
    126                 }
    127                 else
    128                         this.rfi = this.rfi+" (e)";
    129                 convert(mv, type);
    130         }
    131 
    132         void convert (MethodVisitor mv, Type type)
    133         {
    134                 switch (type.getSort())
    135                 {
    136                 case Type.BOOLEAN:
    137                         mv.visitTypeInsn(Opcodes.CHECKCAST, "org/refal/plus/Word");
    138                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Word", "boolValue", "()B");
    139                         break;
    140                 case Type.CHAR:
    141                         mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Character");
    142                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
    143                         break;
    144                 case Type.BYTE:
    145                         mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
    146                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "byteValue", "()B");
    147                         break;
    148                 case Type.SHORT:
    149                         mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
    150                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "shortValue", "()S");
    151                         break;
    152                 case Type.INT:
    153                         mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
    154                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "intValue", "()I");
    155                         break;
    156                 case Type.LONG:
    157                         mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
    158                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "longValue", "()J");
    159                         break;
    160                 case Type.ARRAY:
    161                         boolean isOneDim = type.getDimensions()==1;
    162                         Type elemType = isOneDim?type.getElementType():Type.getType(type.getDescriptor().substring(1));
     137                        convertTo(mv, type);
     138                        break;
     139                case WrapGen.E:
     140                        Type elemType = Type.getType(type.getDescriptor().substring(1));
    163141                        Label l1 = new Label();
    164142                        Label l2 = new Label();
    165                         mv.visitTypeInsn(Opcodes.CHECKCAST, "org/refal/plus/Expr");
    166143                        mv.visitInsn(Opcodes.DUP);
    167144                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Expr", "getLen", "()I");
     
    169146                                mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_INT);
    170147                        else
    171                                 mv.visitTypeInsn(Opcodes.ANEWARRAY, isOneDim?elemType.getInternalName():elemType.getDescriptor());
     148                                mv.visitTypeInsn(Opcodes.ANEWARRAY, elemType.getSort()==Type.ARRAY?elemType.getDescriptor():elemType.getInternalName());
    172149                        mv.visitInsn(Opcodes.ICONST_0);
    173150                        mv.visitLabel(l1);
     
    184161                        mv.visitInsn(Opcodes.POP);
    185162                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Expr", "at", "(I)Ljava/lang/Object;");
    186                         convert(mv, elemType);
     163                        convertTo(mv, elemType);
    187164                        mv.visitInsn(elemType.getOpcode(Opcodes.IASTORE));
    188165                        mv.visitInsn(Opcodes.POP);
     
    194171                        mv.visitInsn(Opcodes.SWAP);
    195172                        mv.visitInsn(Opcodes.POP);
    196                         break;
    197                 case Type.OBJECT:
    198                         if (type.equals(Type.getType("Ljava/lang/String;")))
    199                         {
     173                }
     174        }
     175
     176        private void convertTo (MethodVisitor mv, Type type) {
     177                switch (type.getSort()) {
     178                case Type.BOOLEAN:
     179                        mv.visitTypeInsn(Opcodes.CHECKCAST, "org/refal/plus/Word");
     180                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Word", "boolValue", "()B");
     181                        break;
     182                case Type.BYTE:
     183                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
     184                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "byteValue", "()B");
     185                        break;
     186                case Type.CHAR:
     187                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Character");
     188                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
     189                        break;
     190                case Type.SHORT:
     191                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
     192                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "shortValue", "()S");
     193                        break;
     194                case Type.INT:
     195                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
     196                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "intValue", "()I");
     197                        break;
     198                case Type.LONG:
     199                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/math/BigInteger");
     200                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/math/BigInteger", "longValue", "()J");
     201                        break;
     202                default:
     203                        if (type.equals(Type.getType("Ljava/lang/String;"))) {
    200204                                mv.visitTypeInsn(Opcodes.CHECKCAST, "org/refal/plus/Word");
    201205                                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/refal/plus/Word", "toString", "()Ljava/lang/String;");
    202                         }
    203                         else
    204                                 mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
    205                         break;
    206                 }
     206                        }       else
     207                                mv.visitTypeInsn(Opcodes.CHECKCAST, type.getSort()==Type.ARRAY?type.getDescriptor():type.getInternalName());
     208                        break;
     209                }
     210        }
     211
     212        public static void main (String[] args) throws Exception {
     213                for (int i = 0; i < args.length; i++) {
     214                        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES+ClassWriter.COMPUTE_MAXS);
     215                        WrapGen wg = new WrapGen(cw);
     216                        (new ClassReader(new FileInputStream(args[i]))).accept(wg, 0);
     217                        (new FileOutputStream(wg.newName+".class")).write(cw.toByteArray());
     218                }
     219        }
     220
     221        public String TEST1 (String[][] x) {
     222                return "";
     223        }
     224
     225        public String[] TEST2 (int[][] x) {
     226                return null;
     227        }
     228
     229        public static Integer TEST3 (int[] x) {
     230                int res = 0;
     231                for(int i = 0; i < x.length; i++)
     232                        res += x[i];
     233                return new Integer(res);
     234        }
     235
     236        public static int TEST4 (int[] x) {
     237                int res = 0;
     238                for(int i = 0; i < x.length; i++)
     239                        res += x[i];
     240                return res;
    207241        }
    208242       
    209         public static void main(String[] args) throws Exception
    210         {
    211                 String in = args[0];
    212                 FileInputStream ins = new FileInputStream(in);
    213                 ClassReader cr = new ClassReader(ins);
    214                 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES+ClassWriter.COMPUTE_MAXS);
    215                 WrapGen wg = new WrapGen(cw);
    216                 cr.accept(wg, 0);
    217                 File dir = new File(wg.newName.substring(0, wg.newName.lastIndexOf('/')));
    218                 dir.mkdirs();
    219                 FileOutputStream outs1 = new FileOutputStream(wg.newName+".rfi");
    220                 outs1.write(wg.rfi.getBytes());
    221                 FileOutputStream outs2 = new FileOutputStream(wg.newName+".class");
    222                 outs2.write(cw.toByteArray());
     243        public static boolean TEST1 (boolean x) {
     244                return x;
     245        }
     246
     247        public static int TEST1 (int x) {
     248                return x;
    223249        }
    224250}
Note: See TracChangeset for help on using the changeset viewer.