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.JPFException;
022: import gov.nasa.jpf.jvm.ClassInfo;
023: import gov.nasa.jpf.jvm.KernelState;
024: import gov.nasa.jpf.jvm.SystemState;
025: import gov.nasa.jpf.jvm.ThreadInfo;
026: import gov.nasa.jpf.jvm.Types;
027:
028: import org.apache.bcel.Constants;
029: import org.apache.bcel.classfile.ConstantFloat;
030: import org.apache.bcel.classfile.ConstantInteger;
031: import org.apache.bcel.classfile.ConstantPool;
032: import org.apache.bcel.classfile.ConstantString;
033: import org.apache.bcel.generic.ConstantPoolGen;
034: import org.apache.bcel.generic.Type;
035:
036: /**
037: * Push item from runtime constant pool (wide index)
038: * ... => ..., value
039: */
040: public class LDC_W extends Instruction {
041: private int value;
042: private String string;
043: Type type;
044:
045: private boolean isString;
046: private boolean isClass;
047:
048: public void setPeer(org.apache.bcel.generic.Instruction i,
049: ConstantPool cp) {
050: ConstantPoolGen cpg = ClassInfo.getConstantPoolGen(cp);
051: type = ((org.apache.bcel.generic.LDC_W) i).getType(cpg);
052:
053: int index = ((org.apache.bcel.generic.LDC_W) i).getIndex();
054:
055: if (type == Type.STRING) {
056: string = cp.constantToString(cp
057: .getConstant(((ConstantString) cp
058: .getConstant(index)).getStringIndex()));
059: } else if (type == Type.INT) {
060: value = ((ConstantInteger) cp.getConstant(index))
061: .getBytes();
062: } else if (type == Type.FLOAT) {
063: value = Types.floatToInt(((ConstantFloat) cp
064: .getConstant(index)).getBytes());
065:
066: /*
067: * Java 1.5 silently introduced a class file change - LDCs can now directly reference class
068: * constpool entries. To make it more interesting, BCEL 5.1 chokes on this with a hard exception.
069: * As of Aug 2004, this was fixed in the BCEL Subversion repository, but there is no new
070: * release out yet. In order to compile this code with BCEL 5.1, we can't even use Type.CLASS.
071: * The current hack should compile with both BCEL 5.1 and svn, but only runs - when encountering
072: * a Java 1.5 class file - if the BCEL svn jar is used
073: */
074: // } else if (type == Type.CLASS) {
075: } else if (type.getType() == Constants.T_REFERENCE) { // <2do> replace when BCEL > 5.1
076: // that's kind of a hack - if this is a const class ref to the class that is
077: // currently loaded, we don't have a corresponding object created yet, and
078: // the StaticArea access methods might do a recursive class init. Our solution
079: // is to store the name, and resolve the reference when we get executed
080: string = cp.constantToString(index,
081: Constants.CONSTANT_Class);
082: } else {
083: throw new JPFException("invalid type of constant");
084: }
085: }
086:
087: public Instruction execute(SystemState ss, KernelState ks,
088: ThreadInfo th) {
089: if (type == Type.STRING) {
090: th.push(ks.da.newConstantString(string), true);
091: // } else if (type == Type.CLASS) {
092: } else if (type.getType() == Constants.T_REFERENCE) { // <2do> replace when BCEL > 5.1
093: ClassInfo ci = ClassInfo.getClassInfo(string);
094: th.push(ci.getClassObjectRef(), true);
095: } else {
096: th.push(value, false);
097: }
098:
099: return getNext(th);
100: }
101:
102: public int getByteCode() {
103: return 0x13;
104: }
105: }
|