gen.setProceedHandler(h, proceedName);
}
+ /**
+ * Prepares to use $proceed() representing a private/super's method.
+ * If the return type of $proceed() is void, null is pushed on the
+ * stack. This method is for methods invoked by INVOKESPECIAL.
+ *
+ * @param target an expression specifying the target object.
+ * if null, "this" is the target.
+ * @param classname the class name declaring the method.
+ * @param methodname the method name.
+ * @param descriptor the method descriptor.
+ */
+ public void recordSpecialProceed(String target, String classname,
+ String methodname, String descriptor)
+ throws CompileError
+ {
+ Parser p = new Parser(new Lex(target));
+ final ASTree texpr = p.parseExpression(stable);
+ final String cname = classname;
+ final String method = methodname;
+ final String desc = descriptor;
+
+ ProceedHandler h = new ProceedHandler() {
+ public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
+ throws CompileError
+ {
+ gen.compileInvokeSpecial(texpr,
+ cname, method, desc, args);
+ }
+ };
+
+ gen.setProceedHandler(h, proceedName);
+ }
+
/**
* Prepares to use $proceed().
*/
}
/*
- public int atMethodArgsLength(ASTList args) {
+ public int getMethodArgsLength(ASTList args) {
if (!isParamListName(args))
- return super.atMethodArgsLength(args);
+ return super.getMethodArgsLength(args);
return paramTypeList.length;
}
*/
- public int atMethodArgsLength(ASTList args) {
+ public int getMethodArgsLength(ASTList args) {
String pname = paramListName;
int n = 0;
while (args != null) {
}
*/
+ /* called by Javac#recordSpecialProceed().
+ */
+ void compileInvokeSpecial(ASTree target, String classname,
+ String methodname, String descriptor,
+ ASTList args)
+ throws CompileError
+ {
+ target.accept(this);
+ int nargs = getMethodArgsLength(args);
+ atMethodArgs(args, new int[nargs], new int[nargs],
+ new String[nargs]);
+ bytecode.addInvokespecial(classname, methodname, descriptor);
+ setReturnType(descriptor, false, false);
+ addNullIfVoid();
+ }
+
/*
* Makes it valid to write "return <expr>;" for a void method.
*/
int aload0pos)
throws CompileError
{
- int nargs = atMethodArgsLength(args);
+ int nargs = getMethodArgsLength(args);
int[] types = new int[nargs];
int[] dims = new int[nargs];
String[] cnames = new String[nargs];
setReturnType(desc, isStatic, popTarget);
}
- public int atMethodArgsLength(ASTList args) {
+ public int getMethodArgsLength(ASTList args) {
return ASTList.length(args);
}
}
}
- private void setReturnType(String desc, boolean isStatic,
- boolean popTarget)
+ void setReturnType(String desc, boolean isStatic, boolean popTarget)
throws CompileError
{
int i = desc.indexOf(')');
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
throws CompileError
{
- if (gen.atMethodArgsLength(args) != 1)
+ if (gen.getMethodArgsLength(args) != 1)
throw new CompileError(Javac.proceedName
+ "() cannot take more than one parameter "
+ "for cast");
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
throws CompileError
{
- if (gen.atMethodArgsLength(args) != 1)
+ if (gen.getMethodArgsLength(args) != 1)
throw new CompileError(Javac.proceedName
+ "() cannot take more than one parameter "
+ "for field writing");
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
throws CompileError
{
- if (gen.atMethodArgsLength(args) != 1)
+ if (gen.getMethodArgsLength(args) != 1)
throw new CompileError(Javac.proceedName
+ "() cannot take more than one parameter "
+ "for instanceof");
int retVar = jc.recordReturnType(retType, true);
if (c == INVOKESTATIC)
jc.recordStaticProceed(classname, methodname);
+ else if (c == INVOKESPECIAL)
+ jc.recordSpecialProceed(Javac.param0Name, classname,
+ methodname, signature);
else
jc.recordProceed(Javac.param0Name, methodname);