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 a class (static) method
029: * ..., [arg1, [arg2 ...]] => ...
030: */
031: public class INVOKESTATIC extends InvokeInstruction {
032: ClassInfo ci;
033:
034: public INVOKESTATIC() {
035: }
036:
037: public INVOKESTATIC(MethodInfo mi, String cname, String mname,
038: String signature, int offset, int position) {
039: super (mi, cname, mname, signature, offset, position);
040: }
041:
042: ClassInfo getClassInfo() {
043: if (ci == null) {
044: ci = ClassInfo.getClassInfo(cname);
045: }
046: return ci;
047: }
048:
049: public int getByteCode() {
050: return 0xB8;
051: }
052:
053: public boolean isDeterministic(SystemState ss, KernelState ks,
054: ThreadInfo ti) {
055: MethodInfo mi = getInvokedMethod();
056: if (mi == null) {
057: return true; // doesn't really matter
058: }
059:
060: return mi.isDeterministic(ti);
061: }
062:
063: public boolean isExecutable(SystemState ss, KernelState ks,
064: ThreadInfo ti) {
065: MethodInfo mi = getInvokedMethod();
066: if (mi == null) {
067: return true; // execute so that we get the exception
068: }
069:
070: return mi.isExecutable(ti);
071: }
072:
073: public boolean examineAbstraction(SystemState ss, KernelState ks,
074: ThreadInfo ti) {
075: MethodInfo mi = getInvokedMethod();
076:
077: if (mi == null) {
078: return true;
079: }
080:
081: return !ci.isStaticMethodAbstractionDeterministic(ti, mi);
082: }
083:
084: public Instruction execute(SystemState ss, KernelState ks,
085: ThreadInfo ti) {
086: // make sure the class got initialized, if this is not the '<clinit>'
087: // itself (note this could be a backtracked state where the class wasn't
088: // initialized yet, i.e. we can't store it here - how bad)
089: if (mname.charAt(0) != '<') {
090: ks.sa.get(cname);
091: }
092:
093: MethodInfo mi = getInvokedMethod();
094: if (mi == null) {
095: return ti.createAndThrowException(
096: "java.lang.NoSuchMethodException", "static "
097: + ci.getName() + "." + mname);
098: }
099:
100: return mi.execute(ti, false);
101: }
102:
103: public boolean isSchedulingRelevant(SystemState ss, KernelState ks,
104: ThreadInfo ti) {
105: ClassInfo clsInfo = getClassInfo();
106: MethodInfo mi = getInvokedMethod();
107: int objRef = clsInfo.getClassObjectRef();
108:
109: return mi.isSchedulingRelevant(ti, ks.da.get(objRef));
110: }
111:
112: public MethodInfo getInvokedMethod() {
113: ClassInfo clsInfo = getClassInfo();
114: if (invokedMethod == null) {
115: invokedMethod = clsInfo.getMethod(mname, true);
116: }
117:
118: return invokedMethod;
119: }
120:
121: public String toString() {
122: if (asString == null) {
123: asString = ("invokeStatic " + cname + "." + mname);
124: }
125:
126: return asString;
127: }
128: }
|