Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnLookupSwitch.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnMultiDimArrayNew.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnReadEnv.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnSingle.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTableSwitch.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTarget.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.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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnTargetOp.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/InsnUtils.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LineNumberTableAttribute.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariable.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/LocalVariableTableAttribute.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SourceFileAttribute.java Fri Mar 18 17:02:29 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/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/SyntheticAttribute.java Fri Mar 18 17:02:29 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); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMConstants.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMConstants.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMConstants.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMConstants.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,282 @@ +/* + * 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; + +/** + * VMConstants is a collection of the constants defined in the + * virtual machine spec. + * Also included are several assorted constants of our own which + * seem logical to define here. + */ +public interface VMConstants { + /* Access types */ + static final int ACCPublic = 0x0001; + static final int ACCPrivate = 0x0002; + static final int ACCProtected = 0x0004; + static final int ACCStatic = 0x0008; + static final int ACCFinal = 0x0010; + static final int ACCSuper = 0x0020; /* For Class file */ + static final int ACCSynchronized = 0x0020; /* For methods */ + static final int ACCVolatile = 0x0040; + static final int ACCTransient = 0x0080; + static final int ACCNative = 0x0100; + static final int ACCInterface = 0x0200; + static final int ACCAbstract = 0x0400; + + + /* Primitive Types */ + /* These correspond to the values used by newarray */ + static final int T_BOOLEAN = 4; + static final int T_CHAR = 5; + static final int T_FLOAT = 6; + static final int T_DOUBLE = 7; + static final int T_BYTE = 8; + static final int T_SHORT = 9; + static final int T_INT = 10; + static final int T_LONG = 11; + + /* Class types - Not really part of the VM spec */ + static final int TC_OBJECT = 12; + static final int TC_INTERFACE = 13; + static final int TC_STRING = 14; + + /* Special pseudo types - Not really part of the VM spec */ + static final int T_UNKNOWN = 15; + static final int T_WORD = 16; + static final int T_TWOWORD = 17; + + /* Constant pool types */ + static final int CONSTANTUtf8 = 1; + static final int CONSTANTUnicode = 2; /* Def.in Beta doc - not in 1.0.2 */ + static final int CONSTANTInteger = 3; + static final int CONSTANTFloat = 4; + static final int CONSTANTLong = 5; + static final int CONSTANTDouble = 6; + static final int CONSTANTClass = 7; + static final int CONSTANTString = 8; + static final int CONSTANTFieldRef = 9; + static final int CONSTANTMethodRef = 10; + static final int CONSTANTInterfaceMethodRef = 11; + static final int CONSTANTNameAndType = 12; + + + + /* Java VM opcodes */ + final static int opc_nop = 0; + final static int opc_aconst_null = 1; + final static int opc_iconst_m1 = 2; + final static int opc_iconst_0 = 3; + final static int opc_iconst_1 = 4; + final static int opc_iconst_2 = 5; + final static int opc_iconst_3 = 6; + final static int opc_iconst_4 = 7; + final static int opc_iconst_5 = 8; + final static int opc_lconst_0 = 9; + final static int opc_lconst_1 = 10; + final static int opc_fconst_0 = 11; + final static int opc_fconst_1 = 12; + final static int opc_fconst_2 = 13; + final static int opc_dconst_0 = 14; + final static int opc_dconst_1 = 15; + final static int opc_bipush = 16; + final static int opc_sipush = 17; + final static int opc_ldc = 18; + final static int opc_ldc_w = 19; + final static int opc_ldc2_w = 20; + final static int opc_iload = 21; + final static int opc_lload = 22; + final static int opc_fload = 23; + final static int opc_dload = 24; + final static int opc_aload = 25; + final static int opc_iload_0 = 26; + final static int opc_iload_1 = 27; + final static int opc_iload_2 = 28; + final static int opc_iload_3 = 29; + final static int opc_lload_0 = 30; + final static int opc_lload_1 = 31; + final static int opc_lload_2 = 32; + final static int opc_lload_3 = 33; + final static int opc_fload_0 = 34; + final static int opc_fload_1 = 35; + final static int opc_fload_2 = 36; + final static int opc_fload_3 = 37; + final static int opc_dload_0 = 38; + final static int opc_dload_1 = 39; + final static int opc_dload_2 = 40; + final static int opc_dload_3 = 41; + final static int opc_aload_0 = 42; + final static int opc_aload_1 = 43; + final static int opc_aload_2 = 44; + final static int opc_aload_3 = 45; + final static int opc_iaload = 46; + final static int opc_laload = 47; + final static int opc_faload = 48; + final static int opc_daload = 49; + final static int opc_aaload = 50; + final static int opc_baload = 51; + final static int opc_caload = 52; + final static int opc_saload = 53; + final static int opc_istore = 54; + final static int opc_lstore = 55; + final static int opc_fstore = 56; + final static int opc_dstore = 57; + final static int opc_astore = 58; + final static int opc_istore_0 = 59; + final static int opc_istore_1 = 60; + final static int opc_istore_2 = 61; + final static int opc_istore_3 = 62; + final static int opc_lstore_0 = 63; + final static int opc_lstore_1 = 64; + final static int opc_lstore_2 = 65; + final static int opc_lstore_3 = 66; + final static int opc_fstore_0 = 67; + final static int opc_fstore_1 = 68; + final static int opc_fstore_2 = 69; + final static int opc_fstore_3 = 70; + final static int opc_dstore_0 = 71; + final static int opc_dstore_1 = 72; + final static int opc_dstore_2 = 73; + final static int opc_dstore_3 = 74; + final static int opc_astore_0 = 75; + final static int opc_astore_1 = 76; + final static int opc_astore_2 = 77; + final static int opc_astore_3 = 78; + final static int opc_iastore = 79; + final static int opc_lastore = 80; + final static int opc_fastore = 81; + final static int opc_dastore = 82; + final static int opc_aastore = 83; + final static int opc_bastore = 84; + final static int opc_castore = 85; + final static int opc_sastore = 86; + final static int opc_pop = 87; + final static int opc_pop2 = 88; + final static int opc_dup = 89; + final static int opc_dup_x1 = 90; + final static int opc_dup_x2 = 91; + final static int opc_dup2 = 92; + final static int opc_dup2_x1 = 93; + final static int opc_dup2_x2 = 94; + final static int opc_swap = 95; + final static int opc_iadd = 96; + final static int opc_ladd = 97; + final static int opc_fadd = 98; + final static int opc_dadd = 99; + final static int opc_isub = 100; + final static int opc_lsub = 101; + final static int opc_fsub = 102; + final static int opc_dsub = 103; + final static int opc_imul = 104; + final static int opc_lmul = 105; + final static int opc_fmul = 106; + final static int opc_dmul = 107; + final static int opc_idiv = 108; + final static int opc_ldiv = 109; + final static int opc_fdiv = 110; + final static int opc_ddiv = 111; + final static int opc_irem = 112; + final static int opc_lrem = 113; + final static int opc_frem = 114; + final static int opc_drem = 115; + final static int opc_ineg = 116; + final static int opc_lneg = 117; + final static int opc_fneg = 118; + final static int opc_dneg = 119; + final static int opc_ishl = 120; + final static int opc_lshl = 121; + final static int opc_ishr = 122; + final static int opc_lshr = 123; + final static int opc_iushr = 124; + final static int opc_lushr = 125; + final static int opc_iand = 126; + final static int opc_land = 127; + final static int opc_ior = 128; + final static int opc_lor = 129; + final static int opc_ixor = 130; + final static int opc_lxor = 131; + final static int opc_iinc = 132; + final static int opc_i2l = 133; + final static int opc_i2f = 134; + final static int opc_i2d = 135; + final static int opc_l2i = 136; + final static int opc_l2f = 137; + final static int opc_l2d = 138; + final static int opc_f2i = 139; + final static int opc_f2l = 140; + final static int opc_f2d = 141; + final static int opc_d2i = 142; + final static int opc_d2l = 143; + final static int opc_d2f = 144; + final static int opc_i2b = 145; + final static int opc_i2c = 146; + final static int opc_i2s = 147; + final static int opc_lcmp = 148; + final static int opc_fcmpl = 149; + final static int opc_fcmpg = 150; + final static int opc_dcmpl = 151; + final static int opc_dcmpg = 152; + final static int opc_ifeq = 153; + final static int opc_ifne = 154; + final static int opc_iflt = 155; + final static int opc_ifge = 156; + final static int opc_ifgt = 157; + final static int opc_ifle = 158; + final static int opc_if_icmpeq = 159; + final static int opc_if_icmpne = 160; + final static int opc_if_icmplt = 161; + final static int opc_if_icmpge = 162; + final static int opc_if_icmpgt = 163; + final static int opc_if_icmple = 164; + final static int opc_if_acmpeq = 165; + final static int opc_if_acmpne = 166; + final static int opc_goto = 167; + final static int opc_jsr = 168; + final static int opc_ret = 169; + final static int opc_tableswitch = 170; + final static int opc_lookupswitch = 171; + final static int opc_ireturn = 172; + final static int opc_lreturn = 173; + final static int opc_freturn = 174; + final static int opc_dreturn = 175; + final static int opc_areturn = 176; + final static int opc_return = 177; + final static int opc_getstatic = 178; + final static int opc_putstatic = 179; + final static int opc_getfield = 180; + final static int opc_putfield = 181; + final static int opc_invokevirtual = 182; + final static int opc_invokespecial = 183; + final static int opc_invokestatic = 184; + final static int opc_invokeinterface = 185; + final static int opc_xxxunusedxxx = 186; + final static int opc_new = 187; + final static int opc_newarray = 188; + final static int opc_anewarray = 189; + final static int opc_arraylength = 190; + final static int opc_athrow = 191; + final static int opc_checkcast = 192; + final static int opc_instanceof = 193; + final static int opc_monitorenter = 194; + final static int opc_monitorexit = 195; + final static int opc_wide = 196; + final static int opc_multianewarray = 197; + final static int opc_ifnull = 198; + final static int opc_ifnonnull = 199; + final static int opc_goto_w = 200; + final static int opc_jsr_w = 201; +}