summaryrefslogtreecommitdiff
path: root/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/fjbg/ch/epfl/lamp/fjbg/JMethod.java')
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JMethod.java133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
new file mode 100644
index 0000000000..dbddf6547d
--- /dev/null
+++ b/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
@@ -0,0 +1,133 @@
+// $Id$
+
+package ch.epfl.lamp.fjbg;
+
+import java.util.LinkedList;
+import java.util.Iterator;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * Representation of a Java method.
+ *
+ * @version 1.0
+ * @author Michel Schinz
+ */
+
+public class JMethod extends JFieldOrMethod {
+ public final static String CLASS_CONSTRUCTOR_NAME = "<clinit>";
+ public final static String INSTANCE_CONSTRUCTOR_NAME = "<init>";
+
+ protected final JCode code;
+ protected final String[] argNames;
+
+ protected final LinkedList/*<JLocalVariable>*/ localVariables =
+ new LinkedList();
+ protected int localVariableIndex = 0;
+
+ protected JMethod(FJBGContext context,
+ JClass owner,
+ int accessFlags,
+ String name,
+ JType returnType,
+ JType[] argTypes,
+ String[] argNames) {
+ super(context,
+ owner,
+ accessFlags,
+ name,
+ new JMethodType(returnType, argTypes));
+ this.argNames = argNames;
+
+ assert argTypes.length == argNames.length;
+
+ if (isAbstract() || isNative()) {
+ code = null;
+ } else {
+ JConstantPool pool = owner.getConstantPool();
+ code = context.JCode(owner, this);
+ addAttribute(context.JCodeAttribute(owner, this));
+
+ if (!isStatic())
+ addNewLocalVariable(owner.getType(), "this");
+
+ for (int i = 0; i < argTypes.length; ++i)
+ addNewLocalVariable(argTypes[i], argNames[i]);
+ }
+ }
+
+ protected JMethod(FJBGContext context,
+ JClass owner,
+ DataInputStream stream)
+ throws IOException {
+ super(context, owner, stream);
+
+ // Fetch code from the attributes.
+ setCode: {
+ Iterator attrIt = attributes.iterator();
+ while (attrIt.hasNext()) {
+ Object attr = attrIt.next();
+ if (attr instanceof JCodeAttribute) {
+ code = ((JCodeAttribute)attr).code;
+ break setCode;
+ }
+ }
+ code = null;
+ }
+ argNames = null; // TODO get from attribute
+ }
+
+ public void freeze() throws JCode.OffsetTooBigException {
+ if (code != null) code.freeze();
+ super.freeze();
+ }
+
+ public JType getReturnType() {
+ return ((JMethodType)type).getReturnType();
+ }
+
+ public JType[] getArgumentTypes() {
+ return ((JMethodType)type).getArgumentTypes();
+ }
+
+ public String[] getArgumentNames() {
+ return argNames;
+ }
+
+ public JCode getCode() {
+ assert !isAbstract();
+ return code;
+ }
+
+ public JCodeIterator codeIterator() {
+ return new JCodeIterator(code);
+ }
+
+ // Local variables
+ // FIXME : find a better management method for local variables
+ public JLocalVariable addNewLocalVariable(JType type, String name) {
+ assert !frozen;
+ JLocalVariable var =
+ context.JLocalVariable(this, type, name, localVariableIndex);
+ localVariableIndex += type.getSize();
+ localVariables.add(var);
+ return var;
+ }
+
+ public JLocalVariable getLocalVariable(int index) {
+ for (int i = 0; i < localVariables.size(); i++) {
+ if (((JLocalVariable)localVariables.get(i)).index == index)
+ return (JLocalVariable)localVariables.get(i);
+ }
+ return null;
+ }
+
+ public JLocalVariable[] getLocalVariables() {
+ return (JLocalVariable[])localVariables
+ .toArray(new JLocalVariable[localVariables.size()]);
+ }
+
+ public int getMaxLocals() {
+ return localVariableIndex;
+ }
+}