You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/06/28 21:46:19 UTC
svn commit: r417860 [8/12] - in /incubator/openjpa/trunk: ./ openjpa-lib/
openjpa-lib/main/ openjpa-lib/src/ openjpa-lib/src/main/
openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/
openjpa-lib/src/test/ openjpa-lib/src/test/java/ openjpa-lib/src/t...
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ * <p>An instruction that has an argument of an index into the
+ * local variable table of the current frame. This includes most of the
+ * <code>load</code> and <code>store</code> instructions.</p>
+ *
+ * <p>The local variable table size is fixed by the <code>maxLocals</code>
+ * property of the code block. Long and double types take up 2 local variable
+ * indexes.</p>
+ *
+ * <p>Parameter values to methods are loaded into the local variable table
+ * prior to the execution of the first instruction. The 0 index of the
+ * table is set to the instance of the class the method is being invoked
+ * on.</p>
+ *
+ * @author Abe White
+ */
+public abstract class LocalVariableInstruction extends TypedInstruction {
+ private int _index = -1;
+
+ LocalVariableInstruction(Code owner) {
+ super(owner);
+ }
+
+ LocalVariableInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ calculateLocal();
+ }
+
+ public String getTypeName() {
+ return null;
+ }
+
+ public TypedInstruction setType(String type) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the index of the local variable that this instruction
+ * operates on.
+ */
+ public int getLocal() {
+ return _index;
+ }
+
+ /**
+ * Set the index of the local variable that this instruction
+ * operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public LocalVariableInstruction setLocal(int index) {
+ _index = index;
+ calculateOpcode();
+
+ return this;
+ }
+
+ /**
+ * Return the parameter that this instruction operates on, or -1 if none.
+ */
+ public int getParam() {
+ return getCode().getParamsIndex(getLocal());
+ }
+
+ /**
+ * Set the method parameter that this instruction operates on. This
+ * will set both the local index and the type of the instruction based
+ * on the current method parameters.
+ */
+ public LocalVariableInstruction setParam(int param) {
+ int local = getCode().getLocalsIndex(param);
+
+ if (local != -1) {
+ BCMethod method = getCode().getMethod();
+ setType(method.getParamNames()[param]);
+ }
+
+ return setLocal(local);
+ }
+
+ /**
+ * Return the local variable object this instruction
+ * operates on, or null if none.
+ *
+ * @see LocalVariableTable#getLocalVariable(int)
+ */
+ public LocalVariable getLocalVariable() {
+ LocalVariableTable table = getCode().getLocalVariableTable(false);
+
+ if (table == null) {
+ return null;
+ }
+
+ return table.getLocalVariable(getLocal());
+ }
+
+ /**
+ * Set the local variable object this instruction
+ * operates on. This method will set both the type and local index
+ * of this instruction from the given local variable.
+ *
+ * @return this instruction, for method chaining
+ */
+ public LocalVariableInstruction setLocalVariable(LocalVariable local) {
+ if (local == null) {
+ return setLocal(-1);
+ } else {
+ String type = local.getTypeName();
+
+ if (type != null) {
+ setType(type);
+ }
+
+ return setLocal(local.getLocal());
+ }
+ }
+
+ /**
+ * Two local variable instructions are equal if the local index they
+ * reference is equal or if either index is 0/unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!getClass().equals(other.getClass())) {
+ return false;
+ }
+
+ LocalVariableInstruction ins = (LocalVariableInstruction) other;
+ int index = getLocal();
+ int insIndex = ins.getLocal();
+
+ return (index == -1) || (insIndex == -1) || (index == insIndex);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+ setLocal(((LocalVariableInstruction) orig).getLocal());
+ }
+
+ /**
+ * Subclasses with variable opcodes can use this method to be
+ * notified that information possibly affecting the opcode has been
+ * changed.
+ */
+ void calculateOpcode() {
+ }
+
+ /**
+ * Subclasses can use this method to calculate
+ * the locals index based on their opcode.
+ */
+ void calculateLocal() {
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTable.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTable.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTable.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ * <p>Code blocks compiled from source have local variable tables mapping
+ * locals used in opcodes to their names and descriptions.</p>
+ *
+ * @author Abe White
+ */
+public class LocalVariableTable extends LocalTable {
+ LocalVariableTable(int nameIndex, Attributes owner) {
+ super(nameIndex, owner);
+ }
+
+ /**
+ * Return all the locals of this method.
+ */
+ public LocalVariable[] getLocalVariables() {
+ return (LocalVariable[]) getLocals();
+ }
+
+ /**
+ * Return the local with the given locals index, or null if none.
+ */
+ public LocalVariable getLocalVariable(int local) {
+ return (LocalVariable) getLocal(local);
+ }
+
+ /**
+ * Return the local with the given name, or null if none. If multiple
+ * locals have the given name, which is returned is undefined.
+ */
+ public LocalVariable getLocalVariable(String name) {
+ return (LocalVariable) getLocal(name);
+ }
+
+ /**
+ * Return all locals with the given name, or empty array if none.
+ */
+ public LocalVariable[] getLocalVariables(String name) {
+ return (LocalVariable[]) getLocals(name);
+ }
+
+ /**
+ * Import a local from another method/class. Note that
+ * the program counter and length from the given local is copied
+ * directly, and thus will be incorrect unless this method is the same
+ * as the one the local is copied from, or the pc and length are reset.
+ */
+ public LocalVariable addLocalVariable(LocalVariable local) {
+ return (LocalVariable) addLocal(local);
+ }
+
+ /**
+ * Add a local to this table.
+ */
+ public LocalVariable addLocalVariable() {
+ return (LocalVariable) addLocal();
+ }
+
+ /**
+ * Add a local to this table.
+ */
+ public LocalVariable addLocalVariable(String name, String type) {
+ return (LocalVariable) addLocal(name, type);
+ }
+
+ /**
+ * Add a local to this table.
+ */
+ public LocalVariable addLocalVariable(String name, Class type) {
+ String typeName = (type == null) ? null : type.getName();
+
+ return addLocalVariable(name, typeName);
+ }
+
+ /**
+ * Add a local to this table.
+ */
+ public LocalVariable addLocalVariable(String name, BCClass type) {
+ String typeName = (type == null) ? null : type.getName();
+
+ return addLocalVariable(name, typeName);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterLocalVariableTable(this);
+
+ LocalVariable[] locals = (LocalVariable[]) getLocals();
+
+ for (int i = 0; i < locals.length; i++)
+ locals[i].acceptVisit(visit);
+
+ visit.exitLocalVariableTable(this);
+ }
+
+ protected Local newLocal() {
+ return new LocalVariable(this);
+ }
+
+ protected Local[] newLocalArray(int size) {
+ return new LocalVariable[size];
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTable.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableType.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableType.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableType.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableType.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ * <p>A local variable type contains the name, signature, index and scope
+ * of a generics-using local used in opcodes.</p>
+ *
+ * @author Abe White
+ */
+public class LocalVariableType extends Local {
+ LocalVariableType(LocalVariableTypeTable owner) {
+ super(owner);
+ }
+
+ /**
+ * The owning table.
+ */
+ public LocalVariableTypeTable getLocalVariableTypeTable() {
+ return (LocalVariableTypeTable) getTable();
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterLocalVariableType(this);
+ visit.exitLocalVariableType(this);
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableType.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTypeTable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTypeTable.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTypeTable.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTypeTable.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ * <p>Code blocks compiled from source have local variable type tables mapping
+ * generics-using locals used in opcodes to their names and signatures.</p>
+ *
+ * @author Abe White
+ */
+public class LocalVariableTypeTable extends LocalTable {
+ LocalVariableTypeTable(int nameIndex, Attributes owner) {
+ super(nameIndex, owner);
+ }
+
+ /**
+ * Return all the locals of this method.
+ */
+ public LocalVariableType[] getLocalVariableTypes() {
+ return (LocalVariableType[]) getLocals();
+ }
+
+ /**
+ * Return the local with the given locals index, or null if none.
+ */
+ public LocalVariableType getLocalVariableType(int local) {
+ return (LocalVariableType) getLocal(local);
+ }
+
+ /**
+ * Return the local with the given name, or null if none. If multiple
+ * locals have the given name, which is returned is undefined.
+ */
+ public LocalVariableType getLocalVariableType(String name) {
+ return (LocalVariableType) getLocal(name);
+ }
+
+ /**
+ * Return all locals with the given name, or empty array if none.
+ */
+ public LocalVariableType[] getLocalVariableTypes(String name) {
+ return (LocalVariableType[]) getLocals(name);
+ }
+
+ /**
+ * Import a local from another method/class. Note that
+ * the program counter and length from the given local is copied
+ * directly, and thus will be incorrect unless this method is the same
+ * as the one the local is copied from, or the pc and length are reset.
+ */
+ public LocalVariableType addLocalVariableType(LocalVariableType local) {
+ return (LocalVariableType) addLocal(local);
+ }
+
+ /**
+ * Add a local to this table.
+ */
+ public LocalVariableType addLocalVariableType() {
+ return (LocalVariableType) addLocal();
+ }
+
+ /**
+ * Add a local to this table.
+ */
+ public LocalVariableType addLocalVariableType(String name, String type) {
+ return (LocalVariableType) addLocal(name, type);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterLocalVariableTypeTable(this);
+
+ LocalVariableType[] locals = (LocalVariableType[]) getLocals();
+
+ for (int i = 0; i < locals.length; i++)
+ locals[i].acceptVisit(visit);
+
+ visit.exitLocalVariableTypeTable(this);
+ }
+
+ protected Local newLocal() {
+ return new LocalVariableType(this);
+ }
+
+ protected Local[] newLocalArray(int size) {
+ return new LocalVariableType[size];
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LocalVariableTypeTable.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LookupSwitchInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LookupSwitchInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LookupSwitchInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LookupSwitchInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * <p>The <code>lookupswitch</code> instruction.</p>
+ *
+ * @author Abe White
+ */
+public class LookupSwitchInstruction extends JumpInstruction {
+ // case info
+ private List _matches = new LinkedList();
+ private List _cases = new LinkedList();
+
+ LookupSwitchInstruction(Code owner) {
+ super(owner, Constants.LOOKUPSWITCH);
+ }
+
+ int getLength() {
+ // don't call super.getLength(), cause JumpInstruction will return
+ // value assuming this is an 'if' or 'goto' instruction
+ int length = 1;
+
+ // make the first byte of the 'default' a multiple of 4 from the
+ // start of the method
+ int byteIndex = getByteIndex() + 1;
+
+ for (; (byteIndex % 4) != 0; byteIndex++, length++)
+ ;
+
+ // default, npairs
+ length += 8;
+
+ // pairs
+ length += (8 * _matches.size());
+
+ return length;
+ }
+
+ public int getLogicalStackChange() {
+ return getStackChange();
+ }
+
+ public int getStackChange() {
+ return -1;
+ }
+
+ /**
+ * Synonymous with {@link #getTarget}.
+ */
+ public Instruction getDefaultTarget() {
+ return getTarget();
+ }
+
+ /**
+ * Synonymous with {@link #setTarget}.
+ */
+ public LookupSwitchInstruction setDefaultTarget(Instruction ins) {
+ return (LookupSwitchInstruction) setTarget(ins);
+ }
+
+ /**
+ * Synonymous with {@link #getOffset}.
+ */
+ public int getDefaultOffset() {
+ return getOffset();
+ }
+
+ /**
+ * Synonymous with {@link #setOffset}.
+ */
+ public LookupSwitchInstruction setDefaultOffset(int offset) {
+ setOffset(offset);
+
+ return this;
+ }
+
+ /**
+ * Set the match-jumppt pairs for this switch.
+ *
+ * @return this instruction, for method chaining
+ */
+ public LookupSwitchInstruction setCases(int[] matches, Instruction[] targets) {
+ _matches.clear();
+ _cases.clear();
+
+ for (int i = 0; i < matches.length; i++)
+ _matches.add(Numbers.valueOf(matches[i]));
+
+ for (int i = 0; i < targets.length; i++) {
+ InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+ next.setTargetInstruction(targets[i]);
+ _cases.add(next);
+ }
+
+ return this;
+ }
+
+ public int[] getOffsets() {
+ int bi = getByteIndex();
+ int[] offsets = new int[_cases.size()];
+
+ for (int i = 0; i < offsets.length; i++)
+ offsets[i] = ((InstructionPtrStrategy) _cases.get(i)).getByteIndex() -
+ bi;
+
+ return offsets;
+ }
+
+ /**
+ * Return the values of the case statements for this switch.
+ */
+ public int[] getMatches() {
+ int[] matches = new int[_matches.size()];
+ Iterator itr = _matches.iterator();
+
+ for (int i = 0; i < matches.length; i++)
+ matches[i] = ((Integer) itr.next()).intValue();
+
+ return matches;
+ }
+
+ /**
+ * Return the targets of the case statements for this switch.
+ */
+ public Instruction[] getTargets() {
+ Instruction[] result = new Instruction[_cases.size()];
+
+ for (int i = 0; i < result.length; i++)
+ result[i] = ((InstructionPtrStrategy) _cases.get(i)).getTargetInstruction();
+
+ return result;
+ }
+
+ /**
+ * Add a case to this switch.
+ *
+ * @return this instruction, for method chaining
+ */
+ public LookupSwitchInstruction addCase(int match, Instruction target) {
+ _matches.add(Numbers.valueOf(match));
+ _cases.add(new InstructionPtrStrategy(this, target));
+
+ return this;
+ }
+
+ private Instruction findJumpPoint(int jumpByteIndex, List inss) {
+ Instruction ins;
+
+ for (Iterator itr = inss.iterator(); itr.hasNext();) {
+ ins = (Instruction) itr.next();
+
+ if (ins.getByteIndex() == jumpByteIndex) {
+ return ins;
+ }
+ }
+
+ return null;
+ }
+
+ public void updateTargets() {
+ super.updateTargets();
+
+ for (Iterator itr = _cases.iterator(); itr.hasNext();)
+ ((InstructionPtrStrategy) itr.next()).updateTargets();
+ }
+
+ public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
+ super.replaceTarget(oldTarget, newTarget);
+
+ for (Iterator itr = _cases.iterator(); itr.hasNext();)
+ ((InstructionPtrStrategy) itr.next()).replaceTarget(oldTarget,
+ newTarget);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterLookupSwitchInstruction(this);
+ visit.exitLookupSwitchInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+
+ LookupSwitchInstruction ins = (LookupSwitchInstruction) orig;
+ _matches = new LinkedList(ins._matches);
+ _cases.clear();
+
+ for (Iterator itr = ins._cases.iterator(); itr.hasNext();) {
+ InstructionPtrStrategy origPtr = (InstructionPtrStrategy) itr.next();
+ InstructionPtrStrategy newPtr = new InstructionPtrStrategy(this);
+ newPtr.setByteIndex(origPtr.getByteIndex());
+ _cases.add(newPtr);
+ }
+ }
+
+ void read(DataInput in) throws IOException {
+ // don't call super
+ int bi = getByteIndex();
+
+ for (int byteIndex = bi + 1; (byteIndex % 4) != 0; byteIndex++)
+ in.readByte();
+
+ setOffset(in.readInt());
+
+ _matches.clear();
+ _cases.clear();
+
+ for (int i = 0, pairCount = in.readInt(); i < pairCount; i++) {
+ _matches.add(Numbers.valueOf(in.readInt()));
+
+ InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+ next.setByteIndex(bi + in.readInt());
+ _cases.add(next);
+ }
+ }
+
+ void write(DataOutput out) throws IOException {
+ // don't call super
+ int bi = getByteIndex();
+
+ for (int byteIndex = bi + 1; (byteIndex % 4) != 0; byteIndex++)
+ out.writeByte(0);
+
+ out.writeInt(getOffset());
+ out.writeInt(_matches.size());
+
+ for (int i = 0; i < _matches.size(); i++) {
+ out.writeInt(((Integer) _matches.get(i)).intValue());
+ out.writeInt(((InstructionPtrStrategy) _cases.get(i)).getByteIndex() -
+ bi);
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/LookupSwitchInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MathInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MathInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MathInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MathInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+import java.util.*;
+
+
+/**
+ * <p>One of the math operations defined in the {@link Constants} interface.
+ * Changing the type or operation of the instruction will automatically
+ * update the underlying opcode.</p>
+ *
+ * @author Abe White
+ */
+public class MathInstruction extends TypedInstruction {
+ private static final Class[][] _mappings = new Class[][] {
+ { byte.class, int.class },
+ { boolean.class, int.class },
+ { char.class, int.class },
+ { short.class, int.class },
+ { void.class, int.class },
+ { Object.class, int.class },
+ };
+ private int _op = -1;
+ private String _type = null;
+
+ MathInstruction(Code owner) {
+ super(owner);
+ }
+
+ MathInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ _op = getOperation();
+ }
+
+ public int getStackChange() {
+ int op = getOperation();
+
+ if ((op == Constants.MATH_NEG) || (getOpcode() == Constants.NOP)) {
+ return 0;
+ }
+
+ String type = getTypeName();
+
+ if (long.class.getName().equals(type) ||
+ double.class.getName().equals(type)) {
+ switch (getOpcode()) {
+ case (Constants.LSHL):
+ case (Constants.LSHR):
+ case (Constants.LUSHR):
+ return -1;
+
+ default:
+ return -2;
+ }
+ }
+
+ return -1;
+ }
+
+ public int getLogicalStackChange() {
+ int op = getOperation();
+
+ if ((op == Constants.MATH_NEG) || (getOpcode() == Constants.NOP)) {
+ return 0;
+ }
+
+ return -1;
+ }
+
+ public String getTypeName() {
+ switch (getOpcode()) {
+ case Constants.IADD:
+ case Constants.ISUB:
+ case Constants.IMUL:
+ case Constants.IDIV:
+ case Constants.IREM:
+ case Constants.INEG:
+ case Constants.ISHL:
+ case Constants.ISHR:
+ case Constants.IUSHR:
+ case Constants.IAND:
+ case Constants.IOR:
+ case Constants.IXOR:
+ return int.class.getName();
+
+ case Constants.LADD:
+ case Constants.LSUB:
+ case Constants.LMUL:
+ case Constants.LDIV:
+ case Constants.LREM:
+ case Constants.LNEG:
+ case Constants.LSHL:
+ case Constants.LSHR:
+ case Constants.LUSHR:
+ case Constants.LAND:
+ case Constants.LOR:
+ case Constants.LXOR:
+ return long.class.getName();
+
+ case Constants.FADD:
+ case Constants.FSUB:
+ case Constants.FMUL:
+ case Constants.FDIV:
+ case Constants.FREM:
+ case Constants.FNEG:
+ return float.class.getName();
+
+ case Constants.DADD:
+ case Constants.DSUB:
+ case Constants.DMUL:
+ case Constants.DDIV:
+ case Constants.DREM:
+ case Constants.DNEG:
+ return double.class.getName();
+
+ default:
+ return _type;
+ }
+ }
+
+ public TypedInstruction setType(String type) {
+ type = mapType(type, _mappings, true);
+
+ // if an invalid type or op, revert to nop
+ if ((type == null) || (_op < 0)) {
+ _type = type;
+
+ return (TypedInstruction) setOpcode(Constants.NOP);
+ }
+
+ // valid opcode, unset saved type
+ _type = null;
+
+ switch (type.charAt(0)) {
+ case 'i':
+ return (TypedInstruction) setOpcode(_op);
+
+ case 'l':
+ return (TypedInstruction) setOpcode(_op + 1);
+
+ case 'f':
+ return (TypedInstruction) setOpcode(_op + 2);
+
+ case 'd':
+ return (TypedInstruction) setOpcode(_op + 3);
+
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Set the math operation to be performed. This should be one of the
+ * math constant defined in {@link Constants}.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MathInstruction setOperation(int operation) {
+ _op = operation;
+
+ // this calculates the opcode
+ setType(getTypeName());
+
+ return this;
+ }
+
+ /**
+ * Return the operation for this math instruction; will be one of the
+ * math constant defined in {@link Constants}, or -1 if
+ * unset.
+ */
+ public int getOperation() {
+ switch (getOpcode()) {
+ case Constants.IADD:
+ case Constants.LADD:
+ case Constants.FADD:
+ case Constants.DADD:
+ return Constants.MATH_ADD;
+
+ case Constants.ISUB:
+ case Constants.LSUB:
+ case Constants.FSUB:
+ case Constants.DSUB:
+ return Constants.MATH_SUB;
+
+ case Constants.IMUL:
+ case Constants.LMUL:
+ case Constants.FMUL:
+ case Constants.DMUL:
+ return Constants.MATH_MUL;
+
+ case Constants.IDIV:
+ case Constants.LDIV:
+ case Constants.FDIV:
+ case Constants.DDIV:
+ return Constants.MATH_DIV;
+
+ case Constants.IREM:
+ case Constants.LREM:
+ case Constants.FREM:
+ case Constants.DREM:
+ return Constants.MATH_REM;
+
+ case Constants.INEG:
+ case Constants.LNEG:
+ case Constants.FNEG:
+ case Constants.DNEG:
+ return Constants.MATH_NEG;
+
+ case Constants.ISHL:
+ case Constants.LSHL:
+ return Constants.MATH_SHL;
+
+ case Constants.ISHR:
+ case Constants.LSHR:
+ return Constants.MATH_SHR;
+
+ case Constants.IUSHR:
+ case Constants.LUSHR:
+ return Constants.MATH_USHR;
+
+ case Constants.IAND:
+ case Constants.LAND:
+ return Constants.MATH_AND;
+
+ case Constants.IOR:
+ case Constants.LOR:
+ return Constants.MATH_OR;
+
+ case Constants.IXOR:
+ case Constants.LXOR:
+ return Constants.MATH_XOR;
+
+ default:
+ return _op;
+ }
+ }
+
+ /**
+ * MathInstructions are equal if they have the same operation and type,
+ * or the operation and type of either is unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof MathInstruction)) {
+ return false;
+ }
+
+ MathInstruction ins = (MathInstruction) other;
+
+ int op = getOperation();
+ int otherOp = ins.getOperation();
+ boolean opEq = (op == -1) || (otherOp == -1) || (op == otherOp);
+
+ String type = getTypeName();
+ String otherType = ins.getTypeName();
+ boolean typeEq = (type == null) || (otherType == null) ||
+ type.equals(otherType);
+
+ return opEq && typeEq;
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterMathInstruction(this);
+ visit.exitMathInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+
+ MathInstruction ins = (MathInstruction) orig;
+ _type = ins._type;
+ _op = ins._op;
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MathInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MethodInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MethodInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MethodInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MethodInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,777 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.lang.reflect.*;
+
+
+/**
+ * <p>An instruction that invokes a method.</p>
+ *
+ * @author Abe White
+ */
+public class MethodInstruction extends Instruction {
+ private int _index = 0;
+
+ MethodInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ }
+
+ int getLength() {
+ if (getOpcode() == Constants.INVOKEINTERFACE) {
+ return super.getLength() + 4;
+ }
+
+ return super.getLength() + 2;
+ }
+
+ public int getLogicalStackChange() {
+ String ret = getMethodReturnName();
+
+ if (ret == null) {
+ return 0;
+ }
+
+ int stack = 0;
+
+ // subtract a stack pos for the this ptr
+ if (getOpcode() != Constants.INVOKESTATIC) {
+ stack--;
+ }
+
+ // and for each arg
+ String[] params = getMethodParamNames();
+
+ for (int i = 0; i < params.length; i++)
+ stack--;
+
+ // add for the return value, if any
+ if (!void.class.getName().equals(ret)) {
+ stack++;
+ }
+
+ return stack;
+ }
+
+ public int getStackChange() {
+ String ret = getMethodReturnName();
+
+ if (ret == null) {
+ return 0;
+ }
+
+ int stack = 0;
+
+ // subtract a stack pos for the this ptr
+ if (getOpcode() != Constants.INVOKESTATIC) {
+ stack--;
+ }
+
+ // and for each arg (2 for longs, doubles)
+ String[] params = getMethodParamNames();
+
+ for (int i = 0; i < params.length; i++, stack--)
+ if (long.class.getName().equals(params[i]) ||
+ double.class.getName().equals(params[i])) {
+ stack--;
+ }
+
+ // add for the return value, if any
+ if (!void.class.getName().equals(ret)) {
+ stack++;
+ }
+
+ if (long.class.getName().equals(ret) ||
+ double.class.getName().equals(ret)) {
+ stack++;
+ }
+
+ return stack;
+ }
+
+ /////////////////////
+ // Method operations
+ /////////////////////
+
+ /**
+ * Return the index in the class {@link ConstantPool} of the
+ * {@link ComplexEntry} describing the method to operate on.
+ */
+ public int getMethodIndex() {
+ return _index;
+ }
+
+ /**
+ * Set the index in the class {@link ConstantPool} of the
+ * {@link ComplexEntry} describing the method to operate on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodIndex(int index) {
+ _index = index;
+
+ return this;
+ }
+
+ /**
+ * Return the method this instruction operates on, or null if not set.
+ */
+ public BCMethod getMethod() {
+ String dec = getMethodDeclarerName();
+
+ if (dec == null) {
+ return null;
+ }
+
+ BCClass bc = getProject().loadClass(dec, getClassLoader());
+ BCMethod[] meths = bc.getMethods(getMethodName(), getMethodParamNames());
+
+ if (meths.length == 0) {
+ return null;
+ }
+
+ return meths[0];
+ }
+
+ /**
+ * Set the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(BCMethod method) {
+ if (method == null) {
+ return setMethodIndex(0);
+ }
+
+ return setMethod(method.getDeclarer().getName(), method.getName(),
+ method.getReturnName(), method.getParamNames());
+ }
+
+ /**
+ * Set the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(Method method) {
+ if (method == null) {
+ return setMethodIndex(0);
+ }
+
+ return setMethod(method.getDeclaringClass(), method.getName(),
+ method.getReturnType(), method.getParameterTypes());
+ }
+
+ /**
+ * Set the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(Constructor method) {
+ if (method == null) {
+ return setMethodIndex(0);
+ }
+
+ setOpcode(Constants.INVOKESPECIAL);
+
+ return setMethod(method.getDeclaringClass(), "<init>", void.class,
+ method.getParameterTypes());
+ }
+
+ /**
+ * Set the method this instruction operates on.
+ *
+ * @param dec the full class name of the method's declaring class
+ * @param name the method name
+ * @param returnType the full class name of the method return type
+ * @param param the full class names of the method param types
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(String dec, String name,
+ String returnType, String[] params) {
+ if ((name == null) && (returnType == null) && (dec == null) &&
+ ((params == null) || (params.length == 0))) {
+ return setMethodIndex(0);
+ }
+
+ if (dec == null) {
+ dec = "";
+ }
+
+ if (name == null) {
+ name = "";
+ }
+
+ if (returnType == null) {
+ returnType = "";
+ }
+
+ if (params == null) {
+ params = new String[0];
+ }
+
+ NameCache cache = getProject().getNameCache();
+ returnType = cache.getInternalForm(returnType, true);
+ dec = cache.getInternalForm(dec, false);
+
+ for (int i = 0; i < params.length; i++)
+ params[i] = cache.getInternalForm(params[i], true);
+
+ String desc = cache.getDescriptor(returnType, params);
+
+ if (getOpcode() == Constants.INVOKEINTERFACE) {
+ return setMethodIndex(getPool()
+ .findInterfaceMethodEntry(dec, name,
+ desc, true));
+ }
+
+ return setMethodIndex(getPool().findMethodEntry(dec, name, desc, true));
+ }
+
+ /**
+ * Set the method this instruction operates on, for methods that are
+ * declared by the current class.
+ *
+ * @param name the method name
+ * @param returnType the full class name of the method return type
+ * @param param the full class names of the method param types
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(String name, String returnType,
+ String[] params) {
+ BCClass owner = getCode().getMethod().getDeclarer();
+
+ return setMethod(owner.getName(), name, returnType, params);
+ }
+
+ /**
+ * Set the method this instruction operates on.
+ *
+ * @param dec the method's declaring class
+ * @param name the method name
+ * @param returnType the class of the method return type
+ * @param param the class of the method param types
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(Class dec, String name,
+ Class returnType, Class[] params) {
+ String decName = (dec == null) ? null : dec.getName();
+ String returnName = (returnType == null) ? null : returnType.getName();
+ String[] paramNames = null;
+
+ if (params != null) {
+ paramNames = new String[params.length];
+
+ for (int i = 0; i < params.length; i++)
+ paramNames[i] = params[i].getName();
+ }
+
+ return setMethod(decName, name, returnName, paramNames);
+ }
+
+ /**
+ * Set the method this instruction operates on, for methods that are
+ * declared by the current class.
+ *
+ * @param name the method name
+ * @param returnType the class of the method return type
+ * @param param the class of the method param types
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(String name, Class returnType,
+ Class[] params) {
+ BCClass owner = getCode().getMethod().getDeclarer();
+ String returnName = (returnType == null) ? null : returnType.getName();
+ String[] paramNames = null;
+
+ if (params != null) {
+ paramNames = new String[params.length];
+
+ for (int i = 0; i < params.length; i++)
+ paramNames[i] = params[i].getName();
+ }
+
+ return setMethod(owner.getName(), name, returnName, paramNames);
+ }
+
+ /**
+ * Set the method this instruction operates on.
+ *
+ * @param dec the method's declaring class
+ * @param name the method name
+ * @param returnType the class of the method return type
+ * @param param the class of the method param types
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(BCClass dec, String name,
+ BCClass returnType, BCClass[] params) {
+ String decName = (dec == null) ? null : dec.getName();
+ String returnName = (returnType == null) ? null : returnType.getName();
+ String[] paramNames = null;
+
+ if (params != null) {
+ paramNames = new String[params.length];
+
+ for (int i = 0; i < params.length; i++)
+ paramNames[i] = params[i].getName();
+ }
+
+ return setMethod(decName, name, returnName, paramNames);
+ }
+
+ /**
+ * Set the method this instruction operates on, for methods that are
+ * declared by the current class.
+ *
+ * @param name the method name
+ * @param returnType the class of the method return type
+ * @param param the class of the method param types
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethod(String name, BCClass returnType,
+ BCClass[] params) {
+ BCClass owner = getCode().getMethod().getDeclarer();
+ String returnName = (returnType == null) ? null : returnType.getName();
+ String[] paramNames = null;
+
+ if (params != null) {
+ paramNames = new String[params.length];
+
+ for (int i = 0; i < params.length; i++)
+ paramNames[i] = params[i].getName();
+ }
+
+ return setMethod(owner.getName(), name, returnName, paramNames);
+ }
+
+ /////////////////////////////////////////
+ // Name, Return, Param, Owner operations
+ /////////////////////////////////////////
+
+ /**
+ * Return the name of the method this instruction operates on, or null
+ * if not set.
+ */
+ public String getMethodName() {
+ int index = getMethodIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String name = entry.getNameAndTypeEntry().getNameEntry().getValue();
+
+ if (name.length() == 0) {
+ return null;
+ }
+
+ return name;
+ }
+
+ /**
+ * Set the name of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodName(String name) {
+ return setMethod(getMethodDeclarerName(), name, getMethodReturnName(),
+ getMethodParamNames());
+ }
+
+ /**
+ * Return the return type of the method this instruction operates on,
+ * or null if not set.
+ */
+ public String getMethodReturnName() {
+ int index = getMethodIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String desc = entry.getNameAndTypeEntry().getDescriptorEntry().getValue();
+ NameCache cache = getProject().getNameCache();
+ String name = cache.getExternalForm(cache.getDescriptorReturnName(desc),
+ false);
+
+ if (name.length() == 0) {
+ return null;
+ }
+
+ return name;
+ }
+
+ /**
+ * Return the return type of the method this instruction operates on,
+ * or null if not set.
+ */
+ public Class getMethodReturnType() {
+ String type = getMethodReturnName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return Strings.toClass(type, getClassLoader());
+ }
+
+ /**
+ * Return the return type of the method this instruction operates on,
+ * or null if not set.
+ */
+ public BCClass getMethodReturnBC() {
+ String type = getMethodReturnName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return getProject().loadClass(type, getClassLoader());
+ }
+
+ /**
+ * Set the return type of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodReturn(String type) {
+ return setMethod(getMethodDeclarerName(), getMethodName(), type,
+ getMethodParamNames());
+ }
+
+ /**
+ * Set the return type of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodReturn(Class type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setMethodReturn(name);
+ }
+
+ /**
+ * Set the return type of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodReturn(BCClass type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setMethodReturn(name);
+ }
+
+ /**
+ * Return the param types of the method this instruction operates on,
+ * or empty array if none.
+ */
+ public String[] getMethodParamNames() {
+ int index = getMethodIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String desc = entry.getNameAndTypeEntry().getDescriptorEntry().getValue();
+ NameCache cache = getProject().getNameCache();
+ String[] names = cache.getDescriptorParamNames(desc);
+
+ for (int i = 0; i < names.length; i++)
+ names[i] = cache.getExternalForm(names[i], false);
+
+ return names;
+ }
+
+ /**
+ * Return the param types of the method this instruction operates on,
+ * or empty array if none.
+ */
+ public Class[] getMethodParamTypes() {
+ String[] paramNames = getMethodParamNames();
+ Class[] params = new Class[paramNames.length];
+
+ for (int i = 0; i < paramNames.length; i++)
+ params[i] = Strings.toClass(paramNames[i], getClassLoader());
+
+ return params;
+ }
+
+ /**
+ * Return the param types of the method this instruction operates on,
+ * or empty array if none.
+ */
+ public BCClass[] getMethodParamBCs() {
+ String[] paramNames = getMethodParamNames();
+ BCClass[] params = new BCClass[paramNames.length];
+
+ for (int i = 0; i < paramNames.length; i++)
+ params[i] = getProject().loadClass(paramNames[i], getClassLoader());
+
+ return params;
+ }
+
+ /**
+ * Set the param types of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodParams(String[] types) {
+ return setMethod(getMethodDeclarerName(), getMethodName(),
+ getMethodReturnName(), types);
+ }
+
+ /**
+ * Set the param types of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public void setMethodParams(Class[] types) {
+ if (types == null) {
+ setMethodParams((String[]) null);
+ } else {
+ String[] names = new String[types.length];
+
+ for (int i = 0; i < types.length; i++)
+ names[i] = types[i].getName();
+
+ setMethodParams(names);
+ }
+ }
+
+ /**
+ * Set the param types of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public void setMethodParams(BCClass[] types) {
+ if (types == null) {
+ setMethodParams((String[]) null);
+ } else {
+ String[] names = new String[types.length];
+
+ for (int i = 0; i < types.length; i++)
+ names[i] = types[i].getName();
+
+ setMethodParams(names);
+ }
+ }
+
+ /**
+ * Return the declaring type of the method this instruction operates on,
+ * or null if not set.
+ */
+ public String getMethodDeclarerName() {
+ int index = getMethodIndex();
+
+ if (index == 0) {
+ return null;
+ }
+
+ ComplexEntry entry = (ComplexEntry) getPool().getEntry(index);
+ String name = getProject().getNameCache()
+ .getExternalForm(entry.getClassEntry().getNameEntry()
+ .getValue(), false);
+
+ if (name.length() == 0) {
+ return null;
+ }
+
+ return name;
+ }
+
+ /**
+ * Return the declaring type of the method this instruction operates on,
+ * or null if not set.
+ */
+ public Class getMethodDeclarerType() {
+ String type = getMethodDeclarerName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return Strings.toClass(type, getClassLoader());
+ }
+
+ /**
+ * Return the declaring type of the method this instruction operates on,
+ * or null if not set.
+ */
+ public BCClass getMethodDeclarerBC() {
+ String type = getMethodDeclarerName();
+
+ if (type == null) {
+ return null;
+ }
+
+ return getProject().loadClass(type, getClassLoader());
+ }
+
+ /**
+ * Set the declaring type of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodDeclarer(String type) {
+ return setMethod(type, getMethodName(), getMethodReturnName(),
+ getMethodParamNames());
+ }
+
+ /**
+ * Set the declaring type of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodDeclarer(Class type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setMethodDeclarer(name);
+ }
+
+ /**
+ * Set the declaring type of the method this instruction operates on.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MethodInstruction setMethodDeclarer(BCClass type) {
+ String name = null;
+
+ if (type != null) {
+ name = type.getName();
+ }
+
+ return setMethodDeclarer(name);
+ }
+
+ /**
+ * MethodInstructions are equal if the method they reference is the same,
+ * or if the method of either is unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MethodInstruction)) {
+ return false;
+ }
+
+ if (!super.equalsInstruction(other)) {
+ return false;
+ }
+
+ MethodInstruction ins = (MethodInstruction) other;
+
+ String s1 = getMethodName();
+ String s2 = ins.getMethodName();
+
+ if (!((s1 == null) || (s2 == null) || s1.equals(s2))) {
+ return false;
+ }
+
+ s1 = getMethodReturnName();
+ s2 = ins.getMethodReturnName();
+
+ if (!((s1 == null) || (s2 == null) || s1.equals(s2))) {
+ return false;
+ }
+
+ s1 = getMethodDeclarerName();
+ s2 = ins.getMethodDeclarerName();
+
+ if (!((s1 == null) || (s2 == null) || s1.equals(s2))) {
+ return false;
+ }
+
+ String[] p1 = getMethodParamNames();
+ String[] p2 = ins.getMethodParamNames();
+
+ if (!((p1.length == 0) || (p2.length == 0) || (p1.length == p2.length))) {
+ return false;
+ }
+
+ for (int i = 0; i < p1.length; i++)
+ if (!((p1[i] == null) || (p2[i] == null) || p1[i].equals(p2[i]))) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterMethodInstruction(this);
+ visit.exitMethodInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+
+ MethodInstruction ins = (MethodInstruction) orig;
+ setMethod(ins.getMethodDeclarerName(), ins.getMethodName(),
+ ins.getMethodReturnName(), ins.getMethodParamNames());
+ }
+
+ void read(DataInput in) throws IOException {
+ super.read(in);
+ setMethodIndex(in.readUnsignedShort());
+
+ if (getOpcode() == Constants.INVOKEINTERFACE) {
+ in.readByte();
+ in.readByte();
+ }
+ }
+
+ void write(DataOutput out) throws IOException {
+ super.write(out);
+ out.writeShort(getMethodIndex());
+
+ if (getOpcode() == Constants.INVOKEINTERFACE) {
+ String[] args = getMethodParamNames();
+ int count = 1;
+
+ for (int i = 0; i < args.length; i++, count++)
+ if (long.class.getName().equals(args[i]) ||
+ double.class.getName().equals(args[i])) {
+ count++;
+ }
+
+ out.writeByte(count);
+ out.writeByte(0);
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MethodInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorEnterInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorEnterInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorEnterInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorEnterInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ * <p>The <code>monitorenter</code> instruction.</p>
+ *
+ * @author Abe White
+ */
+public class MonitorEnterInstruction extends MonitorInstruction {
+ MonitorEnterInstruction(Code owner) {
+ super(owner, Constants.MONITORENTER);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterMonitorEnterInstruction(this);
+ visit.exitMonitorEnterInstruction(this);
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorEnterInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorExitInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorExitInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorExitInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorExitInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ * <p>The <code>monitorexit</code> instruction.</p>
+ *
+ * @author Abe White
+ */
+public class MonitorExitInstruction extends MonitorInstruction {
+ MonitorExitInstruction(Code owner) {
+ super(owner, Constants.MONITOREXIT);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterMonitorExitInstruction(this);
+ visit.exitMonitorExitInstruction(this);
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorExitInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+
+/**
+ * <p>A synchronization instruction.</p>
+ *
+ * @author Abe White
+ */
+public abstract class MonitorInstruction extends Instruction {
+ MonitorInstruction(Code owner, int opcode) {
+ super(owner, opcode);
+ }
+
+ public int getLogicalStackChange() {
+ return getStackChange();
+ }
+
+ public int getStackChange() {
+ return -1;
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MonitorInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MultiANewArrayInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MultiANewArrayInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MultiANewArrayInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MultiANewArrayInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ * <p>The <code>multianewarray</code> instruction, which creates a new
+ * multi-dimensional array.</p>
+ *
+ * @author Abe White
+ */
+public class MultiANewArrayInstruction extends ClassInstruction {
+ private int _dims = -1;
+
+ MultiANewArrayInstruction(Code owner) {
+ super(owner, Constants.MULTIANEWARRAY);
+ }
+
+ int getLength() {
+ return super.getLength() + 1;
+ }
+
+ public int getLogicalStackChange() {
+ return getStackChange();
+ }
+
+ public int getStackChange() {
+ return -(getDimensions()) + 1;
+ }
+
+ /**
+ * Return the dimensions of the array, or -1 if not set.
+ */
+ public int getDimensions() {
+ return _dims;
+ }
+
+ /**
+ * Set the dimensions of the array.
+ *
+ * @return this instruction, for method chaining
+ */
+ public MultiANewArrayInstruction setDimensions(int dims) {
+ _dims = dims;
+
+ return this;
+ }
+
+ /**
+ * Two MultiANewArray instructions are equal if they have the same
+ * type and dimensions, or if the type and dimensions of either
+ * is unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MultiANewArrayInstruction)) {
+ return false;
+ }
+
+ if (!super.equalsInstruction(other)) {
+ return false;
+ }
+
+ MultiANewArrayInstruction ins = (MultiANewArrayInstruction) other;
+ int dims = getDimensions();
+ int otherDims = ins.getDimensions();
+
+ return (dims == -1) || (otherDims == -1) || (dims == otherDims);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterMultiANewArrayInstruction(this);
+ visit.exitMultiANewArrayInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+ setDimensions(((MultiANewArrayInstruction) orig).getDimensions());
+ }
+
+ void read(DataInput in) throws IOException {
+ super.read(in);
+ setDimensions(in.readUnsignedByte());
+ }
+
+ void write(DataOutput out) throws IOException {
+ super.write(out);
+ out.writeByte(getDimensions());
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/MultiANewArrayInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NameCache.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NameCache.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NameCache.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NameCache.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import java.util.*;
+
+
+/**
+ * <p>Caching and conversion of names in both internal and external form.</p>
+ *
+ * @author Abe White
+ */
+public class NameCache {
+ static final Object[][] _codes = new Object[][] {
+ { byte.class, "B" },
+ { char.class, "C" },
+ { double.class, "D" },
+ { float.class, "F" },
+ { int.class, "I" },
+ { long.class, "J" },
+ { short.class, "S" },
+ { boolean.class, "Z" },
+ { void.class, "V" },
+ };
+
+ // caches of internal and external forms of strings
+ private final Map _internal = new HashMap();
+ private final Map _internalDescriptor = new HashMap();
+ private final Map _external = new HashMap();
+ private final Map _externalHuman = new HashMap();
+
+ /**
+ * Converts the given class name to its internal form.
+ *
+ * @param className the name to convert
+ * @param descriptor true if the name is to be used for a descriptor
+ * section -- the difference seems to be that for
+ * descriptors, non-primitives are prefixed with 'L'
+ * and ended with ';'
+ */
+ public String getInternalForm(String className, boolean descriptor) {
+ if ((className == null) || (className.length() == 0)) {
+ return className;
+ }
+
+ Map cache = (descriptor) ? _internalDescriptor : _internal;
+ String cached = (String) cache.get(className);
+
+ if (cached != null) {
+ return cached;
+ }
+
+ String ret = getInternalFormInternal(className, descriptor);
+ cache.put(className, ret);
+
+ return ret;
+ }
+
+ /**
+ * @see #getInternalForm
+ */
+ private String getInternalFormInternal(String cls, boolean descriptor) {
+ // handle array types, whether already in internal form or not
+ StringBuffer prefix = new StringBuffer();
+
+ while (true) {
+ if (cls.endsWith("[]")) {
+ prefix.append("[");
+ cls = cls.substring(0, cls.length() - 2);
+ } else if (cls.startsWith("[")) {
+ prefix.append("[");
+ cls = cls.substring(1);
+ } else {
+ break;
+ }
+ }
+
+ // handle primitive array types
+ for (int i = 0; i < _codes.length; i++)
+ if (cls.equals(_codes[i][1].toString()) ||
+ cls.equals(_codes[i][0].toString())) {
+ return prefix.append(_codes[i][1]).toString();
+ }
+
+ // if in descriptor form, strip leading 'L' and trailing ';'
+ if (cls.startsWith("L") && cls.endsWith(";")) {
+ cls = cls.substring(1, cls.length() - 1);
+ }
+
+ // non-primitive; make sure we don't prefix method descriptors with 'L'
+ cls = cls.replace('.', '/');
+
+ if ((descriptor || (prefix.length() > 0)) && (cls.charAt(0) != '(')) {
+ return prefix.append("L").append(cls).append(";").toString();
+ }
+
+ return prefix.append(cls).toString();
+ }
+
+ /**
+ * Given the internal name of the class, return the 'normal' java name.
+ *
+ * @param internalName the internal name being used
+ * @param humanReadable if the returned name should be in human-readable
+ * form, rather than a form suitable for a
+ * {@link Class#forName} call -- the difference
+ * lies in the handling of arrays
+ */
+ public String getExternalForm(String internalName, boolean humanReadable) {
+ if ((internalName == null) || (internalName.length() == 0)) {
+ return internalName;
+ }
+
+ Map cache = (humanReadable) ? _externalHuman : _external;
+ String cached = (String) cache.get(internalName);
+
+ if (cached != null) {
+ return cached;
+ }
+
+ String ret = getExternalFormInternal(internalName, humanReadable);
+ cache.put(internalName, ret);
+
+ return ret;
+ }
+
+ /**
+ * @see #getExternalForm
+ */
+ private String getExternalFormInternal(String intern, boolean humanReadable) {
+ if (!humanReadable) {
+ // check against primitives
+ for (int i = 0; i < _codes.length; i++) {
+ if (intern.equals(_codes[i][1].toString())) {
+ return _codes[i][0].toString();
+ }
+
+ if (intern.equals(_codes[i][0].toString())) {
+ return intern;
+ }
+ }
+
+ intern = getInternalForm(intern, false);
+
+ return intern.replace('/', '.');
+ }
+
+ // handle arrays
+ StringBuffer postfix = new StringBuffer(2);
+
+ while (intern.startsWith("[")) {
+ intern = intern.substring(1);
+ postfix.append("[]");
+ }
+
+ // strip off leading 'L' and trailing ';'
+ if (intern.endsWith(";")) {
+ intern = intern.substring(1, intern.length() - 1);
+ }
+
+ // check primitives
+ for (int i = 0; i < _codes.length; i++)
+ if (intern.equals(_codes[i][1].toString())) {
+ return _codes[i][0].toString() + postfix;
+ }
+
+ return intern.replace('/', '.') + postfix;
+ }
+
+ /**
+ * Construct a method descriptor from the given return and parameter
+ * types, which will be converted to internal form.
+ */
+ public String getDescriptor(String returnType, String[] paramTypes) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("(");
+
+ if (paramTypes != null) {
+ for (int i = 0; i < paramTypes.length; i++) {
+ if (paramTypes[i] == null) {
+ throw new NullPointerException("paramTypes[" + i +
+ "] = null");
+ }
+
+ buf.append(getInternalForm(paramTypes[i], true));
+ }
+ }
+
+ buf.append(")");
+
+ if (returnType == null) {
+ throw new NullPointerException("returnType = null");
+ }
+
+ buf.append(getInternalForm(returnType, true));
+
+ return buf.toString();
+ }
+
+ /**
+ * Return the return type, in internal form, for the given method
+ * descriptor string.
+ */
+ public String getDescriptorReturnName(String descriptor) {
+ int index = descriptor.indexOf(')');
+
+ if (index == -1) {
+ return "";
+ }
+
+ return descriptor.substring(descriptor.indexOf(')') + 1);
+ }
+
+ /**
+ * Return the parameter types, in internal form, for the given method
+ * descriptor string.
+ */
+ public String[] getDescriptorParamNames(String descriptor) {
+ if ((descriptor == null) || (descriptor.length() == 0)) {
+ return new String[0];
+ }
+
+ int index = descriptor.indexOf(')');
+
+ if (index == -1) {
+ return new String[0];
+ }
+
+ // get rid of the parens and the return type
+ descriptor = descriptor.substring(1, index);
+
+ // break the param string into individual params
+ List tokens = new LinkedList();
+
+ while (descriptor.length() > 0) {
+ index = 0;
+
+ // skip the '[' up to the first letter code
+ while (!Character.isLetter(descriptor.charAt(index)))
+ index++;
+
+ // non-primitives always start with 'L' and end with ';'
+ if (descriptor.charAt(index) == 'L') {
+ index = descriptor.indexOf(';');
+ }
+
+ tokens.add(descriptor.substring(0, index + 1));
+ descriptor = descriptor.substring(index + 1);
+ }
+
+ return (String[]) tokens.toArray(new String[tokens.size()]);
+ }
+
+ /**
+ * Return the component type name for the given array type, or null
+ * if the given string does not represent an array type name. The name
+ * given should be in proper {@link Class#forName} form.
+ */
+ public String getComponentName(String name) {
+ if ((name == null) || !name.startsWith("[")) {
+ return null;
+ }
+
+ name = name.substring(1);
+
+ if (!name.startsWith("[") && name.endsWith(";")) {
+ name = name.substring(1, name.length() - 1);
+ }
+
+ // will convert primitive type codes to names
+ return getExternalForm(name, false);
+ }
+
+ /**
+ * Clear the cache.
+ */
+ public void clear() {
+ _internal.clear();
+ _internalDescriptor.clear();
+ _external.clear();
+ _externalHuman.clear();
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NameCache.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NewArrayInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NewArrayInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NewArrayInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NewArrayInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * <p>The <code>newarray</code> instruction, which is used to create new
+ * arrays of primitive types.</p>
+ *
+ * @author Abe White
+ */
+public class NewArrayInstruction extends TypedInstruction {
+ private static final Class[][] _mappings = new Class[][] {
+ { void.class, int.class },
+ { Object.class, int.class },
+ };
+ private int _code = -1;
+
+ NewArrayInstruction(Code owner) {
+ super(owner, Constants.NEWARRAY);
+ }
+
+ int getLength() {
+ return super.getLength() + 1;
+ }
+
+ public String getTypeName() {
+ switch (getTypeCode()) {
+ case Constants.ARRAY_BOOLEAN:
+ return boolean.class.getName();
+
+ case Constants.ARRAY_CHAR:
+ return char.class.getName();
+
+ case Constants.ARRAY_FLOAT:
+ return float.class.getName();
+
+ case Constants.ARRAY_DOUBLE:
+ return double.class.getName();
+
+ case Constants.ARRAY_BYTE:
+ return byte.class.getName();
+
+ case Constants.ARRAY_SHORT:
+ return short.class.getName();
+
+ case Constants.ARRAY_INT:
+ return int.class.getName();
+
+ case Constants.ARRAY_LONG:
+ return long.class.getName();
+
+ default:
+ return null;
+ }
+ }
+
+ public TypedInstruction setType(String type) {
+ type = mapType(type, _mappings, true);
+
+ if (type == null) {
+ return setTypeCode(-1);
+ }
+
+ switch (type.charAt(0)) {
+ case 'b':
+
+ if (boolean.class.getName().equals(type)) {
+ return setTypeCode(Constants.ARRAY_BOOLEAN);
+ }
+
+ return setTypeCode(Constants.ARRAY_BYTE);
+
+ case 'c':
+ return setTypeCode(Constants.ARRAY_CHAR);
+
+ case 'f':
+ return setTypeCode(Constants.ARRAY_FLOAT);
+
+ case 'd':
+ return setTypeCode(Constants.ARRAY_DOUBLE);
+
+ case 's':
+ return setTypeCode(Constants.ARRAY_SHORT);
+
+ case 'i':
+ return setTypeCode(Constants.ARRAY_INT);
+
+ case 'l':
+ return setTypeCode(Constants.ARRAY_LONG);
+
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Return the array code used in the lowlevel bytecode, or -1 if unset.
+ */
+ public int getTypeCode() {
+ return _code;
+ }
+
+ /**
+ * Set the array code used in the lowlevel bytecode.
+ *
+ * @return this instruction, for method chaining
+ */
+ public NewArrayInstruction setTypeCode(int code) {
+ _code = code;
+
+ return this;
+ }
+
+ /**
+ * NewArray instructions are equal if the array type is the same,
+ * of if the array type of either is unset.
+ */
+ public boolean equalsInstruction(Instruction other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof NewArrayInstruction)) {
+ return false;
+ }
+
+ NewArrayInstruction ins = (NewArrayInstruction) other;
+ int code = getTypeCode();
+ int otherCode = ins.getTypeCode();
+
+ return (code == -1) || (otherCode == -1) || (code == otherCode);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterNewArrayInstruction(this);
+ visit.exitNewArrayInstruction(this);
+ }
+
+ void read(Instruction orig) {
+ super.read(orig);
+ setTypeCode(((NewArrayInstruction) orig).getTypeCode());
+ }
+
+ void read(DataInput in) throws IOException {
+ super.read(in);
+ setTypeCode(in.readUnsignedByte());
+ }
+
+ void write(DataOutput out) throws IOException {
+ super.write(out);
+ out.writeByte(getTypeCode());
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/NewArrayInstruction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ObjectState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ObjectState.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ObjectState.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ObjectState.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import java.util.*;
+
+
+/**
+ * <p>State implementing the behavior of an object type.</p>
+ *
+ * @author Abe White
+ */
+class ObjectState extends State {
+ private final ConstantPool _pool = new ConstantPool();
+ private final NameCache _names;
+ private int _index = 0;
+ private int _superclassIndex = 0;
+ private int _magic = Constants.VALID_MAGIC;
+ private int _major = Constants.MAJOR_VERSION;
+ private int _minor = Constants.MINOR_VERSION;
+ private int _access = Constants.ACCESS_PUBLIC | Constants.ACCESS_SUPER;
+ private final Collection _interfaces = new HashSet();
+ private final Collection _fields = new LinkedList();
+ private final Collection _methods = new LinkedList();
+ private final Collection _attributes = new LinkedList();
+
+ public ObjectState(NameCache names) {
+ _names = names;
+ }
+
+ public int getMagic() {
+ return _magic;
+ }
+
+ public void setMagic(int magic) {
+ _magic = magic;
+ }
+
+ public int getMajorVersion() {
+ return _major;
+ }
+
+ public void setMajorVersion(int major) {
+ _major = major;
+ }
+
+ public int getMinorVersion() {
+ return _minor;
+ }
+
+ public void setMinorVersion(int minor) {
+ _minor = minor;
+ }
+
+ public int getAccessFlags() {
+ return _access;
+ }
+
+ public void setAccessFlags(int access) {
+ _access = access;
+ }
+
+ public int getIndex() {
+ return _index;
+ }
+
+ public void setIndex(int index) {
+ _index = index;
+ }
+
+ public int getSuperclassIndex() {
+ return _superclassIndex;
+ }
+
+ public void setSuperclassIndex(int index) {
+ _superclassIndex = index;
+ }
+
+ public Collection getInterfacesHolder() {
+ return _interfaces;
+ }
+
+ public Collection getFieldsHolder() {
+ return _fields;
+ }
+
+ public Collection getMethodsHolder() {
+ return _methods;
+ }
+
+ public Collection getAttributesHolder() {
+ return _attributes;
+ }
+
+ public ConstantPool getPool() {
+ return _pool;
+ }
+
+ public String getName() {
+ if (_index == 0) {
+ return null;
+ }
+
+ return _names.getExternalForm(((ClassEntry) _pool.getEntry(_index)).getNameEntry()
+ .getValue(), false);
+ }
+
+ public String getSuperclassName() {
+ if (_superclassIndex == 0) {
+ return null;
+ }
+
+ return _names.getExternalForm(((ClassEntry) _pool.getEntry(
+ _superclassIndex)).getNameEntry().getValue(), false);
+ }
+
+ public String getComponentName() {
+ return null;
+ }
+
+ public boolean isPrimitive() {
+ return false;
+ }
+
+ public boolean isArray() {
+ return false;
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ObjectState.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PrimitiveState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PrimitiveState.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PrimitiveState.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PrimitiveState.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package serp.bytecode;
+
+import serp.bytecode.lowlevel.*;
+
+import java.util.*;
+
+
+/**
+ * <p>State implementing the behavior of a primitive class.</p>
+ *
+ * @author Abe White
+ */
+class PrimitiveState extends State {
+ private final Class _type;
+ private final NameCache _names;
+
+ public PrimitiveState(Class type, NameCache names) {
+ _type = type;
+ _names = names;
+ }
+
+ public int getMagic() {
+ return Constants.VALID_MAGIC;
+ }
+
+ public int getMajorVersion() {
+ return Constants.MAJOR_VERSION;
+ }
+
+ public int getMinorVersion() {
+ return Constants.MINOR_VERSION;
+ }
+
+ public int getAccessFlags() {
+ return Constants.ACCESS_PUBLIC | Constants.ACCESS_FINAL;
+ }
+
+ public int getIndex() {
+ return 0;
+ }
+
+ public int getSuperclassIndex() {
+ return 0;
+ }
+
+ public Collection getInterfacesHolder() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public Collection getFieldsHolder() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public Collection getMethodsHolder() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public Collection getAttributesHolder() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public String getName() {
+ return _names.getExternalForm(_type.getName(), false);
+ }
+
+ public String getSuperclassName() {
+ return null;
+ }
+
+ public String getComponentName() {
+ return null;
+ }
+
+ public boolean isPrimitive() {
+ return true;
+ }
+
+ public boolean isArray() {
+ return false;
+ }
+}
Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PrimitiveState.java
------------------------------------------------------------------------------
svn:executable = *