You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by mb...@apache.org on 2005/05/22 19:55:54 UTC

svn commit: r171351 [6/16] - in /incubator/jdo/trunk/enhancer20: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ 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/ test/ test/sempdept/ test/sempdept/src/ test/sempdept/src/empdept/

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIInc.java Sun May 22 10:55:51 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/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnIntOp.java Sun May 22 10:55:51 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/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnInterfaceInvoke.java Sun May 22 10:55:51 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);
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java Sun May 22 10:55:51 2005
@@ -0,0 +1,227 @@
+/*
+ * 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_lookupswitch instruction
+ */
+public class InsnLookupSwitch extends Insn {
+    /* The target for the default case */
+    private InsnTarget defaultOp;
+
+    /* The int constants against which to perform the lookup */
+    private int[] matchesOp;
+
+    /* The branch targets for the cases corresponding to the entries in
+     * the matchesOp array */
+    private InsnTarget[] targetsOp;
+
+    /* public accessors */
+
+    public int nStackArgs() {
+        return 1;
+    }
+
+    public int nStackResults() {
+        return 0;
+    }
+
+    /**
+     * What are the types of the stack operands ?
+     */
+    public String argTypes() {
+        return "I";
+    }
+
+    /**
+     * What are the types of the stack results?
+     */
+    public String resultTypes() {
+        return "";
+    }
+
+    public boolean branches() {
+        return true;
+    }
+
+    /**
+     * Mark possible branch targets
+     */
+    public void markTargets() {
+        defaultOp.setBranchTarget();
+        for (int i=0; i<targetsOp.length; i++)
+            targetsOp[i].setBranchTarget();
+    }
+
+
+    /**
+     * Return the defaultTarget for the switch
+     */
+    public InsnTarget defaultTarget() {
+        return defaultOp;
+    }
+
+    /**
+     * Return the case values of the switch.
+     */
+    public int[] switchCases() {
+        return matchesOp;
+    }
+
+    /**
+     * Return the targets for the cases of the switch.
+     */
+    public InsnTarget[] switchTargets() {
+        return targetsOp;
+    }
+
+    /**
+     * Constructor for opc_lookupswitch
+     */
+    public InsnLookupSwitch(InsnTarget defaultOp, int[] matchesOp,
+                            InsnTarget[] targetsOp) {
+        this(defaultOp, matchesOp, targetsOp, NO_OFFSET);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnLookupSwitch)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnLookupSwitch other = (InsnLookupSwitch)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (!this.defaultOp.isEqual(msg, other.defaultOp)) {
+            msg.push(String.valueOf("defaultOp = "
+                                    + other.defaultOp));
+            msg.push(String.valueOf("defaultOp = "
+                                    + this.defaultOp));
+            return false;
+        }
+
+        if (this.matchesOp.length != other.matchesOp.length) {
+            msg.push("matchesOp.length "
+                     + String.valueOf(other.matchesOp.length));
+            msg.push("matchesOp.length "
+                     + String.valueOf(this.matchesOp.length));
+            return false;
+        }
+        for (int i = 0; i < matchesOp.length; i++) {
+            int m1 = this.matchesOp[i];
+            int m2 = other.matchesOp[i];
+            if (m1 != m2) {
+                msg.push("matchesOp[" + i + "] = " + String.valueOf(m2));
+                msg.push("matchesOp[" + i + "] = " + String.valueOf(m1));
+                return false;
+            }
+        }
+
+        if (this.targetsOp.length != other.targetsOp.length) {
+            msg.push("targetsOp.length "
+                     + String.valueOf(other.targetsOp.length));
+            msg.push("targetsOp.length "
+                     + String.valueOf(this.targetsOp.length));
+            return false;
+        }
+        for (int i = 0; i < targetsOp.length; i++) {
+            InsnTarget t1 = this.targetsOp[i];
+            InsnTarget t2 = other.targetsOp[i];
+            if (!t1.isEqual(msg, t2)) {
+                msg.push("targetsOp[" + i + "] = " + String.valueOf(t2));
+                msg.push("targetsOp[" + i + "] = " + String.valueOf(t1));
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    InsnLookupSwitch(InsnTarget defaultOp, int[] matchesOp,
+                     InsnTarget[] targetsOp, int offset) {
+        super(opc_lookupswitch, offset);
+
+        this.defaultOp = defaultOp; 
+        this.matchesOp = matchesOp;
+        this.targetsOp = targetsOp;
+
+        if (defaultOp == null || targetsOp == null || matchesOp == null ||
+            targetsOp.length != matchesOp.length)
+            throw new InsnError ("attempt to create an opc_lookupswitch" +
+                                 " with invalid operands");
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  opc_lookupswitch  ");
+        for (int i=0; i<matchesOp.length; i++) {
+            ClassPrint.spaces(out, indent+2);
+            out.println(matchesOp[i] + " -> " + targetsOp[i].offset());
+        }
+        ClassPrint.spaces(out, indent+2);
+        out.println("default -> " + defaultOp.offset());
+    }
+
+    int store(byte[] buf, int index) {
+        buf[index++] = (byte) opcode();
+        index = (index + 3) & ~3;
+        index = storeInt(buf, index, defaultOp.offset() - offset());
+        index = storeInt(buf, index, targetsOp.length);
+        for (int i=0; i<targetsOp.length; i++) {
+            index = storeInt(buf, index, matchesOp[i]);
+            index = storeInt(buf, index, targetsOp[i].offset() - offset());
+        }
+        return index;
+    }
+
+    int size() {
+        /* account for the instruction, 0-3 bytes of pad, 2 ints */
+        int basic = ((offset() + 4) & ~3) - offset() + 8;
+        /* Add 8*number of offsets */
+        return basic + targetsOp.length*8;
+    }
+
+    static InsnLookupSwitch read (InsnReadEnv insnEnv, int myPC) {
+        /* eat up any padding */
+        int thisPC = myPC +1;
+        for (int pads = ((thisPC + 3) & ~3) - thisPC; pads > 0; pads--)
+            insnEnv.getByte();
+        InsnTarget defaultTarget = insnEnv.getTarget(insnEnv.getInt() + myPC);
+        int npairs = insnEnv.getInt();
+        int matches[] = new int[npairs];
+        InsnTarget[] offsets = new InsnTarget[npairs];
+        for (int i=0; i<npairs; i++) {
+            matches[i] = insnEnv.getInt();
+            offsets[i] = insnEnv.getTarget(insnEnv.getInt() + myPC);
+        }
+        return new InsnLookupSwitch(defaultTarget, matches, offsets, myPC);
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java Sun May 22 10:55:51 2005
@@ -0,0 +1,170 @@
+/*
+ * 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_multianewarray instruction
+ */
+public class InsnMultiDimArrayNew extends Insn {
+    /* The array class for creation */
+    private ConstClass classOp;
+
+    /* The number of dimensions present on the stack */
+    private int nDimsOp;
+
+    /* public accessors */
+
+    public boolean isSimpleLoad() {
+        return false;
+    }
+
+    public int nStackArgs() {
+        return nDimsOp;
+    }
+
+    public int nStackResults() {
+        return 1;
+    }
+
+    /**
+     * What are the types of the stack operands ?
+     */
+    public String argTypes() {
+        StringBuffer buf = new StringBuffer();
+        for (int i=0; i<nDimsOp; i++) {
+            buf.append("I");
+        }
+        return buf.toString();
+    }
+
+    /**
+     * What are the types of the stack results?
+     */
+    public String resultTypes() {
+        return "A";
+    }
+
+    public boolean branches() {
+        return false;
+    }
+
+    /**
+     * Return the array class being created
+     */
+    public ConstClass arrayClass() {
+        return classOp;
+    }
+
+    /**
+     * Sets the array class being created
+     */
+    public void setArrayClass(ConstClass classOp) {
+        this.classOp = classOp;
+    }
+
+    /**
+     * Return the number of dimensions of the array class being created
+     */
+    public int nDims() {
+        return nDimsOp;
+    }
+
+    /**
+     * Constructor for opc_multianewarray.
+     * classOp must be an array class
+     * nDimsOp must be > 0 and <= number of array dimensions for classOp
+     */
+    public InsnMultiDimArrayNew (ConstClass classOp, int nDimsOp) {
+        this(classOp, nDimsOp, NO_OFFSET);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnMultiDimArrayNew)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnMultiDimArrayNew other = (InsnMultiDimArrayNew)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (!this.classOp.isEqual(msg, other.classOp)) {
+            msg.push(String.valueOf("classOp = "
+                                    + other.classOp));
+            msg.push(String.valueOf("classOp = "
+                                    + this.classOp));
+            return false;
+        }
+        if (this.nDimsOp != other.nDimsOp) {
+            msg.push(String.valueOf("nDimsOp = "
+                                    + other.nDimsOp));
+            msg.push(String.valueOf("nDimsOp = "
+                                    + this.nDimsOp));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    InsnMultiDimArrayNew (ConstClass classOp, int nDimsOp, int offset) {
+        super(opc_multianewarray, offset);
+
+        this.classOp = classOp;
+        this.nDimsOp = nDimsOp; 
+
+        if (classOp == null || nDimsOp < 1)
+            throw new InsnError ("attempt to create an opc_multianewarray" +
+                                 " with invalid operands");
+    }  
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  opc_multianewarray  pool(" +
+                    classOp.getIndex() + ")," + nDimsOp);
+    }
+
+    int store(byte[] buf, int index) {
+        buf[index++] = (byte) opcode();
+        index = storeShort(buf, index, (short) classOp.getIndex());
+        buf[index++] = (byte) nDimsOp;
+        return index;
+    }
+
+    int size() {
+        return 4;
+    }
+
+    static InsnMultiDimArrayNew read (InsnReadEnv insnEnv, int myPC) {
+        ConstClass classOp = (ConstClass)
+            insnEnv.pool().constantAt(insnEnv.getUShort());
+        int nDims = insnEnv.getUByte();
+        return new InsnMultiDimArrayNew(classOp, nDims, myPC);
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java Sun May 22 10:55:51 2005
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+/**
+ * Environment for decoding byte codes into instructions
+ */
+class InsnReadEnv {
+
+    /* The parent method environment */
+    private CodeEnv codeEnv;
+
+    /* The byte codes to be decoded */
+    private byte[] byteCodes;
+
+    /* The index into byteCodes for the next instruction to be decoded */
+    private int currPc;
+
+    /**
+     * Constructor
+     */
+    InsnReadEnv(byte[] bytes, CodeEnv codeEnv) {
+        this.byteCodes = bytes;
+        this.currPc = 0;
+        this.codeEnv = codeEnv;
+    }
+
+    /**
+     * Return the index of the next instruction to decode
+     */
+    int currentPC() {
+        return currPc;
+    }
+
+    /**
+     * Are there more byte codes to decode?
+     */
+    boolean more() {
+        return currPc < byteCodes.length;
+    }
+
+    /**
+     * Get a single byte from the byte code stream
+     */
+    byte getByte() {
+        if (!more())
+            throw new InsnError("out of byte codes");
+
+        return byteCodes[currPc++];
+    }
+
+    /**
+     * Get a single unsigned byte from the byte code stream
+     */
+    int getUByte() {
+        return getByte() & 0xff;
+    }
+
+    /**
+     * Get a short from the byte code stream
+     */
+    int getShort() {
+        byte byte1 = byteCodes[currPc++];
+        byte byte2 = byteCodes[currPc++];
+        return (byte1 << 8) | (byte2 & 0xff);
+    }
+
+    /**
+     * Get an unsigned short from the byte code stream
+     */
+    int getUShort() {
+        return getShort() & 0xffff;
+    }
+
+    /**
+     * Get an int from the byte code stream
+     */
+    int getInt() {
+        byte byte1 = byteCodes[currPc++];
+        byte byte2 = byteCodes[currPc++];
+        byte byte3 = byteCodes[currPc++];
+        byte byte4 = byteCodes[currPc++];
+        return (byte1 << 24) | ((byte2 & 0xff) << 16) |
+	    ((byte3  & 0xff) << 8) | (byte4 & 0xff);
+    }
+
+    /**
+     * Get the constant pool which applies to the method being decoded
+     */
+    ConstantPool pool() {
+        return codeEnv.pool();
+    }
+
+    /**
+     * Get the canonical InsnTarget instance for the specified
+     * pc within the method.
+     */
+    InsnTarget getTarget(int targ) {
+        return codeEnv.getTarget(targ);
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java Sun May 22 10:55:51 2005
@@ -0,0 +1,269 @@
+/*
+ * 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;
+
+/**
+ * A java VM instruction which takes no immediate operands.
+ */
+public class InsnSingle extends Insn {
+
+    public int nStackArgs() {
+        return VMOp.ops[opcode()].nStackArgs();
+    }
+
+    public int nStackResults() {
+        return VMOp.ops[opcode()].nStackResults();
+    }
+
+    /**
+     * What are the types of the stack operands ?
+     */
+    public String argTypes() {
+        return VMOp.ops[opcode()].argTypes();
+    }
+
+    /**
+     * What are the types of the stack results?
+     */
+    public String resultTypes() {
+        return VMOp.ops[opcode()].resultTypes();
+    }
+
+    public boolean branches() {
+        switch (opcode()) {
+        case opc_ireturn:
+        case opc_lreturn:
+        case opc_freturn:
+        case opc_dreturn:
+        case opc_areturn:
+        case opc_return:
+        case opc_athrow:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnSingle)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnSingle other = (InsnSingle)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  " + opName(opcode()));
+    }
+
+    int store(byte[] buf, int index) {
+        buf[index] = (byte) opcode();
+        return index+1;
+    }
+
+    int size() {
+        return 1;
+    }
+
+    /* Construct an instruction.  The opcode must be one which requires
+       no operands */
+
+    InsnSingle(int theOpcode) {
+        this(theOpcode, NO_OFFSET);
+    }
+
+    /* The no-check constructor */
+
+    InsnSingle(int theOpcode, int theOffset) {
+        super(theOpcode, theOffset);
+
+        switch (theOpcode) {
+        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:
+            break;
+
+        default:
+            throw new InsnError ("attempt to create an " + opName(opcode()) +
+                                 " without specifying the required operands");
+        }
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java Sun May 22 10:55:51 2005
@@ -0,0 +1,213 @@
+/*
+ * 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_tableswitch instruction
+ */
+public class InsnTableSwitch extends Insn {
+    /* The lowest value in the jump table */
+    private int lowOp;
+
+    /* The default target for the switch */
+    private InsnTarget defaultOp;
+
+    /* The targets for the switch - a switch value of lowOp dispatches
+     * to targetsOp[0], lowOp+1 dispatches to targetsOp[1], etc. */
+    private InsnTarget[] targetsOp;
+
+    /* public accessors */
+
+    public int nStackArgs() {
+        return 1;
+    }
+
+    public int nStackResults() {
+        return 0;
+    }
+
+    public String argTypes() {
+        return "I";
+    }
+
+    public String resultTypes() {
+        return "";
+    }
+
+    public boolean branches() {
+        return true;
+    }
+
+    /**
+     * Mark possible branch targets
+     */
+    public void markTargets() {
+        defaultOp.setBranchTarget();
+        for (int i=0; i<targetsOp.length; i++)
+            targetsOp[i].setBranchTarget();
+    }
+
+    /**
+     * Return the lowest case for the switch
+     */
+    public int lowCase() {
+        return lowOp;
+    }
+
+    /**
+     * Return the defaultTarget for the switch
+     */
+    public InsnTarget defaultTarget() {
+        return defaultOp;
+    }
+
+    /**
+     * Return the targets for the cases of the switch.
+     */
+    public InsnTarget[] switchTargets() {
+        return targetsOp;
+    }
+
+    /**
+     * Constructor for opc_tableswitch
+     */
+    //@olsen: made public
+    public InsnTableSwitch(int lowOp, InsnTarget defaultOp, 
+                           InsnTarget[] targetsOp) {
+        this(lowOp, defaultOp, targetsOp, NO_OFFSET);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnTableSwitch)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnTableSwitch other = (InsnTableSwitch)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.lowOp != other.lowOp) {
+            msg.push(String.valueOf("lowOp = "
+                                    + other.lowOp));
+            msg.push(String.valueOf("lowOp = "
+                                    + this.lowOp));
+            return false;
+        }
+
+        if (!this.defaultOp.isEqual(msg, other.defaultOp)) {
+            msg.push(String.valueOf("defaultOp = "
+                                    + other.defaultOp));
+            msg.push(String.valueOf("defaultOp = "
+                                    + this.defaultOp));
+            return false;
+        }
+
+        if (this.targetsOp.length != other.targetsOp.length) {
+            msg.push("targetsOp.length "
+                     + String.valueOf(other.targetsOp.length));
+            msg.push("targetsOp.length "
+                     + String.valueOf(this.targetsOp.length));
+            return false;
+        }
+        for (int i = 0; i < targetsOp.length; i++) {
+            InsnTarget t1 = this.targetsOp[i];
+            InsnTarget t2 = other.targetsOp[i];
+            if (!t1.isEqual(msg, t2)) {
+                msg.push("targetsOp[" + i + "] = " + String.valueOf(t2));
+                msg.push("targetsOp[" + i + "] = " + String.valueOf(t1));
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + "  opc_tableswitch  ");
+        for (int i=0; i<targetsOp.length; i++) {
+            int index = i + lowOp;
+            if (targetsOp[i].offset() != defaultOp.offset()) {
+                ClassPrint.spaces(out, indent+2);
+                out.println(index + " -> " + targetsOp[i].offset());
+            }
+        }
+        ClassPrint.spaces(out, indent+2);
+        out.println("default -> " + defaultOp.offset());
+    }
+
+    int store(byte[] buf, int index) {
+        buf[index++] = (byte) opcode();
+        index = (index + 3) & ~3;
+        index = storeInt(buf, index, defaultOp.offset() - offset());
+        index = storeInt(buf, index, lowOp);
+        index = storeInt(buf, index, lowOp+targetsOp.length-1);
+        for (int i=0; i<targetsOp.length; i++)
+            index = storeInt(buf, index, targetsOp[i].offset() - offset());
+        return index;
+    }
+
+    int size() {
+        /* account for the instruction, 0-3 bytes of pad, 3 ints */
+        int basic = ((offset() + 4) & ~3) - offset() + 12;
+        /* Add 4*number of offsets */
+        return basic + targetsOp.length*4;
+    }
+
+
+    InsnTableSwitch(int lowOp, InsnTarget defaultOp, 
+                    InsnTarget[] targetsOp, int offset) {
+        super(opc_tableswitch, offset);
+
+        this.lowOp = lowOp;
+        this.defaultOp = defaultOp; 
+        this.targetsOp = targetsOp;
+
+        if (defaultOp == null || targetsOp == null)
+            throw new InsnError ("attempt to create an opc_tableswitch" +
+                                 " with invalid operands");
+    }
+
+    static InsnTableSwitch read (InsnReadEnv insnEnv, int myPC) {
+        /* eat up any padding */
+        int thisPC = myPC +1;
+        for (int pads = ((thisPC + 3) & ~3) - thisPC; pads > 0; pads--)
+            insnEnv.getByte();
+        InsnTarget defaultTarget = insnEnv.getTarget(insnEnv.getInt() + myPC);
+        int low = insnEnv.getInt();
+        int high = insnEnv.getInt();
+        InsnTarget[] offsets = new InsnTarget[high - low + 1];
+        for (int i=0; i<offsets.length; i++)
+            offsets[i] = insnEnv.getTarget(insnEnv.getInt() + myPC);
+        return new InsnTableSwitch(low, defaultTarget,   offsets, myPC);
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java Sun May 22 10:55:51 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.PrintStream;
+import java.util.Stack;
+
+/**
+ * InsnTarget is a pseudo-instruction which represents a branch target
+ * in an instruction stream.
+ */
+public class InsnTarget extends Insn {
+
+    private boolean branchTarget = false;
+
+    public int nStackArgs() {
+        return 0;
+    }
+
+    public int nStackResults() {
+        return 0;
+    }
+
+    public String argTypes() {
+        return "";
+    }
+
+    public String resultTypes() {
+        return "";
+    }
+
+    public boolean branches() {
+        return false;
+    }
+
+    public void setBranchTarget() {
+        branchTarget = true;
+    }
+
+    /* not valid unless method instructions processed specially */
+    public boolean isBranchTarget() {
+        return branchTarget;
+    }
+
+    /**
+     * Constructor
+     */
+    public InsnTarget() {
+        super(opc_target, NO_OFFSET);
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnTarget)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnTarget other = (InsnTarget)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (this.branchTarget != other.branchTarget) {
+            msg.push(String.valueOf("branchTarget = "
+                                    + other.branchTarget));
+            msg.push(String.valueOf("branchTarget = "
+                                    + this.branchTarget));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(offset() + ":");
+    }
+
+    int store(byte buf[], int index) {
+        return index;
+    }
+
+    int size() {
+        return 0;
+    }
+
+    InsnTarget(int offset) {
+        super(opc_target, offset);
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java Sun May 22 10:55:51 2005
@@ -0,0 +1,162 @@
+/*
+ * 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 branch offset
+ * as an immediate operand .
+ */
+public class InsnTargetOp extends Insn {
+    /* The branch target */
+    InsnTarget targetOp;
+
+    /* 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 true;
+    }
+
+    /**
+     * Mark possible branch targets
+     */
+    public void markTargets() {
+        targetOp.setBranchTarget();
+    }
+
+    /**
+     * Return the branch target which is the immediate operand
+     */
+    public InsnTarget target() {
+        return targetOp;
+    }
+    
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof InsnTargetOp)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        InsnTargetOp other = (InsnTargetOp)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        if (!this.targetOp.isEqual(msg, other.targetOp)) {
+            msg.push(String.valueOf("targetOp = "
+                                    + other.targetOp));
+            msg.push(String.valueOf("targetOp = "
+                                    + this.targetOp));
+            return false;
+        }
+        return true;
+    }
+
+    /* package local methods */
+
+    void print (PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        /* print offset in non-relative form for readability */
+        out.println(offset() + "  " + opName(opcode()) + "  " + 
+                    targetOp.offset());
+    }
+
+    int store(byte[] buf, int index) {
+        buf[index++] = (byte) opcode();
+        int off = targetOp.offset() - offset();
+        if (opcode() == opc_goto_w || opcode() == opc_jsr_w)
+            return storeInt(buf, index, off);
+        else
+            return storeShort(buf, index, (short)off);
+    }
+
+    int size() {
+        if (opcode() == opc_goto_w || opcode() == opc_jsr_w)
+            return 5;
+        return 3;
+    }
+
+    InsnTargetOp (int theOpcode, InsnTarget theOperand, int pc) {
+        super(theOpcode, pc);
+        targetOp = theOperand;
+    }
+
+    InsnTargetOp (int theOpcode, InsnTarget theOperand) {
+        super(theOpcode, NO_OFFSET);
+
+        targetOp = theOperand;
+
+        switch(theOpcode) {
+        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:
+        case opc_goto_w:
+        case opc_jsr_w:
+            /* Target */
+            if (theOperand == null)
+                throw new InsnError ("attempt to create an " + opName(theOpcode) +
+                                     " with a null Target operand");
+            break;
+
+        default:
+            throw new InsnError ("attempt to create an " + opName(theOpcode) +
+                                 " with an InsnTarget operand");
+        }
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java Sun May 22 10:55:51 2005
@@ -0,0 +1,351 @@
+/*
+ * 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;
+
+/**
+ * InsnUtils provides a set of static methods which serve to 
+ * select vm instructions during code annotation.
+ */
+public
+class InsnUtils implements VMConstants {
+
+    /**
+     * Return the best instruction for loading a value from the constant
+     * pool onto the stack - hopefully use short form
+     */
+    //@olsen: added method
+    public static Insn constantValue(ConstValue value) {
+        int tag = value.tag();
+        switch (tag) {
+        case CONSTANTInteger :
+        case CONSTANTFloat :
+        case CONSTANTString :
+            //@olsen: check index range to select opc_ldc vs. opc_ldc_w
+            int opcode = (value.getIndex() <= 0xFF ? opc_ldc : opc_ldc_w);
+            return Insn.create(opcode, value);
+        case CONSTANTLong :
+        case CONSTANTDouble :
+            //@olsen: require opc_ldc2_w (there's no short form: opc_ldc2)
+            return Insn.create(opc_ldc2_w, value);
+        default:
+            throw new InsnError("bad constant tag");
+        }
+    }
+    
+    /**
+     * Return the best instruction for loading the specified String
+     * constant onto the stack - hopefully use short form
+     */
+    //@olsen: added method
+    public static Insn stringConstant(String s, ConstantPool pool) {
+        //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
+        return constantValue(pool.addString(s));
+    }
+
+    /**
+     * Return the best instruction for loading the specified integer 
+     * constant onto the stack - hopefully use short form
+     */
+    public static Insn integerConstant(int i, ConstantPool pool) {
+        //@olsen: removed redundant 'else's
+        //@olsen: added use of opc_iconst_m1
+        if (i == -1)
+            return Insn.create(opc_iconst_m1);
+        if (i == 0)
+            return Insn.create(opc_iconst_0);
+        if (i == 1)
+            return Insn.create(opc_iconst_1);
+        if (i == 2)
+            return Insn.create(opc_iconst_2);
+        if (i == 3)
+            return Insn.create(opc_iconst_3);
+        if (i == 4)
+            return Insn.create(opc_iconst_4);
+        if (i == 5)
+            return Insn.create(opc_iconst_5);
+        if (i >= -128 && i < 128)
+            return Insn.create(opc_bipush, i);
+        //@olsen: added use of opc_sipush
+        if (i >= -32768 && i < 32768)
+            return Insn.create(opc_sipush, i);
+        //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
+        //return Insn.create(opc_ldc, pool.addInteger(i));
+        return constantValue(pool.addInteger(i));
+    }
+
+    /**
+     * Return the best instruction for loading the specified long constant onto
+     * the stack.
+     */
+    public static Insn longConstant(long l, ConstantPool pool) {
+        //@olsen: removed redundant 'else's
+        if (l == 0)
+            return Insn.create(opc_lconst_0);
+        if (l == 1)
+            return Insn.create(opc_lconst_1);
+        //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
+        //return Insn.create(opc_ldc2_w, pool.addLong(l));
+        return constantValue(pool.addLong(l));
+    }
+
+    /**
+     * Return the best instruction for loading the specified float constant onto
+     * the stack.
+     */
+    public static Insn floatConstant(float f, ConstantPool pool) {
+        //@olsen: removed redundant 'else's
+        if (f == 0)
+            return Insn.create(opc_fconst_0);
+        if (f == 1)
+            return Insn.create(opc_fconst_1);
+        if (f == 2)
+            return Insn.create(opc_fconst_2);
+        //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
+        //return Insn.create(opc_ldc, pool.addFloat(f));
+        return constantValue(pool.addFloat(f));
+    }
+
+    /**
+     * Return the best instruction for loading the specified double constant onto
+     * the stack.
+     */
+    public static Insn doubleConstant(double d, ConstantPool pool) {
+        //@olsen: removed redundant 'else's
+        if (d == 0)
+            return Insn.create(opc_dconst_0);
+        if (d == 1)
+            return Insn.create(opc_dconst_1);
+        //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
+        //return Insn.create(opc_ldc2_w, pool.addDouble(d));
+        return constantValue(pool.addDouble(d));
+    }
+
+    /**
+     * Return the best instruction for storing a reference to a local
+     * variable slot
+     */
+    public static Insn aStore(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_astore_0);
+        else if (i == 1)
+            return Insn.create(opc_astore_1);
+        else if (i == 2)
+            return Insn.create(opc_astore_2);
+        else if (i == 3)
+            return Insn.create(opc_astore_3);
+        return Insn.create(opc_astore, i);
+    }
+
+    /**
+     * Return the best instruction for storing an int to a local
+     * variable slot
+     */
+    public static Insn iStore(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_istore_0);
+        else if (i == 1)
+            return Insn.create(opc_istore_1);
+        else if (i == 2)
+            return Insn.create(opc_istore_2);
+        else if (i == 3)
+            return Insn.create(opc_istore_3);
+        return Insn.create(opc_istore, i);
+    }
+
+    /**
+     * Return the best instruction for storing a float to a local
+     * variable slot
+     */
+    public static Insn fStore(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_fstore_0);
+        else if (i == 1)
+            return Insn.create(opc_fstore_1);
+        else if (i == 2)
+            return Insn.create(opc_fstore_2);
+        else if (i == 3)
+            return Insn.create(opc_fstore_3);
+        return Insn.create(opc_fstore, i);
+    }
+
+    /**
+     * Return the best instruction for storing a long to a local
+     * variable slot
+     */
+    public static Insn lStore(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_lstore_0);
+        else if (i == 1)
+            return Insn.create(opc_lstore_1);
+        else if (i == 2)
+            return Insn.create(opc_lstore_2);
+        else if (i == 3)
+            return Insn.create(opc_lstore_3);
+        return Insn.create(opc_lstore, i);
+    }
+
+    /**
+     * Return the best instruction for storing a double to a local
+     * variable slot
+     */
+    public static Insn dStore(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_dstore_0);
+        else if (i == 1)
+            return Insn.create(opc_dstore_1);
+        else if (i == 2)
+            return Insn.create(opc_dstore_2);
+        else if (i == 3)
+            return Insn.create(opc_dstore_3);
+        return Insn.create(opc_dstore, i);
+    }
+
+    /**
+     * Return the best instruction for loading a reference from a local
+     * variable slot
+     */
+    public static Insn aLoad(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_aload_0);
+        else if (i == 1)
+            return Insn.create(opc_aload_1);
+        else if (i == 2)
+            return Insn.create(opc_aload_2);
+        else if (i == 3)
+            return Insn.create(opc_aload_3);
+        return Insn.create(opc_aload, i);
+    }
+
+    /**
+     * Return the best instruction for loading an int from a local
+     * variable slot
+     */
+    public static Insn iLoad(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_iload_0);
+        else if (i == 1)
+            return Insn.create(opc_iload_1);
+        else if (i == 2)
+            return Insn.create(opc_iload_2);
+        else if (i == 3)
+            return Insn.create(opc_iload_3);
+        return Insn.create(opc_iload, i);
+    }
+
+    /**
+     * Return the best instruction for loading a float from a local
+     * variable slot
+     */
+    public static Insn fLoad(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_fload_0);
+        else if (i == 1)
+            return Insn.create(opc_fload_1);
+        else if (i == 2)
+            return Insn.create(opc_fload_2);
+        else if (i == 3)
+            return Insn.create(opc_fload_3);
+        return Insn.create(opc_fload, i);
+    }
+
+    /**
+     * Return the best instruction for loading a long from a local
+     * variable slot
+     */
+    public static Insn lLoad(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_lload_0);
+        else if (i == 1)
+            return Insn.create(opc_lload_1);
+        else if (i == 2)
+            return Insn.create(opc_lload_2);
+        else if (i == 3)
+            return Insn.create(opc_lload_3);
+        return Insn.create(opc_lload, i);
+    }
+
+    /**
+     * Return the best instruction for loading a double from a local
+     * variable slot
+     */
+    public static Insn dLoad(int i, ConstantPool pool) {
+        if (i == 0)
+            return Insn.create(opc_dload_0);
+        else if (i == 1)
+            return Insn.create(opc_dload_1);
+        else if (i == 2)
+            return Insn.create(opc_dload_2);
+        else if (i == 3)
+            return Insn.create(opc_dload_3);
+        return Insn.create(opc_dload, i);
+    }
+
+    /**
+     * Return the best instruction for loading a value from a local
+     * variable slot
+     */
+    public static Insn load(int tp, int i, ConstantPool pool) {
+        switch(tp) {
+            //@olsen: added these cases:
+        case T_BOOLEAN:
+        case T_CHAR:
+        case T_BYTE:
+        case T_SHORT:
+            //@olsen: end added cases
+        case T_INT:
+            return iLoad(i, pool);
+        case T_FLOAT:
+            return fLoad(i, pool);
+        case T_DOUBLE:
+            return dLoad(i, pool);
+        case T_LONG:
+            return lLoad(i, pool);
+        case TC_OBJECT:
+            return aLoad(i, pool);
+        default:
+            throw new InsnError("bad load type");
+        }
+    }
+
+    /**
+     * Return the best instruction for storing a value to a local
+     * variable slot
+     */
+    public static Insn store(int tp, int i, ConstantPool pool) {
+        switch(tp) {
+            //@olsen: added these cases:
+        case T_BOOLEAN:
+        case T_CHAR:
+        case T_BYTE:
+        case T_SHORT:
+            //@olsen: end added cases
+        case T_INT:
+            return iStore(i, pool);
+        case T_FLOAT:
+            return fStore(i, pool);
+        case T_DOUBLE:
+            return dStore(i, pool);
+        case T_LONG:
+            return lStore(i, pool);
+        case TC_OBJECT:
+            return aStore(i, pool);
+        default:
+            throw new InsnError("bad store type");
+        }
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+/**
+ * LineNumberTableAttribute represents a line number table attribute
+ * within a CodeAttribute within a class file
+ */
+public class LineNumberTableAttribute extends ClassAttribute {
+    /* The expected attribute name */
+    public final static String expectedAttrName = "LineNumberTable";
+
+    /* The line numbers */
+    private short lineNumbers[];
+
+    /* The corresponding instructions */
+    private InsnTarget targets[];
+
+    /* public accessors */
+
+    /**
+     * Constructor
+     */
+    public LineNumberTableAttribute(
+	ConstUtf8 nameAttr, short lineNums[], InsnTarget targets[]) {
+        super(nameAttr);
+        lineNumbers = lineNums;
+        this.targets = targets;
+    }
+
+    /**
+     * Compares this instance with another for structural equality.
+     */
+    //@olsen: added method
+    public boolean isEqual(Stack msg, Object obj) {
+        if (!(obj instanceof LineNumberTableAttribute)) {
+            msg.push("obj/obj.getClass() = "
+                     + (obj == null ? null : obj.getClass()));
+            msg.push("this.getClass() = "
+                     + this.getClass());
+            return false;
+        }
+        LineNumberTableAttribute other = (LineNumberTableAttribute)obj;
+
+        if (!super.isEqual(msg, other)) {
+            return false;
+        }
+
+        // intentionally ingore any linenumber differences
+        return true;
+    }
+
+    /* package local methods */
+
+    static LineNumberTableAttribute read(
+	ConstUtf8 attrName, DataInputStream data, CodeEnv env)
+        throws IOException {
+        int nLnums = data.readUnsignedShort();
+        short lineNums[] = new short[nLnums];
+        InsnTarget targs[] = new InsnTarget[nLnums];
+        for (int i=0; i<nLnums; i++) {
+            targs[i] = env.getTarget(data.readShort());
+            lineNums[i] = data.readShort();
+        }
+        return  new LineNumberTableAttribute(attrName, lineNums, targs);
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(attrName().getIndex());
+        int nlines = lineNumbers.length;
+        out.writeInt(2+4*nlines);
+        out.writeShort(nlines);
+        for (int i=0; i<nlines; i++) {
+            out.writeShort(targets[i].offset());
+            out.writeShort(lineNumbers[i]);
+        }
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println("Line Numbers: ");
+        for (int i=0; i<lineNumbers.length; i++) {
+            ClassPrint.spaces(out, indent+2);
+            out.println(Integer.toString(lineNumbers[i]) + " @ " +
+                        Integer.toString(targets[i].offset()));
+        }
+    }
+}
+

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java Sun May 22 10:55:51 2005
@@ -0,0 +1,89 @@
+/*
+ * 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.*;
+
+/**
+ * Represents a local variable within a LocalVariableTable within
+ * a CodeAttribute in a class file.
+ */
+public class LocalVariable {
+    /* The pc at which the variable becomes effecive */
+    private InsnTarget varStartPC; /* inclusive */
+
+    /* The pc at which the variable becomes in-effecive */
+    private InsnTarget varEndPC;   /* exclusive */
+
+    /* The name of the variable */
+    private ConstUtf8 varName;
+
+    /* The type signature of the variable */
+    private ConstUtf8 varSig;
+
+    /* The slot to which the variable is assigned */
+    private int varSlot;
+
+    /* public accessors */
+
+    /**
+     * Constructor for a local variable
+     */
+    public LocalVariable(InsnTarget startPC, InsnTarget endPC,
+                         ConstUtf8 name, ConstUtf8 sig, int slot) {
+        varStartPC = startPC;
+        varEndPC = endPC;
+        varName = name;
+        varSig = sig;
+        varSlot = slot;
+    }
+
+    /* package local methods */
+
+    static LocalVariable read(DataInputStream data, CodeEnv env)
+        throws IOException {
+        int startPC = data.readUnsignedShort();
+        InsnTarget startPCTarget = env.getTarget(startPC);
+        int length = data.readUnsignedShort();
+        InsnTarget endPCTarget = env.getTarget(startPC+length);
+        ConstUtf8 name = 
+            (ConstUtf8) env.pool().constantAt(data.readUnsignedShort());
+        ConstUtf8 sig = 
+            (ConstUtf8) env.pool().constantAt(data.readUnsignedShort());
+        int slot = data.readUnsignedShort();
+        return new LocalVariable(startPCTarget, endPCTarget, name, sig, slot);
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(varStartPC.offset());
+        out.writeShort(varEndPC.offset() - varStartPC.offset());
+        out.writeShort((varName == null) ? 0 : varName.getIndex());
+        out.writeShort((varSig == null) ? 0 : varSig.getIndex());
+        out.writeShort(varSlot);
+    }
+
+    public void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.print("'" + ((varName == null) ? "(null)" : varName.asString()) + "'");
+        out.print(" sig = " + ((varSig == null) ? "(null)" : varSig.asString()));
+        out.print(" start_pc = " + Integer.toString(varStartPC.offset()));
+        out.print(" length = " +
+                  Integer.toString(varEndPC.offset() - varStartPC.offset()));
+        out.println(" slot = " + Integer.toString(varSlot));
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,90 @@
+/*
+ * 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.Vector;
+import java.util.Enumeration;
+
+/**
+ * Represents the LocalVariableTable attribute within a
+ * method in a class file.
+ */
+public class LocalVariableTableAttribute extends ClassAttribute {
+    /* The expected attribute name */
+    public static final String expectedAttrName = "LocalVariableTable";
+
+    /* The list of local variables */
+    private Vector localTable;
+
+    /* public accessors */
+
+    /**
+     * Returns an enumeration of the local variables in the table
+     * Each element is a LocalVariable
+     */
+    Enumeration variables() {
+        return localTable.elements();
+    }
+
+    /**
+     * Constructor for a local variable table
+     */
+    public LocalVariableTableAttribute(
+	ConstUtf8 nameAttr, Vector lvarTable) {
+        super(nameAttr);
+        localTable = lvarTable;
+    }
+
+    /* package local methods */
+
+    static LocalVariableTableAttribute read(
+	ConstUtf8 attrName, DataInputStream data, CodeEnv env)
+        throws IOException {
+        int nVars = data.readUnsignedShort();
+        Vector lvarTable = new Vector();
+        while (nVars-- > 0) {
+            lvarTable.addElement(LocalVariable.read(data, env));
+        }
+        
+        return new LocalVariableTableAttribute(attrName, lvarTable);
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(attrName().getIndex());
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream tmp_out = new DataOutputStream(baos);
+        tmp_out.writeShort(localTable.size());
+        for (int i=0; i<localTable.size(); i++)
+            ((LocalVariable) localTable.elementAt(i)).write(tmp_out);
+
+        tmp_out.flush();
+        byte tmp_bytes[] = baos.toByteArray();
+        out.writeInt(tmp_bytes.length);
+        out.write(tmp_bytes, 0, tmp_bytes.length);
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println("LocalVariables: ");
+        for (int i=0; i<localTable.size(); i++) {
+            ((LocalVariable) localTable.elementAt(i)).print(out, indent+2);
+        }
+    }
+}
+

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,78 @@
+/*
+ * 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.*;
+
+/**
+ * Represents the source file attribute in a class file
+ */
+public class SourceFileAttribute extends ClassAttribute {
+    /* The expected attribute name */
+    public static final String expectedAttrName = "SourceFile";
+
+    /* The source file name */
+    private ConstUtf8 sourceFileName;
+
+    /* public accessors */
+
+    /**
+     * Returns the source file name
+     * The file name should not include directories
+     */
+    public ConstUtf8 fileName() {
+        return sourceFileName;
+    }
+
+    /**
+     * Sets the source file name
+     */
+    public void setFileName(ConstUtf8 name) {
+        sourceFileName = name;
+    }
+
+    /**
+     * Constructor for a source file attribute
+     */
+    public SourceFileAttribute(ConstUtf8 attrName, ConstUtf8 sourceName) {
+        super(attrName);
+        sourceFileName = sourceName;
+    }
+
+    /* package local methods */
+    static SourceFileAttribute read(ConstUtf8 attrName,
+                                    DataInputStream data, ConstantPool pool)
+        throws IOException {
+        int index = 0;
+        index = data.readUnsignedShort();
+
+        return new SourceFileAttribute(attrName,
+                                       (ConstUtf8) pool.constantAt(index));
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(attrName().getIndex());
+        out.writeInt(2);
+        out.writeShort(sourceFileName.getIndex());
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println("SourceFile: " + sourceFileName.asString());
+    }
+}

Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,62 @@
+/*
+ * 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.*;
+
+//@olsen: fix 4467428, added class for synthetic attribute to be added
+// to generated jdo fields and methods
+
+/**
+ * A SyntheticAttribute is a fixed-length attribute in the attributes table
+ * of ClassFile, ClassField, and ClassMethod structures.  A class member
+ * that does not appear in the source code must be marked using a
+ * SyntheticAttribute. 
+ */
+public class SyntheticAttribute extends ClassAttribute {
+    /* The expected name of this attribute */
+    public static final String expectedAttrName = "Synthetic";
+
+    /** 
+     * Construct a constant value attribute
+     */
+    public SyntheticAttribute(ConstUtf8 attrName) {
+        super(attrName);
+        //System.out.println("new SyntheticAttribute()");
+    }
+
+    /* package local methods */
+
+    static SyntheticAttribute read(ConstUtf8 attrName,
+                                   DataInputStream data,
+                                   ConstantPool pool)
+        throws IOException {
+        return new SyntheticAttribute(attrName);
+    }
+
+    void write(DataOutputStream out) throws IOException {
+        out.writeShort(attrName().getIndex());
+        final int attributeBytesLength = 0;
+        out.writeInt(attributeBytesLength);
+    }
+
+    void print(PrintStream out, int indent) {
+        ClassPrint.spaces(out, indent);
+        out.println(expectedAttrName);
+    }
+}