You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/06/28 21:46:19 UTC
svn commit: r417860 [6/12] - in /incubator/openjpa/trunk: ./ openjpa-lib/
openjpa-lib/main/ openjpa-lib/src/ openjpa-lib/src/main/
openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/
openjpa-lib/src/test/ openjpa-lib/src/test/java/ openjpa-lib/src/t...
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+
+/**
+ * <p>An instruction that that loads a constant onto the stack.
+ * The opcode represented by this instruction may change depending on the
+ * type and value of the constant set. For example, if the constant value
+ * is initially set to 5, the opcode will be <code>iconst5</code>; if later
+ * incremented to 6, the opcode will be changed to <code>bipush(6)</code>.</p>
+ *
+ * @author Abe White
+ */
+public class ConstantInstruction extends TypedInstruction {
+ private int _arg = -1;
+
+ ConstantInstruction(Code owner) {
+ super(owner);
+ }
+
+ ConstantInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ }
+
+ int getLength() {
+ switch (getOpcode()) {
+ case Constants.BIPUSH:
+ case Constants.LDC:
+ return super.getLength() + 1;
+
+ case Constants.SIPUSH:
+ case Constants.LDCW:
+ case Constants.LDC2W:
+ return super.getLength() + 2;
+
+ default:
+ return super.getLength();
+ }
+ }
+
+ public int getStackChange() {
+ String type = getTypeName();
+
+ if (double.class.getName().equals(type) ||
+ long.class.getName().equals(type)) {
+ return 2;
+ }
+
+ return 1;
+ }
+
+ public int getLogicalStackChange() {
+ return 1;
+ }
+
+ public String getTypeName() {
+ int opcode = getOpcode();
+
+ switch (opcode) {
+ case Constants.NOP:
+ return null;
+
+ case Constants.ACONSTNULL:
+ return Object.class.getName();
+
+ case Constants.ICONSTM1:
+ case Constants.ICONST0:
+ case Constants.ICONST1:
+ case Constants.ICONST2:
+ case Constants.ICONST3:
+ case Constants.ICONST4:
+ case Constants.ICONST5:
+ case Constants.BIPUSH:
+ case Constants.SIPUSH:
+ return int.class.getName();
+
+ case Constants.LCONST0:
+ case Constants.LCONST1:
+ return long.class.getName();
+
+ case Constants.FCONST0:
+ case Constants.FCONST1:
+ case Constants.FCONST2:
+ return float.class.getName();
+
+ case Constants.DCONST0:
+ case Constants.DCONST1:
+ return double.class.getName();
+ }
+
+ Entry entry = getPool().getEntry(_arg);
+
+ switch (entry.getType()) {
+ case Entry.UTF8:
+ case Entry.STRING:
+ return String.class.getName();
+
+ case Entry.INT:
+ return int.class.getName();
+
+ case Entry.FLOAT:
+ return float.class.getName();
+
+ case Entry.LONG:
+ return long.class.getName();
+
+ case Entry.DOUBLE:
+ return double.class.getName();
+
+ case Entry.CLASS:
+ return Class.class.getName();
+
+ default:
+ return null;
+ }
+ }
+
+ public TypedInstruction setType(String type) {
+ throw new UnsupportedOperationException("Use setValue");
+ }
+
+ /**
+ * Return the value of the constant as its wrapper type, or null if
+ * not set. Returns class values as the class name.
+ */
+ public Object getValue() {
+ int opcode = getOpcode();
+
+ switch (opcode) {
+ case Constants.NOP:
+ case Constants.ACONSTNULL:
+ return null;
+
+ case Constants.ICONSTM1:
+ case Constants.ICONST0:
+ case Constants.ICONST1:
+ case Constants.ICONST2:
+ case Constants.ICONST3:
+ case Constants.ICONST4:
+ case Constants.ICONST5:
+ return Numbers.valueOf(opcode - Constants.ICONST0);
+
+ case Constants.LCONST0:
+ case Constants.LCONST1:
+ return Numbers.valueOf((long) (opcode - Constants.LCONST0));
+
+ case Constants.FCONST0:
+ case Constants.FCONST1:
+ case Constants.FCONST2:
+ return new Float(opcode - Constants.FCONST0);
+
+ case Constants.DCONST0:
+ case Constants.DCONST1:
+ return new Double(opcode - Constants.DCONST0);
+
+ case Constants.BIPUSH:
+ case Constants.SIPUSH:
+ return Numbers.valueOf(_arg);
+
+ default:
+
+ Entry entry = getPool().getEntry(_arg);
+ Object val = ((ConstantEntry) entry).getConstant();
+
+ if (entry.getType() == Entry.CLASS) {
+ return getProject().getNameCache()
+ .getExternalForm((String) val, false);
+ }
+
+ return val;
+ }
+ }
+
+ /**
+ * Set the constant to the given value. The value should be
+ * an instance of String, Integer, Long, Double, Float, Class, BCClass, or
+ * null depending on the constant type. If the given value is not
+ * supported directly, it will be converted accordingly.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(Object value) {
+ if (value instanceof Boolean) {
+ value = Numbers.valueOf((((Boolean) value).booleanValue()) ? 1 : 0);
+ } else if (value instanceof Character) {
+ value = Numbers.valueOf((int) ((Character) value).charValue());
+ } else if (value instanceof Byte) {
+ value = Numbers.valueOf(((Byte) value).intValue());
+ } else if (value instanceof Short) {
+ value = Numbers.valueOf(((Short) value).intValue());
+ } else if ((value != null) && !(value instanceof Number) &&
+ !(value instanceof String) && !(value instanceof Class) &&
+ !(value instanceof BCClass)) {
+ throw new IllegalArgumentException("value = " + value);
+ }
+
+ calculateOpcode(value, false);
+
+ return this;
+ }
+
+ /**
+ * Return the string value of this constant, or null if not set.
+ */
+ public String getStringValue() {
+ return (String) getValue();
+ }
+
+ /**
+ * Return the int value of this constant, or 0 if not set.
+ */
+ public int getIntValue() {
+ Object value = getValue();
+
+ return (value == null) ? 0 : ((Number) value).intValue();
+ }
+
+ /**
+ * Return the long value of this constant, or 0 if not set.
+ */
+ public long getLongValue() {
+ Object value = getValue();
+
+ return (value == null) ? 0L : ((Number) value).longValue();
+ }
+
+ /**
+ * Return the float value of this constant, or 0 if not set.
+ */
+ public float getFloatValue() {
+ Object value = getValue();
+
+ return (value == null) ? 0F : ((Number) value).floatValue();
+ }
+
+ /**
+ * Return the double value of this constant, or 0 if not set.
+ */
+ public double getDoubleValue() {
+ Object value = getValue();
+
+ return (value == null) ? 0D : ((Number) value).doubleValue();
+ }
+
+ /**
+ * Return the class value of this constant, or null if not set.
+ */
+ public String getClassNameValue() {
+ return (String) getValue();
+ }
+
+ /**
+ * Set this constant to null.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setNull() {
+ calculateOpcode(null, false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(String value) {
+ calculateOpcode(value, false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(Class value) {
+ calculateOpcode(value, false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(BCClass value) {
+ calculateOpcode(value, false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(int value) {
+ calculateOpcode(Numbers.valueOf(value), false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(long value) {
+ calculateOpcode(Numbers.valueOf(value), false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(float value) {
+ calculateOpcode(new Float(value), false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(double value) {
+ calculateOpcode(new Double(value), false);
+
+ return this;
+ }
+
+ /**
+ * Set the value of this constant; note that this type is converted
+ * to int.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(boolean value) {
+ return setValue((value) ? 1 : 0);
+ }
+
+ /**
+ * Set the value of this constant; note that this type is converted
+ * to int.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(short value) {
+ return setValue((int) value);
+ }
+
+ /**
+ * Set the value of this constant; note that this type is converted
+ * to int.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConstantInstruction setValue(char value) {
+ return setValue((int) value);
+ }
+
+ /**
+ * ConstantInstructions are equal if the const they reference is the same,
+ * or if the const of either is unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof ConstantInstruction)) {
+ return false;
+ }
+
+ Object value = getValue();
+ Object otherValue = ((ConstantInstruction) other).getValue();
+
+ return (value == null) || (otherValue == null) ||
+ value.equals(otherValue);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterConstantInstruction(this);
+ visit.exitConstantInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+
+ ConstantInstruction ci = (ConstantInstruction) orig;
+ calculateOpcode(ci.getValue(), ci.getOpcode() == Constants.LDCW);
+ }
+
+ void read(DataInput in) throws IOException {
+ super.read(in);
+
+ switch (getOpcode()) {
+ case Constants.BIPUSH:
+ case Constants.LDC:
+ _arg = in.readUnsignedByte();
+
+ break;
+
+ case Constants.SIPUSH:
+ case Constants.LDCW:
+ case Constants.LDC2W:
+ _arg = in.readUnsignedShort();
+ }
+ }
+
+ void write(DataOutput out) throws IOException {
+ super.write(out);
+
+ switch (getOpcode()) {
+ case Constants.BIPUSH:
+ case Constants.LDC:
+ out.writeByte(_arg);
+
+ break;
+
+ case Constants.SIPUSH:
+ case Constants.LDCW:
+ case Constants.LDC2W:
+ out.writeShort(_arg);
+
+ break;
+ }
+ }
+
+ private void calculateOpcode(Object value, boolean wide) {
+ _arg = -1;
+
+ if (value == null) {
+ setOpcode(Constants.ACONSTNULL);
+ } else if (value instanceof Float) {
+ float floatVal = ((Float) value).floatValue();
+
+ if ((floatVal == 0) || (floatVal == 1) || (floatVal == 2)) {
+ setOpcode(Constants.FCONST0 + (int) floatVal);
+ } else {
+ _arg = getPool().findFloatEntry((float) floatVal, true);
+ setOpcode(((_arg > 255) || wide) ? Constants.LDCW : Constants.LDC);
+ }
+ } else if (value instanceof Long) {
+ long longVal = ((Long) value).longValue();
+
+ if ((longVal == 0) || (longVal == 1)) {
+ setOpcode(Constants.LCONST0 + (int) longVal);
+ } else {
+ _arg = getPool().findLongEntry(longVal, true);
+ setOpcode(Constants.LDC2W);
+ }
+ } else if (value instanceof Double) {
+ double doubleVal = ((Double) value).doubleValue();
+
+ if ((doubleVal == 0) || (doubleVal == 1)) {
+ setOpcode(Constants.DCONST0 + (int) doubleVal);
+ } else {
+ _arg = getPool().findDoubleEntry(doubleVal, true);
+ setOpcode(Constants.LDC2W);
+ }
+ } else if (value instanceof Integer) {
+ int intVal = ((Integer) value).intValue();
+
+ if ((intVal >= -1) && (intVal <= 5)) {
+ setOpcode(Constants.ICONST0 + intVal);
+ } else if ((intVal >= -(2 << 6)) && (intVal < (2 << 6))) {
+ setOpcode(Constants.BIPUSH);
+ _arg = intVal;
+ } else if ((intVal >= -(2 << 14)) && (intVal < (2 << 14))) {
+ setOpcode(Constants.SIPUSH);
+ _arg = intVal;
+ } else {
+ _arg = getPool().findIntEntry(intVal, true);
+ setOpcode(((_arg > 255) || wide) ? Constants.LDCW : Constants.LDC);
+ }
+ } else if (value instanceof String) {
+ _arg = getPool().findStringEntry((String) value, true);
+ setOpcode(((_arg > 255) || wide) ? Constants.LDCW : Constants.LDC);
+ } else if (value instanceof Class) {
+ String name = getProject().getNameCache()
+ .getInternalForm(((Class) value).getName(), false);
+ _arg = getPool().findClassEntry(name, true);
+ setOpcode(Constants.LDCW);
+ } else if (value instanceof BCClass) {
+ BCClass bc = (BCClass) value;
+ ClassEntry entry = (ClassEntry) bc.getPool().getEntry(bc.getIndex());
+
+ if (bc.getPool() == getPool()) {
+ _arg = getPool().indexOf(entry);
+ } else {
+ _arg = getPool()
+ .findClassEntry((String) entry.getConstant(), true);
+ }
+
+ setOpcode(Constants.LDCW);
+ } else {
+ throw new IllegalArgumentException(String.valueOf(value));
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantValue.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantValue.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantValue.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantValue.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ * <p>A constant value for a member field.</p>
+ *
+ * @author Abe White
+ */
+public class ConstantValue extends Attribute {
+ int _valueIndex = 0;
+
+ ConstantValue(int nameIndex, Attributes owner) {
+ super(nameIndex, owner);
+ }
+
+ int getLength() {
+ return 2;
+ }
+
+ /**
+ * Return the owning field.
+ */
+ public BCField getField() {
+ return (BCField) getOwner();
+ }
+
+ /**
+ * Return the {@link ConstantPool} index of the {@link ConstantEntry}
+ * holding the value of this constant. Defaults to 0.
+ */
+ public int getValueIndex() {
+ return _valueIndex;
+ }
+
+ /**
+ * Set the {@link ConstantPool} of the {@link ConstantEntry}
+ * holding the value of this constant.
+ */
+ public void setValueIndex(int valueIndex) {
+ _valueIndex = valueIndex;
+ }
+
+ /**
+ * Return the type of constant this attribute represents, or null if
+ * not set.
+ */
+ public String getTypeName() {
+ Class type = getType();
+
+ if (type == null) {
+ return null;
+ }
+
+ return type.getName();
+ }
+
+ /**
+ * Return the type of constant this attribute represents (String.class,
+ * int.class, etc), or null if not set.
+ */
+ public Class getType() {
+ Object value = getValue();
+
+ if (value == null) {
+ return null;
+ }
+
+ Class type = value.getClass();
+
+ if (type == Integer.class) {
+ return int.class;
+ }
+
+ if (type == Float.class) {
+ return float.class;
+ }
+
+ if (type == Double.class) {
+ return double.class;
+ }
+
+ if (type == Long.class) {
+ return long.class;
+ }
+
+ return String.class;
+ }
+
+ /**
+ * Return the bytecode for the type of constant this attribute
+ * represents.
+ */
+ public BCClass getTypeBC() {
+ return getProject().loadClass(getType());
+ }
+
+ /**
+ * Return the value of this constant as an Object of the appropriate
+ * type (String, Integer, Double, etc), or null if not set.
+ */
+ public Object getValue() {
+ if (_valueIndex <= 0) {
+ return null;
+ }
+
+ return ((ConstantEntry) getPool().getEntry(_valueIndex)).getConstant();
+ }
+
+ /**
+ * Set the value of this constant using the appropriate wrapper Object
+ * type (String, Integer, Double, etc). Types that are not directly
+ * supported will be converted accordingly if possible.
+ */
+ public void setValue(Object value) {
+ Class type = value.getClass();
+
+ if (type == Boolean.class) {
+ setIntValue((((Boolean) value).booleanValue()) ? 1 : 0);
+ } else if (type == Character.class) {
+ setIntValue((int) ((Character) value).charValue());
+ } else if ((type == Byte.class) || (type == Integer.class) ||
+ (type == Short.class)) {
+ setIntValue(((Number) value).intValue());
+ } else if (type == Float.class) {
+ setFloatValue(((Number) value).floatValue());
+ } else if (type == Double.class) {
+ setDoubleValue(((Number) value).doubleValue());
+ } else if (type == Long.class) {
+ setLongValue(((Number) value).longValue());
+ } else {
+ setStringValue(value.toString());
+ }
+ }
+
+ /**
+ * Get the value of this int constant, or 0 if not set.
+ */
+ public int getIntValue() {
+ if (getValueIndex() <= 0) {
+ return 0;
+ }
+
+ return ((IntEntry) getPool().getEntry(getValueIndex())).getValue();
+ }
+
+ /**
+ * Set the value of this int constant.
+ */
+ public void setIntValue(int value) {
+ setValueIndex(getPool().findIntEntry(value, true));
+ }
+
+ /**
+ * Get the value of this float constant.
+ */
+ public float getFloatValue() {
+ if (getValueIndex() <= 0) {
+ return 0F;
+ }
+
+ return ((FloatEntry) getPool().getEntry(getValueIndex())).getValue();
+ }
+
+ /**
+ * Set the value of this float constant.
+ */
+ public void setFloatValue(float value) {
+ setValueIndex(getPool().findFloatEntry(value, true));
+ }
+
+ /**
+ * Get the value of this double constant.
+ */
+ public double getDoubleValue() {
+ if (getValueIndex() <= 0) {
+ return 0D;
+ }
+
+ return ((DoubleEntry) getPool().getEntry(getValueIndex())).getValue();
+ }
+
+ /**
+ * Set the value of this double constant.
+ */
+ public void setDoubleValue(double value) {
+ setValueIndex(getPool().findDoubleEntry(value, true));
+ }
+
+ /**
+ * Get the value of this long constant.
+ */
+ public long getLongValue() {
+ if (getValueIndex() <= 0) {
+ return 0L;
+ }
+
+ return ((LongEntry) getPool().getEntry(getValueIndex())).getValue();
+ }
+
+ /**
+ * Set the value of this long constant.
+ */
+ public void setLongValue(long value) {
+ setValueIndex(getPool().findLongEntry(value, true));
+ }
+
+ /**
+ * Get the value of this string constant.
+ */
+ public String getStringValue() {
+ if (getValueIndex() <= 0) {
+ return null;
+ }
+
+ return ((StringEntry) getPool().getEntry(getValueIndex())).getStringEntry()
+ .getValue();
+ }
+
+ /**
+ * Set the value of this string constant.
+ */
+ public void setStringValue(String value) {
+ setValueIndex(getPool().findStringEntry(value, true));
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterConstantValue(this);
+ visit.exitConstantValue(this);
+ }
+
+ void read(Attribute other) {
+ setValue(((ConstantValue) other).getValue());
+ }
+
+ void read(DataInput in, int length) throws IOException {
+ setValueIndex(in.readUnsignedShort());
+ }
+
+ void write(DataOutput out, int length) throws IOException {
+ out.writeShort(getValueIndex());
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConstantValue.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Constants.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Constants.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Constants.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Constants.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+
+/**
+ * <p>Interface to track constants used in bytecode. Entities can access these
+ * constants using the static <code>Constants.</code> field prefix,
+ * or implement this interface themselves to conveniently import the
+ * constants into their own namespace.</p>
+ *
+ * @author Abe White
+ */
+public interface Constants {
+ // class magic number
+ public static final int VALID_MAGIC = 0xcafebabe;
+
+ // standard major, minor versions
+ public static final int MAJOR_VERSION = 45;
+ public static final int MINOR_VERSION = 3;
+
+ // access constants for classes, fields, methods
+ public static final int ACCESS_PUBLIC = 0x0001;
+ public static final int ACCESS_PRIVATE = 0x0002;
+ public static final int ACCESS_PROTECTED = 0x0004;
+ public static final int ACCESS_STATIC = 0x0008;
+ public static final int ACCESS_FINAL = 0x0010;
+ public static final int ACCESS_SUPER = 0x0020;
+ public static final int ACCESS_SYNCHRONIZED = 0x0020;
+ public static final int ACCESS_VOLATILE = 0x0040;
+ public static final int ACCESS_TRANSIENT = 0x0080;
+ public static final int ACCESS_NATIVE = 0x0100;
+ public static final int ACCESS_INTERFACE = 0x0200;
+ public static final int ACCESS_ABSTRACT = 0x0400;
+ public static final int ACCESS_STRICT = 0x0800;
+
+ // attribute types the compiler must support
+ public static final String ATTR_CODE = "Code";
+ public static final String ATTR_CONST = "ConstantValue";
+ public static final String ATTR_DEPRECATED = "Deprecated";
+ public static final String ATTR_EXCEPTIONS = "Exceptions";
+ public static final String ATTR_INNERCLASS = "InnerClasses";
+ public static final String ATTR_LINENUMBERS = "LineNumberTable";
+ public static final String ATTR_LOCALS = "LocalVariableTable";
+ public static final String ATTR_LOCAL_TYPES = "LocalVariableTypeTable";
+ public static final String ATTR_SOURCE = "SourceFile";
+ public static final String ATTR_SYNTHETIC = "Synthetic";
+ public static final String ATTR_UNKNOWN = "Unknown";
+
+ // opcodes
+ public static final int NOP = 0;
+ public static final int ACONSTNULL = 1;
+ public static final int ICONSTM1 = 2;
+ public static final int ICONST0 = 3;
+ public static final int ICONST1 = 4;
+ public static final int ICONST2 = 5;
+ public static final int ICONST3 = 6;
+ public static final int ICONST4 = 7;
+ public static final int ICONST5 = 8;
+ public static final int LCONST0 = 9;
+ public static final int LCONST1 = 10;
+ public static final int FCONST0 = 11;
+ public static final int FCONST1 = 12;
+ public static final int FCONST2 = 13;
+ public static final int DCONST0 = 14;
+ public static final int DCONST1 = 15;
+ public static final int BIPUSH = 16;
+ public static final int SIPUSH = 17;
+ public static final int LDC = 18;
+ public static final int LDCW = 19;
+ public static final int LDC2W = 20;
+ public static final int ILOAD = 21;
+ public static final int LLOAD = 22;
+ public static final int FLOAD = 23;
+ public static final int DLOAD = 24;
+ public static final int ALOAD = 25;
+ public static final int ILOAD0 = 26;
+ public static final int ILOAD1 = 27;
+ public static final int ILOAD2 = 28;
+ public static final int ILOAD3 = 29;
+ public static final int LLOAD0 = 30;
+ public static final int LLOAD1 = 31;
+ public static final int LLOAD2 = 32;
+ public static final int LLOAD3 = 33;
+ public static final int FLOAD0 = 34;
+ public static final int FLOAD1 = 35;
+ public static final int FLOAD2 = 36;
+ public static final int FLOAD3 = 37;
+ public static final int DLOAD0 = 38;
+ public static final int DLOAD1 = 39;
+ public static final int DLOAD2 = 40;
+ public static final int DLOAD3 = 41;
+ public static final int ALOAD0 = 42;
+ public static final int ALOAD1 = 43;
+ public static final int ALOAD2 = 44;
+ public static final int ALOAD3 = 45;
+ public static final int IALOAD = 46;
+ public static final int LALOAD = 47;
+ public static final int FALOAD = 48;
+ public static final int DALOAD = 49;
+ public static final int AALOAD = 50;
+ public static final int BALOAD = 51;
+ public static final int CALOAD = 52;
+ public static final int SALOAD = 53;
+ public static final int ISTORE = 54;
+ public static final int LSTORE = 55;
+ public static final int FSTORE = 56;
+ public static final int DSTORE = 57;
+ public static final int ASTORE = 58;
+ public static final int ISTORE0 = 59;
+ public static final int ISTORE1 = 60;
+ public static final int ISTORE2 = 61;
+ public static final int ISTORE3 = 62;
+ public static final int LSTORE0 = 63;
+ public static final int LSTORE1 = 64;
+ public static final int LSTORE2 = 65;
+ public static final int LSTORE3 = 66;
+ public static final int FSTORE0 = 67;
+ public static final int FSTORE1 = 68;
+ public static final int FSTORE2 = 69;
+ public static final int FSTORE3 = 70;
+ public static final int DSTORE0 = 71;
+ public static final int DSTORE1 = 72;
+ public static final int DSTORE2 = 73;
+ public static final int DSTORE3 = 74;
+ public static final int ASTORE0 = 75;
+ public static final int ASTORE1 = 76;
+ public static final int ASTORE2 = 77;
+ public static final int ASTORE3 = 78;
+ public static final int IASTORE = 79;
+ public static final int LASTORE = 80;
+ public static final int FASTORE = 81;
+ public static final int DASTORE = 82;
+ public static final int AASTORE = 83;
+ public static final int BASTORE = 84;
+ public static final int CASTORE = 85;
+ public static final int SASTORE = 86;
+ public static final int POP = 87;
+ public static final int POP2 = 88;
+ public static final int DUP = 89;
+ public static final int DUPX1 = 90;
+ public static final int DUPX2 = 91;
+ public static final int DUP2 = 92;
+ public static final int DUP2X1 = 93;
+ public static final int DUP2X2 = 94;
+ public static final int SWAP = 95;
+ public static final int IADD = 96;
+ public static final int LADD = 97;
+ public static final int FADD = 98;
+ public static final int DADD = 99;
+ public static final int ISUB = 100;
+ public static final int LSUB = 101;
+ public static final int FSUB = 102;
+ public static final int DSUB = 103;
+ public static final int IMUL = 104;
+ public static final int LMUL = 105;
+ public static final int FMUL = 106;
+ public static final int DMUL = 107;
+ public static final int IDIV = 108;
+ public static final int LDIV = 109;
+ public static final int FDIV = 110;
+ public static final int DDIV = 111;
+ public static final int IREM = 112;
+ public static final int LREM = 113;
+ public static final int FREM = 114;
+ public static final int DREM = 115;
+ public static final int INEG = 116;
+ public static final int LNEG = 117;
+ public static final int FNEG = 118;
+ public static final int DNEG = 119;
+ public static final int ISHL = 120;
+ public static final int LSHL = 121;
+ public static final int ISHR = 122;
+ public static final int LSHR = 123;
+ public static final int IUSHR = 124;
+ public static final int LUSHR = 125;
+ public static final int IAND = 126;
+ public static final int LAND = 127;
+ public static final int IOR = 128;
+ public static final int LOR = 129;
+ public static final int IXOR = 130;
+ public static final int LXOR = 131;
+ public static final int IINC = 132;
+ public static final int I2L = 133;
+ public static final int I2F = 134;
+ public static final int I2D = 135;
+ public static final int L2I = 136;
+ public static final int L2F = 137;
+ public static final int L2D = 138;
+ public static final int F2I = 139;
+ public static final int F2L = 140;
+ public static final int F2D = 141;
+ public static final int D2I = 142;
+ public static final int D2L = 143;
+ public static final int D2F = 144;
+ public static final int I2B = 145;
+ public static final int I2C = 146;
+ public static final int I2S = 147;
+ public static final int LCMP = 148;
+ public static final int FCMPL = 149;
+ public static final int FCMPG = 150;
+ public static final int DCMPL = 151;
+ public static final int DCMPG = 152;
+ public static final int IFEQ = 153;
+ public static final int IFNE = 154;
+ public static final int IFLT = 155;
+ public static final int IFGE = 156;
+ public static final int IFGT = 157;
+ public static final int IFLE = 158;
+ public static final int IFICMPEQ = 159;
+ public static final int IFICMPNE = 160;
+ public static final int IFICMPLT = 161;
+ public static final int IFICMPGE = 162;
+ public static final int IFICMPGT = 163;
+ public static final int IFICMPLE = 164;
+ public static final int IFACMPEQ = 165;
+ public static final int IFACMPNE = 166;
+ public static final int GOTO = 167;
+ public static final int JSR = 168;
+ public static final int RET = 169;
+ public static final int TABLESWITCH = 170;
+ public static final int LOOKUPSWITCH = 171;
+ public static final int IRETURN = 172;
+ public static final int LRETURN = 173;
+ public static final int FRETURN = 174;
+ public static final int DRETURN = 175;
+ public static final int ARETURN = 176;
+ public static final int RETURN = 177;
+ public static final int GETSTATIC = 178;
+ public static final int PUTSTATIC = 179;
+ public static final int GETFIELD = 180;
+ public static final int PUTFIELD = 181;
+ public static final int INVOKEVIRTUAL = 182;
+ public static final int INVOKESPECIAL = 183;
+ public static final int INVOKESTATIC = 184;
+ public static final int INVOKEINTERFACE = 185;
+ public static final int NEW = 187;
+ public static final int NEWARRAY = 188;
+ public static final int ANEWARRAY = 189;
+ public static final int ARRAYLENGTH = 190;
+ public static final int ATHROW = 191;
+ public static final int CHECKCAST = 192;
+ public static final int INSTANCEOF = 193;
+ public static final int MONITORENTER = 194;
+ public static final int MONITOREXIT = 195;
+ public static final int WIDE = 196;
+ public static final int MULTIANEWARRAY = 197;
+ public static final int IFNULL = 198;
+ public static final int IFNONNULL = 199;
+ public static final int GOTOW = 200;
+ public static final int JSRW = 201;
+
+ // array types
+ public static final int ARRAY_BOOLEAN = 4;
+ public static final int ARRAY_CHAR = 5;
+ public static final int ARRAY_FLOAT = 6;
+ public static final int ARRAY_DOUBLE = 7;
+ public static final int ARRAY_BYTE = 8;
+ public static final int ARRAY_SHORT = 9;
+ public static final int ARRAY_INT = 10;
+ public static final int ARRAY_LONG = 11;
+
+ // math operations
+ public static final int MATH_ADD = IADD;
+ public static final int MATH_SUB = ISUB;
+ public static final int MATH_MUL = IMUL;
+ public static final int MATH_DIV = IDIV;
+ public static final int MATH_REM = IREM;
+ public static final int MATH_NEG = INEG;
+ public static final int MATH_SHL = ISHL;
+ public static final int MATH_SHR = ISHR;
+ public static final int MATH_USHR = IUSHR;
+ public static final int MATH_AND = IAND;
+ public static final int MATH_OR = IOR;
+ public static final int MATH_XOR = IXOR;
+
+ // human-readable opcode names
+ public static final String[] OPCODE_NAMES = new String[] {
+ "nop", "aconstnull", "iconstm1", "iconst0", "iconst1", "iconst2",
+ "iconst3", "iconst4", "iconst5", "lconst0", "lconst1", "fconst0",
+ "fconst1", "fconst2", "dconst0", "dconst1", "bipush", "sipush",
+ "ldc", "ldcw", "ldc2w", "iload", "lload", "fload", "dload", "aload",
+ "iload0", "iload1", "iload2", "iload3", "lload0", "lload1", "lload2",
+ "lload3", "fload0", "fload1", "fload2", "fload3", "dload0", "dload1",
+ "dload2", "dload3", "aload0", "aload1", "aload2", "aload3", "iaload",
+ "laload", "faload", "daload", "aaload", "baload", "caload", "saload",
+ "istore", "lstore", "fstore", "dstore", "astore", "istore0",
+ "istore1", "istore2", "istore3", "lstore0", "lstore1", "lstore2",
+ "lstore3", "fstore0", "fstore1", "fstore2", "fstore3", "dstore0",
+ "dstore1", "dstore2", "dstore3", "astore0", "astore1", "astore2",
+ "astore3", "iastore", "lastore", "fastore", "dastore", "aastore",
+ "bastore", "castore", "sastore", "pop", "pop2", "dup", "dupx1",
+ "dupx2", "dup2", "dup2x1", "dup2x2", "swap", "iadd", "ladd", "fadd",
+ "dadd", "isub", "lsub", "fsub", "dsub", "imul", "lmul", "fmul",
+ "dmul", "idiv", "ldiv", "fdiv", "ddiv", "irem", "lrem", "frem",
+ "drem", "ineg", "lneg", "fneg", "dneg", "ishl", "lshl", "ishr",
+ "lshr", "iushr", "lushr", "iand", "land", "ior", "lor", "ixor",
+ "lxor", "iinc", "i2l", "i2f", "i2d", "l2i", "l2f", "l2d", "f2i",
+ "f2l", "f2d", "d2i", "d2l", "d2f", "i2b", "i2c", "i2s", "lcmp",
+ "fcmpl", "fcmpg", "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge",
+ "ifgt", "ifle", "ificmpeq", "ificmpne", "ificmplt", "ificmpge",
+ "ificmpgt", "ificmple", "ifacmpeq", "ifacmpne", "goto", "jsr", "ret",
+ "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn",
+ "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield",
+ "putfield", "invokevirtual", "invokespecial", "invokestatic",
+ "invokeinterface", "??", "new", "newarray", "anewarray",
+ "arraylength", "athrow", "checkcast", "instanceof", "monitorenter",
+ "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull",
+ "gotow", "jsrw",
+ };
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Constants.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConvertInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConvertInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConvertInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConvertInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,440 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.util.*;
+
+
+/**
+ * <p>A conversion opcode such as <code>i2l, f2i</code>, etc.
+ * Changing the types of the instruction will automatically
+ * update the underlying opcode. Converting from one type to the same
+ * type will result in a <code>nop</code>.</p>
+ *
+ * @author Abe White
+ */
+public class ConvertInstruction extends TypedInstruction {
+ private static final Class[][] _mappings = new Class[][] {
+ { boolean.class, int.class },
+ { void.class, int.class },
+ { Object.class, int.class },
+ };
+ private static final Class[][] _fromMappings = new Class[][] {
+ { boolean.class, int.class },
+ { void.class, int.class },
+ { Object.class, int.class },
+ { byte.class, int.class },
+ { char.class, int.class },
+ { short.class, int.class },
+ };
+ String _toType = null;
+ String _fromType = null;
+
+ ConvertInstruction(Code owner) {
+ super(owner);
+ }
+
+ ConvertInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ }
+
+ public int getLogicalStackChange() {
+ return 0;
+ }
+
+ public int getStackChange() {
+ switch (getOpcode()) {
+ case Constants.I2L:
+ case Constants.I2D:
+ case Constants.F2L:
+ case Constants.F2D:
+ return 1;
+
+ case Constants.L2I:
+ case Constants.L2F:
+ case Constants.D2I:
+ case Constants.D2F:
+ return -1;
+
+ default:
+ return 0;
+ }
+ }
+
+ public String getTypeName() {
+ switch (getOpcode()) {
+ case Constants.L2I:
+ case Constants.F2I:
+ case Constants.D2I:
+ return int.class.getName();
+
+ case Constants.I2L:
+ case Constants.F2L:
+ case Constants.D2L:
+ return long.class.getName();
+
+ case Constants.I2F:
+ case Constants.L2F:
+ case Constants.D2F:
+ return float.class.getName();
+
+ case Constants.I2D:
+ case Constants.L2D:
+ case Constants.F2D:
+ return double.class.getName();
+
+ case Constants.I2B:
+ return byte.class.getName();
+
+ case Constants.I2C:
+ return char.class.getName();
+
+ case Constants.I2S:
+ return short.class.getName();
+
+ default:
+ return _toType;
+ }
+ }
+
+ public TypedInstruction setType(String type) {
+ String toType = mapType(type, _mappings, true);
+ String fromType = getFromTypeName();
+
+ // if no valid opcode, remember current types in case they reset one
+ // to create a valid opcode
+ if ((toType == null) || (fromType == null) || toType.equals(fromType)) {
+ _toType = toType;
+ _fromType = fromType;
+
+ return (TypedInstruction) setOpcode(Constants.NOP);
+ }
+
+ // ok, valid conversion possible, forget saved types
+ _toType = null;
+ _fromType = null;
+
+ char to = toType.charAt(0);
+ char from = fromType.charAt(0);
+
+ switch (to) {
+ case 'i':
+
+ switch (from) {
+ case 'l':
+ return (TypedInstruction) setOpcode(Constants.L2I);
+
+ case 'f':
+ return (TypedInstruction) setOpcode(Constants.F2I);
+
+ case 'd':
+ return (TypedInstruction) setOpcode(Constants.D2I);
+ }
+
+ case 'l':
+
+ switch (from) {
+ case 'i':
+ return (TypedInstruction) setOpcode(Constants.I2L);
+
+ case 'f':
+ return (TypedInstruction) setOpcode(Constants.F2L);
+
+ case 'd':
+ return (TypedInstruction) setOpcode(Constants.D2L);
+ }
+
+ case 'f':
+
+ switch (from) {
+ case 'i':
+ return (TypedInstruction) setOpcode(Constants.I2F);
+
+ case 'l':
+ return (TypedInstruction) setOpcode(Constants.L2F);
+
+ case 'd':
+ return (TypedInstruction) setOpcode(Constants.D2F);
+ }
+
+ case 'd':
+
+ switch (from) {
+ case 'i':
+ return (TypedInstruction) setOpcode(Constants.I2D);
+
+ case 'l':
+ return (TypedInstruction) setOpcode(Constants.L2D);
+
+ case 'f':
+ return (TypedInstruction) setOpcode(Constants.F2D);
+ }
+
+ case 'b':
+
+ if (from == 'i') {
+ return (TypedInstruction) setOpcode(Constants.I2B);
+ }
+
+ case 'C':
+
+ if (from == 'i') {
+ return (TypedInstruction) setOpcode(Constants.I2C);
+ }
+
+ case 'S':
+
+ if (from == 'i') {
+ return (TypedInstruction) setOpcode(Constants.I2S);
+ }
+
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Return the name of the type being converted from.
+ * If neither type has been set, this method will return null.
+ */
+ public String getFromTypeName() {
+ switch (getOpcode()) {
+ case Constants.I2L:
+ case Constants.I2F:
+ case Constants.I2D:
+ case Constants.I2B:
+ case Constants.I2S:
+ case Constants.I2C:
+ return int.class.getName();
+
+ case Constants.L2I:
+ case Constants.L2F:
+ case Constants.L2D:
+ return long.class.getName();
+
+ case Constants.F2I:
+ case Constants.F2L:
+ case Constants.F2D:
+ return float.class.getName();
+
+ case Constants.D2I:
+ case Constants.D2L:
+ case Constants.D2F:
+ return double.class.getName();
+
+ default:
+ return _fromType;
+ }
+ }
+
+ /**
+ * Return the {@link Class} of the type being converted from.
+ * If neither type has been set, this method will return null.
+ */
+ public Class getFromType() {
+ String type = getFromTypeName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return Strings.toClass(type, getClassLoader());
+ }
+
+ /**
+ * Return the bytecode of the type being converted from.
+ * If neither type has been set, this method will return null.
+ */
+ public BCClass getFromTypeBC() {
+ String type = getFromTypeName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return getProject().loadClass(type, getClassLoader());
+ }
+
+ /**
+ * Set the type being converted from. Types that have no direct
+ * support will be converted accordingly.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConvertInstruction setFromType(String type) {
+ String fromType = mapType(type, _fromMappings, true);
+ String toType = getTypeName();
+
+ // if no valid opcode, remember current types in case they reset one
+ // to create a valid opcode
+ if ((toType == null) || (fromType == null) || toType.equals(fromType)) {
+ _toType = toType;
+ _fromType = fromType;
+
+ return (ConvertInstruction) setOpcode(Constants.NOP);
+ }
+
+ // ok, valid conversion possible, forget saved types
+ _toType = null;
+ _fromType = null;
+
+ char to = toType.charAt(0);
+ char from = fromType.charAt(0);
+
+ switch (from) {
+ case 'i':
+
+ switch (to) {
+ case 'l':
+ return (ConvertInstruction) setOpcode(Constants.I2L);
+
+ case 'f':
+ return (ConvertInstruction) setOpcode(Constants.I2F);
+
+ case 'd':
+ return (ConvertInstruction) setOpcode(Constants.I2D);
+
+ case 'b':
+ return (ConvertInstruction) setOpcode(Constants.I2B);
+
+ case 'c':
+ return (ConvertInstruction) setOpcode(Constants.I2C);
+
+ case 's':
+ return (ConvertInstruction) setOpcode(Constants.I2S);
+ }
+
+ case 'l':
+
+ switch (to) {
+ case 'i':
+ return (ConvertInstruction) setOpcode(Constants.L2I);
+
+ case 'f':
+ return (ConvertInstruction) setOpcode(Constants.L2F);
+
+ case 'd':
+ return (ConvertInstruction) setOpcode(Constants.L2D);
+ }
+
+ case 'f':
+
+ switch (to) {
+ case 'i':
+ return (ConvertInstruction) setOpcode(Constants.F2I);
+
+ case 'l':
+ return (ConvertInstruction) setOpcode(Constants.F2L);
+
+ case 'd':
+ return (ConvertInstruction) setOpcode(Constants.F2D);
+ }
+
+ case 'd':
+
+ switch (to) {
+ case 'i':
+ return (ConvertInstruction) setOpcode(Constants.D2I);
+
+ case 'l':
+ return (ConvertInstruction) setOpcode(Constants.D2L);
+
+ case 'f':
+ return (ConvertInstruction) setOpcode(Constants.D2F);
+ }
+
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Set the type being converted from. Types that have no direct
+ * support will be converted accordingly.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConvertInstruction setFromType(Class type) {
+ if (type == null) {
+ return setFromType((String) null);
+ }
+
+ return setFromType(type.getName());
+ }
+
+ /**
+ * Set the type being converted from. Types that have no direct
+ * support will be converted accordingly.
+ *
+ * @return this instruction, for method chaining
+ */
+ public ConvertInstruction setFromType(BCClass type) {
+ if (type == null) {
+ return setFromType((String) null);
+ }
+
+ return setFromType(type.getName());
+ }
+
+ /**
+ * ConvertInstructions are equal if the types they convert between are
+ * either equal or unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ConvertInstruction)) {
+ return false;
+ }
+
+ ConvertInstruction ins = (ConvertInstruction) other;
+
+ if ((getOpcode() != Constants.NOP) && (getOpcode() == ins.getOpcode())) {
+ return true;
+ }
+
+ String type = getTypeName();
+ String otherType = ins.getTypeName();
+
+ if (!((type == null) || (otherType == null) || type.equals(otherType))) {
+ return false;
+ }
+
+ type = getFromTypeName();
+ otherType = ins.getFromTypeName();
+
+ return (type == null) || (otherType == null) || type.equals(otherType);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterConvertInstruction(this);
+ visit.exitConvertInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+
+ ConvertInstruction ins = (ConvertInstruction) orig;
+ _toType = ins._toType;
+ _fromType = ins._fromType;
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ConvertInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Deprecated.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Deprecated.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Deprecated.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Deprecated.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ * <p>Attribute signifying that a method or class is deprecated.</p>
+ *
+ * @author Abe White
+ */
+public class Deprecated extends Attribute {
+ Deprecated(int nameIndex, Attributes owner) {
+ super(nameIndex, owner);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterDeprecated(this);
+ visit.exitDeprecated(this);
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Deprecated.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ExceptionHandler.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ExceptionHandler.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ExceptionHandler.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ExceptionHandler.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * <p>Represents a <code>try {} catch() {}</code> statement in bytecode.</p>
+ *
+ * @author Abe White
+ */
+public class ExceptionHandler implements InstructionPtr, BCEntity,
+ VisitAcceptor {
+ private int _catchIndex = 0;
+ private Code _owner = null;
+ private InstructionPtrStrategy _tryStart = new InstructionPtrStrategy(this);
+ private InstructionPtrStrategy _tryEnd = new InstructionPtrStrategy(this);
+ private InstructionPtrStrategy _tryHandler = new InstructionPtrStrategy(this);
+
+ ExceptionHandler(Code owner) {
+ _owner = owner;
+ }
+
+ /**
+ * Return the owning code block.
+ */
+ public Code getCode() {
+ return _owner;
+ }
+
+ ///////////////////
+ // Body operations
+ ///////////////////
+
+ /**
+ * Return the instruction marking the beginning of the try {} block.
+ */
+ public Instruction getTryStart() {
+ return _tryStart.getTargetInstruction();
+ }
+
+ /**
+ * Set the {@link Instruction} marking the beginning of the try block.
+ * The instruction must already be a part of the method.
+ */
+ public void setTryStart(Instruction instruction) {
+ _tryStart.setTargetInstruction(instruction);
+ }
+
+ /**
+ * Return the instruction at the end of the try {} block.
+ */
+ public Instruction getTryEnd() {
+ return _tryEnd.getTargetInstruction();
+ }
+
+ /**
+ * Set the Instruction at the end of the try block. The
+ * Instruction must already be a part of the method.
+ */
+ public void setTryEnd(Instruction instruction) {
+ _tryEnd.setTargetInstruction(instruction);
+ }
+
+ //////////////////////
+ // Handler operations
+ //////////////////////
+
+ /**
+ * Return the instruction marking the beginning of the catch {} block.
+ */
+ public Instruction getHandlerStart() {
+ return _tryHandler.getTargetInstruction();
+ }
+
+ /**
+ * Set the {@link Instruction} marking the beginning of the catch block.
+ * The instruction must already be a part of the method.
+ * WARNING: if this instruction is deleted, the results are undefined.
+ */
+ public void setHandlerStart(Instruction instruction) {
+ _tryHandler.setTargetInstruction(instruction);
+ }
+
+ ////////////////////
+ // Catch operations
+ ////////////////////
+
+ /**
+ * Return the index into the class {@link ConstantPool} of the
+ * {@link ClassEntry} describing the exception type this handler catches.
+ */
+ public int getCatchIndex() {
+ return _catchIndex;
+ }
+
+ /**
+ * Set the index into the class {@link ConstantPool} of the
+ * {@link ClassEntry} describing the exception type this handler catches.
+ */
+ public void setCatchIndex(int catchTypeIndex) {
+ _catchIndex = catchTypeIndex;
+ }
+
+ /**
+ * Return the name of the exception type; returns null for catch-all
+ * clauses used to implement finally blocks. The name will be returned
+ * in a forum suitable for a {@link Class#forName} call.
+ */
+ public String getCatchName() {
+ if (_catchIndex == 0) {
+ return null;
+ }
+
+ ClassEntry entry = (ClassEntry) getPool().getEntry(_catchIndex);
+
+ return getProject().getNameCache()
+ .getExternalForm(entry.getNameEntry().getValue(), false);
+ }
+
+ /**
+ * Return the {@link Class} of the exception type; returns null for
+ * catch-all clauses used to implement finally blocks.
+ */
+ public Class getCatchType() {
+ String name = getCatchName();
+
+ if (name == null) {
+ return null;
+ }
+
+ return Strings.toClass(name, getClassLoader());
+ }
+
+ /**
+ * Return the bytecode of the exception type; returns null for
+ * catch-all clauses used to implement finally blocks.
+ */
+ public BCClass getCatchBC() {
+ String name = getCatchName();
+
+ if (name == null) {
+ return null;
+ }
+
+ return getProject().loadClass(name, getClassLoader());
+ }
+
+ /**
+ * Set the class of the exception type, or null for catch-all clauses used
+ * with finally blocks.
+ */
+ public void setCatch(String name) {
+ if (name == null) {
+ _catchIndex = 0;
+ } else {
+ _catchIndex = getPool()
+ .findClassEntry(getProject().getNameCache()
+ .getInternalForm(name, false),
+ true);
+ }
+ }
+
+ /**
+ * Set the class of the exception type, or null for catch-all clauses used
+ * for finally blocks.
+ */
+ public void setCatch(Class type) {
+ if (type == null) {
+ setCatch((String) null);
+ } else {
+ setCatch(type.getName());
+ }
+ }
+
+ /**
+ * Set the class of the exception type, or null for catch-all clauses used
+ * for finally blocks.
+ */
+ public void setCatch(BCClass type) {
+ if (type == null) {
+ setCatch((String) null);
+ } else {
+ setCatch(type.getName());
+ }
+ }
+
+ /////////////////////////////////
+ // InstructionPtr implementation
+ /////////////////////////////////
+ public void updateTargets() {
+ _tryStart.updateTargets();
+ _tryEnd.updateTargets();
+ _tryHandler.updateTargets();
+ }
+
+ public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
+ _tryStart.replaceTarget(oldTarget, newTarget);
+ _tryEnd.replaceTarget(oldTarget, newTarget);
+ _tryHandler.replaceTarget(oldTarget, newTarget);
+ }
+
+ ///////////////////////////
+ // BCEntity implementation
+ ///////////////////////////
+ public Project getProject() {
+ return _owner.getProject();
+ }
+
+ public ConstantPool getPool() {
+ return _owner.getPool();
+ }
+
+ public ClassLoader getClassLoader() {
+ return _owner.getClassLoader();
+ }
+
+ public boolean isValid() {
+ return _owner != null;
+ }
+
+ ////////////////////////////////
+ // VisitAcceptor implementation
+ ////////////////////////////////
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterExceptionHandler(this);
+ visit.exitExceptionHandler(this);
+ }
+
+ //////////////////
+ // I/O operations
+ //////////////////
+ void read(ExceptionHandler orig) {
+ _tryStart.setByteIndex(orig._tryStart.getByteIndex());
+ _tryEnd.setByteIndex(orig._tryEnd.getByteIndex());
+ _tryHandler.setByteIndex(orig._tryHandler.getByteIndex());
+
+ // done at a high level so that if the name isn't in our constant pool,
+ // it will be added
+ setCatch(orig.getCatchName());
+ }
+
+ void read(DataInput in) throws IOException {
+ setTryStart(in.readUnsignedShort());
+ setTryEnd(in.readUnsignedShort());
+ setHandlerStart(in.readUnsignedShort());
+ setCatchIndex(in.readUnsignedShort());
+ }
+
+ void write(DataOutput out) throws IOException {
+ out.writeShort(getTryStartPc());
+ out.writeShort(getTryEndPc());
+ out.writeShort(getHandlerStartPc());
+ out.writeShort(getCatchIndex());
+ }
+
+ public void setTryStart(int start) {
+ _tryStart.setByteIndex(start);
+ }
+
+ public int getTryStartPc() {
+ return _tryStart.getByteIndex();
+ }
+
+ public void setTryEnd(int end) {
+ setTryEnd((Instruction) _owner.getInstruction(end).prev);
+ }
+
+ /**
+ * Return the program counter end position for this exception handler.
+ * This represents an index into the code byte array.
+ */
+ public int getTryEndPc() {
+ return _tryEnd.getByteIndex() + getTryEnd().getLength();
+ }
+
+ public void setHandlerStart(int handler) {
+ _tryHandler.setByteIndex(handler);
+ }
+
+ public int getHandlerStartPc() {
+ return _tryHandler.getByteIndex();
+ }
+
+ void invalidate() {
+ _owner = null;
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ExceptionHandler.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Exceptions.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Exceptions.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Exceptions.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Exceptions.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * <p>Attribute declaring the checked exceptions a method can throw.</p>
+ *
+ * @author Abe White
+ */
+public class Exceptions extends Attribute {
+ private List _indexes = new LinkedList();
+
+ Exceptions(int nameIndex, Attributes owner) {
+ super(nameIndex, owner);
+ }
+
+ int getLength() {
+ return 2 + (2 * _indexes.size());
+ }
+
+ /**
+ * Return the owning method.
+ */
+ public BCMethod getMethod() {
+ return (BCMethod) getOwner();
+ }
+
+ /**
+ * Return the indexes in the class {@link ConstantPool} of the
+ * {@link ClassEntry}s for the exception types thrown by this method, or
+ * an empty array if none.
+ */
+ public int[] getExceptionIndexes() {
+ int[] indexes = new int[_indexes.size()];
+ Iterator itr = _indexes.iterator();
+
+ for (int i = 0; i < indexes.length; i++)
+ indexes[i] = ((Integer) itr.next()).intValue();
+
+ return indexes;
+ }
+
+ /**
+ * Set the indexes in the class {@link ConstantPool} of the
+ * {@link ClassEntry}s for the exception types thrown by this method. Use
+ * null or an empty array for none.
+ */
+ public void setExceptionIndexes(int[] exceptionIndexes) {
+ _indexes.clear();
+
+ if (exceptionIndexes != null) {
+ for (int i = 0; i < exceptionIndexes.length; i++)
+ _indexes.add(Numbers.valueOf(exceptionIndexes[i]));
+ }
+ }
+
+ /**
+ * Return the names of the exception types for this method, or an empty
+ * array if none. The names will be in a form suitable for a
+ * {@link Class#forName} call.
+ */
+ public String[] getExceptionNames() {
+ String[] names = new String[_indexes.size()];
+ Iterator itr = _indexes.iterator();
+ int index;
+ ClassEntry entry;
+
+ for (int i = 0; i < names.length; i++) {
+ index = ((Number) itr.next()).intValue();
+ entry = (ClassEntry) getPool().getEntry(index);
+ names[i] = getProject().getNameCache()
+ .getExternalForm(entry.getNameEntry().getValue(),
+ false);
+ }
+
+ return names;
+ }
+
+ /**
+ * Return the {@link Class} objects for the exception types for this
+ * method, or an empty array if none.
+ */
+ public Class[] getExceptionTypes() {
+ String[] names = getExceptionNames();
+ Class[] types = new Class[names.length];
+
+ for (int i = 0; i < names.length; i++)
+ types[i] = Strings.toClass(names[i], getClassLoader());
+
+ return types;
+ }
+
+ /**
+ * Return bytecode for the exception types of this
+ * method, or an empty array if none.
+ */
+ public BCClass[] getExceptionBCs() {
+ String[] names = getExceptionNames();
+ BCClass[] types = new BCClass[names.length];
+
+ for (int i = 0; i < names.length; i++)
+ types[i] = getProject().loadClass(names[i], getClassLoader());
+
+ return types;
+ }
+
+ /**
+ * Set the checked exceptions thrown by this method. Use null or an
+ * empty array for none.
+ */
+ public void setExceptions(String[] exceptions) {
+ if (exceptions != null) {
+ for (int i = 0; i < exceptions.length; i++)
+ if (exceptions[i] == null) {
+ throw new NullPointerException("exceptions[" + i +
+ "] = null");
+ }
+ }
+
+ clear();
+
+ if (exceptions != null) {
+ for (int i = 0; i < exceptions.length; i++)
+ addException(exceptions[i]);
+ }
+ }
+
+ /**
+ * Set the checked exceptions thrown by this method. Use null or an
+ * empty array for none.
+ */
+ public void setExceptions(Class[] exceptions) {
+ String[] names = null;
+
+ if (exceptions != null) {
+ names = new String[exceptions.length];
+
+ for (int i = 0; i < exceptions.length; i++)
+ names[i] = exceptions[i].getName();
+ }
+
+ setExceptions(names);
+ }
+
+ /**
+ * Set the checked exceptions thrown by this method. Use null or an
+ * empty array for none.
+ */
+ public void setExceptions(BCClass[] exceptions) {
+ String[] names = null;
+
+ if (exceptions != null) {
+ names = new String[exceptions.length];
+
+ for (int i = 0; i < exceptions.length; i++)
+ names[i] = exceptions[i].getName();
+ }
+
+ setExceptions(names);
+ }
+
+ /**
+ * Clear this method of all exception declarations.
+ */
+ public void clear() {
+ _indexes.clear();
+ }
+
+ /**
+ * Remove an exception type thrown by this method.
+ *
+ * @return true if the method had the exception type, false otherwise
+ */
+ public boolean removeException(String type) {
+ String internalForm = getProject().getNameCache()
+ .getInternalForm(type, false);
+ ClassEntry entry;
+
+ for (Iterator itr = _indexes.iterator(); itr.hasNext();) {
+ entry = (ClassEntry) getPool()
+ .getEntry(((Integer) itr.next()).intValue());
+
+ if (entry.getNameEntry().getValue().equals(internalForm)) {
+ itr.remove();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove an exception thrown by this method.
+ *
+ * @return true if the method had the exception type, false otherwise
+ */
+ public boolean removeException(Class type) {
+ if (type == null) {
+ return false;
+ }
+
+ return removeException(type.getName());
+ }
+
+ /**
+ * Remove an exception thrown by this method.
+ *
+ * @return true if the method had the exception type, false otherwise
+ */
+ public boolean removeException(BCClass type) {
+ if (type == null) {
+ return false;
+ }
+
+ return removeException(type.getName());
+ }
+
+ /**
+ * Add an exception type to those thrown by this method.
+ */
+ public void addException(String type) {
+ int index = getPool()
+ .findClassEntry(getProject().getNameCache()
+ .getInternalForm(type, false), true);
+ _indexes.add(Numbers.valueOf(index));
+ }
+
+ /**
+ * Add an exception to those thrown by this method.
+ */
+ public void addException(Class type) {
+ addException(type.getName());
+ }
+
+ /**
+ * Add an exception to those thrown by this method.
+ */
+ public void addException(BCClass type) {
+ addException(type.getName());
+ }
+
+ /**
+ * Return true if the method declares that it throws the given
+ * exception type.
+ */
+ public boolean throwsException(String type) {
+ String[] exceptions = getExceptionNames();
+
+ for (int i = 0; i < exceptions.length; i++)
+ if (exceptions[i].equals(type)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Return true if the method declares that it throws the given
+ * exception type.
+ */
+ public boolean throwsException(Class type) {
+ if (type == null) {
+ return false;
+ }
+
+ return throwsException(type.getName());
+ }
+
+ /**
+ * Return true if the method declares that it throws the given
+ * exception type.
+ */
+ public boolean throwsException(BCClass type) {
+ if (type == null) {
+ return false;
+ }
+
+ return throwsException(type.getName());
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterExceptions(this);
+ visit.exitExceptions(this);
+ }
+
+ void read(Attribute other) {
+ setExceptions(((Exceptions) other).getExceptionNames());
+ }
+
+ void read(DataInput in, int length) throws IOException {
+ _indexes.clear();
+
+ int exceptionCount = in.readUnsignedShort();
+
+ for (int i = 0; i < exceptionCount; i++)
+ _indexes.add(Numbers.valueOf((int) in.readUnsignedShort()));
+ }
+
+ void write(DataOutput out, int length) throws IOException {
+ out.writeShort(_indexes.size());
+
+ for (Iterator itr = _indexes.iterator(); itr.hasNext();)
+ out.writeShort(((Number) itr.next()).shortValue());
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Exceptions.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/FieldInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/FieldInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/FieldInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/FieldInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,499 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.lang.reflect.*;
+
+
+/**
+ * <p>Instruction that takes as an argument a field to operate
+ * on. Examples include <code>getfield, getstatic, setfield,
+ * setstatic</code>.</p>
+ *
+ * @author Abe White
+ */
+public abstract class FieldInstruction extends Instruction {
+ private int _index = 0;
+
+ FieldInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ }
+
+ int getLength() {
+ return super.getLength() + 2;
+ }
+
+ ////////////////////
+ // Field operations
+ ////////////////////
+
+ /**
+ * Return the index in the class {@link ConstantPool} of the
+ * {@link ComplexEntry} describing the field to operate on.
+ */
+ public int getFieldIndex() {
+ return _index;
+ }
+
+ /**
+ * Set the index in the class {@link ConstantPool} of the
+ * {@link ComplexEntry} describing the field to operate on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldIndex(int index) {
+ _index = index;
+
+ return this;
+ }
+
+ /**
+ * Return the field this instruction operates on, or null if not set.
+ */
+ public BCField getField() {
+ String dec = getFieldDeclarerName();
+
+ if (dec == null) {
+ return null;
+ }
+
+ BCClass bc = getProject().loadClass(dec, getClassLoader());
+ BCField[] fields = bc.getFields(getFieldName());
+
+ if (fields.length == 0) {
+ return null;
+ }
+
+ return fields[0];
+ }
+
+ /**
+ * Set the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(BCField field) {
+ if (field == null) {
+ return setFieldIndex(0);
+ }
+
+ return setField(field.getDeclarer().getName(), field.getName(),
+ field.getTypeName());
+ }
+
+ /**
+ * Set the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(Field field) {
+ if (field == null) {
+ return setFieldIndex(0);
+ }
+
+ return setField(field.getDeclaringClass(), field.getName(),
+ field.getType());
+ }
+
+ /**
+ * Set the field this instruction operates on.
+ *
+ * @param dec the full class name of the field's declaring class
+ * @param name the field name
+ * @param type the full class name of the field type
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(String dec, String name, String type) {
+ if ((dec == null) && (name == null) && (type == null)) {
+ return setFieldIndex(0);
+ }
+
+ if (dec == null) {
+ dec = "";
+ }
+
+ if (name == null) {
+ name = "";
+ }
+
+ if (type == null) {
+ type = "";
+ }
+
+ dec = getProject().getNameCache().getInternalForm(dec, false);
+ type = getProject().getNameCache().getInternalForm(type, true);
+
+ return setFieldIndex(getPool().findFieldEntry(dec, name, type, true));
+ }
+
+ /**
+ * Set the field this instruction operates on, for fields that are
+ * declared by the current class.
+ *
+ * @param name the field name
+ * @param type the full class name of the field type
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(String name, String type) {
+ BCClass owner = getCode().getMethod().getDeclarer();
+
+ return setField(owner.getName(), name, type);
+ }
+
+ /**
+ * Set the field this instruction operates on.
+ *
+ * @param dec the field's declaring class
+ * @param name the field name
+ * @param type the class of the field type
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(Class dec, String name, Class type) {
+ String decName = (dec == null) ? null : dec.getName();
+ String typeName = (type == null) ? null : type.getName();
+
+ return setField(decName, name, typeName);
+ }
+
+ /**
+ * Set the field this instruction operates on, for fields that are
+ * declared by the current class.
+ *
+ * @param name the field name
+ * @param type the class of the field type
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(String name, Class type) {
+ BCClass owner = getCode().getMethod().getDeclarer();
+ String typeName = (type == null) ? null : type.getName();
+
+ return setField(owner.getName(), name, typeName);
+ }
+
+ /**
+ * Set the field this instruction operates on.
+ *
+ * @param dec the field's declaring class
+ * @param name the field name
+ * @param type the class of the field type
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(BCClass dec, String name, BCClass type) {
+ String decName = (dec == null) ? null : dec.getName();
+ String typeName = (type == null) ? null : type.getName();
+
+ return setField(decName, name, typeName);
+ }
+
+ /**
+ * Set the field this instruction operates on, for fields that are
+ * declared by the current class.
+ *
+ * @param name the field name
+ * @param type the class of the field type
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setField(String name, BCClass type) {
+ BCClass owner = getCode().getMethod().getDeclarer();
+ String typeName = (type == null) ? null : type.getName();
+
+ return setField(owner.getName(), name, typeName);
+ }
+
+ ////////////////////////////////
+ // Name, Type, Owner operations
+ ////////////////////////////////
+
+ /**
+ * Return the name of the field this instruction operates on, or null
+ * if not set.
+ */
+ public String getFieldName() {
+ int index = getFieldIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String name = entry.getNameAndTypeEntry().getNameEntry().getValue();
+
+ if (name.length() == 0) {
+ return null;
+ }
+
+ return name;
+ }
+
+ /**
+ * Set the name of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldName(String name) {
+ return setField(getFieldDeclarerName(), name, getFieldTypeName());
+ }
+
+ /**
+ * Return the type of the field this instruction operates on, or null
+ * if not set.
+ */
+ public String getFieldTypeName() {
+ int index = getFieldIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String name = getProject().getNameCache()
+ .getExternalForm(entry.getNameAndTypeEntry()
+ .getDescriptorEntry().getValue(),
+ false);
+
+ if (name.length() == 0) {
+ return null;
+ }
+
+ return name;
+ }
+
+ /**
+ * Return the type of the field this instruction operates on, or null
+ * if not set.
+ */
+ public Class getFieldType() {
+ String type = getFieldTypeName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return Strings.toClass(type, getClassLoader());
+ }
+
+ /**
+ * Return the type of the field this instruction operates on, or null
+ * if not set.
+ */
+ public BCClass getFieldTypeBC() {
+ String type = getFieldTypeName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return getProject().loadClass(type, getClassLoader());
+ }
+
+ /**
+ * Set the type of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldType(String type) {
+ return setField(getFieldDeclarerName(), getFieldName(), type);
+ }
+
+ /**
+ * Set the type of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldType(Class type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setFieldType(name);
+ }
+
+ /**
+ * Set the type of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldType(BCClass type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setFieldType(name);
+ }
+
+ /**
+ * Return the declaring class of the field this instruction operates on,
+ * or null if not set.
+ */
+ public String getFieldDeclarerName() {
+ int index = getFieldIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String name = getProject().getNameCache()
+ .getExternalForm(entry.getClassEntry().getNameEntry()
+ .getValue(), false);
+
+ if (name.length() == 0) {
+ return null;
+ }
+
+ return name;
+ }
+
+ /**
+ * Return the declaring class of the field this instruction operates on,
+ * or null if not set.
+ */
+ public Class getFieldDeclarerType() {
+ String type = getFieldDeclarerName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return Strings.toClass(type, getClassLoader());
+ }
+
+ /**
+ * Return the declaring class of the field this instruction operates on,
+ * or null if not set.
+ */
+ public BCClass getFieldDeclarerBC() {
+ String type = getFieldDeclarerName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return getProject().loadClass(type, getClassLoader());
+ }
+
+ /**
+ * Set the declaring class of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldDeclarer(String type) {
+ return setField(type, getFieldName(), getFieldTypeName());
+ }
+
+ /**
+ * Set the declaring class of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldDeclarer(Class type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setFieldDeclarer(name);
+ }
+
+ /**
+ * Set the declaring class of the field this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public FieldInstruction setFieldDeclarer(BCClass type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setFieldDeclarer(name);
+ }
+
+ /**
+ * FieldInstructions are equal if the field they reference is the same,
+ * or if the field of either is unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof FieldInstruction)) {
+ return false;
+ }
+
+ if (!super.equalsInstruction(other)) {
+ return false;
+ }
+
+ FieldInstruction ins = (FieldInstruction) other;
+
+ String s1 = getFieldName();
+ String s2 = ins.getFieldName();
+
+ if (!((s1 == null) || (s2 == null) || s1.equals(s2))) {
+ return false;
+ }
+
+ s1 = getFieldTypeName();
+ s2 = ins.getFieldTypeName();
+
+ if (!((s1 == null) || (s2 == null) || s1.equals(s2))) {
+ return false;
+ }
+
+ s1 = getFieldDeclarerName();
+ s2 = ins.getFieldDeclarerName();
+
+ if (!((s1 == null) || (s2 == null) || s1.equals(s2))) {
+ return false;
+ }
+
+ return true;
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+
+ FieldInstruction ins = (FieldInstruction) orig;
+ setField(ins.getFieldDeclarerName(), ins.getFieldName(),
+ ins.getFieldTypeName());
+ }
+
+ void read(DataInput in) throws IOException {
+ super.read(in);
+ setFieldIndex(in.readUnsignedShort());
+ }
+
+ void write(DataOutput out) throws IOException {
+ super.write(out);
+ out.writeShort(getFieldIndex());
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/FieldInstruction.java
------------------------------------------------------------------------------
svn:executable = *