1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.verifier.structurals;
18
19
20 import org.apache.bcel.Constants;
21 import org.apache.bcel.Repository;
22 import org.apache.bcel.classfile.Constant;
23 import org.apache.bcel.classfile.ConstantClass;
24 import org.apache.bcel.classfile.ConstantDouble;
25 import org.apache.bcel.classfile.ConstantFieldref;
26 import org.apache.bcel.classfile.ConstantFloat;
27 import org.apache.bcel.classfile.ConstantInteger;
28 import org.apache.bcel.classfile.ConstantLong;
29 import org.apache.bcel.classfile.ConstantString;
30 import org.apache.bcel.classfile.Field;
31 import org.apache.bcel.classfile.JavaClass;
32 import org.apache.bcel.generic.*;
33 import org.apache.bcel.verifier.VerificationResult;
34 import org.apache.bcel.verifier.Verifier;
35 import org.apache.bcel.verifier.VerifierFactory;
36 import org.apache.bcel.verifier.exc.AssertionViolatedException;
37 import org.apache.bcel.verifier.exc.StructuralCodeConstraintException;
38
39
40 /***
41 * A Visitor class testing for valid preconditions of JVM instructions.
42 * The instance of this class will throw a StructuralCodeConstraintException
43 * instance if an instruction is visitXXX()ed which has preconditions that are
44 * not satisfied.
45 * TODO: Currently, the JVM's behaviour concerning monitors (MONITORENTER,
46 * MONITOREXIT) is not modeled in JustIce.
47 *
48 * @version $Id: InstConstraintVisitor.java 386056 2006-03-15 11:31:56Z tcurdt $
49 * @author Enver Haase
50 * @see org.apache.bcel.verifier.exc.StructuralCodeConstraintException
51 * @see org.apache.bcel.verifier.exc.LinkingConstraintException
52 */
53 public class InstConstraintVisitor extends EmptyVisitor implements org.apache.bcel.generic.Visitor{
54
55 private static ObjectType GENERIC_ARRAY = new ObjectType("org.apache.bcel.verifier.structurals.GenericArray");
56
57 /***
58 * The constructor. Constructs a new instance of this class.
59 */
60 public InstConstraintVisitor(){}
61
62 /***
63 * The Execution Frame we're working on.
64 *
65 * @see #setFrame(Frame f)
66 * @see #locals()
67 * @see #stack()
68 */
69 private Frame frame = null;
70
71 /***
72 * The ConstantPoolGen we're working on.
73 *
74 * @see #setConstantPoolGen(ConstantPoolGen cpg)
75 */
76 private ConstantPoolGen cpg = null;
77
78 /***
79 * The MethodGen we're working on.
80 *
81 * @see #setMethodGen(MethodGen mg)
82 */
83 private MethodGen mg = null;
84
85 /***
86 * The OperandStack we're working on.
87 *
88 * @see #setFrame(Frame f)
89 */
90 private OperandStack stack(){
91 return frame.getStack();
92 }
93
94 /***
95 * The LocalVariables we're working on.
96 *
97 * @see #setFrame(Frame f)
98 */
99 private LocalVariables locals(){
100 return frame.getLocals();
101 }
102
103 /***
104 * This method is called by the visitXXX() to notify the acceptor of this InstConstraintVisitor
105 * that a constraint violation has occured. This is done by throwing an instance of a
106 * StructuralCodeConstraintException.
107 * @throws org.apache.bcel.verifier.exc.StructuralCodeConstraintException always.
108 */
109 private void constraintViolated(Instruction violator, String description){
110 String fq_classname = violator.getClass().getName();
111 throw new StructuralCodeConstraintException("Instruction "+ fq_classname.substring(fq_classname.lastIndexOf('.')+1) +" constraint violated: " + description);
112 }
113
114 /***
115 * This returns the single instance of the InstConstraintVisitor class.
116 * To operate correctly, other values must have been set before actually
117 * using the instance.
118 * Use this method for performance reasons.
119 *
120 * @see #setConstantPoolGen(ConstantPoolGen cpg)
121 * @see #setMethodGen(MethodGen mg)
122 */
123 public void setFrame(Frame f){
124 this.frame = f;
125
126 }
127
128 /***
129 * Sets the ConstantPoolGen instance needed for constraint
130 * checking prior to execution.
131 */
132 public void setConstantPoolGen(ConstantPoolGen cpg){
133 this.cpg = cpg;
134 }
135
136 /***
137 * Sets the MethodGen instance needed for constraint
138 * checking prior to execution.
139 */
140 public void setMethodGen(MethodGen mg){
141 this.mg = mg;
142 }
143
144 /***
145 * Assures index is of type INT.
146 * @throws org.apache.bcel.verifier.exc.StructuralCodeConstraintException if the above constraint is not satisfied.
147 */
148 private void indexOfInt(Instruction o, Type index){
149 if (! index.equals(Type.INT)) {
150 constraintViolated(o, "The 'index' is not of type int but of type "+index+".");
151 }
152 }
153
154 /***
155 * Assures the ReferenceType r is initialized (or Type.NULL).
156 * Formally, this means (!(r instanceof UninitializedObjectType)), because
157 * there are no uninitialized array types.
158 * @throws org.apache.bcel.verifier.exc.StructuralCodeConstraintException if the above constraint is not satisfied.
159 */
160 private void referenceTypeIsInitialized(Instruction o, ReferenceType r){
161 if (r instanceof UninitializedObjectType){
162 constraintViolated(o, "Working on an uninitialized object '"+r+"'.");
163 }
164 }
165
166 /*** Assures value is of type INT. */
167 private void valueOfInt(Instruction o, Type value){
168 if (! value.equals(Type.INT)) {
169 constraintViolated(o, "The 'value' is not of type int but of type "+value+".");
170 }
171 }
172
173 /***
174 * Assures arrayref is of ArrayType or NULL;
175 * returns true if and only if arrayref is non-NULL.
176 * @throws org.apache.bcel.verifier.exc.StructuralCodeConstraintException if the above constraint is violated.
177 */
178 private boolean arrayrefOfArrayType(Instruction o, Type arrayref){
179 if (! ((arrayref instanceof ArrayType) || arrayref.equals(Type.NULL)) ) {
180 constraintViolated(o, "The 'arrayref' does not refer to an array but is of type "+arrayref+".");
181 }
182 return (arrayref instanceof ArrayType);
183 }
184
185 /****************************************************************/
186
187 /****************************************************************/
188 /***
189 * Ensures the general preconditions of an instruction that accesses the stack.
190 * This method is here because BCEL has no such superinterface for the stack
191 * accessing instructions; and there are funny unexpected exceptions in the
192 * semantices of the superinterfaces and superclasses provided.
193 * E.g. SWAP is a StackConsumer, but DUP_X1 is not a StackProducer.
194 * Therefore, this method is called by all StackProducer, StackConsumer,
195 * and StackInstruction instances via their visitXXX() method.
196 * Unfortunately, as the superclasses and superinterfaces overlap, some instructions
197 * cause this method to be called two or three times. [TODO: Fix this.]
198 *
199 * @see #visitStackConsumer(StackConsumer o)
200 * @see #visitStackProducer(StackProducer o)
201 * @see #visitStackInstruction(StackInstruction o)
202 */
203 private void _visitStackAccessor(Instruction o){
204 int consume = o.consumeStack(cpg);
205 if (consume > stack().slotsUsed()){
206 constraintViolated((Instruction) o, "Cannot consume "+consume+" stack slots: only "+stack().slotsUsed()+" slot(s) left on stack!\nStack:\n"+stack());
207 }
208
209 int produce = o.produceStack(cpg) - ((Instruction) o).consumeStack(cpg);
210 if ( produce + stack().slotsUsed() > stack().maxStack() ){
211 constraintViolated((Instruction) o, "Cannot produce "+produce+" stack slots: only "+(stack().maxStack()-stack().slotsUsed())+" free stack slot(s) left.\nStack:\n"+stack());
212 }
213 }
214
215 /****************************************************************/
216
217
218
219 /****************************************************************/
220
221 /***
222 * Assures the generic preconditions of a LoadClass instance.
223 * The referenced class is loaded and pass2-verified.
224 */
225 public void visitLoadClass(LoadClass o){
226 ObjectType t = o.getLoadClassType(cpg);
227 if (t != null){
228 Verifier v = VerifierFactory.getVerifier(t.getClassName());
229 VerificationResult vr = v.doPass2();
230 if (vr.getStatus() != VerificationResult.VERIFIED_OK){
231 constraintViolated((Instruction) o, "Class '"+o.getLoadClassType(cpg).getClassName()+"' is referenced, but cannot be loaded and resolved: '"+vr+"'.");
232 }
233 }
234 }
235
236 /***
237 * Ensures the general preconditions of a StackConsumer instance.
238 */
239 public void visitStackConsumer(StackConsumer o){
240 _visitStackAccessor((Instruction) o);
241 }
242
243 /***
244 * Ensures the general preconditions of a StackProducer instance.
245 */
246 public void visitStackProducer(StackProducer o){
247 _visitStackAccessor((Instruction) o);
248 }
249
250
251 /****************************************************************/
252
253
254
255 /****************************************************************/
256 /***
257 * Ensures the general preconditions of a CPInstruction instance.
258 */
259 public void visitCPInstruction(CPInstruction o){
260 int idx = o.getIndex();
261 if ((idx < 0) || (idx >= cpg.getSize())){
262 throw new AssertionViolatedException("Huh?! Constant pool index of instruction '"+o+"' illegal? Pass 3a should have checked this!");
263 }
264 }
265
266 /***
267 * Ensures the general preconditions of a FieldInstruction instance.
268 */
269 public void visitFieldInstruction(FieldInstruction o){
270
271
272
273
274 Constant c = cpg.getConstant(o.getIndex());
275 if (!(c instanceof ConstantFieldref)){
276 constraintViolated(o, "Index '"+o.getIndex()+"' should refer to a CONSTANT_Fieldref_info structure, but refers to '"+c+"'.");
277 }
278
279 Type t = o.getType(cpg);
280 if (t instanceof ObjectType){
281 String name = ((ObjectType)t).getClassName();
282 Verifier v = VerifierFactory.getVerifier( name );
283 VerificationResult vr = v.doPass2();
284 if (vr.getStatus() != VerificationResult.VERIFIED_OK){
285 constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'.");
286 }
287 }
288 }
289
290 /***
291 * Ensures the general preconditions of an InvokeInstruction instance.
292 */
293 public void visitInvokeInstruction(InvokeInstruction o){
294
295
296
297
298 }
299
300 /***
301 * Ensures the general preconditions of a StackInstruction instance.
302 */
303 public void visitStackInstruction(StackInstruction o){
304 _visitStackAccessor(o);
305 }
306
307 /***
308 * Assures the generic preconditions of a LocalVariableInstruction instance.
309 * That is, the index of the local variable must be valid.
310 */
311 public void visitLocalVariableInstruction(LocalVariableInstruction o){
312 if (locals().maxLocals() <= (o.getType(cpg).getSize()==1? o.getIndex() : o.getIndex()+1) ){
313 constraintViolated(o, "The 'index' is not a valid index into the local variable array.");
314 }
315 }
316
317 /***
318 * Assures the generic preconditions of a LoadInstruction instance.
319 */
320 public void visitLoadInstruction(LoadInstruction o){
321
322
323
324 if (locals().get(o.getIndex()) == Type.UNKNOWN){
325 constraintViolated(o, "Read-Access on local variable "+o.getIndex()+" with unknown content.");
326 }
327
328
329
330
331 if (o.getType(cpg).getSize() == 2){
332 if (locals().get(o.getIndex()+1) != Type.UNKNOWN){
333 constraintViolated(o, "Reading a two-locals value from local variables "+o.getIndex()+" and "+(o.getIndex()+1)+" where the latter one is destroyed.");
334 }
335 }
336
337
338 if (!(o instanceof ALOAD)){
339 if (locals().get(o.getIndex()) != o.getType(cpg) ){
340 constraintViolated(o, "Local Variable type and LOADing Instruction type mismatch: Local Variable: '"+locals().get(o.getIndex())+"'; Instruction type: '"+o.getType(cpg)+"'.");
341 }
342 }
343 else{
344 if (!(locals().get(o.getIndex()) instanceof ReferenceType)){
345 constraintViolated(o, "Local Variable type and LOADing Instruction type mismatch: Local Variable: '"+locals().get(o.getIndex())+"'; Instruction expects a ReferenceType.");
346 }
347
348
349 }
350
351
352 if ((stack().maxStack() - stack().slotsUsed()) < o.getType(cpg).getSize()){
353 constraintViolated(o, "Not enough free stack slots to load a '"+o.getType(cpg)+"' onto the OperandStack.");
354 }
355 }
356
357 /***
358 * Assures the generic preconditions of a StoreInstruction instance.
359 */
360 public void visitStoreInstruction(StoreInstruction o){
361
362
363 if (stack().isEmpty()){
364 constraintViolated(o, "Cannot STORE: Stack to read from is empty.");
365 }
366
367 if ( (!(o instanceof ASTORE)) ){
368 if (! (stack().peek() == o.getType(cpg)) ){
369 constraintViolated(o, "Stack top type and STOREing Instruction type mismatch: Stack top: '"+stack().peek()+"'; Instruction type: '"+o.getType(cpg)+"'.");
370 }
371 }
372 else{
373 Type stacktop = stack().peek();
374 if ( (!(stacktop instanceof ReferenceType)) && (!(stacktop instanceof ReturnaddressType)) ){
375 constraintViolated(o, "Stack top type and STOREing Instruction type mismatch: Stack top: '"+stack().peek()+"'; Instruction expects a ReferenceType or a ReturnadressType.");
376 }
377
378
379
380 }
381 }
382
383 /***
384 * Assures the generic preconditions of a ReturnInstruction instance.
385 */
386 public void visitReturnInstruction(ReturnInstruction o){
387 Type method_type = mg.getType();
388 if (method_type == Type.BOOLEAN ||
389 method_type == Type.BYTE ||
390 method_type == Type.SHORT ||
391 method_type == Type.CHAR){
392 method_type = Type.INT;
393 }
394
395 if (o instanceof RETURN){
396 if (method_type != Type.VOID){
397 constraintViolated(o, "RETURN instruction in non-void method.");
398 }
399 else{
400 return;
401 }
402 }
403 if (o instanceof ARETURN){
404 if (stack().peek() == Type.NULL){
405 return;
406 }
407 else{
408 if (! (stack().peek() instanceof ReferenceType)){
409 constraintViolated(o, "Reference type expected on top of stack, but is: '"+stack().peek()+"'.");
410 }
411 referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()));
412
413
414
415
416
417
418 }
419 }
420 else{
421 if (! ( method_type.equals( stack().peek() ))){
422 constraintViolated(o, "Current method has return type of '"+mg.getType()+"' expecting a '"+method_type+"' on top of the stack. But stack top is a '"+stack().peek()+"'.");
423 }
424 }
425 }
426
427 /****************************************************************/
428
429 /****************************************************************/
430
431 /***
432 * Ensures the specific preconditions of the said instruction.
433 */
434 public void visitAALOAD(AALOAD o){
435 Type arrayref = stack().peek(1);
436 Type index = stack().peek(0);
437
438 indexOfInt(o, index);
439 if (arrayrefOfArrayType(o, arrayref)){
440 if (! (((ArrayType) arrayref).getElementType() instanceof ReferenceType)){
441 constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a ReferenceType but to an array of "+((ArrayType) arrayref).getElementType()+".");
442 }
443
444 }
445 }
446
447 /***
448 * Ensures the specific preconditions of the said instruction.
449 */
450 public void visitAASTORE(AASTORE o){
451 try {
452 Type arrayref = stack().peek(2);
453 Type index = stack().peek(1);
454 Type value = stack().peek(0);
455
456 indexOfInt(o, index);
457 if (!(value instanceof ReferenceType)){
458 constraintViolated(o, "The 'value' is not of a ReferenceType but of type "+value+".");
459 }else{
460
461 }
462
463
464 if (arrayrefOfArrayType(o, arrayref)){
465 if (! (((ArrayType) arrayref).getElementType() instanceof ReferenceType)){
466 constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a ReferenceType but to an array of "+((ArrayType) arrayref).getElementType()+".");
467 }
468 if (! ((ReferenceType)value).isAssignmentCompatibleWith((ReferenceType) ((ArrayType) arrayref).getElementType())){
469 constraintViolated(o, "The type of 'value' ('"+value+"') is not assignment compatible to the components of the array 'arrayref' refers to. ('"+((ArrayType) arrayref).getElementType()+"')");
470 }
471 }
472 } catch (ClassNotFoundException e) {
473
474 throw new AssertionViolatedException("Missing class: " + e.toString());
475 }
476 }
477
478 /***
479 * Ensures the specific preconditions of the said instruction.
480 */
481 public void visitACONST_NULL(ACONST_NULL o){
482
483 }
484
485 /***
486 * Ensures the specific preconditions of the said instruction.
487 */
488 public void visitALOAD(ALOAD o){
489
490
491
492 }
493
494 /***
495 * Ensures the specific preconditions of the said instruction.
496 */
497 public void visitANEWARRAY(ANEWARRAY o){
498 if (!stack().peek().equals(Type.INT)) {
499 constraintViolated(o, "The 'count' at the stack top is not of type '"+Type.INT+"' but of type '"+stack().peek()+"'.");
500
501
502 }
503 }
504
505 /***
506 * Ensures the specific preconditions of the said instruction.
507 */
508 public void visitARETURN(ARETURN o){
509 if (! (stack().peek() instanceof ReferenceType) ){
510 constraintViolated(o, "The 'objectref' at the stack top is not of a ReferenceType but of type '"+stack().peek()+"'.");
511 }
512 ReferenceType objectref = (ReferenceType) (stack().peek());
513 referenceTypeIsInitialized(o, objectref);
514
515
516
517
518
519
520
521 }
522
523 /***
524 * Ensures the specific preconditions of the said instruction.
525 */
526 public void visitARRAYLENGTH(ARRAYLENGTH o){
527 Type arrayref = stack().peek(0);
528 arrayrefOfArrayType(o, arrayref);
529 }
530
531 /***
532 * Ensures the specific preconditions of the said instruction.
533 */
534 public void visitASTORE(ASTORE o){
535 if (! ( (stack().peek() instanceof ReferenceType) || (stack().peek() instanceof ReturnaddressType) ) ){
536 constraintViolated(o, "The 'objectref' is not of a ReferenceType or of ReturnaddressType but of "+stack().peek()+".");
537 }
538
539
540
541 }
542
543 /***
544 * Ensures the specific preconditions of the said instruction.
545 */
546 public void visitATHROW(ATHROW o){
547 try {
548
549
550 if (! ((stack().peek() instanceof ObjectType) || (stack().peek().equals(Type.NULL))) ){
551 constraintViolated(o, "The 'objectref' is not of an (initialized) ObjectType but of type "+stack().peek()+".");
552 }
553
554
555 if (stack().peek().equals(Type.NULL)) {
556 return;
557 }
558
559 ObjectType exc = (ObjectType) (stack().peek());
560 ObjectType throwable = (ObjectType) (Type.getType("Ljava/lang/Throwable;"));
561 if ( (! (exc.subclassOf(throwable)) ) && (! (exc.equals(throwable))) ){
562 constraintViolated(o, "The 'objectref' is not of class Throwable or of a subclass of Throwable, but of '"+stack().peek()+"'.");
563 }
564 } catch (ClassNotFoundException e) {
565
566 throw new AssertionViolatedException("Missing class: " + e.toString());
567 }
568 }
569
570 /***
571 * Ensures the specific preconditions of the said instruction.
572 */
573 public void visitBALOAD(BALOAD o){
574 Type arrayref = stack().peek(1);
575 Type index = stack().peek(0);
576 indexOfInt(o, index);
577 if (arrayrefOfArrayType(o, arrayref)){
578 if (! ( (((ArrayType) arrayref).getElementType().equals(Type.BOOLEAN)) ||
579 (((ArrayType) arrayref).getElementType().equals(Type.BYTE)) ) ){
580 constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a Type.BYTE or Type.BOOLEAN but to an array of '"+((ArrayType) arrayref).getElementType()+"'.");
581 }
582 }
583 }
584
585 /***
586 * Ensures the specific preconditions of the said instruction.
587 */
588 public void visitBASTORE(BASTORE o){
589 Type arrayref = stack().peek(2);
590 Type index = stack().peek(1);
591 Type value = stack().peek(0);
592
593 indexOfInt(o, index);
594 valueOfInt(o, value);
595 if (arrayrefOfArrayType(o, arrayref)){
596 if (! ( (((ArrayType) arrayref).getElementType().equals(Type.BOOLEAN)) ||
597 (((ArrayType) arrayref).getElementType().equals(Type.BYTE)) ) ) {
598 constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a Type.BYTE or Type.BOOLEAN but to an array of '"+((ArrayType) arrayref).getElementType()+"'.");
599 }
600 }
601 }
602
603 /***
604 * Ensures the specific preconditions of the said instruction.
605 */
606 public void visitBIPUSH(BIPUSH o){
607
608 }
609
610 /***
611 * Ensures the specific preconditions of the said instruction.
612 */
613 public void visitBREAKPOINT(BREAKPOINT o){
614 throw new AssertionViolatedException("In this JustIce verification pass there should not occur an illegal instruction such as BREAKPOINT.");
615 }
616
617 /***
618 * Ensures the specific preconditions of the said instruction.
619 */
620 public void visitCALOAD(CALOAD o){
621 Type arrayref = stack().peek(1);
622 Type index = stack().peek(0);
623
624 indexOfInt(o, index);
625 arrayrefOfArrayType(o, arrayref);
626 }
627
628 /***
629 * Ensures the specific preconditions of the said instruction.
630 */
631 public void visitCASTORE(CASTORE o){
632 Type arrayref = stack().peek(2);
633 Type index = stack().peek(1);
634 Type value = stack().peek(0);
635
636 indexOfInt(o, index);
637 valueOfInt(o, value);
638 if (arrayrefOfArrayType(o, arrayref)){
639 if (! ((ArrayType) arrayref).getElementType().equals(Type.CHAR) ){
640 constraintViolated(o, "The 'arrayref' does not refer to an array with elements of type char but to an array of type "+((ArrayType) arrayref).getElementType()+".");
641 }
642 }
643 }
644
645 /***
646 * Ensures the specific preconditions of the said instruction.
647 */
648 public void visitCHECKCAST(CHECKCAST o){
649
650 Type objectref = stack().peek(0);
651 if (!(objectref instanceof ReferenceType)){
652 constraintViolated(o, "The 'objectref' is not of a ReferenceType but of type "+objectref+".");
653 }
654
655
656
657
658
659
660 Constant c = cpg.getConstant(o.getIndex());
661 if (! (c instanceof ConstantClass)){
662 constraintViolated(o, "The Constant at 'index' is not a ConstantClass, but '"+c+"'.");
663 }
664 }
665
666 /***
667 * Ensures the specific preconditions of the said instruction.
668 */
669 public void visitD2F(D2F o){
670 if (stack().peek() != Type.DOUBLE){
671 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
672 }
673 }
674
675 /***
676 * Ensures the specific preconditions of the said instruction.
677 */
678 public void visitD2I(D2I o){
679 if (stack().peek() != Type.DOUBLE){
680 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
681 }
682 }
683
684 /***
685 * Ensures the specific preconditions of the said instruction.
686 */
687 public void visitD2L(D2L o){
688 if (stack().peek() != Type.DOUBLE){
689 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
690 }
691 }
692
693 /***
694 * Ensures the specific preconditions of the said instruction.
695 */
696 public void visitDADD(DADD o){
697 if (stack().peek() != Type.DOUBLE){
698 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
699 }
700 if (stack().peek(1) != Type.DOUBLE){
701 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
702 }
703 }
704
705 /***
706 * Ensures the specific preconditions of the said instruction.
707 */
708 public void visitDALOAD(DALOAD o){
709 indexOfInt(o, stack().peek());
710 if (stack().peek(1) == Type.NULL){
711 return;
712 }
713 if (! (stack().peek(1) instanceof ArrayType)){
714 constraintViolated(o, "Stack next-to-top must be of type double[] but is '"+stack().peek(1)+"'.");
715 }
716 Type t = ((ArrayType) (stack().peek(1))).getBasicType();
717 if (t != Type.DOUBLE){
718 constraintViolated(o, "Stack next-to-top must be of type double[] but is '"+stack().peek(1)+"'.");
719 }
720 }
721
722 /***
723 * Ensures the specific preconditions of the said instruction.
724 */
725 public void visitDASTORE(DASTORE o){
726 if (stack().peek() != Type.DOUBLE){
727 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
728 }
729 indexOfInt(o, stack().peek(1));
730 if (stack().peek(2) == Type.NULL){
731 return;
732 }
733 if (! (stack().peek(2) instanceof ArrayType)){
734 constraintViolated(o, "Stack next-to-next-to-top must be of type double[] but is '"+stack().peek(2)+"'.");
735 }
736 Type t = ((ArrayType) (stack().peek(2))).getBasicType();
737 if (t != Type.DOUBLE){
738 constraintViolated(o, "Stack next-to-next-to-top must be of type double[] but is '"+stack().peek(2)+"'.");
739 }
740 }
741
742 /***
743 * Ensures the specific preconditions of the said instruction.
744 */
745 public void visitDCMPG(DCMPG o){
746 if (stack().peek() != Type.DOUBLE){
747 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
748 }
749 if (stack().peek(1) != Type.DOUBLE){
750 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
751 }
752 }
753
754 /***
755 * Ensures the specific preconditions of the said instruction.
756 */
757 public void visitDCMPL(DCMPL o){
758 if (stack().peek() != Type.DOUBLE){
759 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
760 }
761 if (stack().peek(1) != Type.DOUBLE){
762 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
763 }
764 }
765
766 /***
767 * Ensures the specific preconditions of the said instruction.
768 */
769 public void visitDCONST(DCONST o){
770
771 }
772
773 /***
774 * Ensures the specific preconditions of the said instruction.
775 */
776 public void visitDDIV(DDIV o){
777 if (stack().peek() != Type.DOUBLE){
778 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
779 }
780 if (stack().peek(1) != Type.DOUBLE){
781 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
782 }
783 }
784
785 /***
786 * Ensures the specific preconditions of the said instruction.
787 */
788 public void visitDLOAD(DLOAD o){
789
790
791
792 }
793
794 /***
795 * Ensures the specific preconditions of the said instruction.
796 */
797 public void visitDMUL(DMUL o){
798 if (stack().peek() != Type.DOUBLE){
799 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
800 }
801 if (stack().peek(1) != Type.DOUBLE){
802 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
803 }
804 }
805
806 /***
807 * Ensures the specific preconditions of the said instruction.
808 */
809 public void visitDNEG(DNEG o){
810 if (stack().peek() != Type.DOUBLE){
811 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
812 }
813 }
814
815 /***
816 * Ensures the specific preconditions of the said instruction.
817 */
818 public void visitDREM(DREM o){
819 if (stack().peek() != Type.DOUBLE){
820 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
821 }
822 if (stack().peek(1) != Type.DOUBLE){
823 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
824 }
825 }
826
827 /***
828 * Ensures the specific preconditions of the said instruction.
829 */
830 public void visitDRETURN(DRETURN o){
831 if (stack().peek() != Type.DOUBLE){
832 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
833 }
834 }
835
836 /***
837 * Ensures the specific preconditions of the said instruction.
838 */
839 public void visitDSTORE(DSTORE o){
840
841
842
843 }
844
845 /***
846 * Ensures the specific preconditions of the said instruction.
847 */
848 public void visitDSUB(DSUB o){
849 if (stack().peek() != Type.DOUBLE){
850 constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'.");
851 }
852 if (stack().peek(1) != Type.DOUBLE){
853 constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'.");
854 }
855 }
856
857 /***
858 * Ensures the specific preconditions of the said instruction.
859 */
860 public void visitDUP(DUP o){
861 if (stack().peek().getSize() != 1){
862 constraintViolated(o, "Won't DUP type on stack top '"+stack().peek()+"' because it must occupy exactly one slot, not '"+stack().peek().getSize()+"'.");
863 }
864 }
865
866 /***
867 * Ensures the specific preconditions of the said instruction.
868 */
869 public void visitDUP_X1(DUP_X1 o){
870 if (stack().peek().getSize() != 1){
871 constraintViolated(o, "Type on stack top '"+stack().peek()+"' should occupy exactly one slot, not '"+stack().peek().getSize()+"'.");
872 }
873 if (stack().peek(1).getSize() != 1){
874 constraintViolated(o, "Type on stack next-to-top '"+stack().peek(1)+"' should occupy exactly one slot, not '"+stack().peek(1).getSize()+"'.");
875 }
876 }
877
878 /***
879 * Ensures the specific preconditions of the said instruction.
880 */
881 public void visitDUP_X2(DUP_X2 o){
882 if (stack().peek().getSize() != 1){
883 constraintViolated(o, "Stack top type must be of size 1, but is '"+stack().peek()+"' of size '"+stack().peek().getSize()+"'.");
884 }
885 if (stack().peek(1).getSize() == 2){
886 return;
887 }
888 else{
889 if (stack().peek(2).getSize() != 1){
890 constraintViolated(o, "If stack top's size is 1 and stack next-to-top's size is 1, stack next-to-next-to-top's size must also be 1, but is: '"+stack().peek(2)+"' of size '"+stack().peek(2).getSize()+"'.");
891 }
892 }
893 }
894
895 /***
896 * Ensures the specific preconditions of the said instruction.
897 */
898 public void visitDUP2(DUP2 o){
899 if (stack().peek().getSize() == 2){
900 return;
901 }
902 else{
903 if (stack().peek(1).getSize() != 1){
904 constraintViolated(o, "If stack top's size is 1, then stack next-to-top's size must also be 1. But it is '"+stack().peek(1)+"' of size '"+stack().peek(1).getSize()+"'.");
905 }
906 }
907 }
908
909 /***
910 * Ensures the specific preconditions of the said instruction.
911 */
912 public void visitDUP2_X1(DUP2_X1 o){
913 if (stack().peek().getSize() == 2){
914 if (stack().peek(1).getSize() != 1){
915 constraintViolated(o, "If stack top's size is 2, then stack next-to-top's size must be 1. But it is '"+stack().peek(1)+"' of size '"+stack().peek(1).getSize()+"'.");
916 }
917 else{
918 return;
919 }
920 }
921 else{
922 if ( stack().peek(1).getSize() != 1 ){
923 constraintViolated(o, "If stack top's size is 1, then stack next-to-top's size must also be 1. But it is '"+stack().peek(1)+"' of size '"+stack().peek(1).getSize()+"'.");
924 }
925 if ( stack().peek(2).getSize() != 1 ){
926 constraintViolated(o, "If stack top's size is 1, then stack next-to-next-to-top's size must also be 1. But it is '"+stack().peek(2)+"' of size '"+stack().peek(2).getSize()+"'.");
927 }
928 }
929 }
930
931 /***
932 * Ensures the specific preconditions of the said instruction.
933 */
934 public void visitDUP2_X2(DUP2_X2 o){
935
936 if (stack().peek(0).getSize() == 2){
937 if (stack().peek(1).getSize() == 2){
938 return;
939 }
940 else{
941 if ( stack().peek(2).getSize() != 1 ){
942 constraintViolated(o, "If stack top's size is 2 and stack-next-to-top's size is 1, then stack next-to-next-to-top's size must also be 1. But it is '"+stack().peek(2)+"' of size '"+stack().peek(2).getSize()+"'.");
943 }
944 else{
945 return;
946 }
947 }
948 }
949 else{
950 if (stack().peek(1).getSize() == 1){
951 if ( stack().peek(2).getSize() == 2 ){
952 return;
953 }
954 else{
955 if ( stack().peek(3).getSize() == 1){
956 return;
957 }
958 }
959 }
960 }
961 constraintViolated(o, "The operand sizes on the stack do not match any of the four forms of usage of this instruction.");
962 }
963
964 /***
965 * Ensures the specific preconditions of the said instruction.
966 */
967 public void visitF2D(F2D o){
968 if (stack().peek() != Type.FLOAT){
969 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
970 }
971 }
972
973 /***
974 * Ensures the specific preconditions of the said instruction.
975 */
976 public void visitF2I(F2I o){
977 if (stack().peek() != Type.FLOAT){
978 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
979 }
980 }
981
982 /***
983 * Ensures the specific preconditions of the said instruction.
984 */
985 public void visitF2L(F2L o){
986 if (stack().peek() != Type.FLOAT){
987 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
988 }
989 }
990
991 /***
992 * Ensures the specific preconditions of the said instruction.
993 */
994 public void visitFADD(FADD o){
995 if (stack().peek() != Type.FLOAT){
996 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
997 }
998 if (stack().peek(1) != Type.FLOAT){
999 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1000 }
1001 }
1002
1003 /***
1004 * Ensures the specific preconditions of the said instruction.
1005 */
1006 public void visitFALOAD(FALOAD o){
1007 indexOfInt(o, stack().peek());
1008 if (stack().peek(1) == Type.NULL){
1009 return;
1010 }
1011 if (! (stack().peek(1) instanceof ArrayType)){
1012 constraintViolated(o, "Stack next-to-top must be of type float[] but is '"+stack().peek(1)+"'.");
1013 }
1014 Type t = ((ArrayType) (stack().peek(1))).getBasicType();
1015 if (t != Type.FLOAT){
1016 constraintViolated(o, "Stack next-to-top must be of type float[] but is '"+stack().peek(1)+"'.");
1017 }
1018 }
1019
1020 /***
1021 * Ensures the specific preconditions of the said instruction.
1022 */
1023 public void visitFASTORE(FASTORE o){
1024 if (stack().peek() != Type.FLOAT){
1025 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1026 }
1027 indexOfInt(o, stack().peek(1));
1028 if (stack().peek(2) == Type.NULL){
1029 return;
1030 }
1031 if (! (stack().peek(2) instanceof ArrayType)){
1032 constraintViolated(o, "Stack next-to-next-to-top must be of type float[] but is '"+stack().peek(2)+"'.");
1033 }
1034 Type t = ((ArrayType) (stack().peek(2))).getBasicType();
1035 if (t != Type.FLOAT){
1036 constraintViolated(o, "Stack next-to-next-to-top must be of type float[] but is '"+stack().peek(2)+"'.");
1037 }
1038 }
1039
1040 /***
1041 * Ensures the specific preconditions of the said instruction.
1042 */
1043 public void visitFCMPG(FCMPG o){
1044 if (stack().peek() != Type.FLOAT){
1045 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1046 }
1047 if (stack().peek(1) != Type.FLOAT){
1048 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1049 }
1050 }
1051
1052 /***
1053 * Ensures the specific preconditions of the said instruction.
1054 */
1055 public void visitFCMPL(FCMPL o){
1056 if (stack().peek() != Type.FLOAT){
1057 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1058 }
1059 if (stack().peek(1) != Type.FLOAT){
1060 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1061 }
1062 }
1063
1064 /***
1065 * Ensures the specific preconditions of the said instruction.
1066 */
1067 public void visitFCONST(FCONST o){
1068
1069 }
1070
1071 /***
1072 * Ensures the specific preconditions of the said instruction.
1073 */
1074 public void visitFDIV(FDIV o){
1075 if (stack().peek() != Type.FLOAT){
1076 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1077 }
1078 if (stack().peek(1) != Type.FLOAT){
1079 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1080 }
1081 }
1082
1083 /***
1084 * Ensures the specific preconditions of the said instruction.
1085 */
1086 public void visitFLOAD(FLOAD o){
1087
1088
1089
1090 }
1091
1092 /***
1093 * Ensures the specific preconditions of the said instruction.
1094 */
1095 public void visitFMUL(FMUL o){
1096 if (stack().peek() != Type.FLOAT){
1097 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1098 }
1099 if (stack().peek(1) != Type.FLOAT){
1100 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1101 }
1102 }
1103
1104 /***
1105 * Ensures the specific preconditions of the said instruction.
1106 */
1107 public void visitFNEG(FNEG o){
1108 if (stack().peek() != Type.FLOAT){
1109 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1110 }
1111 }
1112
1113 /***
1114 * Ensures the specific preconditions of the said instruction.
1115 */
1116 public void visitFREM(FREM o){
1117 if (stack().peek() != Type.FLOAT){
1118 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1119 }
1120 if (stack().peek(1) != Type.FLOAT){
1121 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1122 }
1123 }
1124
1125 /***
1126 * Ensures the specific preconditions of the said instruction.
1127 */
1128 public void visitFRETURN(FRETURN o){
1129 if (stack().peek() != Type.FLOAT){
1130 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1131 }
1132 }
1133
1134 /***
1135 * Ensures the specific preconditions of the said instruction.
1136 */
1137 public void visitFSTORE(FSTORE o){
1138
1139
1140
1141 }
1142
1143 /***
1144 * Ensures the specific preconditions of the said instruction.
1145 */
1146 public void visitFSUB(FSUB o){
1147 if (stack().peek() != Type.FLOAT){
1148 constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'.");
1149 }
1150 if (stack().peek(1) != Type.FLOAT){
1151 constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'.");
1152 }
1153 }
1154
1155 /***
1156 * Ensures the specific preconditions of the said instruction.
1157 */
1158 public void visitGETFIELD(GETFIELD o){
1159 try {
1160 Type objectref = stack().peek();
1161 if (! ( (objectref instanceof ObjectType) || (objectref == Type.NULL) ) ){
1162 constraintViolated(o, "Stack top should be an object reference that's not an array reference, but is '"+objectref+"'.");
1163 }
1164
1165 String field_name = o.getFieldName(cpg);
1166
1167 JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName());
1168 Field[] fields = jc.getFields();
1169 Field f = null;
1170 for (int i=0; i<fields.length; i++){
1171 if (fields[i].getName().equals(field_name)){
1172 Type f_type = Type.getType(fields[i].getSignature());
1173 Type o_type = o.getType(cpg);
1174
1175
1176
1177 if (f_type.equals(o_type)){
1178 f = fields[i];
1179 break;
1180 }
1181 }
1182 }
1183
1184 if (f == null){
1185 JavaClass[] superclasses = jc.getSuperClasses();
1186 outer:
1187 for (int j=0; j<superclasses.length; j++){
1188 fields = superclasses[j].getFields();
1189 for (int i=0; i<fields.length; i++){
1190 if (fields[i].getName().equals(field_name)){
1191 Type f_type = Type.getType(fields[i].getSignature());
1192 Type o_type = o.getType(cpg);
1193 if (f_type.equals(o_type)){
1194 f = fields[i];
1195 if ((f.getAccessFlags() & (Constants.ACC_PUBLIC | Constants.ACC_PROTECTED)) == 0) {
1196 f = null;
1197 }
1198 break outer;
1199 }
1200 }
1201 }
1202 }
1203 if (f == null) {
1204 throw new AssertionViolatedException("Field '"+field_name+"' not found?!?");
1205 }
1206 }
1207
1208 if (f.isProtected()){
1209 ObjectType classtype = o.getClassType(cpg);
1210 ObjectType curr = new ObjectType(mg.getClassName());
1211
1212 if ( classtype.equals(curr) ||
1213 curr.subclassOf(classtype) ){
1214 Type t = stack().peek();
1215 if (t == Type.NULL){
1216 return;
1217 }
1218 if (! (t instanceof ObjectType) ){
1219 constraintViolated(o, "The 'objectref' must refer to an object that's not an array. Found instead: '"+t+"'.");
1220 }
1221 ObjectType objreftype = (ObjectType) t;
1222 if (! ( objreftype.equals(curr) ||
1223 objreftype.subclassOf(curr) ) ){
1224
1225
1226
1227
1228 }
1229 }
1230 }
1231
1232
1233 if (f.isStatic()){
1234 constraintViolated(o, "Referenced field '"+f+"' is static which it shouldn't be.");
1235 }
1236
1237 } catch (ClassNotFoundException e) {
1238
1239 throw new AssertionViolatedException("Missing class: " + e.toString());
1240 }
1241 }
1242
1243 /***
1244 * Ensures the specific preconditions of the said instruction.
1245 */
1246 public void visitGETSTATIC(GETSTATIC o){
1247
1248 }
1249
1250 /***
1251 * Ensures the specific preconditions of the said instruction.
1252 */
1253 public void visitGOTO(GOTO o){
1254
1255 }
1256
1257 /***
1258 * Ensures the specific preconditions of the said instruction.
1259 */
1260 public void visitGOTO_W(GOTO_W o){
1261
1262 }
1263
1264 /***
1265 * Ensures the specific preconditions of the said instruction.
1266 */
1267 public void visitI2B(I2B o){
1268 if (stack().peek() != Type.INT){
1269 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1270 }
1271 }
1272
1273 /***
1274 * Ensures the specific preconditions of the said instruction.
1275 */
1276 public void visitI2C(I2C o){
1277 if (stack().peek() != Type.INT){
1278 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1279 }
1280 }
1281
1282 /***
1283 * Ensures the specific preconditions of the said instruction.
1284 */
1285 public void visitI2D(I2D o){
1286 if (stack().peek() != Type.INT){
1287 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1288 }
1289 }
1290
1291 /***
1292 * Ensures the specific preconditions of the said instruction.
1293 */
1294 public void visitI2F(I2F o){
1295 if (stack().peek() != Type.INT){
1296 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1297 }
1298 }
1299
1300 /***
1301 * Ensures the specific preconditions of the said instruction.
1302 */
1303 public void visitI2L(I2L o){
1304 if (stack().peek() != Type.INT){
1305 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1306 }
1307 }
1308
1309 /***
1310 * Ensures the specific preconditions of the said instruction.
1311 */
1312 public void visitI2S(I2S o){
1313 if (stack().peek() != Type.INT){
1314 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1315 }
1316 }
1317
1318 /***
1319 * Ensures the specific preconditions of the said instruction.
1320 */
1321 public void visitIADD(IADD o){
1322 if (stack().peek() != Type.INT){
1323 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1324 }
1325 if (stack().peek(1) != Type.INT){
1326 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1327 }
1328 }
1329
1330 /***
1331 * Ensures the specific preconditions of the said instruction.
1332 */
1333 public void visitIALOAD(IALOAD o){
1334 indexOfInt(o, stack().peek());
1335 if (stack().peek(1) == Type.NULL){
1336 return;
1337 }
1338 if (! (stack().peek(1) instanceof ArrayType)){
1339 constraintViolated(o, "Stack next-to-top must be of type int[] but is '"+stack().peek(1)+"'.");
1340 }
1341 Type t = ((ArrayType) (stack().peek(1))).getBasicType();
1342 if (t != Type.INT){
1343 constraintViolated(o, "Stack next-to-top must be of type int[] but is '"+stack().peek(1)+"'.");
1344 }
1345 }
1346
1347 /***
1348 * Ensures the specific preconditions of the said instruction.
1349 */
1350 public void visitIAND(IAND o){
1351 if (stack().peek() != Type.INT){
1352 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1353 }
1354 if (stack().peek(1) != Type.INT){
1355 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1356 }
1357 }
1358
1359 /***
1360 * Ensures the specific preconditions of the said instruction.
1361 */
1362 public void visitIASTORE(IASTORE o){
1363 if (stack().peek() != Type.INT){
1364 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1365 }
1366 indexOfInt(o, stack().peek(1));
1367 if (stack().peek(2) == Type.NULL){
1368 return;
1369 }
1370 if (! (stack().peek(2) instanceof ArrayType)){
1371 constraintViolated(o, "Stack next-to-next-to-top must be of type int[] but is '"+stack().peek(2)+"'.");
1372 }
1373 Type t = ((ArrayType) (stack().peek(2))).getBasicType();
1374 if (t != Type.INT){
1375 constraintViolated(o, "Stack next-to-next-to-top must be of type int[] but is '"+stack().peek(2)+"'.");
1376 }
1377 }
1378
1379 /***
1380 * Ensures the specific preconditions of the said instruction.
1381 */
1382 public void visitICONST(ICONST o){
1383
1384 }
1385
1386 /***
1387 * Ensures the specific preconditions of the said instruction.
1388 */
1389 public void visitIDIV(IDIV o){
1390 if (stack().peek() != Type.INT){
1391 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1392 }
1393 if (stack().peek(1) != Type.INT){
1394 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1395 }
1396 }
1397
1398 /***
1399 * Ensures the specific preconditions of the said instruction.
1400 */
1401 public void visitIF_ACMPEQ(IF_ACMPEQ o){
1402 if (!(stack().peek() instanceof ReferenceType)){
1403 constraintViolated(o, "The value at the stack top is not of a ReferenceType, but of type '"+stack().peek()+"'.");
1404 }
1405
1406
1407 if (!(stack().peek(1) instanceof ReferenceType)){
1408 constraintViolated(o, "The value at the stack next-to-top is not of a ReferenceType, but of type '"+stack().peek(1)+"'.");
1409 }
1410
1411
1412 }
1413
1414 /***
1415 * Ensures the specific preconditions of the said instruction.
1416 */
1417 public void visitIF_ACMPNE(IF_ACMPNE o){
1418 if (!(stack().peek() instanceof ReferenceType)){
1419 constraintViolated(o, "The value at the stack top is not of a ReferenceType, but of type '"+stack().peek()+"'.");
1420
1421 }
1422 if (!(stack().peek(1) instanceof ReferenceType)){
1423 constraintViolated(o, "The value at the stack next-to-top is not of a ReferenceType, but of type '"+stack().peek(1)+"'.");
1424
1425 }
1426 }
1427
1428 /***
1429 * Ensures the specific preconditions of the said instruction.
1430 */
1431 public void visitIF_ICMPEQ(IF_ICMPEQ o){
1432 if (stack().peek() != Type.INT){
1433 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1434 }
1435 if (stack().peek(1) != Type.INT){
1436 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1437 }
1438 }
1439
1440 /***
1441 * Ensures the specific preconditions of the said instruction.
1442 */
1443 public void visitIF_ICMPGE(IF_ICMPGE o){
1444 if (stack().peek() != Type.INT){
1445 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1446 }
1447 if (stack().peek(1) != Type.INT){
1448 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1449 }
1450 }
1451
1452 /***
1453 * Ensures the specific preconditions of the said instruction.
1454 */
1455 public void visitIF_ICMPGT(IF_ICMPGT o){
1456 if (stack().peek() != Type.INT){
1457 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1458 }
1459 if (stack().peek(1) != Type.INT){
1460 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1461 }
1462 }
1463
1464 /***
1465 * Ensures the specific preconditions of the said instruction.
1466 */
1467 public void visitIF_ICMPLE(IF_ICMPLE o){
1468 if (stack().peek() != Type.INT){
1469 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1470 }
1471 if (stack().peek(1) != Type.INT){
1472 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1473 }
1474 }
1475
1476 /***
1477 * Ensures the specific preconditions of the said instruction.
1478 */
1479 public void visitIF_ICMPLT(IF_ICMPLT o){
1480 if (stack().peek() != Type.INT){
1481 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1482 }
1483 if (stack().peek(1) != Type.INT){
1484 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1485 }
1486 }
1487
1488 /***
1489 * Ensures the specific preconditions of the said instruction.
1490 */
1491 public void visitIF_ICMPNE(IF_ICMPNE o){
1492 if (stack().peek() != Type.INT){
1493 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1494 }
1495 if (stack().peek(1) != Type.INT){
1496 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1497 }
1498 }
1499
1500 /***
1501 * Ensures the specific preconditions of the said instruction.
1502 */
1503 public void visitIFEQ(IFEQ o){
1504 if (stack().peek() != Type.INT){
1505 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1506 }
1507 }
1508
1509 /***
1510 * Ensures the specific preconditions of the said instruction.
1511 */
1512 public void visitIFGE(IFGE o){
1513 if (stack().peek() != Type.INT){
1514 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1515 }
1516 }
1517
1518 /***
1519 * Ensures the specific preconditions of the said instruction.
1520 */
1521 public void visitIFGT(IFGT o){
1522 if (stack().peek() != Type.INT){
1523 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1524 }
1525 }
1526
1527 /***
1528 * Ensures the specific preconditions of the said instruction.
1529 */
1530 public void visitIFLE(IFLE o){
1531 if (stack().peek() != Type.INT){
1532 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1533 }
1534 }
1535
1536 /***
1537 * Ensures the specific preconditions of the said instruction.
1538 */
1539 public void visitIFLT(IFLT o){
1540 if (stack().peek() != Type.INT){
1541 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1542 }
1543 }
1544
1545 /***
1546 * Ensures the specific preconditions of the said instruction.
1547 */
1548 public void visitIFNE(IFNE o){
1549 if (stack().peek() != Type.INT){
1550 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1551 }
1552 }
1553
1554 /***
1555 * Ensures the specific preconditions of the said instruction.
1556 */
1557 public void visitIFNONNULL(IFNONNULL o){
1558 if (!(stack().peek() instanceof ReferenceType)){
1559 constraintViolated(o, "The value at the stack top is not of a ReferenceType, but of type '"+stack().peek()+"'.");
1560 }
1561 referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()) );
1562 }
1563
1564 /***
1565 * Ensures the specific preconditions of the said instruction.
1566 */
1567 public void visitIFNULL(IFNULL o){
1568 if (!(stack().peek() instanceof ReferenceType)){
1569 constraintViolated(o, "The value at the stack top is not of a ReferenceType, but of type '"+stack().peek()+"'.");
1570 }
1571 referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()) );
1572 }
1573
1574 /***
1575 * Ensures the specific preconditions of the said instruction.
1576 */
1577 public void visitIINC(IINC o){
1578
1579 if (locals().maxLocals() <= (o.getType(cpg).getSize()==1? o.getIndex() : o.getIndex()+1) ){
1580 constraintViolated(o, "The 'index' is not a valid index into the local variable array.");
1581 }
1582
1583 indexOfInt(o, locals().get(o.getIndex()));
1584 }
1585
1586 /***
1587 * Ensures the specific preconditions of the said instruction.
1588 */
1589 public void visitILOAD(ILOAD o){
1590
1591 }
1592
1593 /***
1594 * Ensures the specific preconditions of the said instruction.
1595 */
1596 public void visitIMPDEP1(IMPDEP1 o){
1597 throw new AssertionViolatedException("In this JustIce verification pass there should not occur an illegal instruction such as IMPDEP1.");
1598 }
1599
1600 /***
1601 * Ensures the specific preconditions of the said instruction.
1602 */
1603 public void visitIMPDEP2(IMPDEP2 o){
1604 throw new AssertionViolatedException("In this JustIce verification pass there should not occur an illegal instruction such as IMPDEP2.");
1605 }
1606
1607 /***
1608 * Ensures the specific preconditions of the said instruction.
1609 */
1610 public void visitIMUL(IMUL o){
1611 if (stack().peek() != Type.INT){
1612 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1613 }
1614 if (stack().peek(1) != Type.INT){
1615 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1616 }
1617 }
1618
1619 /***
1620 * Ensures the specific preconditions of the said instruction.
1621 */
1622 public void visitINEG(INEG o){
1623 if (stack().peek() != Type.INT){
1624 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1625 }
1626 }
1627
1628 /***
1629 * Ensures the specific preconditions of the said instruction.
1630 */
1631 public void visitINSTANCEOF(INSTANCEOF o){
1632
1633 Type objectref = stack().peek(0);
1634 if (!(objectref instanceof ReferenceType)){
1635 constraintViolated(o, "The 'objectref' is not of a ReferenceType but of type "+objectref+".");
1636 }
1637
1638
1639
1640
1641
1642
1643 Constant c = cpg.getConstant(o.getIndex());
1644 if (! (c instanceof ConstantClass)){
1645 constraintViolated(o, "The Constant at 'index' is not a ConstantClass, but '"+c+"'.");
1646 }
1647 }
1648
1649 /***
1650 * Ensures the specific preconditions of the said instruction.
1651 */
1652 public void visitINVOKEINTERFACE(INVOKEINTERFACE o){
1653
1654
1655 int count = o.getCount();
1656 if (count == 0){
1657 constraintViolated(o, "The 'count' argument must not be 0.");
1658 }
1659
1660
1661
1662
1663
1664
1665 Type t = o.getType(cpg);
1666 if (t instanceof ObjectType){
1667 String name = ((ObjectType)t).getClassName();
1668 Verifier v = VerifierFactory.getVerifier( name );
1669 VerificationResult vr = v.doPass2();
1670 if (vr.getStatus() != VerificationResult.VERIFIED_OK){
1671 constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'.");
1672 }
1673 }
1674
1675
1676 Type[] argtypes = o.getArgumentTypes(cpg);
1677 int nargs = argtypes.length;
1678
1679 for (int i=nargs-1; i>=0; i--){
1680 Type fromStack = stack().peek( (nargs-1) - i );
1681 Type fromDesc = argtypes[i];
1682 if (fromDesc == Type.BOOLEAN ||
1683 fromDesc == Type.BYTE ||
1684 fromDesc == Type.CHAR ||
1685 fromDesc == Type.SHORT){
1686 fromDesc = Type.INT;
1687 }
1688 if (! fromStack.equals(fromDesc)){
1689 if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){
1690 ReferenceType rFromStack = (ReferenceType) fromStack;
1691
1692
1693
1694
1695
1696
1697 referenceTypeIsInitialized(o, rFromStack);
1698 }
1699 else{
1700 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack.");
1701 }
1702 }
1703 }
1704
1705 Type objref = stack().peek(nargs);
1706 if (objref == Type.NULL){
1707 return;
1708 }
1709 if (! (objref instanceof ReferenceType) ){
1710 constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'.");
1711 }
1712 referenceTypeIsInitialized(o, (ReferenceType) objref);
1713 if (!(objref instanceof ObjectType)){
1714 if (!(objref instanceof ArrayType)){
1715 constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'.");
1716 }
1717 else{
1718 objref = GENERIC_ARRAY;
1719 }
1720 }
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730 int counted_count = 1;
1731 for (int i=0; i<nargs; i++){
1732 counted_count += argtypes[i].getSize();
1733 }
1734 if (count != counted_count){
1735 constraintViolated(o, "The 'count' argument should probably read '"+counted_count+"' but is '"+count+"'.");
1736 }
1737 }
1738
1739 /***
1740 * Ensures the specific preconditions of the said instruction.
1741 */
1742 public void visitINVOKESPECIAL(INVOKESPECIAL o){
1743 try {
1744
1745 if ( (o.getMethodName(cpg).equals(Constants.CONSTRUCTOR_NAME)) && (!(stack().peek(o.getArgumentTypes(cpg).length) instanceof UninitializedObjectType)) ){
1746 constraintViolated(o, "Possibly initializing object twice. A valid instruction sequence must not have an uninitialized object on the operand stack or in a local variable during a backwards branch, or in a local variable in code protected by an exception handler. Please see The Java Virtual Machine Specification, Second Edition, 4.9.4 (pages 147 and 148) for details.");
1747 }
1748
1749
1750
1751 Type t = o.getType(cpg);
1752 if (t instanceof ObjectType){
1753 String name = ((ObjectType)t).getClassName();
1754 Verifier v = VerifierFactory.getVerifier( name );
1755 VerificationResult vr = v.doPass2();
1756 if (vr.getStatus() != VerificationResult.VERIFIED_OK){
1757 constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'.");
1758 }
1759 }
1760
1761
1762 Type[] argtypes = o.getArgumentTypes(cpg);
1763 int nargs = argtypes.length;
1764
1765 for (int i=nargs-1; i>=0; i--){
1766 Type fromStack = stack().peek( (nargs-1) - i );
1767 Type fromDesc = argtypes[i];
1768 if (fromDesc == Type.BOOLEAN ||
1769 fromDesc == Type.BYTE ||
1770 fromDesc == Type.CHAR ||
1771 fromDesc == Type.SHORT){
1772 fromDesc = Type.INT;
1773 }
1774 if (! fromStack.equals(fromDesc)){
1775 if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){
1776 ReferenceType rFromStack = (ReferenceType) fromStack;
1777 ReferenceType rFromDesc = (ReferenceType) fromDesc;
1778
1779
1780 if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){
1781 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible).");
1782 }
1783 referenceTypeIsInitialized(o, rFromStack);
1784 }
1785 else{
1786 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack.");
1787 }
1788 }
1789 }
1790
1791 Type objref = stack().peek(nargs);
1792 if (objref == Type.NULL){
1793 return;
1794 }
1795 if (! (objref instanceof ReferenceType) ){
1796 constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'.");
1797 }
1798 String objref_classname = null;
1799 if ( !(o.getMethodName(cpg).equals(Constants.CONSTRUCTOR_NAME))){
1800 referenceTypeIsInitialized(o, (ReferenceType) objref);
1801 if (!(objref instanceof ObjectType)){
1802 if (!(objref instanceof ArrayType)){
1803 constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'.");
1804 }
1805 else{
1806 objref = GENERIC_ARRAY;
1807 }
1808 }
1809
1810 objref_classname = ((ObjectType) objref).getClassName();
1811 }
1812 else{
1813 if (!(objref instanceof UninitializedObjectType)){
1814 constraintViolated(o, "Expecting an UninitializedObjectType as 'objectref' on the stack, not a '"+objref+"'. Otherwise, you couldn't invoke a method since an array has no methods (not to speak of a return address).");
1815 }
1816 objref_classname = ((UninitializedObjectType) objref).getInitialized().getClassName();
1817 }
1818
1819
1820 String theClass = o.getClassName(cpg);
1821 if ( ! Repository.instanceOf(objref_classname, theClass) ){
1822 constraintViolated(o, "The 'objref' item '"+objref+"' does not implement '"+theClass+"' as expected.");
1823 }
1824
1825 } catch (ClassNotFoundException e) {
1826
1827 throw new AssertionViolatedException("Missing class: " + e.toString());
1828 }
1829 }
1830
1831 /***
1832 * Ensures the specific preconditions of the said instruction.
1833 */
1834 public void visitINVOKESTATIC(INVOKESTATIC o){
1835 try {
1836
1837
1838 Type t = o.getType(cpg);
1839 if (t instanceof ObjectType){
1840 String name = ((ObjectType)t).getClassName();
1841 Verifier v = VerifierFactory.getVerifier( name );
1842 VerificationResult vr = v.doPass2();
1843 if (vr.getStatus() != VerificationResult.VERIFIED_OK){
1844 constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'.");
1845 }
1846 }
1847
1848 Type[] argtypes = o.getArgumentTypes(cpg);
1849 int nargs = argtypes.length;
1850
1851 for (int i=nargs-1; i>=0; i--){
1852 Type fromStack = stack().peek( (nargs-1) - i );
1853 Type fromDesc = argtypes[i];
1854 if (fromDesc == Type.BOOLEAN ||
1855 fromDesc == Type.BYTE ||
1856 fromDesc == Type.CHAR ||
1857 fromDesc == Type.SHORT){
1858 fromDesc = Type.INT;
1859 }
1860 if (! fromStack.equals(fromDesc)){
1861 if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){
1862 ReferenceType rFromStack = (ReferenceType) fromStack;
1863 ReferenceType rFromDesc = (ReferenceType) fromDesc;
1864
1865
1866 if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){
1867 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible).");
1868 }
1869 referenceTypeIsInitialized(o, rFromStack);
1870 }
1871 else{
1872 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack.");
1873 }
1874 }
1875 }
1876 } catch (ClassNotFoundException e) {
1877
1878 throw new AssertionViolatedException("Missing class: " + e.toString());
1879 }
1880 }
1881
1882 /***
1883 * Ensures the specific preconditions of the said instruction.
1884 */
1885 public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o){
1886 try {
1887
1888
1889 Type t = o.getType(cpg);
1890 if (t instanceof ObjectType){
1891 String name = ((ObjectType)t).getClassName();
1892 Verifier v = VerifierFactory.getVerifier( name );
1893 VerificationResult vr = v.doPass2();
1894 if (vr.getStatus() != VerificationResult.VERIFIED_OK){
1895 constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'.");
1896 }
1897 }
1898
1899
1900 Type[] argtypes = o.getArgumentTypes(cpg);
1901 int nargs = argtypes.length;
1902
1903 for (int i=nargs-1; i>=0; i--){
1904 Type fromStack = stack().peek( (nargs-1) - i );
1905 Type fromDesc = argtypes[i];
1906 if (fromDesc == Type.BOOLEAN ||
1907 fromDesc == Type.BYTE ||
1908 fromDesc == Type.CHAR ||
1909 fromDesc == Type.SHORT){
1910 fromDesc = Type.INT;
1911 }
1912 if (! fromStack.equals(fromDesc)){
1913 if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){
1914 ReferenceType rFromStack = (ReferenceType) fromStack;
1915 ReferenceType rFromDesc = (ReferenceType) fromDesc;
1916
1917
1918 if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){
1919 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible).");
1920 }
1921 referenceTypeIsInitialized(o, rFromStack);
1922 }
1923 else{
1924 constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack.");
1925 }
1926 }
1927 }
1928
1929 Type objref = stack().peek(nargs);
1930 if (objref == Type.NULL){
1931 return;
1932 }
1933 if (! (objref instanceof ReferenceType) ){
1934 constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'.");
1935 }
1936 referenceTypeIsInitialized(o, (ReferenceType) objref);
1937 if (!(objref instanceof ObjectType)){
1938 if (!(objref instanceof ArrayType)){
1939 constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'.");
1940 }
1941 else{
1942 objref = GENERIC_ARRAY;
1943 }
1944 }
1945
1946 String objref_classname = ((ObjectType) objref).getClassName();
1947
1948 String theClass = o.getClassName(cpg);
1949
1950 if ( ! Repository.instanceOf(objref_classname, theClass) ){
1951 constraintViolated(o, "The 'objref' item '"+objref+"' does not implement '"+theClass+"' as expected.");
1952 }
1953 } catch (ClassNotFoundException e) {
1954
1955 throw new AssertionViolatedException("Missing class: " + e.toString());
1956 }
1957 }
1958
1959 /***
1960 * Ensures the specific preconditions of the said instruction.
1961 */
1962 public void visitIOR(IOR o){
1963 if (stack().peek() != Type.INT){
1964 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1965 }
1966 if (stack().peek(1) != Type.INT){
1967 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1968 }
1969 }
1970
1971 /***
1972 * Ensures the specific preconditions of the said instruction.
1973 */
1974 public void visitIREM(IREM o){
1975 if (stack().peek() != Type.INT){
1976 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1977 }
1978 if (stack().peek(1) != Type.INT){
1979 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
1980 }
1981 }
1982
1983 /***
1984 * Ensures the specific preconditions of the said instruction.
1985 */
1986 public void visitIRETURN(IRETURN o){
1987 if (stack().peek() != Type.INT){
1988 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1989 }
1990 }
1991
1992 /***
1993 * Ensures the specific preconditions of the said instruction.
1994 */
1995 public void visitISHL(ISHL o){
1996 if (stack().peek() != Type.INT){
1997 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
1998 }
1999 if (stack().peek(1) != Type.INT){
2000 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
2001 }
2002 }
2003
2004 /***
2005 * Ensures the specific preconditions of the said instruction.
2006 */
2007 public void visitISHR(ISHR o){
2008 if (stack().peek() != Type.INT){
2009 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2010 }
2011 if (stack().peek(1) != Type.INT){
2012 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
2013 }
2014 }
2015
2016 /***
2017 * Ensures the specific preconditions of the said instruction.
2018 */
2019 public void visitISTORE(ISTORE o){
2020
2021
2022
2023 }
2024
2025 /***
2026 * Ensures the specific preconditions of the said instruction.
2027 */
2028 public void visitISUB(ISUB o){
2029 if (stack().peek() != Type.INT){
2030 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2031 }
2032 if (stack().peek(1) != Type.INT){
2033 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
2034 }
2035 }
2036
2037 /***
2038 * Ensures the specific preconditions of the said instruction.
2039 */
2040 public void visitIUSHR(IUSHR o){
2041 if (stack().peek() != Type.INT){
2042 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2043 }
2044 if (stack().peek(1) != Type.INT){
2045 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
2046 }
2047 }
2048
2049 /***
2050 * Ensures the specific preconditions of the said instruction.
2051 */
2052 public void visitIXOR(IXOR o){
2053 if (stack().peek() != Type.INT){
2054 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2055 }
2056 if (stack().peek(1) != Type.INT){
2057 constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'.");
2058 }
2059 }
2060
2061 /***
2062 * Ensures the specific preconditions of the said instruction.
2063 */
2064 public void visitJSR(JSR o){
2065
2066 }
2067
2068 /***
2069 * Ensures the specific preconditions of the said instruction.
2070 */
2071 public void visitJSR_W(JSR_W o){
2072
2073 }
2074
2075 /***
2076 * Ensures the specific preconditions of the said instruction.
2077 */
2078 public void visitL2D(L2D o){
2079 if (stack().peek() != Type.LONG){
2080 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2081 }
2082 }
2083
2084 /***
2085 * Ensures the specific preconditions of the said instruction.
2086 */
2087 public void visitL2F(L2F o){
2088 if (stack().peek() != Type.LONG){
2089 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2090 }
2091 }
2092
2093 /***
2094 * Ensures the specific preconditions of the said instruction.
2095 */
2096 public void visitL2I(L2I o){
2097 if (stack().peek() != Type.LONG){
2098 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2099 }
2100 }
2101
2102 /***
2103 * Ensures the specific preconditions of the said instruction.
2104 */
2105 public void visitLADD(LADD o){
2106 if (stack().peek() != Type.LONG){
2107 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2108 }
2109 if (stack().peek(1) != Type.LONG){
2110 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2111 }
2112 }
2113
2114 /***
2115 * Ensures the specific preconditions of the said instruction.
2116 */
2117 public void visitLALOAD(LALOAD o){
2118 indexOfInt(o, stack().peek());
2119 if (stack().peek(1) == Type.NULL){
2120 return;
2121 }
2122 if (! (stack().peek(1) instanceof ArrayType)){
2123 constraintViolated(o, "Stack next-to-top must be of type long[] but is '"+stack().peek(1)+"'.");
2124 }
2125 Type t = ((ArrayType) (stack().peek(1))).getBasicType();
2126 if (t != Type.LONG){
2127 constraintViolated(o, "Stack next-to-top must be of type long[] but is '"+stack().peek(1)+"'.");
2128 }
2129 }
2130
2131 /***
2132 * Ensures the specific preconditions of the said instruction.
2133 */
2134 public void visitLAND(LAND o){
2135 if (stack().peek() != Type.LONG){
2136 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2137 }
2138 if (stack().peek(1) != Type.LONG){
2139 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2140 }
2141 }
2142
2143 /***
2144 * Ensures the specific preconditions of the said instruction.
2145 */
2146 public void visitLASTORE(LASTORE o){
2147 if (stack().peek() != Type.LONG){
2148 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2149 }
2150 indexOfInt(o, stack().peek(1));
2151 if (stack().peek(2) == Type.NULL){
2152 return;
2153 }
2154 if (! (stack().peek(2) instanceof ArrayType)){
2155 constraintViolated(o, "Stack next-to-next-to-top must be of type long[] but is '"+stack().peek(2)+"'.");
2156 }
2157 Type t = ((ArrayType) (stack().peek(2))).getBasicType();
2158 if (t != Type.LONG){
2159 constraintViolated(o, "Stack next-to-next-to-top must be of type long[] but is '"+stack().peek(2)+"'.");
2160 }
2161 }
2162
2163 /***
2164 * Ensures the specific preconditions of the said instruction.
2165 */
2166 public void visitLCMP(LCMP o){
2167 if (stack().peek() != Type.LONG){
2168 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2169 }
2170 if (stack().peek(1) != Type.LONG){
2171 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2172 }
2173 }
2174
2175 /***
2176 * Ensures the specific preconditions of the said instruction.
2177 */
2178 public void visitLCONST(LCONST o){
2179
2180 }
2181
2182 /***
2183 * Ensures the specific preconditions of the said instruction.
2184 */
2185 public void visitLDC(LDC o){
2186
2187
2188 Constant c = cpg.getConstant(o.getIndex());
2189 if (! ( ( c instanceof ConstantInteger) ||
2190 ( c instanceof ConstantFloat ) ||
2191 ( c instanceof ConstantString ) ) ){
2192 constraintViolated(o, "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String, but is '"+c+"'.");
2193 }
2194 }
2195
2196 /***
2197 * Ensures the specific preconditions of the said instruction.
2198 */
2199 public void visitLDC_W(LDC_W o){
2200
2201
2202 Constant c = cpg.getConstant(o.getIndex());
2203 if (! ( ( c instanceof ConstantInteger) ||
2204 ( c instanceof ConstantFloat ) ||
2205 ( c instanceof ConstantString ) ) ){
2206 constraintViolated(o, "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String, but is '"+c+"'.");
2207 }
2208 }
2209
2210 /***
2211 * Ensures the specific preconditions of the said instruction.
2212 */
2213 public void visitLDC2_W(LDC2_W o){
2214
2215
2216 Constant c = cpg.getConstant(o.getIndex());
2217 if (! ( ( c instanceof ConstantLong) ||
2218 ( c instanceof ConstantDouble ) ) ){
2219 constraintViolated(o, "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String, but is '"+c+"'.");
2220 }
2221 }
2222
2223 /***
2224 * Ensures the specific preconditions of the said instruction.
2225 */
2226 public void visitLDIV(LDIV o){
2227 if (stack().peek() != Type.LONG){
2228 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2229 }
2230 if (stack().peek(1) != Type.LONG){
2231 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2232 }
2233 }
2234
2235 /***
2236 * Ensures the specific preconditions of the said instruction.
2237 */
2238 public void visitLLOAD(LLOAD o){
2239
2240
2241
2242 }
2243
2244 /***
2245 * Ensures the specific preconditions of the said instruction.
2246 */
2247 public void visitLMUL(LMUL o){
2248 if (stack().peek() != Type.LONG){
2249 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2250 }
2251 if (stack().peek(1) != Type.LONG){
2252 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2253 }
2254 }
2255
2256 /***
2257 * Ensures the specific preconditions of the said instruction.
2258 */
2259 public void visitLNEG(LNEG o){
2260 if (stack().peek() != Type.LONG){
2261 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2262 }
2263 }
2264
2265 /***
2266 * Ensures the specific preconditions of the said instruction.
2267 */
2268 public void visitLOOKUPSWITCH(LOOKUPSWITCH o){
2269 if (stack().peek() != Type.INT){
2270 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2271 }
2272
2273 }
2274
2275 /***
2276 * Ensures the specific preconditions of the said instruction.
2277 */
2278 public void visitLOR(LOR o){
2279 if (stack().peek() != Type.LONG){
2280 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2281 }
2282 if (stack().peek(1) != Type.LONG){
2283 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2284 }
2285 }
2286
2287 /***
2288 * Ensures the specific preconditions of the said instruction.
2289 */
2290 public void visitLREM(LREM o){
2291 if (stack().peek() != Type.LONG){
2292 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2293 }
2294 if (stack().peek(1) != Type.LONG){
2295 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2296 }
2297 }
2298
2299 /***
2300 * Ensures the specific preconditions of the said instruction.
2301 */
2302 public void visitLRETURN(LRETURN o){
2303 if (stack().peek() != Type.LONG){
2304 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2305 }
2306 }
2307
2308 /***
2309 * Ensures the specific preconditions of the said instruction.
2310 */
2311 public void visitLSHL(LSHL o){
2312 if (stack().peek() != Type.INT){
2313 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2314 }
2315 if (stack().peek(1) != Type.LONG){
2316 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2317 }
2318 }
2319
2320 /***
2321 * Ensures the specific preconditions of the said instruction.
2322 */
2323 public void visitLSHR(LSHR o){
2324 if (stack().peek() != Type.INT){
2325 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2326 }
2327 if (stack().peek(1) != Type.LONG){
2328 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2329 }
2330 }
2331
2332 /***
2333 * Ensures the specific preconditions of the said instruction.
2334 */
2335 public void visitLSTORE(LSTORE o){
2336
2337
2338
2339 }
2340
2341 /***
2342 * Ensures the specific preconditions of the said instruction.
2343 */
2344 public void visitLSUB(LSUB o){
2345 if (stack().peek() != Type.LONG){
2346 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2347 }
2348 if (stack().peek(1) != Type.LONG){
2349 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2350 }
2351 }
2352
2353 /***
2354 * Ensures the specific preconditions of the said instruction.
2355 */
2356 public void visitLUSHR(LUSHR o){
2357 if (stack().peek() != Type.INT){
2358 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2359 }
2360 if (stack().peek(1) != Type.LONG){
2361 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2362 }
2363 }
2364
2365 /***
2366 * Ensures the specific preconditions of the said instruction.
2367 */
2368 public void visitLXOR(LXOR o){
2369 if (stack().peek() != Type.LONG){
2370 constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'.");
2371 }
2372 if (stack().peek(1) != Type.LONG){
2373 constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'.");
2374 }
2375 }
2376
2377 /***
2378 * Ensures the specific preconditions of the said instruction.
2379 */
2380 public void visitMONITORENTER(MONITORENTER o){
2381 if (! ((stack().peek()) instanceof ReferenceType)){
2382 constraintViolated(o, "The stack top should be of a ReferenceType, but is '"+stack().peek()+"'.");
2383 }
2384
2385 }
2386
2387 /***
2388 * Ensures the specific preconditions of the said instruction.
2389 */
2390 public void visitMONITOREXIT(MONITOREXIT o){
2391 if (! ((stack().peek()) instanceof ReferenceType)){
2392 constraintViolated(o, "The stack top should be of a ReferenceType, but is '"+stack().peek()+"'.");
2393 }
2394
2395 }
2396
2397 /***
2398 * Ensures the specific preconditions of the said instruction.
2399 */
2400 public void visitMULTIANEWARRAY(MULTIANEWARRAY o){
2401 int dimensions = o.getDimensions();
2402
2403 for (int i=0; i<dimensions; i++){
2404 if (stack().peek(i) != Type.INT){
2405 constraintViolated(o, "The '"+dimensions+"' upper stack types should be 'int' but aren't.");
2406 }
2407 }
2408
2409
2410 }
2411
2412 /***
2413 * Ensures the specific preconditions of the said instruction.
2414 */
2415 public void visitNEW(NEW o){
2416
2417
2418
2419 Type t = o.getType(cpg);
2420 if (! (t instanceof ReferenceType)){
2421 throw new AssertionViolatedException("NEW.getType() returning a non-reference type?!");
2422 }
2423 if (! (t instanceof ObjectType)){
2424 constraintViolated(o, "Expecting a class type (ObjectType) to work on. Found: '"+t+"'.");
2425 }
2426 ObjectType obj = (ObjectType) t;
2427
2428
2429 if (! obj.referencesClass()){
2430 constraintViolated(o, "Expecting a class type (ObjectType) to work on. Found: '"+obj+"'.");
2431 }
2432 }
2433
2434 /***
2435 * Ensures the specific preconditions of the said instruction.
2436 */
2437 public void visitNEWARRAY(NEWARRAY o){
2438 if (stack().peek() != Type.INT){
2439 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2440 }
2441 }
2442
2443 /***
2444 * Ensures the specific preconditions of the said instruction.
2445 */
2446 public void visitNOP(NOP o){
2447
2448 }
2449
2450 /***
2451 * Ensures the specific preconditions of the said instruction.
2452 */
2453 public void visitPOP(POP o){
2454 if (stack().peek().getSize() != 1){
2455 constraintViolated(o, "Stack top size should be 1 but stack top is '"+stack().peek()+"' of size '"+stack().peek().getSize()+"'.");
2456 }
2457 }
2458
2459 /***
2460 * Ensures the specific preconditions of the said instruction.
2461 */
2462 public void visitPOP2(POP2 o){
2463 if (stack().peek().getSize() != 2){
2464 constraintViolated(o, "Stack top size should be 2 but stack top is '"+stack().peek()+"' of size '"+stack().peek().getSize()+"'.");
2465 }
2466 }
2467
2468 /***
2469 * Ensures the specific preconditions of the said instruction.
2470 */
2471 public void visitPUTFIELD(PUTFIELD o){
2472 try {
2473
2474 Type objectref = stack().peek(1);
2475 if (! ( (objectref instanceof ObjectType) || (objectref == Type.NULL) ) ){
2476 constraintViolated(o, "Stack next-to-top should be an object reference that's not an array reference, but is '"+objectref+"'.");
2477 }
2478
2479 String field_name = o.getFieldName(cpg);
2480
2481 JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName());
2482 Field[] fields = jc.getFields();
2483 Field f = null;
2484 for (int i=0; i<fields.length; i++){
2485 if (fields[i].getName().equals(field_name)){
2486 Type f_type = Type.getType(fields[i].getSignature());
2487 Type o_type = o.getType(cpg);
2488
2489
2490
2491 if (f_type.equals(o_type)){
2492 f = fields[i];
2493 break;
2494 }
2495 }
2496 }
2497 if (f == null){
2498 throw new AssertionViolatedException("Field not found?!?");
2499 }
2500
2501 Type value = stack().peek();
2502 Type t = Type.getType(f.getSignature());
2503 Type shouldbe = t;
2504 if (shouldbe == Type.BOOLEAN ||
2505 shouldbe == Type.BYTE ||
2506 shouldbe == Type.CHAR ||
2507 shouldbe == Type.SHORT){
2508 shouldbe = Type.INT;
2509 }
2510 if (t instanceof ReferenceType){
2511 ReferenceType rvalue = null;
2512 if (value instanceof ReferenceType){
2513 rvalue = (ReferenceType) value;
2514 referenceTypeIsInitialized(o, rvalue);
2515 }
2516 else{
2517 constraintViolated(o, "The stack top type '"+value+"' is not of a reference type as expected.");
2518 }
2519
2520
2521
2522 if (!(rvalue.isAssignmentCompatibleWith(shouldbe))){
2523 constraintViolated(o, "The stack top type '"+value+"' is not assignment compatible with '"+shouldbe+"'.");
2524 }
2525 }
2526 else{
2527 if (shouldbe != value){
2528 constraintViolated(o, "The stack top type '"+value+"' is not of type '"+shouldbe+"' as expected.");
2529 }
2530 }
2531
2532 if (f.isProtected()){
2533 ObjectType classtype = o.getClassType(cpg);
2534 ObjectType curr = new ObjectType(mg.getClassName());
2535
2536 if ( classtype.equals(curr) ||
2537 curr.subclassOf(classtype) ){
2538 Type tp = stack().peek(1);
2539 if (tp == Type.NULL){
2540 return;
2541 }
2542 if (! (tp instanceof ObjectType) ){
2543 constraintViolated(o, "The 'objectref' must refer to an object that's not an array. Found instead: '"+tp+"'.");
2544 }
2545 ObjectType objreftype = (ObjectType) tp;
2546 if (! ( objreftype.equals(curr) ||
2547 objreftype.subclassOf(curr) ) ){
2548 constraintViolated(o, "The referenced field has the ACC_PROTECTED modifier, and it's a member of the current class or a superclass of the current class. However, the referenced object type '"+stack().peek()+"' is not the current class or a subclass of the current class.");
2549 }
2550 }
2551 }
2552
2553
2554 if (f.isStatic()){
2555 constraintViolated(o, "Referenced field '"+f+"' is static which it shouldn't be.");
2556 }
2557
2558 } catch (ClassNotFoundException e) {
2559
2560 throw new AssertionViolatedException("Missing class: " + e.toString());
2561 }
2562 }
2563
2564 /***
2565 * Ensures the specific preconditions of the said instruction.
2566 */
2567 public void visitPUTSTATIC(PUTSTATIC o){
2568 try {
2569 String field_name = o.getFieldName(cpg);
2570 JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName());
2571 Field[] fields = jc.getFields();
2572 Field f = null;
2573 for (int i=0; i<fields.length; i++){
2574 if (fields[i].getName().equals(field_name)){
2575 Type f_type = Type.getType(fields[i].getSignature());
2576 Type o_type = o.getType(cpg);
2577
2578
2579
2580 if (f_type.equals(o_type)){
2581 f = fields[i];
2582 break;
2583 }
2584 }
2585 }
2586 if (f == null){
2587 throw new AssertionViolatedException("Field not found?!?");
2588 }
2589 Type value = stack().peek();
2590 Type t = Type.getType(f.getSignature());
2591 Type shouldbe = t;
2592 if (shouldbe == Type.BOOLEAN ||
2593 shouldbe == Type.BYTE ||
2594 shouldbe == Type.CHAR ||
2595 shouldbe == Type.SHORT){
2596 shouldbe = Type.INT;
2597 }
2598 if (t instanceof ReferenceType){
2599 ReferenceType rvalue = null;
2600 if (value instanceof ReferenceType){
2601 rvalue = (ReferenceType) value;
2602 referenceTypeIsInitialized(o, rvalue);
2603 }
2604 else{
2605 constraintViolated(o, "The stack top type '"+value+"' is not of a reference type as expected.");
2606 }
2607
2608
2609
2610 if (!(rvalue.isAssignmentCompatibleWith(shouldbe))){
2611 constraintViolated(o, "The stack top type '"+value+"' is not assignment compatible with '"+shouldbe+"'.");
2612 }
2613 }
2614 else{
2615 if (shouldbe != value){
2616 constraintViolated(o, "The stack top type '"+value+"' is not of type '"+shouldbe+"' as expected.");
2617 }
2618 }
2619
2620
2621
2622 } catch (ClassNotFoundException e) {
2623
2624 throw new AssertionViolatedException("Missing class: " + e.toString());
2625 }
2626 }
2627
2628 /***
2629 * Ensures the specific preconditions of the said instruction.
2630 */
2631 public void visitRET(RET o){
2632 if (! (locals().get(o.getIndex()) instanceof ReturnaddressType)){
2633 constraintViolated(o, "Expecting a ReturnaddressType in local variable "+o.getIndex()+".");
2634 }
2635 if (locals().get(o.getIndex()) == ReturnaddressType.NO_TARGET){
2636 throw new AssertionViolatedException("Oops: RET expecting a target!");
2637 }
2638
2639
2640 }
2641
2642 /***
2643 * Ensures the specific preconditions of the said instruction.
2644 */
2645 public void visitRETURN(RETURN o){
2646 if (mg.getName().equals(Constants.CONSTRUCTOR_NAME)){
2647 if ((Frame._this != null) && (!(mg.getClassName().equals(Type.OBJECT.getClassName()))) ) {
2648 constraintViolated(o, "Leaving a constructor that itself did not call a constructor.");
2649 }
2650 }
2651 }
2652
2653 /***
2654 * Ensures the specific preconditions of the said instruction.
2655 */
2656 public void visitSALOAD(SALOAD o){
2657 indexOfInt(o, stack().peek());
2658 if (stack().peek(1) == Type.NULL){
2659 return;
2660 }
2661 if (! (stack().peek(1) instanceof ArrayType)){
2662 constraintViolated(o, "Stack next-to-top must be of type short[] but is '"+stack().peek(1)+"'.");
2663 }
2664 Type t = ((ArrayType) (stack().peek(1))).getBasicType();
2665 if (t != Type.SHORT){
2666 constraintViolated(o, "Stack next-to-top must be of type short[] but is '"+stack().peek(1)+"'.");
2667 }
2668 }
2669
2670 /***
2671 * Ensures the specific preconditions of the said instruction.
2672 */
2673 public void visitSASTORE(SASTORE o){
2674 if (stack().peek() != Type.INT){
2675 constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'.");
2676 }
2677 indexOfInt(o, stack().peek(1));
2678 if (stack().peek(2) == Type.NULL){
2679 return;
2680 }
2681 if (! (stack().peek(2) instanceof ArrayType)){
2682 constraintViolated(o, "Stack next-to-next-to-top must be of type short[] but is '"+stack().peek(2)+"'.");
2683 }
2684 Type t = ((ArrayType) (stack().peek(2))).getBasicType();
2685 if (t != Type.SHORT){
2686 constraintViolated(o, "Stack next-to-next-to-top must be of type short[] but is '"+stack().peek(2)+"'.");
2687 }
2688 }
2689
2690 /***
2691 * Ensures the specific preconditions of the said instruction.
2692 */
2693 public void visitSIPUSH(SIPUSH o){
2694
2695 }
2696
2697 /***
2698 * Ensures the specific preconditions of the said instruction.
2699 */
2700 public void visitSWAP(SWAP o){
2701 if (stack().peek().getSize() != 1){
2702 constraintViolated(o, "The value at the stack top is not of size '1', but of size '"+stack().peek().getSize()+"'.");
2703 }
2704 if (stack().peek(1).getSize() != 1){
2705 constraintViolated(o, "The value at the stack next-to-top is not of size '1', but of size '"+stack().peek(1).getSize()+"'.");
2706 }
2707 }
2708
2709 /***
2710 * Ensures the specific preconditions of the said instruction.
2711 */
2712 public void visitTABLESWITCH(TABLESWITCH o){
2713 indexOfInt(o, stack().peek());
2714
2715 }
2716
2717 }
2718