Index: toba-1.1/History
diff -c toba-1.1/History:1.11 toba-1.1/History:1.13
*** toba-1.1/History:1.11	Sun Jul 26 12:25:28 1998
--- toba-1.1/History	Thu Oct 29 16:56:47 1998
***************
*** 1,5 ****
--- 1,8 ----
  Toba Version Log
  
+ 1.1a	October 27, 1998
+ 	Fixes for serialization, internationalization, networking
+ 
  1.1     July 31, 1998
          JDK 1.1 support
  
Index: toba-1.1/README
diff -c toba-1.1/README:1.9 toba-1.1/README:1.11
*** toba-1.1/README:1.9	Fri May  1 18:09:14 1998
--- toba-1.1/README	Mon Oct 26 13:32:31 1998
***************
*** 1,6 ****
  Toba README file
! March 6, 1998
! 
  
  This is Toba, a freely distributable system for translating Java
  code into C code.  Toba comes from the Sumatra Group, part of the
--- 1,5 ----
  Toba README file
! 30Oct98 -- Version 1.1a
  
  This is Toba, a freely distributable system for translating Java
  code into C code.  Toba comes from the Sumatra Group, part of the
***************
*** 11,35 ****
  of the Boehm-Dermers-Weiner conservative garbage collector.  It is 
  covered by its own copyright; see gc/README.
  
! The biss/biss-0.87 subdirectory, included by permission, is version 0.87 
! of the BISS AWT package.  Additionally the C and H files in the biss 
! subdirectory are derived from BISS AWT sources.  The BISS AWT is 
! covered by its own copyright; see biss/biss-0.87/LICENSE.BISS-AWT.
! 
! The first beta version of Toba was known as Juice.
  
  Documentation in HTML form is contained in the doc subdirectory.
  Installation instructions are given in the "install.html" file.
  
! Toba currently does not support Java version 1.1 or higher.
! To build Toba, you will need version 1.1.3 of the Java Developers Kit (JDK).
! For the Irix version, see
!     http://www.sgi.com/Fun/Free_webtools.html
! For Linux, see
!     http://www.blackdown.org/java-linux.html
! For Solaris and Windows NT, see
!     http://java.sun.com/products/JDK/1.1.3/index.html
! 
  
  Additional information about the Sumatra project may be found at
  http://www.cs.arizona.edu/sumatra/.
--- 10,27 ----
  of the Boehm-Dermers-Weiner conservative garbage collector.  It is 
  covered by its own copyright; see gc/README.
  
! The zlib and bnlib packages in ./SupFiles, and the BISS archives in ./biss,
! are distributed in original form in accordance with their respective
! copyrights.  The home sites for these packages are documented in
! doc/porting.html.  These supplementary systems will be unpacked, and in the
! cast of BISS patched to meet Toba's needs, during the configuration process;
! see doc/install.html.
  
  Documentation in HTML form is contained in the doc subdirectory.
  Installation instructions are given in the "install.html" file.
  
! Toba currently supports Java version 1.1.  Serialization is supported;
! reflection is not.
  
  Additional information about the Sumatra project may be found at
  http://www.cs.arizona.edu/sumatra/.
Index: toba-1.1/bin/toba.sh
diff -c toba-1.1/bin/toba.sh:1.37 toba-1.1/bin/toba.sh:1.38
*** toba-1.1/bin/toba.sh:1.37	Thu Jul 30 15:16:13 1998
--- toba-1.1/bin/toba.sh	Wed Oct 28 21:38:20 1998
***************
*** 239,245 ****
  trace export TOBAPATH
  
  # explicit or implicit CLASSPATH, before we add to it
! CPATH="${CLASSPATH:-.}"
  
  # set JAVA_HOME in the same way javac would
  PRG=`whereis ${JAVA}`
--- 239,255 ----
  trace export TOBAPATH
  
  # explicit or implicit CLASSPATH, before we add to it
! CPATH=''
! # Normally, we'd tack our stuff on _after_ the user's class path.  However,
! # when we've built for BISS, we've replaced certain classes in the standard
! # library with new versions, and if we end up looking at the old ones first,
! # bad things will happen.  So, if there's a BISSAPI directory, set the
! # first places we look to be where we put the retranslated classes.
! if [ -d ${PKGS}/BISSAPI ] ; then
!   CPATH="${PKGS}/SUNAPI/classes:${PKGS}/BISSAPI/classes:"
! fi
! # Now tack on the user's CLASSPATH as the next highest priority.
! CPATH="${CPATH}${CLASSPATH:-.}"
  
  # set JAVA_HOME in the same way javac would
  PRG=`whereis ${JAVA}`
Index: toba-1.1/configs/biss.linux.opt
diff -c toba-1.1/configs/biss.linux.opt:1.2 toba-1.1/configs/biss.linux.opt:1.3
*** toba-1.1/configs/biss.linux.opt:1.2	Tue Jul 28 15:14:54 1998
--- toba-1.1/configs/biss.linux.opt	Thu Oct 29 16:56:47 1998
***************
*** 1,6 ****
! # $Id: biss.linux.opt,v 1.2 1998/07/28 22:14:54 pab Exp $
  # Option overrides to build BISS on Linux
  OPTION_BISS = true
  JDK_SOURCE_DIR = @@JDK_SOURCE_DIR@@
! BISS_LDFLAGS = -L/usr/X11/lib -lX11 -lXext -lXaw
  BISS_INCLUDE_FLAG = -I../packages/BISSAPI/include
--- 1,7 ----
! # $Id: biss.linux.opt,v 1.3 1998/10/29 23:56:47 pab Exp $
  # Option overrides to build BISS on Linux
  OPTION_BISS = true
  JDK_SOURCE_DIR = @@JDK_SOURCE_DIR@@
! # This maybe should be -L/usr/X11/lib, depending on your installation
! BISS_LDFLAGS = -L/usr/X11R6/lib -lX11 -lXext -lXaw
  BISS_INCLUDE_FLAG = -I../packages/BISSAPI/include
Index: toba-1.1/packages/buildAPI
diff -c toba-1.1/packages/buildAPI:1.4 toba-1.1/packages/buildAPI:1.5
*** toba-1.1/packages/buildAPI:1.4	Mon Jul 27 10:39:36 1998
--- toba-1.1/packages/buildAPI	Thu Oct 29 16:56:47 1998
***************
*** 1,5 ****
  #!/bin/sh
! # $Id: buildAPI,v 1.4 1998/07/27 17:39:36 pab Exp $
  #
  # Script to automate the translation of Sun and BISS class files into
  # packages suitable for use by Toba.
--- 1,5 ----
  #!/bin/sh
! # $Id: buildAPI,v 1.5 1998/10/29 23:56:47 pab Exp $
  #
  # Script to automate the translation of Sun and BISS class files into
  # packages suitable for use by Toba.
***************
*** 74,79 ****
--- 74,85 ----
    done
  fi
  
+ # CLASS_INCLUDE: A set of additional classes that would otherwise be excluded,
+ # but that we want anyway.  Separate with single spaces.
+ # sun.io.ByteToCharISO8859_1 and its companion provide the JDK default
+ # conversion between Unicode characters and bytes.
+ CLASS_INCLUDE='sun.io.ByteToCharISO8859_1 sun.io.CharToByteISO8859_1'
+ 
  # Create an fgrep "pattern" file that we'll use to exclude what we don't
  # want to see.
  EXCLUDE="${JAVA_EXCLUDE} ${SUN_EXCLUDE} ${CLASS_EXCLUDE}"
***************
*** 118,125 ****
    | sed -e 's@^@^@' -e 's@$@$@' \
    | fgrep -v -f fgrep.in$$ \
    | sed -e 's@^^@@' -e 's@\$$@@' \
-   | sort \
    > api.core-${TAG}
  # If we're building BISS, we should add the BISS classes to the ones we
  # want.
  if ${OPTION_BISS} ; then
--- 124,136 ----
    | sed -e 's@^@^@' -e 's@$@$@' \
    | fgrep -v -f fgrep.in$$ \
    | sed -e 's@^^@@' -e 's@\$$@@' \
    > api.core-${TAG}
+ if [ -n "${CLASS_INCLUDE}" ] ; then
+   echo ${CLASS_INCLUDE} \
+     | tr ' ' '\012' \
+     >> api.core-${TAG}
+ fi
+ sort -o api.core-${TAG} api.core-${TAG}
  # If we're building BISS, we should add the BISS classes to the ones we
  # want.
  if ${OPTION_BISS} ; then
Index: toba-1.1/runtime/alloc.c
diff -c toba-1.1/runtime/alloc.c:1.10 toba-1.1/runtime/alloc.c:1.11
*** toba-1.1/runtime/alloc.c:1.10	Wed Jan 28 16:27:46 1998
--- toba-1.1/runtime/alloc.c	Tue Oct 27 14:50:20 1998
***************
*** 22,28 ****
  
  static Object memerror;			/* out-of-memory Error exception */
  
- 
  static void null_warn_proc(char *msg, GC_word arg) /*ARGSUSED*/ {}
  
  /* 
--- 22,27 ----
***************
*** 76,88 ****
      return;
  }
  
! 
  
  /*  memexit -- shut down memory interface  */
  
  void memexit(void)
  {
!     GC_finalize_all();
      return;
  }
  
--- 75,98 ----
      return;
  }
  
! static Boolean doRunFinalizers = JAVA_FALSE;
! /* This is java.lang.Runtime.runFinalizersOnExit, defined here so we don't
!  * have to make either that flag or a mutator function global. */
! Void
! runFinalizersOnExit0_z_osowt (Boolean arg1)
! {
!     doRunFinalizers = arg1;
! }
  
  /*  memexit -- shut down memory interface  */
  
  void memexit(void)
  {
!     /* Only run the finalizers if we were asked to do so.  By default,
!      * java doesn't. */
!     if (doRunFinalizers) {
!         GC_finalize_all();
!     }
      return;
  }
  
Index: toba-1.1/runtime/lang_Class.c
diff -c toba-1.1/runtime/lang_Class.c:1.9 toba-1.1/runtime/lang_Class.c:1.11
*** toba-1.1/runtime/lang_Class.c:1.9	Wed May  6 14:29:31 1998
--- toba-1.1/runtime/lang_Class.c	Mon Oct 26 12:32:42 1998
***************
*** 14,19 ****
--- 14,22 ----
  #include "java_lang_NoSuchMethodException.h"
  #include "classfile_ClassData.h"
  #include "java_io_Serializable.h"
+ 
+ static Object GetClassFromSignature(const Char *sig,int *cnt);
+ 
  #ifdef OPTION_JIT
  #include "toba_runtime_SystemClassLoader.h"
  
***************
*** 24,30 ****
  
  /* hash table with (classname -> instance of class Class) */
  static struct in_java_util_Hashtable *all_classes = 0;
- static Object GetClassFromSignature(const Char *sig,int *cnt);
  
  /* install a class in the hashtable (called during startup) */
  void
--- 27,32 ----
***************
*** 89,127 ****
      /* STATIC Method */
      init_java_lang_Class();
      
! #ifdef OPTION_JIT
!     /* This is the moral equivalent of systemclassloader.findSystemClass(c),
!      * which loads the class, followed by systemclassloader.resolveClass(c),
!      * which links it.  Don't call loadClass; we may not want to generate
!      * code.  findSystemClass knows whether defineClass is required or not,
!      * depending on where it found things. */
!     /* From empirical testing, this routine is not obliged to find classes
!      * that were loaded with something other than the system class loader. */
!     val = system_loader->class->M.findSystemClass_S_FLv3x.f(system_loader, arg1);
!     /* If the find failed, we threw an exception, right? */
!     assert (NULL != val);
!     system_loader->class->M.resolveClass_C_vKDXp.f(system_loader, val);
! #else /* OPTION_JIT */
      /* look it up in our hash table of all known classes */
      /* java_util_Hashtable get(Object, Object) */
      val = (struct in_java_lang_Class *)get_O_doAa7(all_classes, arg1);
  
      /* Try to find the class in the shared libraries */
!     if(!val)
          val = load_native_system_class(arg1);
  
      if (!val){
          int  x;
          Char *s = ((struct carray*)arg1->value)->data;
  	
  	/* find array classes */
!         if (s[0]=='[')
              return GetClassFromSignature(s,&x);
      }
      if(!val) {
          throwClassNotFoundException(cstring(arg1));
      }
- #endif /* OPTION_JIT */
      return val;
  }
  
--- 91,138 ----
      /* STATIC Method */
      init_java_lang_Class();
      
!     val = NULL;
!     
! #ifndef OPTION_JIT
      /* look it up in our hash table of all known classes */
      /* java_util_Hashtable get(Object, Object) */
      val = (struct in_java_lang_Class *)get_O_doAa7(all_classes, arg1);
+ #endif /* OPTION_JIT */
  
      /* Try to find the class in the shared libraries */
!     if(!val) {
          val = load_native_system_class(arg1);
+     }
  
+     /* No go.  See if it's an array class. */
      if (!val){
          int  x;
          Char *s = ((struct carray*)arg1->value)->data;
  	
  	/* find array classes */
!         if (s[0]=='[') {
              return GetClassFromSignature(s,&x);
+         }
      }
+ 
+ #ifdef OPTION_JIT
+     if (!val) {
+        /* This is the moral equivalent of systemclassloader.findSystemClass(c),
+         * which loads the class, followed by systemclassloader.resolveClass(c),
+         * which links it.  Don't call loadClass; we may not want to generate
+         * code.  findSystemClass knows whether defineClass is required or not,
+         * depending on where it found things. */
+        /* From empirical testing, this routine is not obliged to find classes
+         * that were loaded with something other than the system class loader. */
+        val = system_loader->class->M.findSystemClass_S_FLv3x.f(system_loader, arg1);
+        /* If the find failed, we threw an exception, right? */
+        assert (NULL != val);
+        system_loader->class->M.resolveClass_C_vKDXp.f(system_loader, val);
+     }
+ #endif /* OPTION_JIT */
      if(!val) {
          throwClassNotFoundException(cstring(arg1));
      }
      return val;
  }
  
Index: toba-1.1/runtime/lang_ClassLoader.c
diff -c toba-1.1/runtime/lang_ClassLoader.c:1.9 toba-1.1/runtime/lang_ClassLoader.c:1.10
*** toba-1.1/runtime/lang_ClassLoader.c:1.9	Tue Jul 28 15:14:55 1998
--- toba-1.1/runtime/lang_ClassLoader.c	Wed Oct 28 21:38:20 1998
***************
*** 117,127 ****
  Object	defineClass0_Sabii_vMwv8(Object Harg1,Object Harg2,Object Harg3,Int arg4,Int arg5) /* Since JDK1.1 */
  {
      struct in_java_lang_Class *ret;
!     Class c;
!     /* Throw out the name; we don't use it */
      ret = defineClass0_abii_v0LzF(Harg1,Harg3,arg4,arg5);
!     c  = find_class(ret);
!     c->name = Harg1;
      return ret;
  }
  
--- 117,136 ----
  Object	defineClass0_Sabii_vMwv8(Object Harg1,Object Harg2,Object Harg3,Int arg4,Int arg5) /* Since JDK1.1 */
  {
      struct in_java_lang_Class *ret;
!     Class cl;
!     /* In toba, the nameless version is primary; use that to define the
!      * class.  This sets the name from the class internal data somehow. */
      ret = defineClass0_abii_v0LzF(Harg1,Harg3,arg4,arg5);
!     cl  = find_class(ret);
!     /* Harg2, if not null, is the expected name of the class.  We could
!      * decide to override the compiled-in name; or, we could verify that
!      * the class name matches.  For now, we'll only use it if the class
!      * had no built-in name. */
!     if ((0 != Harg2) &&
!         (0 == cl->name)) {
!        cl->name = Harg2;
!     }
! 
      return ret;
  }
  
Index: toba-1.1/runtime/lang_Runtime.c
diff -c toba-1.1/runtime/lang_Runtime.c:1.14 toba-1.1/runtime/lang_Runtime.c:1.15
*** toba-1.1/runtime/lang_Runtime.c:1.14	Sat Apr 18 16:30:20 1998
--- toba-1.1/runtime/lang_Runtime.c	Tue Oct 27 14:50:20 1998
***************
*** 178,185 ****
      return 1;
  }
  
! Void	runFinalizersOnExit0_z_osowt(Boolean arg1) /* Unimplemented JDK1.1 */
! {
!     unimpl("runFinalizersOnExit0_z_osowt");
! }
  
--- 178,185 ----
      return 1;
  }
  
! /* This routine is defined in alloc.c to avoid namespace clutter.
! Void // see alloc.c
! runFinalizersOnExit0_z_osowt (Boolean arg1)
! */
  
Index: toba-1.1/runtime/lang_System.c
diff -c toba-1.1/runtime/lang_System.c:1.9 toba-1.1/runtime/lang_System.c:1.10
*** toba-1.1/runtime/lang_System.c:1.9	Mon Jul 27 10:39:37 1998
--- toba-1.1/runtime/lang_System.c	Wed Oct 28 21:38:21 1998
***************
*** 140,145 ****
--- 140,146 ----
          { "file.separator",     FILE_SEPARATOR },
          { "path.separator",     PATH_SEPARATOR },
          { "line.separator",     LINE_SEPARATOR },
+         { "file.encoding.pkg",	"sun.io" }, /* Needed for char/byte conversion: ISO8859 */
          { "os.name",            "" },
          { "os.version",         "" },
          { "java.home",          "" },
Index: toba-1.1/runtime/net_PlainDatagramSocketImpl.c
diff -c toba-1.1/runtime/net_PlainDatagramSocketImpl.c:1.2 toba-1.1/runtime/net_PlainDatagramSocketImpl.c:1.3
*** toba-1.1/runtime/net_PlainDatagramSocketImpl.c:1.2	Wed May  6 14:30:09 1998
--- toba-1.1/runtime/net_PlainDatagramSocketImpl.c	Mon Oct 26 11:23:14 1998
***************
*** 1,8 ****
- #include <errno.h>
- #include <string.h>
- #include <stdio.h>
  #include "toba.h"
- #include "runtime.h"
  #include "java_net_PlainDatagramSocketImpl.h"
  #include "java_net_DatagramPacket.h"
  #include "java_net_InetAddress.h"
--- 1,4 ----
***************
*** 10,15 ****
--- 6,47 ----
  #include "java_lang_Integer.h"
  #include "java_net_SocketException.h"
  
+ /* Here is ugliness incarnate.  Java uses the same identifier for
+  * particular options as systems do, except that it uses it as a field name
+  * in a structure, and most systems define it as a macro.  The values are
+  * also almost guaranteed to be different.  So what we need to do is,
+  * include the java.net.SocketOption file first so that the structures are
+  * defined (we get to the Java values through the class fields).  Because
+  * we need to be able to name the fields _after_ we've defined macros with
+  * the name of the field, we set up pointers to the static field addresses,
+  * and use those for access.  _Then_ we can include the system files to get
+  * the real value.  If that doesn't make sense, read the source and think
+  * about it.  If it still doesn't make sense, you shouldn't be modifying
+  * this file. */
+  
+ #include "java_net_SocketOptions.h"
+ 
+ static Int * ptr_TCP_NODELAY = &cl_java_net_SocketOptions.V.TCP_NODELAY;
+ #define JDK_TCP_NODELAY *(ptr_TCP_NODELAY)
+ static Int * ptr_SO_BINDADDR = &cl_java_net_SocketOptions.V.SO_BINDADDR;
+ #define JDK_SO_BINDADDR *(ptr_SO_BINDADDR)
+ static Int * ptr_SO_REUSEADDR = &cl_java_net_SocketOptions.V.SO_REUSEADDR;
+ #define JDK_SO_REUSEADDR *(ptr_SO_REUSEADDR)
+ static Int * ptr_IP_MULTICAST_IF = &cl_java_net_SocketOptions.V.IP_MULTICAST_IF;
+ #define JDK_IP_MULTICAST_IF *(ptr_IP_MULTICAST_IF)
+ static Int * ptr_SO_LINGER = &cl_java_net_SocketOptions.V.SO_LINGER;
+ #define JDK_SO_LINGER *(ptr_SO_LINGER)
+ static Int * ptr_SO_TIMEOUT = &cl_java_net_SocketOptions.V.SO_TIMEOUT;
+ #define JDK_SO_TIMEOUT *(ptr_SO_TIMEOUT)
+ 
+ /* Now that we've got all that crap done, include the runtime definition
+  * file that's going to make some of those identifiers look like numbers */
+ #include "runtime.h"
+ 
+ #include <errno.h>
+ #include <string.h>
+ #include <stdio.h>
+ 
  Void	sy_bind_iI_cCoDA(Object Harg1, Int arg2, Object Harg3) /* Since JDK1.1 */
  {
      struct in_java_net_PlainDatagramSocketImpl *this = 
***************
*** 257,289 ****
      struct in_java_net_InetAddress   *inetaddr;
      int unixfd, ival, ret;
      struct in_addr addr;
-     char errmsg[64];
  
      fd = this->fd;
!     if (!fd)
          throwNullPointerException("socketSetOption");
      unixfd = unix_fd(fd->fd);
  
!     /*
!      *  only SO_REUSEADDR & IP_MULTICAST_IF can get here
!      */
!     switch(opt){
!     case SO_REUSEADDR :    ival = ((struct in_java_lang_Integer*)val)->value;
! 			   ival = htonl(ival);
! 			   ret  = setsockopt(unixfd,SOL_SOCKET,opt,(void*)&ival,sizeof(ival));
! 			   break;
!     case IP_MULTICAST_IF :
!                            inetaddr = (struct in_java_net_InetAddress*)val;
! 			   addr.s_addr = htonl(inetaddr->address);
! 			   ret = setsockopt(unixfd,IPPROTO_IP,opt,(void*)&addr,sizeof(addr));
! 			   break;
!     default :
!                throwMesg(&cl_java_net_SocketException.C,"Invalid socket option");
! 	       return;
      }
      if (ret==-1){
!         sprintf(errmsg,"socketSetOption errno=%d",errno);
!         throwMesg(&cl_java_net_SocketException.C,errmsg);
      }
  }
  
--- 289,317 ----
      struct in_java_net_InetAddress   *inetaddr;
      int unixfd, ival, ret;
      struct in_addr addr;
  
      fd = this->fd;
!     if (!fd) {
          throwNullPointerException("socketSetOption");
+     }
      unixfd = unix_fd(fd->fd);
  
!     /* NB: The options here use Java's values, not the system ones.  E.g.,
!      * Java might use 4 for SO_REUSEADDR, and Linux might use 2. */
!     if (JDK_SO_REUSEADDR == opt) {
!        ival = ((struct in_java_lang_Integer*)val)->value;
!        ival = htonl(ival);
!        ret  = setsockopt(unixfd,SOL_SOCKET,SO_REUSEADDR,(void*)&ival,sizeof(ival));
!     } else if (JDK_IP_MULTICAST_IF == opt) {
!        inetaddr = (struct in_java_net_InetAddress*)val;
!        addr.s_addr = htonl(inetaddr->address);
!        ret = setsockopt(unixfd,IPPROTO_IP,IP_MULTICAST_IF,(void*)&addr,sizeof(addr));
!     } else {
!        throwMesg(&cl_java_net_SocketException.C,"Unrecognized socket option (%d)", opt);
      }
+ 
      if (ret==-1){
!         throwMesg(&cl_java_net_SocketException.C,"socketSetOption errno=%d",errno);
      }
  }
  
***************
*** 295,319 ****
      struct sockaddr_in saddr;
      struct in_addr iaddr;
      int unixfd, ret, blen;
-     char errmsg[64];
  
      fd = this->fd;
      if (!fd)
          throwNullPointerException("socketGetOption");
      unixfd = unix_fd(fd->fd);
  
!     if (arg2==0x4){           /* Java defined constant SO_BINDADDR */
          blen = sizeof(saddr);
          getsockname(unixfd,(struct sockaddr*)&saddr,&blen);
  	return ntohl(saddr.sin_addr.s_addr);
      }
!     if (arg2==IP_MULTICAST_IF){
          blen = sizeof(iaddr);
          ret = getsockopt(unixfd,IPPROTO_IP,arg2,(char *)&iaddr,&blen);
  	if (ret==-1){
! 	    sprintf(errmsg,"socketGetOption errno=%d",errno);
! 	    throwMesg(&cl_java_net_SocketException.C,errmsg);
  	}
  	return ntohl(iaddr.s_addr);
      }
  }
--- 323,349 ----
      struct sockaddr_in saddr;
      struct in_addr iaddr;
      int unixfd, ret, blen;
  
      fd = this->fd;
      if (!fd)
          throwNullPointerException("socketGetOption");
      unixfd = unix_fd(fd->fd);
  
!     /* Option values passed in are Java's notions of the value, not the
!      * system's.  They also aren't necessarily constant across JDK
!      * releases, so don't hard-code them. */
!     if (JDK_SO_BINDADDR == arg2) {
          blen = sizeof(saddr);
          getsockname(unixfd,(struct sockaddr*)&saddr,&blen);
  	return ntohl(saddr.sin_addr.s_addr);
      }
!     if (JDK_SO_BINDADDR == arg2) {
          blen = sizeof(iaddr);
          ret = getsockopt(unixfd,IPPROTO_IP,arg2,(char *)&iaddr,&blen);
  	if (ret==-1){
! 	    throwMesg(&cl_java_net_SocketException.C,"socketGetOption errno=%d",errno);
  	}
  	return ntohl(iaddr.s_addr);
      }
+     throwMesg (&cl_java_net_SocketException.C, "socketGetOption: Unrecognized option %d", arg2);
  }
Index: toba-1.1/runtime/net_PlainSocketImpl.c
diff -c toba-1.1/runtime/net_PlainSocketImpl.c:1.5 toba-1.1/runtime/net_PlainSocketImpl.c:1.6
*** toba-1.1/runtime/net_PlainSocketImpl.c:1.5	Sat Apr 18 16:30:23 1998
--- toba-1.1/runtime/net_PlainSocketImpl.c	Mon Oct 26 11:23:14 1998
***************
*** 1,3 ****
--- 1,47 ----
+ /* $Id: net_PlainSocketImpl.c,v 1.6 1998/10/26 18:23:14 pab Exp $
+  */
+ 
+ #include "toba.h"
+ /* DO NOT include "runtime.h" here---see below */
+ #include "java_net_SocketImpl.h"
+ #include "java_net_PlainSocketImpl.h"
+ #include "java_net_InetAddress.h"
+ #include "java_io_FileDescriptor.h"
+ #include "java_net_SocketException.h"
+ #include "java_lang_Integer.h"
+ 
+ /* Here is ugliness incarnate.  Java uses the same identifier for
+  * particular options as systems do, except that it uses it as a field name
+  * in a structure, and most systems define it as a macro.  The values are
+  * also almost guaranteed to be different.  So what we need to do is,
+  * include the java.net.SocketOption file first so that the structures are
+  * defined (we get to the Java values through the class fields).  Because
+  * we need to be able to name the fields _after_ we've defined macros with
+  * the name of the field, we set up pointers to the static field addresses,
+  * and use those for access.  _Then_ we can include the system files to get
+  * the real value.  If that doesn't make sense, read the source and think
+  * about it.  If it still doesn't make sense, you shouldn't be modifying
+  * this file. */
+  
+ #include "java_net_SocketOptions.h"
+ 
+ static Int * ptr_TCP_NODELAY = &cl_java_net_SocketOptions.V.TCP_NODELAY;
+ #define JDK_TCP_NODELAY *(ptr_TCP_NODELAY)
+ static Int * ptr_SO_BINDADDR = &cl_java_net_SocketOptions.V.SO_BINDADDR;
+ #define JDK_SO_BINDADDR *(ptr_SO_BINDADDR)
+ static Int * ptr_SO_REUSEADDR = &cl_java_net_SocketOptions.V.SO_REUSEADDR;
+ #define JDK_SO_REUSEADDR *(ptr_SO_REUSEADDR)
+ static Int * ptr_IP_MULTICAST_IF = &cl_java_net_SocketOptions.V.IP_MULTICAST_IF;
+ #define JDK_IP_MULTICAST_IF *(ptr_IP_MULTICAST_IF)
+ static Int * ptr_SO_LINGER = &cl_java_net_SocketOptions.V.SO_LINGER;
+ #define JDK_SO_LINGER *(ptr_SO_LINGER)
+ static Int * ptr_SO_TIMEOUT = &cl_java_net_SocketOptions.V.SO_TIMEOUT;
+ #define JDK_SO_TIMEOUT *(ptr_SO_TIMEOUT)
+ 
+ /* Now that we've got all that crap done, include the runtime definition
+  * file that's going to make some of those identifiers look like numbers */
+ #include "runtime.h"
+ 
  #include <unistd.h>
  #include <sys/ioctl.h>
  #ifdef sun
***************
*** 8,22 ****
  #include <stdio.h>
  #include <netinet/tcp.h>
  
- #include "toba.h"
- #include "runtime.h"
- #include "java_net_SocketImpl.h"
- #include "java_net_PlainSocketImpl.h"
- #include "java_net_InetAddress.h"
- #include "java_io_FileDescriptor.h"
- #include "java_net_SocketException.h"
- #include "java_lang_Integer.h"
- 
  /* java/net/PlainSocketImpl socketCreate (Z)V */
  Void socketCreate_z_UMixT(Object Harg1, Boolean arg2) 
  {
--- 52,57 ----
***************
*** 198,204 ****
      struct in_java_io_FileDescriptor *fd;
      struct linger l;
      int unixfd,ret;
-     char errmsg[64];
  
      fd = this->fd;
      if (!fd)
--- 233,238 ----
***************
*** 206,232 ****
  
      unixfd = unix_fd(fd->fd);
  
!     /* The only options are SO_LINGER and TCP_NODELAY in this version */
!     switch(opt){
!     case SO_LINGER :   l.l_onoff = htonl(onoff);
!                        if (onoff){
! 			   l.l_linger = ((struct in_java_lang_Integer*)val)->value;
! 			   l.l_linger = htonl(l.l_linger);
! 		       }
! 		       else
! 			   l.l_linger = 0;
! 		       ret = setsockopt(unixfd,SOL_SOCKET,SO_LINGER,(void*)&l,sizeof(l));
! 		       break;
!     case TCP_NODELAY : onoff = htonl(onoff);
!                        ret = setsockopt(unixfd,IPPROTO_TCP,TCP_NODELAY,(char *)&onoff,sizeof(onoff));
!                        break;
!     default :
!                throwMesg(&cl_java_net_SocketException.C,"Invalid socket option");
! 	       return;
      }
      if (ret==-1){
!         sprintf(errmsg,"socketSetOption errno=%d",errno);
!         throwMesg(&cl_java_net_SocketException.C,errmsg);
      }
  }
  
--- 240,265 ----
  
      unixfd = unix_fd(fd->fd);
  
!     /* NB: The options here use Java's values, not the system ones.  E.g.,
!      * Java might use 0x80 for SO_REUSEADDR, and Linux might use 13. */
!     if (JDK_SO_LINGER == opt) {
!        l.l_onoff = htonl(onoff);
!        if (onoff){
!           l.l_linger = ((struct in_java_lang_Integer*)val)->value;
!           l.l_linger = htonl(l.l_linger);
!        } else {
!           l.l_linger = 0;
!        }
!        ret = setsockopt(unixfd,SOL_SOCKET,SO_LINGER,(void*)&l,sizeof(l));
!     } else if (JDK_TCP_NODELAY == opt) {
!        onoff = htonl(onoff);
!        ret = setsockopt(unixfd,IPPROTO_TCP,TCP_NODELAY,(char *)&onoff,sizeof(onoff));
!     } else {
!        throwMesg(&cl_java_net_SocketException.C,"Unrecognized socket option (%d)", opt);
!        /*NOTREACHED*/
      }
      if (ret==-1){
!         throwMesg(&cl_java_net_SocketException.C,"socketSetOption errno=%d",errno);
      }
  }
  
***************
*** 238,277 ****
      struct sockaddr_in saddr;
      struct linger l;
      int unixfd,ret,onoff,blen;
-     char errmsg[64];
  
      fd = this->fd;
      if (!fd)
          throwNullPointerException("socketGetOption");
  
      unixfd = unix_fd(fd->fd);
!     switch(opt){
!     case TCP_NODELAY : blen = sizeof(onoff);
!                        ret = getsockopt(unixfd,IPPROTO_TCP,TCP_NODELAY,(char*)&onoff,&blen);
! 		       if (ret==-1)
! 			   break;
! 		       if (onoff)
! 			   return 0;
! 		       return -1;     /* return -1 if the option is turned off */
!     case SO_LINGER :   blen = sizeof(l);
!                        ret = getsockopt(unixfd,SOL_SOCKET,SO_LINGER,(char*)&l,&blen);
! 		       if (ret==-1)
! 			   break;
! 		       if (l.l_onoff)
! 			   return 0;
! 		       return -1;     /* return -1 if the option is turned off */
!     case 0x4 :         /* SO_BINDADDR */
!                        blen = sizeof(saddr);
! 		       ret = getsockname(unixfd,(struct sockaddr*)&saddr,&blen);
! 		       if (ret==-1)
! 			   break;
! 		       return ntohl(saddr.sin_addr.s_addr);
!     default :
!                throwMesg(&cl_java_net_SocketException.C,"Invalid socket option");
! 	       return;
      }
!     sprintf(errmsg,"socketGetOption errno=%d",errno);
!     throwMesg(&cl_java_net_SocketException.C,errmsg);
  }
  
  
--- 271,311 ----
      struct sockaddr_in saddr;
      struct linger l;
      int unixfd,ret,onoff,blen;
  
      fd = this->fd;
      if (!fd)
          throwNullPointerException("socketGetOption");
  
+     /* Use Java's values to identify the option.  Note that "I know about
+      * this, and it's off" is denoted by returning -1; "what are you talking
+      * about" throws a SocketException. */
      unixfd = unix_fd(fd->fd);
!     if (JDK_TCP_NODELAY == opt) {
!        blen = sizeof(onoff);
!        ret = getsockopt(unixfd,IPPROTO_TCP,TCP_NODELAY,(char*)&onoff,&blen);
!        if (0 > ret) {
!           throwMesg (&cl_java_net_SocketException.C, "getSocketOptions(TCP_NODELAY) returned error %d\n", errno);
!        }
!        return (onoff ? 0 : -1);
!     } else if (JDK_SO_LINGER == opt) {
!        blen = sizeof(l);
!        ret = getsockopt(unixfd,SOL_SOCKET,SO_LINGER,(char*)&l,&blen);
!        if (0 > ret) {
!           throwMesg (&cl_java_net_SocketException.C, "getSocketOptions(SO_LINGER) returned error %d\n", errno);
!        }
!        return (l.l_onoff ? 0 : -1);
!     } else if (JDK_SO_BINDADDR == opt) {
!        blen = sizeof(saddr);
!        ret = getsockname(unixfd,(struct sockaddr*)&saddr,&blen);
!        if (0 > ret) {
!           throwMesg (&cl_java_net_SocketException.C, "getSocketOptions(SO_BINDADDR) returned error %d\n", errno);
!        }
!        return ntohl(saddr.sin_addr.s_addr);
!     } else {
!        throwMesg(&cl_java_net_SocketException.C,"Unrecognized socket option (%d)", opt);
!        /*NOTREACHED*/
      }
!     /*NOTREACHED*/
  }
  
  
Index: toba-1.1/runtime/runtime.h
diff -c toba-1.1/runtime/runtime.h:1.22 toba-1.1/runtime/runtime.h:1.23
*** toba-1.1/runtime/runtime.h:1.22	Thu Jul 30 16:51:41 1998
--- toba-1.1/runtime/runtime.h	Tue Oct 27 14:49:59 1998
***************
*** 38,48 ****
  #endif /* linux/glibc2? */
  
  /* implementation identification */
! #define JAVA_VERSION 	"1.1.3"		/* Java spec version */
  #define CLASS_VERSION	"45.3"		/* Java classfile version */
  #define TOBA_VENDOR	"The University of Arizona"
  #define TOBA_URL	"http://www.cs.arizona.edu/sumatra/"
! #define TOBA_VERSION	"1.1"	/* our own version number */
  /* NB: For static joust in Scout, if this toolkit changes, the patch
   * to java.awt.Toolkit must be updated to force inclusion of the toolkit,
   * which is looked up by name only. */
--- 38,48 ----
  #endif /* linux/glibc2? */
  
  /* implementation identification */
! #define JAVA_VERSION 	"1.1.?"		/* Java spec version */
  #define CLASS_VERSION	"45.3"		/* Java classfile version */
  #define TOBA_VENDOR	"The University of Arizona"
  #define TOBA_URL	"http://www.cs.arizona.edu/sumatra/"
! #define TOBA_VERSION	"1.1a"	/* our own version number */
  /* NB: For static joust in Scout, if this toolkit changes, the patch
   * to java.awt.Toolkit must be updated to force inclusion of the toolkit,
   * which is looked up by name only. */
Index: toba-1.1/runtime/runtime_ClassRT.c
diff -c toba-1.1/runtime/runtime_ClassRT.c:1.9 toba-1.1/runtime/runtime_ClassRT.c:1.11
*** toba-1.1/runtime/runtime_ClassRT.c:1.9	Tue May 12 08:27:03 1998
--- toba-1.1/runtime/runtime_ClassRT.c	Mon Oct 26 11:23:46 1998
***************
*** 450,456 ****
  	if (NULL == cl->cldata) {
  	   throwInternalError ("Class definition: missing ClassData structure");
  	}
! 	mtp->localp = isInArray_aF_ppXbl (f, cl->cldata->fields);
  	mtp->access = f->access;
      }
      return;
--- 450,456 ----
  	if (NULL == cl->cldata) {
  	   throwInternalError ("Class definition: missing ClassData structure");
  	}
! 	mtp->localp = isInArray_aF_ppXbl (f, cl->cldata->methods);
  	mtp->access = f->access;
      }
      return;
***************
*** 482,488 ****
  	if (NULL == cl->cldata) {
  	   throwInternalError ("Class definition: missing ClassData structure");
  	}
! 	stp->localp = isInArray_aF_ppXbl (f, cl->cldata->fields);
  	stp->access = f->access;
      }
  
--- 482,488 ----
  	if (NULL == cl->cldata) {
  	   throwInternalError ("Class definition: missing ClassData structure");
  	}
! 	stp->localp = isInArray_aF_ppXbl (f, cl->cldata->methods);
  	stp->access = f->access;
      }
  
***************
*** 539,546 ****
  
      initclass(&cl_toba_runtime_ClassRT.C);
  
      if (0 == cl->ivars) {
! 	/* XXX */;
      }
  
      return cl->ivars[index].offset;
--- 539,549 ----
  
      initclass(&cl_toba_runtime_ClassRT.C);
  
+     if ((0 > index) || (index >= cl->nivars)) {
+        throwInternalError ("getInstanceVarOffset: Class variable slot %d is invalid\n", index);
+     }
      if (0 == cl->ivars) {
!        throwInternalError ("getInstanceVarOffset: No instance vars in class\n");
      }
  
      return cl->ivars[index].offset;
***************
*** 554,561 ****
  
      initclass(&cl_toba_runtime_ClassRT.C);
  
      if (0 == cl->cvars) {
! 	/* XXX */;
      }
  
      return addressToLong(cl->cvars[index].addr);
--- 557,567 ----
  
      initclass(&cl_toba_runtime_ClassRT.C);
  
+     if ((0 > index) || (index >= cl->ncvars)) {
+        throwInternalError ("getClassVarAddr: Class variable slot %d is invalid\n", index);
+     }
      if (0 == cl->cvars) {
!        throwInternalError ("getClassVarAddr: No instance vars in class\n");
      }
  
      return addressToLong(cl->cvars[index].addr);
***************
*** 578,590 ****
      if (instancep) {
         mtable = (struct mt_generic *)((char *)cl + methodTableOffset());
         if (index >= cl->nimethods) {
!           /* throw error */
         }
         return addressToLong(mtable + index);
      } else {
!        if ((NULL == cl->smethods) ||
!            (index >= cl->nsmethods)) {
!           /* throw error */
         }
         return addressToLong (cl->smethods + index);
      }
--- 584,598 ----
      if (instancep) {
         mtable = (struct mt_generic *)((char *)cl + methodTableOffset());
         if (index >= cl->nimethods) {
!           throwInternalError ("getMethodTEnt: Invalid index %d for %d instance methods", index, cl->nimethods);
         }
         return addressToLong(mtable + index);
      } else {
!        if (NULL == cl->smethods) {
!           throwInternalError ("getMethodTEnt: No static methods available");
!           }
!        if (index >= cl->nsmethods) {
!           throwInternalError ("getMethodTEnt: Invalid index %d for %d instance methods", index, cl->nimethods);
         }
         return addressToLong (cl->smethods + index);
      }
Index: toba-1.1/toba/classfile/MethodRef.java
diff -c toba-1.1/toba/classfile/MethodRef.java:1.2 toba-1.1/toba/classfile/MethodRef.java:1.3
*** toba-1.1/toba/classfile/MethodRef.java:1.2	Mon Nov 24 11:11:20 1997
--- toba-1.1/toba/classfile/MethodRef.java	Wed Oct 28 21:38:21 1998
***************
*** 8,30 ****
      // Locate the method that this reference refers
      // to in the given ClassData
      protected Field findMethod(ClassData cdata) {
! 	Field[] imtable = cdata.imtable;
  
! 	for (int i = 0; i < imtable.length; i++) {
! 	    if ((name == imtable[i].name) && 
! 		(signature == imtable[i].signature)) {
! 		return imtable[i];
! 	    }
  	}
  
! 	Field[] smtable = cdata.smtable;
! 	for (int i = 0; i < smtable.length; i++) {
! 	    if ((name == smtable[i].name) && 
! 		(signature == smtable[i].signature)) {
! 		return smtable[i];
! 	    }
  	}
! 	throw new NoSuchMethodError(name + signature);
      }
  
      public void resolveWith(ClassData cdata) {
--- 8,44 ----
      // Locate the method that this reference refers
      // to in the given ClassData
      protected Field findMethod(ClassData cdata) {
!         Field rm;
!         Field [] mt;
!         int i;
  
!         /* This method is wrong in exactly the same way as VariableRef's
!          * findVariable.  It may return the wrong reference if a class
!          * has a static and instance method of the same name (due to
!          * overloading). */
! 
!         /* Give static methods priority; one of them has to come first.... */
!         mt = cdata.smtable;
!         i = mt.length;
!         while (0 <= --i) {
! 	    if ((name == mt[i].name) && 
! 		(signature == mt[i].signature)) {
! 		return mt[i];
!             }
  	}
  
!         /* If no static method found, look through the dynamic table. */
! 	mt = cdata.imtable;
!         i = mt.length;
!         while (0 <= --i) {
! 	    if ((name == mt[i].name) && 
! 		(signature == mt[i].signature)) {
! 		return mt[i];
!             }
  	}
! 
!         /* Blow chow. */
! 	throw new NoSuchMethodError(cdata.name + "." + name + signature);
      }
  
      public void resolveWith(ClassData cdata) {
Index: toba-1.1/toba/classfile/VariableRef.java
diff -c toba-1.1/toba/classfile/VariableRef.java:1.3 toba-1.1/toba/classfile/VariableRef.java:1.5
*** toba-1.1/toba/classfile/VariableRef.java:1.3	Tue May 12 08:27:07 1998
--- toba-1.1/toba/classfile/VariableRef.java	Wed Oct 28 21:38:21 1998
***************
*** 5,24 ****
  public class VariableRef extends FieldRef {
      public VariableRef(ClassRef cl, String n, String s) { super(cl, n, s); }
  
!     protected Field findVariable(ClassData cdata) {
! 	Field[] ivtable = cdata.ivtable;
! 	for (int i = 0; i < ivtable.length; i++) {
! 	    if ((name == ivtable[i].name) && 
! 		(signature == ivtable[i].signature))
! 		return ivtable[i];
  	}
  
! 	Field[] cvtable = cdata.cvtable;
! 	for (int i = 0; i < cvtable.length; i++) {
! 	    if ((name == cvtable[i].name) && 
! 		(signature == cvtable[i].signature))
! 		return cvtable[i];
  	}
  	throw new NoSuchFieldError(cdata.name + "." + name + "(" + signature + ")");
      }
  
--- 5,47 ----
  public class VariableRef extends FieldRef {
      public VariableRef(ClassRef cl, String n, String s) { super(cl, n, s); }
  
!     protected Field
!     findVariable (ClassData cdata)
!     {
!         Field [] vt;
!         int i;
! 
!         /* This method is fundamentally wrong: it fails to account for cases
!          * where fields have the same name and signature, as in hiding
!          * a superclass public field, overriding a superclass private field,
!          * or obscuring a superclass instance/static variable with a subclass
!          * static/instance variable.  What we do to decrease the frequency
!          * of screwup is go through the static var table first (because
!          * the serialization code hits this bug with a reference to a static
!          * field that ends up accessing a parent instance field), and by
!          * going from the end of the table down, since that's the order
!          * of priority (heading towards superclasses). */
!         
!         vt = cdata.cvtable;
!         i = vt.length;
!         while (0 <= --i) {
! 	    if ((name == vt[i].name) && 
! 		(signature == vt[i].signature)) {
! 		return vt[i];
!             }
  	}
  
!         /* No static field found; try the instance fields */
! 	vt = cdata.ivtable;
!         i = vt.length;
!         while (0 <= --i) {
! 	    if ((name == vt[i].name) && 
! 		(signature == vt[i].signature)) {
! 		return vt[i];
!             }
  	}
+ 
+         /* No field with this name. */
  	throw new NoSuchFieldError(cdata.name + "." + name + "(" + signature + ")");
      }
  

