svn commit: r158176 [7/79] - in incubator/jdo/trunk/ri11: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ src/java/org/apache/jdo/ejb/ src/java/org/apache/jdo/enhancer/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/enhancer/ src/java/org/apache/jdo/impl/enhancer/classfile/ src/java/org/apache/jdo/impl/enhancer/core/ src/java/org/apache/jdo/impl/enhancer/generator/ src/java/org/apache/jdo/impl/enhancer/meta/ src/java/org/apache/jdo/impl/enhancer/meta/model/ src/java/org/apache/jdo/impl/enhancer/meta/prop/ src/java/org/apache/jdo/impl/enhancer/meta/util/ src/java/org/apache/jdo/impl/enhancer/util/ src/java/org/apache/jdo/impl/fostore/ src/java/org/apache/jdo/impl/jdoql/ src/java/org/apache/jdo/impl/jdoql/jdoqlc/ src/java/org/apache/jdo/impl/jdoql/scope/ src/java/org/apache/jdo/impl/jdoql/tree/ src/java/org/apache/jdo/impl/model/ src/java/org/apache/jdo/impl/model/java/ src/java/org/apache/jdo/impl/model/java/runtime/ src/java/org/apache/jdo/impl/model/jdo/ src/java/org/apache/jdo/impl/model/jdo/caching/ src/java/org/apache/jdo/impl/model/jdo/util/ src/java/org/apache/jdo/impl/model/jdo/xml/ src/java/org/apache/jdo/impl/pm/ src/java/org/apache/jdo/impl/sco/ src/java/org/apache/jdo/impl/state/ src/java/org/apache/jdo/jdoql/ src/java/org/apache/jdo/jdoql/tree/ src/java/org/apache/jdo/model/ src/java/org/apache/jdo/model/java/ src/java/org/apache/jdo/model/jdo/ src/java/org/apache/jdo/pm/ src/java/org/apache/jdo/sco/ src/java/org/apache/jdo/state/ src/java/org/apache/jdo/store/ src/java/org/apache/jdo/util/ test/ test/conf/ test/enhancer/ test/enhancer/sempdept/ test/enhancer/sempdept/src/ test/enhancer/sempdept/src/empdept/ test/fsuid2/ test/fsuid2/org/ test/fsuid2/org/apache/ test/fsuid2/org/apache/jdo/ test/fsuid2/org/apache/jdo/pc/ test/java/ test/java/org/ test/java/org/apache/ test/java/org/apache/jdo/ test/java/org/apache/jdo/impl/ test/java/org/apache/jdo/impl/fostore/ test/java/org/apache/jdo/pc/ test/java/org/apache/jdo/pc/appid/ test/java/org/apache/jdo/pc/empdept/ test/java/org/apache/jdo/pc/serializable/ test/java/org/apache/jdo/pc/xempdept/ test/java/org/apache/jdo/test/ test/java/org/apache/jdo/test/query/ test/java/org/apache/jdo/test/util/ test/jdo/ test/jdo/org/ test/jdo/org/apache/ test/jdo/org/apache/jdo/ test/jdo/org/apache/jdo/pc/ test/jdo/org/apache/jdo/pc/appid/ test/jdo/org/apache/jdo/pc/empdept/ test/jdo/org/apache/jdo/pc/serializable/ test/jdo/org/apache/jdo/pc/xempdept/ xdocs/

19 Mar 2005 05:33:01 -0000

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Descriptor.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Descriptor.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Descriptor.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Descriptor.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.util.Stack;
+import java.util.Map;
+
+//@olsen: subst: Hashtable -> Map, HashMap
+
+
+/**
+ * A collection of static methods which manipulate type descriptors
+ */
+public class Descriptor implements VMConstants {
+    /** 
+     * Return the number of words of arguments to the method 
+     * based on the method signature
+     */
+    public static int countMethodArgWords(String sig) {
+        if (sig.charAt(0) != '(')
+            throw new InsnError ("not a method signature");
+        int count = 0;
+        for (int idx = 1; sig.charAt(idx) != ')'; idx++) {
+            switch (sig.charAt(idx)) {
+            case 'B': /* byte */
+            case 'C': /* char */
+            case 'S': /* short */
+            case 'I': /* int */
+            case 'F': /* float */
+            case 'Z': /* boolean */
+                count++;
+                break;
+            case 'J': /* long */
+            case 'D': /* double */
+                count += 2;
+                break;
+            case 'L':
+                count++;
+                idx = sig.indexOf(';', idx);
+                break;
+            case '[':
+                count++;
+                while (sig.charAt(idx) == '[' || sig.charAt(idx) == ']')
+                    idx++;
+                if (sig.charAt(idx) == 'L')
+                    idx = sig.indexOf(';', idx);
+                /* else, let idx++ at loop iteration skip primitive descriptor 
*/
+                break;
+            default:
+                throw new InsnError("missing case");
+            }
+        }
+        return count;
+    }
+
+    /** 
+     * Return the number of words of return value for the method
+     * based on the method signature
+     */
+    public static int countMethodReturnWords(String sig) {
+        int idx = sig.lastIndexOf(')') + 1;
+        if (idx == 0)
+            throw new InsnError ("not a method signature");
+        switch (sig.charAt(idx)) {
+        case 'J': /* long */
+        case 'D': /* double */
+            return 2;
+        case 'B': /* byte */
+        case 'C': /* char */
+        case 'S': /* short */
+        case 'I': /* int */
+        case 'F': /* float */
+        case 'Z': /* boolean */
+        case 'L': /* object */
+        case '[': /* array */
+            return 1;
+        case 'V': /* void */
+            return 0;
+        default:
+            throw new InsnError("missing case");
+        }
+    }
+
+    /**
+     * Return the stack descriptor for the result of a method
+     * invocation.  Void return values yield "V".
+     */
+    public static String extractResultSig(String methodSig) {
+        return methodSig.substring(methodSig.indexOf(')')+1);
+    }
+
+    /**
+     * Return the stack descriptor for the arguments to a method
+     * invocation (not including any "this" argument)
+     */
+    public static String extractArgSig(String methodSig) {
+        return methodSig.substring(1, methodSig.indexOf(')'));
+    }
+
+    /**
+     * Return the reversed stack descriptor for the arguments to a method
+     * invocation (not including any "this" argument).  The top of stack
+     * element will be first.
+     */
+    public static String extractReversedArgSig(String methodSig) {
+        StringBuffer buf = new StringBuffer();;
+        reverseArgSig(buf, methodSig, 1);
+        return buf.toString();
+    }
+
+    /**
+     * Given a StringBuffer, a method descriptor, and a index to the 
+     * start of an argument descriptor, append the arguments to the
+     * string buffer in reverse order.
+     */
+    private static void reverseArgSig(StringBuffer buf, String methodSig, 
+                                      int idx) {
+        char c = methodSig.charAt(idx);
+        if (c == ')')
+            return;
+        int startIdx = idx;
+
+        switch(c) {
+        case 'B':
+        case 'C':
+        case 'S':
+        case 'I':
+        case 'F':
+        case 'J':
+        case 'D':
+        case 'Z':
+            idx = idx+1;
+            break;
+        case '[':
+            while (methodSig.charAt(idx) == '[' || methodSig.charAt(idx) == 
']')
+                idx++;
+            if (methodSig.charAt(idx) != 'L') {
+                idx++;
+                break;
+            }
+            /* fall through */
+        case 'L':
+            idx = methodSig.indexOf(';', idx) + 1;
+            break;
+        default:
+            throw new InsnError("bad signature char");
+        }
+
+        reverseArgSig(buf, methodSig, idx);
+        while (startIdx < idx)
+            buf.append(methodSig.charAt(startIdx++));
+    }
+
+    /** 
+     * Return the number of words of a field based on its signature.
+     */
+    //@olsen: added method
+    public static int countFieldWords(String sig) {
+        if (sig == null || sig.length() < 1)
+            throw new InsnError ("not a field signature");
+        switch (sig.charAt(0)) {
+        case 'J': /* long */
+        case 'D': /* double */
+            return 2;
+        case 'B': /* byte */
+        case 'C': /* char */
+        case 'S': /* short */
+        case 'I': /* int */
+        case 'F': /* float */
+        case 'Z': /* boolean */
+        case 'L': /* object */
+        case '[': /* array */
+            return 1;
+        default:
+            throw new InsnError("missing case");
+        }
+    }
+
+    /**
+     * Return the element type for the first char in the type descriptor 
string.
+     */
+    //@olsen: added method
+    public static int elementType(String sig) {
+        if (sig == null || sig.length() < 1)
+            throw new InsnError ("not a value signature");
+        switch(sig.charAt(0)) {
+        case 'B':
+            return T_BOOLEAN;
+        case 'C':
+            return T_CHAR;
+        case 'Z':
+            return T_BYTE;
+        case 'S':
+            return T_SHORT;
+        case 'I':
+            return T_INT;
+        case 'J':
+            return T_LONG;
+        case 'F':
+            return T_FLOAT;
+        case 'D':
+            return T_DOUBLE;
+        case '[':
+            return TC_OBJECT;
+        case 'L':
+            return TC_OBJECT;
+        default:
+            throw new InsnError("bad signature char");
+        }
+    }
+
+    /**
+     * Return the element type descriptor char for the element type.
+     * The element type must be one of the T_ or TC_OBJECT.
+     */
+    public static String elementSig(int valueType) {
+        switch(valueType) {
+        case T_BYTE:
+            return "B";
+        case T_CHAR:
+            return "C";
+        case T_BOOLEAN:
+            return "Z";
+        case T_SHORT:
+            return "S";
+        case T_INT:
+            return "I";
+        case T_LONG:
+            return "J";
+        case T_FLOAT:
+            return "F";
+        case T_DOUBLE:
+            return "D";
+        case TC_OBJECT:
+            return "Ljava/lang/Object;";
+        default:
+            throw new InsnError("bad element type");
+        }
+    }
+
+    /**
+     * Return the number of stack words required for a value of the specified
+     * type on the operand stack.
+     */
+    public static int elementSize(int elementType) {
+        switch(elementType) {
+        case T_LONG:
+        case T_DOUBLE:
+        case T_TWOWORD:
+            return 2;
+        default:
+            return 1;
+        }
+    }
+
+    /**
+     * stackSig is a signature for a list of types on the JVM stack with the
+     * last type in the signature intended to be on the top of JVM stack.
+     * For each type in the signature, pushes an Integer objects identifying
+     * the types on top of the input Stack object.
+     */
+    public static void computeStackTypes(String stackSig, Stack stack) {
+        for (int idx = 0; idx < stackSig.length(); idx++) {
+            int tp = 0;
+            switch(stackSig.charAt(idx)) {
+            case 'B':
+            case 'C':
+            case 'Z':
+            case 'S':
+            case 'I':
+                tp = T_INT;
+                break;
+            case 'F':
+                tp = T_FLOAT;
+                break;
+            case 'J':
+                tp = T_LONG;
+                break;
+            case 'D':
+                tp = T_DOUBLE;
+                break;
+            case '?':
+                tp = T_UNKNOWN;
+                break;
+            case 'W':
+                tp = T_WORD;
+                break;
+            case 'X':
+                tp = T_TWOWORD;
+                break;
+            case 'A':
+                /* This isn't a real type, but any object refrence */
+                tp = TC_OBJECT;
+                break;
+            case '[':
+                tp = TC_OBJECT;
+                while (stackSig.charAt(idx) == '[' || stackSig.charAt(idx) == 
']')
+                    idx++;
+                if (stackSig.charAt(idx) != 'L')
+                    break;
+                /* fall through */
+            case 'L':
+                tp = TC_OBJECT;
+                idx = stackSig.indexOf(';', idx);
+                break;
+            default:
+                throw new InsnError("bad signature char");
+            }
+            stack.push(new Integer(tp));
+        }
+    }
+
+    /**
+     * stackSig is a signature for the types on the stack with the last
+     * type in the signature on the top of stack.  idx is the index of
+     * the start of a valid signature type element.  Return the index of
+     * the next element (which may be past the end of the string).
+     */
+    public static int nextSigElement(String stackSig, int idx) {
+        switch(stackSig.charAt(idx)) {
+        case 'B':
+        case 'C':
+        case 'Z':
+        case 'S':
+        case 'I':
+        case 'F':
+        case 'J':
+        case 'D':
+            break;
+        case '[':
+            while (stackSig.charAt(idx) == '[' || stackSig.charAt(idx) == ']')
+                idx++;
+            if (stackSig.charAt(idx) != 'L')
+                break;
+            /* fall through */
+        case 'L':
+            idx = stackSig.indexOf(';', idx);
+            break;
+        default:
+            throw new InsnError("bad signature char");
+        }
+
+        idx++;
+        return idx;
+    }
+
+    /**
+     * classTranslations contains a set of mappings of class names.
+     * For any types within the input signature which appear as keys
+     * in the translation table, change the signature to replace the
+     * original type with the translation.  Return a string containing
+     * the original signature with any translations applied.
+     */
+    public static String remapTypes(String sig, Map classTranslations) {
+        /* Defer allocation of the string buffer until it's needed */
+        StringBuffer buf = null;
+
+        for (int idx = 0; idx < sig.length(); idx++) {
+            char c;
+            switch(c = sig.charAt(idx)) {
+            case '[':
+                /* An array - skip through the [] pairs, copying to buf if not 
null */
+                while ((c = sig.charAt(idx)) == '[' || c == ']') {
+                    idx++;
+                    if (buf != null)
+                        buf.append(c);
+                }
+
+                /* If the next char isnt 'L', the next char is a simple type 
and
+                   will be handled by the default 1 char translation */
+                if (sig.charAt(idx) != 'L')
+                    break;
+                /* fall through to type name translation */
+            case 'L':
+                /* This is a type name */
+                idx++;
+                int endIdx = sig.indexOf(';', idx);
+                String typeName = sig.substring(idx, endIdx);
+                String mapTo = (String) classTranslations.get(typeName);
+                if (mapTo != null) {
+                    /* This type needs translation - allocate the string buffer
+                       now if needed and copy in all up to this type name. */
+                    if (buf == null) {
+                        buf = new StringBuffer(sig.length() + 20);
+                        buf.append(sig.substring(0,idx-1));
+                    }
+                    typeName = mapTo;
+                }
+
+                if (buf != null) {
+                    buf.append('L');
+                    buf.append(typeName);
+                }
+                idx = endIdx;
+                c = ';';
+                break;
+            }
+
+            if (buf != null)
+                buf.append(c);
+        }
+        return (buf == null) ? sig : (buf.toString());
+    }
+
+    /**
+     * classTranslations contains a set of mappings of class names.
+     * Translate the class name (which may be an array class) according
+     * to the entries in the translation table.
+     * Return either the original string if no translation applies or
+     * else the translated string.
+     */
+    public static String translateClass(
+       String cls, Map classTranslations) {
+        if (cls.charAt(0) == '[')
+            return remapTypes(cls, classTranslations);
+        else {
+            String mapTo = (String) classTranslations.get(cls);
+            if (mapTo != null)
+                return mapTo;
+            return cls;
+        }
+    }
+
+    /**
+     * Translates a VM type field signature into a  user-format signature.
+     * Just a front for the two argument overload of this method.
+     */
+    public static String userFieldSig(String vmSig) {
+        return userFieldSig(vmSig, 0);
+    }
+
+    /**
+     * Translates a VM type field signature into a  user-format signature.
+     */
+    public static String userFieldSig(String vmSig, int idx) {
+        String sigElement = "";
+        int arrayDims = 0;
+        boolean moreSig = true;
+        while (moreSig) {
+            moreSig = false;
+            char c = vmSig.charAt(idx);
+            switch (c) {
+            case 'B':
+                sigElement = "byte";
+                break;
+            case 'C':
+                sigElement = "char";
+                break;
+            case 'Z':
+                sigElement = "boolean";
+                break;
+            case 'S':
+                sigElement = "short";
+                break;
+            case 'I':
+                sigElement = "int";
+                break;
+            case 'F':
+                sigElement = "float";
+                break;
+            case 'J':
+                sigElement = "long";
+                break;
+            case 'D':
+                sigElement = "double";
+                break;
+            case 'V':
+                /* void isn't really valid as a field signature but this method
+                   might be useful in implementing method signature conversion 
and
+                   void is a valid return type. */
+                sigElement = "void";
+                break;
+            case '[':
+                idx++;
+                arrayDims++;
+                moreSig = true;
+                break;
+            case 'L':
+                int nextIdx = vmSig.indexOf(';', idx);
+                sigElement = vmSig.substring(idx+1,nextIdx).replace('/','.');
+                break;
+            default:
+                throw new InsnError("bad signature char");
+            }
+        }
+
+        /* If a non-array type, we already have the answer */
+        if (arrayDims == 0)
+            return sigElement;
+
+        /* array types need a little more work */
+        StringBuffer buf = new StringBuffer(sigElement.length()
+                                            + 2 * arrayDims);
+        buf.append(sigElement);
+        while (arrayDims-- > 0) 
+            buf.append("[]");
+
+        return buf.toString();
+    }
+
+    /**
+     * Produce a user consumable representation of a method argument list
+     * from the method signature.  The return value is ignored.
+     */
+    public static String userMethodArgs(String methodSig) {
+        /* This better be a method signature */
+        if (methodSig.charAt(0) != '(')
+            throw new InsnError("Invalid method signature");
+
+        StringBuffer buf = new StringBuffer();
+
+        buf.append('(');
+
+        int idx = 1;
+        boolean firstArg = true;
+        while (methodSig.charAt(idx) != ')') {
+            if (firstArg)
+                firstArg = false;
+            else
+                buf.append(", ");
+       
+            buf.append(userFieldSig(methodSig, idx));
+            idx = nextSigElement(methodSig, idx);
+        }
+
+        buf.append(')');
+        return buf.toString();
+    }
+
+    /**
+     * Produce a user consumable representation of a method result type
+     * from the method signature.  The argument list is ignored.
+     */
+    //@olsen: added method
+    public static String userMethodResult(String methodSig) {
+        /* This better be a method signature */
+        if (methodSig.charAt(0) != '(')
+            throw new InsnError("Invalid method signature");
+        return userFieldSig(extractResultSig(methodSig));    
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionRange.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionRange.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionRange.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionRange.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+import java.util.Stack;
+
+/**
+ * ExceptionRange represents a range an exception handler within
+ * a method in class file.
+ */
+public class ExceptionRange {
+    /* The start of the exception hander (inclusive) */
+    private InsnTarget excStartPC;
+
+    /* The end of the exception hander (exclusive) */
+    private InsnTarget excEndPC;
+
+    /* The exception handler code */
+    private InsnTarget excHandlerPC;
+
+    /* The exception specification */
+    private ConstClass excCatchType;
+
+    /* public accessors */
+
+    /**
+     * return the start of the exception hander (inclusive)
+     */
+    public InsnTarget startPC() {
+        return excStartPC;
+    }
+
+    /**
+     * return the end of the exception hander (exclusive)
+     */
+    public InsnTarget endPC() {
+        return excEndPC;
+    }
+
+    /**
+     * return the exception handler code
+     */
+    public InsnTarget handlerPC() {
+        return excHandlerPC;
+    }
+
+    /** 
+     * return the exception specification
+     * a null return value means a catch of any (try/finally)
+     */
+    public ConstClass catchType() {
+        return excCatchType;
+    }
+
+    /**
+     * constructor 
+     */
+    public ExceptionRange(InsnTarget startPC, InsnTarget endPC,
+                          InsnTarget handlerPC, ConstClass catchType) {
+        excStartPC = startPC;
+        excEndPC = endPC;
+        excHandlerPC = handlerPC;
+        excCatchType = catchType;
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof ExceptionRange)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        ExceptionRange other = (ExceptionRange)obj;
+
+        if (!this.excStartPC.isEqual(msg, other.excStartPC)) {
+            msg.push(String.valueOf("excStartPC = "
+                                    + other.excStartPC));
+            msg.push(String.valueOf("excStartPC = "
+                                    + this.excStartPC));
+            return false;
+        }
+        if (!this.excEndPC.isEqual(msg, other.excEndPC)) {
+            msg.push(String.valueOf("excEndPC = "
+                                    + other.excEndPC));
+            msg.push(String.valueOf("excEndPC = "
+                                    + this.excEndPC));
+            return false;
+        }
+        if (!this.excHandlerPC.isEqual(msg, other.excHandlerPC)) {
+            msg.push(String.valueOf("excHandlerPC = "
+                                    + other.excHandlerPC));
+            msg.push(String.valueOf("excHandlerPC = "
+                                    + this.excHandlerPC));
+            return false;
+        }
+        if (!this.excCatchType.isEqual(msg, other.excCatchType)) {
+            msg.push(String.valueOf("excCatchType = "
+                                    + other.excCatchType));
+            msg.push(String.valueOf("excCatchType = "
+                                    + this.excCatchType));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    static ExceptionRange read(DataInputStream data, CodeEnv env)
+        throws IOException {
+        InsnTarget startPC = env.getTarget(data.readUnsignedShort());
+        InsnTarget endPC = env.getTarget(data.readUnsignedShort());
+        InsnTarget handlerPC = env.getTarget(data.readUnsignedShort());
+        ConstClass catchType =
+            (ConstClass) env.pool().constantAt(data.readUnsignedShort());
+        return new ExceptionRange(startPC, endPC, handlerPC, catchType);
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(excStartPC.offset());
+        out.writeShort(excEndPC.offset());
+        out.writeShort(excHandlerPC.offset());
+        out.writeShort(excCatchType == null ? 0 : excCatchType.getIndex());
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.print("Exc Range:");
+        if (excCatchType == null)
+            out.print("any");
+        else
+            out.print("'" + excCatchType.asString() + "'");
+        out.print(" start = " + Integer.toString(excStartPC.offset()));
+        out.print(" end = " + Integer.toString(excEndPC.offset()));
+        out.println(" handle = " + Integer.toString(excHandlerPC.offset()));
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionTable.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionTable.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionTable.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionTable.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * ExceptionTable represents the exception handlers within the code
+ * of a method.
+ */
+public class ExceptionTable {
+    /* A variable length list of ExceptionRange objects */
+    //@olsen: renamed theVector -> handlers
+    private Vector handlers = new Vector();
+
+    /* public accessors */
+
+    /**
+     * Return an enumeration of the exception handlers
+     * Each element in the enumeration is an ExceptionRange
+     */
+    public Enumeration handlers() {
+        return handlers.elements();
+    }
+
+    /**
+     * Add an exception handler to the list
+     */
+    public void addElement(ExceptionRange range) {
+        handlers.addElement(range);
+    }
+
+    public ExceptionTable() { }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof ExceptionTable)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        ExceptionTable other = (ExceptionTable)obj;
+
+        if (this.handlers.size() != other.handlers.size()) {
+            msg.push("handlers.size() "
+                     + String.valueOf(other.handlers.size()));
+            msg.push("handlers.size() "
+                     + String.valueOf(this.handlers.size()));
+            return false;
+        }
+
+        for (int i = 0; i < handlers.size(); i++) {
+            ClassAttribute h1 = (ClassAttribute)this.handlers.get(i);
+            ClassAttribute h2 = (ClassAttribute)other.handlers.get(i);
+            if (!h1.isEqual(msg, h2)) {
+                msg.push("handlers[" + i + "] = "
+                         + String.valueOf(h2));
+                msg.push("handlers[" + i + "] = "
+                         + String.valueOf(h1));
+                return false;
+            }
+        }
+        return true;
+    }
+
+   /* package local methods */
+
+    static ExceptionTable read(DataInputStream data, CodeEnv env)
+        throws IOException {
+        ExceptionTable excTable = new ExceptionTable();
+        int nExcepts = data.readUnsignedShort();
+        while (nExcepts-- > 0) {
+            excTable.addElement(ExceptionRange.read(data, env));
+        }
+        return excTable;
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(handlers.size());
+        for (int i=0; i<handlers.size(); i++)
+            ((ExceptionRange) handlers.elementAt(i)).write(out);
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println("Exception Table: ");
+        for (int i=0; i<handlers.size(); i++)
+            ((ExceptionRange) handlers.elementAt(i)).print(out, indent+2);
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionsAttribute.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionsAttribute.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionsAttribute.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/ExceptionsAttribute.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+import java.util.Stack;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * ExceptionsAttribute represents a method attribute in a class file
+ * listing the checked exceptions for the method.
+ */
+public class ExceptionsAttribute extends ClassAttribute {
+    public final static String expectedAttrName = "Exceptions";
+
+    /* The list of checked exceptions */
+    private Vector exceptionTable;
+
+    /* public accessors */
+
+    /**
+     *  Return an enumeration of the checked exceptions
+     */
+    public Enumeration exceptions() {
+        return exceptionTable.elements();
+    }
+
+    /**
+     * Returns the vector of the checked exceptions.
+     */
+    //@olsen: added method
+    public Vector getExceptions() {
+        return exceptionTable;
+    }
+
+    /**
+     * Constructor
+     */
+    public ExceptionsAttribute(ConstUtf8 attrName, Vector excTable) {
+        super(attrName);
+        exceptionTable = excTable;
+    }
+
+    /**
+     * Convenience Constructor - for single exception
+     */
+    public ExceptionsAttribute(ConstUtf8 attrName, ConstClass exc) {
+        super(attrName);
+        exceptionTable = new Vector(1);
+        exceptionTable.addElement(exc);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof ExceptionsAttribute)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        ExceptionsAttribute other = (ExceptionsAttribute)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.exceptionTable.size() != other.exceptionTable.size()) {
+            msg.push("exceptionTable.size() "
+                     + String.valueOf(other.exceptionTable.size()));
+            msg.push("exceptionTable.size() "
+                     + String.valueOf(this.exceptionTable.size()));
+            return false;
+        }
+
+        // sort exceptions by name
+        class ConstClassComparator implements Comparator {
+            public int compare(Object o1, Object o2) {
+                ConstClass c1 = (ConstClass)o1;
+                ConstClass c2 = (ConstClass)o2;
+                String s1 = c1.className().asString();
+                String s2 = c2.className().asString();
+                return s1.compareTo(s2);
+            }
+        }
+        ConstClassComparator comparator = new ConstClassComparator();
+        ConstClass[] thisExceptionTable
+            = (ConstClass[])this.exceptionTable.toArray(new ConstClass[0]);
+        ConstClass[] otherExceptionTable
+            = (ConstClass[])other.exceptionTable.toArray(new ConstClass[0]);
+        Arrays.sort(thisExceptionTable, comparator);
+        Arrays.sort(otherExceptionTable, comparator);
+        for (int i = 0; i < exceptionTable.size(); i++) {
+            ConstClass c1 = thisExceptionTable[i];
+            ConstClass c2 = otherExceptionTable[i];
+            if (!c1.isEqual(msg, c2)) {
+                msg.push("exceptionTable[i] = " + String.valueOf(c2));
+                msg.push("exceptionTable[i] = " + String.valueOf(c1));
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    static ExceptionsAttribute read(ConstUtf8 attrName,
+                                    DataInputStream data, ConstantPool pool)
+        throws IOException {
+        int nExcepts = data.readUnsignedShort();
+        Vector excTable = new Vector();
+        while (nExcepts-- > 0) {
+            int excIndex = data.readUnsignedShort();
+            ConstClass exc_class = null;
+            if (excIndex != 0)
+                exc_class = (ConstClass) pool.constantAt(excIndex);
+            excTable.addElement(exc_class);
+        }
+        
+        return new ExceptionsAttribute(attrName, excTable);
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(attrName().getIndex());
+        out.writeInt(2+2*exceptionTable.size());
+        out.writeShort(exceptionTable.size());
+        for (int i=0; i<exceptionTable.size(); i++)
+            out.writeShort(((ConstClass) 
exceptionTable.elementAt(i)).getIndex());
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.print("Exceptions:");
+        for (int i=0; i<exceptionTable.size(); i++)
+            out.print(" " + ((ConstClass) 
exceptionTable.elementAt(i)).asString());
+        out.println();
+    }
+  
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/GenericAttribute.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/GenericAttribute.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/GenericAttribute.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/GenericAttribute.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+import java.util.Stack;
+
+/**
+ * GenericAttribute represents a class attribute in a class file which
+ * is not recognized as any supported attribute type.  These attributes
+ * are maintained, and are not modified in any way.
+ */
+
+public class GenericAttribute extends ClassAttribute {
+
+    /* The bytes of the attribute following the name */
+    byte attributeBytes[];
+
+    /* public accessors */
+
+    /**
+     * constructor
+     */
+    public GenericAttribute(ConstUtf8 attrName, byte attrBytes[]) {
+        super(attrName);
+        attributeBytes = attrBytes;
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof GenericAttribute)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        GenericAttribute other = (GenericAttribute)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.attributeBytes.length != other.attributeBytes.length) {
+            msg.push("attributeBytes.length "
+                     + String.valueOf(other.attributeBytes.length));
+            msg.push("attributeBytes.length "
+                     + String.valueOf(this.attributeBytes.length));
+            return false;
+        }
+
+        for (int i = 0; i < attributeBytes.length; i++) {
+            byte b1 = this.attributeBytes[i];
+            byte b2 = other.attributeBytes[i];
+            if (b1 != b2) {
+                msg.push("attributeBytes[" + i + "] = "
+                         + String.valueOf(b2));
+                msg.push("attributeBytes[" + i + "] = "
+                         + String.valueOf(b1));
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(attrName().getIndex());
+        out.writeInt(attributeBytes.length);
+        out.write(attributeBytes, 0, attributeBytes.length);
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println("Generic Attribute(" + attrName().asString() + "): " +
+                    Integer.toString(attributeBytes.length) +
+                    " in length");
+        for (int i=0; i<attributeBytes.length; i++) {
+            if ((i % 16) == 0) {
+                if (i != 0) 
+                    out.println();
+                out.print(i + " :");
+            }
+            out.print(" " + Integer.toString((attributeBytes[i] & 0xff), 16));
+        }
+        out.println();
+    }
+}
+

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Insn.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Insn.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Insn.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/Insn.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,660 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.PrintStream;
+import java.util.Stack;
+
+/**
+ * Insn is an abstract class which represents a java VM instruction in a
+ * sequence of instructions.
+ */
+abstract public class Insn implements VMConstants {
+    /* An instruction with no pc defined yet */
+    final static int NO_OFFSET = -1;
+
+    /* A special magic opcode for branch target pseudo instructions */
+    final public static int opc_target = -1;
+
+    /* The opcode of this instruction */
+    private int insnOpcode;
+
+    /* The pc of this instruction within the containing code sequence */
+    private int insnOffset = NO_OFFSET;
+
+    /* The next instruction in the code sequence */
+    private Insn nextInsn = null;
+
+    /* The previous instruction in the code sequence */
+    private Insn prevInsn = null;
+
+    /* public accessors */
+
+    /**
+     * Returns the next instruction in the code sequence
+     */
+    public Insn next() {
+        return nextInsn;
+    }
+
+    /**
+     * Returns the previous instruction in the code sequence
+     */
+    public Insn prev() {
+        return prevInsn;
+    }
+
+    /**
+     * Removes the current instruction from it's embedding sequence.
+     */
+    //@olsen: added method
+    public void remove() {
+        if (nextInsn != null)
+            nextInsn.prevInsn = prevInsn;
+
+        if (prevInsn != null)
+            prevInsn.nextInsn = nextInsn;
+
+        prevInsn = null;
+        nextInsn = null;
+    }
+
+    /**
+     * Insert the single instruction in the code sequence after this 
+     * instruction.
+     * Returns the inserted instruction.
+     */
+    public Insn setNext(Insn i) {
+        if (nextInsn != null)
+            nextInsn.prevInsn = i;
+
+        if (i != null) {
+            i.nextInsn = nextInsn;
+            i.prevInsn = this;
+        }
+        nextInsn = i;
+        return i;
+    }
+
+    /**
+     * Insert an instruction sequence in the code sequence after this 
+     * instruction.
+     * Returns the final instruction.
+     */
+    public Insn insert(Insn i) {
+        if (i == null)
+            return this;
+
+        Insn theNextInsn = nextInsn;
+        nextInsn = i;
+        i.prevInsn = this;
+
+        while (i.nextInsn != null)
+            i = i.nextInsn;
+        i.nextInsn = theNextInsn;
+        if (theNextInsn != null)
+            theNextInsn.prevInsn = i;
+        return i;
+    }
+
+    /**
+     * Append an instruction sequence at the end of this instruction
+     * sequence. 
+     * Returns the final instruction.
+     */
+    public Insn append(Insn i) {
+        Insn thisInsn = this;
+        while (thisInsn.nextInsn != null)
+            thisInsn = thisInsn.nextInsn;
+        return thisInsn.insert(i);
+    }
+
+    /**
+     * Return the opcode for this instruction
+     */
+    public int opcode() {
+        return insnOpcode;
+    }
+
+    /**
+     * Return the offset of this instruction in the containing code sequence
+     */
+    public int offset() {
+        return insnOffset;
+    }
+
+    /**
+     * How many words of stack operands does this instruction take?
+     */
+    abstract public int nStackArgs();
+
+    /**
+     * How many words of stack results does this instruction deposit?
+     */
+    abstract public int nStackResults();
+
+    /**
+     * What are the types of the stack operands ?
+     */
+    abstract public String argTypes();
+
+    /**
+     * What are the types of the stack results?
+     */
+    abstract public String resultTypes();
+
+    /**
+     * Does this instruction branch?
+     */
+    abstract public boolean branches();
+
+    /**
+     * Mark possible branch targets
+     */
+    public void markTargets() {
+    }
+
+    /**
+     * Return the name of the operation for a given opcode
+     */
+    public static String opName(int opcode) {
+        if (opcode == opc_target)
+            return "target:";
+        if (opcode >=0 && opcode <= VMOp.ops.length)
+            return VMOp.ops[opcode].name();
+        else
+            throw new InsnError("invalid opcode for opName: " + opcode);
+    }
+
+    /* Instruction creation interfaces - these should be used for all
+     * instructions except opc_iinc, opc_tableswitch, opc_lookupswitch,
+     * opc_multidimarraynew, and opc_invokeinterface.
+     */
+
+    /**
+     * Create an instruction which requires no immediate operands
+     */
+    public static Insn create(int theOpCode) {
+        return new InsnSingle(theOpCode);
+    }
+
+    /**
+     * Create an instruction which requires a single constant from the 
+     * constant pool as an immediate operand.
+     */
+    public static Insn create(int theOpCode, ConstBasic constValue) {
+        return new InsnConstOp(theOpCode, constValue);
+    }
+
+    /**
+     * Create an instruction which requires a single integral constant
+     * as an immediate operand.
+     */
+    public static Insn create(int theOpCode, int intValue) {
+        return new InsnIntOp(theOpCode, intValue);
+    }
+
+    /**
+     * Create an instruction which requires a single branch offset
+     * as an immediate operand.
+     */
+    public static Insn create(int theOpCode, InsnTarget target) {
+        return new InsnTargetOp(theOpCode, target);
+    }
+
+    /**
+     * Print the sequence of instructions to the output stream
+     */
+    public void printList(PrintStream out) {
+        Insn insn = this;
+        while (insn != null) {
+            insn.print(out, 0);
+            insn = insn.next();
+        }
+    }
+
+    /**
+     * Print this instruction to the output stream
+     */
+    public void printInsn(PrintStream out) {
+        print(out, 0);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof Insn)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        Insn other = (Insn)obj;
+
+        if (this.insnOpcode != other.insnOpcode) {
+            // be tolerant against opc_ldc vs. opc_ldc_w
+            if (!((this.insnOpcode == opc_ldc
+                   || this.insnOpcode == opc_ldc_w)
+                  && (other.insnOpcode == opc_ldc
+                      || other.insnOpcode == opc_ldc_w))) {
+                msg.push(String.valueOf("insnOpcode = "
+                                        + other.insnOpcode));
+                msg.push(String.valueOf("insnOpcode = "
+                                        + this.insnOpcode));
+                return false;
+            }
+        }
+        // offsets may differ due to different byte length
+        // (e.g. opc_ldc vs. opc_ldc_w)
+        //if (this.insnOffset != other.insnOffset) {
+        //    msg.push(String.valueOf("insnOffset = "
+        //                            + other.insnOffset));
+        //    msg.push(String.valueOf("insnOffset = "
+        //                            + this.insnOffset));
+        //    return false;
+        //}
+        return true;
+    }
+
+    /**
+     * A printable representation 
+     */
+    public String toString() {
+        return ("Insn: " + "insnOpcode(" + opName(insnOpcode) + ")"
+                + "  insnOffset(" + insnOffset + ")");
+    }
+
+    /* package local methods */
+
+    abstract void print(PrintStream out, int indent);
+
+    abstract int store(byte[] buf, int index);
+
+    /* return the size of the instruction in bytes
+     * Note: some instructions are unable to answer correctly until their
+     * start offset is known
+     */
+    abstract int size();
+
+    /* Set the offset of the instruction and return the offset of the
+       following instruction */
+
+    final int resolveOffset(int pc) {
+        insnOffset = pc;
+        return pc + size();
+    }
+
+    Insn(int theOpcode, int theOffset) {
+        insnOpcode = theOpcode;
+        insnOffset = theOffset;
+    }
+
+    static int storeInt(byte buf[], int index, int v) {
+        buf[index++] = (byte) (v >> 24);
+        buf[index++] = (byte) ((v >> 16) & 0xff);
+        buf[index++] = (byte) ((v >> 8) & 0xff);
+        buf[index++] = (byte) (v & 0xff);
+        return index;
+    }
+
+
+    static int storeShort(byte buf[], int index, short v) {
+        buf[index++] = (byte) ((v >> 8) & 0xff);
+        buf[index++] = (byte) (v & 0xff);
+        return index;
+    }
+
+    static Insn read(InsnReadEnv insnEnv) {
+        boolean widen = false;
+        int pc = insnEnv.currentPC();
+
+        int op = insnEnv.getUByte();
+        if (op == opc_wide) {
+            widen = true;
+            op = insnEnv.getUByte();
+        }
+
+        switch (op) {
+        case opc_nop:
+        case opc_aconst_null:
+        case opc_iconst_m1:
+        case opc_iconst_0:
+        case opc_iconst_1:
+        case opc_iconst_2:
+        case opc_iconst_3:
+        case opc_iconst_4:
+        case opc_iconst_5:
+        case opc_lconst_0:
+        case opc_lconst_1:
+        case opc_fconst_0:
+        case opc_fconst_1:
+        case opc_fconst_2:
+        case opc_dconst_0:
+        case opc_dconst_1:
+        case opc_iload_0:
+        case opc_iload_1:
+        case opc_iload_2:
+        case opc_iload_3:
+        case opc_lload_0:
+        case opc_lload_1:
+        case opc_lload_2:
+        case opc_lload_3:
+        case opc_fload_0:
+        case opc_fload_1:
+        case opc_fload_2:
+        case opc_fload_3:
+        case opc_dload_0:
+        case opc_dload_1:
+        case opc_dload_2:
+        case opc_dload_3:
+        case opc_aload_0:
+        case opc_aload_1:
+        case opc_aload_2:
+        case opc_aload_3:
+        case opc_iaload:
+        case opc_laload:
+        case opc_faload:
+        case opc_daload:
+        case opc_aaload:
+        case opc_baload:
+        case opc_caload:
+        case opc_saload:
+        case opc_istore_0:
+        case opc_istore_1:
+        case opc_istore_2:
+        case opc_istore_3:
+        case opc_lstore_0:
+        case opc_lstore_1:
+        case opc_lstore_2:
+        case opc_lstore_3:
+        case opc_fstore_0:
+        case opc_fstore_1:
+        case opc_fstore_2:
+        case opc_fstore_3:
+        case opc_dstore_0:
+        case opc_dstore_1:
+        case opc_dstore_2:
+        case opc_dstore_3:
+        case opc_astore_0:
+        case opc_astore_1:
+        case opc_astore_2:
+        case opc_astore_3:
+        case opc_iastore:
+        case opc_lastore:
+        case opc_fastore:
+        case opc_dastore:
+        case opc_aastore:
+        case opc_bastore:
+        case opc_castore:
+        case opc_sastore:
+        case opc_pop:
+        case opc_pop2:
+        case opc_dup:
+        case opc_dup_x1:
+        case opc_dup_x2:
+        case opc_dup2:
+        case opc_dup2_x1:
+        case opc_dup2_x2:
+        case opc_swap:
+        case opc_iadd:
+        case opc_ladd:
+        case opc_fadd:
+        case opc_dadd:
+        case opc_isub:
+        case opc_lsub:
+        case opc_fsub:
+        case opc_dsub:
+        case opc_imul:
+        case opc_lmul:
+        case opc_fmul:
+        case opc_dmul:
+        case opc_idiv:
+        case opc_ldiv:
+        case opc_fdiv:
+        case opc_ddiv:
+        case opc_irem:
+        case opc_lrem:
+        case opc_frem:
+        case opc_drem:
+        case opc_ineg:
+        case opc_lneg:
+        case opc_fneg:
+        case opc_dneg:
+        case opc_ishl:
+        case opc_lshl:
+        case opc_ishr:
+        case opc_lshr:
+        case opc_iushr:
+        case opc_lushr:
+        case opc_iand:
+        case opc_land:
+        case opc_ior:
+        case opc_lor:
+        case opc_ixor:
+        case opc_lxor:
+        case opc_i2l:
+        case opc_i2f:
+        case opc_i2d:
+        case opc_l2i:
+        case opc_l2f:
+        case opc_l2d:
+        case opc_f2i:
+        case opc_f2l:
+        case opc_f2d:
+        case opc_d2i:
+        case opc_d2l:
+        case opc_d2f:
+        case opc_i2b:
+        case opc_i2c:
+        case opc_i2s:
+        case opc_lcmp:
+        case opc_fcmpl:
+        case opc_fcmpg:
+        case opc_dcmpl:
+        case opc_dcmpg:
+        case opc_ireturn:
+        case opc_lreturn:
+        case opc_freturn:
+        case opc_dreturn:
+        case opc_areturn:
+        case opc_return:
+        case opc_xxxunusedxxx:
+        case opc_arraylength:
+        case opc_athrow:
+        case opc_monitorenter:
+        case opc_monitorexit:
+            return new InsnSingle(op, pc);
+      
+        case opc_ldc:
+            return new InsnConstOp(op, 
insnEnv.pool().constantAt(insnEnv.getUByte()),
+                                   pc);
+      
+        case opc_ldc_w:
+        case opc_ldc2_w:
+        case opc_getstatic:
+        case opc_putstatic:
+        case opc_getfield:
+        case opc_putfield:
+        case opc_invokevirtual:
+        case opc_invokespecial:
+        case opc_invokestatic:
+        case opc_new:
+        case opc_anewarray:
+        case opc_checkcast:
+        case opc_instanceof:
+            return new InsnConstOp(op,
+                                   
insnEnv.pool().constantAt(insnEnv.getUShort()),
+                                   pc);
+      
+        case opc_iload:
+        case opc_lload:
+        case opc_fload:
+        case opc_dload:
+        case opc_aload:
+        case opc_istore:
+        case opc_lstore:
+        case opc_fstore:
+        case opc_dstore:
+        case opc_astore:
+        case opc_ret:
+            if (widen)
+                return new InsnIntOp(op, insnEnv.getShort(), pc);
+            else
+                return new InsnIntOp(op, insnEnv.getByte(), pc);
+
+        case opc_bipush: /* a byte constant */
+        case opc_newarray:
+            return new InsnIntOp(op, insnEnv.getByte(), pc);
+
+        case opc_sipush: /* a short constant */
+            return new InsnIntOp(op, insnEnv.getShort(), pc);
+
+        case opc_iinc:
+            if (widen)
+                return new InsnIInc(insnEnv.getUShort(), insnEnv.getShort(), 
pc);
+            else
+                return new InsnIInc(insnEnv.getUByte(), insnEnv.getByte(), pc);
+
+        case opc_ifeq:
+        case opc_ifne:
+        case opc_iflt:
+        case opc_ifge:
+        case opc_ifgt:
+        case opc_ifle:
+        case opc_if_icmpeq:
+        case opc_if_icmpne:
+        case opc_if_icmplt:
+        case opc_if_icmpge:
+        case opc_if_icmpgt:
+        case opc_if_icmple:
+        case opc_if_acmpeq:
+        case opc_if_acmpne:
+        case opc_goto:
+        case opc_jsr:
+        case opc_ifnull:
+        case opc_ifnonnull:
+            return new InsnTargetOp(op, 
insnEnv.getTarget(insnEnv.getShort()+pc), pc);
+
+        case opc_goto_w:
+        case opc_jsr_w:
+            return new InsnTargetOp(op, 
insnEnv.getTarget(insnEnv.getInt()+pc), pc);
+
+        case opc_tableswitch:
+            return InsnTableSwitch.read(insnEnv, pc);
+
+        case opc_lookupswitch:
+            return InsnLookupSwitch.read(insnEnv, pc);
+
+        case opc_invokeinterface:
+            return InsnInterfaceInvoke.read(insnEnv, pc);
+
+        case opc_multianewarray:
+            return InsnMultiDimArrayNew.read(insnEnv, pc);
+        }
+        throw new InsnError("Invalid byte code (" + op + ")");
+    }
+
+    /**
+     * Return the type of value manipulated by the load/store instruction
+     */
+    public static final int loadStoreDataType(int opcode) {
+        switch(opcode) {
+        case opc_iload:
+        case opc_iload_0:
+        case opc_iload_1:
+        case opc_iload_2:
+        case opc_iload_3:
+        case opc_istore:
+        case opc_istore_0:
+        case opc_istore_1:
+        case opc_istore_2:
+        case opc_istore_3:
+        case opc_iaload:
+        case opc_baload:
+        case opc_caload:
+        case opc_saload:
+        case opc_iastore:
+        case opc_bastore:
+        case opc_castore:
+        case opc_sastore:
+            return T_INT;
+
+        case opc_lload:
+        case opc_lload_0:
+        case opc_lload_1:
+        case opc_lload_2:
+        case opc_lload_3:
+        case opc_lstore:
+        case opc_lstore_0:
+        case opc_lstore_1:
+        case opc_lstore_2:
+        case opc_lstore_3:
+        case opc_laload:
+        case opc_lastore:
+            return T_LONG;
+
+        case opc_fload:
+        case opc_fload_0:
+        case opc_fload_1:
+        case opc_fload_2:
+        case opc_fload_3:
+        case opc_fstore:
+        case opc_fstore_0:
+        case opc_fstore_1:
+        case opc_fstore_2:
+        case opc_fstore_3:
+        case opc_faload:
+        case opc_fastore:
+            return T_FLOAT;
+
+        case opc_dload:
+        case opc_dload_0:
+        case opc_dload_1:
+        case opc_dload_2:
+        case opc_dload_3:
+        case opc_dstore:
+        case opc_dstore_0:
+        case opc_dstore_1:
+        case opc_dstore_2:
+        case opc_dstore_3:
+        case opc_daload:
+        case opc_dastore:
+            return T_DOUBLE;
+
+        case opc_aload:
+        case opc_aload_0:
+        case opc_aload_1:
+        case opc_aload_2:
+        case opc_aload_3:
+        case opc_astore:
+        case opc_astore_0:
+        case opc_astore_1:
+        case opc_astore_2:
+        case opc_astore_3:
+        case opc_aaload:
+        case opc_aastore:
+            return TC_OBJECT;
+
+        default:
+            throw new InsnError("not a load/store");
+        }
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnConstOp.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnConstOp.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnConstOp.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnConstOp.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+
+import java.io.PrintStream;
+import java.util.Stack;
+
+/**
+ * An instruction which requires a single constant from the constant
+ * pool as an immediate operand 
+ */
+public class InsnConstOp extends Insn {
+    /* The constant from the constant pool */
+    private ConstBasic constValue;
+
+    /* public accessors */
+
+    public int nStackArgs() {
+        int n = VMOp.ops[opcode()].nStackArgs();
+        if (n >= 0) 
+            return n;
+        switch (opcode()) {
+        case opc_putstatic:
+        case opc_putfield:
+        {
+            ConstFieldRef fld = (ConstFieldRef) constValue;
+            String sig = fld.nameAndType().signature().asString();
+            if (sig.equals("J") || sig.equals("D"))
+                return (opcode() == opc_putfield) ? 3 : 2;
+            return (opcode() == opc_putfield) ? 2 : 1;
+        }
+        case opc_invokevirtual:
+        case opc_invokespecial:
+        case opc_invokestatic:
+            /* handle interface invoke too */
+        case opc_invokeinterface:
+        {
+            ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
+            String sig = meth.nameAndType().signature().asString();
+            int nMethodArgWords = Descriptor.countMethodArgWords(sig);
+            return nMethodArgWords +
+                ((opcode() == opc_invokestatic) ? 0 : 1);
+        }
+        default:
+            throw new InsnError("unexpected variable opcode");
+        }
+    }
+
+    public int nStackResults() {
+        int n = VMOp.ops[opcode()].nStackResults();
+        if (n >= 0) 
+            return n;
+        switch (opcode()) {
+        case opc_getstatic:
+        case opc_getfield:
+        {
+            ConstFieldRef fld = (ConstFieldRef) constValue;
+            String sig = fld.nameAndType().signature().asString();
+            if (sig.equals("J") || sig.equals("D"))
+                return 2;
+            return 1;
+        }
+        case opc_invokevirtual:
+        case opc_invokespecial:
+        case opc_invokestatic:
+            /* handle interface invoke too */
+        case opc_invokeinterface:
+        {
+            ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
+            return Descriptor.countMethodReturnWords(
+                meth.nameAndType().signature().asString());
+        }
+        default:
+            throw new InsnError("unexpected variable opcode");
+        }
+    }
+
+    public String argTypes() {
+        switch (opcode()) {
+        case opc_putstatic:
+        case opc_putfield:
+        {
+            ConstFieldRef fld = (ConstFieldRef) constValue;
+            String sig = fld.nameAndType().signature().asString();
+            if (opcode() == opc_putstatic)
+                return sig;
+            else
+                return descriptorTypeOfObject(fld) + sig;
+        }
+        case opc_invokevirtual:
+        case opc_invokespecial:
+        case opc_invokestatic:
+            /* handle interface invoke too */
+        case opc_invokeinterface:
+        {
+            ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
+            String argSig =
+                
Descriptor.extractArgSig(meth.nameAndType().signature().asString());
+            if (opcode() == opc_invokestatic)
+                return argSig;
+            else
+                return descriptorTypeOfObject(meth) + argSig;
+        }
+        default:
+            return VMOp.ops[opcode()].argTypes();
+        }
+    }
+
+    public String resultTypes() {
+        switch (opcode()) {
+        case opc_invokevirtual:
+        case opc_invokespecial:
+        case opc_invokestatic:
+            /* handle interface invoke too */
+        case opc_invokeinterface:
+        {
+            ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
+            String resultSig = Descriptor.extractResultSig(
+                meth.nameAndType().signature().asString());
+            if (resultSig.equals("V"))
+                return "";
+            return resultSig;
+        }
+        case opc_getstatic:
+        case opc_getfield:
+        {
+            ConstFieldRef fld = (ConstFieldRef) constValue;
+            return fld.nameAndType().signature().asString();
+        }
+        case opc_ldc:
+        case opc_ldc_w:
+        case opc_ldc2_w:
+        {
+            ConstValue constVal = (ConstValue) constValue;
+            return constVal.descriptor();
+        }
+        default:
+            return VMOp.ops[opcode()].resultTypes();
+        }
+    }
+
+    public boolean branches() {
+        /* invokes don't count as a branch */
+        return false;
+    }
+
+    /**
+     * Return the constant pool entry which is the immediate operand
+     */
+    public ConstBasic value() {
+        return constValue;
+    }
+    
+    /**
+     * Modify the referenced constant
+     */
+    public void setValue(ConstBasic newValue) {
+        checkConstant(newValue);
+        constValue = newValue;
+    }
+    
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnConstOp)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnConstOp other = (InsnConstOp)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+        
+        if (!this.constValue.isEqual(msg, other.constValue)) {
+            msg.push(String.valueOf("constValue = "
+                                    + other.constValue));
+            msg.push(String.valueOf("constValue = "
+                                    + this.constValue));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  " + opName(opcode()) + "  pool(" + 
+                    constValue.getIndex() + ")");
+    }
+
+    int store(byte[] buf, int index) {
+        if (opcode() == opc_ldc && !isNarrowldc())
+            buf[index++] = (byte) opc_ldc_w;
+        else
+            buf[index++] = (byte) opcode();
+        int constIndex = constValue.getIndex();
+        if (size() == 3)
+            buf[index++] = (byte) (constIndex >> 8);
+        buf[index++] = (byte)(constIndex & 0xff);
+        return index;
+    }
+
+    int size() {
+        return isNarrowldc() ? 2 : 3;
+    }
+
+    private boolean isNarrowldc() {
+        return (opcode() == opc_ldc && constValue.getIndex() < 256);
+    }
+    
+
+    InsnConstOp(int theOpcode, ConstBasic theOperand) {
+        this(theOpcode, theOperand, NO_OFFSET);
+    }
+
+    InsnConstOp(int theOpcode, ConstBasic theOperand, int pc) {
+        super(theOpcode, pc);
+        constValue = theOperand;
+        checkConstant(theOperand);
+        if (theOpcode == opc_invokeinterface) 
+            throw new InsnError("attempt to create an " + opName(theOpcode) +
+                                " as an InsnConstOp instead of 
InsnInterfaceInvoke");
+    }
+
+    /* used only by InsnInterfaceInvoke, to make sure that opc_invokeinterface 
cannot
+     * come through the wrong path and miss its extra nArgsOp */
+    InsnConstOp(int theOpcode, ConstInterfaceMethodRef theOperand, int pc) {
+        super(theOpcode, pc);
+        constValue = theOperand;
+        checkConstant(theOperand);
+    }
+
+    private void checkConstant(ConstBasic operand) {
+        switch(opcode()) {
+        case opc_ldc:
+        case opc_ldc_w:
+        case opc_ldc2_w:
+            /* ConstValue */
+            if (operand == null ||
+                (! (operand instanceof ConstValue)))
+                throw new InsnError ("attempt to create an " + 
opName(opcode()) +
+                                     " without a ConstValue operand");
+            break;
+
+        case opc_getstatic:
+        case opc_putstatic:
+        case opc_getfield:
+        case opc_putfield:
+            /* ConstFieldRef */
+            if (operand == null ||
+                (! (operand instanceof ConstFieldRef)))
+                throw new InsnError ("attempt to create an " + 
opName(opcode()) +
+                                     " without a ConstFieldRef operand");
+            break;
+
+        case opc_invokevirtual:
+        case opc_invokespecial:
+        case opc_invokestatic:
+            /* ConstMethodRef */
+            if (operand == null ||
+                (! (operand instanceof ConstMethodRef)))
+                throw new InsnError ("attempt to create an " + 
opName(opcode()) +
+                                     " without a ConstMethodRef operand");
+            break;
+      
+        case opc_invokeinterface:
+            /* ConstInterfaceMethodRef */
+            if (operand == null ||
+                (! (operand instanceof ConstInterfaceMethodRef)))
+                throw new InsnError("Attempt to create an " + opName(opcode()) 
+
+                                    " without a ConstInterfaceMethodRef 
operand");
+            break;
+
+        case opc_new:
+        case opc_anewarray:
+        case opc_checkcast:
+        case opc_instanceof:
+            /* ConstClass */
+            if (operand == null ||
+                (! (operand instanceof ConstClass)))
+                throw new InsnError ("attempt to create an " + 
opName(opcode()) +
+                                     " without a ConstClass operand");
+            break;
+
+        default:
+            throw new InsnError ("attempt to create an " + opName(opcode()) +
+                                 " with a constant operand");
+        }
+    }
+
+    private final String descriptorTypeOfObject(ConstBasicMemberRef memRef) {
+        String cname = memRef.className().className().asString();
+        return "L" + cname + ";";
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnError.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnError.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnError.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnError.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+/**
+ * An exception thrown when an error occurs in encoding or decoding
+ * instruction sequences
+ */
+public class InsnError extends RuntimeException {
+    public InsnError(String s) {
+        super(s);
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+
+import java.io.PrintStream;
+import java.util.Stack;
+
+/**
+ * Special instruction form for the opc_iinc instruction
+ */
+public class InsnIInc extends Insn {
+
+    /* The local variable slot to be incremented */
+    private int localVarIndex;
+
+    /* The amount by which the slot is to be incremented */
+    private int value;
+
+    /* public accessors */
+
+    public int nStackArgs() {
+        return 0;
+    }
+
+    public int nStackResults() {
+        return 0;
+    }
+
+    /**
+     * What are the types of the stack operands ?
+     */
+    public String argTypes() {
+        return "";
+    }
+
+    /**
+     * What are the types of the stack results?
+     */
+    public String resultTypes() {
+        return "";
+    }
+
+    public boolean branches() {
+        return false;
+    }
+
+    /**
+     * The local variable slot to be incremented
+     */
+    public int varIndex() {
+        return localVarIndex;
+    }
+
+    /**
+     * The amount by which the slot is to be incremented 
+     */
+    public int incrValue() {
+        return value;
+    }
+  
+    /**
+     * Constructor for opc_iinc instruction
+     */
+    public InsnIInc (int localVarIndex, int value) {
+        this(localVarIndex, value, NO_OFFSET);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnIInc)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnIInc other = (InsnIInc)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.localVarIndex != other.localVarIndex) {
+            msg.push(String.valueOf("localVarIndex = "
+                                    + other.localVarIndex));
+            msg.push(String.valueOf("localVarIndex = "
+                                    + this.localVarIndex));
+            return false;
+        }
+        if (this.value != other.value) {
+            msg.push(String.valueOf("value = "
+                                    + other.value));
+            msg.push(String.valueOf("value = "
+                                    + this.value));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    InsnIInc (int localVarIndex, int value, int pc) {
+        super(opc_iinc, pc);
+
+        this.localVarIndex = localVarIndex;
+        this.value =value;
+    }
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  opc_iinc  " + 
+                    localVarIndex + "," + value);
+    }
+
+    int store(byte[] buf, int index) {
+        if (isWide())
+            buf[index++] = (byte) opc_wide;
+        buf[index++] = (byte) opcode();
+        if (isWide()) {
+            index = storeShort(buf, index, (short) localVarIndex);
+            index = storeShort(buf, index, (short) value);
+        } else {
+            buf[index++] = (byte)localVarIndex;
+            buf[index++] = (byte)value;
+        }
+        return index;
+    }
+
+    int size() {
+        return isWide() ? 6 : 3;
+    }
+
+    private boolean isWide() {
+        return (value > 127 || value < -128 || localVarIndex > 255);
+    }
+
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.PrintStream;
+import java.util.Stack;
+
+/**
+ * An instruction which requires a integral constant as an immediate operand 
+ */
+
+public class InsnIntOp extends Insn {
+    /* The operand */
+    private int operandValue;
+
+    /* public accessors */
+
+    public int nStackArgs() {
+        return VMOp.ops[opcode()].nStackArgs();
+    }
+
+    public int nStackResults() {
+        return VMOp.ops[opcode()].nStackResults();
+    }
+
+    public String argTypes() {
+        return VMOp.ops[opcode()].argTypes();
+    }
+
+    public String resultTypes() {
+        return VMOp.ops[opcode()].resultTypes();
+    }
+
+    public boolean branches() {
+        return opcode() == opc_ret;
+    }
+
+    public int value() {
+        return operandValue;
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnIntOp)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnIntOp other = (InsnIntOp)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.operandValue != other.operandValue) {
+            msg.push(String.valueOf("operandValue = "
+                                    + other.operandValue));
+            msg.push(String.valueOf("operandValue = "
+                                    + this.operandValue));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    static String primType(int primIndex) {
+        switch (primIndex) {
+        case T_BOOLEAN:
+            return "boolean";
+        case T_CHAR:
+            return "char";
+        case T_FLOAT:
+            return "float";
+        case T_DOUBLE:
+            return "double";
+        case T_BYTE:
+            return "byte";
+        case T_SHORT:
+            return "short";
+        case T_INT:
+            return "int";
+        case T_LONG:
+            return "long";
+        default:
+            throw new InsnError ("Invalid primitive type(" + primIndex + ")");
+        }
+    }
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        if (opcode() == opc_newarray) 
+            out.println(offset() + "  opc_newarray  " + 
primType(operandValue));
+        else
+            out.println(offset() + "  " + opName(opcode()) + "  " + 
operandValue);
+    }
+
+    int store(byte[] buf, int index) {
+        if (size() == 4) {
+            /* prefix with an opc_wide */
+            buf[index++] = (byte) opc_wide;
+        }
+
+        buf[index++] = (byte) opcode();
+        if (size() > 2)
+            buf[index++] = (byte)(operandValue >> 8);
+        buf[index++] = (byte)(operandValue & 0xff);
+        return index;
+    }
+
+
+    /* return the size of the instruction in bytes */
+
+    int size() {
+        switch(opcode()) {
+        case opc_bipush:
+        case opc_newarray:
+            /* These are always 1 byte constants */
+            return 2;
+
+        case opc_sipush: /* a short constant */
+            /* This is always a 2 byte constant */
+            return 3;
+
+        case opc_iload:
+        case opc_lload:
+        case opc_fload:
+        case opc_dload:
+        case opc_aload:
+        case opc_istore:
+        case opc_lstore:
+        case opc_fstore:
+        case opc_dstore:
+        case opc_astore:
+        case opc_ret:
+            /* These can be one or two byte constants specifying a local var.
+             * If a two byte constant, the constant is prefixed by a wide
+             * instruction */
+            if (operandValue < 256)
+                return 2;
+            else
+                return 4;
+
+        default:
+            throw new InsnError ("invalid instruction " + opName(opcode()) +
+                                 " with an integer operand");
+        }
+    }
+
+
+    InsnIntOp (int theOpcode, int theOperand, int pc) {
+        super(theOpcode, pc);
+
+        operandValue = theOperand;
+    }
+
+
+    InsnIntOp (int theOpcode, int theOperand) {
+        super(theOpcode, NO_OFFSET);
+
+        operandValue = theOperand;
+        switch(theOpcode) {
+        case opc_bipush:
+        case opc_newarray:
+            /* These are always 1 byte constants */
+
+        case opc_sipush: /* a short constant */
+            /* This is always a 2 byte constant */
+
+        case opc_dload:
+        case opc_lload:
+        case opc_iload:
+        case opc_fload:
+        case opc_aload:
+        case opc_istore:
+        case opc_lstore:
+        case opc_fstore:
+        case opc_dstore:
+        case opc_astore:
+        case opc_ret:
+            /* These can be one or two byte constants specifying a local var */
+            break;
+
+        default:
+            throw new InsnError ("attempt to create an " + opName(theOpcode) +
+                                 " with an integer operand");
+        }
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2005 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.PrintStream;
+import java.util.Stack;
+
+/**
+ * Special instruction form for the opc_invokeinterface instruction
+ */
+public class InsnInterfaceInvoke extends InsnConstOp {
+    /* The number of arguments to the interface method */
+    private int nArgsOp;
+
+    /* public accessors */
+
+    public int nStackArgs() {
+        return super.nStackArgs();
+    }
+
+    public int nStackResults() {
+        return super.nStackResults();
+    }
+
+    /**
+     * What are the types of the stack operands ?
+     */
+    public String argTypes() {
+        return super.argTypes();
+    }
+
+    /**
+     * What are the types of the stack results?
+     */
+    public String resultTypes() {
+        return super.resultTypes();
+    }
+
+    public boolean branches() {
+        return false;
+    }
+
+    /**
+     * Return the interface to be invoked
+     */
+    public ConstInterfaceMethodRef method() {
+        return (ConstInterfaceMethodRef) value();
+    }
+
+    /**
+     * Return the number of arguments to the interface
+     */
+    public int nArgs() {
+        return nArgsOp;
+    }
+
+    /**
+     * constructor for opc_invokeinterface
+     */
+    public InsnInterfaceInvoke (ConstInterfaceMethodRef methodRefOp, 
+                                int nArgsOp) {
+        this(methodRefOp, nArgsOp, NO_OFFSET);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnInterfaceInvoke)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnInterfaceInvoke other = (InsnInterfaceInvoke)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.nArgsOp != other.nArgsOp) {
+            msg.push(String.valueOf("nArgsOp = "
+                                    + other.nArgsOp));
+            msg.push(String.valueOf("nArgsOp = "
+                                    + this.nArgsOp));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    InsnInterfaceInvoke (ConstInterfaceMethodRef methodRefOp, int nArgsOp,
+                         int offset) {
+        super(opc_invokeinterface, methodRefOp, offset);
+
+        this.nArgsOp = nArgsOp; 
+
+        if (methodRefOp == null || nArgsOp < 0)
+            throw new InsnError ("attempt to create an opc_invokeinterface" +
+                                 " with invalid operands");
+    }
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  opc_invokeinterface  " + 
+                    "pool(" + method().getIndex() + ")," + nArgsOp);
+    }
+
+    int store(byte[] buf, int index) {
+        buf[index++] = (byte) opcode();
+        index = storeShort(buf, index, (short)method().getIndex());
+        buf[index++] = (byte) nArgsOp;
+        buf[index++] = (byte) 0;
+        return index;
+    }
+
+    int size() {
+        return 5;
+    }
+
+    static InsnInterfaceInvoke read(InsnReadEnv insnEnv, int myPC) {
+        ConstInterfaceMethodRef iface = (ConstInterfaceMethodRef)
+            insnEnv.pool().constantAt(insnEnv.getUShort());
+        int nArgs = insnEnv.getUByte();
+        insnEnv.getByte(); // eat reserved arg
+        return new InsnInterfaceInvoke(iface, nArgs, myPC);
+    }
+}


Reply via email to