00001 package edu.ksu.cis.bandera.bir;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import ca.mcgill.sable.util.*;
00036
00037 import java.util.*;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 public class BirState extends AbstractExprSwitch
00073 implements Cloneable, BirConstants {
00074
00075 TransSystem system;
00076 Literal [] store;
00077 Location [] location;
00078 boolean [] threadActive;
00079
00080 boolean lhs = false;
00081 int choice;
00082 String output = "";
00083
00084 BirState(TransSystem system) {
00085 this.system = system;
00086 }
00087 public void applyAction(Action action, int choice) {
00088 this.choice = choice;
00089 action.apply(this);
00090 }
00091 public void caseAddExpr(AddExpr expr)
00092 {
00093 expr.getOp1().apply(this);
00094 ConstExpr op1 = (ConstExpr) getResult();
00095 expr.getOp2().apply(this);
00096 ConstExpr op2 = (ConstExpr) getResult();
00097 setResult(new IntLit(op1.getValue() + op2.getValue()));
00098 }
00099 public void caseAndExpr(AndExpr expr)
00100 {
00101 expr.getOp1().apply(this);
00102 BoolLit op1 = (BoolLit) getResult();
00103 expr.getOp2().apply(this);
00104 BoolLit op2 = (BoolLit) getResult();
00105 setResult(new BoolLit(op1.getValue() && op2.getValue()));
00106 }
00107 public void caseArrayExpr(ArrayExpr expr)
00108 {
00109 boolean saveLhs = lhs;
00110
00111
00112 lhs = false;
00113 expr.getIndex().apply(this);
00114 ConstExpr index = (ConstExpr) getResult();
00115 lhs = saveLhs;
00116 expr.getArray().apply(this);
00117 Integer offset = (Integer) getResult();
00118 int address = offset.intValue() + index.getValue() + 1;
00119
00120 if (lhs || expr.getType().isKind(ARRAY|RECORD))
00121 setResult(new Integer(address));
00122 else
00123 setResult(store[address]);
00124 }
00125 public void caseAssertAction(AssertAction assertAction) {
00126
00127 }
00128
00129
00130
00131
00132 public void caseAssignAction(AssignAction assign)
00133 {
00134 assign.getRhs().apply(this);
00135 Literal val = (Literal) getResult();
00136 lhs = true;
00137 assign.getLhs().apply(this);
00138 Integer index = (Integer) getResult();
00139 lhs = false;
00140 store[index.intValue()] = val;
00141 }
00142 public void caseBoolLit(BoolLit expr)
00143 {
00144 setResult(expr);
00145 }
00146 public void caseChooseExpr(ChooseExpr expr)
00147 {
00148
00149 setResult(expr.getChoice(choice));
00150 }
00151 public void caseConstant(Constant expr)
00152 {
00153 setResult(expr);
00154 }
00155 public void caseDerefExpr(DerefExpr expr)
00156 {
00157
00158
00159 boolean saveLhs = lhs;
00160 lhs = false;
00161 expr.getTarget().apply(this);
00162 RefLit ref = (RefLit) getResult();
00163 lhs = saveLhs;
00164 int address = ref.getCollection().getOffset();
00165 if (ref.getCollection().getType().isKind(COLLECTION))
00166 address += ref.getIndex() * expr.getType().getExtent();
00167 if (lhs || expr.getType().isKind(ARRAY|RECORD))
00168 setResult(new Integer(address));
00169 else
00170 setResult(store[address]);
00171 }
00172 public void caseDivExpr(DivExpr expr)
00173 {
00174 expr.getOp1().apply(this);
00175 ConstExpr op1 = (ConstExpr) getResult();
00176 expr.getOp2().apply(this);
00177 ConstExpr op2 = (ConstExpr) getResult();
00178 setResult(new IntLit(op1.getValue() / op2.getValue()));
00179 }
00180 public void caseEqExpr(EqExpr expr)
00181 {
00182 expr.getOp1().apply(this);
00183 ConstExpr op1 = (ConstExpr) getResult();
00184 expr.getOp2().apply(this);
00185 ConstExpr op2 = (ConstExpr) getResult();
00186 setResult(new BoolLit(op1.getValue() == op2.getValue()));
00187 }
00188 public void caseInstanceOfExpr(InstanceOfExpr expr)
00189 {
00190 expr.getRefExpr().apply(this);
00191 if (getResult() instanceof NullExpr)
00192
00193 setResult(new BoolLit(true));
00194 else {
00195 StateVar collection = ((RefLit)getResult()).getCollection();
00196 StateVarVector targets = expr.getRefType().getTargets();
00197 setResult(new BoolLit(targets.indexOf(collection) >= 0));
00198 }
00199 }
00200 public void caseIntLit(IntLit expr)
00201 {
00202 setResult(expr);
00203 }
00204 public void caseLeExpr(LeExpr expr)
00205 {
00206 expr.getOp1().apply(this);
00207 ConstExpr op1 = (ConstExpr) getResult();
00208 expr.getOp2().apply(this);
00209 ConstExpr op2 = (ConstExpr) getResult();
00210 setResult(new BoolLit(op1.getValue() <= op2.getValue()));
00211 }
00212 public void caseLengthExpr(LengthExpr expr)
00213 {
00214 expr.getArray().apply(this);
00215 Integer offset = (Integer) getResult();
00216 setResult(store[offset.intValue()]);
00217 }
00218 public void caseLockAction(LockAction lockAction)
00219 {
00220 lhs = true;
00221 lockAction.getLockExpr().apply(this);
00222 Integer index = (Integer) getResult();
00223 lhs = false;
00224 LockLit lock = (LockLit) store[index.intValue()];
00225 int operation = lockAction.getOperation();
00226 BirThread thread = lockAction.getThread();
00227 store[index.intValue()] = lock.nextState(operation,thread,choice);
00228 }
00229 public void caseLockTest(LockTest lockTest)
00230 {
00231 lockTest.getLockExpr().apply(this);
00232 LockLit lock = (LockLit) getResult();
00233 setResult(new BoolLit(lock.queryState(lockTest.getOperation(),
00234 lockTest.getThread())));
00235 }
00236 public void caseLtExpr(LtExpr expr)
00237 {
00238 expr.getOp1().apply(this);
00239 ConstExpr op1 = (ConstExpr) getResult();
00240 expr.getOp2().apply(this);
00241 ConstExpr op2 = (ConstExpr) getResult();
00242 setResult(new BoolLit(op1.getValue() < op2.getValue()));
00243 }
00244 public void caseMulExpr(MulExpr expr)
00245 {
00246 expr.getOp1().apply(this);
00247 ConstExpr op1 = (ConstExpr) getResult();
00248 expr.getOp2().apply(this);
00249 ConstExpr op2 = (ConstExpr) getResult();
00250 setResult(new IntLit(op1.getValue() * op2.getValue()));
00251 }
00252 public void caseNeExpr(NeExpr expr)
00253 {
00254 expr.getOp1().apply(this);
00255 ConstExpr op1 = (ConstExpr) getResult();
00256 expr.getOp2().apply(this);
00257 ConstExpr op2 = (ConstExpr) getResult();
00258 setResult(new BoolLit(op1.getValue() != op2.getValue()));
00259 }
00260 public void caseNewArrayExpr(NewArrayExpr expr)
00261 {
00262 StateVar target = expr.getCollection();
00263 Type type = ((Collection)target.getType()).getBaseType();
00264 BirTypeInit initializer = new BirTypeInit(this);
00265
00266 int length = target.getActualBaseTypeSize();
00267 int address = target.getOffset() + choice * length;
00268
00269 store[address] = new IntLit(length);
00270 type.apply(initializer,new Integer(address));
00271 setResult(new RefLit(target,choice));
00272 }
00273 public void caseNewExpr(NewExpr expr)
00274 {
00275 StateVar target = expr.getCollection();
00276 Type type = ((Collection)target.getType()).getBaseType();
00277
00278 BirTypeInit initializer = new BirTypeInit(this);
00279 int address = target.getOffset() + choice * type.getExtent();
00280 type.apply(initializer,new Integer(address));
00281 setResult(new RefLit(target,choice));
00282 }
00283 public void caseNotExpr(NotExpr expr)
00284 {
00285 expr.getOp().apply(this);
00286 BoolLit op = (BoolLit) getResult();
00287 setResult(new BoolLit(! op.getValue()));
00288 }
00289 public void caseNullExpr(NullExpr expr)
00290 {
00291 setResult(expr);
00292 }
00293 public void caseOrExpr(OrExpr expr)
00294 {
00295 expr.getOp1().apply(this);
00296 BoolLit op1 = (BoolLit) getResult();
00297 expr.getOp2().apply(this);
00298 BoolLit op2 = (BoolLit) getResult();
00299 setResult(new BoolLit(op1.getValue() || op2.getValue()));
00300 }
00301 public void casePrintAction(PrintAction printAction)
00302 {
00303
00304 Vector printItems = printAction.getPrintItems();
00305 for (int i = 0; i < printItems.size(); i++) {
00306 Object item = printItems.elementAt(i);
00307 if (item instanceof String)
00308 output += item;
00309 else {
00310 ((Expr)item).apply(this);
00311 output += getResult().toString();
00312 }
00313 }
00314 output += "\n";
00315 }
00316 public void caseRecordExpr(RecordExpr expr)
00317 {
00318 expr.getRecord().apply(this);
00319 Integer offset = (Integer) getResult();
00320 int address = offset.intValue() + expr.getField().getOffset();
00321 if (lhs || expr.getType().isKind(ARRAY|RECORD))
00322 setResult(new Integer(address));
00323 else
00324 setResult(store[address]);
00325 }
00326 public void caseRefExpr(RefExpr expr)
00327 {
00328 setResult(new RefLit(expr.getTarget(),0));
00329 }
00330 public void caseRemExpr(RemExpr expr)
00331 {
00332 expr.getOp1().apply(this);
00333 ConstExpr op1 = (ConstExpr) getResult();
00334 expr.getOp2().apply(this);
00335 ConstExpr op2 = (ConstExpr) getResult();
00336 setResult(new IntLit(op1.getValue() % op2.getValue()));
00337 }
00338 public void caseStateVar(StateVar expr)
00339 {
00340 if (lhs || expr.getType().isKind(ARRAY|RECORD|COLLECTION))
00341 setResult(new Integer(expr.getOffset()));
00342 else
00343 setResult(store[expr.getOffset()]);
00344 }
00345 public void caseSubExpr(SubExpr expr)
00346 {
00347 expr.getOp1().apply(this);
00348 ConstExpr op1 = (ConstExpr) getResult();
00349 expr.getOp2().apply(this);
00350 ConstExpr op2 = (ConstExpr) getResult();
00351 setResult(new IntLit(op1.getValue() - op2.getValue()));
00352 }
00353 public void caseThreadAction(ThreadAction threadAction)
00354 {
00355 if (threadAction.isStart())
00356 threadActive[threadAction.getThreadArg().getId()] = true;
00357 else if (threadAction.isExit())
00358 threadActive[threadAction.getThread().getId()] = false;
00359 }
00360 public void caseThreadLocTest(ThreadLocTest threadLocTest)
00361 {
00362 setResult(new BoolLit(location[threadLocTest.getThread().getId()]
00363 == threadLocTest.getLocation()));
00364 }
00365 public void caseThreadTest(ThreadTest threadTest)
00366 {
00367 boolean done = ! threadActive[threadTest.getThreadArg().getId()];
00368 setResult(new BoolLit(done));
00369 }
00370
00371
00372
00373
00374 public void completeTrans(Transformation trans) {
00375 Location toLoc = trans.getToLoc();
00376 location[toLoc.getThread().getId()] = toLoc;
00377 }
00378
00379
00380
00381
00382 public BirState copy() {
00383 BirState result = new BirState(system);
00384 result.store = (Literal []) store.clone();
00385 result.location = (Location []) location.clone();
00386 result.threadActive = (boolean []) threadActive.clone();
00387 result.output = output;
00388 return result;
00389 }
00390 public void defaultCase(Object obj)
00391 {
00392 throw new RuntimeException("Forgot to handle case: " + obj);
00393 }
00394 public String exprValue(Expr expr) {
00395 expr.apply(this);
00396 if (expr.getType().isKind(ARRAY|RECORD))
00397 return "Object";
00398 else
00399 return getResult().toString();
00400 }
00401 public String getOutput() { return output; }
00402 public Literal [] getStore() { return store; }
00403 public TransSystem getSystem() { return system; }
00404
00405
00406
00407
00408 public static BirState initialState(TransSystem system,
00409 TransVector transVector,
00410 Vector choiceVector) {
00411 int stateSize =
00412 setActualSizesFromTrace(system,transVector,choiceVector);
00413 BirState state = new BirState(system);
00414 state.location = new Location[system.getThreads().size()];
00415 state.threadActive = new boolean[system.getThreads().size()];
00416 state.store = new Literal[stateSize];
00417
00418
00419 BirTypeInit initializer = new BirTypeInit(state);
00420 StateVarVector vars = system.getStateVars();
00421 for (int i = 0; i < vars.size(); i++) {
00422 StateVar var = vars.elementAt(i);
00423 var.getType().apply(initializer,var);
00424 }
00425
00426
00427 ThreadVector threads = system.getThreads();
00428 for (int i = 0; i < threads.size(); i++) {
00429 BirThread thread = threads.elementAt(i);
00430 state.location[thread.getId()] = thread.getStartLoc();
00431 state.threadActive[thread.getId()] = thread.isMain();
00432 }
00433
00434 return state;
00435 }
00436 public boolean isActive(BirThread thread) {
00437 return threadActive[thread.getId()];
00438 }
00439 public void print() {
00440 System.out.println("STATE");
00441 for (int i = 0; i < store.length; i++)
00442 System.out.print(store[i] + " ");
00443 System.out.println();
00444 ThreadVector threads = system.getThreads();
00445 for (int i = 0; i < threads.size(); i++) {
00446 BirThread thread = threads.elementAt(i);
00447 if (threadActive[thread.getId()])
00448 System.out.println(" " + thread.getName() + " at " +
00449 location[thread.getId()].getLabel());
00450 }
00451 BirTypePrint printer = new BirTypePrint(this);
00452 StateVarVector vars = system.getStateVars();
00453 for (int i = 0; i < vars.size(); i++) {
00454 StateVar var = vars.elementAt(i);
00455 System.out.print(" " + var.getName() + " = ");
00456 var.getType().apply(printer,var);
00457 System.out.println();
00458 }
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 public static int setActualSizesFromTrace(TransSystem system,
00478 TransVector transVector,
00479 Vector choiceVector) {
00480
00481
00482 StateVarVector vars = system.getStateVars();
00483 StateVarVector targets = system.refAnyType().getTargets();
00484 int numAlloc [] = new int[targets.size()];
00485 int maxArrayLength [] = new int[targets.size()];
00486
00487 for (int i = 0; i < transVector.size(); i++) {
00488 ActionVector actions = transVector.elementAt(i).getActions();
00489 int choices [] = (int []) choiceVector.elementAt(i);
00490 for (int j = 0; j < actions.size(); j++) {
00491 Action action = actions.elementAt(j);
00492 if (action.isAssignAction()) {
00493 Expr rhs = ((AssignAction)action).getRhs();
00494
00495
00496
00497
00498 if (rhs instanceof Allocator) {
00499 int targetNum =
00500 targets.indexOf(((Allocator)rhs).getCollection());
00501 if (rhs instanceof NewArrayExpr) {
00502 int arrayLength = choices[j];
00503 if (arrayLength > maxArrayLength[targetNum])
00504 maxArrayLength[targetNum] = arrayLength;
00505 }
00506
00507 choices[j] = numAlloc[targetNum];
00508 numAlloc[targetNum] += 1;
00509 }
00510 }
00511 }
00512 }
00513
00514
00515
00516
00517
00518
00519 int currentStateSize = 0;
00520 for (int i = 0; i < vars.size(); i++) {
00521 StateVar var = vars.elementAt(i);
00522 var.setOffset(currentStateSize);
00523 int varExtent = 0;
00524 if (var.getType().isKind(COLLECTION)) {
00525 int targetNum = targets.indexOf(var);
00526 int numItems = numAlloc[targetNum];
00527 var.setActualSize(numItems);
00528 Type baseType = ((Collection)var.getType()).getBaseType();
00529 int itemExtent = baseType.getExtent();
00530 if (baseType.isKind(ARRAY)) {
00531 int elementExtent =
00532 ((Array)baseType).getBaseType().getExtent();
00533 int arraySize = maxArrayLength[targetNum];
00534 var.setActualBaseTypeSize(arraySize);
00535 itemExtent = 1 + arraySize * elementExtent;
00536
00537 }
00538 var.setActualBaseTypeExtent(itemExtent);
00539
00540 varExtent = numItems * itemExtent;
00541 }
00542 else
00543 varExtent = var.getType().getExtent();
00544 currentStateSize += varExtent;
00545 System.out.println(" Var " + var + " extent = " + varExtent);
00546 }
00547 return currentStateSize;
00548 }
00549 }