Changeset 2296


Ignore:
Timestamp:
Jan 29, 2007, 6:29:44 PM (14 years ago)
Author:
yura
Message:

Static final fields and constructors are generated.

Location:
to-imperative/trunk/java/org/refal/plus/wrapgen
Files:
2 edited

Legend:

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

    r2293 r2296  
    5959                this.refalNames.add(name);
    6060                refFun.name = name;
    61                 refFun.retType = retType.getSort()==Type.ARRAY ? WrapGen.E : WrapGen.S;
     61                int x = retType.getSort();
     62                switch (x) {
     63                case Type.VOID: refFun.retType = WrapGen.Void; break;
     64                case Type.ARRAY: refFun.retType = WrapGen.E; break;
     65                default: refFun.retType = WrapGen.S; break;
     66                }
    6267                refFun.argTypes = new int[(isStatic?0:1)+argTypes.length];
    63                 if (isStatic)
     68                if (! isStatic)
    6469                        refFun.argTypes[0] = WrapGen.S;
    6570                for (int i = 0; i < argTypes.length; i++)
     
    7378                String str = new String(file, 0, z);
    7479                while (str.length() != 0) {
    75                         int i = str.indexOf("$func");
    76                         if (i == -1)
     80                        int i1 = str.indexOf("$func");
     81                        int i2 = str.indexOf("$const");
     82                        if ((i1<i2 || i2==-1) && i1!=-1) {
     83                                int i = i1;
     84                                for (i += 5; ;i++)
     85                                        if (str.charAt(i)!=' ')
     86                                                break;
     87                                int j;
     88                                String name;
     89                                if (str.charAt(i)=='\"')
     90                                {
     91                                        j = str.indexOf('\"', i+1);
     92                                        name = str.substring(i+1,j);
     93                                        j++;                           
     94                                }
     95                                else
     96                                {
     97                                        j = str.indexOf(' ', i+1);
     98                                        name = str.substring(i,j);
     99                                }
     100                                int[] argTypes = new int[1024];
     101                                int retType = 0;
     102                                int l = 0;
     103                                boolean flag = true;
     104                                for (;flag;j++) {
     105                                        switch (str.charAt(j)) {
     106                                        case 'e': argTypes[l] = WrapGen.E; l++; break;
     107                                        case 's': argTypes[l] = WrapGen.S; l++; break;
     108                                        case '=': flag = false; break;
     109                                        default: break;
     110                                        }
     111                                }
     112                                flag = true;
     113                                for (;flag;j++) {
     114                                        switch (str.charAt(j)) {
     115                                        case 'e': retType = WrapGen.E; flag = false; break;
     116                                        case 's': retType = WrapGen.S; flag = false; break;
     117                                        case ';': flag = false; break;
     118                                        default: break;
     119                                        }
     120                                }
     121                                int m = str.indexOf("//", j);
     122                                for (m += 2; str.charAt(m)==' ';m++);
     123                                int n = str.indexOf('\n', m);
     124                                String javaDesc = str.substring(m,n);
     125                                str = str.substring(n);
     126                               
     127                                RefalFunction refFun = new RefalFunction();
     128                                refFun.name = name;
     129                                refFun.retType = retType;
     130                                refFun.argTypes = new int[l];
     131                                for (int ii = 0; ii < l; ii++)
     132                                        refFun.argTypes[ii] = argTypes[ii];
     133                               
     134                                this.refalFunctions.put(javaDesc, refFun);
     135                        } else if (i2 != -1) {
     136                                int i = i2;
     137                                for (i += 6; ;i++)
     138                                        if (str.charAt(i)!=' ')
     139                                                break;
     140                                int j;
     141                                String name;
     142                                if (str.charAt(i)=='\"')
     143                                {
     144                                        j = str.indexOf('\"', i+1);
     145                                        name = str.substring(i+1,j);
     146                                        j++;                           
     147                                }
     148                                else
     149                                {
     150                                        j = str.indexOf(' ', i+1);
     151                                        name = str.substring(i,j);
     152                                }
     153                                int m = str.indexOf("//", j);
     154                                for (m += 2; str.charAt(m)==' ';m++);
     155                                int n = str.indexOf('\n', m);
     156                                String javaDesc = str.substring(m,n);
     157                                str = str.substring(n);
     158                               
     159                                this.refalFunctions.put(javaDesc, name);
     160                        } else
    77161                                break;
    78                         for (i += 5; ;i++)
    79                                 if (str.charAt(i)!=' ')
    80                                         break;
    81                         int j;
    82                         String name;
    83                         if (str.charAt(i)=='\"')
    84                         {
    85                                 j = str.indexOf('\"', i+1);
    86                                 name = str.substring(i+1,j);
    87                                 j++;                           
    88                         }
    89                         else
    90                         {
    91                                 j = str.indexOf(' ', i+1);
    92                                 name = str.substring(i,j);
    93                         }
    94                         int[] argTypes = new int[1024];
    95                         int retType = 0;
    96                         int l = 0;
    97                         boolean flag = true;
    98                         for (;flag;j++) {
    99                                 switch (str.charAt(j)) {
    100                                 case 'e': argTypes[l] = WrapGen.E; l++; break;
    101                                 case 's': argTypes[l] = WrapGen.S; l++; break;
    102                                 case '=': flag = false; break;
    103                                 default: break;
    104                                 }
    105                         }
    106                         flag = true;
    107                         for (;flag;j++) {
    108                                 switch (str.charAt(j)) {
    109                                 case 'e': retType = WrapGen.E; flag = false; break;
    110                                 case 's': retType = WrapGen.S; flag = false; break;
    111                                 case ';': flag = false; break;
    112                                 default: break;
    113                                 }
    114                         }
    115                         int m = str.indexOf("//", j);
    116                         for (m += 2; str.charAt(m)==' ';m++);
    117                         int n = str.indexOf('\n', m);
    118                         String javaDesc = str.substring(m,n);
    119                         str = str.substring(n);
    120                        
    121                         RefalFunction refFun = new RefalFunction();
    122                         refFun.name = name;
    123                         refFun.retType = retType;
    124                         refFun.argTypes = new int[l];
    125                         for (int ii = 0; ii < l; ii++)
    126                                 refFun.argTypes[ii] = argTypes[ii];
    127                        
    128                         this.refalFunctions.put(javaDesc, refFun);
    129162                }
    130163        }
     
    161194                }
    162195        }
     196       
     197        String getRefalConst (String name, int value) {
     198                String name1 = "int "+name;
     199                try {
     200                        if (out != null) {
     201                                if (this.refalNames.indexOf(name)!=-1)
     202                                        for(int i = 1; ; i++)
     203                                                if (this.refalNames.indexOf(name+i)==-1)
     204                                                {
     205                                                        name = name+i;
     206                                                        break;
     207                                                }
     208                                this.refalNames.add(name1);
     209                                out.write(("$const \""+name+"\" = "+value+"; // "+name1+"\n").getBytes());
     210                        } else {
     211                                return (String)this.refalFunctions.get(name1);
     212                        }
     213                } catch (Exception e) {
     214                        return null;
     215                }
     216                return name;
     217        }
    163218}
  • to-imperative/trunk/java/org/refal/plus/wrapgen/WrapGen.java

    r2294 r2296  
    44import java.io.FileInputStream;
    55import java.io.FileOutputStream;
     6import java.math.BigInteger;
     7import java.util.HashMap;
     8import java.util.Iterator;
    69
    710import org.objectweb.asm.ClassAdapter;
     
    1720public class WrapGen extends ClassAdapter
    1821{
    19         static final int S = 0;
    20         static final int E = 1;
    21         static final int Void = -1;
     22        public static final BigInteger S1 = BigInteger.valueOf(1);
     23        public static final int S = 0;
     24        public static final int E = 1;
     25        public static final int Void = -1;
    2226
    2327        private Type oldType;
     
    2529        private String newName;
    2630        private RFIFile rfiFile;
     31        private HashMap constants;
     32        private boolean isInterface;
    2733
    2834        public WrapGen (ClassVisitor cv) {
    2935                super(cv);
     36                constants = new HashMap();
    3037        }
    3138
     
    3441                this.oldType = Type.getType("L"+name+";");
    3542                this.newName = "org/refal/plus/wrappers/"+this.oldName;
     43                this.isInterface = (access&Opcodes.ACC_INTERFACE)!=0;
    3644
    3745                (new File(this.newName.substring(0, this.newName.lastIndexOf('/')))).mkdirs();
     
    4654
    4755        public FieldVisitor visitField (int access, String name, String desc, String signature, Object value) {
     56                if ((access & Opcodes.ACC_PUBLIC)==0 || (access & Opcodes.ACC_STATIC)==0 || !desc.equals("I"))
     57                        return null;
     58                String refConst = this.rfiFile.getRefalConst(name, ((Integer)value).intValue());
     59                if (refConst != null) {
     60                        super.visitField(access, refConst, "Ljava/math/BigInteger;", signature, null);
     61                        constants.put(refConst, value);
     62                }
    4863                return null;
    4964        }
    5065
    5166        public MethodVisitor visitMethod (int access, String name, String desc, String signature, String[] exceptions) {
    52                 if ((access & Opcodes.ACC_PUBLIC)==0 || name.equals("<init>"))
     67                if ((access & Opcodes.ACC_PUBLIC)==0)
    5368                        return null;
    5469
    5570                Type retType = Type.getReturnType(desc);
    5671                Type[] argTypes = Type.getArgumentTypes(desc);
    57                 boolean isStatic = (access&Opcodes.ACC_STATIC)!=0;
     72                boolean isConstructor = name.equals("<init>");
     73                boolean isStatic = (access & Opcodes.ACC_STATIC)!=0;
    5874                boolean isVoid = retType==Type.VOID_TYPE;
    5975
    60                 RFIFile.RefalFunction refFun = this.rfiFile.getRefalFuncion(isStatic, name, retType, argTypes);
     76                RFIFile.RefalFunction refFun;
     77                if (isConstructor)
     78                {
     79                        retType = this.oldType;
     80                        isStatic = true;
     81                        isVoid = false;
     82                        refFun = this.rfiFile.getRefalFuncion(isStatic, this.oldName.replaceAll(".*/", ""), retType, argTypes);
     83                }
     84                else
     85                        refFun = this.rfiFile.getRefalFuncion(isStatic, name, retType, argTypes);
    6186                if (refFun == null)
    6287                        return null;
     
    7196
    7297                mv.visitCode();
    73                 if (! isStatic)
     98                if (isConstructor) {
     99                        mv.visitTypeInsn(Opcodes.NEW, this.oldName);
     100                        mv.visitInsn(Opcodes.DUP);
     101                } else if (! isStatic)
    74102                        putArgToStack(mv, this.oldType, refFun.argTypes[0], 0);
    75103                for (int i = 0; i < argTypes.length; i++)
    76104                        putArgToStack(mv, argTypes[i], refFun.argTypes[(isStatic?0:1)+i], (isStatic?0:1)+i);
    77                 mv.visitMethodInsn(isStatic?Opcodes.INVOKESTATIC:Opcodes.INVOKEVIRTUAL, this.oldName, name, desc);
     105                mv.visitMethodInsn(isConstructor?Opcodes.INVOKESPECIAL:(isStatic?Opcodes.INVOKESTATIC:(this.isInterface?Opcodes.INVOKEINTERFACE:Opcodes.INVOKEVIRTUAL)), this.oldName, name, desc);
    78106                if (! isVoid)
    79107                        getResFromStack(mv, retType, refFun.retType, refFun.argTypes.length);
     
    83111
    84112                return null;
     113        }
     114
     115        public void visitEnd() {
     116                MethodVisitor mv = super.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
     117                Iterator it = constants.keySet().iterator();
     118                mv.visitCode();
     119                while (it.hasNext()) {
     120                        String name = (String)it.next();
     121                        mv.visitTypeInsn(Opcodes.NEW, "org/refal/plus/Expr");
     122                        mv.visitInsn(Opcodes.DUP);
     123                        mv.visitLdcInsn(constants.get(name));
     124                        mv.visitInsn(Opcodes.I2L);
     125                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/math/BigInteger", "valueOf", "(J)Ljava/math/BigInteger;");
     126                        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Object"); // TODO: It is not needed.
     127                        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/refal/plus/Expr", "<init>", "(Ljava/lang/Object;)V");
     128                        mv.visitFieldInsn(Opcodes.PUTSTATIC, this.newName, name, "Lorg/refal/plus/Expr;");
     129                }
     130                mv.visitInsn(Opcodes.RETURN);
     131                mv.visitMaxs(0,0);
     132                mv.visitEnd();
     133
     134                super.visitEnd();
    85135        }
    86136
Note: See TracChangeset for help on using the changeset viewer.