Initialize class objects first as in the staic blocks there might be references to...
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index e5179e6229709c1e7a58861ab19f5e0d85f34016..11e4b0ccde09b118164e000aa26cef623bdeb786 100644 (file)
@@ -331,23 +331,57 @@ public class BuildCode {
     // execute all the static blocks and all the static field initializations
     SymbolTable sctbl = this.state.getSClassSymbolTable();
     Iterator it_sclasses = sctbl.getDescriptorsIterator();
-    if(it_sclasses.hasNext()) {
-      while(it_sclasses.hasNext()) {
-        ClassDescriptor t_cd = (ClassDescriptor)it_sclasses.next();
-        MethodDescriptor t_md = (MethodDescriptor)t_cd.getMethodTable().get("staticblocks");
-
-        if(t_md != null&&callgraph.isInit(t_cd)) {
-          outmethod.println("   {");
-          if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) {
-            outmethod.print("       struct "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
-            outmethod.println("0, NULL};");
-            outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
-          } else {
-            outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
-          }
-          outmethod.println("   }");
-        }
-      }
+    Vector<ClassDescriptor> tooutput = new Vector<ClassDescriptor>();
+    Queue<ClassDescriptor> toprocess=new LinkedList<ClassDescriptor>();
+    Vector<ClassDescriptor> outputs = new Vector<ClassDescriptor>();
+    while(it_sclasses.hasNext()) {
+       ClassDescriptor t_cd = (ClassDescriptor)it_sclasses.next();
+       if(!outputs.contains(t_cd)) {
+           tooutput.clear();
+           tooutput.add(t_cd);
+           toprocess.clear();
+           toprocess.add(t_cd);
+           while(!toprocess.isEmpty()) {
+               ClassDescriptor pcd = toprocess.poll();
+               // check super interfaces
+               Iterator it_sinterfaces = pcd.getSuperInterfaces();
+               while(it_sinterfaces.hasNext()) {
+                   ClassDescriptor sint = (ClassDescriptor)it_sinterfaces.next();
+                   if(!outputs.contains(sint)) {
+                       toprocess.add(sint);
+                       if(sctbl.contains(sint.getClassName())) {
+                           tooutput.add(sint);
+                       }
+                   }
+               }
+               // check super classes
+               ClassDescriptor supercd = pcd.getSuperDesc();
+               if(supercd!=null && !outputs.contains(supercd)) {
+                   toprocess.add(supercd);
+                   if(sctbl.contains(supercd.getClassName())) {
+                       tooutput.add(supercd);
+                   }
+               }
+           }
+           
+           for(int i = tooutput.size()-1; i>=0; i--) {
+               ClassDescriptor output = tooutput.elementAt(i);
+               MethodDescriptor t_md = (MethodDescriptor)output.getMethodTable().get("staticblocks");
+
+               if(t_md != null&&callgraph.isInit(output)) {
+                   outmethod.println("   {");
+                   if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) {
+                       outmethod.print("       struct "+output.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
+                       outmethod.println("0, NULL};");
+                       outmethod.println("     "+output.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
+                   } else {
+                       outmethod.println("     "+output.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
+                   }
+                   outmethod.println("   }");
+               }
+               outputs.add(output);
+           }
+       }
     }
   }
 
@@ -394,9 +428,8 @@ public class BuildCode {
       outmethod.println("    ((struct garbagelist *)global_defs_p)->array[i]=NULL;");
       outmethod.println("  }");
     }
-    outputStaticBlocks(outmethod);
     outputClassObjects(outmethod);
-
+    outputStaticBlocks(outmethod);
 
     additionalCodeAtTopOfMain(outmethod);
     for(BuildCodeExtension bcx: extensions) {
@@ -537,7 +570,7 @@ public class BuildCode {
     if (state.main!=null) {
       outmethod.println("#include <string.h>");
     }
-    if (state.SSJAVA){
+    if (state.SSJAVA_GENCODE_PREVENT_CRASHES){
       outmethod.println("#include <stdio.h>");
     }
     if (state.CONSCHECK) {
@@ -2769,7 +2802,7 @@ fldloop:
         }
       }
       // redirect to the global_defs_p structure
-      if(state.SSJAVA){
+      if(state.SSJAVA_GENCODE_PREVENT_CRASHES){
         if (ffn.getField().getType().isPtr()){
           output.println("if ( global_defs_p == NULL) {");
           output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
@@ -2794,7 +2827,7 @@ fldloop:
     } else if (ffn.getField().isEnum()) {
       // an Enum value, directly replace the field access as int
       output.println(generateTemp(fm, ffn.getDst()) + "=" + ffn.getField().enumValue() + ";");
-    } else if(state.SSJAVA){
+    } else if(state.SSJAVA_GENCODE_PREVENT_CRASHES){
       output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {");
       output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
       if(ffn.getDst().getType().isPrimitive()){
@@ -2805,7 +2838,22 @@ fldloop:
       output.println("}else{");
       output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
       output.println("}");
-    }else {
+    }else if (ffn.getField().getSymbol().equals("this")) {
+       // an inner class refers to itself
+       if( state.CAPTURE_NULL_DEREFERENCES ) {
+           output.println("#ifdef CAPTURE_NULL_DEREFERENCES");
+           output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {");
+           output.println("printf(\" NULL ptr error: %s, %s, %d \\n\", __FILE__, __func__, __LINE__);");
+           if(state.MULTICOREGC||state.PMC) {
+               output.println("failednullptr(&___locals___);");
+           } else {
+               output.println("failednullptr(NULL);");
+           }
+           output.println("}");
+           output.println("#endif //CAPTURE_NULL_DEREFERENCES");
+       }
+       output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+";");
+    } else {
       if( state.CAPTURE_NULL_DEREFERENCES ) {
         output.println("#ifdef CAPTURE_NULL_DEREFERENCES");
         output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {");
@@ -2868,7 +2916,7 @@ fldloop:
         }
       }
       // redirect to the global_defs_p structure
-      if(state.SSJAVA){
+      if(state.SSJAVA_GENCODE_PREVENT_CRASHES){
         if (fsfn.getField().getType().isPtr()) {
           output.println("if ( global_defs_p == NULL) {");
           output.println("printf(\"SSJAVA: Discard a write due to dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
@@ -2901,7 +2949,7 @@ fldloop:
           output.println("global_defsprim_p->" +
                          fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
       }
-    } else if(state.SSJAVA){
+    } else if(state.SSJAVA_GENCODE_PREVENT_CRASHES){
       output.println("if (" + generateTemp(fm,fsfn.getDst()) + " == NULL) {");
       output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
       output.println("}else{");
@@ -2947,7 +2995,7 @@ fldloop:
     else
       type=elementtype.getSafeSymbol()+" ";
     
-    if(state.SSJAVA){
+    if(state.SSJAVA_GENCODE_PREVENT_CRASHES){
       output.println("if (" + generateTemp(fm,fen.getSrc())  + " == NULL) {");
       output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
       output.println("}else{");
@@ -2987,7 +3035,7 @@ fldloop:
     else
       type=elementtype.getSafeSymbol()+" ";
     
-    if(state.SSJAVA){
+    if(state.SSJAVA_GENCODE_PREVENT_CRASHES){
       output.println("if ("+generateTemp(fm,fsen.getDst())+"==NULL){");
       output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
       output.println("}else{");
@@ -3064,7 +3112,7 @@ fldloop:
           output.println(generateTemp(fm, fon.getDest())+" = ((unsigned int)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";");
 
       } else {
-        if(state.SSJAVA && fon.getOp().getOp()==Operation.DIV){
+        if(state.SSJAVA_GENCODE_PREVENT_CRASHES && fon.getOp().getOp()==Operation.DIV){
           output.println("if (unlikely("+generateTemp(fm,fon.getRight())+"==0)){");
           output.println("printf(\"SSJAVA: Divided by zero at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);");
           output.println(generateTemp(fm, fon.getDest())+" = 0;");