changes and data/eval files for new evaluations
[IRC.git] / Robust / src / IR / Flat / BCXSSJavaInjectError.java
1 package IR.Flat;
2
3 import IR.*;
4 import IR.Tree.*;
5
6 import java.util.*;
7 import java.io.*;
8
9 import Util.*;
10
11 public class BCXSSJavaInjectError implements BuildCodeExtension {
12
13   private State state;
14   private BuildCode buildCode;
15   private String nStr = "__ssjava_inv_error_prob__";
16   private String errorInjectedStr = "__ssjava_error_has_been_injected__";
17   private String errorInjectionStarted = "__ssjava_error_injection_started__";
18   private boolean agg = false;
19
20   public BCXSSJavaInjectError(State state, BuildCode buildCode) {
21     this.state = state;
22     this.buildCode = buildCode;
23   }
24
25   public void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
26     outmethod.println("#include <stdlib.h>");
27     outmethod.println("#include <stdio.h>");
28   }
29
30   // the reason for errorInjectionInit is that some code (like static
31   // initializers
32   // in the compiled program) actually run before the GENERATED MAIN runs! Not
33   // the
34   // complied program's main, either! So just rig it so no error injection code
35   // runs
36   // until we're sure the random seed is initialized.
37
38   public void additionalCodeGen(PrintWriter outmethodheader, PrintWriter outstructs,
39       PrintWriter outmethod) {
40     outmethodheader.println("extern int " + nStr + ";");
41     outmethodheader.println("extern int " + errorInjectedStr + ";");
42     outmethodheader.println("extern int errorInjectionInit;");
43     outmethodheader.println("extern int " + errorInjectionStarted + ";");
44     outmethodheader.println("extern int errorInjectionMax;");
45
46     outmethod.println("int " + nStr + " = " + state.SSJAVA_INV_ERROR_PROB + ";");
47     outmethod.println("int " + errorInjectedStr + " = 0;");
48     outmethod.println("int " + errorInjectionStarted + " = 0;");
49     outmethod.println("int errorInjectionMax = 1;");
50     outmethod.println("int errorInjectionInit = 0;");
51   }
52
53   public void additionalCodeAtTopOfMain(PrintWriter outmethod) {
54     outmethod.println("  srand(" + state.SSJAVA_ERROR_SEED + ");");
55     outmethod.println("  errorInjectionInit = 1;");
56   }
57
58   public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
59   }
60
61   public void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
62
63     TempDescriptor injectTarget = null;
64     FieldDescriptor injectField = null;
65
66     if ((!state.getAnnotationRequireSet().contains(fm.getMethod()))) {
67       return;
68     }
69
70     if (fm.getMethod().getClassDesc().getClassName().equals("String")) {
71       return;
72     }
73
74     switch (fn.kind()) {
75     case FKind.FlatOpNode:
76       FlatOpNode fon = (FlatOpNode) fn;
77       injectTarget = fon.getDest();
78
79       int op = fon.getOp().getOp();
80       if (injectTarget.getType().isPrimitive()
81           && (op == Operation.DIV || (agg && (op == Operation.ADD || op == Operation.SUB
82               || op == Operation.MULT || op == Operation.MOD || op == Operation.LOGIC_AND
83               || op == Operation.LOGIC_OR || op == Operation.LOGIC_NOT || op == Operation.NOTEQUAL
84               || op == Operation.BIT_AND || op == Operation.BIT_OR || op == Operation.BIT_XOR/*|| op == Operation.EQUAL*/)))) {
85         // inject a random value
86         initializeInjection(output);
87         output.println("    " + buildCode.generateTemp(fm, injectTarget) + " = ("
88             + injectTarget.getType().getSafeSymbol() + ") rand();");
89         closingInjection(output);
90       }
91       break;
92
93     // case FKind.FlatFieldNode:
94     // injectTarget = ((FlatFieldNode) fn).getDst();
95     // break;
96     //
97     // case FKind.FlatElementNode:
98     // injectTarget = ((FlatElementNode) fn).getDst();
99     // break;
100
101     case FKind.FlatSetFieldNode:
102       FlatSetFieldNode fsn = (FlatSetFieldNode) fn;
103       injectTarget = fsn.getDst();
104       injectField = fsn.getField();
105
106       if (injectTarget != null && injectField != null && injectField.getType().isPrimitive()
107           && !injectTarget.getType().isArray() && !injectField.isStatic()) {
108         initializeInjection(output);
109         // inject a random value
110         output.println("    " + buildCode.generateTemp(fm, injectTarget) + "->"
111             + injectField.getSafeSymbol() + " = (" + injectField.getType().getSafeSymbol()
112             + ") rand();");
113         closingInjection(output);
114
115       }
116
117       break;
118
119     case FKind.FlatSetElementNode:
120       FlatSetElementNode fsen = (FlatSetElementNode) fn;
121       injectTarget = fsen.getDst();
122
123       if (injectTarget != null && injectTarget.getType().isPrimitive()) {
124         initializeInjection(output);
125
126         String type;
127         TypeDescriptor elementtype = fsen.getDst().getType().dereference();
128         if (elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
129           type = "int ";
130         } else if (elementtype.isArray() || elementtype.isClass() || (elementtype.isNull()))
131           type = "void *";
132         else
133           type = elementtype.getSafeSymbol() + " ";
134
135         output.println("((" + type + "*)(((char *) &(" + buildCode.generateTemp(fm, injectTarget)
136             + "->___length___))+sizeof(int)))[" + buildCode.generateTemp(fm, fsen.getIndex())
137             + "] = (" + type + ") rand();");
138
139         closingInjection(output);
140       }
141       break;
142
143     }
144
145   }
146
147   private void initializeInjection(PrintWriter output) {
148     output.println("if( errorInjectionInit ) {");
149     output.println("  int roll = rand() % " + nStr + ";");
150     output.println("  if( ( " + errorInjectedStr + " && " + errorInjectionStarted
151         + " < errorInjectionMax ) || (!" + errorInjectedStr + " && roll == 0) ) {");
152     output.println("    " + errorInjectedStr + " = 1;");
153     output.println("    " + errorInjectionStarted + " += 1;");
154   }
155
156   private void closingInjection(PrintWriter output) {
157     output.println("    printf(\"SSJAVA: Injecting error at file:%s, func:%s, line:%d \\n\""
158         + ", __FILE__, __func__, __LINE__);");
159     output.println("  }");
160     output.println("}");
161   }
162
163   public void printExtraArrayFields(PrintWriter outclassdefs) {
164   }
165
166   public void outputTransCode(PrintWriter output) {
167   }
168
169   public void buildCodeSetup() {
170   }
171
172   public void generateSizeArrayExtensions(PrintWriter outclassdefs) {
173   }
174
175   public void preCodeGenInitialization() {
176   }
177
178   public void postCodeGenCleanUp() {
179   }
180
181   public void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
182   }
183
184   public void additionalIncludesStructsHeader(PrintWriter outstructs) {
185   }
186
187   public void additionalClassObjectFields(PrintWriter outclassdefs) {
188   }
189
190   public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {
191   }
192
193   public void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
194   }
195
196   public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {
197   }
198
199   public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
200   }
201
202   public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew) {
203   }
204
205   public void additionalCodeNewStringLiteral(PrintWriter output, String dstVar) {
206   }
207 }