diff options
Diffstat (limited to 'src/fjbg/ch/epfl/lamp/fjbg/JMethod.java')
-rw-r--r-- | src/fjbg/ch/epfl/lamp/fjbg/JMethod.java | 133 |
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; + } +} |