Logo Search packages:      
Sourcecode: babel version File versions  Download package

IORSource.java

//
// File: IORSource.java
// Package: gov.llnl.babel.backend.ior
// Revision: @(#) $Id: IORSource.java 6201 2007-10-26 06:15:35Z kumfert $
// Description: generate IOR implementation source to a pretty writer stream
//
// Copyright (c) 2000-2004, The Regents of the University of Calfornia.
// Produced at the Lawrence Livermore National Laboratory.
// Written by the Components Team <components@llnl.gov>
// UCRL-CODE-2002-054
// All rights reserved.
// 
// This file is part of Babel. For more information, see
// http://www.llnl.gov/CASC/components/. Please read the COPYRIGHT file
// for Our Notice and the LICENSE file for the GNU Lesser General Public
// License.
// 
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License (as published by
// the Free Software Foundation) version 2.1 dated February 1999.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
// conditions of the GNU Lesser General Public License for more details.
// 
// You should have recieved a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package gov.llnl.babel.backend.ior;

import gov.llnl.babel.BabelConfiguration;
import gov.llnl.babel.Context;
import gov.llnl.babel.backend.CodeConstants;
import gov.llnl.babel.backend.CodeGenerationException;
import gov.llnl.babel.backend.IOR;
import gov.llnl.babel.backend.Utilities;
import gov.llnl.babel.backend.c.C;
import gov.llnl.babel.backend.rmi.RMIIORSource;
import gov.llnl.babel.backend.writers.LanguageWriterForC;
import gov.llnl.babel.symbols.Assertion;
import gov.llnl.babel.symbols.Class;
import gov.llnl.babel.symbols.Extendable;
import gov.llnl.babel.symbols.Method;
import gov.llnl.babel.symbols.MethodCall;
import gov.llnl.babel.symbols.Struct;
import gov.llnl.babel.symbols.Symbol;
import gov.llnl.babel.symbols.SymbolID;
import gov.llnl.babel.symbols.SymbolTable;
import gov.llnl.babel.symbols.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Class <code>IORSource</code> generates an IOR implementation source file to
 * a language writer output stream. The constructor takes a language writer
 * stream and method <code>generateCode</code> generates intermediate object
 * representation for the specified symbol to the output stream. The language
 * writer output stream is not closed by this object.
 */
00068 public class IORSource {
  private static int s_longestBuiltin;

  private static final String s_castBuiltin = IOR.getBuiltinName(IOR.CAST);

  private static final String s_deleteBuiltin = IOR.getBuiltinName(IOR.DELETE);

  private static final String s_execBuiltin = IOR.getBuiltinName(IOR.EXEC);

  private static final String s_getURLBuiltin = IOR.getBuiltinName(IOR.GETURL);

  private static final String s_raddRefBuiltin = IOR
    .getBuiltinName(IOR.RADDREF);

  private static final String s_isRemoteBuiltin = IOR
    .getBuiltinName(IOR.ISREMOTE);

  private static final String s_self = Utilities.s_self;

  private static final String s_exception_var = Utilities.s_exception;

  private static final String s_superBuiltin = "_super";

  private static final String s_asserts_okay = "aOkay";

  private static final String s_methods_okay = "mOkay";

  private static final String s_preEPV = "s_preEPV";
  private static final String s_postEPV = "s_postEPV";
  private static final String s_preSEPV = "s_preSEPV";
  private static final String s_postSEPV = "s_postSEPV";


  /**
   * Some assertion checking defaults...at least until we provide another
   * mechanism.
   */
00105   private final static int ASSERT_DECLARE = 1;

  private final static int ASSERT_RAISE = 2;

  private Context d_context = null;

  /**
   * Store the SymbolID for sidl.BaseClass, if the extendable being printed is
   * not abstract (i.e., is a concrete class).
   */
00115   SymbolID d_baseClass = null;

  /**
   * Store the SymbolID for sidl.ClassInfo, if the extendable being printed is
   * not abstract (i.e., is a concrete class).
   */
00121   SymbolID d_classInfo = null;

  /**
   * Store the SymbolID for sidl.ClassInfoI, if the extendable being printed is
   * not abstract (i.e., is a concrete class).
   */
00127   SymbolID d_classInfoI = null;

  static {
    s_longestBuiltin = 0;
    for (int j = 0; j < IOR.CLASS_BUILTIN_METHODS; ++j) {
      String mname = IOR.getBuiltinName(j, true);
      if (mname.length() > s_longestBuiltin) {
        s_longestBuiltin = mname.length();
      }
    }
  }

  private LanguageWriterForC d_writer;

  /**
   * This is a convenience utility function that writes the symbol source
   * information into the provided language writer output stream. The output
   * stream is not closed on exit. A code generation exception is thrown if an
   * error is detected.
   */
00147   public static void generateCode(Symbol symbol, 
                                  LanguageWriterForC writer,
                                  Context context)
    throws CodeGenerationException {
    IORSource source = new IORSource(writer, context);
    source.generateCode(symbol);
  }

  /**
   * Create a <code>IORSource</code> object that will write symbol information
   * to the provided output writer stream.
   */
00159   public IORSource(LanguageWriterForC writer,
                   Context context) {
    d_writer = writer;
    d_context = context;
  }

  /**
   * Write IOR source information for the provided symbol to the language writer
   * output stream provided in the constructor. This method does not close the
   * language writer output stream and may be called for more than one symbol
   * (although the generated source may not be valid input for the C compiler).
   * A code generation exception is generated if an error is detected. No code
   * is generated for enumerated and package symbols.
   */
00173   public void generateCode(Symbol symbol) throws CodeGenerationException {
    if (symbol != null) {
      switch (symbol.getSymbolType()) {
      case Symbol.PACKAGE:
      case Symbol.INTERFACE:
        break;
      case Symbol.CLASS:
        generateSource((Class) symbol);
        break;
      }
    }
  }

  private void writeStructInclude(Struct strct)
  {
    Iterator i = strct.getItems().iterator();
    boolean hasStruct = false;
    HashSet set = new HashSet();
    if (strct.hasArrayReference()) {
      d_writer.generateInclude("sidlArray.h", true);
    }
    while (i.hasNext()) {
      final Struct.Item item = (Struct.Item)i.next();
      final Type t = item.getType();
      switch(t.getDetailedType()) {
      case Type.STRUCT:
        hasStruct = true; /* fall through intended */
      case Type.INTERFACE:
      case Type.CLASS:
        final String header = IOR.getHeaderFile(t.getSymbolID());
        if (!set.contains(header)) {
          d_writer.generateInclude(header, true);
          set.add(header);
        }
        break;
      case Type.STRING:
        final String strheader = "sidl_String.h";
        if (!set.contains(strheader)) {
          d_writer.generateInclude(strheader, true);
          set.add(strheader);
        }
      }
    }
    if (hasStruct) {
      d_writer.printlnUnformatted("#ifdef SIDL_DYNAMIC_LIBRARY");
      d_writer.generateInclude("sidlOps.h", true);
      d_writer.printlnUnformatted("#endif");
    }
    d_writer.println();

  }

  /**
   * Lookup the SymbolIDs for sidl.BaseClass, sidl.ClassInfo and
   * sidl.ClassInfoI.
   */
00229   private void lookupSymbolIDs() {
    SymbolTable table = d_context.getSymbolTable();
    d_baseClass = table.lookupSymbol(BabelConfiguration.getBaseClass())
      .getSymbolID();
    d_classInfo = table.lookupSymbol(BabelConfiguration.getClassInfo())
      .getSymbolID();
    d_classInfoI = table.lookupSymbol(BabelConfiguration.getClassInfoI())
      .getSymbolID();
  }

  /**
   * Generate the IOR source for a SIDL class or interface. The source file
   * begins with a banner and include files followed by a declaration of static
   * methods and (for a class) external methods expected in the skeleton file.
   * For classes, the source file then defines a number of functions (cast,
   * delete, initialize EPVs, new, init, and fini).
   */
00246   private void generateSource(Class cls) throws CodeGenerationException {
    /*
     * Generate the file banner and include files.
     */
    SymbolID id = cls.getSymbolID();
    String source = IOR.getSourceFile(id);
    String header = IOR.getHeaderFile(id);

    d_writer.writeBanner(cls, source, CodeConstants.C_IS_NOT_IMPL,
                         CodeConstants.C_DESC_IOR_PREFIX + id.getFullName());
    comment("Begin: RMI includes");
    d_writer.printlnUnformatted("#include \"sidl_rmi_InstanceHandle.h\"");
    d_writer.printlnUnformatted("#include \"sidl_rmi_InstanceRegistry.h\"");
    d_writer.printlnUnformatted("#include \"sidl_rmi_ServerRegistry.h\"");
    d_writer.printlnUnformatted("#include \"sidl_rmi_Call.h\"");
    d_writer.printlnUnformatted("#include \"sidl_rmi_Return.h\"");
    d_writer.printlnUnformatted("#include \"sidl_Exception.h\"");
    d_writer.printlnUnformatted("#include \"sidl_exec_err.h\"");
    d_writer.printlnUnformatted("#include \"sidl_PreViolation.h\"");
    d_writer.printlnUnformatted("#include \"sidl_NotImplementedException.h\"");
    d_writer.printlnUnformatted("#include <stdio.h>");
    comment("End: RMI includes");
    d_writer.printlnUnformatted("#include <stdlib.h>");
    d_writer.printlnUnformatted("#include <stddef.h>");
    d_writer.printlnUnformatted("#include <string.h>");
    if (IOR.supportAssertions(cls, d_context)) {
      d_writer.printlnUnformatted("#include <stdio.h>");
      d_writer.printlnUnformatted("#if TIME_WITH_SYS_TIME");
      d_writer.printlnUnformatted("#  include <sys/time.h>");
      d_writer.printlnUnformatted("#  include <time.h>");
      d_writer.printlnUnformatted("#else");
      d_writer.printlnUnformatted("#  if HAVE_SYS_TIME_H");
      d_writer.printlnUnformatted("#    include <sys/time.h>");
      d_writer.printlnUnformatted("#  else");
      d_writer.printlnUnformatted("#    include <time.h>");
      d_writer.printlnUnformatted("#  endif");
      d_writer.printlnUnformatted("#endif");
      d_writer.printlnUnformatted("#include \"sidlAsserts.h\"");
      d_writer.printlnUnformatted("#include \"sidlAssertUtils.h\"");
      if (!d_context.getConfig().getAssertionLevel().equals(
                                                                       BabelConfiguration.ADVANCED_CHECKING)) {
        d_writer.println("/* ");
      }
      d_writer.printlnUnformatted("#define " + IOR.S_FULL_STATS_MACRO);
      if (!d_context.getConfig().getAssertionLevel().equals(
                                                                       BabelConfiguration.ADVANCED_CHECKING)) {
        d_writer.println(" */");
      }
      d_writer.printlnUnformatted("#define " + IOR.S_TEXT_STATS_MACRO);
      d_writer.println();
    }
    d_writer.generateInclude("sidlOps.h", true);
    d_writer.generateInclude(header, false);
    generateIncludes(cls);
    lookupSymbolIDs();
    d_writer.generateInclude(C.getImplHeaderFile(d_baseClass), true);
    d_writer.generateInclude(C.getHeaderFile(d_baseClass), true);
    d_writer.generateInclude(C.getHeaderFile(d_classInfo), true);
    d_writer.generateInclude(C.getHeaderFile(d_classInfoI), true);
    d_writer.println();

    d_writer.printlnUnformatted("#ifndef " + C.NULL);
    d_writer.printlnUnformatted("#define " + C.NULL + " 0");
    d_writer.printlnUnformatted("#endif");
    d_writer.println();

    String my_mutex = IOR.getSymbolName(id) + "__mutex";
    String lock_name = IOR.getLockStaticGlobalsMacroName();
    String unlock_name = IOR.getUnlockStaticGlobalsMacroName();
    String have_lock = IOR.getHaveLockStaticGlobalsMacroName();
    d_writer.printlnUnformatted("#include \"sidl_thread.h\"");
    d_writer.printlnUnformatted("#ifdef HAVE_PTHREAD");
    d_writer.printlnUnformatted("static struct sidl_recursive_mutex_t "
                                + my_mutex + "= SIDL_RECURSIVE_MUTEX_INITIALIZER;");
    d_writer.printlnUnformatted("#define " + lock_name
                                + " sidl_recursive_mutex_lock( &" + my_mutex + " )");
    d_writer.printlnUnformatted("#define " + unlock_name
                                + " sidl_recursive_mutex_unlock( &" + my_mutex + " )");
    d_writer.printlnUnformatted("/* #define " + have_lock
                                + " (sidl_recursive_mutex_trylock( &" + my_mutex + " )==EDEADLOCK) */");
    d_writer.printlnUnformatted("#else");
    d_writer.printlnUnformatted("#define " + lock_name);
    d_writer.printlnUnformatted("#define " + unlock_name);
    d_writer.printlnUnformatted("/* #define " + have_lock + " (1) */");
    d_writer.printlnUnformatted("#endif");
    d_writer.println();

    /*
     * Generate internal static variables and external references to be supplied
     * by the skeleton file.
     */
    generateStaticVariables(cls);
    generateExternalReferences(cls);

    /*
     * Generate a number of local functions (cast, delete, initialization of
     * EPVs, new, init, and fini). These functions are only needed for classes.
     */
    boolean doStatic = cls.hasStaticMethod(true);
    boolean doAsserts = IOR.supportAssertions(cls, d_context);
    boolean doHooks = IOR.supportHooks(cls, d_context);

    RMIIORSource.generateCode(cls, d_writer, d_context);
    generateEnsureLoad(cls);
    IOR.generateCastFunction(cls,s_self,d_writer, false,true);
    if (doAsserts) {
      if (doStatic) {
        generateChecksFunction(cls, true);
        generateDumpStatsFunction(cls, true);
      }
      generateChecksFunction(cls, false);
      generateDumpStatsFunction(cls, false);
      generateAllChecks(cls);
    }
  
    if (doStatic) {
      generateHooksFunction(cls, true);
    }
    generateHooksFunction(cls, false);
    if (doHooks) {
      generateAllHooks(cls);
    }
    generateDeleteFunction(cls);
    generateGetURLFunction(cls);
    generateIsLocalIsRemote(cls);
    generateMainExec(cls);
    generateNonblockingMethods(cls);
    generateInitEPV(cls);
    generateInitSEPV(cls);
    declareGetEPVs(cls);
    generateStaticFunction(cls, false);
    generateSuperFunction(cls);
    if (doAsserts || doHooks) {
      generateStaticFunction(cls, true);
    }
    generateInitClassInfo(cls);
    generateInitMetadata(cls);
    generateNewFunction(cls);
    generateInitFunction(cls);
    generateFiniFunction(cls);
    generateVersionFunction(cls);
    generateExternalFunc(cls);
  }

  private void generateIncludes(Class ext)
    throws CodeGenerationException
  {
    final SymbolID eid = ext.getSymbolID();
    Set references = ext.getSymbolReferences();
    if (references != null ) {
      Iterator i = references.iterator();
      while (i.hasNext()) {
        final SymbolID id = (SymbolID)i.next();
        final Symbol sym = Utilities.lookupSymbol(d_context, id);
        if (sym instanceof Struct) {
          d_writer.generateInclude(IOR.getHeaderFile(sym.getSymbolID()),true);
          d_writer.printlnUnformatted("#define RMI_" +
                                      IOR.getSymbolName(id) +
                                      "_serialize " +
                                      IOR.getSkelSerializationName(eid, id, true));
          d_writer.printlnUnformatted("#define RMI_" +
                                      IOR.getSymbolName(id) +
                                      "_deserialize " +
                                      IOR.getSkelSerializationName(eid, id, false));
        }
      }
    }
  }

  /**
   * Generate a single line comment. This is called out as a separate method to
   * make the code formatting below a little prettier.
   */
00419   private void comment(String s) {
    d_writer.writeComment(s, false);
  }

  /**
   * Generate the static variables used to store the EPVs and also the
   * initialization flags for the EPVs. Classes require EPVs for their static
   * methods (if present), standard methods, and old, and new versions for all
   * parent classes and interfaces.
   */
00429   private void generateStaticVariables(Class cls) throws CodeGenerationException {
    comment("Static variables to hold version of IOR");
    d_writer.println("static const int32_t s_IOR_MAJOR_VERSION = "
                     + IOR.MAJOR_VERSION + ";");
    d_writer.println("static const int32_t s_IOR_MINOR_VERSION = "
                     + IOR.MINOR_VERSION + ";");
    d_writer.println();

    if (!cls.isAbstract()) {
      comment("Static variable to hold shared ClassInfo interface.");
      d_writer.println("static " + C.getObjectName(d_classInfo)
                       + " s_classInfo = " + C.NULL + ";");
      if (d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println("static int s_classInfo_init = 1;");
      }
      d_writer.println();
    }

    comment("Static variable to make sure _load called no more than once");
    d_writer.println("static int s_load_called = 0;");

    comment("Static variables for managing EPV initialization.");

    /*
     * Output the initialization flags for the EPV structures.
     */
    boolean has_static = cls.hasStaticMethod(true);
    boolean doAsserts = IOR.supportAssertions(cls, d_context);
    boolean doHooks = IOR.supportHooks(cls, d_context);
    
    d_writer.println("static int s_method_initialized = 0;");
    if (has_static) {
      d_writer.println("static int s_static_initialized = 0;");
    }
    d_writer.println();

    /*
     * Output the EPV and static EPV for this object for each supported type of
     * static EPV.
     */
    IOR.generateStaticEPVVariables(d_writer, cls, has_static, false,
                                   IOR.SET_PUBLIC);
    if (doAsserts) {
      IOR.generateStaticEPVVariables(d_writer, cls, has_static, false,
                                     IOR.SET_ASSERTIONS);
    }
    //    if (doHooks) {
    IOR.generateStaticEPVVariables(d_writer, cls, has_static, false,
                                   IOR.SET_HOOKS);
    //}

    //    comment("Parent class hooks epvs");
    //Class parentclass = cls.getParentClass();
    //if(parentclass != null) {
    //  IOR.generateStaticEPVVariables(d_writer, parentclass, has_static, false,
    //                                IOR.SET_HOOKS);
    //}
    /*
     * Collect all the parents of the class in a set and output EPV structures
     * for the parents.
     */
    Set parents = Utilities.getAllParents(cls);
    Set new_interfaces = Utilities.getUniqueInterfaceIDs(cls);

    if (!parents.isEmpty()) {
      List sorted = Utilities.sort(parents);
      for (Iterator i = sorted.iterator(); i.hasNext();) {
        SymbolID p_id = (SymbolID) i.next();
        String p_epv = "static " + IOR.getEPVName(p_id);
        boolean is_old = !new_interfaces.contains(p_id);
        String p_epvStr = (is_old ? p_epv + "  " : p_epv + " ");

        d_writer.print(p_epvStr);
        d_writer.println(IOR.getStaticEPVVariable(p_id, IOR.EPV_NEW,
                                                  IOR.SET_PUBLIC)+ ";");

        d_writer.print(p_epvStr);
        d_writer.println(IOR.getStaticEPVVariable(p_id, IOR.EPV_NEW,
                                                  IOR.SET_HOOKS)+ ";");


        if (is_old) {
          d_writer.print(p_epv + "* ");
          d_writer.println(IOR.getStaticEPVVariable(p_id, IOR.EPV_OLD,
                                                    IOR.SET_PUBLIC)
                           + ";");
          d_writer.print(p_epv + "* ");
          d_writer.println(IOR.getStaticEPVVariable(p_id, IOR.EPV_OLD,
                                                    IOR.SET_HOOKS)
                           + ";");

        }
        d_writer.println();
      }
    }

    if (has_static && (doAsserts || doHooks || 
                       d_context.getConfig().generateHooks()) ) {
      comment("Static variables for assertion and/or hooks controls.");
      String asCtrls = "static " + IOR.getControlsStruct(cls.getSymbolID());
      int asWidth = asCtrls.length() + 1;
      d_writer.printAligned(asCtrls, asWidth);
      d_writer.println(IOR.S_CONTROLS + ";");
      d_writer.println();
    }
    if (doAsserts) {
      comment("Static file for assertion statistics.");
      d_writer
        .println("static FILE* " + IOR.S_DUMP_FILE + " = " + C.NULL + ";");
      d_writer.println();
    }

    //Declare static hooks epvs
    if(IOR.supportHooks(cls, d_context)) {
      SymbolID id = cls.getSymbolID();
      d_writer.println("static " + IOR.getPreEPVName(id) + " "+s_preEPV+";");
      d_writer.println("static " + IOR.getPostEPVName(id) + " "+s_postEPV+";");
      if(has_static) {
        d_writer.println("static " + IOR.getPreSEPVName(id) + " "+s_preSEPV+";");
        d_writer.println("static " + IOR.getPostSEPVName(id) + " "+s_postSEPV+";");
      }
    }
  }

  /**
   * Generate external references for skeleton routines that define the
   * functions in the EPVs. A class will have a method EPV. If there are static
   * functions, then there must also be a static EPV.
   */
00558   private void generateExternalReferences(Class cls) {
    comment("Declare EPV routines defined in the skeleton file.");

    SymbolID id = cls.getSymbolID();
    d_writer.openCxxExtern();
    d_writer.println("extern void " + IOR.getSetEPVName(id) + "(");
    d_writer.tab();
    if(IOR.supportHooks(id, d_context)) {
      d_writer.println(IOR.getEPVName(id) + "* epv,");
      d_writer.println(IOR.getPreEPVName(id) + "* pre_epv,");
      d_writer.println(IOR.getPostEPVName(id) + "* post_epv);");
    } else {
      d_writer.println(IOR.getEPVName(id) + "* epv);");
    }
    d_writer.backTab();

    if (cls.hasStaticMethod(true)) {
      d_writer.println("extern void " + IOR.getSetSEPVName(id) + "(");
      d_writer.tab();
      if(IOR.supportHooks(id, d_context)) {
        d_writer.println(IOR.getSEPVName(id) + "* epv,");
        d_writer.println(IOR.getPreSEPVName(id) + "* pre_sepv,");
        d_writer.println(IOR.getPostSEPVName(id) + "* post_sepv);");
      } else {
        d_writer.println(IOR.getSEPVName(id) + "* sepv);");
      }
      d_writer.backTab();
    }
    d_writer.println("extern void " + IOR.getCallLoadName(id) + "(void);");
    d_writer.closeCxxExtern();

    d_writer.println();
  }

  /**
   * Returns the controls variable base for the specified version.
   */
00595   private String getBaseControls(boolean doStatic, String self) {
    return (doStatic ? IOR.S_CONTROLS : self + "->" + IOR.D_CONTROLS);
  }

  /**
   * Returns the method controls variable base for the specified base and index
   * variable name.
   */
00603   private String getBaseMethodControls(String base, String indexVar) {
    return base + IOR.D_METHOD_CONTROLS + "[" + indexVar + "]";
  }

  /**
   * Generate the countdown macro call.
   */
00610   private void generateStatisticsUpdate(String ctrlBase, String methBase,
                                        String aOkay, String mOkay, String methTime, String totalTime) {
    d_writer.printlnUnformatted("#ifdef " + IOR.S_FULL_STATS_MACRO);
    if (mOkay.equals("0")) {
      d_writer.println(methBase + IOR.D_METHOD_EXCEPT + " += 1;");
    } else if (mOkay.equals(s_methods_okay)) {
      d_writer.println(methBase + IOR.D_TRIES + " += 1;");
      d_writer.println("SIDL_INCR_IF_TRUE(!" + mOkay + "," + methBase
                       + IOR.D_METHOD_EXCEPT + ")");
      d_writer.println("SIDL_INCR_IF_TRUE(" + aOkay + "," + methBase
                       + IOR.D_SUCCESSES + ")");
    }
    d_writer.printlnUnformatted("#endif /* " + IOR.S_FULL_STATS_MACRO + " */");
    d_writer.println("SIDL_SET_COUNTDOWN(" + ctrlBase + IOR.D_CHECKS + ",");
    d_writer.tab();
    d_writer.println(ctrlBase + IOR.D_RATE + ", " + methBase + IOR.D_COUNTDOWN
                     + ", " + aOkay + ", " + mOkay + ", ");
    d_writer.println("" + methTime + ", " + totalTime + ")");
    d_writer.backTab();
  }

  /**
   * Returns the name of the built-in method, prepending "ior_" and the name of
   * the symbol.
   */
00635   private String getIORMethodName(SymbolID id, String name) {
    return "ior_" + IOR.getSymbolName(id) + '_' + name;
  }

  /**
   * Returns the name of the specified version of the function to set the
   * assertion checking level.
   */
00643   private String getSetChecksMethodName(SymbolID id, boolean doStatic) {
    return getIORMethodName(id, IOR.getBuiltinName(IOR.CHECKS, doStatic));
  }

  /**
   * Generate the specified function to set the assertion checking level.
   */
00650   private void generateChecksFunction(Extendable ext, boolean doStatic) 
    throws CodeGenerationException {
    String desc = doStatic ? "static " : "";
    comment("CHECKS: set the " + desc + "assertion checking level.");

    SymbolID id = ext.getSymbolID();
    boolean doAsserts = IOR.supportAssertions(ext, d_context);
    boolean doBoth = doAsserts && IOR.supportHooks(ext, d_context);

    d_writer.println("static void " + getSetChecksMethodName(id, doStatic)
                     + '(');
    d_writer.tab();
    if (!doStatic) {
      d_writer.println(IOR.getObjectName(id) + "* " + s_self + ",");
    }
    d_writer.println("int32_t level,");
    d_writer.println("double  rate,");
    d_writer.println("int32_t resetCounters,");
    d_writer.println(IOR.getExceptionFundamentalType() + "*_ex)");
    d_writer.backTab();

    d_writer.println("{");
    d_writer.tab();

    if (doAsserts) {
      String base = getBaseControls(doStatic, s_self) + ".";
      String mBase = "mc->";

      d_writer.println(IOR.getMethodControlsStruct(id) + " *mc;");
      if (!doStatic) {
        d_writer.println("int checkAsserts = CHECK_ASSERTIONS & level;");
      }
      d_writer.println(base + IOR.D_CHECKS + "  = level;");
      d_writer.println(base + IOR.D_RATE + " = rate;");
      d_writer.println();
      d_writer.println("if (resetCounters) {");
      d_writer.tab();
      d_writer.println("int i;");
      d_writer.println("for (i =" + IOR.getMethodIndex(id, "MIN") + ";");
      d_writer.println("     i<=" + IOR.getMethodIndex(id, "MAX") + "; i++)"
                       + " {");
      d_writer.tab();
      d_writer.println("mc = &" + getBaseMethodControls(base, "i") + ";");
      d_writer.printlnUnformatted("#ifdef " + IOR.S_FULL_STATS_MACRO);
      d_writer.println(mBase + IOR.D_CALLS + "             = 0;");
      d_writer.println(mBase + IOR.D_METHOD_EXCEPT + " = 0;");
      d_writer.println(mBase + IOR.D_TRIES + "             = 0;");
      d_writer.println(mBase + IOR.D_SUCCESSES + "         = 0;");
      d_writer.println(mBase + IOR.D_COUNTDOWN + "         = 0;");
      d_writer
        .printlnUnformatted("#else /* !" + IOR.S_FULL_STATS_MACRO + " */");
      d_writer.println(mBase + IOR.D_COUNTDOWN + "         = 0;");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_FULL_STATS_MACRO + " */");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
      if (!doStatic) {
        d_writer.println();
        d_writer.println("/* Ensure the EPVs are set properly. */");
      }
    }

    if (!doStatic) {
      String publicepv = s_self + "->" + IOR.getEPVVar(IOR.PUBLIC_EPV);
      if (doBoth) {
        String baseepv = s_self + "->" + IOR.getEPVVar(IOR.BASE_EPV);
        String use = getBaseControls(false, s_self) + "." + IOR.D_HOOKS;
        d_writer.println("if (checkAsserts && (" + use + ")) {");
        d_writer.tab();
        d_writer.println(publicepv + "  = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_ASSERTIONS)
                         + ";");
        d_writer.println(baseepv + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_HOOKS) + ";");
        d_writer.backTab();
        d_writer.println("} else if (checkAsserts) {");
        d_writer.tab();
        d_writer.println(publicepv + "  = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_ASSERTIONS)
                         + ";");
        d_writer.println(baseepv + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        d_writer.backTab();
        d_writer.println("} else if (" + use + ") {");
        d_writer.tab();
        d_writer.println(publicepv + "  = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_HOOKS) + ";");
        d_writer.println(baseepv + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        d_writer.backTab();
        d_writer.println("} else {");
        d_writer.tab();
        d_writer.println(publicepv + "  = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        d_writer.println(baseepv + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        d_writer.backTab();
        d_writer.println("}");
      } else if (doAsserts) {
        d_writer.println("if (checkAsserts) {");
        d_writer.tab();
        d_writer.println(publicepv + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_ASSERTIONS)
                         + ";");
        d_writer.backTab();
        d_writer.println("} else {");
        d_writer.tab();
        d_writer.println(publicepv + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        d_writer.backTab();
        d_writer.println("}");
      } else {
        comment("Nothing to do since assertion support not needed.");
      }
    }

    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Returns the name of the assertion statistics dump method.
   */
00776   private String getDumpStatsMethodName(SymbolID id, boolean doStatic) {
    return getIORMethodName(id, IOR.getBuiltinName(IOR.DUMP_STATS, doStatic));
  }

  /**
   * Generate the specified version of the dump assertion statistics and control
   * data function.
   */
00784   private void generateDumpStatsFunction(Extendable ext, boolean doStatic) 
    throws CodeGenerationException {
    
    String desc = doStatic ? "static " : "";
    comment("DUMP: Dump the " + desc + "assertion statistics.");

    SymbolID id = ext.getSymbolID();
    boolean doAsserts = IOR.supportAssertions(ext, d_context);
    boolean doHooks = IOR.supportHooks(ext, d_context);

    d_writer.println("static void " + getDumpStatsMethodName(id, doStatic)
                     + '(');
    d_writer.tab();
    if (!doStatic) {
      d_writer.println(IOR.getObjectName(id) + "* " + s_self + ",");
    }
    d_writer.println("const char* filename,");
    d_writer.println(IOR.getExceptionFundamentalType() + "*_ex)");
    d_writer.backTab();
    d_writer.println("{");
    d_writer.tab();

    if (doAsserts) {
      String base = getBaseControls(doStatic, s_self) + ".";
      String mBase = "mc->";

      d_writer.println(IOR.getMethodControlsStruct(id) + " *mc;");
      d_writer.println("time_t currTime = time(" + C.NULL + ");");
      d_writer.println("int    level    = " + base + IOR.D_CHECKS + ";");
      d_writer.printlnUnformatted("#ifdef " + IOR.S_TEXT_STATS_MACRO);
      d_writer.println("char*  desc     = sidl_getCheckDescription(level);");
      d_writer
        .printlnUnformatted("#else /* !" + IOR.S_TEXT_STATS_MACRO + " */");
      d_writer.println("char*  desc     = sidl_getCheckFrequencyDesc(level);");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_TEXT_STATS_MACRO + " */");
      d_writer.println("int    i;");
      d_writer.println();
      d_writer.println("if (" + IOR.S_DUMP_FILE + " == " + C.NULL + ") {");
      d_writer.tab();
      d_writer.println("if ((" + IOR.S_DUMP_FILE
                       + "=fopen(filename,\"w\")) == " + C.NULL + ") {");
      d_writer.tab();
      try {
        d_writer.pushLineBreak(false);
        d_writer.println("printf(\"Cannot open file %s to dump the " + desc
                         + "assertion statistics.\\n\", filename);");
      }
      finally {
        d_writer.popLineBreak();
      }
      d_writer.println("return;");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println();

      d_writer.printlnUnformatted("#ifdef " + IOR.S_TEXT_STATS_MACRO);
      try {
        d_writer.pushLineBreak(false);
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE + ", \""
                         + desc.toUpperCase() + "ASSERTION CONTROL AND STATISTICS AT %s\\n\","
                         + " ctime(&currTime));");
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE
                         + ", \"Checking Level      = %d (%s)\\n\", level, desc);");
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE
                         + ", \"Checking Threshold  = %f\\n\", " + base + IOR.D_RATE + ");");
        if (doHooks) {
          d_writer.println("fprintf(" + IOR.S_DUMP_FILE
                           + ", \"Hooks Support = %s\\n\", (" + base + IOR.D_HOOKS
                           + " ? \"on\" : \"off\"));");
        }
        d_writer.printlnUnformatted("#ifdef " + IOR.S_FULL_STATS_MACRO);
        d_writer.print("fprintf(" + IOR.S_DUMP_FILE
                       + ", \"\\n%26s  \\t%s (%s (%s), %s)  \\t%s (%s, %s)\\n\",");
        d_writer.println("\"Method          \", \"Calls\", \"Chkd\", "
                         + "\"OK\", \"MExcs\", \"Cd\", \"Meth\", \"Total\");");
        d_writer
          .printlnUnformatted("#else /* !" + IOR.S_FULL_STATS_MACRO + " */");
        d_writer.pushLineBreak(false);
        d_writer.print("fprintf(" + IOR.S_DUMP_FILE + ", \"\\n%26s  \\t%s\\n\",");
        d_writer.println("\"Method          \", \"Cd\");");
      }
      finally {
        d_writer.popLineBreak();
      }
        d_writer
        .printlnUnformatted("#endif /* " + IOR.S_FULL_STATS_MACRO + " */");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_TEXT_STATS_MACRO + " */");
      d_writer.println("for (i =" + IOR.getMethodIndex(id, "MIN") + ";");
      d_writer.println("     i<=" + IOR.getMethodIndex(id, "MAX") + "; i++)"
                       + " {");
      d_writer.tab();
      d_writer.println("mc = &" + getBaseMethodControls(base, "i") + ";");
      d_writer.print("if (  (");
      if (!doStatic) {
        d_writer.print("!");
      }
      d_writer.println(IOR.getMethodDescDataName(id) + "[i].isStatic) ");
      d_writer.printlnUnformatted("#ifdef " + IOR.S_FULL_STATS_MACRO);
      d_writer.println("   && (" + mBase + IOR.D_CALLS + " > 0) ) {");
      d_writer.tab();
      d_writer.printlnUnformatted("#ifdef " + IOR.S_TEXT_STATS_MACRO);
      try {
        d_writer.pushLineBreak(false);
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE
                         + ", \"%26s  \\t%5d (%d (%d), %d)  \\t\\t%2d\\n\",");
        d_writer
          .printlnUnformatted("#else /* !" + IOR.S_TEXT_STATS_MACRO + " */");
        d_writer.pushLineBreak(false);
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE
                         + ", \"%s\\t%f\\t%s\\t%d\\t%d\\t%d\\t%d\\t%d\\n\",");
      }
      finally {
        d_writer.popLineBreak();
      }
      d_writer.println("        desc,");
      d_writer.println("        " + base + IOR.D_RATE + ",");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_TEXT_STATS_MACRO + " */");
      d_writer
        .printlnUnformatted("#else /* !" + IOR.S_FULL_STATS_MACRO + " */");
      d_writer.backTab();
      d_writer.println("   && (" + mBase + IOR.D_COUNTDOWN + " > 0) ) {");
      d_writer.tab();
      d_writer.printlnUnformatted("#ifdef " + IOR.S_TEXT_STATS_MACRO);
      try {
        d_writer.pushLineBreak(false);
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE + ", \"%26s  \\t%5d\\n\",");
        d_writer
          .printlnUnformatted("#else /* !" + IOR.S_TEXT_STATS_MACRO + " */");
        d_writer.println("fprintf(" + IOR.S_DUMP_FILE
                         + ", \"%s\\t%f\\t%s\\t%d\\n\",");
      }
      finally {
        d_writer.popLineBreak();
      }
      d_writer.println("        desc,");
      d_writer.println("        " + base + IOR.D_RATE + ",");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_TEXT_STATS_MACRO + " */");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_FULL_STATS_MACRO + " */");
      d_writer
        .println("        " + IOR.getMethodDescDataName(id) + "[i].name,");
      d_writer.printlnUnformatted("#ifdef " + IOR.S_FULL_STATS_MACRO);
      d_writer.println("        " + mBase + IOR.D_CALLS + ",");
      d_writer.println("        " + mBase + IOR.D_TRIES + ",");
      d_writer.println("        " + mBase + IOR.D_SUCCESSES + ",");
      d_writer.println("        " + mBase + IOR.D_METHOD_EXCEPT + ",");
      d_writer.println("        " + mBase + IOR.D_COUNTDOWN + ");");
      d_writer
        .printlnUnformatted("#else /* !" + IOR.S_FULL_STATS_MACRO + " */");
      d_writer.println("        " + mBase + IOR.D_COUNTDOWN + ");");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_FULL_STATS_MACRO + " */");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.printlnUnformatted("#ifdef " + IOR.S_TEXT_STATS_MACRO);
      d_writer.println("fprintf(" + IOR.S_DUMP_FILE + ", \"\\n\\n\");");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_TEXT_STATS_MACRO + " */");
      d_writer.println("fflush(" + IOR.S_DUMP_FILE + ");");
      d_writer.println("free(desc);");
      d_writer.println("return;");
    } else {
      comment("Nothing to do since assertion support not needed.");
    }

    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Generate any assertion checks associated with each method of the class.
   * Optimally, this will only be called if the class has assertions that need
   * to be checked.
   */
00967   private void generateAllChecks(Class cls) throws CodeGenerationException {
    List invariants = cls.getAllInvariants();

    List normal = (List) cls.getMethods(true);
    Iterator i = normal.iterator();
    Method meth = null;
    while (i.hasNext()) {
      meth = (Method) i.next();
      generateMethodChecks(cls, meth, invariants);
    }
  }

  /**
   * Returns the name of the assertion checking method for the specified method.
   */
00982   private String getCheckMethodName(Extendable ext, Method meth) {
    return "check_" + IOR.getSymbolName(ext.getSymbolID()) + '_'
      + meth.getLongMethodName();
  }

  /**
   * Generate call to the base method.
   */
00990   private void generateBaseCall(String name, String var,
                                List args, boolean isStatic, boolean doThrows, Type returnType,
                                boolean deref_inout)
    throws CodeGenerationException {
    if ((returnType != null) && (returnType.getType() != Type.VOID)) {
      d_writer.print(C.FUNCTION_RESULT + " = ");
    }
    d_writer.print("(" + var + "->");
    d_writer.println(IOR.getVectorEntry(name) + ")(");
    d_writer.tab();
    d_writer.tab();
    IOR.generateArguments(d_writer, d_context,
                          s_self, args, isStatic, 
                          doThrows, returnType, false, false,
                        false, deref_inout);
    d_writer.println(");");
    d_writer.backTab();
    d_writer.backTab();
  }

  /**
   * Generate the checks associated with the invariants, preconditions, and
   * postconditions, if any, for the given method. Assumes being called only if
   * assertion check generation is enabled.
   * 
   * @param cls
   *          The class associated with the method.
   * @param m
   *          Method to be checked.
   * @param invariants
   *          List of invariants, if any.
   */
01022   private void generateMethodChecks(Class cls, Method m, List invariants)
    throws CodeGenerationException {
    SymbolID id = cls.getSymbolID();
    String name = m.getLongMethodName();
    List preconditions = m.getPreconditions();
    List postconditions = m.getPostconditions();
    int numInv = invariants.size();
    int numPre = preconditions.size();
    int numPure = (m.hasPureAssertion()) ? 1 : 0;
    int numPost = postconditions.size() - numPure;
    int total = (2 * numInv) + numPre + numPost;
    comment("Check relevant assertions, if any, before and after the method "
            + "call.");
    String methname = getCheckMethodName(cls, m);

    Type type = m.getReturnType();
    boolean hasReturn = false;
    if ((type != null) && (type.getType() != Type.VOID)) {
      hasReturn = true;
    }
    d_writer.println("static " + getReturnString(type) + " " + methname + '(');
    d_writer.tab();
    List args = m.getArgumentList();
    boolean hasThrows = !m.getThrows().isEmpty();
    boolean isStatic = m.isStatic();
    IOR.generateArguments(d_writer, d_context,
                          IOR.getObjectName(id) + "* " + s_self, args,
                        isStatic, hasThrows, type, true, true, false, false);
    d_writer.println(")");
    d_writer.backTab();
    d_writer.println("{");
    d_writer.tab();

    if (hasReturn) {
      d_writer.println(getReturnString(type) + " " + C.FUNCTION_RESULT + 
                       Utilities.getTypeInitialization(type, d_context) + ";");
    }

    /*
     * WARNING/ToDo...Must figure out how to ensure the exception type is
     * declared should the class never throw an exception AND the base exception
     * type ever stop being the base interface!
     */
    if ((!hasThrows) && (m.hasUnreservedMethodAssertion(false))) {
      d_writer.println(IOR.getExceptionFundamentalType() + "* "
                       + s_exception_var + ";");
    }
    String var;
    boolean addBlank = false;
    boolean doHooks = IOR.supportHooks(cls, d_context);
    if (isStatic) {
      var = "sepv";
      if (doHooks) {
        d_writer.println("int _type = " + getBaseControls(isStatic, "") + "."
                         + IOR.D_HOOKS + " ? " + IOR.getStaticTypeOption(id, IOR.SET_HOOKS)
                         + " : " + IOR.getStaticTypeOption(id, IOR.SET_PUBLIC) + ";");
        d_writer.println(IOR.getSEPVName(id) + "* " + var + " = "
                         + IOR.getLocalStaticsName(id) + "(_type);");
      } else {
        d_writer.println(IOR.getSEPVName(id) + "* " + var + " = "
                         + IOR.getLocalStaticsName(id) + "("
                         + IOR.getStaticTypeOption(id, IOR.SET_PUBLIC) + ");");
      }
      addBlank = true;
    } else {
      if (doHooks) {
        var = s_self + "->" + IOR.getEPVVar(IOR.BASE_EPV);
      } else {
        var = "epv";
        d_writer.println(IOR.getEPVName(id) + "* " + var + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        addBlank = true;
      }
    }
    if (addBlank) {
      d_writer.println();
    }
    if (total > 0) {
      String ctrlBase = getBaseControls(isStatic, s_self) + ".";
      String methIndex = IOR.getMethodIndex(id, m);
      String bvar = (isStatic || doHooks) ? var : s_self + "->"
        + IOR.getEPVVar(IOR.PUBLIC_EPV);
      String excvar = hasThrows ? s_exception_var : "";
      String methBase = "mc->";
      String timingVar = "doTiming";

      d_writer.println("int " + s_asserts_okay + "    = 1;");
      d_writer.println("int " + s_methods_okay + "    = 1;");
      d_writer.println("int " + timingVar + " = 0;");

      /*
       * ToDo...Need to determine the number of each macro return type actually
       * needed. (This would be the maximum number associated with any given
       * assertion!)
       */
      int totalMacros = 0;
      int maxMacros = m
        .getMaxArrayIterMacros(MethodCall.MACRO_RETURN_TYPE[MethodCall.MACRO_RETURNS_BOOLEAN_IND]);
      if (maxMacros > 0) {
        d_writer.println("int " + MethodCall.ARRAY_BOOLEAN_RESULT_VAR + "["
                         + maxMacros + "];");
        totalMacros += maxMacros;
      }
      maxMacros = m
        .getMaxArrayIterMacros(MethodCall.MACRO_RETURN_TYPE[MethodCall.MACRO_RETURNS_DOUBLE_IND]);
      if (maxMacros > 0) {
        d_writer.println("double  " + MethodCall.ARRAY_DOUBLE_RESULT_VAR + "["
                         + maxMacros + "];");
        totalMacros += maxMacros;
      } else {
        d_writer.println("double  " + MethodCall.ARRAY_DOUBLE_RESULT_VAR + ";");
      }
      maxMacros = m
        .getMaxArrayIterMacros(MethodCall.MACRO_RETURN_TYPE[MethodCall.MACRO_RETURNS_INTEGER_IND]);
      if (maxMacros > 0) {
        d_writer.println("int32_t " + MethodCall.ARRAY_INTEGER_RESULT_VAR + "["
                         + maxMacros + "];");
        totalMacros += maxMacros;
      }
      if (totalMacros > 0) {
        d_writer.println("int32_t " + MethodCall.ARRAY_COUNT_VAR + ", "
                         + MethodCall.ARRAY_ITER_VAR + ", " + MethodCall.ARRAY_SIZE_VAR
                         + ";");
      }
      boolean doAssertBegin = ((numInv > 0) || (numPre > 0));
      boolean doAssertEnd = ((numInv > 0) || (numPost > 0));
      if (doAssertBegin && doAssertEnd) {
        d_writer.println("struct timeval  aBegin, aEnd;");
      } else if (doAssertBegin) {
        d_writer.println("struct timeval  aBegin;");
      } else if (doAssertEnd) {
        d_writer.println("struct timeval  aEnd;");
      }
      d_writer.println("struct timeval  mBegin, mEnd;");
      d_writer.println("char*           errMsg;");
      d_writer.println(IOR.getExceptionFundamentalType() +
                       "throwaway_exception;");
      if (numInv > 0) {
        generateAssertionViolation(Assertion.INVARIANT, ASSERT_DECLARE, null,
                                   excvar);
      }
      if (numPre > 0) {
        generateAssertionViolation(Assertion.REQUIRE, ASSERT_DECLARE, null,
                                   excvar);
      }
      if (numPost > 0) {
        generateAssertionViolation(Assertion.ENSURE, ASSERT_DECLARE, null,
                                   excvar);
      }

      d_writer.println();
      d_writer.println(IOR.getMethodControlsStruct(id) + " *mc = ");
      d_writer.tab();
      d_writer.println("&" + getBaseMethodControls(ctrlBase, methIndex) + ";");
      d_writer.backTab();

      d_writer.println(timingVar + " = (" + ctrlBase + IOR.D_CHECKS
                       + " & CHECK_TIMING) && (" + methBase + IOR.D_COUNTDOWN + " >= 0);");
      if (hasThrows) {
        d_writer.println("(*" + s_exception_var + ") = NULL;");
      }
      d_writer.printlnUnformatted("#ifdef " + IOR.S_FULL_STATS_MACRO);
      d_writer.println(methBase + IOR.D_CALLS + " += 1;");
      d_writer
        .printlnUnformatted("#endif /* " + IOR.S_FULL_STATS_MACRO + " */");
      d_writer.println();

      d_writer.println("if (" + methBase + IOR.D_COUNTDOWN + " > 0) {");
      d_writer.tab();
      // d_writer.println("/* Fast path since not time to check yet */");
      d_writer.println(methBase + IOR.D_COUNTDOWN + " -= 1;");
      generateBaseCall(name, var, args, isStatic, hasThrows, type, false);
      if (hasThrows) {
        d_writer.println("if ((*" + s_exception_var + ") != NULL) {");
        d_writer.tab();
        generateStatisticsUpdate(ctrlBase, methBase, "1", "0", "0", "0");
        d_writer.backTab();
        d_writer.println("}");
      }
      d_writer.backTab();
      d_writer.println("} else {");
      d_writer.tab();
      // d_writer.println("/* Slower path since it is time to perform the "
      // + "checks */");
      if (doAssertBegin) {
        d_writer.println("if (" + timingVar + ") { gettimeofday(&aBegin, NULL);"
                         + " }");
      }
      if (numPre > 0) {
        d_writer.println("if (" + ctrlBase + IOR.D_CHECKS
                         + " & CHECK_PRECONDITIONS) {");
        d_writer.tab();
        generateAssertionChecks(preconditions, bvar, isStatic, excvar);
        d_writer.backTab();
        d_writer.println("}");
      }
      if (numInv > 0) {
        d_writer.println("if (" + ctrlBase + IOR.D_CHECKS
                         + " & CHECK_INVARIANTS) {");
        d_writer.tab();
        generateAssertionChecks(invariants, bvar, isStatic, excvar);
        d_writer.backTab();
        d_writer.println("}");
      }
      d_writer.println("if (" + timingVar + ") { gettimeofday(&mBegin, NULL); }");

      if (hasThrows) {
        d_writer.println("if (" + s_asserts_okay + ") {");
        d_writer.tab();
      }

      generateBaseCall(name, var, args, isStatic, hasThrows, type, false);
      if (hasThrows) {
        d_writer.println("if ((*" + s_exception_var + ") != NULL) {");
        d_writer.tab();
        d_writer.println(s_methods_okay + " = 0;");
        d_writer.backTab();
        d_writer.println("}");
        d_writer.backTab();
        d_writer.println("}");
      }

      if (doAssertEnd) {
        d_writer.println("if (" + timingVar + ") { gettimeofday(&mEnd, NULL); }");
      } else {
        d_writer.println("if (" + timingVar + ") {");
        d_writer.tab();
        d_writer.println("gettimeofday(&mEnd, NULL);");
      }

      /*
       * ToDo...Really need to properly handle inherited postconditions (i.e.,
       * used to weaken the contract NOT strengthen)!
       */
      if (numPost > 0) {
        d_writer.println("if (" + s_asserts_okay + " && (" + ctrlBase
                         + IOR.D_CHECKS + " & CHECK_POSTCONDITIONS)) {");
        d_writer.tab();
        generateAssertionChecks(postconditions, bvar, isStatic, excvar);
        d_writer.backTab();
        d_writer.println("}");
      }
      if (numInv > 0) {
        d_writer.println("if (" + ctrlBase + IOR.D_CHECKS
                         + " & CHECK_INVARIANTS) {");
        d_writer.tab();
        generateAssertionChecks(invariants, bvar, isStatic, excvar);
        d_writer.backTab();
        d_writer.println("}");
      }
      if (doAssertEnd) {
        d_writer.println("if (" + timingVar + ") {");
        d_writer.tab();
        d_writer.println("gettimeofday(&aEnd, NULL);");
        d_writer.println();
      }
      String assertTime;
      String methodTime = "SIDL_DIFF_MICROSECONDS(mEnd,mBegin)";
      String timeMacroStart = "SIDL_DIFF_MICROSECONDS(";
      if (doAssertBegin && doAssertEnd) {
        assertTime = timeMacroStart + "aEnd,aBegin)";
      } else if (doAssertBegin) {
        assertTime = timeMacroStart + "mEnd,aBegin)";
      } else if (doAssertEnd) {
        assertTime = timeMacroStart + "aEnd,mBegin)";
      } else {
        assertTime = timeMacroStart + "mEnd,mBegin)";
      }
      generateStatisticsUpdate(ctrlBase, methBase, s_asserts_okay,
                               s_methods_okay, methodTime, assertTime);
      d_writer.backTab();
      d_writer.println("} else {");
      d_writer.tab();
      generateStatisticsUpdate(ctrlBase, methBase, s_asserts_okay,
                               s_methods_okay, "0", "0");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
    } else {
      generateBaseCall(name, var, args, isStatic, hasThrows, type, false);
    }
    if (hasReturn) {
      d_writer.println();
      d_writer.println("return " + C.FUNCTION_RESULT + ";");
    }
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Generate a return string for the specified SIDL type. Most of the SIDL
   * return strings are listed in the static structures defined at the start of
   * this class. Symbol types and array types require special processing.
   */
01318   private String getReturnString(Type type)
    throws CodeGenerationException {
    return IOR.getReturnString(type, d_context, true, false);
  }

  /**
   * Returns the next set of starting indices after those in the specified
   * assertion.
   */
01327   private int[] getNextStartInd(Assertion as, int[] startInd) {
    int[] nextStartInd = new int[MethodCall.MAX_VALID_MACRO_RETURNS];
    for (int i = 0; i < MethodCall.MAX_VALID_MACRO_RETURNS; i++) {
      nextStartInd[i] = startInd[i]
        + as.getNumArrayIterMacrosByType(MethodCall.MACRO_RETURN_TYPE[i]);
    }
    return nextStartInd;
  }

  /**
   * Generate the assertion checks associated with the list of assertions.
   */
01339   private void generateAssertionChecks(List assertions, String var,
                                       boolean doStatic, String excvar) {
    if (!assertions.isEmpty()) {
      boolean first = true;
      Iterator i = assertions.iterator();
      int[] startInd = new int[MethodCall.MAX_VALID_MACRO_RETURNS];
      for (int j = 0; j < MethodCall.MAX_VALID_MACRO_RETURNS; j++) {
        startInd[j] = 0;
      }
      while (i.hasNext()) {
        Assertion as = (Assertion) i.next();
        String expr = as.cExpression(var, startInd);
        if ((expr != null) && (!expr.equals(""))) {
          generateAssertion(as, var, startInd, doStatic, expr, excvar, first);
          first = false;
        }
        startInd = getNextStartInd(as, startInd);
      }
    }
  }

  /**
   * Generate the assertion check.
   */
01363   private void generateAssertion(Assertion as, String var, int[] startInd,
                                 boolean doStatic, String expr, String excvar, boolean first) {
    List mlist = as.getArrayIterMacros(var, startInd);
    int numIterMacros = (mlist != null) ? mlist.size() : 0;
    boolean extraIndent = false;
    if (!first) {
      if (numIterMacros <= 0) {
        try {
          d_writer.pushLineBreak(false);
          d_writer.println("else if (!" + expr + ") {");
        }
        finally {
          d_writer.popLineBreak();
        }
      } else {
        d_writer.println("if ( " + s_asserts_okay + " ) {");
        extraIndent = true;
        d_writer.tab();
        generateArrayIterMacros(mlist);
        try {
          d_writer.pushLineBreak(false);
          d_writer.println("if (!" + expr + ") {");
        }
        finally {
          d_writer.popLineBreak();
        }
      }
    } else {
      if (numIterMacros > 0) {
        generateArrayIterMacros(mlist);
      }
      try {
        d_writer.pushLineBreak(false);
        d_writer.println("if (!" + expr + ") {");
      }
      finally {
        d_writer.popLineBreak();
      }
    }
    d_writer.tab();
    d_writer.println(s_asserts_okay + "  = 0;");
    try {
      d_writer.pushLineBreak(false);
      d_writer.println("errMsg = \"" + as.errorMessage() + "\";");
      generateCheckErrorCall(as, var, doStatic);
    }
    finally {
      d_writer.popLineBreak();
    }
    if (!excvar.equals("")) {
      d_writer.println("if ((*" + excvar + ") == NULL) {");
      d_writer.tab();
      generateAssertionViolation(as.getType(), ASSERT_RAISE, as, excvar);
      d_writer.backTab();
      d_writer.println("}");
    }
    if (extraIndent) {
      d_writer.backTab();
      d_writer.println("}");
    }
    d_writer.backTab();
    d_writer.println("}");
  }

  /**
   * Generate the array iteration macro calls.
   */
01430   private void generateArrayIterMacros(List list) {
    Iterator i = list.iterator();
    try {
      d_writer.pushLineBreak(false);
      while (i.hasNext()) {
        String mac = (String) i.next();
        d_writer.println(mac);
      }
    }
    finally {
      d_writer.popLineBreak();
    }
  }

  /**
   * Generate the appropriate assertion violation code based on genType as
   * follows: ASSERT_DECLARE = Generate the assertion violation variable
   * declaration ASSERT_RAISE = Generate the assertion violation instantiation
   * Note that as and excVar are only needed when ASSERT_RAISE is specified.
   */
01450   private void generateAssertionViolation(int assertType, int genType,
                                          Assertion as, String excvar) {
    String prefix;
    String errStr;
    String errType;
    switch (assertType) {
    case Assertion.REQUIRE:
    case Assertion.REQUIRE_ELSE:
      errStr = "pre_err";
      errType = IOR.getPreconditionExceptType();
      prefix = IOR.PRECONDITION_CALL_PREFIX;
      break;
    case Assertion.ENSURE:
    case Assertion.ENSURE_THEN:
      errStr = "post_err";
      errType = IOR.getPostconditionExceptType();
      prefix = IOR.POSTCONDITION_CALL_PREFIX;
      break;
    case Assertion.INVARIANT:
    default:
      errStr = "inv_err";
      errType = IOR.getInvariantExceptType();
      prefix = IOR.INVARIANT_CALL_PREFIX;
    }
    if (genType == ASSERT_DECLARE) {
      d_writer.println(errType + errStr + ";");
    } else {
      d_writer.println(errStr + " = " + prefix + "__create(&throwaway_exception);");
      d_writer.println(prefix + "_setNote(" + errStr + ", errMsg, &throwaway_exception);");
      d_writer.println("(*" + excvar + ") = " + IOR.FUND_EXCEPTION_CALL_PREFIX
                       + "__cast(" + errStr + ", &throwaway_exception);");
      d_writer.println(prefix + "_deleteRef(" + errStr + ", &throwaway_exception);");
    }
  }

  /**
   * Return the specified built-in error check function pointer name.
   */
01488   private String getBuiltinErrorCheckFunctionPtr(boolean doStatic) {
    return IOR.getVectorEntry(IOR.getBuiltinName(IOR.CHECK_ERROR, doStatic));
  }

  /**
   * Generate call to the specified assertion error method implemented by the
   * user.
   */
01496   private void generateCheckErrorCall(Assertion as, String var, boolean doStatic) {
    // d_writer.print("((*" + var + ")->");
    d_writer.print("(" + var + "->");
    d_writer.print(getBuiltinErrorCheckFunctionPtr(doStatic) + ")(");
    if (!doStatic) {
      d_writer.print(s_self + ", ");
    }
    d_writer.println("errMsg, &throwaway_exception);");
  }

  /**
   * Return the specified built-in error check function name.
   */
01509   private String getBuiltinHooksName(SymbolID id, boolean doStatic) {
    return getIORMethodName(id, IOR.getBuiltinName(IOR.HOOKS, doStatic));
  }

  /**
   * Generate the specified function to set hooks activation.
   */
01516   private void generateHooksFunction(Class cls, boolean doStatic) 
    throws CodeGenerationException {
    
    String desc = doStatic ? "static " : "";
    comment("HOOKS: set " + desc + "hooks activation.");

    SymbolID id = cls.getSymbolID();
    d_writer.println("static void " + getBuiltinHooksName(id, doStatic) + '(');
    d_writer.tab();
    if (!doStatic) {
      d_writer.println(IOR.getObjectName(id) + "* " + s_self + ",");
    }
    d_writer.println("int on, " 
                     + IOR.getExceptionFundamentalType() + "*_ex ) { ");
    
    String base = getBaseControls(doStatic, s_self) + ".";
    d_writer.println("*_ex = "+C.NULL+";");
    if (d_context.getConfig().generateHooks()) {
      if (!doStatic) {
        d_writer.println();
        d_writer.println("/* Ensure the EPVs are set properly. */");
        if (IOR.supportAssertions(cls, d_context)) {
          String checks = base + IOR.D_CHECKS;
          String rate = base + IOR.D_RATE;
          d_writer.print(getSetChecksMethodName(id, doStatic) + "(");
          d_writer.print(s_self + ", ");
          d_writer.println(checks + ", " + rate + ", 0, _ex);");
        } else {
          String publicepv = s_self + "->" + IOR.getEPVVar(IOR.PUBLIC_EPV);
          d_writer.println("if (on) {"); 
          d_writer.tab();
          d_writer.println(publicepv + "  = &"
            + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_HOOKS) + ";");
          d_writer.backTab();
          d_writer.println("} else {");
          d_writer.tab();
          d_writer.println(publicepv + "  = &"
            + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
          d_writer.backTab();
          d_writer.println("}");
          d_writer.println("");
        }
      } else {  //setting static
        String use = base + IOR.D_HOOKS;
        d_writer.println(use + " = on;");
      }
    } else {
      comment("Nothing else to do since hooks support not needed.");
    }

    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Returns the name of the hooks method for the specified method.
   */
01574   private String getHooksMethodName(Extendable ext, Method meth) {
    return "hooks_" + IOR.getSymbolName(ext.getSymbolID()) + '_'
      + meth.getLongMethodName();
  }

  /**
   * Generate all hooks functions. These are the functions that invoke the
   * internal pre- and post-method calls before invoking the actual call. It is
   * assumed these methods are only generated when hooks generation is enabled.
   */
01584   private void generateAllHooks(Class cls) throws CodeGenerationException {
    List normal = (List) cls.getMethods(false);
    Iterator i = normal.iterator();
    Method meth = null;
    while (i.hasNext()) {
      meth = (Method) i.next();
      generateHooks(cls, meth);
    }
  }

  /**
   * Generate the hooks method associated with the specified method.
   */
01597   private void generateHooks(Class cls, Method meth)
    throws CodeGenerationException {
    SymbolID id = cls.getSymbolID();
    String name = meth.getLongMethodName();
    String methname = getHooksMethodName(cls, meth);
    Type type = meth.getReturnType();
    String retStr = getReturnString(type);
    String var;
    boolean hasReturn = false;
    if ((type != null) && (type.getType() != Type.VOID)) {
      hasReturn = true;
    }
    comment("Sandwich the execution of the method between the pre- and post- "
            + "calls.");
    d_writer.println("static " + retStr + " " + methname + "(");
    d_writer.tab();
    List args = meth.getArgumentList();
    boolean hasThrows = !meth.getThrows().isEmpty();
    boolean isStatic = meth.isStatic();
    IOR.generateArguments(d_writer, d_context,
                          IOR.getObjectName(id) + "* " + s_self, args,
                        isStatic, hasThrows, type, true, true, false, false);
    d_writer.println(")");
    d_writer.backTab();

    d_writer.println("{");
    d_writer.tab();

    boolean addBlank = false;
    if (hasReturn) {
      d_writer.println(retStr + " " + C.FUNCTION_RESULT + " = "+IOR.getInitialValue(type)+";");
      addBlank = true;
    }
    String preEPV = null;
    String postEPV = null;
    if (isStatic) {
      var = "sepv";
      preEPV = "(&"+s_preSEPV+")";
      postEPV = "(&"+s_postSEPV+")";
      d_writer.println(IOR.getSEPVName(id) + "* " + var + " = "
                       + IOR.getLocalStaticsName(id) + "("
                       + IOR.getStaticTypeOption(id, IOR.SET_PUBLIC) + ");");
      addBlank = true;
    } else {
      if (IOR.supportAssertions(cls, d_context)) {
        var = s_self + "->" + IOR.getEPVVar(IOR.BASE_EPV);
      } else {
        var = "epv";
        preEPV = "(&"+s_preEPV+")";
        postEPV = "(&"+s_postEPV+")";
        d_writer.println(IOR.getEPVName(id) + "* " + var + " = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
        addBlank = true;
      }
    }
    if (addBlank) {
      d_writer.println();
    }
    Method pre = meth.spawnPreHook(true);
    Method post = meth.spawnPostHook(true,true);

    generateBaseCall(pre.getLongMethodName(),preEPV, pre.getArgumentList(), 
                     pre.isStatic(), !pre.getThrows().isEmpty(), 
                     pre.getReturnType(), true);
    d_writer.println("SIDL_CHECK(*_ex);");
    generateBaseCall(name,var, args, isStatic, hasThrows, type, false);
    d_writer.println("SIDL_CHECK(*_ex);");
    generateBaseCall(post.getLongMethodName(), postEPV, post.getArgumentList(), 
                     post.isStatic(), !post.getThrows().isEmpty(), 
                     post.getReturnType(), true);

    d_writer.printUnformatted("EXIT:\n");
    if (hasReturn) {
      d_writer.println();
      d_writer.println("return " + C.FUNCTION_RESULT + ";");
    } else {
      d_writer.println();
      d_writer.println("return;");
    }
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Call the destructor for the object and then deallocate the associated
   * storage using <code>free</code>.
   */
01685   private void generateDeleteFunction(Class cls) {
    comment("DELETE: call destructor and free object memory.");

    SymbolID id = cls.getSymbolID();
    String name = IOR.getSymbolName(id);

    d_writer.println("static void ior_" + name + '_' + s_deleteBuiltin + '(');
    d_writer.tab();
    d_writer.println(IOR.getObjectName(id) + "* self, " + IOR.getExceptionFundamentalType() + "*_ex)");
    d_writer.backTab();

    d_writer.println("{");
    d_writer.tab();

    d_writer.println("*_ex = NULL; /* default to no exception */");
    d_writer.println(IOR.getFiniName(id) + "(self,_ex);");
    d_writer.println("memset((void*)self, 0, sizeof(" + IOR.getObjectName(id)
                     + "));");
    d_writer.println("free((void*) self);");

    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * @param cls
   */
01713   private void generateMainExec(Class cls) {
    SymbolID id = cls.getSymbolID();
    String my_symbolName = IOR.getSymbolName(id);
    d_writer.println("struct " + my_symbolName + "__method {");
    d_writer.tab();
    d_writer.println("const char *d_name;");
    d_writer.println("void (*d_func)(struct " + my_symbolName + "__object*,");
    d_writer.tab();
    d_writer.println("struct sidl_rmi_Call__object *,");
    d_writer.println("struct sidl_rmi_Return__object *,");
    d_writer.println(IOR.getExceptionFundamentalType() + "*);");
    d_writer.backTab();
    d_writer.backTab();
    d_writer.println("};");
    d_writer.println();
    d_writer.println("static void");
    d_writer.println("ior_" + my_symbolName + "__exec(");
    d_writer.println("    struct " + my_symbolName + "__object* self,");
    d_writer.println("    const char* methodName,");
    d_writer.println("    struct sidl_rmi_Call__object* inArgs,");
    d_writer.println("    struct sidl_rmi_Return__object* outArgs,");
    d_writer.println("    " + IOR.getExceptionFundamentalType() + "*_ex ) { ");
    d_writer.tab();
    List methods = new ArrayList(cls.getMethods(true));
    Collections.sort(methods, new IOR.CompareMethods());
    d_writer.println("static const struct " + my_symbolName
                     + "__method  s_methods[] = {");
    d_writer.tab();
    for (Iterator i = methods.iterator(); i.hasNext();) {
      Method m = (Method) i.next();
      if (!m.isStatic()) {
        d_writer.println("{ \"" + m.getLongMethodName() + "\", "
                         + my_symbolName + '_' + m.getLongMethodName() + "__exec }"
                         + (i.hasNext() ? "," : ""));
      }
    }
    d_writer.backTab();
    d_writer.println("};");
    d_writer.println("int i, cmp, l = 0;");
    d_writer.println("int u = sizeof(s_methods)/sizeof(struct " + my_symbolName
                     + "__method);");
    d_writer.println("*_ex = NULL; /* default to no exception */");
    d_writer.println("if (methodName) {");
    d_writer.tab();
    d_writer.writeCommentLine("Use binary search to locate method");
    d_writer.println("while (l < u) {");
    d_writer.tab();
    d_writer.println("i = (l + u) >> 1;");
    d_writer.println("if (!(cmp=strcmp(methodName, s_methods[i].d_name))) {");
    d_writer.tab();
    d_writer.println("(s_methods[i].d_func)(self, inArgs, outArgs, _ex); SIDL_CHECK(*_ex);");
    d_writer.println("return;");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println("else if (cmp < 0) u = i;");
    d_writer.println("else l = i + 1;");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.writeCommentLine("TODO: add code for method not found");
    try {
      d_writer.pushLineBreak(false);
      d_writer.println("SIDL_THROW(*_ex,sidl_PreViolation,\"method name not found\");");
    }
    finally {
      d_writer.popLineBreak();
    }
    d_writer.println("EXIT:");
    d_writer.println("return;");
    d_writer.backTab();
    d_writer.println("}");
  }

  /**
   * @param cls
   */
01790   private void generateNonblockingMethods(Class cls) throws CodeGenerationException {
    for (Iterator i = cls.getMethods(true).iterator(); i.hasNext();) {
      Method m = (Method) i.next();
      if ( m.getCommunicationModifier() == Method.NONBLOCKING) { 
        Method send = m.spawnNonblockingSend();
        Method recv = m.spawnNonblockingRecv();
        generateNonblockingMethod(cls, send);
        generateNonblockingMethod(cls, recv);

      }
    }
  }

  /**
   * @param cls
   * @param m
   */
01807   private void generateNonblockingMethod(Class cls, Method m) throws CodeGenerationException {
    SymbolID id = cls.getSymbolID();

    d_writer.print(IOR.getReturnString(m.getReturnType(), d_context,
                                       true, false));
    d_writer.println(" "+IOR.getMethodName(id,m.getLongMethodName())+
                     "(");
    String self = IOR.getObjectName(id) + "* self";
    List args = m.getArgumentList();
    Type retType = m.getReturnType();
    IOR.generateArguments(d_writer, d_context,
                          self, args, m.isStatic(), true, 
                        retType, true, true, false, false);
    d_writer.println(") {");
    d_writer.tab();
    if(retType.getType() != Type.VOID) {
      d_writer.println(IOR.getReturnString(retType, d_context) +
                       " _retval = "+
                       IOR.getInitialValue(retType)+";");
    }
    d_writer.println("sidl_BaseInterface _throwaway_exception=NULL;");
    d_writer.println("sidl_PreViolation pv = sidl_PreViolation__create(&_throwaway_exception);");
    try {
      d_writer.pushLineBreak(false);
      d_writer.println("sidl_PreViolation_setNote(pv,"+
                       "\"Nonblocking methods on local objects not yet supported\","+ 
                       "&_throwaway_exception);");
    }
    finally {
      d_writer.popLineBreak();
    }
    d_writer.println("*_ex = (sidl_BaseInterface) pv;");

    if(retType.getType() != Type.VOID) {
      d_writer.println("return _retval;");
    } else {
      d_writer.println("return;");
    }

    d_writer.backTab();
    d_writer.println("}");
  }

  /**
   * @param cls
   */
01853   private void generateGetURLFunction(Extendable ext) {
    SymbolID id = ext.getSymbolID();
    String my_symbolName = IOR.getSymbolName(id);

    d_writer.println("static char*");
    d_writer.println("ior_" + IOR.getRemoteGetURLName(id) + "(");
    d_writer.println("    struct " + my_symbolName + "__object* self,");
    d_writer.println("    " + IOR.getExceptionFundamentalType() + "*_ex) {");
    d_writer.tab();
    
    d_writer.println("char* ret = " + C.NULL + ";"); 
    d_writer
      .println("char* objid = sidl_rmi_InstanceRegistry_getInstanceByClass((sidl_BaseClass)self, _ex); SIDL_CHECK(*_ex);");
    d_writer.println("if(!objid) {");
    d_writer.tab();
    d_writer
      .println("objid = sidl_rmi_InstanceRegistry_registerInstance((sidl_BaseClass)self, _ex); SIDL_CHECK(*_ex);");
    d_writer.backTab();
    d_writer.println("}");

    d_writer.printlnUnformatted("#ifdef WITH_RMI");
    d_writer.println();
    d_writer
      .println("ret = sidl_rmi_ServerRegistry_getServerURL(objid, _ex); SIDL_CHECK(*_ex);");
    d_writer.println();
    d_writer.printlnUnformatted("#else");
    d_writer.println();
    d_writer
      .println("ret = objid;");
    d_writer.println();
    d_writer.printlnUnformatted("#endif /*WITH_RMI*/");

    d_writer.println("return ret;");
    d_writer.println("EXIT:");

    d_writer.println("return NULL;");
    d_writer.backTab();
    d_writer.println("}");
  }

  /**
   * @param cls
   */
01896   private void generateIsLocalIsRemote(Extendable ext) {
    SymbolID id = ext.getSymbolID();
    String my_symbolName = IOR.getSymbolName(id);

    d_writer.println("static void");
    d_writer.println("ior_" + IOR.getRaddRefName(id) + "(");
    d_writer.println("    struct " + my_symbolName + "__object* self, sidl_BaseInterface* _ex) {");
    d_writer.tab();

    d_writer.println("sidl_BaseInterface_addRef((sidl_BaseInterface)self, _ex);");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println("");

    d_writer.println("static sidl_bool");
    d_writer.println("ior_" + IOR.getRemoteIsRemoteName(id) + "(");
    d_writer.println("    struct " + my_symbolName + "__object* self, sidl_BaseInterface* _ex) {");
    d_writer.tab();

    d_writer.println("*_ex = NULL; /* default to no exception */");
    d_writer.println("return FALSE;");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println("");
  }

  /**
   * Call the destructor for the object and then deallocate the associated
   * storage using <code>free</code>.
   */
01926   private void generateSuperFunction(Class cls) {
    comment("SUPER: returns parent's non-overrided EPV");

    SymbolID id = cls.getSymbolID();
    Class parent = cls.getParentClass();
    if (parent != null) {
      SymbolID pid = parent.getSymbolID();

      d_writer.println("static " + IOR.getEPVName(pid) + "* "
                       + IOR.getSymbolName(id) + '_' + s_superBuiltin + "(void) {");
      d_writer.tab();
      d_writer.println("return "
                       + IOR.getStaticEPVVariable(pid, IOR.EPV_OLD, IOR.SET_PUBLIC) + ";");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println();
    }
  }

  /**
   * Generate the function that initializes the method entry point vector for
   * this class. This class performs three functions. First, it saves the EPVs
   * from the parent classes and interfaces (assuming there is a parent).
   * Second, it fills the EPV for this class using information from the parent
   * (if there is a parent, and NULL otherwise). It then calls the skeleton
   * method initialization function for the EPV. Third, this function resets
   * interface EPV pointers and parent EPV pointers to use the correct function
   * pointers from the class EPV structure.
   */
01955   private void generateInitEPV(Class cls) throws CodeGenerationException {
    comment("EPV: create method entry point vector (EPV) structure.");

    /*
     * Declare the method signature and open the implementation body.
     */
    SymbolID id = cls.getSymbolID();
    String name = IOR.getSymbolName(id);
    String object = IOR.getObjectName(id);

    d_writer.println("static void " + name + "__init_epv(void)");

    d_writer.println("{");
    comment("assert( " + IOR.getHaveLockStaticGlobalsMacroName() + " );");
    d_writer.tab();

    /*
     * Output entry point vectors aliases for each parent class and interface as
     * well as a special one for the current object.
     */
    List parents = Utilities.sort(Utilities.getAllParents(cls));
    aliasEPVs(cls, parents);

    /*
     * Output pointers to the parent classes to simplify access to their data
     * structures.
     */
    if (cls.getParentClass() != null) {
      generateParentEPVs(cls, 0, 0);
      d_writer.println();
    }

    Class parent = cls.getParentClass();
    if (parent != null) {
      generateGetParentEPVs(parent);
      
      /*
       * Save all parent interface and class EPVs in static pointers.
       */
      comment("Here we alias the static epvs to some handy small names");
      saveEPVs(parent, 1);
      d_writer.println();
    }
    

    /*
     * Generate a list of the nonstatic methods in the class and get the width
     * of every method name.
     */
    List methods = (List) cls.getNonstaticMethods(true);
    int mwidth = Math.max(Utilities.getWidth(methods), s_longestBuiltin)
      + IOR.getVectorEntry("").length() + IOR.GENERIC_POST_SUFFIX.length();

    /*
     * Output builtin methods.
     */
    for (int j = 0; j < IOR.CLASS_BUILTIN_METHODS; j++) {
      if (IOR.isBuiltinBasic(j)
          || (IOR.isBuiltinAssert(j) && IOR.supportAssertions(cls, d_context))
          || ((j == IOR.HOOKS))) {
        String mname = IOR.getBuiltinName(j);
        d_writer.print("epv->");
        d_writer.printAligned(IOR.getVectorEntry(mname), mwidth);
        if ((j == IOR.CONSTRUCTOR) || (j == IOR.DESTRUCTOR)
            || (j == IOR.CHECK_ERROR) || (j == IOR.CONSTRUCTOR2)) {
          d_writer.println(" = " + C.NULL + ";");
        } else {
          d_writer.println(" = " + getIORMethodName(id, mname) + ';');
        }
      }
    }

    /*
     * Output the class methods.
     */
    generateNonstaticMethods(cls, object, methods, "epv", parent, mwidth);

    /*
     * Iterate through all parent EPVs and set each of the function pointers to
     * use the corresponding function in the parent EPV structure.
     */
    HashMap renames = new HashMap();
    IOR.resolveRenamedMethods(cls, renames);
    copyEPVs(parents, renames);
    d_writer.println("s_method_initialized = 1;");
    d_writer.println("ior_" + name + "__ensure_load_called();");

    /*
     * Close the function definition.
     */
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Generate the non-static methods for the specified class.
   */
02053   private void generateNonstaticMethods(Class cls, String object, List methods,
                                        String var, Class parent, int mwidth) throws CodeGenerationException {
    SymbolID id = cls.getSymbolID();

    /*
     * Iterate through all of the nonstatic methods. Assign them to NULL if the
     * parent class does not have the method and to the parent function pointer
     * if the parent has the method.
     */
    for (Iterator i = methods.iterator(); i.hasNext();) {
      Method method = (Method) i.next();
      String mname = method.getLongMethodName();
      boolean parentHas = ((parent != null) && (parent.hasMethodByLongName(
                                                                           mname, true)));
      generateNonstaticMethod(cls, method, object, var, mname, parentHas,
                              mwidth);
      if ( method.getCommunicationModifier() == Method.NONBLOCKING) { 
        Method send = method.spawnNonblockingSend();
        if ( send != null ) { 
          mname = send.getLongMethodName();
          parentHas = ((parent != null) && (parent.hasMethodByLongName(
                                                                       mname, true)));
          assignNonblockingPointer(cls, send, mwidth); 
        }
        Method recv = method.spawnNonblockingRecv();
        if ( recv != null ) { 
          mname = recv.getLongMethodName();
          parentHas = ((parent != null) && (parent.hasMethodByLongName(
                                                                       mname, true)));
          assignNonblockingPointer(cls, recv, mwidth); 
        }
      }
    }
    d_writer.println();

    /*
     * Call the user initialization function to set up the EPV structure.
     */
    if(IOR.supportHooks(id, d_context)) {
      d_writer.println(IOR.getSetEPVName(id) + "(" + var + ",&"+s_preEPV+",&"+s_postEPV+");");
    } else {
      d_writer.println(IOR.getSetEPVName(id) + "(" + var + ");");
    }
    /*
     * Now, if necessary, clone the static that has been set up and overlay with
     * local methods for assertions and/or hooks.
     */
    String xEPV;
    d_writer.println();
    boolean addBlank = false;
    if (IOR.supportAssertions(cls, d_context)) {
      xEPV = "aepv";
      d_writer.println("memcpy((void*)" + xEPV + ", " + var + ", sizeof("
                       + IOR.getEPVName(id) + "));");
      generateEPVMethodAssignments(cls, IOR.SET_ASSERTIONS, xEPV, false);
      addBlank = true;
    }
    xEPV = "hepv";
    d_writer.println("memcpy((void*)" + xEPV + ", " + var + ", sizeof("
                     + IOR.getEPVName(id) + "));");
    if (IOR.supportHooks(cls, d_context)) {
      if (addBlank) {
        d_writer.println();
        addBlank = false;
      }
      generateEPVMethodAssignments(cls, IOR.SET_HOOKS, xEPV, false);
      addBlank = true;
    }
    if (addBlank) {
      d_writer.println();
    }
  }

  /**
   * Generate the non-static method epv entry(ies) for the method.
   */
02129   private void generateNonstaticMethod(Extendable ext, Method m, String object,
                                       String var, String name, boolean parentHas, int width)
    throws CodeGenerationException {
    String ename = IOR.getVectorEntry(name);
    generateNonstaticEPV(m, object, var, ename, parentHas, width);
  }

  /**
   * Generate a nonblocking single assignment in initialization of the EPV pointer
   *
   * TODO: This kludge should probably be removed when we figure out how we
   * want to do nonblocking for local objects prememntly.  This just
   * generates an exception
   * 
   * TODO: doHooks?
   * @param name
   *          String name of the extendable
   * @param method
   *          The method in the EPV to initialzie
   * @param mwidth
   *          formatting parameter related to width of longest method name
   * @param doHooks
   *          trigger for extra semantic code generation
   */
02153   private void assignNonblockingPointer(Class cls, Method method, int mwidth) {
    //      boolean doHooks) {
    String mname = method.getLongMethodName();
    String ename = IOR.getVectorEntry(mname);
    //     if (doHooks) {
    //       d_writer.print("epv->");
    //       d_writer.printAligned(ename + IOR.GENERIC_PRE_SUFFIX, mwidth);
    //       d_writer.println(" = " + C.NULL + ";");
    //       d_writer.print("epv->");
    //       d_writer.printAligned(ename, mwidth);
    //       d_writer.println(" = ior_" + name + "_" + mname + ";");
    //       d_writer.print("epv->");
    //       d_writer.printAligned(ename + IOR.GENERIC_POST_SUFFIX, mwidth);
    //       d_writer.println(" = " + C.NULL + ";");
    //     } else {
    d_writer.print("epv->");
    d_writer.printAligned(ename, mwidth);
    d_writer.println(" = " + IOR.getMethodName(cls.getSymbolID(), method.getLongMethodName()) + ";");
    //    }
  }


  /**
   * Generate the non-static method epv entry for the method.
   */
02178   private void generateNonstaticEPV(Method m, String object, String var,
                                    String ename, boolean parentHas, int width)
    throws CodeGenerationException {
    d_writer.print(var + "->");
    d_writer.printAligned(ename, width);
    if (parentHas) {
      d_writer.print(" = ");
      d_writer.print(IOR.getCast(m, object + "*", d_context));
      d_writer.println(" s1->" /*+ IOR.getEPVVar(IOR.PUBLIC_EPV) + "->"*/ + ename
                       + ";");
    } else {
      d_writer.println(" = " + C.NULL + ";");
    }
  }

  /**
   * Generate the function that initializes the static entry point vector
   * (assuming the class contains static methods). If the parent class contains
   * static methods, then copy the pointers from the parent class, since static
   * methods are "inherited" from the parent (in a funny kinda way). Call the
   * skeleton-supplied function to initialize the remaining static methods.
   */
02200   private void generateInitSEPV(Class cls) throws CodeGenerationException {
    if (cls.hasStaticMethod(true)) {
      comment("SEPV: create the static entry point vector (SEPV).");

      /*
       * Define the method signature and begin the method body.
       */
      SymbolID id = cls.getSymbolID();
      String name = IOR.getSymbolName(id);
      int width = name.length();

      d_writer.println("static void " + name + "__init_sepv(void)");
      d_writer.println("{");
      d_writer.tab();
      comment("assert( " + IOR.getHaveLockStaticGlobalsMacroName() + " );");

      d_writer.println(IOR.getExceptionFundamentalType() + "throwaway_exception = NULL;");

      /*
       * Get information about the parent (if it exists and has static methods).
       */
      Class parent = cls.getParentClass();
      SymbolID pid = null;
      boolean includeParent = (parent != null) && parent.hasStaticMethod(true);
      boolean doAsserts = IOR.supportAssertions(cls, d_context);
      boolean doHooks = IOR.supportHooks(cls, d_context);

      if (includeParent) {
        pid = parent.getSymbolID();
        int w = IOR.getSymbolName(pid).length();
        if (w > width) {
          width = w;
        }
      }
      width += "struct __sepv*".length() + 1;

      /*
       * Create pointers to the local static EPV structure and one to the parent
       * SEPV structure (if the parent exists and has static members).
       */
      d_writer.printAligned(IOR.getSEPVName(id) + "*", width);
      d_writer.println(" s = &"
                       + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_PUBLIC) + ";");
      if (doAsserts) {
        d_writer.printAligned(IOR.getSEPVName(id) + "*", width);
        d_writer.println("as = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_ASSERTIONS)
                         + ";");
      }
      //      if (doHooks) {
      d_writer.printAligned(IOR.getSEPVName(id) + "*", width);
      d_writer
        .println("hs = &"
                 + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_HOOKS)
                 + ";");
      //}
      if (includeParent) {
        d_writer.printAligned(IOR.getSEPVName(pid) + "*", width);
        d_writer.println(" p = " + IOR.getStaticsName(pid) + "();");
      }
      d_writer.println();

      String var = "s";
      /*
       * Output builtin methods.
       */
      for (int j = 0; j < IOR.CLASS_BUILTIN_METHODS; j++) {
        if (IOR.hasStaticBuiltin(j)
            && ((IOR.isBuiltinAssert(j) && doAsserts) || (j == IOR.HOOKS))) {
          String mname = IOR.getBuiltinName(j, true);
          d_writer.print(var + "->");
          d_writer.printAligned(IOR.getVectorEntry(mname), width);
          if ((IOR.CHECKS == j) || (IOR.HOOKS == j) || (IOR.DUMP_STATS == j)) {
            d_writer.println(" = " + getIORMethodName(id, mname) + ';');
          } else {
            d_writer.println(" = " + C.NULL + ";");
          }
        }
      }

      /*
       * Output the static methods.
       */
      generateStaticMethods(cls, var, parent);

      /*
       * Initialize the remainder of the static functions by calling the
       * skeleton initialization routine.
       */
      if (doHooks) {
        d_writer.println(IOR.getSetSEPVName(id) + "(" + var + ", &"+s_preSEPV+
                         ", &"+s_postSEPV+");");
      } else {
        d_writer.println(IOR.getSetSEPVName(id) + "(" + var + ");");
      }
      d_writer.println();

      /*
       * If necessary, initialize the static assertion and/or hooks functions as
       * well.
       */
      String sEPV;
      boolean addBlank = false;
      sEPV = "hs";
      d_writer.println("memcpy((void*)" + sEPV + ", " + var + ", sizeof("
                       + IOR.getSEPVName(id) + "));");

      d_writer.println();
      if (doHooks) {
        d_writer.println(getBuiltinHooksName(id, true) + "(TRUE" +
                         ", &throwaway_exception);");
      } else {
        d_writer.println(getBuiltinHooksName(id, true) + "(FALSE" +
                         ", &throwaway_exception);");
      }

      if (doHooks) {
        generateEPVMethodAssignments(cls, IOR.SET_HOOKS, sEPV, true);
        d_writer.println();
        if (doAsserts) {
          d_writer.println(getBaseControls(true, "") + "." + IOR.D_HOOKS
                           + " = " + IOR.DEFAULT_OPTION_HOOKS + ";");
        }
        addBlank = true;
      }
      if (doAsserts) {
        if (addBlank) {
          d_writer.println();
        }
        sEPV = "as";
        d_writer.println("memcpy((void*)" + sEPV + ", " + var + ", sizeof("
                         + IOR.getSEPVName(id) + "));");
        generateEPVMethodAssignments(cls, IOR.SET_ASSERTIONS, sEPV, true);
        d_writer.println();
        d_writer.println("{");
        d_writer.tab();
        d_writer.println(IOR.getExceptionFundamentalType() + "throwaway_exception;");
        d_writer.println(getSetChecksMethodName(id, true) + "("
                         + IOR.DEFAULT_CHECK_LEVEL + ", " + IOR.DEFAULT_THRESHOLD + ", 0, &throwaway_exception);");
        d_writer.backTab();
        d_writer.println("}");
        
        addBlank = true;
      }
      if (addBlank) {
        d_writer.println();
      }
      d_writer.println("s_static_initialized = 1;");
      d_writer.println("ior_" + name + "__ensure_load_called();");

      /*
       * Close the initialization guard and end the function body.
       */
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println();
    }
  }

  /**
   */
  private void generateEnsureLoad(Class cls) {
    SymbolID id = cls.getSymbolID();
    String name = IOR.getSymbolName(id);

    d_writer
      .println("static void ior_" + name + "__ensure_load_called(void) {");
    d_writer.tab();
    comment("assert( " + IOR.getHaveLockStaticGlobalsMacroName() + " );");
    d_writer.println("if (! s_load_called ) {");
    d_writer.tab();
    d_writer.println("s_load_called=1;");
    d_writer.println(name + "__call_load();");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.backTab();
    d_writer.println("}");
  }

  /**
   * Generate the static methods for the specified class.
   */
02382   private void generateStaticMethods(Class cls, String var, Class parent)
    throws CodeGenerationException {
    List methods = (List) cls.getStaticMethods(true);
    int mwidth = Utilities.getWidth(methods) + IOR.getVectorEntry("").length()
      + IOR.GENERIC_SUFFIX_MAXLEN + var.length() + 2;
    /*
     * Iterate through all of the static methods. Assign them to NULL if the
     * parent class does not have the method and to the parent function pointer
     * if the parent has the method.
     */
    for (Iterator i = methods.iterator(); i.hasNext();) {
      Method method = (Method) i.next();
      String mname = method.getLongMethodName();
      boolean parentHas = ((parent != null) && (parent.hasMethodByLongName(
                                                                           mname, true)));
      String ename = IOR.getVectorEntry(mname);
      generateStaticEPV(var, ename, parentHas, mwidth);
    }
    d_writer.println();
  }

  /**
   * Generate the static method epv entry for the method.
   */
02406   private void generateStaticEPV(String var, String ename, boolean parentHas,
                                 int mwidth) throws CodeGenerationException {
    d_writer.print(var + "->");
    d_writer.printAligned(ename, mwidth);
    if (parentHas) {
      d_writer.println(" = p->" + ename + ";");
    } else {
      d_writer.println(" = " + C.NULL + ";");
    }
  }

  /**
   * Generate the appropriate assertion or hooks methods assignments.
   */
02420   void generateEPVMethodAssignments(Extendable ext, int setType, String ptrVar,
                                    boolean doStatics) {
    List methods = (doStatics ? (List) ext.getStaticMethods(false) : (List) ext
                    .getNonstaticMethods(false));
    Iterator i = methods.iterator();
    Method m = null;
    String mName, tName;
    int mwidth = Math.max(Utilities.getWidth(methods), s_longestBuiltin)
      + IOR.getVectorEntry("").length() + ptrVar.length() + 2;
    while (i.hasNext()) {
      m = (Method) i.next();
      mName = m.getLongMethodName();
      d_writer.printAligned(ptrVar + "->" + IOR.getVectorEntry(mName), mwidth);
      tName = (setType == IOR.SET_ASSERTIONS) ? getCheckMethodName(ext, m)
        : getHooksMethodName(ext, m);
      d_writer.println(" = " + tName + ";");
    }
  }

  /**
   * Generate the appropriate assertion or hooks methods assignments.
   */
02442   void generateEPVMethodAssignments(Extendable p_ext, Extendable ext, int setType, String ptrVar,
                                    boolean doStatics) throws CodeGenerationException {
    List methods = (doStatics ? (List) ext.getStaticMethods(false) : (List) ext
                    .getNonstaticMethods(false));
    Iterator i = methods.iterator();
    Method m = null;
    String mName, tName;
    int mwidth = Math.max(Utilities.getWidth(methods), s_longestBuiltin)
      + IOR.getVectorEntry("").length() + ptrVar.length() + 2;
    while (i.hasNext()) {
      m = (Method) i.next();
      mName = m.getLongMethodName();
      d_writer.printAligned(ptrVar + "->" + IOR.getVectorEntry(mName), mwidth);
      tName = (setType == IOR.SET_ASSERTIONS) ? getCheckMethodName(ext, m)
        : getHooksMethodName(ext, m);
      d_writer.println(" = " + tName + ";");
    }
  }


  /**
   * Generate a function that will return a pointer to the static entry point
   * vector. This function is called by clients to get access to static methods
   * in the class. If this class has no static methods, then do not generate an
   * implementation.
   */
02468   private void generateStaticFunction(Class cls, boolean doLocal) throws CodeGenerationException {
    boolean doAsserts = IOR.supportAssertions(cls, d_context);
    boolean doHooks = IOR.supportHooks(cls, d_context);

    if (cls.hasStaticMethod(true) && ((!doLocal) || (doAsserts || doHooks))) {
      String desc = doLocal ? "specified " : "";
      comment("STATIC: return pointer to " + desc + "static EPV structure.");

      SymbolID id = cls.getSymbolID();
      String name = IOR.getSymbolName(id);

      d_writer.println(IOR.getSEPVName(id) + "*");
      if (doLocal) {
        d_writer.println(IOR.getLocalStaticsName(id) + "(int type)");
      } else {
        d_writer.println(IOR.getStaticsName(id) + "(void)");
      }
      d_writer.println("{");
      d_writer.tab();

      if (doAsserts || doHooks) {
        d_writer.println(IOR.getSEPVName(id) + "* sepv;");
      }

      d_writer.println(IOR.getLockStaticGlobalsMacroName() + ";");

      d_writer.println("if (!s_static_initialized) {");
      d_writer.tab();
      d_writer.println(name + "__init_sepv();");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println(IOR.getUnlockStaticGlobalsMacroName() + ";");

      boolean cont = false;
      if (doAsserts) {
        cont = true;
        if (doLocal) {
          d_writer.println("if (type == "
                           + IOR.getStaticTypeOption(id, IOR.SET_ASSERTIONS) + ") {");
        } else {
          d_writer.println("if (" + getBaseControls(true, "") + "."
                           + IOR.D_CHECKS + " & CHECK_ASSERTIONS) {");
        }
        d_writer.tab();
        d_writer.println("sepv = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_ASSERTIONS)
                         + ";");
        d_writer.backTab();
        d_writer.print("}");
      }
      if (doHooks) {
        if (cont) {
          d_writer.print(" else ");
        }
        if (doLocal) {
          d_writer.println("if (type == "
                           + IOR.getStaticTypeOption(id, IOR.SET_HOOKS) + ") {");
        } else {
          d_writer.println("if (" + getBaseControls(true, "") + "."
                           + IOR.D_HOOKS + ") {");
        }
        d_writer.tab();
        d_writer
          .println("sepv = &"
                   + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_HOOKS)
                   + ";");
        d_writer.backTab();
        d_writer.print("}");
      }
      if (doAsserts || doHooks) {
        d_writer.println(" else {");
        d_writer.tab();
        d_writer.println("sepv = &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_PUBLIC)
                         + ";");
        d_writer.backTab();
        d_writer.println("}");
        d_writer.println("return sepv;");
      } else {
        d_writer.println("return &"
                         + IOR.getStaticEPVVariable(id, IOR.EPV_STATIC, IOR.SET_PUBLIC)
                         + ";");
      }
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println();
    }
  }

  private void generateInitClassInfo(Class cls) {
    if (!cls.isAbstract()) {
      if (d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println("static void");
        d_writer.println("cleanupClassInfo(void *ignored) {");
        d_writer.tab();
        d_writer.println(IOR.getExceptionFundamentalType() + "throwaway_exception = NULL;");
        d_writer.println("if (s_classInfo) {");
        d_writer.tab();
        if (d_classInfoI.equals(cls.getSymbolID())) {
          d_writer.println(IOR.getObjectName(d_baseClass) +
                           " *bc = " +
                           C.getFullMethodName(d_baseClass, "_cast")
                           + "(s_classInfo, &throwaway_exception);");
          d_writer.println(C.getDataName(d_baseClass) + " *data = " 
                           + C.getDataGetName(d_baseClass) + "(bc);" );
          d_writer.println("if (data && data->d_classinfo) {");
          d_writer.tab();
          d_writer.println(IOR.getObjectName(d_classInfo) + "* ci = data->d_classinfo;");
          d_writer.println("data->d_classinfo = NULL;");
          d_writer.println(C.getFullMethodName(d_baseClass, "deleteRef") +
                           "(bc, &throwaway_exception);");
          d_writer.println(C.getFullMethodName(d_classInfo, "deleteRef") +
                           "(ci, &throwaway_exception);");
          d_writer.backTab();
          d_writer.println("}");
        }
        d_writer.println(C.getFullMethodName(d_classInfo, "deleteRef") +
                         "(s_classInfo, &throwaway_exception);");
        d_writer.backTab();
        d_writer.println("}");
        d_writer.println("s_classInfo = NULL;");
        d_writer.println("s_classInfo_init = 1;");
        d_writer.backTab();
        d_writer.println("}");
        d_writer.println();
        d_writer.println("static void initMetadata("
                         + IOR.getObjectName(cls.getSymbolID()) + "*," + IOR.getExceptionFundamentalType() + "*_ex);");
        d_writer.println();
      }
      comment("initClassInfo: create a ClassInfo interface if necessary.");
      d_writer.println("static void");
      d_writer.println("initClassInfo(" + C.getObjectName(d_classInfo)
                       + " *info, " + IOR.getExceptionFundamentalType() + "*_ex)");
      d_writer.println("{");
      d_writer.tab();
      if (!d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println(IOR.getLockStaticGlobalsMacroName() + ";");
      } else {
        d_writer.writeCommentLine("ClassInfo for ClassInfoI is a special case");
        d_writer.writeCommentLine(IOR.getUnlockStaticGlobalsMacroName() + ";");
      }
      d_writer.println("*_ex = NULL; /* default to no exception */");
      if (!d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println("if (!s_classInfo) {");
      }
      else {
        d_writer.println("if (s_classInfo_init) {");
      }
      d_writer.tab();
      d_writer.println(C.getObjectName(d_classInfoI) + " impl;");
      if (d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println("s_classInfo_init = 0;");
      }
      d_writer.println("impl = " + C.getFullMethodName(d_classInfoI, "_create")
                       + "(_ex);");
      d_writer.println("s_classInfo = "
                       + C.getFullMethodName(d_classInfo, "_cast") + "(impl,_ex);");
      d_writer.println("if (impl) {");
      d_writer.tab();
      d_writer.println(C.getFullMethodName(d_classInfoI, "setName")
                       + "(impl, \"" + cls.getFullName() + "\", _ex);");
      d_writer.println(C.getFullMethodName(d_classInfoI, "setVersion")
                       + "(impl, \"" + 
                       cls.getSymbolID().getVersion().getVersionString() +
                       "\", _ex);");
      d_writer.println(C.getFullMethodName(d_classInfoI, "setIORVersion")
                       + "(impl, s_IOR_MAJOR_VERSION, s_IOR_MINOR_VERSION, _ex);");
      if (d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println("initMetadata(impl,_ex);");
      }
      d_writer.println(C.getFullMethodName(d_classInfoI, "deleteRef") +
                       "(impl,_ex);");
      if (d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println("sidl_atexit(cleanupClassInfo, NULL);");
      }
      else {
        d_writer.println("sidl_atexit(sidl_deleteRef_atexit, &s_classInfo);");
      }
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
      if (!d_classInfoI.equals(cls.getSymbolID())) {
        d_writer.println(IOR.getUnlockStaticGlobalsMacroName() + ";");
      } else {
        d_writer.writeCommentLine("ClassInfo for ClassInfoI is a special "
                                  + "case");
        d_writer.writeCommentLine(IOR.getUnlockStaticGlobalsMacroName() + ";");
      }
      d_writer.println("if (s_classInfo) {");
      d_writer.tab();
      d_writer.println("if (*info) {");
      d_writer.tab();
      d_writer.println(C.getFullMethodName(d_classInfo, "deleteRef")
                       + "(*info,_ex);");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println("*info = s_classInfo;");
      d_writer.println(C.getFullMethodName(d_classInfo, "addRef") + "(*info,_ex);");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.println();
    }
  }

  private void generateInitMetadata(Class cls) {
    if (!cls.isAbstract()) {
      SymbolID id = cls.getSymbolID();
      Class parent;
      String object = IOR.getObjectName(id);
      comment("initMetadata: store IOR version & class in sidl.BaseClass's "
              + "data");
      d_writer.println("static void");
      d_writer.println("initMetadata(" + object + "* " + s_self + ", sidl_BaseInterface* _ex)");
      d_writer.println("{");
      d_writer.tab();
      d_writer.println("*_ex = 0; /* default no exception */");
      d_writer.println("if (" + s_self + ") {");
      d_writer.tab();
      d_writer.print(C.getDataName(d_baseClass) + " *data = (" +
                     C.getDataName(d_baseClass) + "*)((*" + 
                     s_self + ")");
      parent = cls.getParentClass();
      while (parent != null) {
        d_writer.print(".d_" + IOR.getSymbolName(parent.getSymbolID()).
                       toLowerCase());
        parent = parent.getParentClass();
      }
      d_writer.println("." + IOR.D_DATA + ");");
      d_writer.println("if (data) {");
      d_writer.tab();
      d_writer.println("data->d_IOR_major_version = s_IOR_MAJOR_VERSION;");
      d_writer.println("data->d_IOR_minor_version = s_IOR_MINOR_VERSION;");
      d_writer.println("initClassInfo(&(data->d_classinfo),_ex); SIDL_CHECK(*_ex);");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("}");
      d_writer.backTab();
      d_writer.println("EXIT:");
      d_writer.println("return;");
      d_writer.println("}");
      d_writer.println();
    }
  }

  /**
   * Allocate the memory for a new instance of the class and then call the
   * constructor (initializer) on the object. This method is not output for
   * abstract classes.
   */
02721   private void generateNewFunction(Class cls) {
    if (!cls.isAbstract()) {
      comment("NEW: allocate object and initialize it.");

      SymbolID id = cls.getSymbolID();
      String object = IOR.getObjectName(id);

      d_writer.println(object + "*");
      d_writer.println(IOR.getNewName(id) + "(void* ddata, " +
                       IOR.getExceptionFundamentalType() +
                       "* _ex)");//sidl_BaseInterface* _ex)");
      d_writer.println("{");
      d_writer.tab();

      d_writer.println(object + "* " + s_self + " =");
      d_writer.tab();
      d_writer.println("(" + object + "*) sidl_malloc(");
      d_writer.tab();
      d_writer.println("sizeof(" + object + "),");
      try {
        d_writer.pushLineBreak(false);
        d_writer.println("\"Object allocation failed for " + object + "\",");
      }
      finally {
        d_writer.popLineBreak();
      }
      d_writer.println("__FILE__, __LINE__, \"" +
                       IOR.getNewName(id) + "\",");
      d_writer.println("_ex);");
      d_writer.backTab();
      d_writer.backTab();
      d_writer.println("if (!" + s_self +") goto EXIT;");

      d_writer.println(IOR.getInitName(id) + "(" + s_self + ", ddata, _ex); SIDL_CHECK(*_ex);");
      d_writer.println("initMetadata(" + s_self + ", _ex); SIDL_CHECK(*_ex);");
      d_writer.println("return " + s_self + ";");
      d_writer.println("EXIT:");
      d_writer.println("return NULL;");

      d_writer.backTab();
      d_writer.println("}");
      d_writer.println();
    }
  }

  /**
   * Generate the initialization function that acts as the constructor for a
   * class object. The logic is as follows. First, if there is a parent for this
   * class, call its constructor. Then, make sure that the EPVs have been
   * initialized. If there are parents, make sure that all parent EPVs are
   * updated to point to the corrected EPVs. Then initialize the new interfaces
   * in this object. Finally, call the user-defined constructor.
   */
02774   private void generateInitFunction(Class cls) throws CodeGenerationException {
    comment("INIT: initialize a new instance of the class object.");

    /*
     * Declare the method signature and open the implementation body.
     */
    SymbolID id = cls.getSymbolID();
    d_writer.println("void " + IOR.getInitName(id) + "(");
    d_writer.tab();
    d_writer.println(IOR.getObjectName(id) + "* " + s_self + ",");
    d_writer.println(" void* ddata,");
    d_writer.println("" + IOR.getExceptionFundamentalType() + "*_ex)");
    d_writer.backTab();

    d_writer.println("{");
    d_writer.tab();

    /*
     * Output parent pointers to simplify access to parent classes.
     */
    generateParentSelf(cls, 0, 0);
    d_writer.println();
    d_writer.println("*_ex = 0; /* default no exception */");

    //JIM MOVED
    /*
     * Ensure that the EPV has been initialized.
     */
    d_writer.println(IOR.getLockStaticGlobalsMacroName() + ";");
    d_writer.println("if (!s_method_initialized) {");
    d_writer.tab();
    d_writer.println(IOR.getInitEPVName(id) + "();");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println(IOR.getUnlockStaticGlobalsMacroName() + ";");
    d_writer.println();


    /*
     * If there is a parent class, then call its constructor.
     */
    Class parent = cls.getParentClass();
    if (parent != null) {
      d_writer.println(IOR.getInitName(parent.getSymbolID()) + "(s1, NULL, _ex); SIDL_CHECK(*_ex);");
      d_writer.println();
    }


    /*
     * Modify the EPVs in parent classes and their interfaces.
     */
    fixEPVs(cls, 0, true);

    /*
     * Iterate through the interfaces defined in this class and allocate the
     * symbol identifier and set the self pointer.
     */
    List interfaces = Utilities.sort(Utilities.getUniqueInterfaceIDs(cls));
    for (Iterator i = interfaces.iterator(); i.hasNext();) {
      SymbolID iid = (SymbolID) i.next();
      String name = IOR.getSymbolName(iid).toLowerCase();
      d_writer.println("s0->d_" + name + ".d_object = " + s_self + ";");
      d_writer.println();
    }

    /*
     * Finally, set the state and data pointer for this class and allocate the
     * symbol identifier.
     */
    d_writer.println("s0->" + IOR.D_DATA + " = " + C.NULL + ";");
    d_writer.println();

    if (IOR.supportHooks(cls, d_context)) {
      d_writer.println(getBuiltinHooksName(id, false) + "(s0, "
                       + "TRUE, _ex);");
    } else {
      d_writer.println(getBuiltinHooksName(id, false) + "(s0, "
                       + "FALSE, _ex);");
    }

    if (IOR.supportHooks(cls, d_context)) {
      if (IOR.supportAssertions(cls, d_context)) {
        d_writer.println("s0->" + IOR.D_CONTROLS + "." + IOR.D_HOOKS + " = "
                         + IOR.DEFAULT_OPTION_HOOKS + ";");
      } 
    }
    if (IOR.supportAssertions(cls, d_context)) {
      d_writer.println("{");
      d_writer.tab();
      d_writer.println(IOR.getExceptionFundamentalType() + "throwaway_exception;");
      d_writer.println(getSetChecksMethodName(id, false) + "(s0, "
                       + IOR.DEFAULT_CHECK_LEVEL + ", " + IOR.DEFAULT_THRESHOLD + ", 0, &throwaway_exception);");
      d_writer.backTab();
      d_writer.println("}");
    }
    d_writer.println();


    /*
     * Call the user constructor now that the object has been constructed.
     * If ddata is null, otherwise, just stick data in 
     */
    d_writer.println("if(ddata) {");
    d_writer.tab();
    d_writer.println("self->d_data = ddata;");
    d_writer.println(methodCall(cls, s_self, IOR.getBuiltinName(IOR.CONSTRUCTOR2), 
                                ",ddata,_ex") + " SIDL_CHECK(*_ex);");

    d_writer.backTab();
    d_writer.println("} else { ");
    d_writer.tab();
    d_writer.println(methodCall(cls, s_self, IOR.getBuiltinName(IOR.CONSTRUCTOR), 
                                ",_ex") + " SIDL_CHECK(*_ex);");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println("EXIT:");
    d_writer.println("return;");

    /*
     * Close the function definition.
     */
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Generate the finalization function that acts as the destructor for a class
   * object. The logic is as follows. First, call the user-defined destructor
   * for the object. Deallocate all identifiers for this object. If there are
   * parents, reset the EPVs to their previous values and call the parent
   * destructor.
   */
02907   private void generateFiniFunction(Class cls) throws CodeGenerationException {
    comment("FINI: deallocate a class instance (destructor).");

    /*
     * Declare the method signature and open the implementation block.
     */
    SymbolID id = cls.getSymbolID();
    d_writer.println("void " + IOR.getFiniName(id) + "(");
    d_writer.tab();
    d_writer.println(IOR.getObjectName(id) + "* " + s_self + ",");
    d_writer.println(IOR.getExceptionFundamentalType() + "*_ex)");
    d_writer.backTab();

    d_writer.println("{");
    d_writer.tab();

    /*
     * Output parent pointers to simplify access to parent classes.
     */
    generateParentSelf(cls, 0, 0);
    d_writer.println();
    d_writer.println("*_ex = NULL; /* default to no exception */");

    /*
     * Call the user-defined destructor for this class.
     */
    d_writer.println(methodCall(cls, "s0", IOR.getBuiltinName(IOR.DESTRUCTOR),
                                ",_ex"));
 
    /*
     * If there is a parent class, then reset all parent pointers and call the
     * parent destructor.
     */
    Class parent = cls.getParentClass();
    if (parent != null) {
      d_writer.println("SIDL_CHECK(*_ex);");
      d_writer.println();
      fixEPVs(parent, 1, false);
      d_writer.println(IOR.getFiniName(parent.getSymbolID()) + "(s1, _ex); SIDL_CHECK(*_ex);");
      d_writer.println("EXIT:");  
    }
    
    d_writer.println("return;");
    /*
     * Close the function definition.
     */
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Generate the version function.
   */
02961   private void generateVersionFunction(Class cls) {
    comment("VERSION: Return the version of the IOR used to generate this "
            + "IOR.");

    /*
     * Declare the method signature and open the implementation block.
     */
    SymbolID id = cls.getSymbolID();
    d_writer.println("void");
    d_writer.println(IOR.getVersionName(id) + "(int32_t *major, int32_t *minor"
                     + ")");
    d_writer.println("{");
    d_writer.tab();
    d_writer.println("*major = s_IOR_MAJOR_VERSION;");
    d_writer.println("*minor = s_IOR_MINOR_VERSION;");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

  /**
   * Recursively output self pointers to the SIDL objects for this class and its
   * parents. The self pointers are of the form sN, where N is an integer
   * represented by the level argument. If the width is zero, then the width of
   * all parents is generated automatically.
   */
02987   private void generateParentSelf(Class cls, int level, int width) {
    if (cls != null) {

      /*
       * Calculate the width of this class and all parents for pretty output.
       * Ooh, very pretty.
       */
      if (width == 0) {
        Class parent = cls;
        while (parent != null) {
          int w = IOR.getObjectName(parent.getSymbolID()).length();
          if (w > width) {
            width = w;
          }
          parent = parent.getParentClass();
        }
      }

      /*
       * Now use the width information to print out symbols.
       */
      SymbolID id = cls.getSymbolID();
      d_writer.printAligned(IOR.getObjectName(id) + "*", width + 1);
      d_writer.print(" s" + String.valueOf(level) + " = ");
      if (level == 0) {
        d_writer.println(s_self + ";");
      } else {
        d_writer.print("&s" + String.valueOf(level - 1) + "->d_");
        d_writer.println(IOR.getSymbolName(id).toLowerCase() + ";");
      }
      generateParentSelf(cls.getParentClass(), level + 1, width);
    }
  }


  /**
   * Recursively output epv pointers to the SIDL objects for this class and its
   * parents. The self pointers are of the form sN, where N is an integer
   * represented by the level argument. If the width is zero, then the width of
   * all parents is generated automatically.
   */
03028   private void generateParentEPVs(Class cls, int level, int width) {
    if (cls != null) {

      /*
       * Calculate the width of this class and all parents for pretty output.
       * Ooh, very pretty.
       */
      if (width == 0) {
        Class parent = cls;
        while (parent != null) {
          int w = IOR.getEPVName(parent.getSymbolID()).length();
          if (w > width) {
            width = w;
          }
          parent = parent.getParentClass();
        }
      }

      /*
       * Now use the width information to print out symbols.
       * Get rid of the now unused s0 var. 
       */
      if(level != 0) {
        SymbolID id = cls.getSymbolID();
        d_writer.printAligned(IOR.getEPVName(id) + "*", width + 1);
        d_writer.println(" s" + String.valueOf(level) + " = "+C.NULL+";");

        d_writer.printAligned(IOR.getEPVName(id) + "*", width + 1);
        d_writer.println(" h" + String.valueOf(level) + " = "+C.NULL+";");

      }
      generateParentEPVs(cls.getParentClass(), level + 1, width);
    }
  }


  /*
   * Recursively modify the EPVs in parent classes and set up interface
   * pointers. Nothing is done if the class argument is null. The flag is_new
   * determines whether the EPVs are being set to a newly defined EPV or to a
   * previously saved EPV.
   */
  private void fixEPVs(Class cls, int level, boolean is_new) throws CodeGenerationException {
    if (cls != null) {
      fixEPVs(cls.getParentClass(), level + 1, is_new);

      /*
       * Update the EPVs for all of the new interfaces in this particular class.
       */
      String self = "s" + String.valueOf(level);
      int epvType = is_new ? IOR.EPV_NEW : IOR.EPV_OLD;
      String prefix = is_new ? "&" : "";
      List ifce = Utilities.sort(Utilities.getUniqueInterfaceIDs(cls));
      String epv = IOR.getEPVVar(IOR.PUBLIC_EPV);
      int width = Utilities.getWidth(ifce) + epv.length() + 3;
      String name;
      for (Iterator i = ifce.iterator(); i.hasNext();) {
        SymbolID id = (SymbolID) i.next();
        name = IOR.getSymbolName(id).toLowerCase();
        d_writer.print(self + "->");
        d_writer.printAligned("d_" + name + "." + epv, width);
        d_writer.print(" = ");
        d_writer.println(prefix
                         + IOR.getStaticEPVVariable(id, epvType, IOR.SET_PUBLIC) + ";");
      }

      /*
       * Modify the class entry point vector.
       */
      String rhs = prefix
        + IOR
        .getStaticEPVVariable(cls.getSymbolID(), epvType, IOR.SET_PUBLIC)
        + ";";
      d_writer.print(self + "->");
      d_writer.printAligned(epv, width);
      d_writer.println(" = " + rhs);
      if (IOR.supportBaseEPVAttr(cls, d_context)) {
        d_writer.print(self + "->");
        d_writer.printAligned(IOR.getEPVVar(IOR.BASE_EPV), width);
        d_writer.println(" = " + rhs);
      }
      d_writer.println();
    }
  }

  /*
   * Recursively save the class and interface EPVs in this class and all parent
   * classes. Nothing is done if the class argument is null.
   */
  private void saveEPVs(Class cls, int level) {
    if (cls != null) {
      saveEPVs(cls.getParentClass(), level + 1);

      /*
       * Save the EPVs for all of the new interfaces in this class.
       */
      String self = "s" + String.valueOf(level);
      String hself = "h" + String.valueOf(level);

      /*
       * Save the class entry point vector.
       */
      d_writer.print(self +"  =  ");
      d_writer.println(IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_OLD,
                                              IOR.SET_PUBLIC)+";");
      d_writer.print(hself +"  =  ");
      d_writer.println(IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_OLD,
                                              IOR.SET_HOOKS)+";");

    }
  }

  /**
   * Generate the entry point vector alias for each parent class and each
   * interface as well as a special one for the current object.
   */
03144   private void aliasEPVs(Class cls, Collection parents) throws CodeGenerationException {
    /*
     * Get the width of the symbols for pretty printing.
     */
    SymbolID id = cls.getSymbolID();
    String epv = IOR.getEPVName(id);

    int width = epv.length() + 2;
    int w = Utilities.getWidth(parents) + "struct __epv*".length();
    if (w > width) {
      width = w;
    }

    /*
     * Output the EPV pointer for this class and its class and interface
     * parents.
     */
    d_writer.printAligned(epv + "*", width);
    d_writer.println(" epv  = &"
                     + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");
    if (IOR.supportAssertions(cls, d_context)) {
      d_writer.printAligned(epv + "*", width);
      d_writer
        .println(" aepv = &"
                 + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_ASSERTIONS)
                 + ";");
    }
    //    if (IOR.supportHooks(cls)) {
      d_writer.printAligned(epv + "*", width);
      d_writer.println(" hepv = &"
                       + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_HOOKS) + ";");
      //}

    int e = 0;
    for (Iterator i = parents.iterator(); i.hasNext();) {
      SymbolID sid = (SymbolID) i.next();
      d_writer.printAligned(IOR.getEPVName(sid) + "*", width);
      d_writer.printAligned(" e" + String.valueOf(e), 4);
      d_writer.println("  = &"
                       + IOR.getStaticEPVVariable(sid, IOR.EPV_NEW, IOR.SET_PUBLIC) + ";");

      d_writer.printAligned(IOR.getEPVName(sid) + "*", width);
      d_writer.printAligned(" he" + String.valueOf(e), 4);
      d_writer.println("  = &"
                       + IOR.getStaticEPVVariable(sid, IOR.EPV_NEW, IOR.SET_HOOKS) + ";");
       ++e;
    }
    d_writer.println();
  }

  /*
   * Copy EPV function pointers from the most derived EPV data structure into
   * all parent class and interface EPVs.
   */
03198   private void copyEPVs(Collection parents, HashMap renames) throws CodeGenerationException {
    int e = 0;
    for (Iterator i = parents.iterator(); i.hasNext();) {
      /*
       * Extract information about the parent extendable object. Generate a list
       * of the nonstatic methods and calculate the width of every method name.
       */
      SymbolID id = (SymbolID) i.next();
      Extendable ext = (Extendable) Utilities.lookupSymbol(d_context, id);

      List methods = (List) ext.getNonstaticMethods(true);
      int mwidth = Math.max(Utilities.getWidth(methods), s_longestBuiltin)
        + IOR.getVectorEntry("").length();

      /*
       * Calculate the "self" pointer for the cast function.
       */
      String self = null;
      if (ext.isInterface()) {
        self = "void*";
      } else {
        self = IOR.getObjectName(id) + "*";
      }

      /*
       * Generate the assignments for the cast and delete functions.
       */
      String estring = "e" + String.valueOf(e) + "->";
      String vecEntry = IOR.getVectorEntry(s_castBuiltin);

      d_writer.print(estring);
      d_writer.printAligned(vecEntry, mwidth);
      d_writer.print(" = (void* (*)(" + self);
      d_writer.print(",const char*, struct sidl_BaseInterface__object**)) epv->");
      d_writer.print(vecEntry);
      d_writer.println(";");

      vecEntry = IOR.getVectorEntry(s_deleteBuiltin);
      d_writer.print(estring);
      d_writer.printAligned(vecEntry, mwidth);
      d_writer.println(" = (void (*)(" + self + ", " +
                       IOR.getExceptionFundamentalType() +
                       "*)) epv->" + vecEntry + ";");

      vecEntry = IOR.getVectorEntry(s_getURLBuiltin);
      d_writer.print(estring);
      d_writer.printAligned(vecEntry, mwidth);
      d_writer.println(" = (char* (*)(" + self + ", " + IOR.getExceptionFundamentalType() + "*)) epv->" + vecEntry + ";");

      vecEntry = IOR.getVectorEntry(s_raddRefBuiltin);
      d_writer.print(estring);
      d_writer.printAligned(vecEntry, mwidth);
      d_writer.println(" = (void (*)(" + self + ", " + IOR.getExceptionFundamentalType() + "*)) epv->" + vecEntry + ";");

      vecEntry = IOR.getVectorEntry(s_isRemoteBuiltin);
      d_writer.print(estring);
      d_writer.printAligned(vecEntry, mwidth);
      d_writer.println(" = (sidl_bool (*)(" + self + ", " + IOR.getExceptionFundamentalType() + "*)) epv->" + vecEntry
                       + ";");

      /**
       * Generate the assignment for exec function
       */
      vecEntry = IOR.getVectorEntry(s_execBuiltin);
      Method m_exec = IOR.getBuiltinMethod(IOR.EXEC, id, d_context, false);
      String ename = m_exec.getLongMethodName();
      d_writer.print(estring);
      d_writer.printAligned(IOR.getVectorEntry(ename), mwidth);
      d_writer.print(" = " + IOR.getCast(m_exec, self, d_context));
      d_writer.println(" epv->" + IOR.getVectorEntry(ename) + ";");

      /*
       * Iterate over all methods in the EPV and set the method pointer.
       */
      for (Iterator j = ext.getMethodsWithNonblocking(true).iterator(); j.hasNext();) {
        Method method = (Method) j.next();
        Method renamedMethod = (Method) renames.get(id.getFullName()+"."+
                                                    method.getLongMethodName());
        String oldname = method.getLongMethodName();
        String newname = null;
        if(renamedMethod != null) {
          newname = renamedMethod.getLongMethodName();
        } else { 
          newname = method.getLongMethodName();
        }
        d_writer.print(estring);
        d_writer.printAligned(IOR.getVectorEntry(oldname), mwidth);
        d_writer.print(" = " + IOR.getCast(method, self, d_context));
        d_writer.println(" epv->" + IOR.getVectorEntry(newname) + ";");
      }
      
      //JIM add in he stuff here?
      d_writer.println();
      d_writer.println("memcpy((void*) he" + e + ", e" + e + ", sizeof("
                       + IOR.getEPVName(id) + "));");
      //generateEPVMethodAssignments(ext, IOR.SET_HOOKS, "he"+e, false);
      /*
       * Iterate over all methods in the EPV and set the method pointer.
       * if we're using hooks
       */
      if(IOR.supportHooks(ext, d_context)) {
        for (Iterator j = methods.iterator(); j.hasNext();) {
          Method method = (Method) j.next();
          Method renamedMethod = (Method) renames.get(id.getFullName()+"."+
                                                      method.getLongMethodName());
          String oldname = method.getLongMethodName();
          String newname = null;
          if(renamedMethod != null) {
            newname = renamedMethod.getLongMethodName();
          } else { 
            newname = method.getLongMethodName();
          }
          d_writer.print("he" + e);
          d_writer.printAligned(IOR.getVectorEntry(oldname), mwidth);
          d_writer.print(" = " + IOR.getCast(method, self, d_context));
          d_writer.println(" hepv->" + IOR.getVectorEntry(newname) + ";");
        }
      }

      d_writer.println();
      e++;
    }
  }

  private void generateGetParentEPVs(Class parent) {
    d_writer.println(IOR.getGetEPVsName(parent.getSymbolID())+"(");
    d_writer.tab();
    listEPVs(parent, true);
    d_writer.println(");");
    d_writer.backTab();
  }

  private void listEPVs(Class cls, boolean first) {
    if (cls != null) {
      listEPVs(cls.getParentClass(), false);
      List ifce = Utilities.sort(Utilities.getUniqueInterfaceIDs(cls));
      for (Iterator i = ifce.iterator(); i.hasNext();) {
        SymbolID id = (SymbolID) i.next();
        d_writer.println("&"+IOR.getStaticEPVVariable(id, IOR.EPV_OLD, IOR.SET_PUBLIC)+",");
        d_writer.println("&"+IOR.getStaticEPVVariable(id, IOR.EPV_OLD, IOR.SET_HOOKS)+",");

      }
      d_writer.print("&"+IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_OLD, IOR.SET_PUBLIC)+",");
      d_writer.print("&"+IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_OLD, IOR.SET_HOOKS));

      if(!first){
        d_writer.println(",");
      } 
    }
  }
  //New JIM function
  private void declareGetEPVs(Class cls) {
    d_writer.println("void "+IOR.getGetEPVsName(cls.getSymbolID())+"(");
    d_writer.tab();
    IOR.declareEPVsAsArgs(d_writer, cls, true);
    d_writer.println(")");
    d_writer.backTab();
    d_writer.println("{");
    d_writer.tab();
    /*
     * Ensure that the EPV has been initialized.
     */
    d_writer.println(IOR.getLockStaticGlobalsMacroName() + ";");
    d_writer.println("if (!s_method_initialized) {");
    d_writer.tab();
    d_writer.println(IOR.getSymbolName(cls.getSymbolID()) + "__init_epv();");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println(IOR.getUnlockStaticGlobalsMacroName() + ";");
    d_writer.println();

    setEPVsInGetEPVs(cls);
    d_writer.backTab();
    d_writer.println("}");
        
  }

  public void setEPVsInGetEPVs(Class cls) {
    if (cls != null) {
      setEPVsInGetEPVs(cls.getParentClass());
      List ifce = Utilities.sort(Utilities.getUniqueInterfaceIDs(cls));
      for (Iterator i = ifce.iterator(); i.hasNext();) {
        SymbolID id = (SymbolID) i.next();
        d_writer.println("*"+IOR.getStaticEPVVariable(id, IOR.EPV_ARG, IOR.SET_PUBLIC)+
                         " = &" + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_PUBLIC)+";");
        d_writer.println("*"+IOR.getStaticEPVVariable(id, IOR.EPV_ARG, IOR.SET_HOOKS)+
                         " = &" + IOR.getStaticEPVVariable(id, IOR.EPV_NEW, IOR.SET_HOOKS)+";");

      }
      d_writer.println("*"+IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_ARG, IOR.SET_PUBLIC) +
                     " = &" +IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_NEW, IOR.SET_PUBLIC)+";");
      d_writer.println("*"+IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_ARG, IOR.SET_HOOKS) +
                     " = &" +IOR.getStaticEPVVariable(cls.getSymbolID(), IOR.EPV_NEW, IOR.SET_HOOKS)+";");
    }
  }

  private static String methodCall(Extendable ext, String var, String method,
                                   String args) {
    String result = "(*(" + var + "->" + IOR.getEPVVar(IOR.PUBLIC_EPV) + "->"
      + IOR.getVectorEntry(method) + "))(" + var;
    if (ext.isInterface()) {
      result += "->d_object";
    }
    result += args;
    result += ");";
    return result;
  }

  public static void generateExternalSignature(LanguageWriterForC lw,
                                               Symbol sym, String terminator) {
    final SymbolID id = sym.getSymbolID();
    lw.beginBlockComment(false);
    lw.println("This function returns a pointer to a static structure of");
    lw.println("pointers to function entry points.  Its purpose is to provide");
    lw.println("one-stop shopping for loading DLLs.");
    lw.endBlockComment(false);
    lw.println("const " + IOR.getExternalName(id) + "*");
    lw.println(IOR.getExternalFunc(id) + "(void)" + terminator);
  }

  private void generateExternalFunc(Symbol sym) {
    SymbolID id = sym.getSymbolID();
    Class cls = null;
    if (sym instanceof Class) {
      cls = (Class) sym;
      /*
       * if (IOR.supportHooks(cls) || IOR.supportAssertions(cls) ) {
       * d_writer.println("const " + IOR.getExternalName(id)); } else {
       */
      d_writer.println("static const " + IOR.getExternalName(id));
      /*
       * }
       */
    }
    d_writer.println("s_externalEntryPoints = {");
    d_writer.tab();
    if (sym instanceof Class) {
      if (!cls.isAbstract()) {
        d_writer.println(IOR.getNewName(id) + ",");
      }
      if (cls.hasStaticMethod(true)) {
        d_writer.println(IOR.getStaticsName(id) + ",");
      }
      if (cls.getParentClass() != null) {
        d_writer.println(IOR.getSymbolName(id) + "__super,");
      }
    }
    d_writer.println(Integer.toString(IOR.MAJOR_VERSION) + ", ");
    d_writer.println(Integer.toString(IOR.MINOR_VERSION));
    d_writer.backTab();
    d_writer.println("};");
    d_writer.println();
    generateExternalSignature(d_writer, sym, "");
    d_writer.println("{");
    d_writer.tab();
    d_writer.println("return &s_externalEntryPoints;");
    d_writer.backTab();
    d_writer.println("}");
    d_writer.println();
  }

}

Generated by  Doxygen 1.6.0   Back to index