|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.mdr.handlers.gen;
import org.netbeans.mdr.storagemodel.StorableClass;
import org.netbeans.mdr.storagemodel.StorableObject;
import org.netbeans.mdr.util.DebugException;
import org.netbeans.mdr.util.Logger;
import org.netbeans.mdr.util.MOFConstants;
import javax.jmi.model.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
/**
*
* @author Martin Matula, Dusan Balek
* @version
*/
class ClassGenerator extends FeaturedGenerator {
private static final String M_CREATE_NAME = "Create"; //NOI18N
private static final String M_CREATE_DESC = "([Ljava/lang/Object;)"; //NOI18N
private static final String M_CREATE_TYPE = "Ljavax/jmi/reflect/RefObject;"; //NOI18N
private static final String M_STRUCT_NAME = "Struct"; //NOI18N
private static final String M_STRUCT_DESC = "(Ljava/lang/String;[Ljava/lang/Object;)"; //NOI18N
private static final String M_STRUCT_TYPE = "Ljavax/jmi/reflect/RefStruct;"; //NOI18N
private static final String M_CREATE_DISPATCH_NAME = "_createInstance"; //NOI18N
ClassGenerator(String name, Class ifc, Class handler, StorableClass storable, Class custom) {
super(name, ifc, handler, storable, custom);
dispatchMethods.put("_createStruct", new HashMap()); //NOI18N
}
protected String getConstructorDescriptor() {
return "(Lorg/netbeans/mdr/storagemodel/StorableClass;)V"; //NOI18N
}
protected MethodInfo[] generateMethods() throws IOException {
try {
ArrayList methods = new ArrayList();
HashSet createdMethods = new HashSet();
methods.add(generateConstructor());
StorableObject meta = obj.getMetaObject();
for (Iterator it = ((List) meta.getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); it.hasNext();) {
StorableObject element = (StorableObject) it.next();
String elementName = (String) element.getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
String metaTypeName = (String) element.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
if (metaTypeName.equals(MOFConstants.SH_MODEL_STRUCTURE_TYPE)) {
ArrayList parameters = new ArrayList();
for (Iterator itt = ((List) element.getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); itt.hasNext();) {
StorableObject field = (StorableObject) itt.next();
String fieldTypeName = (String) field.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
if (fieldTypeName.equals(MOFConstants.SH_MODEL_STRUCTURE_FIELD))
parameters.add(getTypeName2(field));
}
methods.addAll(getCreateMethod("create" + firstUpper(TagSupport.getSubstName(element)), (String[])parameters.toArray(new String[parameters.size()]), TagSupport.getTypeFullName(element), M_STRUCT_NAME, M_STRUCT_DESC, M_STRUCT_TYPE, elementName)); //NOI18N
}
}
ArrayList allAttributes = new ArrayList();
for (Iterator it = new ContainsIterator(meta); it.hasNext();) {
StorableObject element = (StorableObject) it.next();
String elementName = (String) element.getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
String metaTypeName = (String) element.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
String substName = TagSupport.getSubstName(element, elementName, metaTypeName);
if (metaTypeName.equals(MOFConstants.SH_MODEL_ATTRIBUTE)) {
VisibilityKind visibility = (VisibilityKind) element.getAttribute(MOFConstants.SH_MODEL_GENERALIZABLE_ELEMENT_VISIBILITY);
ScopeKind scope = (ScopeKind) element.getAttribute(MOFConstants.SH_MODEL_FEATURE_SCOPE);
if (visibility.equals(VisibilityKindEnum.PUBLIC_VIS) && scope.equals(ScopeKindEnum.CLASSIFIER_LEVEL)) {
String attrName = firstUpper(substName);
String attrTypeName = TagSupport.getDataTypeName(getAttrType(element));
MultiplicityType multiplicity = (MultiplicityType) element.getAttribute(MOFConstants.SH_MODEL_STRUCTURAL_FEATURE_MULTIPLICITY);
if (multiplicity.getUpper() == 1) {
String name;
String setterName;
if (attrTypeName.equals("java.lang.Boolean")) { //NOI18N
if (attrName.substring(0, 2).equals("Is")) name = firstLower(attrName); //NOI18N
else name = "is" + attrName; //NOI18N
setterName = "set" + name.substring(2); //NOI18N
} else {
name = "get" + attrName; //NOI18N
setterName = "set" + attrName; //NOI18N
}
String getterType = attrTypeName;
if (multiplicity.getLower() == 1)
getterType = getPrimitiveName(getterType);
String sign = name + getMethodDescriptor(new String[0], getterType);
if (!createdMethods.contains(sign)) {
methods.addAll(getFeatureMethod(name, new String[0], getterType, M_GET_NAME, M_GET_DESC, M_GET_TYPE, element, null, "_getAttribute")); //NOI18N
createdMethods.add(sign);
}
boolean changeable = ((Boolean) element.getAttribute(MOFConstants.SH_MODEL_STRUCTURAL_FEATURE_IS_CHANGEABLE)).booleanValue();
if (changeable) {
sign = setterName + getMethodDescriptor(new String[] {getterType}, "void"); //NOI18N
if (!createdMethods.contains(sign)) {
methods.addAll(getFeatureMethod(setterName, new String[] {getterType}, "void", M_SET_NAME, M_SET_DESC, M_SET_TYPE, element, null, "_setAttribute")); //NOI18N
createdMethods.add(sign);
}
}
} else if (multiplicity.getUpper() != 0) {
String sign = "get" + attrName + getMethodDescriptor(new String[0], (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED)); //NOI18N
if (!createdMethods.contains(sign)) {
methods.addAll(getFeatureMethod("get" + attrName, new String[0], (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED), M_GET_NAME, M_GET_DESC, M_GET_TYPE, element, null, "_getAttribute")); //NOI18N
createdMethods.add(sign);
}
}
} else if (!((Boolean) element.getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_IS_DERIVED)).booleanValue())
allAttributes.add(getAttrTypeName(element));
} else if (metaTypeName.equals(MOFConstants.SH_MODEL_OPERATION)) {
ScopeKind scope = (ScopeKind) element.getAttribute(MOFConstants.SH_MODEL_FEATURE_SCOPE);
if (scope.equals(ScopeKindEnum.CLASSIFIER_LEVEL)) {
Collection parameters = new ArrayList();
String operType = "void"; //NOI18N
for (Iterator itt = ((List) element.getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); itt.hasNext();) {
StorableObject el = (StorableObject) itt.next();
String mtName = (String) el.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
if (mtName.equals(MOFConstants.SH_MODEL_PARAMETER)) {
DirectionKind direction = (DirectionKind) el.getAttribute(MOFConstants.SH_MODEL_PARAMETER_DIRECTION_KIND);
if (direction.equals(DirectionKindEnum.RETURN_DIR))
operType = getAttrTypeName(el);
else
parameters.add(getAttrTypeName(el) + (direction.equals(DirectionKindEnum.IN_DIR) ? "" : "[]")); //NOI18N
}
}
String[] prms = (String[])parameters.toArray(new String [parameters.size()]);
String sign = substName + getMethodDescriptor(prms, operType);
if (!createdMethods.contains(sign)) {
MethodInfo mInfo = getOperationMethod(substName, prms, operType, elementName);
Collection exceptions = (Collection) element.getReference(MOFConstants.SH_MODEL_OPERATION_EXCEPTIONS);
short[] declaredExceptions = new short[exceptions.size()];
int i = 0;
for (Iterator itt = exceptions.iterator(); itt.hasNext(); i++)
declaredExceptions[i] = cp.getClass(dotToSlash(TagSupport.getTypeFullName((StorableObject)itt.next())));
mInfo.setDeclaredExceptions(declaredExceptions);
methods.add(mInfo);
createdMethods.add(sign);
}
}
}
}
if (!((Boolean) meta.getAttribute(MOFConstants.SH_MODEL_GENERALIZABLE_ELEMENT_IS_ABSTRACT)).booleanValue()) {
String createName = "create" + TagSupport.getSubstName(meta); //NOI18N
String createType = TagSupport.getTypeFullName(meta);
methods.addAll(getDefaultCreateMethod(createName, new String[0], createType, M_CREATE_NAME, M_CREATE_DESC, M_CREATE_TYPE));
String[] attribs = (String[])allAttributes.toArray(new String [allAttributes.size()]);
if (allAttributes.size() > 0)
methods.addAll(getCreateMethod(createName, attribs, createType, M_CREATE_NAME, M_CREATE_DESC, M_CREATE_TYPE, null));
methods.add(getInstanceCreateDispatcher(createName, attribs, createType));
}
MethodInfo[] mtds = super.generateMethods();
methods.add(getDispatcherMethod("_createStruct", new String[] {"java.lang.String", "java.lang.Object[]"}, "javax.jmi.reflect.RefStruct", (HashMap) dispatchMethods.get("_createStruct"))); //NOI18N
for(int i = 0; i < mtds.length; i++)
methods.add(mtds[i]);
return (MethodInfo[]) methods.toArray(new MethodInfo[methods.size()]);
}catch (Exception e) {
throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
}
}
protected MethodInfo getInstanceCreateDispatcher(String name, String[] attrs, String type) throws IOException {
MethodInfo minfo = new MethodInfo(M_CREATE_DISPATCH_NAME, M_CREATE_DESC + M_CREATE_TYPE, ACC_PUBLIC | ACC_FINAL);
int localSlot0 = 1 + getWordsPerType("java.lang.Object[]"); //NOI18N
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
out.writeByte(opc_aload_1);
out.writeByte(opc_ifnull);
out.writeShort(8);
out.writeByte(opc_aload_1);
out.writeByte(opc_arraylength);
out.writeByte(opc_ifne);
out.writeShort(8);
out.writeByte(opc_aload_0);
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef(dotToSlash(className), name, getMethodDescriptor(new String[0], type)));
out.writeByte(opc_areturn);
code_aload(1, out);
out.writeByte(opc_arraylength);
code_ipush(attrs.length, out);
out.writeByte(opc_if_icmpeq);
out.writeShort(12);
out.writeByte(opc_new);
out.writeShort(cp.getClass("javax/jmi/reflect/WrongSizeException")); //NOI18N
out.writeByte(opc_dup);
out.writeByte(opc_aconst_null);
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef("javax/jmi/reflect/WrongSizeException", "", "(Ljavax/jmi/reflect/RefObject;)V")); //NOI18N
out.writeByte(opc_athrow);
short tryStart = (short) out.size();
out.writeByte(opc_aload_0);
for (int i = 0; i < attrs.length; i++) {
out.writeByte(opc_aload_1);
code_ipush(i, out);
out.writeByte(opc_aaload);
codeUnwrapArgumentNull(attrs[i], out);
}
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef(dotToSlash(className), name, getMethodDescriptor(attrs, type)));
out.writeByte(opc_areturn);
short catchStart = (short) out.size();
code_astore(localSlot0, out);
out.writeByte(opc_new);
out.writeShort(cp.getClass("javax/jmi/reflect/TypeMismatchException")); //NOI18N
out.writeByte(opc_dup);
out.writeByte(opc_aconst_null);
out.writeByte(opc_dup);
out.writeByte(opc_dup);
code_aload(localSlot0, out);
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef("java/lang/Throwable", "getMessage", "()Ljava/lang/String;")); //NOI18N
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef("javax/jmi/reflect/TypeMismatchException", "", "(Ljava/lang/Class;Ljava/lang/Object;Ljavax/jmi/reflect/RefObject;Ljava/lang/String;)V")); //NOI18N
out.writeByte(opc_athrow);
minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, cp.getClass("java/lang/ClassCastException"))); //NOI18N
minfo.setMaxStack((short)(6 + attrs.length));
minfo.setMaxLocals((short) (localSlot0 + 2));
return minfo;
}
protected void codeUnwrapArgumentNull(String typeName, DataOutputStream out) throws IOException {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
if (prim != null) {
out.writeByte(opc_dup);
out.writeByte(opc_ifnull);
out.writeShort(12);
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(prim.wrapperClassName));
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef(
prim.wrapperClassName,
prim.unwrapMethodName, prim.unwrapMethodDesc));
out.writeByte(opc_goto);
out.writeShort(5);
out.writeByte(opc_pop);
if (typeName.equals("long")) { //NOI18N
out.writeByte(opc_lconst_0);
} else if (typeName.equals("double")) { //NOI18N
out.writeByte(opc_dconst_0);
} else if (typeName.equals("float")) { //NOI18N
out.writeByte(opc_fconst_0);
} else {
out.writeByte(opc_iconst_0);
}
} else {
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(getParamType(typeName)));
}
}
protected Collection getCreateMethod(String methodName, String[] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType, String featureName) throws IOException {
if (featureName != null) {
HashMap item = (HashMap) dispatchMethods.get("_createStruct"); //NOI18N
item.put(featureName, new MethodDescHolder(methodName, parameterTypes, returnType));
}
short delegateMethod = getHandlerIndex(handlerName, handlerDescriptor, handlerType);
short preMethod = getPreIndex(handlerName, handlerDescriptor);
short postMethod = getPostIndex(handlerName, handlerType);
String desc = getMethodDescriptor(parameterTypes, returnType);
boolean isCustom = customImplContainsMethod(customImpl, methodName, desc);
int[] parameterSlot = new int[parameterTypes.length];
int nextSlot = 1;
for (int i = 0; i < parameterSlot.length; i++) {
parameterSlot[i] = nextSlot;
nextSlot += getWordsPerType(parameterTypes[i]);
}
int localSlot0 = nextSlot;
short fail = (short) localSlot0;
short extraInfo = (short) (localSlot0 + 1);
short result = (short) (localSlot0 + 2);
short addr = (short) (localSlot0 + 3);
short exception = (short) (localSlot0 + 4);
MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
MethodInfo cminfo = null;
DataOutputStream cout = null;
if (isCustom) {
cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, desc, ACC_PUBLIC | ACC_FINAL);
cout = new DataOutputStream(cminfo.getCodeStream());
}
// store "true" in the fail variable
out.writeByte(opc_iconst_1);
code_istore(fail, out);
// store "null" in the extraInfo variable
out.writeByte(opc_aconst_null);
out.writeByte(opc_dup);
code_astore(extraInfo, out);
// store "null" in result variable
code_astore(result, out);
// I'll pass this instance as the first parameter
code_aload(0, out);
if (featureName != null)
// feature name as the second parameter
code_ldc(cp.getString(featureName), out);
// The rest of parameters we'll put into Object[] array
code_ipush(parameterTypes.length, out);
out.writeByte(opc_anewarray);
out.writeShort(cp.getClass("java/lang/Object")); //NOI18N
for (int i = 0; i < parameterTypes.length; i++) {
out.writeByte(opc_dup);
code_ipush(i, out);
codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
out.writeByte(opc_aastore);
}
// start of the try block
short tryStart = (short) out.size();
// call the _pre method
out.writeByte(opc_invokespecial);
out.writeShort(preMethod);
// store the returned object in a local variable
code_astore(extraInfo, out);
if (isCustom) {
// I'll pass this instance as the first parameter
code_aload(0, out);
// The rest of parameters follows
for (int i = 0; i < parameterTypes.length; i++) {
codeLoad(parameterSlot[i], parameterTypes[i], out);
}
// call the custom method
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, desc));
code_astore(result, out);
// I'll pass this instance as the first parameter
code_aload(0, cout);
if (featureName != null)
// feature name as the second parameter
code_ldc(cp.getString(featureName), cout);
// The rest of parameters we'll put into Object[] array
code_ipush(parameterTypes.length, cout);
cout.writeByte(opc_anewarray);
cout.writeShort(cp.getClass("java/lang/Object")); //NOI18N
for (int i = 0; i < parameterTypes.length; i++) {
cout.writeByte(opc_dup);
code_ipush(i, cout);
codeWrapArgument(parameterTypes[i], parameterSlot[i], cout);
cout.writeByte(opc_aastore);
}
// call the delegate method
cout.writeByte(opc_invokespecial);
cout.writeShort(delegateMethod);
// convert returned object to the result type and return
cout.writeByte(opc_checkcast);
cout.writeShort(cp.getClass(dotToSlash(returnType)));
cout.writeByte(opc_areturn);
}
else {
// I'll pass this instance as the first parameter
code_aload(0, out);
if (featureName != null)
// feature name as the second parameter
code_ldc(cp.getString(featureName), out);
// The rest of parameters we'll put into Object[] array
code_ipush(parameterTypes.length, out);
out.writeByte(opc_anewarray);
out.writeShort(cp.getClass("java/lang/Object")); //NOI18N
for (int i = 0; i < parameterTypes.length; i++) {
out.writeByte(opc_dup);
code_ipush(i, out);
codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
out.writeByte(opc_aastore);
}
// call the delegate method
out.writeByte(opc_invokespecial);
out.writeShort(delegateMethod);
// convert the returned value to the result type and store
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(dotToSlash(returnType)));
code_astore(result, out);
}
// change value of fail to "false"
out.writeByte(opc_iconst_0);
code_istore(fail, out);
// call the finally block and return
out.writeByte(opc_jsr);
out.writeShort(3 + getBytesForLoadOrStore(result) + 1 + 2*getBytesForLoadOrStore(exception) + 4);
// load the returned value
code_aload(result, out);
// return
out.writeByte(opc_areturn);
// start of catch block
short catchStart = (short) out.size();
// store exception
code_astore(exception, out);
// call finally
out.writeByte(opc_jsr);
out.writeShort(3 + getBytesForLoadOrStore(exception) + 1);
// load exception
code_aload(exception, out);
// rethrow exception
out.writeByte(opc_athrow);
// start of finally block
// store the return address
code_astore(addr, out);
// load parameters
code_aload(0, out);
code_aload(result, out);
code_aload(extraInfo, out);
code_iload(fail, out);
// call the _post method
out.writeByte(opc_invokespecial);
out.writeShort(postMethod);
// return from finally
out.writeByte(opc_ret);
out.writeByte(addr);
minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, (short) 0));
minfo.setMaxStack((short)15);
minfo.setMaxLocals((short) (localSlot0 + 5));
if (isCustom) {
cminfo.setMaxStack((short)15);
cminfo.setMaxLocals((short) (localSlot0 + 5));
}
ArrayList ret = new ArrayList();
ret.add(minfo);
if (isCustom)
ret.add(cminfo);
return ret;
}
protected Collection getDefaultCreateMethod(String methodName, String[] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType) throws IOException {
short delegateMethod = getHandlerIndex(handlerName, handlerDescriptor, handlerType);
short preMethod = getPreIndex(handlerName, handlerDescriptor);
short postMethod = getPostIndex(handlerName, handlerType);
String desc = getMethodDescriptor(parameterTypes, returnType);
boolean isCustom = customImplContainsMethod(customImpl, methodName, desc);
int localSlot0 = 1;
short fail = (short) localSlot0;
short extraInfo = (short) (localSlot0 + 1);
short result = (short) (localSlot0 + 2);
short addr = (short) (localSlot0 + 3);
short exception = (short) (localSlot0 + 4);
MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
MethodInfo cminfo = null;
DataOutputStream cout = null;
if (isCustom) {
cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, desc, ACC_PUBLIC | ACC_FINAL);
cout = new DataOutputStream(cminfo.getCodeStream());
}
// store "true" in the fail variable
out.writeByte(opc_iconst_1);
code_istore(fail, out);
// store "null" in the extraInfo variable
out.writeByte(opc_aconst_null);
out.writeByte(opc_dup);
code_astore(extraInfo, out);
// store "null" in result variable
code_astore(result, out);
// I'll pass this instance as the first parameter
code_aload(0, out);
out.writeByte(opc_aconst_null);
// call the _pre method
out.writeByte(opc_invokespecial);
out.writeShort(preMethod);
// store the returned object in a local variable
code_astore(extraInfo, out);
// start of the try block
short tryStart = (short) out.size();
if (isCustom) {
// I'll pass this instance as the first parameter
code_aload(0, out);
// call the custom method
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, desc));
code_astore(result, out);
// I'll pass this instance as the first parameter
code_aload(0, cout);
// null as the second parameter
cout.writeByte(opc_aconst_null);
// call the delegate method
cout.writeByte(opc_invokespecial);
cout.writeShort(delegateMethod);
// convert returned object to the result type and return
cout.writeByte(opc_checkcast);
cout.writeShort(cp.getClass(dotToSlash(returnType)));
cout.writeByte(opc_areturn);
}
else {
// I'll pass this instance as the first parameter
code_aload(0, out);
// null as the second parameter
out.writeByte(opc_aconst_null);
// call the delegate method
out.writeByte(opc_invokespecial);
out.writeShort(delegateMethod);
code_astore(result, out);
}
// change value of fail to "false"
out.writeByte(opc_iconst_0);
code_istore(fail, out);
// call the finally block and return
out.writeByte(opc_jsr);
if (isCustom) {
out.writeShort(3 + getBytesForLoadOrStore(result) + 1 + 2*getBytesForLoadOrStore(exception) + 4);
// load the returned value
code_aload(result, out);
// return
out.writeByte(opc_areturn);
}
else {
out.writeShort(3 + getBytesForLoadOrStore(result) + 4 + 2*getBytesForLoadOrStore(exception) + 4);
// load the returned value
code_aload(result, out);
// convert it to the result type and return
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(dotToSlash(returnType)));
out.writeByte(opc_areturn);
}
// start of catch block
short catchStart = (short) out.size();
// store exception
code_astore(exception, out);
// call finally
out.writeByte(opc_jsr);
out.writeShort(3 + getBytesForLoadOrStore(exception) + 1);
// load exception
code_aload(exception, out);
// rethrow exception
out.writeByte(opc_athrow);
// start of finally block
// store the return address
code_astore(addr, out);
// load parameters
code_aload(0, out);
code_aload(result, out);
code_aload(extraInfo, out);
code_iload(fail, out);
// call the _post method
out.writeByte(opc_invokespecial);
out.writeShort(postMethod);
// return from finally
out.writeByte(opc_ret);
out.writeByte(addr);
minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, (short) 0));
minfo.setMaxStack((short)10);
minfo.setMaxLocals((short) (localSlot0 + 5));
if (isCustom) {
cminfo.setMaxStack((short)10);
cminfo.setMaxLocals((short) (localSlot0 + 5));
}
ArrayList ret = new ArrayList();
ret.add(minfo);
if (isCustom)
ret.add(cminfo);
return ret;
}
}
|