alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

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;
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.