return this.arguments.length - 3 - ((extraArgument == null) ? 0 : 1);
// Advice.countOnes(extraArgumentFlags);
}
private void generateProceedMethod(ClassScope classScope, ClassFile classFile) {
MethodBinding binding = proceedMethodBinding;
classFile.generateMethodInfoHeader(binding);
int methodAttributeOffset = classFile.contentsOffset;
int attributeNumber = classFile.generateMethodInfoAttribute(binding, false, AstUtil.getAjSyntheticAttribute());
int codeAttributeOffset = classFile.contentsOffset;
classFile.generateCodeAttributeHeader();
CodeStream codeStream = classFile.codeStream;
codeStream.reset(this, classFile);
// push the closure
int nargs = binding.parameters.length;
int closureIndex = 0;
for (int i = 0; i < nargs - 1; i++) {
closureIndex += AstUtil.slotsNeeded(binding.parameters[i]);
}
codeStream.aload(closureIndex);
// build the Object[]
codeStream.generateInlinedValue(nargs - 1);
codeStream.newArray(new ArrayBinding(classScope.getType(TypeConstants.JAVA_LANG_OBJECT,
TypeConstants.JAVA_LANG_OBJECT.length), 1, classScope.environment()));
int index = 0;
for (int i = 0; i < nargs - 1; i++) {
TypeBinding type = binding.parameters[i];
codeStream.dup();
codeStream.generateInlinedValue(i);
codeStream.load(type, index);
index += AstUtil.slotsNeeded(type);
if (type.isBaseType()) {
codeStream.invokestatic(AjTypeConstants.getConversionMethodToObject(classScope, type));
}
codeStream.aastore();
}
// call run
ReferenceBinding closureType = (ReferenceBinding) binding.parameters[nargs - 1];
MethodBinding runMethod = closureType.getMethods("run".toCharArray())[0];
codeStream.invokevirtual(runMethod);
TypeBinding returnType = binding.returnType;
if (returnType.isBaseType()) {
codeStream.invokestatic(AjTypeConstants.getConversionMethodFromObject(classScope, returnType));