// // Copyright (C) 2006 United States Government as represented by the // Administrator of the National Aeronautics and Space Administration // (NASA). All Rights Reserved. // // This software is distributed under the NASA Open Source Agreement // (NOSA), version 1.3. The NOSA has been approved by the Open Source // Initiative. See the file NOSA-1.3-JPF at the top of the distribution // directory tree for the complete NOSA document. // // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.test.vm.basic; import org.junit.Test; import gov.nasa.jpf.util.test.TestJPF; /** * basic method invocation test */ interface TMI { void gna(); } class TestMethodBase extends TestJPF implements TMI { int baseData; static int sData; static { sData = -1; } static void taz () { sData = 24; } TestMethodBase (int a) { assert a == 42; baseData = 42; } boolean baz (boolean p, byte b, char c, short s, int i, long l, float f, double d, Object o) { assert p; assert b == 4; assert c == '?'; assert s == 42; assert i == 4242; assert l == 424242; assert f == 4.2f; assert d == 4.242; assert o.equals(new Integer(42)); baseData = 44; return p; } void faz () { gna(); } public void gna () { baseData = 0; } int har () { return priv(); } private int priv () { return 7; } } public class MethodTest extends TestMethodBase { int data; static void taz () { sData = 9; } public MethodTest () { super(42); data = 42; } MethodTest (int a) { super(a); data = a; } double foo (boolean p, byte b, char c, short s, int i, long l, float f, double d, Object o) { assert p; assert b == 4; assert c == '?'; assert s == 42; assert i == 4242; assert l == 424242; assert f == 4.2f; assert d == 4.242; assert o.equals(new Integer(42)); data = 43; return d; } public void gna () { baseData = 45; } int priv () { return 8; } @Test public void testCtor() { if (verifyNoPropertyViolation()) { MethodTest o1 = new MethodTest(); assert o1.data == 42; assert o1.baseData == 42; MethodTest o2 = new MethodTest(42); assert o2.data == 42; assert o2.baseData == 42; } } @Test public void testCall() { if (verifyNoPropertyViolation()) { MethodTest o = new MethodTest(); assert o.foo(true, (byte) 4, '?', (short) 42, 4242, 424242, 4.2f, 4.242, new Integer(42)) == 4.242; assert o.data == 43; } } @Test public void testInheritedCall() { if (verifyNoPropertyViolation()) { MethodTest o = new MethodTest(); assert o.baz(true, (byte) 4, '?', (short) 42, 4242, 424242, 4.2f, 4.242, new Integer(42)); assert o.baseData == 44; } } @Test public void testVirtualCall() { if (verifyNoPropertyViolation()) { MethodTest o = new MethodTest(); TestMethodBase b = o; b.faz(); assert o.baseData == 45; } } @Test public void testSpecialCall() { if (verifyNoPropertyViolation()) { MethodTest o = new MethodTest(); assert o.har() == 7; } } @Test public void testStaticCall() { if (verifyNoPropertyViolation()) { assert TestMethodBase.sData == -1; MethodTest.taz(); assert TestMethodBase.sData == 9; TestMethodBase.taz(); assert TestMethodBase.sData == 24; // used to be: //TestMethod o = new TestMethod(); //o.taz(); // statically equiv. to this: (no warnings) - pcd new MethodTest(); MethodTest.taz(); assert TestMethodBase.sData == 9; } } @Test public void testInterfaceCall() { if (verifyNoPropertyViolation()) { MethodTest o = new MethodTest(); TMI ifc = o; ifc.gna(); assert o.baseData == 45; } } static class A { public int foo () { assert false : "should bever be invoked"; return -1; } } static class A0 extends A { public int foo () { return 0; } } static class A1 extends A { public int foo () { return 1; } } /** * this is tricky - both the allocations and the foo() calls have to be * the same instructions, and we have to remove all 'a' references before * forcing a GC. Otherwise we don't allocate 'a's with the same reference values * */ @Test public void testCallAcrossGC () { if (verifyNoPropertyViolation()){ System.out.println("testing virtual calls on GC boundaries"); A a; a = new A0(); assert a.foo() == 0 : "wrong A.foo() called for A0"; // do a GC Runtime.getRuntime().gc(); // this should recycle 'a' a = new A1(); assert a.foo() == 1 : "wrong A.foo() called for A1"; } } }