001: //
002: // Copyright (C) 2005 United States Government as represented by the
003: // Administrator of the National Aeronautics and Space Administration
004: // (NASA). All Rights Reserved.
005: //
006: // This software is distributed under the NASA Open Source Agreement
007: // (NOSA), version 1.3. The NOSA has been approved by the Open Source
008: // Initiative. See the file NOSA-1.3-JPF at the top of the distribution
009: // directory tree for the complete NOSA document.
010: //
011: // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012: // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013: // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014: // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015: // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016: // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017: // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018: //
019: package gov.nasa.jpf.jvm.bytecode;
020:
021: import gov.nasa.jpf.jvm.ClassInfo;
022: import gov.nasa.jpf.jvm.KernelState;
023: import gov.nasa.jpf.jvm.MethodInfo;
024: import gov.nasa.jpf.jvm.SystemState;
025: import gov.nasa.jpf.jvm.ThreadInfo;
026:
027: /**
028: * Invoke instance method; special handling for superclass, private,
029: * and instance initialization method invocations
030: * ..., objectref, [arg1, [arg2 ...]] => ...
031: */
032: public class INVOKESPECIAL extends InvokeInstruction {
033: public INVOKESPECIAL() {
034: }
035:
036: public INVOKESPECIAL(MethodInfo mi, String cname, String mname,
037: String signature, int offset, int position) {
038: super (mi, cname, mname, signature, offset, position);
039: }
040:
041: public int getByteCode() {
042: return 0xB7;
043: }
044:
045: public boolean isDeterministic(SystemState ss, KernelState ks,
046: ThreadInfo th) {
047: MethodInfo mi = getInvokedMethod(th, ks);
048: if (mi == null) {
049: return true;
050: }
051:
052: return mi.isDeterministic(th);
053: }
054:
055: public boolean isExecutable(SystemState ss, KernelState ks,
056: ThreadInfo th) {
057: MethodInfo mi = getInvokedMethod(th, ks);
058: if (mi == null) {
059: return true;
060: }
061:
062: return mi.isExecutable(th);
063: }
064:
065: public Instruction execute(SystemState ss, KernelState ks,
066: ThreadInfo th) {
067: MethodInfo mi = getInvokedMethod(th, ks);
068: if (mi == null) {
069: return th.createAndThrowException(
070: "java.lang.NoSuchMethodException", "calling "
071: + cname + "." + mname);
072: }
073:
074: return mi.execute(th, false);
075: }
076:
077: int getCalleeThis(ThreadInfo ti) {
078: return ti.getCalleeThis(getArgSize());
079: }
080:
081: public boolean isSchedulingRelevant(SystemState ss, KernelState ks,
082: ThreadInfo ti) {
083: MethodInfo mi = getInvokedMethod(ti, ks);
084: int objRef = getCalleeThis(ti);
085:
086: return mi.isSchedulingRelevant(ti, ks.da.get(objRef));
087: }
088:
089: /**
090: * we can do some more caching here - the MethodInfo should be const
091: */
092: MethodInfo getInvokedMethod(ThreadInfo th, KernelState ks) {
093:
094: // since INVOKESPECIAL is only used for private methods and ctors,
095: // we don't have to deal with null object calls
096:
097: if (invokedMethod == null) {
098: ClassInfo ci = ClassInfo.getClassInfo(cname);
099: invokedMethod = ci.getMethod(mname, true);
100: }
101:
102: return invokedMethod; // we can store internally
103: }
104: }
|