Index: toba-1.1/History
diff -c toba-1.1/History:1.11 toba-1.1/History:1.14
*** toba-1.1/History:1.11	Sun Jul 26 12:25:28 1998
--- toba-1.1/History	Thu Dec  3 19:11:52 1998
***************
*** 1,5 ****
--- 1,11 ----
  Toba Version Log
  
+ 1.1b	December 4, 1998
+ 	Fixes for reflection, misc bugs.
+ 
+ 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.12
*** toba-1.1/README:1.9	Fri May  1 18:09:14 1998
--- toba-1.1/README	Thu Dec  3 19:11:52 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
! 04Dec98 -- Version 1.1b
  
  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 mostly supported (invocation of some methods may fail).
  
  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/configs/irix.mk
diff -c toba-1.1/configs/irix.mk:1.4 toba-1.1/configs/irix.mk:1.5
*** toba-1.1/configs/irix.mk:1.4	Thu Jul 30 15:16:14 1998
--- toba-1.1/configs/irix.mk	Thu Dec  3 11:55:29 1998
***************
*** 1,7 ****
  # toba make definitions for MIPS/Irix using SGI CC and Irix threads
  ARCH = mips
  CBUILD = -KPIC
! CTOBA = -ansi
  TBUILD = -O
  SLOPT = -shared
  # NB: Space follows -rpath below
--- 1,9 ----
  # toba make definitions for MIPS/Irix using SGI CC and Irix threads
  ARCH = mips
  CBUILD = -KPIC
! # Shut up noisy Irix warnings:
! # 1429: long long being non-standard.
! CTOBA = -ansi -woff 1429
  TBUILD = -O
  SLOPT = -shared
  # NB: Space follows -rpath below
***************
*** 13,16 ****
  # irix because they hid their resource bundles somewhere we can't find then,
  # so we won't build it there.
  WantXJavac = 
- 
--- 15,17 ----
Index: toba-1.1/packages/buildAPI
diff -c toba-1.1/packages/buildAPI:1.4 toba-1.1/packages/buildAPI:1.6
*** toba-1.1/packages/buildAPI:1.4	Mon Jul 27 10:39:36 1998
--- toba-1.1/packages/buildAPI	Thu Dec  3 19:11:52 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.6 1998/12/04 02:11:52 pab Exp $
  #
  # Script to automate the translation of Sun and BISS class files into
  # packages suitable for use by Toba.
***************
*** 52,63 ****
  # SUN_EXCLUDE: A group of patterns of classes in the sun.* hierarchy that
  # we don't want to tobafy.
  stamp 'Computing sun.* exclusion patterns'
! SUN_EXCLUDE='^sun.'
! # The following is a little more lax, and bloats the library a lot.
! #SUN_EXCLUDE=''
! #for f in applet audio awt beans io jdbc net rmi tools ; do
! #  SUN_EXCLUDE="${SUN_EXCLUDE} ^sun.${f}."
! #done
  
  # CLASS_EXCLUDE: A group of classes that we want to exclude.  Specifically
  # for BISS builds: there are some AWT classes that require things not
--- 52,64 ----
  # SUN_EXCLUDE: A group of patterns of classes in the sun.* hierarchy that
  # we don't want to tobafy.
  stamp 'Computing sun.* exclusion patterns'
! #SUN_EXCLUDE='^sun.'
! # The following is a little more lax, and bloats the library, but also
! # allows serialization to work.
! SUN_EXCLUDE=''
! for f in applet audio awt beans io jdbc net rmi tools ; do
!   SUN_EXCLUDE="${SUN_EXCLUDE} ^sun.${f}."
! done
  
  # CLASS_EXCLUDE: A group of classes that we want to exclude.  Specifically
  # for BISS builds: there are some AWT classes that require things not
***************
*** 74,79 ****
--- 75,86 ----
    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
--- 125,137 ----
    | 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/Makefile
diff -c toba-1.1/runtime/Makefile:1.24 toba-1.1/runtime/Makefile:1.25
*** toba-1.1/runtime/Makefile:1.24	Tue Jul 28 10:39:53 1998
--- toba-1.1/runtime/Makefile	Wed Nov 18 12:22:15 1998
***************
*** 12,18 ****
  
  HELP = alloc.c binary_loader.c file.c finalizer.c helpers.c \
         loader.c monitor.c runtime.c sthreads.c structs.c throw.c \
!        intern.c classfile_ClassData.c
  
  JITSRC = jit_JITCodeGen.c jit_CodeBlock.c \
         runtime_ClassRT.c \
--- 12,18 ----
  
  HELP = alloc.c binary_loader.c file.c finalizer.c helpers.c \
         loader.c monitor.c runtime.c sthreads.c structs.c throw.c \
!        intern.c classfile_ClassData.c invoke_c.c
  
  JITSRC = jit_JITCodeGen.c jit_CodeBlock.c \
         runtime_ClassRT.c \
***************
*** 50,56 ****
  	touch $(UPDATED) $(DONE)
  	sleep 1
  
! $(OBJ): toba.h runtime.h md.h
  
  withjit:
  	$(MAKE) JIT="$(JITSRC)"
--- 50,56 ----
  	touch $(UPDATED) $(DONE)
  	sleep 1
  
! $(OBJ): toba.h runtime.h md.h reflect.h
  
  withjit:
  	$(MAKE) JIT="$(JITSRC)"
Index: toba-1.1/runtime/alloc.c
diff -c toba-1.1/runtime/alloc.c:1.10 toba-1.1/runtime/alloc.c:1.12
*** toba-1.1/runtime/alloc.c:1.10	Wed Jan 28 16:27:46 1998
--- toba-1.1/runtime/alloc.c	Thu Nov 19 18:54:55 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;
  }
  
***************
*** 261,301 ****
      return a;
  }
  
- 
- 
  Object mnewarray(Class c, int arraydim, int ndim, int *dlist)
  {
      int i;
! 
!     /* make Class structs out to final dimension */
      for (i = 0; i < arraydim; i++) {
! 	if (!c->arrayclass)
  	    c->arrayclass = arrayclassof(c);
  	c = c->arrayclass;
      }
      /* recursively create the requested number of dimensions */
      return mkarray(c->elemclass, ndim, dlist);
- 
  }
  
  /*  mnewarray(c, arraydim, ndim, d1, d2, ...) -- implement multianewarray  */
! 
! Object vmnewarray(Class c, int arraydim, int ndim, /*d1,d2,*/...)
  {
!     va_list ap;
      int dlist[256];		/* bytecode limits dimensions to 256 max */
      int i;
  
      /* store dimensions from vararg list in local array */
      va_start(ap, ndim);
!     for (i = 0; i < ndim; i++)
  	dlist[i] = va_arg(ap, int);
      va_end(ap);
  
!     return mnewarray(c, arraydim, ndim, dlist);
  }
  
! static Object mkarray(Class c, int ndim, int *dlist)  /* make ndim-array of c */
  {
      int i;
      Object o;
--- 271,331 ----
      return a;
  }
  
  Object mnewarray(Class c, int arraydim, int ndim, int *dlist)
  {
      int i;
!     
!     /* The class structure we have refers to the ultimate base type.
!      * We need to get a pointer to the class corresponding to the
!      * topmost element type; e.g., with a 5-d array, we want the
!      * [[[[X class (array-four-times of base type).  NB: We go up
!      * one level further than we need to, so there's a class
!      * description available for the type we're going to return
!      * as well as the recursive element types. */
      for (i = 0; i < arraydim; i++) {
! 	if (NULL == c->arrayclass) {
  	    c->arrayclass = arrayclassof(c);
+         }
  	c = c->arrayclass;
      }
+         
      /* recursively create the requested number of dimensions */
      return mkarray(c->elemclass, ndim, dlist);
  }
  
  /*  mnewarray(c, arraydim, ndim, d1, d2, ...) -- implement multianewarray  */
! Object
! vmnewarray (Class c,            /* Class of ultimate base element */
!             int arraydim,       /* Ultimate array rank */
!             int ndim,           /* Number of axes we're going to allocate here */
!             /*d1,d2,*/...)      /* Dimensions for axes 1 through ndim */
  {
!     va_list ap;                 /*  */
      int dlist[256];		/* bytecode limits dimensions to 256 max */
      int i;
  
+     if ((256 <= ndim) || (0 >= ndim)) {
+         throwInternalError ("vmnewarray attempting to allocate %d-dimensional array.", ndim);
+     }
+     if ((ndim > arraydim) || (0 >= arraydim)) {
+         throwInternalError ("vmnewarray invalid dimensions (%d, allocating %d).", arraydim, ndim);
+     }
+ 
      /* store dimensions from vararg list in local array */
      va_start(ap, ndim);
!     for (i = 0; i < ndim; i++) {
  	dlist[i] = va_arg(ap, int);
+     }
      va_end(ap);
  
!     return mnewarray (c, arraydim, ndim, dlist);
! 
  }
  
! static Object
! mkarray (Class c,               /* Element class data */
!          int ndim,              /* Number of dimensions we're going to build */
!          int *dlist)            /* Extent of each dimension */
  {
      int i;
      Object o;
***************
*** 305,313 ****
         throwNegativeArraySizeException(*dlist);
      }
      o = anewarray(c, *dlist);
!     if (ndim > 1)
! 	for (i = 0; i < *dlist; i++)
! 	    ((struct aarray *)o)->data[i] =
! 		mkarray(c->elemclass, ndim - 1, dlist + 1);
      return o;
  }
--- 335,347 ----
         throwNegativeArraySizeException(*dlist);
      }
      o = anewarray(c, *dlist);
! 
!     /* If there are more dimensions to do, fill in each element of the
!      * array we just created with a new n-1--dimensional array. */
!     if (1 < ndim) {
! 	for (i = 0; i < *dlist; i++) {
! 	    ((struct aarray *)o)->data[i] = mkarray(c->elemclass, ndim - 1, dlist + 1);
!         }
!     }
      return o;
  }
Index: toba-1.1/runtime/binary_loader.c
diff -c toba-1.1/runtime/binary_loader.c:1.8 toba-1.1/runtime/binary_loader.c:1.9
*** toba-1.1/runtime/binary_loader.c:1.8	Fri Jul 24 16:19:34 1998
--- toba-1.1/runtime/binary_loader.c	Mon Nov  9 13:47:19 1998
***************
*** 78,83 ****
--- 78,84 ----
  #endif /* HAVE_TCLASS_NAME_LIST */
  }
  
+ #if HAVE_DLSYM
  /* Look up a symbol in all open dynamic libraries.   Y'know, this probably
   * ought to be restricted based on class loader. */
  static void *
***************
*** 97,102 ****
--- 98,104 ----
     }
     return rv;
  }
+ #endif /* HAVE_DLSYM */
  
  /** Given the (fully-qualified) name of a Java class, find it in whatever
    * way we have to. */
Index: toba-1.1/runtime/genInvokeCases
diff -c /dev/null toba-1.1/runtime/genInvokeCases:1.2
*** /dev/null	Thu Dec  3 22:21:42 1998
--- toba-1.1/runtime/genInvokeCases	Thu Nov 19 18:56:19 1998
***************
*** 0 ****
--- 1,97 ----
+ #!/usr/local/bin/perl
+ # $Id: genInvokeCases,v 1.2 1998/11/20 01:56:19 pab Exp $
+ #
+ # Generate the case statements used inside invoke_c to invoke methods that
+ # take primitive types as parameters.
+ 
+ # Sizes of primitive data types
+ @aset = ( 1, 2, 4, 8 );
+ 
+ # Names for the generic type we use to cover all types with a given size.
+ %mtype = ();
+ $mtype{0} = "Void";
+ $mtype{1} = "Byte";
+ $mtype{2} = "Char";
+ $mtype{4} = "Int";
+ $mtype{8} = "Long";
+ 
+ # For a list of sizes, generate the tag value used to represent the list,
+ # the prototype string using the generic types, and the actual parameter
+ # string extracting data from a char array and casting it to the
+ # appropriate type.  We assume the actual parameters are stored aligned
+ # on 4-byte boundaries.
+ sub genSizeInfo () {
+   local @sset = @_;
+   my $tag = "";
+   my $proto = "";
+   my $param = "";
+   my $tsize = 0;
+ 
+   for $s (@sset) {
+     if ("" ne $proto) {
+       $proto .= ",";
+       $param .= ",";
+     }
+ 
+     $tag .= "${s}";
+     $proto .= $mtype{$s};
+     $param .= "*($mtype{$s}*)(pData+$tsize)";
+     if (4 >= $s) {
+       $tsize += 4;
+     } else {
+       $tsize += $s;
+     }
+   }
+   return ($tag, $proto, $param);
+ }
+ 
+ %doneCase = ();
+ 
+ sub emitCase () {
+   local ($tag, $prot, $parm) = @_;
+   return if ($doneCase{$tag});
+   $doneCase{$tag} = 1;
+   while (4 > (length $tag)) {
+     $tag = "0" . $tag;
+   }
+   print <<"EOText"
+ case 0x${tag}:
+   if (0 == rSize) {
+     ((Void(*)($prot))(m->f))($parm);
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)($prot))(m->f))($parm);
+       } else {
+           prv.F = ((Float(*)($prot))(m->f))($parm);
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)($prot))(m->f))($parm);
+       } else {
+           prv.D = ((Double(*)($prot))(m->f))($parm);
+       }
+   }
+   break;
+ EOText
+   ;
+ }
+ 
+ sub genInvokes () {
+   local @sset = @_;
+ 
+   &emitCase (&genSizeInfo (@sset));
+   &emitCase (&genSizeInfo (4, @sset));
+   return;
+ }
+ 
+ 
+ &genInvokes(4);
+ for $s1 (@aset) {
+   &genInvokes ($s1);
+   for $s2 (@aset) {
+     &genInvokes ($s1, $s2);
+ #    for $s3 (@aset) {
+ #        &genInvokes ($s1, $s2, $s3);
+ #    }
+   }
+ }
Index: toba-1.1/runtime/helpers.c
diff -c toba-1.1/runtime/helpers.c:1.12 toba-1.1/runtime/helpers.c:1.14
*** toba-1.1/runtime/helpers.c:1.12	Sat Apr 18 16:30:17 1998
--- toba-1.1/runtime/helpers.c	Fri Nov 20 13:26:16 1998
***************
*** 3,8 ****
--- 3,9 ----
  #include "toba.h"
  #include "runtime.h"
  #include "java_lang_NullPointerException.h"
+ #include "java_io_Serializable.h"
  
  #include <stdlib.h>
  #include <math.h>
***************
*** 150,164 ****
   */
  int assignablefrom(Class c, Class oc)
  {
!     if (oc == c)			/* quick check for exact match */
! 	return 1;
  
!     if ((oc->flags | c->flags) & IS_PRIMITIVE)
! 	return 0;			/* if primitive, must be identical */
  
!     if (c->flags & IS_INTERFACE)	/* if an interface, check specially */
          return interfinstance(oc, c);
  
      /* at this point c is a simple class although oc may be an array; */
      /* an array matches only java.lang.Object */
      return oc->nsupers >= c->nsupers && oc->supers[oc->nsupers-c->nsupers] == c;
--- 151,177 ----
   */
  int assignablefrom(Class c, Class oc)
  {
!     if (oc == c) {			/* quick check for exact match */
! 	return JAVA_TRUE;
!     }
  
!     if ((oc->flags | c->flags) & IS_PRIMITIVE) {
!         /* Primitives are compatible only if they're identical, and these
!          * aren't because we already checked that. */
! 	return JAVA_FALSE;      /* if primitive, must be identical */
!     }
  
!     if ((IS_ARRAY & oc->flags) &&
!         (&cl_java_io_Serializable.C == c)) {
!         /* Arrays can be assigned to serializables. */
!         return JAVA_TRUE;
!     }
! 
!     if (c->flags & IS_INTERFACE) {	/* if an interface, check specially */
          return interfinstance(oc, c);
+     }
  
+     /* Why did somebody put this comment here?  Why is it true? */
      /* at this point c is a simple class although oc may be an array; */
      /* an array matches only java.lang.Object */
      return oc->nsupers >= c->nsupers && oc->supers[oc->nsupers-c->nsupers] == c;
Index: toba-1.1/runtime/invoke_c.c
diff -c /dev/null toba-1.1/runtime/invoke_c.c:1.5
*** /dev/null	Thu Dec  3 22:21:42 1998
--- toba-1.1/runtime/invoke_c.c	Fri Nov 20 14:01:05 1998
***************
*** 0 ****
--- 1,977 ----
+ /* $Id: invoke_c.c,v 1.5 1998/11/20 21:01:05 pab Exp $
+  * Support for invoking dynamically-specified methods.  This includes
+  * both constructors and normal methods. */
+ 
+ #include <stddef.h>
+ #include <string.h>
+ #include <stdio.h>
+ #include <assert.h>
+ 
+ #include "toba.h"
+ #include "classfile_ClassData.h"
+ #include "java_lang_reflect_InvocationTargetException.h"
+ #include "runtime.h"
+ #include "reflect.h"
+ 
+ /* We need to be able to invoke a function with an arbitrary parameter
+  * specification.  We could generate an assembly sequence at runtime that
+  * sticks the parameters in the appropriate location and invokes the
+  * function, but we're going to try to do as much as we can in semi-portable
+  * C.
+  *
+  * Here's the general principle: Although there are a bunch of primitive
+  * types, we're going to assume that all the ones of a particular size
+  * can be treated identically: e.g., all 1-byte quantities as Bytes,
+  * all 4-byte quantities as Ints, all 8-byte quantities as Longs.  This
+  * would break if, e.g., floating point values are not returned in the
+  * same way as longs are.  We're also assuming that Objects are 4-byte
+  * values, and that all 1 and 2-byte values are returned as a 32-bit
+  * integer.
+  *
+  * What we do is calculate a hash code that identifies the parameters
+  * to a method by their size (sizes encoded in the nybbles of an int),
+  * and generate a switch statement which ends up invoking the method
+  * function by casting it to a function pointer of the corresponding
+  * type, and extracting the parameters from a buffer, again casting
+  * them to the appropriate (generic) type for the parameter (size).
+  * The return value is stored into a primitive value location and,
+  * if appropriate, wrapped in an object before being returned from
+  * the invoke routine.
+  *
+  * The provided set supports all 1 and 2-parameter methods, both static
+  * and instance; static 3-parameter methods where the first parameter
+  * is a 4-byte type; and methods with up to 12 parameters all of which
+  * are 4-byte quantities.  Any missing signature ends up throwing
+  * an internal error; you can get around that by adding another case
+  * to the switch, or by writing an assembly-language wrapping invoker.
+  *
+  * Note that when we stuff the parameters into the buffer that we use
+  * to store them in primitive form, we align everything on 4-byte
+  * boundaries, even if they're 1- or 2-byte quantities.  This should
+  * prevent alignment traps on picky hardware.
+  */
+ 
+ /* How many object-like parameters are we prepared to handle? */
+ #define MAX_PARAM_WORDS (12)
+ 
+ static Object 
+ invoke_object (struct mt_generic *m, /* The method we're going to invoke */
+                int nParams,     /* Number of parameters */
+                char * pSize,    /* Sequence of bytes describing sizes of parameters */
+                char * pData)    /* Sequence of native-mode actual parameters */
+ {
+     Object orv;                 /* The object we're returning as a result */
+     int apat;                   /* Hash code of the argument pattern */
+     int hasNonObjParam;         /* Nonzero iff some argument is not 4-bytes big */
+     const Char * chp;           /* Pointer into signature for determining return type */
+     PrimClassTriple * rpct;     /* Data corresponding to return type */
+     AnyJavaValue prv;           /* Where we store primitive result values */
+     int rSize;                  /* Size of the result value */
+     Boolean didInv;             /* True after switch only if we matched and invoked */
+     int i;                      /* General purpose index */
+ 
+     /* The type of the result of the method is indicated by the character
+      * immediately following the close paren in the method's signature.
+      * Back up to that character and use it to look up the primitive
+      * class information for the return type.  Calculate the size of the
+      * result value. */
+     chp = m->sig_chars + m->sig_len - 1;
+     while ((m->sig_chars < chp) &&
+            (')' != chp[-1])) {
+         --chp;
+     }
+     rpct = getPCTbySigChar (*chp);
+     if (NULL == rpct) {
+         /* Only way we should be able to get here is if the return type
+          * is a non-primitive object.  If it isn't, complain loudly. */
+         if ('L' != *chp) {
+             throwInternalError ("invoke: Mismatch extracting return type");
+         }
+         rSize = sizeof (Object);
+     } else {
+         rSize = PCT_primSize (rpct);
+     }
+ 
+ /* The hash code consists of an encoding of the sizes of the first so-many
+  * arguments of the method.  Don't compute a hash on more than the number
+  * of args we're prepared to deal with. */
+ #define MAX_SPECIALIZED_INVOKE_ARGS (3)
+     apat = 0;
+     hasNonObjParam = 0;
+     for (i = 0; i < nParams; i++) {
+         hasNonObjParam |= (sizeof (Object) != pSize [i]);
+         if (MAX_SPECIALIZED_INVOKE_ARGS > i) {
+             assert (16 > pSize [i]);
+             /* Hash encoding is 4-bit left-to-right of sizes */
+             apat = (apat << 4) + (pSize [i] & 0x0F);
+         }
+     }
+     /* If there aren't more arguments than we have special cases for,
+      * try to find a match in the switch statement. */
+     didInv = JAVA_FALSE;
+     if (MAX_SPECIALIZED_INVOKE_ARGS > nParams) {
+         didInv = JAVA_TRUE;
+         switch (apat) {
+ /* The case statements are generated automatically by genInvokeCases.
+  * Edit them there. */
+ case 0x0004:
+   if (0 == rSize) {
+     ((Void(*)(Int))(m->f))(*(Int*)(pData+0));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int))(m->f))(*(Int*)(pData+0));
+       } else {
+           prv.F = ((Float(*)(Int))(m->f))(*(Int*)(pData+0));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int))(m->f))(*(Int*)(pData+0));
+       } else {
+           prv.D = ((Double(*)(Int))(m->f))(*(Int*)(pData+0));
+       }
+   }
+   break;
+ case 0x0044:
+   if (0 == rSize) {
+     ((Void(*)(Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4));
+       }
+   }
+   break;
+ case 0x0001:
+   if (0 == rSize) {
+     ((Void(*)(Byte))(m->f))(*(Byte*)(pData+0));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Byte))(m->f))(*(Byte*)(pData+0));
+       } else {
+           prv.F = ((Float(*)(Byte))(m->f))(*(Byte*)(pData+0));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Byte))(m->f))(*(Byte*)(pData+0));
+       } else {
+           prv.D = ((Double(*)(Byte))(m->f))(*(Byte*)(pData+0));
+       }
+   }
+   break;
+ case 0x0041:
+   if (0 == rSize) {
+     ((Void(*)(Int,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Int,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Int,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4));
+       }
+   }
+   break;
+ case 0x0011:
+   if (0 == rSize) {
+     ((Void(*)(Byte,Byte))(m->f))(*(Byte*)(pData+0),*(Byte*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Byte,Byte))(m->f))(*(Byte*)(pData+0),*(Byte*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Byte,Byte))(m->f))(*(Byte*)(pData+0),*(Byte*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Byte,Byte))(m->f))(*(Byte*)(pData+0),*(Byte*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Byte,Byte))(m->f))(*(Byte*)(pData+0),*(Byte*)(pData+4));
+       }
+   }
+   break;
+ case 0x0411:
+   if (0 == rSize) {
+     ((Void(*)(Int,Byte,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Byte*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Byte,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Byte*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Byte,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Byte*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Byte,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Byte*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Byte,Byte))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Byte*)(pData+8));
+       }
+   }
+   break;
+ case 0x0012:
+   if (0 == rSize) {
+     ((Void(*)(Byte,Char))(m->f))(*(Byte*)(pData+0),*(Char*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Byte,Char))(m->f))(*(Byte*)(pData+0),*(Char*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Byte,Char))(m->f))(*(Byte*)(pData+0),*(Char*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Byte,Char))(m->f))(*(Byte*)(pData+0),*(Char*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Byte,Char))(m->f))(*(Byte*)(pData+0),*(Char*)(pData+4));
+       }
+   }
+   break;
+ case 0x0412:
+   if (0 == rSize) {
+     ((Void(*)(Int,Byte,Char))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Char*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Byte,Char))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Char*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Byte,Char))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Char*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Byte,Char))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Char*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Byte,Char))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Char*)(pData+8));
+       }
+   }
+   break;
+ case 0x0014:
+   if (0 == rSize) {
+     ((Void(*)(Byte,Int))(m->f))(*(Byte*)(pData+0),*(Int*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Byte,Int))(m->f))(*(Byte*)(pData+0),*(Int*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Byte,Int))(m->f))(*(Byte*)(pData+0),*(Int*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Byte,Int))(m->f))(*(Byte*)(pData+0),*(Int*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Byte,Int))(m->f))(*(Byte*)(pData+0),*(Int*)(pData+4));
+       }
+   }
+   break;
+ case 0x0414:
+   if (0 == rSize) {
+     ((Void(*)(Int,Byte,Int))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Int*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Byte,Int))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Int*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Byte,Int))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Int*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Byte,Int))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Int*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Byte,Int))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Int*)(pData+8));
+       }
+   }
+   break;
+ case 0x0018:
+   if (0 == rSize) {
+     ((Void(*)(Byte,Long))(m->f))(*(Byte*)(pData+0),*(Long*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Byte,Long))(m->f))(*(Byte*)(pData+0),*(Long*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Byte,Long))(m->f))(*(Byte*)(pData+0),*(Long*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Byte,Long))(m->f))(*(Byte*)(pData+0),*(Long*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Byte,Long))(m->f))(*(Byte*)(pData+0),*(Long*)(pData+4));
+       }
+   }
+   break;
+ case 0x0418:
+   if (0 == rSize) {
+     ((Void(*)(Int,Byte,Long))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Long*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Byte,Long))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Long*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Byte,Long))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Long*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Byte,Long))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Long*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Byte,Long))(m->f))(*(Int*)(pData+0),*(Byte*)(pData+4),*(Long*)(pData+8));
+       }
+   }
+   break;
+ case 0x0002:
+   if (0 == rSize) {
+     ((Void(*)(Char))(m->f))(*(Char*)(pData+0));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Char))(m->f))(*(Char*)(pData+0));
+       } else {
+           prv.F = ((Float(*)(Char))(m->f))(*(Char*)(pData+0));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Char))(m->f))(*(Char*)(pData+0));
+       } else {
+           prv.D = ((Double(*)(Char))(m->f))(*(Char*)(pData+0));
+       }
+   }
+   break;
+ case 0x0042:
+   if (0 == rSize) {
+     ((Void(*)(Int,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Int,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Int,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4));
+       }
+   }
+   break;
+ case 0x0021:
+   if (0 == rSize) {
+     ((Void(*)(Char,Byte))(m->f))(*(Char*)(pData+0),*(Byte*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Char,Byte))(m->f))(*(Char*)(pData+0),*(Byte*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Char,Byte))(m->f))(*(Char*)(pData+0),*(Byte*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Char,Byte))(m->f))(*(Char*)(pData+0),*(Byte*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Char,Byte))(m->f))(*(Char*)(pData+0),*(Byte*)(pData+4));
+       }
+   }
+   break;
+ case 0x0421:
+   if (0 == rSize) {
+     ((Void(*)(Int,Char,Byte))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Byte*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Char,Byte))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Byte*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Char,Byte))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Byte*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Char,Byte))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Byte*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Char,Byte))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Byte*)(pData+8));
+       }
+   }
+   break;
+ case 0x0022:
+   if (0 == rSize) {
+     ((Void(*)(Char,Char))(m->f))(*(Char*)(pData+0),*(Char*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Char,Char))(m->f))(*(Char*)(pData+0),*(Char*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Char,Char))(m->f))(*(Char*)(pData+0),*(Char*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Char,Char))(m->f))(*(Char*)(pData+0),*(Char*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Char,Char))(m->f))(*(Char*)(pData+0),*(Char*)(pData+4));
+       }
+   }
+   break;
+ case 0x0422:
+   if (0 == rSize) {
+     ((Void(*)(Int,Char,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Char*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Char,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Char*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Char,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Char*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Char,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Char*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Char,Char))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Char*)(pData+8));
+       }
+   }
+   break;
+ case 0x0024:
+   if (0 == rSize) {
+     ((Void(*)(Char,Int))(m->f))(*(Char*)(pData+0),*(Int*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Char,Int))(m->f))(*(Char*)(pData+0),*(Int*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Char,Int))(m->f))(*(Char*)(pData+0),*(Int*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Char,Int))(m->f))(*(Char*)(pData+0),*(Int*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Char,Int))(m->f))(*(Char*)(pData+0),*(Int*)(pData+4));
+       }
+   }
+   break;
+ case 0x0424:
+   if (0 == rSize) {
+     ((Void(*)(Int,Char,Int))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Int*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Char,Int))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Int*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Char,Int))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Int*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Char,Int))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Int*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Char,Int))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Int*)(pData+8));
+       }
+   }
+   break;
+ case 0x0028:
+   if (0 == rSize) {
+     ((Void(*)(Char,Long))(m->f))(*(Char*)(pData+0),*(Long*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Char,Long))(m->f))(*(Char*)(pData+0),*(Long*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Char,Long))(m->f))(*(Char*)(pData+0),*(Long*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Char,Long))(m->f))(*(Char*)(pData+0),*(Long*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Char,Long))(m->f))(*(Char*)(pData+0),*(Long*)(pData+4));
+       }
+   }
+   break;
+ case 0x0428:
+   if (0 == rSize) {
+     ((Void(*)(Int,Char,Long))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Long*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Char,Long))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Long*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Char,Long))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Long*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Char,Long))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Long*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Char,Long))(m->f))(*(Int*)(pData+0),*(Char*)(pData+4),*(Long*)(pData+8));
+       }
+   }
+   break;
+ case 0x0441:
+   if (0 == rSize) {
+     ((Void(*)(Int,Int,Byte))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Byte*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Int,Byte))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Byte*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Int,Byte))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Byte*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Int,Byte))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Byte*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Int,Byte))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Byte*)(pData+8));
+       }
+   }
+   break;
+ case 0x0442:
+   if (0 == rSize) {
+     ((Void(*)(Int,Int,Char))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Char*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Int,Char))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Char*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Int,Char))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Char*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Int,Char))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Char*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Int,Char))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Char*)(pData+8));
+       }
+   }
+   break;
+ case 0x0444:
+   if (0 == rSize) {
+     ((Void(*)(Int,Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Int*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Int*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Int*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Int*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Int,Int))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Int*)(pData+8));
+       }
+   }
+   break;
+ case 0x0048:
+   if (0 == rSize) {
+     ((Void(*)(Int,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4));
+       } else {
+           prv.F = ((Float(*)(Int,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4));
+       } else {
+           prv.D = ((Double(*)(Int,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4));
+       }
+   }
+   break;
+ case 0x0448:
+   if (0 == rSize) {
+     ((Void(*)(Int,Int,Long))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Long*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Int,Long))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Long*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Int,Int,Long))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Long*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Int,Long))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Long*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Int,Int,Long))(m->f))(*(Int*)(pData+0),*(Int*)(pData+4),*(Long*)(pData+8));
+       }
+   }
+   break;
+ case 0x0008:
+   if (0 == rSize) {
+     ((Void(*)(Long))(m->f))(*(Long*)(pData+0));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Long))(m->f))(*(Long*)(pData+0));
+       } else {
+           prv.F = ((Float(*)(Long))(m->f))(*(Long*)(pData+0));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Long))(m->f))(*(Long*)(pData+0));
+       } else {
+           prv.D = ((Double(*)(Long))(m->f))(*(Long*)(pData+0));
+       }
+   }
+   break;
+ case 0x0081:
+   if (0 == rSize) {
+     ((Void(*)(Long,Byte))(m->f))(*(Long*)(pData+0),*(Byte*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Long,Byte))(m->f))(*(Long*)(pData+0),*(Byte*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Long,Byte))(m->f))(*(Long*)(pData+0),*(Byte*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Long,Byte))(m->f))(*(Long*)(pData+0),*(Byte*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Long,Byte))(m->f))(*(Long*)(pData+0),*(Byte*)(pData+8));
+       }
+   }
+   break;
+ case 0x0481:
+   if (0 == rSize) {
+     ((Void(*)(Int,Long,Byte))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Byte*)(pData+12));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Long,Byte))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Byte*)(pData+12));
+       } else {
+           prv.F = ((Float(*)(Int,Long,Byte))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Byte*)(pData+12));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Long,Byte))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Byte*)(pData+12));
+       } else {
+           prv.D = ((Double(*)(Int,Long,Byte))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Byte*)(pData+12));
+       }
+   }
+   break;
+ case 0x0082:
+   if (0 == rSize) {
+     ((Void(*)(Long,Char))(m->f))(*(Long*)(pData+0),*(Char*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Long,Char))(m->f))(*(Long*)(pData+0),*(Char*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Long,Char))(m->f))(*(Long*)(pData+0),*(Char*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Long,Char))(m->f))(*(Long*)(pData+0),*(Char*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Long,Char))(m->f))(*(Long*)(pData+0),*(Char*)(pData+8));
+       }
+   }
+   break;
+ case 0x0482:
+   if (0 == rSize) {
+     ((Void(*)(Int,Long,Char))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Char*)(pData+12));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Long,Char))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Char*)(pData+12));
+       } else {
+           prv.F = ((Float(*)(Int,Long,Char))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Char*)(pData+12));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Long,Char))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Char*)(pData+12));
+       } else {
+           prv.D = ((Double(*)(Int,Long,Char))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Char*)(pData+12));
+       }
+   }
+   break;
+ case 0x0084:
+   if (0 == rSize) {
+     ((Void(*)(Long,Int))(m->f))(*(Long*)(pData+0),*(Int*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Long,Int))(m->f))(*(Long*)(pData+0),*(Int*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Long,Int))(m->f))(*(Long*)(pData+0),*(Int*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Long,Int))(m->f))(*(Long*)(pData+0),*(Int*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Long,Int))(m->f))(*(Long*)(pData+0),*(Int*)(pData+8));
+       }
+   }
+   break;
+ case 0x0484:
+   if (0 == rSize) {
+     ((Void(*)(Int,Long,Int))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Int*)(pData+12));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Long,Int))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Int*)(pData+12));
+       } else {
+           prv.F = ((Float(*)(Int,Long,Int))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Int*)(pData+12));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Long,Int))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Int*)(pData+12));
+       } else {
+           prv.D = ((Double(*)(Int,Long,Int))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Int*)(pData+12));
+       }
+   }
+   break;
+ case 0x0088:
+   if (0 == rSize) {
+     ((Void(*)(Long,Long))(m->f))(*(Long*)(pData+0),*(Long*)(pData+8));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Long,Long))(m->f))(*(Long*)(pData+0),*(Long*)(pData+8));
+       } else {
+           prv.F = ((Float(*)(Long,Long))(m->f))(*(Long*)(pData+0),*(Long*)(pData+8));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Long,Long))(m->f))(*(Long*)(pData+0),*(Long*)(pData+8));
+       } else {
+           prv.D = ((Double(*)(Long,Long))(m->f))(*(Long*)(pData+0),*(Long*)(pData+8));
+       }
+   }
+   break;
+ case 0x0488:
+   if (0 == rSize) {
+     ((Void(*)(Int,Long,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Long*)(pData+12));
+   } else if (4 >= rSize) {
+       if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+           prv.I = ((Int(*)(Int,Long,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Long*)(pData+12));
+       } else {
+           prv.F = ((Float(*)(Int,Long,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Long*)(pData+12));
+       }
+   } else {
+       if (&cl_double != PCT_primClass(rpct)) {
+           prv.J = ((Long(*)(Int,Long,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Long*)(pData+12));
+       } else {
+           prv.D = ((Double(*)(Int,Long,Long))(m->f))(*(Int*)(pData+0),*(Long*)(pData+4),*(Long*)(pData+12));
+       }
+   }
+   break;
+ 
+             default:
+                 /* Remember that invocation failed so we can recover. */
+                 didInv = JAVA_FALSE;
+                 break;
+         }
+     }
+ 
+     /* If we haven't successfully invoked the method, attempt to do so
+      * treating all parameters as object pointers.  We're assuming it's
+      * safe to pass more params to a function than it was declared to
+      * take; C's pretty lenient that way, at least pre-ANSI. */
+     if (! didInv) {
+         Object * inParams;      /* Aliased parameter pointer */
+ 
+         /* We can't invoke this way if some parameter isn't of a conforming
+          * size. */
+         if (hasNonObjParam) {
+             throwInternalError ("invoke: Unsupported parameter grouping.  Try updating runtime/invoke_c.c.");
+         }
+         inParams = (Object *) pData;
+         /* Invoke the appropriate function returning 0-byte, 4-byte, or 8-byte
+          * values. */
+         if (0 == rSize) {
+             ((Void (*) ()) (m->f)) (inParams[0], inParams[1],  inParams[2],
+                                     inParams[3], inParams[4],  inParams[5],
+                                     inParams[6], inParams[7],  inParams[8],
+                                     inParams[9], inParams[10], inParams[11]);
+         } else if (4 >= rSize) {
+             if ((NULL == rpct) || (&cl_float != PCT_primClass(rpct))) {
+                 prv.I = ((Int (*) ()) (m->f)) (inParams[0], inParams[1],  inParams[2],
+                                                inParams[3], inParams[4],  inParams[5],
+                                                inParams[6], inParams[7],  inParams[8],
+                                                inParams[9], inParams[10], inParams[11]);
+             } else {
+                 prv.F = ((Float (*) ()) (m->f)) (inParams[0], inParams[1],  inParams[2],
+                                                  inParams[3], inParams[4],  inParams[5],
+                                                  inParams[6], inParams[7],  inParams[8],
+                                                  inParams[9], inParams[10], inParams[11]);
+             }
+         } else {
+             if (&cl_double != PCT_primClass(rpct)) {
+                 prv.J = ((Long (*) ()) (m->f)) (inParams[0], inParams[1],  inParams[2],
+                                                 inParams[3], inParams[4],  inParams[5],
+                                                 inParams[6], inParams[7],  inParams[8],
+                                                 inParams[9], inParams[10], inParams[11]);
+             } else {
+                 prv.D = ((Double (*) ()) (m->f)) (inParams[0], inParams[1],  inParams[2],
+                                                   inParams[3], inParams[4],  inParams[5],
+                                                   inParams[6], inParams[7],  inParams[8],
+                                                   inParams[9], inParams[10], inParams[11]);
+             }
+         }
+     }
+ 
+     /* Zero out the return value, and copy over the invocation return if
+      * it's an object type, or wrap it if it's a primitive non-void type. */
+     orv = NULL;
+     if (NULL == rpct) {
+         orv = (Object) prv.I;
+     } else if (0 < rSize) {
+         /* If the actual value isn't 4 bytes, do a cast to the appropriate
+          * size to work around byte order problems in the AnyJavaValue union. */
+         if (1 == rSize) {
+             prv.B = (Byte) prv.I;
+         } else if (2 == rSize) {
+             prv.S = (Short) prv.I;
+         }
+         orv = wrapPrimObject (PCT_primClass (rpct), &prv);
+     }
+     
+     return orv;
+ }
+ 
+ Object
+ invoke_c (struct mt_generic *m, /* Information on the method we're to invoke */
+           Object iobj,          /* Instance object on which we're invoking the method */
+           struct aarray *expectedArgs, /* Array of jlClass objects representing formal params*/
+           struct aarray *givenArgs, /* Array of jlObject objects representing actual params */
+           Boolean isInstance,   /* Do we invoke this as an instance method? */
+           Boolean useVoid)      /* Do we invoke this as a void method? */
+ {
+     int nParams;                /* Number of parameters in method */
+     char inParamBlock [MAX_PARAM_WORDS * sizeof (Object)];
+     char inParamSize [MAX_PARAM_WORDS];
+     char * nextParamData;
+     char * nextParamSize;
+     Object *expParams;          /* Pointer into sequence of jlClass objects naming parameter types */
+     Object *giveParams;         /* Pointer into sequence of jlObject objects wrapping actual parameters */
+     Object param;
+     struct mythread *tdata;
+     jmp_buf newbuf;
+     void * oldjmpbuf;
+     int i;
+     Object rv;
+ 
+     /* There's a critical assumption in all this that objects are the same
+      * size as ints.  If you're running on a 64-bit machine, you'll need
+      * to modify the switch statement in the invoker function, and probably
+      * do a bunch of other stuff too. */
+     if (4 != sizeof(Object)) {
+         throwInternalError ("invoke: Built-in assumption that pointers are 4-bytes is wrong.");
+     }
+ 
+     memset (inParamBlock, 0, sizeof (inParamBlock));
+     nextParamData = inParamBlock;
+     nextParamSize = inParamSize;
+ 
+     nParams = expectedArgs->length;
+     expParams = expectedArgs->data;
+     giveParams = givenArgs->data;
+ 
+     /* Comments match javadoc for reflect.Constructor and reflect.Method */
+ 
+     /* If this Method object enforces Java language access control and
+      * the underlying method is inaccessible, the creation throws an
+      * IllegalAccessException. */
+     if (ACC_ABSTRACT == (m->access & ACC_ABSTRACT)) {
+         throwIllegalAccessException ("method inaccessible");
+     }
+ 
+     /* NB: We don't have enough information here to enforce other access
+      * controls: specifically, we may have a protected method, where
+      * invocation is allowed if we're running inside a subclass.  Also,
+      * constructors that are protected seem to be callable from anywhere if
+      * they're the only constructor.  Java is a weird language.*/
+ 
+     /* If the number of actual parameters supplied via args is different
+      * from the number of formal parameters required by the underlying method,
+      * the invocation throws an IllegalArgumentException. */
+     if (nParams != givenArgs->length) {
+         throwIllegalArgumentException ("wrong number of arguments");
+     }
+ 
+     /* First parameter is the instance object.  Don't need to do type/value
+      * checking on it; that was done by our caller. */
+     if (isInstance) {
+         *nextParamSize = sizeof (iobj);
+         *(Object *)nextParamData = iobj;
+         nextParamData += (4 >= *nextParamSize) ? 4 : *nextParamSize;
+         ++nextParamSize;
+     }
+ 
+     /* For each actual parameter in the supplied initargs array:
+      * If the corresponding formal parameter has a primitive type,
+      * an unwrapping conversion is attempted to convert the object
+      * value to a value of the primitive type.
+      * If this attempt fails, the creation throws an IllegalArgumentException.
+      * If, after possible unwrapping, the parameter value cannot be
+      * converted to the corresponding formal parameter type by an identity
+      * or widening conversion, the creation throws an
+      * IllegalArgumentException. */
+ 
+     for (i = 0 ; i < nParams; i++) {
+         Class fpcl;             /* Formal parameter class */
+         Class apcl;             /* Actual parameter class */
+         Object aparam;          /* Actual parameter as object */
+         PrimClassTriple * fpct; /* Translation info for formal parameter */
+         PrimClassTriple * apct; /* Translation info for actual parameter */
+ 
+         /* Get the class information for the formal parameter.  If the
+          * actual parameter isn't null, get its class info too. */
+         fpcl = find_class ((struct in_java_lang_Class *)expParams [i]);
+         apcl = NULL;
+         apct = NULL;
+         aparam = giveParams [i];
+         if (NULL != aparam) {
+             apcl = ((struct in_generic *)aparam)->class;
+             apct = getPCTbyObjClass (apcl);
+         }
+ 
+         /* If the actual parameter is present, and the corresponding formal
+          * is a primitive type, attempt to do the conversion into the
+          * parameter buffer; if that fails, we'll break out, and throw
+          * an IAE later. */
+         if ((NULL != apct) && (IS_PRIMITIVE & fpcl->flags)) {
+             fpct = getPCTbyPrimClass (fpcl);
+             assert (NULL != fpct);
+             /* Convert from the native format of the actual parameter into
+              * the native format of the formal parameter, storing data into
+              * the destination buffer. */
+             if (! widenConvert (PCT_primClass (apct), PCT_objPrimValAddr (apct, aparam),
+                                 fpcl, nextParamData)) {
+                 break;
+             }
+             /* Record how big the formal parameter (what we're actually passing) is. */
+             *nextParamSize = PCT_primSize (fpct);
+         } else {
+             /* Not a primitive-to-primitive assignment.  If the formal type is not
+              * primitive, and the value is either null or assignable to the formal
+              * type, stuff it into place. */
+             if ((! (IS_PRIMITIVE & fpcl->flags)) &&
+                 ((NULL == aparam) ||
+                  assignablefrom (fpcl, apcl))) {
+                 *nextParamSize = sizeof (aparam);
+                 * (Object *)nextParamData = aparam;
+             } else {
+                 /* We can't deal with this. */
+                 break;
+             }
+         }
+         /* Increment the pointer into the actual parameter buffer; do this
+          * 4-byte aligned.  Also point to the next size element. */
+         nextParamData += (4 >= *nextParamSize) ? 4 : *nextParamSize;
+         ++nextParamSize;
+         if (((inParamBlock + sizeof(inParamBlock)) <= nextParamData) ||
+             ((inParamSize + sizeof(inParamSize)) <= nextParamSize)) {
+             throwInternalError ("invoke: too many arguments; need to implement expandable buffers");
+         }
+     }
+     /* If we get out without converting everything, throw an IAE */
+     if (i < nParams) {
+         throwIllegalArgumentException ("argument type mismatch");
+     }
+ 
+     /* Control transfers to the underlying constructor to initialize the
+      * new instance. If the constructor completes abruptly by throwing an
+      * exception, the exception is placed in an InvocationTargetException
+      * and thrown in turn to the caller of newInstance. */
+     tdata = mythread();
+     oldjmpbuf = tdata->jmpbuf;
+     if (setjmp(newbuf)) {
+         Object excep;           /* Exception that was thrown */
+         Object ite;             /* jlrITE encapsulating exception */
+ 
+         /* Clean up after the exception.  Reset state so when we throw the
+          * ITE we'll end up in the caller's exception handler.  Create a
+          * new ITE exception object saving the exception that we caught so
+          * the user can look at it.  Throw the ITE. */
+         sthread_got_exception();
+         tdata->jmpbuf = oldjmpbuf;
+         excep = tdata->exception;
+         ite = new(&cl_java_lang_reflect_InvocationTargetException.C);
+         /* call constructor for jlrITE */
+         init_TS_usqSb (ite, excep, 0);
+         athrow(ite);
+     }
+ 
+ 
+     /* Save the new exception buffer, and invoke the method. */
+     tdata->jmpbuf = newbuf;
+     rv = invoke_object (m, (nextParamSize - inParamSize), inParamSize, inParamBlock);
+     
+     /* Restore the previous exception handler and return the result of
+      * the invocation. */
+     mythread()->jmpbuf = oldjmpbuf;
+ 
+     return rv;
+ }
Index: toba-1.1/runtime/io_ObjectInputStream.c
diff -c toba-1.1/runtime/io_ObjectInputStream.c:1.1 toba-1.1/runtime/io_ObjectInputStream.c:1.2
*** toba-1.1/runtime/io_ObjectInputStream.c:1.1	Sat Apr 18 16:30:18 1998
--- toba-1.1/runtime/io_ObjectInputStream.c	Mon Nov  9 13:58:22 1998
***************
*** 1,4 ****
--- 1,6 ----
+ #ifndef SCOUT
  #include <fcntl.h>
+ #endif /* SCOUT */
  #include "toba.h"
  #include "runtime.h"
  #include "java_io_ObjectInputStream.h"
Index: toba-1.1/runtime/io_ObjectOutputStream.c
diff -c toba-1.1/runtime/io_ObjectOutputStream.c:1.1 toba-1.1/runtime/io_ObjectOutputStream.c:1.2
*** toba-1.1/runtime/io_ObjectOutputStream.c:1.1	Sat Apr 18 16:30:18 1998
--- toba-1.1/runtime/io_ObjectOutputStream.c	Mon Nov  9 13:58:22 1998
***************
*** 1,4 ****
--- 1,6 ----
+ #ifndef SCOUT
  #include <fcntl.h>
+ #endif /* SCOUT */
  #include "toba.h"
  #include "runtime.h"
  #include "java_io_ObjectOutputStream.h"
Index: toba-1.1/runtime/io_ObjectStreamClass.c
diff -c toba-1.1/runtime/io_ObjectStreamClass.c:1.1 toba-1.1/runtime/io_ObjectStreamClass.c:1.2
*** toba-1.1/runtime/io_ObjectStreamClass.c:1.1	Sat Apr 18 16:30:18 1998
--- toba-1.1/runtime/io_ObjectStreamClass.c	Thu Dec  3 11:55:29 1998
***************
*** 97,102 ****
--- 97,104 ----
  	if (len==namelen && memcmp(namebuf,buf,len*sizeof(Char))==0)
  	    return mt[i].access;
      }
+     throwInternalError("jiObjectStreamClass: Improper argument to private native method");
+     /*NOTREACHED*/
  }
  
  Object	getFieldSignatures_C_vtzTW(Object Harg1) /* Since JDK1.1 */
***************
*** 155,160 ****
--- 157,164 ----
  	if (len==namelen && memcmp(buf,namebuf,len*sizeof(Char))==0)
  	    return vt[i].access;
      }
+     throwInternalError("jiObjectStreamClass: Improper argument to private native method");
+     /*NOTREACHED*/
  }
  
  /* Get the array of non-static non-transient fields */
Index: toba-1.1/runtime/java_lang_Character-hc.c
diff -c toba-1.1/runtime/java_lang_Character-hc.c:1.2 toba-1.1/runtime/java_lang_Character-hc.c:1.3
*** toba-1.1/runtime/java_lang_Character-hc.c:1.2	Mon Jul 27 12:24:41 1998
--- toba-1.1/runtime/java_lang_Character-hc.c	Thu Dec  3 11:55:29 1998
***************
*** 750,755 ****
--- 750,756 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M hashCode__WOaBD: java.lang.Character.hashCode()I */
***************
*** 774,779 ****
--- 775,781 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M equals_O_LwTmy: java.lang.Character.equals(Ljava/lang/Object;)Z */
***************
*** 831,836 ****
--- 833,839 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M toString__wiHO9: java.lang.Character.toString()Ljava/lang/String; */
***************
*** 873,878 ****
--- 876,882 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isLowerCase_c_GbMan: java.lang.Character.isLowerCase(C)Z */
***************
*** 934,939 ****
--- 938,944 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isUpperCase_c_1nbCM: java.lang.Character.isUpperCase(C)Z */
***************
*** 995,1000 ****
--- 1000,1006 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isTitleCase_c_PxFAc: java.lang.Character.isTitleCase(C)Z */
***************
*** 1056,1061 ****
--- 1062,1068 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isDigit_c_489xD: java.lang.Character.isDigit(C)Z */
***************
*** 1117,1122 ****
--- 1124,1130 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isDefined_c_KWB7r: java.lang.Character.isDefined(C)Z */
***************
*** 1177,1182 ****
--- 1185,1191 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isLetter_c_DsO7h: java.lang.Character.isLetter(C)Z */
***************
*** 1241,1246 ****
--- 1250,1256 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isLetterOrDigit_c_7lxPy: java.lang.Character.isLetterOrDigit(C)Z */
***************
*** 1305,1310 ****
--- 1315,1321 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isJavaLetter_c_p8wvb: java.lang.Character.isJavaLetter(C)Z */
***************
*** 1366,1371 ****
--- 1377,1383 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isJavaLetterOrDigit_c_1rcua: java.lang.Character.isJavaLetterOrDigit(C)Z */
***************
*** 1426,1431 ****
--- 1438,1444 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isJavaIdentifierStart_c_6EJtS: java.lang.Character.isJavaIdentifierStart(C)Z */
***************
*** 1487,1492 ****
--- 1500,1506 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isJavaIdentifierPart_c_nEv70: java.lang.Character.isJavaIdentifierPart(C)Z */
***************
*** 1547,1552 ****
--- 1561,1567 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isUnicodeIdentifierStar_c_Rlxqr: java.lang.Character.isUnicodeIdentifierStart(C)Z */
***************
*** 1608,1613 ****
--- 1623,1629 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isUnicodeIdentifierPart_c_qxU9a: java.lang.Character.isUnicodeIdentifierPart(C)Z */
***************
*** 1668,1673 ****
--- 1684,1690 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isIdentifierIgnorable_c_9OyUG: java.lang.Character.isIdentifierIgnorable(C)Z */
***************
*** 1729,1734 ****
--- 1746,1752 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M toLowerCase_c_Kft8E: java.lang.Character.toLowerCase(C)C */
***************
*** 1796,1801 ****
--- 1814,1820 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M toUpperCase_c_5rSz3: java.lang.Character.toUpperCase(C)C */
***************
*** 1863,1868 ****
--- 1882,1888 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M toTitleCase_c_TBmyt: java.lang.Character.toTitleCase(C)C */
***************
*** 1960,1965 ****
--- 1980,1986 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M digit_ci_Cj4mh: java.lang.Character.digit(CI)I */
***************
*** 2066,2071 ****
--- 2087,2093 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M getNumericValue_c_kBwFE: java.lang.Character.getNumericValue(C)I */
***************
*** 2213,2218 ****
--- 2235,2241 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isSpace_c_LYJJQ: java.lang.Character.isSpace(C)Z */
***************
*** 2332,2337 ****
--- 2355,2361 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isWhitespace_c_2ZLys: java.lang.Character.isWhitespace(C)Z */
***************
*** 2393,2398 ****
--- 2417,2423 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M isISOControl_c_VHYwq: java.lang.Character.isISOControl(C)Z */
***************
*** 2482,2487 ****
--- 2507,2513 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M forDigit_ii_BpWTd: java.lang.Character.forDigit(II)C */
***************
*** 3828,3833 ****
--- 3854,3860 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  
Index: toba-1.1/runtime/java_text_DecompositionIterator-hc.c
diff -c toba-1.1/runtime/java_text_DecompositionIterator-hc.c:1.2 toba-1.1/runtime/java_text_DecompositionIterator-hc.c:1.3
*** toba-1.1/runtime/java_text_DecompositionIterator-hc.c:1.2	Mon Jul 27 12:24:42 1998
--- toba-1.1/runtime/java_text_DecompositionIterator-hc.c	Thu Dec  3 11:55:30 1998
***************
*** 491,496 ****
--- 491,497 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M next__XpA3r: java.text.DecompositionIterator.next()C */
***************
*** 796,801 ****
--- 797,803 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M previous__PctOH: java.text.DecompositionIterator.previous()C */
***************
*** 986,991 ****
--- 988,994 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M reset__MuNyF: java.text.DecompositionIterator.reset()V */
***************
*** 1021,1026 ****
--- 1024,1030 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M decompose_ci_mIHlA: java.text.DecompositionIterator.decompose(CI)Ljava/lang/String; */
***************
*** 1128,1133 ****
--- 1132,1138 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M decompose_Si_5Zmdx: java.text.DecompositionIterator.decompose(Ljava/lang/StringBuffer;I)V */
***************
*** 1162,1167 ****
--- 1167,1173 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M decompose_Siii_DN1z4: java.text.DecompositionIterator.decompose(Ljava/lang/StringBuffer;III)V */
***************
*** 1313,1318 ****
--- 1319,1325 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M decompose_Si_DUgkc: java.text.DecompositionIterator.decompose(Ljava/lang/String;I)Ljava/lang/String; */
***************
*** 1347,1352 ****
--- 1354,1360 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M decompose_Siii_nh0Qv: java.text.DecompositionIterator.decompose(Ljava/lang/String;III)Ljava/lang/String; */
***************
*** 1467,1472 ****
--- 1475,1481 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M decompose_caci_hGLZD: java.text.DecompositionIterator.decompose(C[CI)I */
***************
*** 1567,1572 ****
--- 1576,1582 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  /*M getMaximumDecomposition__TWsKf: java.text.DecompositionIterator.getMaximumDecomposition()I */
***************
*** 1722,1727 ****
--- 1732,1738 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  static short kOffsetIndex[]={
***************
*** 2845,2850 ****
--- 2856,2862 ----
  
  NULLX:
  	throwNullPointerException(0);
+ 	/*NOTREACHED*/
  }
  
  
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.17
*** toba-1.1/runtime/lang_Class.c:1.9	Wed May  6 14:29:31 1998
--- toba-1.1/runtime/lang_Class.c	Thu Dec  3 11:55:30 1998
***************
*** 2,19 ****
  #include <assert.h>
  #include <string.h>
  #include "toba.h"
! #include "runtime.h"
  #include "java_lang_Class.h"
  #include "java_lang_String.h"
  #include "java_util_Hashtable.h"
  #include "java_lang_Object.h"
  #include "java_lang_reflect_Field.h"
  #include "java_lang_reflect_Method.h"
  #include "java_lang_reflect_Constructor.h"
  #include "java_lang_NoSuchFieldException.h"
  #include "java_lang_NoSuchMethodException.h"
- #include "classfile_ClassData.h"
  #include "java_io_Serializable.h"
  #ifdef OPTION_JIT
  #include "toba_runtime_SystemClassLoader.h"
  
--- 2,41 ----
  #include <assert.h>
  #include <string.h>
  #include "toba.h"
! #include "java_lang_Boolean.h"
! #include "java_lang_Byte.h"
! #include "java_lang_Integer.h"
! #include "java_lang_Short.h"
! #include "java_lang_Long.h"
! #include "java_lang_Float.h"
! #include "java_lang_Double.h"
! #include "java_lang_Character.h"
! #include "java_lang_Void.h"
  #include "java_lang_Class.h"
  #include "java_lang_String.h"
  #include "java_util_Hashtable.h"
  #include "java_lang_Object.h"
  #include "java_lang_reflect_Field.h"
+ #include "java_lang_reflect_Member.h"
  #include "java_lang_reflect_Method.h"
  #include "java_lang_reflect_Constructor.h"
  #include "java_lang_NoSuchFieldException.h"
  #include "java_lang_NoSuchMethodException.h"
  #include "java_io_Serializable.h"
+ #include "runtime.h"
+ #include "reflect.h"
+ #include "classfile_ClassData.h"
+ 
+ /* Tags to identify method as member/nonmember */
+ typedef enum
+ MethodCategory {
+     MT_constructor,             /* Method is named "<init>" */
+     MT_staticInitializer,       /* Method is named "<clinit>" */
+     MT_memberMethod             /* Method is a member method */
+ } MethodCategory;
+ 
+ static Object GetClassFromSignature(const Char *sig,int *cnt);
+ 
  #ifdef OPTION_JIT
  #include "toba_runtime_SystemClassLoader.h"
  
***************
*** 24,36 ****
  
  /* 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
  register_class(Class cl)
  {
!     if (all_classes == NULL) {
  	struct in_java_util_Hashtable * nac;
  
  	/* make a hashtable w/ 250 buckets to start with */
--- 46,57 ----
  
  /* hash table with (classname -> instance of class Class) */
  static struct in_java_util_Hashtable *all_classes = 0;
  
  /* install a class in the hashtable (called during startup) */
  void
  register_class(Class cl)
  {
!     if (NULL == all_classes) {
  	struct in_java_util_Hashtable * nac;
  
  	/* make a hashtable w/ 250 buckets to start with */
***************
*** 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;
  }
  
--- 110,156 ----
      /* 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){
!         Char *s = arg1->offset + ((struct carray*)arg1->value)->data;
  	
! 	/* find array classes; we never jit those. */
!         if ('[' == *s) {
!             return GetClassFromSignature(s, NULL);
!         }
!     }
! 
! #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;
  }
  
***************
*** 136,143 ****
      /* we're never allowed to newInstance java.lang.Class
       * since all instances *must* be embedded within struct Class
       */
!     if(cl == &cl_java_lang_Class.C)
          throwIllegalAccessException("can't instantiate java.lang.Class");
  
      res = construct(cl);
      return res;
--- 165,173 ----
      /* we're never allowed to newInstance java.lang.Class
       * since all instances *must* be embedded within struct Class
       */
!     if (cl == &cl_java_lang_Class.C) {
          throwIllegalAccessException("can't instantiate java.lang.Class");
+     }
  
      res = construct(cl);
      return res;
***************
*** 159,173 ****
  Object getSuperclass__bNIlH(Object Harg1) 
  {
      struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     Class cl, super;
  
      /* do we have a superclass? */
!     cl = find_class(this);
!     if(cl->nsupers < 2)
!         return 0;
  
!     super = cl->supers[1];
!     return find_classclass(super);
  }
  
  /* java/lang/Class getInterfaces ()[Ljava/lang/Class; */
--- 189,203 ----
  Object getSuperclass__bNIlH(Object Harg1) 
  {
      struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     Class cl;
  
      /* do we have a superclass? */
!     cl = find_class (this);
!     if (2 > cl->nsupers) {
!         return NULL;
!     }
  
!     return find_classclass(cl->supers [1]);
  }
  
  /* java/lang/Class getInterfaces ()[Ljava/lang/Class; */
***************
*** 181,187 ****
      c = find_class(this);
      inters = anewarray(&cl_java_lang_Class.C, c->ndinters);
  
!     for(i = 0; i < c->ndinters; i++) {
          inters->data[i] = find_classclass(c->inters[i]);
      }
      return inters;
--- 211,217 ----
      c = find_class(this);
      inters = anewarray(&cl_java_lang_Class.C, c->ndinters);
  
!     for (i = 0; i < c->ndinters; i++) {
          inters->data[i] = find_classclass(c->inters[i]);
      }
      return inters;
***************
*** 201,210 ****
      Class cl;
  
      cl = find_class(this);
!     if(cl->flags & IS_INTERFACE)
          return JAVA_TRUE;
!     else
          return JAVA_FALSE;
  }
  
  Boolean	isInstance_O_ggynA(Object Harg1, Object Harg2) /* Since JDK1.1 */
--- 231,241 ----
      Class cl;
  
      cl = find_class(this);
!     if (cl->flags & IS_INTERFACE) {
          return JAVA_TRUE;
!     } else {
          return JAVA_FALSE;
+     }
  }
  
  Boolean	isInstance_O_ggynA(Object Harg1, Object Harg2) /* Since JDK1.1 */
***************
*** 213,222 ****
      Class cl;
  
      cl = find_class(this);
!     if (instanceof(Harg2,cl,0))
  	return JAVA_TRUE;
!     else
  	return JAVA_FALSE;
  }
  
  Boolean	isAssignableFrom_C_3OtSc(Object Harg1, Object Harg2) /* Since JDK1.1 */
--- 244,254 ----
      Class cl;
  
      cl = find_class(this);
!     if (instanceof(Harg2,cl,0)) {
  	return JAVA_TRUE;
!     } else {
  	return JAVA_FALSE;
+     }
  }
  
  Boolean	isAssignableFrom_C_3OtSc(Object Harg1, Object Harg2) /* Since JDK1.1 */
***************
*** 228,238 ****
      cl_this = find_class(this);
      cl_arg  = find_class(arg);
  
!     if (assignablefrom(cl_this,cl_arg))
! 	return 1;
!     if ((cl_arg->flags&IS_ARRAY) && cl_this==&cl_java_io_Serializable.C)
! 	return 1;
!     return 0;
  }
  
  Boolean	isArray__yE28G(Object Harg1) /* Since JDK1.1 */
--- 260,266 ----
      cl_this = find_class(this);
      cl_arg  = find_class(arg);
  
!     return assignablefrom(cl_this, cl_arg);
  }
  
  Boolean	isArray__yE28G(Object Harg1) /* Since JDK1.1 */
***************
*** 241,250 ****
      Class cl;
  
      cl = find_class(this);
!     if (cl->flags & IS_ARRAY){
          return JAVA_TRUE;
!     }
!     else{
          return JAVA_FALSE;
      }
  }
--- 269,277 ----
      Class cl;
  
      cl = find_class(this);
!     if (cl->flags & IS_ARRAY) {
          return JAVA_TRUE;
!     } else {
          return JAVA_FALSE;
      }
  }
***************
*** 255,264 ****
      Class cl;
  
      cl = find_class(this);
!     if (cl->flags & IS_PRIMITIVE){
          return JAVA_TRUE;
!     }
!     else{
          return JAVA_FALSE;
      }
  }
--- 282,290 ----
      Class cl;
  
      cl = find_class(this);
!     if (cl->flags & IS_PRIMITIVE) {
          return JAVA_TRUE;
!     } else{
          return JAVA_FALSE;
      }
  }
***************
*** 275,283 ****
      cl = find_class(this);
      if (cl->flags & IS_ARRAY){
          return find_classclass(cl->elemclass);
      }
-     else
-         return 0;
  }
  
  Int	getModifiers__W5R4X(Object Harg1) /* Since JDK1.1 */
--- 301,309 ----
      cl = find_class(this);
      if (cl->flags & IS_ARRAY){
          return find_classclass(cl->elemclass);
+     } else {
+         return NULL;
      }
  }
  
  Int	getModifiers__W5R4X(Object Harg1) /* Since JDK1.1 */
***************
*** 293,993 ****
  {
      return anewarray(&cl_java_lang_Object.C,0);
  }
  Void	setSigners_aO_la6GY(Object Harg1, Object Harg2) /* Unimplemented JDK1.1 */
  {
  }
  
  extern struct class cl_void;
! Object	getPrimitiveClass_S_JFLGD(Object Harg1) /* Since JDK1.1 */
  {
!     Class  cl;
!     static char *primNames[]={ "boolean", "byte",  "char",   "short", "int",
! 			       "long",    "float", "double", "void" };
!     static Class primClasses[]={
!                                 &cl_boolean,
!                                 &cl_byte,
!                                 &cl_char,
!                                 &cl_short,
!                                 &cl_int,
!                                 &cl_long,
!                                 &cl_float,
!                                 &cl_double,
!                                 &cl_void
!                                };
!     int    i;
!     char   *name;
  
!     /* STATIC Method */
!     init_java_lang_Class();
!     name = cstring(Harg1);
!     for (i=0;i<sizeof(primNames)/sizeof(char*);i++)
!         if (strcmp(primNames[i],name)==0)
! 	    return find_classclass(primClasses[i]);
  
!     throwClassNotFoundException(name);
  }
  
! /* Parse signature and return a java Class object */
! static Object GetClassFromSignature(const Char *sig,int *cnt)
  {
!     Char buf[1024];
!     int  i,t;
!     Object clcl;
!     Class cl;
  
!     *cnt = 1;
!     switch(toupper(*sig)){
!     case 'B' : return getPrimitiveClass_S_JFLGD(javastring("byte"));
!     case 'C' : return getPrimitiveClass_S_JFLGD(javastring("char"));
!     case 'D' : return getPrimitiveClass_S_JFLGD(javastring("double"));
!     case 'F' : return getPrimitiveClass_S_JFLGD(javastring("float"));
!     case 'I' : return getPrimitiveClass_S_JFLGD(javastring("int"));
!     case 'J' : return getPrimitiveClass_S_JFLGD(javastring("long"));
!     case 'S' : return getPrimitiveClass_S_JFLGD(javastring("short"));
!     case 'V' : return getPrimitiveClass_S_JFLGD(javastring("void"));
!     case 'Z' : return getPrimitiveClass_S_JFLGD(javastring("boolean"));
!     case 'L' :
!                for (i=0,sig++; *sig!=';'; sig++,i++){
! 		   if (*sig=='/')
! 		       buf[i]='.';
! 		   else
! 		       buf[i]=*sig;
! 	       }
! 	       buf[i]=0;
! 	       *cnt = i+2;
! 	       return forName_S_UuOsX(arraystring(buf,i));
!     case '[' : clcl = GetClassFromSignature(sig+1,&t);
!                cl = find_class(clcl);
! 	       *cnt = t+1;
! 	       if (!cl->arrayclass)
! 		   return find_classclass(arrayclassof(cl));
! 	       else
! 		   return find_classclass(cl->arrayclass);
      }
  }
  
! /*
!  * Construct signature from a java.lang.Class object
!  * Return : number of characters appended
!  */
! static int GetSigFromClass(Object clcl,Char *buf)
  {
!     struct carray *v;
!     Class cl;
!     Char *p;
!     int  cnt=0;
!     int  i,len;
  
      cl = find_class((struct in_java_lang_Class*)clcl);
!     v = (struct carray*)((struct in_java_lang_String*)(cl->name))->value;
!     p = v->data;
!     len = ((struct in_java_lang_String*)(cl->name))->count;
!     if (cl->flags & IS_PRIMITIVE){
          *buf = toupper(*p);
! 	if (*p=='l')
  	    *buf = 'J';
! 	if (*p=='b' && *(p+1)=='o')
  	    *buf = 'Z';
  	cnt = 1;
!     }
!     else{
! 	for (*buf++ ='L',cnt=1,i=0; i<len; p++,buf++,cnt++,i++){
! 	    if (*p=='.')
! 	        *buf='/';
! 	    else
! 	        *buf=*p;
! 	}
  	*buf = ';';
! 	cnt++;
      }
      return cnt;
  }
  
! /*
!  * Construct the (partial) signature from an array of java.lang.Class objects
!  */
! static int GetSigFromArgTypes(Object args,Char *buf)
! {
!     int  i,n,cnt;
!     struct aarray *a=(struct aarray*)args;
!     struct in_java_lang_Class **clcls = (struct in_java_lang_Class**)a->data;
!     struct in_java_lang_Class *elem;
  
      *buf++ = '(';
!     cnt = 1;
      for (i=0; i<a->length; i++){
- 	if (isArray__yE28G(clcls[i])){
- 	    elem = getComponentType__hwyYb(clcls[i]);
- 	    *buf++ = '[';
- 	    cnt++;
- 	    while (isArray__yE28G(elem)){
- 	        elem = getComponentType__hwyYb(elem);
- 		*buf++ = '[';
- 		cnt++;
- 	    }
- 	    n = GetSigFromClass(elem,buf);
- 	    buf += n;
- 	    cnt += n;
- 	}
- 	else{
- 	    n = GetSigFromClass(clcls[i],buf);
- 	    buf += n;
- 	    cnt += n;
- 	}
-     }
-     *buf++ = ')';
-     cnt++;
-     *buf=0;
-     return cnt;
- }
  
! static Object GetRetTypeFromSig(const Char *sig,int sig_len)
! {
!     int  t,i;
  
!     for (i=0;i<sig_len;i++){
!         if (sig[i]==')')
! 	    break;
      }
-     if (i>=sig_len)
-         return 0;
  
!     return GetClassFromSignature(sig+i+1,&t);
  }
  
! static Object GetArgTypesFromSig(const Char *sig,int sig_len)
  {
!     struct aarray *args;
!     int    i,cnt;
!     const  Char   *p;
  
!     for (p=sig+1,cnt=0; *p!=')'; ){
!         if (*p=='L'){
! 	    while (*p++!=';');
! 	    cnt++;
! 	}
! 	else if (*p=='['){
! 	    p++;
! 	}
! 	else{
! 	    p++;
! 	    cnt++;
! 	}
      }
  
!     args = anewarray(&cl_java_lang_Class.C,cnt);
!     for (p=sig+1,i=0; *p!=')'; i++){
!         args->data[i] = GetClassFromSignature(p,&cnt);
! 	p += cnt;
      }
!     return args;
  }
  
! static int SameMethod(struct mt_generic *m1,struct mt_generic *m2);
! /* Return an array of exception classes */
! static Object GetExceptionTypes(Class cl,struct mt_generic *m)
! {
!     struct aarray *ret;
!     Class *p;
!     int i,j,cnt;
!     struct mt_generic *mtable;
!     int nmthds;
!     int found=0;
! 
!     /* the exception list is only set in defining class */
!     if (!m->localp){
!         for (i=1;i<cl->nsupers && !found;i++){
! 	    mtable = cl->supers[i]->smethods;
! 	    nmthds = cl->supers[i]->nsmethods;
! 	    for (j=0;j<nmthds;j++){
! 	        if (mtable[j].localp && SameMethod(m,mtable+j)){
! 		    m = mtable+j;
! 		    found=1;
! 		    break;
! 		}
! 	    }
! 	    if (found)
! 	        break;
! 	    mtable = ((struct cl_generic*)cl->supers[i])->M;
! 	    nmthds = cl->supers[i]->nimethods;
! 	    for (j=0;j<nmthds;j++){
! 	        if (mtable[j].localp && SameMethod(m,mtable+j)){
! 		    m = mtable+j;
! 		    found=1;
! 		    break;
! 		}
! 	    }
! 	}
      }
  
!     if (!m->xlist){
!         ret = anewarray(&cl_java_lang_Class.C,0);
! 	return ret;
      }
  
!     /* count the number of exceptions */
!     for (cnt=0,p=m->xlist; *p; p++,cnt++);
! 
!     ret = anewarray(&cl_java_lang_Class.C,cnt);
!     for (i=0; i<cnt; i++)
!         ret->data[i]=find_classclass(m->xlist[i]);
!     return ret;
  }
  
! int SameAsJavaStr(const Char *s,int len,Object jstr)
! {
!     struct carray *x;
!     int i;
! 
!     if (len!=((struct in_java_lang_String*)jstr)->count)
!         return 0;
!     x = (struct carray*)((struct in_java_lang_String*)jstr)->value;
  
!     for (i=0;i<len;i++)
!         if (s[i]!=x->data[i])
! 	    return 0;
!     return 1;
  }
  
- static int SameField(struct vt_generic *v1,struct vt_generic *v2)
- {
-     if ( v1->name_len==v2->name_len &&
- 	 v1->sig_len ==v2->sig_len &&
- 	 memcmp(v1->name_chars,v2->name_chars,v1->name_len*sizeof(Char))==0 &&
- 	 memcmp(v1->sig_chars, v2->sig_chars, v1->sig_len*sizeof(Char))==0 )
-         return 1;
-     return 0;
- }
  
! /* Check if a field is declared in the class */
! static int FieldDeclared(Class cl,struct vt_generic *vt)
  {
!     int  i;
! 
!     for (i=0;i<cl->ncvars;i++){
!         if (cl->cvars[i].localp && SameField(vt,cl->cvars+i))
! 	    return 1;
!     }
!     for (i=0;i<cl->nivars;i++){
!         if (cl->ivars[i].localp && SameField(vt,cl->ivars+i))
! 	    return 1;
      }
-     return 0;
- }
- 
- static int SameMethod(struct mt_generic *m1,struct mt_generic *m2)
- {
-     if ( m1->name_len==m2->name_len &&
- 	 m1->sig_len ==m2->sig_len &&
- 	 memcmp(m1->name_chars,m2->name_chars,m1->name_len*sizeof(Char))==0 &&
- 	 memcmp(m1->sig_chars, m2->sig_chars, m1->sig_len*sizeof(Char))==0 )
-         return 1;
-     return 0;
- }
  
! /* Check if a method is declared in the class */
! static int MethodDeclared(Class cl,struct mt_generic *mt)
! {
!     int  i;
!     struct mt_generic *mtable;
! 
!     mtable = cl->smethods;
!     for (i=0;i<cl->nsmethods;i++){
!         if (mtable[i].localp && SameMethod(mt,mtable+i))
! 	    return 1;
!     }
!     mtable = ((struct cl_generic*)cl)->M;
!     for (i=0;i<cl->nimethods;i++){
!         if (mtable[i].localp && SameMethod(mt,mtable+i))
! 	    return 1;
!     }
!     return 0;
  }
  
! static Object DeclaringClass_V(Class cl,struct vt_generic *v)
  {
      int i;
  
!     for (i=0;i<cl->nsupers;i++){
!         if (FieldDeclared(cl->supers[i],v))
! 	    return find_classclass(cl->supers[i]);
      }
! }
! static Object DeclaringClass_M(Class cl,struct mt_generic *m)
! {
!     int i;
  
!     for (i=0;i<cl->nsupers;i++){
!         if (MethodDeclared(cl->supers[i],m))
! 	    return find_classclass(cl->supers[i]);
      }
  }
  
! static Object GetReflectField(Class cl,
! 			    struct vt_generic *v, 
! 			    int slot)
  {
-     int x;
      struct in_java_lang_reflect_Field *fld;
  
      fld = new(&cl_java_lang_reflect_Field.C);
      fld->name = arraystring(v->name_chars,v->name_len);
      fld->slot = slot;
!     fld->type = GetClassFromSignature(v->sig_chars,&x);
!     fld->clazz = DeclaringClass_V(cl,v);
  
      return fld;
  }
  
! static Object GetReflectMethod(Class cl,
! 			       struct mt_generic *m, 
! 			       int slot)
  {
-     int x;
      struct in_java_lang_reflect_Method *mthd;
  
      mthd = new(&cl_java_lang_reflect_Method.C);
      mthd->name = arraystring(m->name_chars,m->name_len);
      mthd->slot = slot;
!     mthd->clazz = DeclaringClass_M(cl,m);
      mthd->returnType = GetRetTypeFromSig(m->sig_chars,m->sig_len);
      mthd->parameterTypes = GetArgTypesFromSig(m->sig_chars,m->sig_len);
!     mthd->exceptionTypes = GetExceptionTypes(cl,m);
  
      return mthd;
  }
  
- static int isConstructor(struct mt_generic *mt)
- {
-     if (!SameAsJavaStr(mt->name_chars,mt->name_len,javastring("<init>")))
-         return 0;
-     if (mt->sig_chars[mt->sig_len-1]!='V' || mt->sig_chars[mt->sig_len-2]!=')')
-         return 0;
-     return 1;
- }
- 
- static int CountPublicFields(struct vt_generic *vars,int nvars,int declared)
- {
-     int i;
-     int cnt;
  
!     for (i=0,cnt=0;i<nvars;i++){
!         if (vars[i].access & ACC_PUBLIC){
! 	    if (vars[i].localp || !declared)
! 	        cnt++;
! 	}
!     }
!     return cnt;
! }
! static int CountPublicMethods(Class cl,struct mt_generic *mthds,int nmthds,int declared,int constr)
  {
!     int i,j;
!     int cnt;
!     int isConstr;
! 
!     for (i=0,cnt=0;i<nmthds;i++){
!         if (mthds[i].access & ACC_PUBLIC){
! 	    isConstr = isConstructor(mthds+i);
! 	    if (constr && !isConstr || !constr && isConstr)
! 	        continue;
! 	    if (constr && !mthds[i].localp)
! 	        continue;
! 
! 	    /* exclude java.lang.Object methods from interface methods */
! 	    if ((cl->flags & IS_INTERFACE) && !mthds[i].localp){
! 	        for (j=1;j<cl->nsupers;j++){
! 		    if (MethodDeclared(cl->supers[j],mthds+i))
! 		        break;
! 		}
! 		if (!(cl->supers[j]->flags & IS_INTERFACE))
! 		    continue;
! 	    }
! 
! 	    if (mthds[i].localp || !declared){
! 	        cnt++;
! 	    }
! 	}
!     }
!     return cnt;
! }
! 
! /* Fill in the array of java.lang.reflect.Field objects */
! static int FillPublicFields(Class cl,
! 			    struct in_java_lang_reflect_Field **pfld,
! 			    struct vt_generic *vars,
! 			    int nvars,
! 			    int declared)
! {
!     int i,j,cnt;
!     int x;
! 
!     for (i=0,cnt=0;i<nvars;i++){
!         if (vars[i].access & ACC_PUBLIC){
! 	    if (declared && !vars[i].localp)
! 	        continue;
! 	    *pfld = GetReflectField(cl,vars+i,i);
! 	    pfld++;
! 	    cnt++;
! 	}
!     }
!     return cnt;
! }
! 
! /* Fill in the array of java.lang.reflect.Method
!  *                   or java.lang.reflect.Constructor objects
!  */
! static int FillPublicMethods(Class cl,
! 			     void *p_generic,
! 			     struct mt_generic *mtable,
! 			     int nmthds,
! 			     int declared,
! 			     int constr)
! {
!     int i,j,cnt;
!     int isConstr;
!     struct in_java_lang_reflect_Method **pmthd;
!     struct in_java_lang_reflect_Constructor **pconstr;
! 
!     pmthd = (struct in_java_lang_reflect_Method **)p_generic;
!     pconstr = (struct in_java_lang_reflect_Constructor **)p_generic;
! 
!     for (i=0,cnt=0;i<nmthds;i++){
!         if (mtable[i].access & ACC_PUBLIC){
! 	    isConstr = isConstructor(mtable+i);
! 	    if (constr && !isConstr || !constr && isConstr)
! 	        continue;
! 	    if (constr && !mtable[i].localp)
! 	        continue;
! 	    if (declared && !mtable[i].localp)
! 	        continue;
! 	    
! 	    /* exclude java.lang.Object methods from interface methods */
! 	    if ((cl->flags & IS_INTERFACE) && !mtable[i].localp){
! 	        for (j=1;j<cl->nsupers;j++){
! 		    if (MethodDeclared(cl->supers[j],mtable+i))
! 		        break;
! 		}
! 		if (!(cl->supers[j]->flags & IS_INTERFACE))
! 		    continue;
! 	    }
! 
! 	    if (constr){
! 	        *pconstr = new(&cl_java_lang_reflect_Constructor.C);
! 		(*pconstr)->slot = i;
! 		(*pconstr)->clazz = find_classclass(cl);
! 		(*pconstr)->parameterTypes = GetArgTypesFromSig(mtable[i].sig_chars,
! 								mtable[i].sig_len);
! 		(*pconstr)->exceptionTypes = GetExceptionTypes(cl,mtable+i);
! 		pconstr++;
! 		cnt++;
! 	    }
! 	    else{
! 	        *pmthd = GetReflectMethod(cl,mtable+i,i);
! 		pmthd++;
! 		cnt++;
! 	    }
! 	}
      }
!     return cnt;
  }
  
! Object	getFields0_i_hY6Lk(Object Harg1, Int arg2) /* Since JDK1.1 */
! {
!     struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     Class  cl,supercl;
!     Object flds;
!     int    i,cnt;
!     struct in_java_lang_reflect_Field **pfld;
! 
!     cl = find_class(this);
! 
!     cnt = 0;
!     if (!(cl->flags & IS_ARRAY) && !(cl->flags & IS_PRIMITIVE)){
!         for (i=0;i<cl->nsupers;i++)
! 	    cnt += CountPublicFields(cl->supers[i]->cvars,cl->supers[i]->ncvars,arg2);
! 	cnt += CountPublicFields(cl->ivars,cl->nivars,arg2);
      }
  
!     flds = anewarray(&cl_java_lang_reflect_Field.C,cnt);
!     if (!cnt)
!         return flds;
! 
!     pfld = (struct in_java_lang_reflect_Field**)(((struct aarray*)flds)->data);
!     for (i=0;i<cl->nsupers;i++){
!         supercl = cl->supers[i];
!         cnt = FillPublicFields(supercl,pfld,supercl->cvars,supercl->ncvars,arg2);
! 	pfld += cnt;
      }
-     FillPublicFields(cl,pfld,cl->ivars,cl->nivars,arg2);
-     return flds;
- }
- 
- Object	getMethods0_i_XYCWL(Object Harg1, Int arg2) /* Since JDK1.1 */
- {
-     struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
-     Class  cl,supercl;
-     Object mthds;
-     int    i,cnt;
-     struct in_java_lang_reflect_Method **pmthd;
  
      cl = find_class(this);
  
!     for (i=0,cnt=0;i<cl->nsupers;i++){
!         cnt += CountPublicMethods(cl,cl->supers[i]->smethods,cl->supers[i]->nsmethods,arg2,0);
      }
-     cnt += CountPublicMethods(cl,((struct cl_generic *)cl)->M,cl->nimethods,arg2,0);
- 
-     mthds = anewarray(&cl_java_lang_reflect_Method.C,cnt);
-     if (!cnt)
-         return mthds;
  
-     pmthd = (struct in_java_lang_reflect_Method **)(((struct aarray*)mthds)->data);
-     for (i=0;i<cl->nsupers;i++){
-         supercl = cl->supers[i];
-         cnt = FillPublicMethods(supercl,pmthd,supercl->smethods,supercl->nsmethods,arg2,0);
- 	pmthd += cnt;
-     }
-     FillPublicMethods(cl,pmthd,((struct cl_generic *)cl)->M,cl->nimethods,arg2,0);
      return mthds;
  }
  
! Object	getConstructors0_i_L3cNN(Object Harg1, Int arg2) /* Since JDK1.1 */
! {
!     struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     Class  cl,supercl;
!     Object mthds;
!     int    i,cnt;
!     struct in_java_lang_reflect_Constructor **pcons;
  
      cl = find_class(this);
  
!     cnt = CountPublicMethods(cl,((struct cl_generic *)cl)->M,cl->nimethods,arg2,1);
! 
!     mthds = anewarray(&cl_java_lang_reflect_Constructor.C,cnt);
!     if (!cnt)
!         return mthds;
! 
!     pcons = (struct in_java_lang_reflect_Constructor **)(((struct aarray*)mthds)->data);
!     FillPublicMethods(cl,pcons,((struct cl_generic *)cl)->M,cl->nimethods,arg2,1);
!     return mthds;
! }
! 
! Object	getField0_Si_JLURr(Object Harg1, Object Harg2, Int arg3) /* Since JDK1.1 */
! {
!     struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     struct in_java_lang_String *fldname = (struct in_java_lang_String*)Harg2;
!     struct vt_generic *vars;
!     Class  cl;
!     int    i,j,nvars;
! 
!     cl = find_class(this);
!     nvars = cl->nivars;
!     vars  = cl->ivars;
!     for (j=0;j<nvars;j++){
!         if (SameAsJavaStr(vars[j].name_chars,vars[j].name_len,fldname)){
! 	    return GetReflectField(cl,vars+j,j);
! 	}
!     }
!     for (i=0;i<cl->nsupers;i++){
!         nvars = cl->supers[i]->ncvars;
! 	vars  = cl->supers[i]->cvars;
!         for (j=0;j<nvars;j++){
! 	    if (SameAsJavaStr(vars[j].name_chars,vars[j].name_len,fldname)){
! 	        return GetReflectField(cl,vars+j,j);
! 	    }
! 	}
!     }
!     throwMesg(&cl_java_lang_NoSuchFieldException.C,"getField0");
      return 0;
  }
  
! Object	getMethod0_SaCi_XmrLc(Object Harg1,Object Harg2,Object Harg3,Int arg4) /* Since JDK1.1 */
  {
      struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     struct in_java_lang_String *name = (struct in_java_lang_String *)Harg2;
!     struct mt_generic *mtable;
!     Class  cl;
!     Char   sig[1024];
!     int    i,j,num,siglen,namelen;
!     int    nsupers;
  
      cl = find_class(this);
  
!     siglen = GetSigFromArgTypes(Harg3,sig);
!     namelen = name->count;
! 
!     if (arg4){
!       /* If arg4==1 then only find declared method */
!         nsupers = 1;
      }
!     else{
!         nsupers = cl->nsupers;
      }
  
!     num = cl->nimethods;
!     mtable = ((struct cl_generic *)cl)->M;
!     for (j=0;j<num;j++){
!         if (SameAsJavaStr(mtable[j].name_chars,mtable[j].name_len,name) &&
! 	    memcmp(sig,mtable[j].sig_chars,siglen*sizeof(Char))==0 ){
! 	    return GetReflectMethod(cl,mtable+j,j);
! 	}
!     }
!     for (i=0;i<cl->nsupers;i++){
!         num = cl->supers[i]->nsmethods;
! 	mtable  = cl->supers[i]->smethods;
!         for (j=0;j<num;j++){
! 	    if (SameAsJavaStr(mtable[j].name_chars,mtable[j].name_len,name) &&
! 		memcmp(sig,mtable[j].sig_chars,siglen*sizeof(Char))==0 ){
! 	        return GetReflectMethod(cl,mtable+j,j);
! 	    }
! 	}
!     }
!     throwMesg(&cl_java_lang_NoSuchMethodException.C,cstring(Harg2));
      return 0;
  }
  
! Object	getConstructor0_aCi_zfjjL(Object Harg1, Object Harg2, Int arg3) /* Since JDK1.1 */
  {
      struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     struct in_java_lang_reflect_Constructor *constr;
!     struct mt_generic *mtable;
!     Class  cl;
!     Char   sig[1024];
!     int    i,j,num,siglen,namelen;
!     int    nsupers;
!     struct in_java_lang_String *name;
! 
!     cl = find_class(this);
!     constr = new(&cl_java_lang_reflect_Constructor.C);
! 
!     siglen = GetSigFromArgTypes(Harg2,sig);
!     name = javastring("<init>");
!     namelen = 6;
! 
!     if (arg3){
!       /* If arg3==1 then only find declared method */
!         nsupers = 1;
!     }
!     else{
!         nsupers = cl->nsupers;
!     }
! 
!     for (i=0;i<cl->nsupers;i++){
!         num = cl->supers[i]->nimethods;
! 	mtable = ((struct cl_generic *)cl->supers[i])->M;
!         for (j=0;j<num;j++){
! 	    if (SameAsJavaStr(mtable[j].name_chars,mtable[j].name_len,name) &&
! 		memcmp(sig,mtable[j].sig_chars,siglen*sizeof(Char))==0){
! 	        constr->slot = j;
! 		constr->clazz = find_classclass(cl->supers[i]);
! 		constr->parameterTypes = GetArgTypesFromSig(mtable[j].sig_chars,mtable[j].sig_len);
! 		constr->exceptionTypes = GetExceptionTypes(cl->supers[i],mtable+j);
! 		return constr;
! 	    }
! 	}
      }
-     throwMesg(&cl_java_lang_NoSuchMethodException.C,"getConstructor0");
-     return 0;
- }
  
  
--- 319,1653 ----
  {
      return anewarray(&cl_java_lang_Object.C,0);
  }
+ 
  Void	setSigners_aO_la6GY(Object Harg1, Object Harg2) /* Unimplemented JDK1.1 */
  {
+     /* shouldn't we beef about this? */
  }
  
  extern struct class cl_void;
! static PrimClassTriple
! primTriples [] = { 
!     {"int",     'I', &cl_int,     &cl_java_lang_Integer.C,   sizeof(Int),     offsetof(struct in_java_lang_Integer, value)},
!     {"boolean", 'Z', &cl_boolean, &cl_java_lang_Boolean.C,   sizeof(Boolean), offsetof(struct in_java_lang_Boolean, value)},
!     {"byte",    'B', &cl_byte,    &cl_java_lang_Byte.C,      sizeof(Byte),    offsetof(struct in_java_lang_Byte, value)},
!     {"short",   'S', &cl_short,   &cl_java_lang_Short.C,     sizeof(Short),   offsetof(struct in_java_lang_Short, value)},
!     {"char",    'C', &cl_char,    &cl_java_lang_Character.C, sizeof(Char),    offsetof(struct in_java_lang_Character, value)},
!     {"long",    'J', &cl_long,    &cl_java_lang_Long.C,      sizeof(Long),    offsetof(struct in_java_lang_Long, value)},
!     {"float",   'F', &cl_float,   &cl_java_lang_Float.C,     sizeof(Float),   offsetof(struct in_java_lang_Float, value)},
!     {"double",  'D', &cl_double,  &cl_java_lang_Double.C,    sizeof(Double),  offsetof(struct in_java_lang_Double, value)},
!     {"void",    'V', &cl_void,    &cl_java_lang_Void.C,      0,               0}
! };
! static const int nPrimTriples = sizeof (primTriples) / sizeof (*primTriples);
! 
! /* Look up class information given a pointer to the internal structure
!  * for the primitive class; e.g. &cl_boolean.  Returns NULL if the
!  * provided class isn't primitive. */
! PrimClassTriple *
! getPCTbyPrimClass (Class primcl)
  {
!     int i;
!     for (i = 0; i < nPrimTriples; i++) {
!         if (primTriples[i].primClass == primcl) {
! 	    return primTriples + i;
!         }
!     }
!     return NULL;
! }
  
! /* Look up class information given a pointer to the internal structure
!  * for the object class; e.g. java.lang.Boolean.  Returns NULL if the
!  * provided class doesn't have a primitive analogue. */
! PrimClassTriple *
! getPCTbyObjClass (Class objcl)
! {
!     int i;
!     for (i = 0; i < nPrimTriples; i++) {
!         if (primTriples[i].objClass == objcl) {
! 	    return primTriples + i;
!         }
!     }
!     return NULL;
! }
  
! /* Look up class information given the java language level name of
!  * the type; e.g., boolean.  Returns NULL if the name doesn't
!  * name a primitive type. */
! PrimClassTriple *
! getPCTbyName (char *name)
! {
!     int i;
!     for (i = 0; i < nPrimTriples; i++) {
!         if (0 == strcmp(primTriples[i].name,name)) {
! 	    return primTriples + i;
!         }
!     }
!     return NULL;
  }
  
! /* Look up class information given the character by which the type is
!  * represented in signatures; e.g. 'Z'.  Returns NULL if the provided char
!  * doesn't represent a primitive type. */
! PrimClassTriple *
! getPCTbySigChar (int sch)
  {
!     int i;
!     for (i = 0; i < nPrimTriples; i++) {
!         if (primTriples[i].sigChar == sch) {
! 	    return primTriples + i;
!         }
!     }
!     return NULL;
! }
! 
! /* Given: a generic pointer to a primitive value and the Class
!  * corresponding to the (primitive or wrapper) type of that value, create a
!  * new instance of the corresponding wrapper class and copy the value into
!  * it.  Returns NULL iff the provided class has no primitive
!  * correspondent. */
! Object
! wrapPrimObject (Class primClass, /* Class denoting value; e.g. &cl_int */
!                 void * vaddr)
! {
!     PrimClassTriple * wpct;     /* Information on destination type */
!     Object rv;                  /* Value we're returning */
! 
!     /* Gotta have a source value address, the source class, and an
!      * object into which we can store the value. */
!     assert (NULL != vaddr);
!     assert (NULL != primClass);
!     assert (IS_PRIMITIVE & primClass->flags);
! 
!     wpct = getPCTbyPrimClass (primClass);
! 
!     /* Get the translation information corresponding to the target class. */
!     assert (NULL != wpct);
! 
!     /* Allocate a new object of the appropriate class. */
!     rv = new (PCT_objClass (wpct));
!     assert (NULL != rv);
! 
!     /* Make sure the primitive class type has data (isn't void), and
!      * figure out where in it the primitive value is stored. */
!     assert (0 < PCT_primSize (wpct));
!     memcpy (PCT_objPrimValAddr (wpct, rv), vaddr, PCT_primSize (wpct));
! 
!     return rv;
! }
! 
! /* Given types and pointers-to-values for source and destination, assign the
!  * source to the destination through any widening conversion that is necessary.
!  * The types must name primitive classes, not the corresponding wrapped classes.
!  * Iff either type is not a primitive type, or there is no valid widening
!  * conversion from the source to destination type, the function returns 0. */
! int
! widenConvert (Class stype,      /* Source type */
!               void * svp,       /* Pointer to primitive value in source type */
!               Class dtype,      /* Destination type */
!               void * dvp)       /* Pointer to storage for primitive value in destination type */
! {
!     AnyJavaValue * sval;
!     AnyJavaValue * dval;
!     Boolean badconv;
  
!     if (! ((IS_PRIMITIVE & dtype->flags) &&
!            (IS_PRIMITIVE & stype->flags))) {
!         return 0;
      }
+ 
+     sval = (AnyJavaValue *) svp;
+     dval = (AnyJavaValue *) dvp;
+ 
+     if (stype == dtype) {
+         PrimClassTriple * pct;
+ 
+         /* Can't just assign over; one or the other of the values
+          * pointed to might not be the size of an AnyJavaValue.  Look
+          * up the type, and copy over only what's necessary. */
+         pct = getPCTbyPrimClass (stype);
+         assert (NULL != pct);
+         memcpy (dval, sval, PCT_primSize (pct));
+         return 1;
+     }
+ 
+ /* Macro sees whether the desired destination type is _ptype; if it is,
+  * extracts the _sfld field from the source value and casts it through
+  * _jtype to store into _dfld field of the destination value. */
+ #define CheckAndAssign(_ptype,_jtype,_sfld,_dfld) \
+     if (&cl_##_ptype == dtype) { \
+         dval->_dfld = (_jtype) sval->_sfld; \
+     } \
+ 
+     /* Gotta do a widening conversion.  What's allowed is defined by JLS
+      * section 5.1.2. */
+     badconv = JAVA_FALSE;
+     if (&cl_byte == stype) {
+         CheckAndAssign(short,Short,B,S)
+         else CheckAndAssign(int,Int,B,I)
+         else CheckAndAssign(long,Long,B,J)
+         else CheckAndAssign(float,Float,B,F)
+         else CheckAndAssign(double,Double,B,D)
+         else {
+             badconv = JAVA_TRUE;
+         }
+     } else if (&cl_short == stype) {
+         CheckAndAssign(int,Int,S,I)
+         else CheckAndAssign(long,Long,S,J)
+         else CheckAndAssign(float,Float,S,F)
+         else CheckAndAssign(double,Double,S,D)
+         else {
+             badconv = JAVA_TRUE;
+         }
+     } else if (&cl_char == stype) {
+         CheckAndAssign(int,Int,C,I)
+         else CheckAndAssign(long,Long,C,J)
+         else CheckAndAssign(float,Float,C,F)
+         else CheckAndAssign(double,Double,C,D)
+         else {
+             badconv = JAVA_TRUE;
+         }
+     } else if (&cl_int == stype) {
+         CheckAndAssign(long,Long,I,J)
+         else CheckAndAssign(float,Float,I,F)
+         else CheckAndAssign(double,Double,I,D)
+         else {
+             badconv = JAVA_TRUE;
+         }
+     } else if (&cl_long == stype) {
+         CheckAndAssign(float,Float,J,F)
+         else CheckAndAssign(double,Double,J,D)
+         else {
+             badconv = JAVA_TRUE;
+         }
+     } else if (&cl_float == stype) {
+         CheckAndAssign(double,Double,F,D)
+         else {
+             badconv = JAVA_TRUE;
+         }
+     } else {
+         badconv = JAVA_TRUE;
+     }
+ #undef CheckAndAssign
+ 
+     return (! badconv);
  }
  
! Object
! getPrimitiveClass_S_JFLGD (Object Harg1) /* Since JDK1.1 */
  {
!     char *name;                 /* Name of the class in C format */
!     PrimClassTriple * pct;
! 
!     init_java_lang_Class();
!     name = cstring(Harg1);
!     pct = getPCTbyName (name);
!     if (NULL != pct) {
!         return PCT_primClassClass(pct);
!     }
!     throwClassNotFoundException(name);
!     /*NOTREACHED*/
! }
! 
! /* Parse signature and return a java Class object */
! static Object
! GetClassFromSignature (const Char * sig,
!                        int * cnt)
! {
!     if (NULL != cnt) {
!         *cnt = 1;
!     }
!     switch (toupper(*sig)) {
!         case 'B':
!             return &cl_byte.classclass;
!         case 'C':
!             return &cl_char.classclass;
!         case 'D':
!             return &cl_double.classclass;
!         case 'F':
!             return &cl_float.classclass;
!         case 'I':
!             return &cl_int.classclass;
!         case 'J':
!             return &cl_long.classclass;
!         case 'S':
!             return &cl_short.classclass;
!         case 'V':
!             return &cl_void.classclass;
!         case 'Z':
!             return &cl_boolean.classclass;
!         case 'L': {
!             Char buf[1024];
!             int i;
! 
!             /* NB: We're working on 16bit chars here, so can't use
!              * standard str* routines.  We're assuming the signature
!              * is properly formatted (has a ';'), and isn't too
!              * long. */
!             ++sig;
!             i = 0;
!             /* Copy over all characters up to the terminating semicolon,
!              * translating slashes into dots */
!             while ((';' != *sig) &&
!                    (i < (sizeof (buf) - 1))) {
!                 buf [i] = *(sig++);
!                 if ('/' == buf [i]) {
!                     buf [i] = '.';
!                 }
!                 ++i;
!             }
!             buf [i] = 0;
!             if (NULL != cnt) {
!                 /* 'L' + name + ';' */
!                 *cnt = 1 + i + 1;
!             }
!             return forName_S_UuOsX(arraystring(buf,i));
!         }
!         case '[': {
!             int arank;          /* Rank (depth) of the array */
!             Object clcl;        /* jl.Class object corresponding to base element */
!             Class cl;           /* Class structure corresponding to array or element */
! 
!             /* Determine the rank of the array by counting the left
!              * brackets. */
!             arank = 1;
!             while ('[' == *++sig) {
!                 ++arank;
!             }
! 
!             /* We've reached the base element.  Figure out what it is,
!              * including its length.  Then add to the length what
!              * we already consumed computing the array rank. */
!             clcl = GetClassFromSignature(sig, cnt);
!             if (NULL != cnt) {
!                 *cnt += arank;
!             }
! 
!             /* Now we need to back up arank levels of array on top
!              * of the base element.  We do all this in the C class
!              * structures, since it's easier. */
!             cl = find_class(clcl);
!             while (0 <= --arank) {
!                 if (cl->arrayclass) {
!                     /* Already have a class for arrays of these; use it. */
!                     cl = cl->arrayclass;
!                 } else {
!                     /* Don't have an array of these yet; build one. */
!                     cl = arrayclassof (cl);
!                 }
!             }
! 
!             /* Return the jl.Class object corresponding to the final
!              * array class. */
!             return find_classclass (cl);
!         }
!     }
!     /*NOTREACHED*/
! }
! 
! /* Given a java.lang.Class object, append to the buffer the sequence of
!  * Java characters which represent it in signatures.  The object must
!  * either a primitive or a base object, not an array.  Returns the number
!  * of chars added to the buffer. */
! static int
! buildSigFromClass (Object clcl, /* Class for signature */
!                    Char * buf)  /* Where to start storing signature chars */
! {
!     Class cl;                   /* C class data */
!     struct in_java_lang_String * cln; /* Name of class */
!     Char *p;                    /* Pointer into class name */
!     int cnt;                    /* Number of characters added to buffer */
!     int len;                    /* Number of chars remaining in name */
  
      cl = find_class((struct in_java_lang_Class*)clcl);
!     cln = (struct in_java_lang_String *) cl->name;
!     p = cln->offset + ((struct carray*) cln->value)->data;
!     len = cln->count;
!     if (cl->flags & IS_PRIMITIVE) {
          *buf = toupper(*p);
! 	if ('l' == *p) {
!             /* long is J not L */
  	    *buf = 'J';
!         } else if (('b' == p[0]) && ('o' == p[1])) {
!             /* boolean is Z not B */
  	    *buf = 'Z';
+         }
  	cnt = 1;
!     } else {
!         int i;                  /* Index over name length */
!         
!         /* Apparently someone thinks we'll never see an array class here.
!          * Are they right?  As this function is used right now, they are,
!          * but in case somebody wants to reuse it elsewhere, we really ought
!          * to check. */
!         assert (! (IS_ARRAY & cl->flags));
! 
!         /* Insert the name (with dots converted to slashes) between an L
!          * and a semicolon. */
!         *(buf++) = 'L';
!         i = 0;
!         while (i < len) {
!             *buf = *(p++);
!             if ('.' == *buf) {
!                 *buf = '/';
!             }
!             ++buf;
!             ++i;
!         }
  	*buf = ';';
!         /* 'L' + name + ';' */
!         cnt = 1 + i + 1;
      }
      return cnt;
  }
  
! /* Construct the (partial) signature from an array of java.lang.Class objects. */
! static int
! buildSigFromArgTypes (Object args, /* Class [] object */
!                       Char * buf) /* Where to store partial signature */
! {
!     int i;                      /* Index over arguments */
!     Char * obuf;                /* Start of stored signature */
!     struct aarray *a;           /* C structure of jlC array */
!     struct in_java_lang_Class **clcls; /* Pointer to sequence of jlC objects */
!     struct in_java_lang_Class *elem; /* Pointer to current argument class */
! 
!     /* Record where we started, so we can compute how many chars
!      * we added. */
!     obuf = buf;
  
+     /* Start with the opening parenthesis. */
      *buf++ = '(';
!     
!     /* For each class in the array of classes, append any required array
!      * prefixes, and the signature for the base element. */
!     a = (struct aarray*)args;
!     clcls = (struct in_java_lang_Class**)a->data;
      for (i=0; i<a->length; i++){
  
!         /* Get the parameter class.  If it's an array, append the
!          * appropriate number of array markers. */
!         elem = clcls [i];
!         while (isArray__yE28G (elem)) {
! 	    *buf++ = '[';
!             elem = getComponentType__hwyYb(elem);
!         }
  
!         /* Append the signature for the base type. */
!         buf += buildSigFromClass(elem,buf);
      }
  
!     /* Tack on the closing parenthesis. */
!     *buf++ = ')';
! 
!     /* Return the number of chars appended. */
!     return (buf - obuf);
  }
  
! /* Return the java Class object corresponding to the return type of a method
!  * with the provided signature. */
! static Object
! GetRetTypeFromSig (const Char *sig, /* Signature of a method */
!                    int sig_len) /* Length of the signature */
  {
!     int  i;                     /* Index into signature */
  
!     /* Scan backwards for the parenthesis that marks the end of the
!      * parameter list. */
!     i = sig_len;
!     while ((0 <= i) &&
!            (')' != sig [i])) {
!         --i;
      }
  
!     /* If we didn't find a close paren, something went very badly wrong. */
!     if (0 > i) {
!         return 0;
      }
! 
!     return GetClassFromSignature(sig+i+1, NULL);
  }
  
! /* Build an array of java.lang.Class objects corresponding to the
!  * parameter types described by the provided signature. */
! static Object
! GetArgTypesFromSig (const Char *sig, /* Parenthesized partial signature  */
!                     int sig_len) /* Length of signature */
! {
!     struct aarray *args;        /* Array of jlC objects */
!     int na;                     /* Number of arguments in signature */
!     const Char *p;              /* Pointer into signature */
! 
!     assert ('(' == *sig);
! 
!     /* First, parse the argument list to the extent that we can count
!      * the number of args. */
!     p = sig + 1;
!     na = 0;
!     while (')' != *p) {
!         if ('L' == *p) {
!             /* Object type: increment the argument count, and skip
!              * over the thing. */
!             ++na;
!             while (';' != *++p) {
!                 /* skipping to end of Object param */
!             }
!             /* skip over the trailing semicolon too */
!             ++p;
!         } else if ('[' == *p) {
!             /* Skip over array markers; we account for the argument
!              * when we hit the base type. */
!             while ('[' == *++p) {
!                 /* skipping to end of brackets */
!             }
!         } else {
!             /* Ought to be a primitive type; skip over it, and
!              * increment the argument count */
!             ++p;
!             ++na;
!         }
      }
+     
+     /* Allocate an array of jlC objects to hold the parameter types. */
+     args = anewarray(&cl_java_lang_Class.C, na);
  
!     /* Rewalk the signature storing the actual argument type classes. */
!     na = 0;
!     p = sig + 1;
!     while (')' != *p) {
!         int plen;
!         
!         args->data [na++] = GetClassFromSignature(p, &plen);
! 	p += plen;
!         /* Let's just be sure that the signature parsing ends up
!          * counting the same number of arguments as we did above. */
!         assert (na <= args->length);
      }
  
!     assert (na == args->length);
!     return args;
  }
  
! #define FieldMatchNameSig(_f1,_f2) ( \
!     ((_f1)->name_len == (_f2)->name_len) && \
!     ((_f1)->sig_len == (_f2)->sig_len) && \
!     (0 == memcmp ((_f1)->name_chars, (_f2)->name_chars, (_f2)->name_len * sizeof (*(_f2)->name_chars))) && \
!     (0 == memcmp ((_f1)->sig_chars, (_f2)->sig_chars, (_f2)->sig_len * sizeof (*(_f2)->sig_chars))) \
!     )
! 
! /* Find the last method in the table of the given length that matches
!  * the provided method in name and signature.  If needLocal is true,
!  * we further require that a match have the localp flag set.  Returns
!  * a pointer to the match, or NULL if there is none. */
! struct mt_generic *
! findMethodInTable (struct mt_generic * m, /* Method we're trying to match */
!                    struct mt_generic * mtable, /* Array of method structures to compare with */
!                    int nmtb,    /* Number of entries in mtable */
!                    int needLocal) /* Do we insist that the match have localp set? */
! {
!     struct mt_generic * pm;
! 
!     /* Walk the table from top down, looking for a name+sig match */
!     pm = mtable + nmtb;
!     while (0 <= --nmtb) {
!         --pm;
!         if (FieldMatchNameSig(pm,m)) {
!             /* Found an entry that matches in name and signature.  If we
!              * don't care about it being local, or it is local, return it.
!              * If we need a local one and this one isn't local, then
!              * treat this as failure to find a match.  We should _not_
!              * be able to find a method in this table that is local _and_
!              * has been overloaded in this class by a non-local method. */
!             if (pm->localp || (! needLocal)) {
!                 return pm;
!             }
!             return NULL;
!         }
!     }
!     return NULL;
! }
! 
! /* Scan through the provided method table, looking for a method that has
!  * the same name and signature as that provided.  The signature need
!  * match only the parameter portion, not the return value. */
! static struct mt_generic *
! findNamedMethodInTable (struct in_java_lang_String * name, /* Name of method */
!                         Char * sig_chars, /* Parameter portion of signature */
!                         int sig_len, /* Length of partial signature */
!                         struct mt_generic * mtable, /* Sequence of method structures */
!                         int nmtb) /* Number of method structures in table */
! {
!     struct mt_generic * pm;     /* Potential method match */
!     const Char * name_chars;    /* Java char data for name */
!     int name_len;               /* Length of name */
!     
!     /* Get the character data and length of the provided name. */
!     name_chars = name->offset + ((struct carray *)name->value)->data;
!     name_len = name->count;
! 
!     /* Walk the table from top down, looking for a name+sig match.
!      * Note that we only compare the first sig_len chars of the signature,
!      * since we are not checking against the return type.  The partial
!      * signature should start and end with parentheses to avoid
!      * any improper prefix matching. */
!     pm = mtable + nmtb;
!     while (0 <= --nmtb) {
!         --pm;
!         if ((pm->name_len == name_len) &&
!             (pm->sig_len > sig_len) &&
!             (0 == memcmp (pm->name_chars, name_chars, name_len * sizeof (*name_chars))) &&
!             (0 == memcmp (pm->sig_chars, sig_chars, sig_len * sizeof (*sig_chars)))) {
! 
!             /* The entry matches in name and signature; return it. */
!             return pm;
!         }
!     }
! 
!     /* No match: return null */
!     return NULL;
! }
!                      
! 
! /* Scan through the provided field table, looking for a field that has
!  * the same name as that provided.  */
! static struct vt_generic *
! findNamedFieldInTable (struct in_java_lang_String * name, /* Name of field */
!                        struct vt_generic * ftable, /* Sequence of field structures */
!                        int nftb) /* Number of field structures in table */
! {
!     struct vt_generic * pf;     /* Potential field match */
!     const Char * name_chars;    /* Java char data for name */
!     int name_len;               /* Length of name */
!     
!     /* Get the character data and length of the provided name. */
!     name_chars = name->offset + ((struct carray *)name->value)->data;
!     name_len = name->count;
! 
!     /* Walk the table from top down, looking for a name match. */
!     pf = ftable + nftb;
!     while (0 <= --nftb) {
!         --pf;
!         if ((pf->name_len == name_len) &&
!             (0 == memcmp (pf->name_chars, name_chars, name_len * sizeof (*name_chars)))) {
!             /* The entry matches in name; return it. */
!             return pf;
!         }
!     }
  
!     /* No match: return null */
!     return NULL;
  }
+                      
  
  
! /* Return an array of exception classes */
! static Object
! GetExceptionTypes (struct mt_generic *m)
  {
!     struct aarray *ret;         /* Array of class objects representing exceptions */
!     Class * ecl;                /* Pointer into the exception table */
!     int nexc;                   /* Number of exceptions */
! 
!     /* The exception list is null-terminated.  Count the number of exceptions.
!      * Count should be zero if the exception list is undefined (null). */
!     nexc = 0;
!     ecl = m->xlist;
!     while ((NULL != ecl) && (NULL != *(ecl++))) {
!         ++nexc;
!     }
! 
!     /* Allocate an array of class pointers, then store the Class entries
!      * for each exception. */
!     ret = anewarray(&cl_java_lang_Class.C, nexc);
!     while (0 <= --nexc) {
!         ret->data [nexc] = find_classclass (m->xlist [nexc]);
      }
  
!     return ret;
  }
  
! int SameAsJavaStr (const Char *s,int len,Object arg3)
  {
+     struct in_java_lang_String * jstr = (struct in_java_lang_String *) arg3;
+     Char * scp;
      int i;
  
!     if (len != jstr->count) {
!         return 0;
      }
!     scp = jstr->offset + ((struct carray*)jstr->value)->data;
  
!     while (0 <= --len) {
!         if (s [len] != scp [len]) {
!             return 0;
!         }
      }
+ 
+     return 1;
  }
  
! static Object
! buildReflectField(Class cl,
!                   struct vt_generic *v, 
!                   int slot)
  {
      struct in_java_lang_reflect_Field *fld;
  
+     assert (FTS_invalidSlot != slot);
      fld = new(&cl_java_lang_reflect_Field.C);
      fld->name = arraystring(v->name_chars,v->name_len);
      fld->slot = slot;
!     fld->type = GetClassFromSignature(v->sig_chars, NULL);
!     /* The class we store is the one we found the field in, i.e.
!      * the one where it's declared.  We don't dynamically re-resolve
!      * at runtime---doing so would prevent accessing obscured instance
!      * fields. */
!     assert (v->localp);
!     fld->clazz = find_classclass (cl);
  
      return fld;
  }
  
! static Object
! buildReflectMethod (Class cl,   /* Class in which method was found */
!                     struct mt_generic *m, 
!                     int slot)
  {
      struct in_java_lang_reflect_Method *mthd;
  
      mthd = new(&cl_java_lang_reflect_Method.C);
      mthd->name = arraystring(m->name_chars,m->name_len);
+ 
+     assert (FTS_invalidSlot != slot);
      mthd->slot = slot;
! 
!     /* We need to find the class in which the method was actually declared;
!      * that's the one we store here.  It'll only be different if we're
!      * doing an instance method; static methods are only listed in their
!      * declaring class. */
!     if (! m->localp) {
!         assert (! FTS_isStaticSlot (slot));
!         /* As long as we're not local, back up to our superclass and
!          * use the method data defined in the same slot there. */
!         while (! m->localp) {
!             assert (1 < cl->nsupers); /* Gotta have a superclass */
!             cl = cl->supers[1];
!             assert (slot < cl->nimethods); /* Superclass has to have this method */
!             m = slot + ((struct cl_generic *)cl)->M;
!         }
!     }
!     mthd->clazz = find_classclass (cl);
! 
      mthd->returnType = GetRetTypeFromSig(m->sig_chars,m->sig_len);
      mthd->parameterTypes = GetArgTypesFromSig(m->sig_chars,m->sig_len);
!     mthd->exceptionTypes = GetExceptionTypes(m);
  
      return mthd;
  }
  
  
! static Object
! buildReflectConstructor (Class cl,
!                          struct mt_generic *m, 
!                          int slot)
! {
!     struct in_java_lang_reflect_Constructor *cnstr;
! 
!     cnstr = new(&cl_java_lang_reflect_Constructor.C);
!     assert (FTS_invalidSlot != slot);
!     cnstr->slot = slot;
!     /* NB: Constructors are not member functions, therefore they are not
!      * inherited, therefore they are always local. */
!     assert (m->localp);
!     cnstr->clazz = find_classclass (cl);
!     cnstr->parameterTypes = GetArgTypesFromSig(m->sig_chars,m->sig_len);
!     cnstr->exceptionTypes = GetExceptionTypes(m);
! 
!     return cnstr;
! }
! 
! static void
! addToDynArray (Object val,
!                int * nelts,
!                int * maxelts,
!                Object ** arrpp)
  {
!     Object * arrp;
!     
!     arrp = *arrpp;
!     if (*nelts >= *maxelts) {
!         Object * narrp;
! 
!         *maxelts = *nelts + 5 + 2 * *maxelts;
!         narrp = allocate (*maxelts * sizeof (*narrp));
!         if (NULL != arrp) {
!             memcpy (narrp, arrp, *nelts * sizeof (*arrp));
!         }
!         arrp = *arrpp = narrp;
!     }
!     arrp [(*nelts)++] = val;
!     return;
! }
! 
! /* Scan through an array of java reflection objects and return nonzero iff
!  * there is already a reflection object (method, constructor, or field)
!  * that matches (name, name+sig) with the provided data (method or field). */
! static int
! entryIsInReflList (void * co,  /* Candidate mt_generic or vt_generic pointer */
!                    int nrl,    /* Number of elements in reflected array */
!                    Object * rla) /* Sequence of reflection objects */
! {
!     while (0 < nrl--) {
!         struct in_generic * ip; /* Reflection instance */
!         Class cl;               /* Class to which reflected object belongs */
!         int slot;               /* Slot in cl for reflected object */
!         struct mt_generic * rms; /* Method data corresponding to reflected object */
! 
!         /* Grab the reflection instance.  Extract its class and slot
!          * in an appropriate way depending on whether it's a jlr.Method
!          * or a jlr.Constructor. */
!         ip = (struct in_generic *) *(rla++);
! 
!         if ((Class)&cl_java_lang_reflect_Method == ip->class) {
!             struct in_java_lang_reflect_Method * rmp;
! 
!             rmp = (struct in_java_lang_reflect_Method *) ip;
!             cl = find_class (rmp->clazz);
!             slot = rmp->slot;
!         } else {
!             struct in_java_lang_reflect_Constructor * rcp;
! 
!             assert ((Class)&cl_java_lang_reflect_Constructor == ip->class);
!             rcp = (struct in_java_lang_reflect_Constructor *) ip;
!             cl = find_class (rcp->clazz);
!             slot = rcp->slot;
!         }
! 
!         /* Get a pointer to the method named by the reflection object. */
!         if (FTS_isStaticSlot(slot)) {
!             rms = cl->smethods + FTS_extractStaticSlot(slot);
!         } else {
!             rms = ((struct cl_generic*)cl)->M + slot;
!         }
! 
!         /* Succeed if it name/sig matches the key. */
!         if (FieldMatchNameSig ((struct mt_generic *) co, rms)) {
!             return 1;
!         }
      }
!     return 0;
  }
  
! /* Return TRUE iff the sequence of len java characters starting at chars
!  * matches the EOS-terminated sequence of C chars starting at cstr. */
! static Boolean
! jcstrMatch (const Char * jp,    /* Java char sequence */
!             int len,            /* Length of java char sequence */
!             const char * cp)    /* C string to compare */
! {
!     int cslen;                  /* Length of C string */
! 
!     /* Compute the length of the C string.  If the java string isn't the
!      * same length, they don't match. */
!     cslen = strlen (cp);
!     if (cslen != len) {
!         return JAVA_FALSE;
      }
  
!     /* Compare until mismatch or reach end of C string. */
!     while (*cp) {
!         if (*cp != *jp) {
!             return JAVA_FALSE;
!         }
!         ++cp;
!         ++jp;
!     }
!     return JAVA_TRUE;
! }
! 
! /* Return the type code that identifies this method as a constructor, static
!  * initializer, or member method. */
! static MethodCategory
! identifyMethodCategory (struct mt_generic * m) /* Method pointer */
! {
!     if (jcstrMatch (m->name_chars, m->name_len, "<init>")) {
!         return MT_constructor;
!     }
!     if (jcstrMatch (m->name_chars, m->name_len, "<clinit>")) {
!         return MT_staticInitializer;
!     }
!     return MT_memberMethod;
! }
! 
! /* Scan through the method tables to find either the declared methods in this
!  * class, or all public methods visible in this class.  Alternatively, we
!  * do the same thing looking for constructors instead of member methods.
!  * Returns a java array of reflection objects denoting the matched
!  * methods or constructors. */
! static Object
! findReflInMethods (struct in_java_lang_Class * this, /* Class data */
!                    Int wantMode, /* PUBLIC or DECLARED */
!                    Boolean findConstructor) /* Look for constructors instead of methods? */
! {
!     Class  cl;                  /* C class for this */
!     Object mthds;               /* Array of method objects */
!     Object * pmthd;             /* Dynamically-increased array of method objects */
!     int npmthd;                 /* Number of elements in pmthd array */
!     int maxpmthd;               /* Maximum number of elements in current pmthd array */
!     int mpi;                    /* Method table position index */
!     struct mt_generic * mp;     /* Method pointer */
!     /* What function do we use to build a reflection object? */
!     Object (*buildReflObj)(Class cl, struct mt_generic *m, int slot);
!     MethodCategory matchCategory; /* Is *mp a method or a constructor or... */
!     Class scl;                  /* Superclass pointer */
!     int sci;                    /* Index into superclasses */
! 
!     /* If we're to search for PUBLIC methods, we include inherited ones.
!      * Otherwise, we're to search for DECLARED methods, and we only look
!      * within this one class (set super scan limit to one level). */
!     if ((cl_java_lang_reflect_Member.V.PUBLIC != wantMode) &&
!         (cl_java_lang_reflect_Member.V.DECLARED != wantMode)) {
!         /* If this blows, somebody added new functionality to this method. */
!         throwInternalError ("getMethod0: Unmatched declared/public parameter %d", wantMode);
!     }
! 
!     /* Get a pointer to the thing we'll use to build the reflected
!      * object; either a Method or a Constructor. */
!     if (findConstructor) {
!         buildReflObj = buildReflectConstructor;
!         matchCategory = MT_constructor;
!     } else {
!         buildReflObj = buildReflectMethod;
!         matchCategory = MT_memberMethod;
      }
  
+     /* Find the basic class data. */
      cl = find_class(this);
  
!     /* Set up for extending the list of methods; we have no default bound
!      * on its length. */
!     npmthd = maxpmthd = 0;
!     pmthd = NULL;
! 
!     /* We want all public methods, except those that have been overridden
!      * or hidden. */
!     sci = 0;
!     while (sci < cl->nsupers) {
!         scl = cl->supers [sci++];
! 
!         /* If we're looking for declared ones, we stop after the first
!          * class. */
!         if ((cl_java_lang_reflect_Member.V.DECLARED == wantMode) &&
!             (scl != cl)) {
!             break;
!         }
! 
!         /* Empirically, we do not include constructors inherited from
!          * java.lang.Object unless we're querying java.lang.Object. */
!         if (findConstructor &&
!             (scl != cl) &&
!             ((Class)&cl_java_lang_Object == scl)) {
!             continue;
!         }
! 
! /* Restrict to ones that are local if we want DECLARED, and ones that are
!  * public if we want PUBLIC.  Furthermore, must be a constructor/method
!  * as we require.  For instance methods, we'll further require that we
!  * not have already seen a method with this signature; static methods
!  * do allow visibility of methods in parent classes. */
! #define WantMP(_mp) ( \
!     (_mp)->localp && \
!     ((cl_java_lang_reflect_Member.V.DECLARED == wantMode) || \
!      ((cl_java_lang_reflect_Member.V.PUBLIC == wantMode) && (ACC_PUBLIC == (ACC_PUBLIC & (_mp)->access)))) && \
!     (matchCategory == identifyMethodCategory (_mp)) && \
!     ExtraCondition(_mp) \
!     )
! 
! #define AddMethods(_mvl,_mvc) { \
!     int mpi = 0; \
!     struct mt_generic * mp = (_mvl); \
!     while (mpi < (_mvc)) { \
!         if (WantMP(mp)) { \
!             addToDynArray (buildReflObj (scl, mp, ConvertSlot(mpi)), &npmthd, &maxpmthd, &pmthd); \
!         } \
!         ++mp; \
!         ++mpi; \
!     } \
! }
! 
!         /* Don't look for constructors in the static table; there
!          * won't be any.  Do look for methods there. */
!         if (! findConstructor) {
! #define ExtraCondition(_mp) (1)
! #define ConvertSlot(_sl) FTS_buildStaticSlot(_sl)
!             AddMethods(scl->smethods,scl->nsmethods);
! #undef ConvertSlot
! #undef ExtraCondition
!         }
! 
!         /* Now the instance ones. */
! #define ExtraCondition(_mp) (! entryIsInReflList (_mp, npmthd, pmthd))
! #define ConvertSlot(_sl) (_sl)
!         AddMethods(((struct cl_generic *)scl)->M,scl->nimethods);
! #undef ConvertSlot
! #undef ExtraCondition
! 
! #undef WantMP
! #undef AddMethods
!     }
! 
!     /* Allocate an array object with the appropriate base type. */
!     if (findConstructor) {
!         mthds = anewarray(&cl_java_lang_reflect_Constructor.C,npmthd);
!     } else {
!         mthds = anewarray(&cl_java_lang_reflect_Method.C,npmthd);
!     }
! 
!     /* If we collected some objects, copy them over into the array. */
!     if (0 < npmthd) {
!         memcpy (((struct aarray*)mthds)->data, pmthd, npmthd * sizeof (*pmthd));
      }
  
      return mthds;
  }
  
! Object
! getMethods0_i_XYCWL (Object Harg1,
!                      Int wantMode) /* Since JDK1.1 */
! {
!     return findReflInMethods((struct in_java_lang_Class *) Harg1, wantMode, JAVA_FALSE);
! }
! 
! Object
! getConstructors0_i_L3cNN (Object Harg1,
!                           Int wantMode) /* Since JDK1.1 */
! {
!     return findReflInMethods ((struct in_java_lang_Class *) Harg1, wantMode, JAVA_TRUE);
! }
! 
! /* Locate the method/constructor with the given name and a signature
!  * corresponding to the provided parameter array in this class's method
!  * tables.  Can lookup either PUBLIC or DECLARED. */
! static Object
! findTypedReflInMethods (struct in_java_lang_Class * this, /* Java class data */
!                         struct in_java_lang_String * name, /* Name of method */
!                         Object parameterTypeArray, /* Array of parameter types */
!                         Int wantMode, /* PUBLIC or DECLARED */
!                         Boolean findConstructor) /* Want a constructor instead of a method? */
! {
!     Class cl;                   /* C version of class data */
!     Char sig[1024];             /* Where we build the signature from parameterTypeArray */
!     int siglen;                 /* Length of the signature */
!     struct mt_generic * m;      /* Method pointer */
!     /* What function do we use to build a reflecting object? */
!     Object (*buildReflObj)(Class cl, struct mt_generic *m, int slot);
!     int nsc;                    /* Number of superclasses to scan */
!     int sci;                    /* Index into superclasses */
!     Class scl;                  /* Class wherein we found a match */
!     int sl;                     /* Slot number of match in class */
! 
!     /* NB: This implementation relies on an understanding that one cannot
!      * override a static method with an instance method, nor hide an instance
!      * method with a static method.  I.e., if we find a signature match
!      * in either the instance or static table, we need not look in
!      * the other table.  Cf JLS section 8.4.6. */
! 
!     /* If we're to search for PUBLIC methods, we include inherited ones.
!      * Otherwise, we're to search for DECLARED methods, and we only look
!      * within this one class (set super scan limit to one level). */
!     if ((cl_java_lang_reflect_Member.V.PUBLIC != wantMode) &&
!         (cl_java_lang_reflect_Member.V.DECLARED != wantMode)) {
!         /* If this blows, somebody added new functionality to this method. */
!         throwInternalError ("findMethodEntry: Unmatched declared/public parameter %d", wantMode);
!     }
! 
!     if (NULL == name) {
!         /* We're not going to find this thing; don't even try.  Yes,
!          * this method is supposed to throw an NSME instead of an NPE
!          * in this case. */
!         throwMesg(&cl_java_lang_NoSuchMethodException.C,NULL /*cstring(name)*/);
!     }
! 
!     /* Get a pointer to the thing we'll use to build the reflected
!      * object; either a Method or a Constructor. */
!     if (findConstructor) {
!         buildReflObj = buildReflectConstructor;
!     } else {
!         buildReflObj = buildReflectMethod;
!     }
  
+     /* Find the C class data, and build a partial signature based on the
+      * parameters that we're looking for. */
      cl = find_class(this);
+     siglen = buildSigFromArgTypes(parameterTypeArray,sig);
  
!     /* Start by assuming we won't find a match. */
!     m = NULL;
!     
!     if (cl_java_lang_reflect_Member.V.DECLARED == wantMode) {
!         /* Search only within this class. */
!         nsc = 1;
!     } else {
!         nsc = cl->nsupers;
!     }
! 
!     /* We look for a match starting with this class and going up the
!      * superclasses.  We stop as soon as we hit a class that has a
!      * match, regardless of whether the match is public, because you
!      * can't override a public method with a non-public. */
!     for (sci = 0; sci < nsc; sci++) {
!         scl = cl->supers [sci];
! 
!         /* First look in the instance table. */
!         m = findNamedMethodInTable (name, sig, siglen, ((struct cl_generic *)scl)->M, scl->nimethods);
!         if (NULL != m) {
!             /* Compute the slot; this marks that we found a match */
!             sl = m - ((struct cl_generic *)scl)->M;
!         } else {
!             /* Only look in the static table if we're after a member
!              * method, not a constructor. */
!             if (! findConstructor) {
!                 /* No instance match in this class.  Look in the static table. */
!                 m = findNamedMethodInTable (name, sig, siglen, scl->smethods, scl->nsmethods);
!                 if (NULL != m) {
!                     /* Compute the slot; this marks that we found a match. */
!                     sl = FTS_buildStaticSlot (m - scl->smethods);
!                 }
!             }
!         }
!         if (NULL != m) {
!             /* Found something.  We gotta stop, because this is
!              * what we resolve to, but if we want public methods and
!              * this one isn't public, or if we want local methods and this
!              * one isn't local, we consider the search to have failed. */
!             if (((cl_java_lang_reflect_Member.V.PUBLIC == wantMode) &&
!                  (ACC_PUBLIC != (m->access & ACC_PUBLIC))) ||
!                 ((cl_java_lang_reflect_Member.V.DECLARED == wantMode) &&
!                  (! m->localp))) {
!                 m = NULL;
!             }
!             break;
!         }
!     }
! 
!     /* If we have a match, return it */
!     if (NULL != m) {
!         return buildReflObj (scl, m, sl);
!     }
! 
!     /* For compatibility with JDK, we can't put the method name in the
!      * exception. */
!     throwMesg(&cl_java_lang_NoSuchMethodException.C,NULL /*cstring(name)*/);
      return 0;
  }
  
! Object
! getMethod0_SaCi_XmrLc (Object Harg1,
!                        Object Harg2,
!                        Object parameterTypeArray,
!                        Int wantMode) /* Since JDK1.1 */
! {
!     return findTypedReflInMethods ((struct in_java_lang_Class *) Harg1,
!                                    (struct in_java_lang_String *) Harg2,
!                                    parameterTypeArray, wantMode, JAVA_FALSE);
! }
! 
! Object
! getConstructor0_aCi_zfjjL (Object Harg1,
!                            Object parameterTypeArray,
!                            Int wantMode) /* Since JDK1.1 */
! {
!     return findTypedReflInMethods ((struct in_java_lang_Class *) Harg1,
!                                    javastring ("<init>"),
!                                    parameterTypeArray, wantMode, JAVA_TRUE);
! }
! 
! /* Locate the field with the given name in this class's field
!  * tables.  Can lookup either PUBLIC or DECLARED. */
! Object
! getField0_Si_JLURr (Object Harg1, /* Java class data */
!                     Object Harg2, /* Name of method */
!                     Int wantMode) /* PUBLIC or DECLARED */
  {
      struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     struct in_java_lang_String *name = (struct in_java_lang_String*)Harg2;
!     Class cl;                   /* C version of class data */
!     struct vt_generic * f;      /* Field pointer */
!     Class scl;                  /* Class wherein we found a match */
!     int sci;
!     int sl;                     /* Slot number of match in class */
! 
!     /* NB: This implementation relies on an acceptance that one CAN
!      * override a static field with an instance field, or hide an instance
!      * field with a static field.  I.e., if we find a signature match
!      * in either the instance or static table, we need to look in
!      * the other table if there's a chance there's an overriding
!      * declaration there.  Cf JLS section 8.3. */
! 
!     /* If we're to search for PUBLIC fields, we include inherited ones.
!      * Otherwise, we're to search for DECLARED fields, and we only look
!      * within this one class. */
!     if ((cl_java_lang_reflect_Member.V.PUBLIC != wantMode) &&
!         (cl_java_lang_reflect_Member.V.DECLARED != wantMode)) {
!         /* If this blows, somebody added new functionality to this method. */
!         throwInternalError ("findFieldEntry: Unmatched declared/public parameter %d", wantMode);
!     }
  
+     /* Find the C class data. */
      cl = find_class(this);
  
!     /* We look for a match starting with this class and going up the
!      * superclasses.  We stop as soon as we hit a class that has the field
!      * as a declared (local) field; this is the only way we can tell
!      * whether a static or an instance field is the one we end up resolving
!      * to if both are present in the table.  Fortunately, lookup through
!      * fields does _not_ dynamically change based on the type of the
!      * underlying object, as it does for methods, so we will be looking up
!      * the field as visible in the declaring class we store in the jlField
!      * structure, not as visible in the object we're pulling data out of,
!      * so we want the local one _anyway_. */
!     f = NULL;
!     scl = NULL;
!     for (sci = 0; (sci < cl->nsupers) && (NULL == f); sci++) {
!         struct vt_generic * inf;
!         struct vt_generic * clf;
!         int insl;
!         int clsl;
!         
!         scl = cl->supers [sci];
! 
!         /* First look in the instance table. */
!         inf = findNamedFieldInTable (name, scl->ivars, scl->nivars);
!         if (NULL != inf) {
!             /* Compute the slot; this marks that we found a match */
!             insl = inf - scl->ivars;
!         }
!         clf = findNamedFieldInTable (name, scl->cvars, scl->ncvars);
!         if (NULL != clf) {
!             /* Compute the slot; this marks that we found a match */
!             clsl = FTS_buildStaticSlot (clf - scl->cvars);
!         }
!         /* If we found a local instance field, that's our return value.
!          * There cannot also be a static field of the same name declared
!          * in this class. */
!         if ((NULL != inf) && inf->localp) {
!             assert ((NULL == clf) || (! clf->localp));
!             f = inf;
!             sl = insl;
!         } else if ((NULL != clf) && clf->localp) {
!             /* Same-same for static field matches */
!             assert ((NULL == inf) || (! inf->localp));
!             f = clf;
!             sl = clsl;
!         } 
!     }
! 
!     if (NULL != f) {
!         /* Found the field we resolve to.  If we want public fields and
!          * this one isn't public, or if we want local methods and this one
!          * wasn't declared in the bottom class, we consider the search to
!          * have failed. */
!         assert (f->localp);
!         if (((cl_java_lang_reflect_Member.V.PUBLIC == wantMode) &&
!              (ACC_PUBLIC != (f->access & ACC_PUBLIC))) ||
!             ((cl_java_lang_reflect_Member.V.DECLARED == wantMode) &&
!              (scl != cl))) {
!             f = NULL;
!         }
      }
!     
!     /* If we have a match, return it */
!     if (NULL != f) {
!         return buildReflectField (scl, f, sl);
      }
  
!     /* JDK doesn't provide the name of the field that isn't there in its
!      * exception messages, so we won't either. */
!     throwMesg(&cl_java_lang_NoSuchFieldException.C,0);
      return 0;
  }
  
! Object
! getFields0_i_hY6Lk (Object Harg1, Int wantMode) /* Since JDK1.1 */
  {
      struct in_java_lang_Class *this = (struct in_java_lang_Class *)Harg1;
!     Class  cl,supercl;
!     Object flds;               /* Array of field objects */
!     Object * pfld;             /* Dynamically-increased array of field objects */
!     int npfld;                 /* Number of elements in pfld array */
!     int maxpfld;               /* Maximum number of elements in current pfld array */
!     int sci;                    /* Index over superclasses */
!     int    i,cnt;
! 
!     /* If we're to search for PUBLIC methods, we include inherited ones.
!      * Otherwise, we're to search for DECLARED methods, and we only look
!      * within this one class (set super scan limit to one level). */
!     if ((cl_java_lang_reflect_Member.V.PUBLIC != wantMode) &&
!         (cl_java_lang_reflect_Member.V.DECLARED != wantMode)) {
!         /* If this blows, somebody added new functionality to this method. */
!         throwInternalError ("getMethod0: Unmatched declared/public parameter %d", wantMode);
      }
  
+     /* Find the basic class data. */
+     cl = find_class(this);
+ 
+     /* Set up for extending the list of methods; we have no default bound
+      * on its length. */
+     npfld = maxpfld = 0;
+     pfld = NULL;
+ 
+     /* Walk the class hierarchy looking for fields of the appropriate type. */
+     sci = 0;
+     while (sci < cl->nsupers) {
+         Class scl;
+         
+         /* Get a pointer to the class data for this scan.  If we're looking
+          * for declared ones, we stop after the first class. */
+         scl = cl->supers [sci++];
+         if ((cl_java_lang_reflect_Member.V.DECLARED == wantMode) &&
+             (scl != cl)) {
+             break;
+         }
+ 
+ /* Restrict ourselves to local ones, so we can tell whether an instance
+  * one obscures a class one and v/v.  Further restrict by access if
+  * we're looking only for public fields.  We do _not_ restrict to fields
+  * that we haven't seen in a subclass; the way field reflection works
+  * we can still access the superclass fields that have been hidden. */
+ #define WantFP(_fp) ( \
+     (_fp)->localp && \
+     ((cl_java_lang_reflect_Member.V.DECLARED == wantMode) || \
+      ((cl_java_lang_reflect_Member.V.PUBLIC == wantMode) && (ACC_PUBLIC == (ACC_PUBLIC & (_fp)->access)))) \
+     )
+ 
+ #define AddFields(_fvl,_fvc) { \
+     int fpi = 0; \
+     struct vt_generic * fp = (_fvl); \
+     while (fpi < (_fvc)) { \
+         if (WantFP(fp)) { \
+             addToDynArray (buildReflectField (scl, fp, ConvertSlot(fpi)), &npfld, &maxpfld, &pfld); \
+         } \
+         ++fp; \
+         ++fpi; \
+     } \
+ }
+ #define ConvertSlot(_sl) FTS_buildStaticSlot(_sl)
+         AddFields(scl->cvars,scl->ncvars);
+ #undef ConvertSlot
+ #define ConvertSlot(_sl) (_sl)
+         AddFields(scl->ivars,scl->nivars);
+ #undef ConvertSlot
+ 
+ #undef WantFP
+ #undef AddFields
+     }
+ 
+     /* Allocate an array object with the appropriate base type. */
+     flds = anewarray(&cl_java_lang_reflect_Field.C,npfld);
+ 
+     /* If we collected some objects, copy them over into the array. */
+     if (0 < npfld) {
+         memcpy (((struct aarray*)flds)->data, pfld, npfld * sizeof (*pfld));
+     }
  
+     return flds;
+ }
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.11
*** toba-1.1/runtime/lang_ClassLoader.c:1.9	Tue Jul 28 15:14:55 1998
--- toba-1.1/runtime/lang_ClassLoader.c	Thu Dec  3 11:55:30 1998
***************
*** 42,47 ****
--- 42,48 ----
      return cl;
  #else /* OPTION_JIT */
      throwInternalError ("(defineClass0) Dynamic loading is not supported in this system");
+     /*NOTREACHED*/
  #endif /* OPTION_JIT */
  }
  
***************
*** 89,94 ****
--- 90,96 ----
      return;
  #else /* OPTION_JIT */
      throwInternalError ("(resolveClass0) Dynamic loading is not supported in this system");
+     /*NOTREACHED*/
  #endif /* OPTION_JIT */
  }
  
***************
*** 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;
  }
  
--- 119,138 ----
  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;
  }
  
***************
*** 139,144 ****
--- 150,156 ----
  Object	getSystemResourceAsName_S_i23lr(Object Harg1) /* Unimplemented JDK1.1 */
  {
      unimpl("getSystemResourceAsName_S_i23lr");
+     /*NOTREACHED*/
  }
  
  
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.16
*** toba-1.1/runtime/lang_Runtime.c:1.14	Sat Apr 18 16:30:20 1998
--- toba-1.1/runtime/lang_Runtime.c	Fri Nov 13 22:11:36 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.11
*** toba-1.1/runtime/lang_System.c:1.9	Mon Jul 27 10:39:37 1998
--- toba-1.1/runtime/lang_System.c	Mon Nov  9 14:00:52 1998
***************
*** 23,29 ****
  #include <scout/event.h>
  #include <scout/errno.h>
  #include <scout/time.h>
- #include <awt.h>
  #include <joust_i.h>
  #else /* SCOUT */
  #include <stdlib.h>
--- 23,28 ----
***************
*** 140,145 ****
--- 139,145 ----
          { "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/lang_Thread.c
diff -c toba-1.1/runtime/lang_Thread.c:1.4 toba-1.1/runtime/lang_Thread.c:1.5
*** toba-1.1/runtime/lang_Thread.c:1.4	Sat Apr 18 16:30:21 1998
--- toba-1.1/runtime/lang_Thread.c	Thu Dec  3 11:55:30 1998
***************
*** 94,99 ****
--- 94,100 ----
  Boolean	isInterrupted_z_rlmXv(Object Harg1,Boolean arg2) /* Unimplemented JDK1.1 */
  {
      unimpl("isInterrupted_z_rlmXv");
+     /*NOTREACHED*/
  }
  Void	interrupt0__4xsPX(Object Harg1) /* Unimplemented JDK1.1 */
  {
Index: toba-1.1/runtime/lang_reflect_Array.c
diff -c toba-1.1/runtime/lang_reflect_Array.c:1.1 toba-1.1/runtime/lang_reflect_Array.c:1.4
*** toba-1.1/runtime/lang_reflect_Array.c:1.1	Sat Apr 18 16:30:21 1998
--- toba-1.1/runtime/lang_reflect_Array.c	Fri Nov 20 08:53:13 1998
***************
*** 1,11 ****
  #include <stddef.h>
  #include <string.h>
  
  #include "toba.h"
  #include "java_lang_Object.h"
  #include "java_lang_reflect_Array.h"
- #include "java_lang_IllegalArgumentException.h"
- #include "java_lang_NegativeArraySizeException.h"
  #include "java_lang_Boolean.h"
  #include "java_lang_Byte.h"
  #include "java_lang_Integer.h"
--- 1,10 ----
  #include <stddef.h>
  #include <string.h>
+ #include <assert.h>
  
  #include "toba.h"
  #include "java_lang_Object.h"
  #include "java_lang_reflect_Array.h"
  #include "java_lang_Boolean.h"
  #include "java_lang_Byte.h"
  #include "java_lang_Integer.h"
***************
*** 14,479 ****
  #include "java_lang_Float.h"
  #include "java_lang_Double.h"
  #include "java_lang_Character.h"
  #include "runtime.h"
  
! extern Class GetObjClassFromPrimClass(Class cl);
! 
! /*
!  *   Check if the object is an array
!  *   and fill in the class and element class if they are not null
!  */
! static int IsArray(Object obj,Class *cl,Class *elemcl,char *errmsg)
  {
      Class c;
      c = find_class(getClass__zh19H(obj));
!     if (c->flags & IS_ARRAY){
!         if (cl)
! 	    *cl = c;
! 	if (elemcl)
! 	    *elemcl = c->elemclass;
! 	return 1;
!     }
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     return 0;
  }
  
! static void CheckIndex(Object arobj,int ndx)
  {
!     if ( ndx<0 || ndx>=((struct aarray*)arobj)->length ){
!         throwArrayIndexOutOfBoundsException(arobj,ndx);
      }
  }
  
  Int	getLength_O_fqEvl(Object Harg1) /* Since JDK1.1 */
  {
!     if (IsArray(Harg1,0,0,"Array.getLength")){
!         return ((struct aarray*)Harg1)->length;
!     }
  }
  
  Object	get_Oi_NIg8U(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
      Class elemcl,objcl;
-     char  *errmsg = "Array.get";
      Object ret;
  
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl->flags & IS_PRIMITIVE){
! 	    objcl = GetObjClassFromPrimClass(elemcl);
! 	    ret = new(objcl);
! 	    memcpy((char*)ret+sizeof(struct in_generic),
! 		   (char*)((struct carray*)Harg1)->data + arg2*elemcl->instsize,
! 		   elemcl->instsize);
! 	    return ret;
! 	}
! 	else
! 	    return ((struct aarray*)Harg1)->data[arg2];
!     }
! }
! Boolean	getBoolean_Oi_p1Guu(Object Harg1,Int arg2) /* Since JDK1.1 */
! {
!     Class elemcl;
!     char  *errmsg = "Array.getBoolean";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_boolean)
! 	    return ((struct barray*)Harg1)->data[arg2];
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
      }
  }
  
! Byte	getByte_Oi_TOC91(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getByte";
  
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_byte)
! 	    return ((struct barray*)Harg1)->data[arg2];
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Char	getChar_Oi_wzbv7(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getChar";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_char)
! 	    return ((struct carray*)Harg1)->data[arg2];
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Short	getShort_Oi_S9r1j(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getShort";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_short)
! 	    return ((struct sarray*)Harg1)->data[arg2];
! 	if (elemcl==&cl_byte)
! 	    return (Short)(((struct barray*)Harg1)->data[arg2]);
! 	throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  Int	getInt_Oi_B2k6D(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getInt";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_int)
! 	    return ((struct iarray*)Harg1)->data[arg2];
! 	if (elemcl==&cl_short)
! 	    return (Int)(((struct sarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_char)
! 	    return (Int)(((struct carray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_byte)
! 	    return (Int)(((struct barray*)Harg1)->data[arg2]);
! 	throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Long	getLong_Oi_h1wvq(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getLong";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_long)
! 	    return ((struct larray*)Harg1)->data[arg2];
! 	if (elemcl==&cl_int)
! 	    return (Long)(((struct iarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_short)
! 	    return (Long)(((struct sarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_char)
! 	    return (Long)(((struct carray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_byte)
! 	    return (Long)(((struct barray*)Harg1)->data[arg2]);
! 	throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Float	getFloat_Oi_9OzjO(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getFloat";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_float)
! 	    return ((struct farray*)Harg1)->data[arg2];
! 	if (elemcl==&cl_long)
! 	    return (Float)(((struct larray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_int)
! 	    return (Float)(((struct iarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_short)
! 	    return (Float)(((struct sarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_char)
! 	    return (Float)(((struct carray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_byte)
! 	    return (Float)(((struct barray*)Harg1)->data[arg2]);
! 	throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Double	getDouble_Oi_Ob699(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.getDouble";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_double)
! 	    return ((struct darray*)Harg1)->data[arg2];
! 	if (elemcl==&cl_float)
! 	    return (Double)(((struct farray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_long)
! 	    return (Double)(((struct larray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_int)
! 	    return (Double)(((struct iarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_short)
! 	    return (Double)(((struct sarray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_char)
! 	    return (Double)(((struct carray*)Harg1)->data[arg2]);
! 	if (elemcl==&cl_byte)
! 	    return (Double)(((struct barray*)Harg1)->data[arg2]);
! 	throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
! Void	set_OiO_RBvo8(Object Harg1,Int arg2,Object Harg3) /* Since JDK1.1 */
! {
!     Class elemcl,valcl;
!     char  *errmsg = "Array.set";
!     void  *vaddr;
  
-     if (!Harg1)
-         throwNullPointerException(errmsg);
-     
-     valcl = Harg3 ? find_class(getClass__zh19H(Harg3)) : 0;
-     vaddr = (char*)Harg3 + sizeof(struct in_generic);
- 
-     if (IsArray(Harg1,0,&elemcl,errmsg)){
-         CheckIndex(Harg1,arg2);
- 	if ( elemcl->flags & IS_PRIMITIVE ){
- 	    if (!Harg3)
- 	        throwNullPointerException(errmsg);
- 
- 	    if (valcl==&cl_java_lang_Integer.C)
- 	        setInt_Oii_N7HVI(Harg1,arg2,*(Int*)vaddr);
- 	    else if (valcl==&cl_java_lang_Short.C)
- 	        setShort_Ois_GSFcL(Harg1,arg2,*(Short*)vaddr);
- 	    else if (valcl==&cl_java_lang_Byte.C)
- 	        setByte_Oib_1WQzK(Harg1,arg2,*(Byte*)vaddr);
- 	    else if (valcl==&cl_java_lang_Boolean.C)
- 	        setBoolean_Oiz_nvusI(Harg1,arg2,*(Boolean*)vaddr);
- 	    else if (valcl==&cl_java_lang_Character.C)
- 	        setChar_Oic_cmosl(Harg1,arg2,*(Char*)vaddr);
- 	    else if (valcl==&cl_java_lang_Long.C)
- 	        setLong_Oil_Zob0O(Harg1,arg2,*(Long*)vaddr);
- 	    else if (valcl==&cl_java_lang_Float.C)
- 	        setFloat_Oif_NbKGb(Harg1,arg2,*(Float*)vaddr);
- 	    else if (valcl==&cl_java_lang_Double.C)
- 	        setDouble_Oid_y2hF8(Harg1,arg2,*(Double*)vaddr);
- 	    else
- 	        throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
- 	}
- 	else{
- 	    if (!Harg3 || isAssignableFrom_C_3OtSc(elemcl,valcl))
- 	        ((struct aarray*)Harg1)->data[arg2] = Harg3;
- 	    else
- 	        throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
- 	}
-     }
- }
  
  Void	setBoolean_Oiz_nvusI(Object Harg1,Int arg2,Boolean arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setBoolean";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_boolean)
! 	    ((struct barray*)Harg1)->data[arg2] = arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setByte_Oib_1WQzK(Object Harg1,Int arg2,Byte arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setByte";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_byte)
! 	    ((struct barray*)Harg1)->data[arg2] = arg3;
! 	else if (elemcl==&cl_short)
! 	    ((struct sarray*)Harg1)->data[arg2] = (Short)arg3;
! 	else if (elemcl==&cl_int)
! 	    ((struct iarray*)Harg1)->data[arg2] = (Int)arg3;
! 	else if (elemcl==&cl_long)
! 	    ((struct larray*)Harg1)->data[arg2] = (Long)arg3;
! 	else if (elemcl==&cl_float)
! 	    ((struct farray*)Harg1)->data[arg2] = (Float)arg3;
! 	else if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = (Double)arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setChar_Oic_cmosl(Object Harg1,Int arg2,Char arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setChar";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_char)
! 	    ((struct carray*)Harg1)->data[arg2] = arg3;
! 	else if (elemcl==&cl_int)
! 	    ((struct iarray*)Harg1)->data[arg2] = (Int)arg3;
! 	else if (elemcl==&cl_long)
! 	    ((struct larray*)Harg1)->data[arg2] = (Long)arg3;
! 	else if (elemcl==&cl_float)
! 	    ((struct farray*)Harg1)->data[arg2] = (Float)arg3;
! 	else if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = (Double)arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setShort_Ois_GSFcL(Object Harg1,Int arg2,Short arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setShort";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_short)
! 	    ((struct sarray*)Harg1)->data[arg2] = arg3;
! 	else if (elemcl==&cl_int)
! 	    ((struct iarray*)Harg1)->data[arg2] = (Int)arg3;
! 	else if (elemcl==&cl_long)
! 	    ((struct larray*)Harg1)->data[arg2] = (Long)arg3;
! 	else if (elemcl==&cl_float)
! 	    ((struct farray*)Harg1)->data[arg2] = (Float)arg3;
! 	else if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = (Double)arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setInt_Oii_N7HVI(Object Harg1,Int arg2,Int arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setInt";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_int)
! 	    ((struct iarray*)Harg1)->data[arg2] = arg3;
! 	else if (elemcl==&cl_long)
! 	    ((struct larray*)Harg1)->data[arg2] = (Long)arg3;
! 	else if (elemcl==&cl_float)
! 	    ((struct farray*)Harg1)->data[arg2] = (Float)arg3;
! 	else if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = (Double)arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setLong_Oil_Zob0O(Object Harg1,Int arg2,Long arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setLong";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_long)
! 	    ((struct larray*)Harg1)->data[arg2] = arg3;
! 	else if (elemcl==&cl_float)
! 	    ((struct farray*)Harg1)->data[arg2] = (Float)arg3;
! 	else if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = (Double)arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setFloat_Oif_NbKGb(Object Harg1,Int arg2,Float arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setFloat";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_float)
! 	    ((struct farray*)Harg1)->data[arg2] = arg3;
! 	else if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = (Double)arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Void	setDouble_Oid_y2hF8(Object Harg1,Int arg2,Double arg3) /* Since JDK1.1 */
  {
!     Class elemcl;
!     char  *errmsg = "Array.setDouble";
! 
!     if (!Harg1)
!         throwNullPointerException(errmsg);
!     if (IsArray(Harg1,0,&elemcl,errmsg)){
!         CheckIndex(Harg1,arg2);
! 	if (elemcl==&cl_double)
! 	    ((struct darray*)Harg1)->data[arg2] = arg3;
! 	else
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
!     }
  }
  
  Object	newArray_Ci_h4nZp(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
      Class cl;
      
!     if (arg2<0)
!         throwMesg(&cl_java_lang_NegativeArraySizeException.C,"Array.newArray");
      cl = find_class(Harg1);
      return anewarray(cl,arg2);
  }
  
  /* Object multiNewArray(java.lang.Class componentType, int[] dimensions) */
! Object	multiNewArray_Cai_tb3kS(Object Harg1,Object Harg2) /* Since JDK1.1 */
  {
      Class cl,elemcl,primcl;
      struct iarray *dims = (struct iarray*)Harg2;
-     char  *errmsg = "Array.multiNewArray";
      int i,ndims;
  
!     if (IsArray(Harg2,0,&elemcl,errmsg)){
!         if (elemcl!=&cl_int || dims->length<=0 )
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
! 	for (i=0;i<dims->length;i++){
! 	    if (dims->data[i]<0)
! 	        throwMesg(&cl_java_lang_NegativeArraySizeException.C,errmsg);
! 	}
! 	cl = find_class(Harg1);
! 	for (primcl=cl,ndims=0; primcl->arrayclass; primcl=primcl->arrayclass,ndims++);
! 	return mnewarray(cl,ndims,dims->length,dims->data);
      }
  }
  
--- 13,262 ----
  #include "java_lang_Float.h"
  #include "java_lang_Double.h"
  #include "java_lang_Character.h"
+ #include "java_lang_ArrayIndexOutOfBoundsException.h"
  #include "runtime.h"
+ #include "reflect.h"
  
! /* Verify that the object is an array; if not, throw the given error
!  * message as an NPE if the object is null, or as an illegal argument
!  * exception if it is not null.  If the object is an array, fill in the
!  * class and element class fields if the pointers aren't null. */
! static void
! checkArray (Object obj,Class *cl,Class *elemcl)
  {
      Class c;
+     if (NULL == obj) {
+         throwNullPointerException (0);
+     }
      c = find_class(getClass__zh19H(obj));
!     if (! (IS_ARRAY & c->flags)) {
!         throwIllegalArgumentException("argument is not an array");
!     }
!     if (NULL != cl) {
!         *cl = c;
!     }
!     if (NULL != elemcl) {
!         *elemcl = c->elemclass;
!     }
!     return;
  }
  
! static void
! checkIndex (Object arobj,int idx)
  {
!     if ((0 > idx) ||
!         (((struct aarray*)arobj)->length <= idx)) {
!         /* We don't call the standard one here, because the JDK implementation
!          * doesn't include the index in its message when done through
!          * reflection, as our standard one does. */
!         throwMesg(&cl_java_lang_ArrayIndexOutOfBoundsException.C, 0);
      }
  }
  
  Int	getLength_O_fqEvl(Object Harg1) /* Since JDK1.1 */
  {
!     checkArray(Harg1,0,0);
!     return ((struct aarray*)Harg1)->length;
  }
  
+ /* Retrieve the value of the element at the given position, wrapping it in an
+  * object if it's of primitive type. */
  Object	get_Oi_NIg8U(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
      Class elemcl,objcl;
      Object ret;
  
!     checkArray(Harg1,0,&elemcl);
!     checkIndex(Harg1,arg2);
!     if (elemcl->flags & IS_PRIMITIVE){
!         return wrapPrimObject (elemcl, ((char*)((struct carray*)Harg1)->data + arg2*elemcl->instsize));
      }
+     return ((struct aarray*)Harg1)->data[arg2];
  }
  
! 
! #define DefnGetBody(_pt,_jt) \
!     Class elemcl; \
!     _jt rv; \
!  \
!     checkArray (Harg1,0,&elemcl); \
!     checkIndex (Harg1, arg2); \
!     if (! widenConvert (elemcl, ((char*)((struct carray*)Harg1)->data + arg2*elemcl->instsize), \
!                         &cl_##_pt, &rv)) { \
!         throwIllegalArgumentException("array element type mismatch"); \
!     } \
!     return rv;
! 
! 
! Boolean
! getBoolean_Oi_p1Guu(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(boolean,Boolean);
! }
  
! Byte	getByte_Oi_TOC91(Object Harg1,Int arg2) /* Since JDK1.1 */
! {
!     DefnGetBody(byte,Byte);
  }
  
  Char	getChar_Oi_wzbv7(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(char,Char);
  }
  
  Short	getShort_Oi_S9r1j(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(short,Short);
  }
+ 
  Int	getInt_Oi_B2k6D(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(int,Int);
  }
  
  Long	getLong_Oi_h1wvq(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(long,Long);
  }
  
  Float	getFloat_Oi_9OzjO(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(float,Float);
  }
  
  Double	getDouble_Oi_Ob699(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
!     DefnGetBody(double,Double);
  }
+ #undef DefnGetBody
  
! Void	set_OiO_RBvo8(Object Harg1,Int arg2,Object val) /* Since JDK1.1 */
! {
!     Class elemcl;               /* Information about class of array elements */
!     Class valcl;                /* Information about class of value to be assigned */
!     PrimClassTriple * pct;      /* Primitive class info relative to value class */
! 
!     /* Make sure we're dealing with a valid array and index. */
!     checkArray(Harg1,0,&elemcl);
!     checkIndex(Harg1,arg2);
! 
!     /* If the element type is primitive and the incoming object is null, we
!      * can't do a type conversion, so throw an error. */
!     if ((IS_PRIMITIVE & elemcl->flags) &&
!         (NULL == val)) {
!         throwNullPointerException(0);
!     }
! 
!     /* Extract value class and primitive class triple, if value is not null. */
!     valcl = NULL;
!     pct = NULL;
!     if (NULL != val) {
!         valcl = find_class(getClass__zh19H(val));
!         pct = getPCTbyObjClass (valcl);
!     }
! 
!     /* If the value to be assigned is a wrapped primitive type, and the
!      * target element is a primitive type, unwrap the value and call the
!      * appropriate type-specific assignment method.  Note that the
!      * assignment method will verify that the value is compatible with
!      * the actual type of the underyling element. */
!     if ((NULL != pct) && (IS_PRIMITIVE & elemcl->flags)) {
!         if (widenConvert (PCT_primClass (pct), PCT_objPrimValAddr (pct, val),
!                           elemcl, ((char*)((struct carray*)Harg1)->data + arg2*elemcl->instsize))) {
!             return;
!         }
!     } else {
!         /* Not a primitive-to-primitive assignment.  If the element type is not
!          * primitive, and the value is either null or assignable to the element
!          * type, stuff it into place. */
!         if ((! (IS_PRIMITIVE & elemcl->flags)) &&
!             ((NULL == val) ||
!              assignablefrom (elemcl,valcl))) {
!             ((struct aarray*)Harg1)->data[arg2] = val;
!             return;
!         }
!     }
!     throwIllegalArgumentException("array element type mismatch");
! }
! 
! #define DefnSetBody(_pt,_jt) \
!     Class elemcl; \
!  \
!     checkArray(Harg1,0,&elemcl); \
!     checkIndex(Harg1,arg2); \
!     if (! widenConvert (&cl_##_pt,&arg3,elemcl,((char*)((struct carray*)Harg1)->data + arg2*elemcl->instsize))) { \
!         throwIllegalArgumentException("array element type mismatch"); \
!     } \
!     return;
  
  
  Void	setBoolean_Oiz_nvusI(Object Harg1,Int arg2,Boolean arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(boolean,Boolean);
  }
  
  Void	setByte_Oib_1WQzK(Object Harg1,Int arg2,Byte arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(byte,Byte);
  }
  
  Void	setChar_Oic_cmosl(Object Harg1,Int arg2,Char arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(char,Char);
  }
  
  Void	setShort_Ois_GSFcL(Object Harg1,Int arg2,Short arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(short,Short);
  }
  
  Void	setInt_Oii_N7HVI(Object Harg1,Int arg2,Int arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(int,Int);
  }
  
  Void	setLong_Oil_Zob0O(Object Harg1,Int arg2,Long arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(long,Long);
  }
  
  Void	setFloat_Oif_NbKGb(Object Harg1,Int arg2,Float arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(float,Float);
  }
  
  Void	setDouble_Oid_y2hF8(Object Harg1,Int arg2,Double arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(double,Double);
  }
  
  Object	newArray_Ci_h4nZp(Object Harg1,Int arg2) /* Since JDK1.1 */
  {
      Class cl;
      
!     if (0 > arg2) {
!         throwNegativeArraySizeException (arg2);
!     }
!     if (NULL == Harg1) {
!         throwNullPointerException (0);
!     }
      cl = find_class(Harg1);
      return anewarray(cl,arg2);
  }
  
  /* Object multiNewArray(java.lang.Class componentType, int[] dimensions) */
! Object
! multiNewArray_Cai_tb3kS(Object Harg1,Object Harg2) /* Since JDK1.1 */
  {
      Class cl,elemcl,primcl;
      struct iarray *dims = (struct iarray*)Harg2;
      int i,ndims;
  
!     if (0 == dims->length) {
!         throwIllegalArgumentException ("zero dimensions");
      }
+     assert (0 < dims->length);
+     cl = find_class(Harg1);
+     return mnewarray(cl,dims->length,dims->length,dims->data);
  }
  
Index: toba-1.1/runtime/lang_reflect_Constructor.c
diff -c toba-1.1/runtime/lang_reflect_Constructor.c:1.1 toba-1.1/runtime/lang_reflect_Constructor.c:1.5
*** toba-1.1/runtime/lang_reflect_Constructor.c:1.1	Sat Apr 18 16:30:21 1998
--- toba-1.1/runtime/lang_reflect_Constructor.c	Thu Nov 19 19:00:32 1998
***************
*** 1,21 ****
  #include <stddef.h>
  #include <string.h>
  
  #include "toba.h"
! #include "runtime.h"
  #include "java_lang_reflect_Constructor.h"
  
! Int	getModifiers__ECsyZ(Object Harg1) /* Since JDK1.1 */
  {
      struct in_java_lang_reflect_Constructor *this = Harg1;
-     struct mt_generic *mtable;
      Class  cl;
      
      cl = find_class(this->clazz);
!     mtable = ((struct cl_generic*)cl)->M;
!     return mtable[this->slot].access;
  }
! Object	newInstance_aO_noE10(Object Harg1,Object Harg2) /* Unimplemented JDK1.1 */
  {
!     unimpl("newInstance_aO_noE10");
  }
--- 1,53 ----
  #include <stddef.h>
  #include <string.h>
+ #include <assert.h>
  
  #include "toba.h"
! #include "classfile_ClassData.h"
  #include "java_lang_reflect_Constructor.h"
+ #include "java_lang_InstantiationException.h"
+ #include "runtime.h"
+ #include "reflect.h"
  
! Int
! getModifiers__ECsyZ(Object Harg1) /* Since JDK1.1 */
  {
      struct in_java_lang_reflect_Constructor *this = Harg1;
      Class  cl;
      
      cl = find_class(this->clazz);
!     /* Constructors are always local, and always in the instance method table. */
!     assert (0 <= this->slot);
!     return (this->slot + ((struct cl_generic*)cl)->M)->access;
  }
! 
! Object
! newInstance_aO_noE10 (Object Harg1,Object prArray)
  {
!     struct in_java_lang_reflect_Constructor *this=(struct in_java_lang_reflect_Constructor *)Harg1;
!     Class  cl;
!     struct mt_generic *m;
!     Object *obj;
! 
!     cl = find_class(this->clazz);
!     obj = new(cl);
!     m = (((struct cl_generic*)cl)->M)+this->slot;
! 
!     /* Comments match javadoc on java.lang.reflect.Constructor#newInstance */
! 
!     /* If the class that declares the underlying constructor represents an
!      * abstract class, the creation throws an InstantiationException. */
!     if ((((struct cl_generic*)cl)->C.access & ACC_ABSTRACT) == ACC_ABSTRACT) {
!         throwInstantiationException (obj);
!     }
! 
!     /* Invoke the constructor as a void instance method. */
!     invoke_c (m, obj,
!               (struct aarray *) this->parameterTypes,
!               (struct aarray *) prArray, JAVA_TRUE, JAVA_TRUE);
!     
!     /* Return the new object. */
!     return obj;
  }
+ 
+ 
Index: toba-1.1/runtime/lang_reflect_Field.c
diff -c toba-1.1/runtime/lang_reflect_Field.c:1.1 toba-1.1/runtime/lang_reflect_Field.c:1.5
*** toba-1.1/runtime/lang_reflect_Field.c:1.1	Sat Apr 18 16:30:22 1998
--- toba-1.1/runtime/lang_reflect_Field.c	Fri Nov 20 08:53:13 1998
***************
*** 1,550 ****
  #include <stddef.h>
  #include <string.h>
  
  #include "toba.h"
- #include "java_lang_Boolean.h"
- #include "java_lang_Byte.h"
- #include "java_lang_Integer.h"
- #include "java_lang_Short.h"
- #include "java_lang_Long.h"
- #include "java_lang_Float.h"
- #include "java_lang_Double.h"
- #include "java_lang_Character.h"
  #include "java_lang_reflect_Field.h"
- #include "java_lang_IllegalArgumentException.h"
- #include "java_lang_InternalError.h"
  #include "java_lang_Object.h"
  #include "runtime.h"
  #include "classfile_ClassData.h"
  
! extern SameAsJavaStr(const Char *name_chars,int name_len,Object jstr);
! 
! static int isClassVar(Object fld)
! {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)fld;
!     int    namelen;
!     Class  cl;
! 
!     namelen = ((struct in_java_lang_String*)this->name)->count;
!     cl = find_class(this->clazz);
!     if (this->slot<cl->ncvars && SameAsJavaStr(cl->cvars[this->slot].name_chars,namelen,this->name))
!         return 1;
!     else
!         return 0;
! }
! 
! static void *GetFieldAddr(Object fld,Object obj,char *exceptionMsg)
  {
      struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)fld;
      Class  cl;
  
      cl = find_class(this->clazz);
!     if (isClassVar(this)){
!         return cl->cvars[this->slot].addr;
!     }
!     else{
!         if (!obj)
! 	    throwNullPointerException(exceptionMsg);
! 	if (!instanceof(obj,cl,0)){
! 	    throwMesg(&cl_java_lang_IllegalArgumentException.C,exceptionMsg);
  	}
!         return (char*)obj+cl->ivars[this->slot].offset;
      }
  }
  
! static struct primClassTriple{
!        char *name;
!        Class primClass;
!        Class objClass;
! }primTriples[] = { 
!                     {"int",     &cl_int,     &cl_java_lang_Integer.C},
! 		    {"boolean", &cl_boolean, &cl_java_lang_Boolean.C},
! 		    {"byte",    &cl_byte,    &cl_java_lang_Byte.C},
! 		    {"short",   &cl_short,   &cl_java_lang_Short.C},
! 		    {"char",    &cl_char,    &cl_java_lang_Character.C},
! 		    {"long",    &cl_long,    &cl_java_lang_Long.C},
! 		    {"float",   &cl_float,   &cl_java_lang_Float.C},
! 		    {"double",  &cl_double,  &cl_java_lang_Double.C}
!                  };
! 
! Class GetObjClassFromPrimClass(Class primcl)
! {
!     int i;
!     for (i=0;i<sizeof(primTriples)/sizeof(struct primClassTriple);i++){
!         if (primTriples[i].primClass == primcl)
! 	    return primTriples[i].objClass;
!     }
!     return 0;
! }
! Class GetPrimClassFromObjClass(Class objcl)
! {
!     int i;
!     for (i=0;i<sizeof(primTriples)/sizeof(struct primClassTriple);i++){
!         if (primTriples[i].objClass == objcl)
! 	    return primTriples[i].primClass;
!     }
!     return 0;
! }
! Class GetObjClassFromName(char *name)
! {
!     int i;
!     for (i=0;i<sizeof(primTriples)/sizeof(struct primClassTriple);i++){
!         if ( strcmp(primTriples[i].name,name)==0 )
! 	    return primTriples[i].objClass;
!     }
!     return 0;
! }
! Class GetPrimClassFromName(char *name)
! {
!     int i;
!     for (i=0;i<sizeof(primTriples)/sizeof(struct primClassTriple);i++){
!         if ( strcmp(primTriples[i].name,name)==0 )
! 	    return primTriples[i].primClass;
!     }
!     return 0;
! }
! 
! static Object WrapField(Object fld,void *addr)
! {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)fld;
!     Class  fldcl,objcl;
!     Object ret;
!     int    i;
! 
!     fldcl = find_class(this->type);
!     if (fldcl->flags & IS_PRIMITIVE){
!         objcl = GetObjClassFromPrimClass(fldcl);
! 	ret = new(objcl);
! 	memcpy((char*)ret+sizeof(struct in_generic),addr,
! 	       objcl->instsize-sizeof(struct in_generic));
! 	return ret;
!     }
!     else{
!         return *(Object*)addr;
!     }
! }
! 
! Int	getModifiers__KljNq(Object Harg1) /* Since JDK1.1 */
  {
      struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
      Class  cl;
  
      cl = find_class(this->clazz);
!     if (isClassVar(this))
!         return cl->cvars[this->slot].access;
!     else
          return cl->ivars[this->slot].access;
  }
  
! Object	get_O_p04pc(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     void   *addr;
! 
!     addr = GetFieldAddr(Harg1,Harg2,"Field.get");
!     return WrapField(Harg1,addr);
  }
  
  
! Boolean	getBoolean_O_hRqw8(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getBoolean";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_boolean)
!         return *(Boolean*)addr;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Byte	getByte_O_9jSSo(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getByte";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_byte)
!         return *(Byte*)addr;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Char	getChar_O_EHJj2(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getChar";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_char)
!         return *(Char*)addr;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Short	getShort_O_AqspT(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getShort";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_short)
!         return *(Short*)addr;
!     if (cl==&cl_byte)
!         return (Short)(*(Byte*)addr);
!     throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Int	getInt_O_rBjV8(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getInt";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_int)
!         return *(Int*)addr;
!     if (cl==&cl_char)
!         return (Int)(*(Char*)addr);
!     if (cl==&cl_byte)
!         return (Int)(*(Byte*)addr);
!     if (cl==&cl_short)
!         return (Int)(*(Short*)addr);
!     throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Long	getLong_O_RJpEW(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getLong";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_long)
!         return *(Long*)addr;
!     if (cl==&cl_int)
!         return (Long)(*(Int*)addr);
!     if (cl==&cl_char)
!         return (Long)(*(Char*)addr);
!     if (cl==&cl_byte)
!         return (Long)(*(Byte*)addr);
!     if (cl==&cl_short)
!         return (Long)(*(Short*)addr);
!     throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Float	getFloat_O_pyFZg(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getFloat";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_float)
!         return *(Float*)addr;
!     if (cl==&cl_char)
!         return (Float)(*(Char*)addr);
!     if (cl==&cl_byte)
!         return (Float)(*(Byte*)addr);
!     if (cl==&cl_short)
!         return (Float)(*(Short*)addr);
!     if (cl==&cl_int)
!         return (Float)(*(Int*)addr);
!     if (cl==&cl_long)
!         return (Float)(*(Long*)addr);
!     throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Double	getDouble_O_kEBm5(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getDouble";
! 
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
!     if (cl==&cl_double)
!         return *(Double*)addr;
!     if (cl==&cl_char)
!         return (Double)(*(Char*)addr);
!     if (cl==&cl_byte)
!         return (Double)(*(Byte*)addr);
!     if (cl==&cl_short)
!         return (Double)(*(Short*)addr);
!     if (cl==&cl_int)
!         return (Double)(*(Int*)addr);
!     if (cl==&cl_long)
!         return (Double)(*(Long*)addr);
!     if (cl==&cl_float)
!         return (Double)(*(Float*)addr);
!     throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! static void CheckWriteAccess(Object fld,char *errmsg)
! {
!     int acc = getModifiers__KljNq(fld);
  
!     if (acc & ACC_FINAL)
!         throwIllegalAccessException(errmsg);
  }
  
  Void	set_OO_Ft0Kq(Object fld, Object obj, Object val) /* Since JDK1.1 */
  {
!     static Class primClasses[]={
!                     &cl_java_lang_Integer.C,
! 		    &cl_java_lang_Boolean.C,
! 		    &cl_java_lang_Byte.C,
! 		    &cl_java_lang_Short.C,
! 		    &cl_java_lang_Character.C,
! 		    &cl_java_lang_Long.C,
! 		    &cl_java_lang_Float.C,
! 		    &cl_java_lang_Double.C
!     };
!     Class valcl,fldcl;
!     int   i;
!     void  *addr;
!     void  *vaddr;
!     char  *errmsg = "Field.set";
  
!     CheckWriteAccess(fld,errmsg);
!     addr = GetFieldAddr(fld,obj,errmsg);
!     fldcl = find_class(((struct in_java_lang_reflect_Field*)fld)->type);
  
!     if ( (fldcl->flags & IS_PRIMITIVE) && !val)
!         throwNullPointerException(errmsg);
!     valcl = val ? find_class(getClass__zh19H(val)) : 0;
!     vaddr = (char*)val + sizeof(struct in_generic);
! 
!     for (i=0;i<sizeof(primClasses)/sizeof(Class);i++){
! 	    if (valcl==primClasses[i])
! 	        break;
!     }
!     switch(i){
! 	case 0:
!            setInt_Oi_bU4yN(fld,obj,*(Int*)vaddr);         
!            return;
! 	case 1:
!            setBoolean_Oz_3hIAl(fld,obj,*(Boolean*)vaddr);
!            return;
! 	case 2:
!            setByte_Ob_NqkQe(fld,obj,*(Byte*)vaddr);
!            return;
! 	case 3:
!            setShort_Os_oT4ZA(fld,obj,*(Short*)vaddr);
!            return;
! 	case 4:
!            setChar_Oc_uxTbl(fld,obj,*(Char*)vaddr);
!            return;
! 	case 5:
!            setLong_Ol_Dh1xX(fld,obj,*(Long*)vaddr);
!            return;
! 	case 6:
!            setFloat_Of_PU8h6(fld,obj,*(Float*)vaddr);
!            return;
! 	case 7:
!            setDouble_Od_m8Svx(fld,obj,*(Double*)vaddr);
!            return;
!     }
  
!     /* the val is an object of non-primitive type */
!     if (!(fldcl->flags & IS_PRIMITIVE)){
!         if (!val || isAssignableFrom_C_3OtSc(fldcl,valcl)){
! 	    *(Object*)addr = val;
! 	    return;
! 	}
!     }
!     throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
- Void	setBoolean_Oz_3hIAl(Object Harg1, Object Harg2, Boolean arg3) /* Since JDK1.1 */
- {
-     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
-     Class  cl;
-     void   *addr;
-     char   *errmsg = "Field.setBoolean";
  
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_boolean)
!         *(Boolean*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
  Void	setByte_Ob_NqkQe(Object Harg1, Object Harg2, Byte arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.setByte";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_byte)
!         *(Byte*)addr = arg3;
!     else if (cl==&cl_short)
!         *(Short*)addr = arg3;
!     else if (cl==&cl_int)
!         *(Int*)addr = arg3;
!     else if (cl==&cl_long)
!         *(Long*)addr = arg3;
!     else if (cl==&cl_float)
!         *(Float*)addr = arg3;
!     else if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Void	setChar_Oc_uxTbl(Object Harg1, Object Harg2, Char arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.getChar";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_char)
!         *(Char*)addr = arg3;
!     else if (cl==&cl_int)
!         *(Int*)addr = arg3;
!     else if (cl==&cl_long)
!         *(Long*)addr = arg3;
!     else if (cl==&cl_float)
!         *(Float*)addr = arg3;
!     else if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Void	setShort_Os_oT4ZA(Object Harg1, Object Harg2, Short arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.setShort";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_short)
!         *(Short*)addr = arg3;
!     else if (cl==&cl_int)
!         *(Int*)addr = arg3;
!     else if (cl==&cl_long)
!         *(Long*)addr = arg3;
!     else if (cl==&cl_float)
!         *(Float*)addr = arg3;
!     else if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Void	setInt_Oi_bU4yN(Object Harg1, Object Harg2, Int arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.setInt";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_int)
!         *(Int*)addr = arg3;
!     else if (cl==&cl_long)
!         *(Long*)addr = arg3;
!     else if (cl==&cl_float)
!         *(Float*)addr = arg3;
!     else if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Void	setLong_Ol_Dh1xX(Object Harg1, Object Harg2, Long arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.setLong";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_long)
!         *(Long*)addr = arg3;
!     else if (cl==&cl_float)
!         *(Float*)addr = arg3;
!     else if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Void	setFloat_Of_PU8h6(Object Harg1, Object Harg2, Float arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.setFloat";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_float)
!         *(Float*)addr = arg3;
!     else if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
! Void	setDouble_Od_m8Svx(Object Harg1, Object Harg2, Double arg3) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
!     Class  cl;
!     void   *addr;
!     char   *errmsg = "Field.setDouble";
! 
!     CheckWriteAccess(Harg1,errmsg);
!     addr = GetFieldAddr(Harg1,Harg2,errmsg);
!     cl = find_class(this->type);
! 
!     if (cl==&cl_double)
!         *(Double*)addr = arg3;
!     else
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
  }
  
--- 1,243 ----
  #include <stddef.h>
  #include <string.h>
+ #include <assert.h>
  
  #include "toba.h"
  #include "java_lang_reflect_Field.h"
  #include "java_lang_Object.h"
  #include "runtime.h"
+ #include "reflect.h"
  #include "classfile_ClassData.h"
  
! static void *
! GetFieldAddr (Object fld,
!               Object obj,
!               char *exceptionMsg)
  {
      struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)fld;
      Class  cl;
  
      cl = find_class(this->clazz);
!     if (FTS_isStaticSlot(this->slot)) {
!         return cl->cvars[FTS_extractStaticSlot(this->slot)].addr;
!     } else {
!         if (!obj) {
! 	    throwNullPointerException(0);
!         }
! 	if (! instanceof(obj,cl,0)) {
! 	    throwIllegalArgumentException(exceptionMsg);
  	}
!         return cl->ivars[this->slot].offset + (char*)obj;
      }
  }
  
! Int
! getModifiers__KljNq (Object Harg1) /* Since JDK1.1 */
  {
      struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1;
      Class  cl;
  
      cl = find_class(this->clazz);
!     if (FTS_isStaticSlot(this->slot)) {
!         return cl->cvars[FTS_extractStaticSlot(this->slot)].access;
!     } else {
          return cl->ivars[this->slot].access;
+     }
  }
  
! Object
! get_O_p04pc(Object fieldObj, Object instObj) /* Since JDK1.1 */
  {
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)fieldObj;
!     Class fcl;
!     void * faddr;
!     
!     fcl = find_class(this->type);
!     faddr = GetFieldAddr (fieldObj, instObj, "object is not an instance of declaring class");
!     if (IS_PRIMITIVE & fcl->flags) {
!         return wrapPrimObject (fcl, faddr);
!     }
!     return * (Object *) faddr;
  }
  
+ #define DefnGetBody(_pt,_jt) \
+     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1; \
+     _jt rv; \
+  \
+     if (! widenConvert (find_class(this->type), \
+                         GetFieldAddr(Harg1,Harg2,"object is not an instance of declaring class"), \
+                         &cl_##_pt, &rv)) { \
+         throwIllegalArgumentException("field type mismatch"); \
+     } \
+     return rv;
  
! Boolean
! getBoolean_O_hRqw8 (Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(boolean,Boolean)
  }
  
! Byte
! getByte_O_9jSSo (Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(byte,Byte)
  }
  
! Char
! getChar_O_EHJj2(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(char,Char)
  }
  
! Short
! getShort_O_AqspT(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(short,Short)
  }
  
! Int
! getInt_O_rBjV8(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(int,Int)
  }
  
! Long
! getLong_O_RJpEW(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(long,Long);
  }
  
! Float
! getFloat_O_pyFZg(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(float,Float);
  }
  
! Double
! getDouble_O_kEBm5(Object Harg1, Object Harg2) /* Since JDK1.1 */
  {
!     DefnGetBody(double,Double);
  }
  
! #undef DefnGetBody
  
! static void
! CheckWriteAccess(Object fld)
! {
!     if (0 != (ACC_FINAL & getModifiers__KljNq(fld))) {
!         throwIllegalAccessException("field is final");
!     }
!     return;
  }
  
  Void	set_OO_Ft0Kq(Object fld, Object obj, Object val) /* Since JDK1.1 */
  {
!     Class valcl;
!     Class fldcl;
!     char  *errmsg = "object is not an instance of declaring class";
!     PrimClassTriple * pct;
  
!     /* Make sure we're allowed to write to this field. */
!     CheckWriteAccess(fld);
  
!     /* Find out what type of data the field holds. */
!     fldcl = find_class(((struct in_java_lang_reflect_Field*)fld)->type);
  
!     /* If the field is primitive and the incoming object is null, we
!      * can't do a type conversion, so throw an error. */
!     if ((IS_PRIMITIVE & fldcl->flags) &&
!         (NULL == val)) {
!         throwNullPointerException(0);
!     }
!     /* Get the class information corresponding to the value; NULL if
!      * there is no value (ends up treating it as an Object) */
!     valcl = NULL;
!     pct = NULL;
!     if (NULL != val) {
!         valcl = find_class (getClass__zh19H (val));
!         pct = getPCTbyObjClass (valcl);
!     }
!     /* If the value to be assigned is a wrapped primitive type, and the
!      * target field has a primitive type, do a widen conversion from the
!      * primitive value to the field. */
!     if ((NULL != pct) && (0 != (IS_PRIMITIVE & fldcl->flags))) {
!         if (widenConvert (PCT_primClass (pct), PCT_objPrimValAddr (pct, val),
!                           fldcl, GetFieldAddr (fld, obj, "object is not an instance of declaring class"))) {
!             return;
!         }
!     } else {
!         /* Not a primitive-to-primitive assignment.  If the field type is not
!          * primitive, and the value is either null or assignable to the field
!          * type, stuff it into place. */
!         if ((! (IS_PRIMITIVE & fldcl->flags)) &&
!             ((NULL == val) ||
!              assignablefrom (fldcl, valcl))) {
!             *(Object*)GetFieldAddr(fld,obj,"object is not an instance of declaring class") = val;
!             return;
!         }
!     }
! 
!     /* Something went wrong---blow chow. */
!     throwIllegalArgumentException("field type mismatch");
  }
  
  
! #define DefnSetBody(_pt,_jt) \
!     struct in_java_lang_reflect_Field *this=(struct in_java_lang_reflect_Field *)Harg1; \
!  \
!     CheckWriteAccess(Harg1); \
!     if (! widenConvert (&cl_##_pt, &arg3, \
!                         find_class(this->type), \
!                         GetFieldAddr(Harg1,Harg2,"object is not an instance of declaring class"))) { \
!         throwIllegalArgumentException("field type mismatch"); \
!     } \
!     return;
! 
! Void
! setBoolean_Oz_3hIAl(Object Harg1, Object Harg2, Boolean arg3) /* Since JDK1.1 */
! {
!     DefnSetBody(boolean,Boolean);
  }
  
  Void	setByte_Ob_NqkQe(Object Harg1, Object Harg2, Byte arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(byte,Byte);
  }
  
! Void
! setChar_Oc_uxTbl(Object Harg1, Object Harg2, Char arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(char,Char);
  }
  
! Void
! setShort_Os_oT4ZA(Object Harg1, Object Harg2, Short arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(short,Short);
  }
  
! Void
! setInt_Oi_bU4yN(Object Harg1, Object Harg2, Int arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(int,Int);
  }
  
! Void
! setLong_Ol_Dh1xX(Object Harg1, Object Harg2, Long arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(long,Long);
  }
  
! Void
! setFloat_Of_PU8h6(Object Harg1, Object Harg2, Float arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(float,Float);
  }
  
! Void
! setDouble_Od_m8Svx(Object Harg1, Object Harg2, Double arg3) /* Since JDK1.1 */
  {
!     DefnSetBody(double,Double);
  }
  
+ #undef DefnSetBody
Index: toba-1.1/runtime/lang_reflect_Method.c
diff -c toba-1.1/runtime/lang_reflect_Method.c:1.1 toba-1.1/runtime/lang_reflect_Method.c:1.5
*** toba-1.1/runtime/lang_reflect_Method.c:1.1	Sat Apr 18 16:30:22 1998
--- toba-1.1/runtime/lang_reflect_Method.c	Thu Nov 19 19:00:59 1998
***************
*** 1,89 ****
  #include <stddef.h>
  #include <string.h>
  #include <stdarg.h>
  
  #include "toba.h"
- #include "runtime.h"
  #include "java_lang_reflect_Method.h"
  
! extern SameAsJavaStr(const Char *name_chars,int name_len,Object jstr);
! 
! Int	getModifiers__3k65b(Object Harg1) /* Since JDK1.1 */
  {
      struct in_java_lang_reflect_Method *this=(struct in_java_lang_reflect_Method *)Harg1;
      Class  cl;
-     int    namelen;
-     struct mt_generic *mtable;
  
-     namelen = ((struct in_java_lang_String*)this->name)->count;
      cl = find_class(this->clazz);
!     if (this->slot<cl->nsmethods && SameAsJavaStr(cl->smethods[this->slot].name_chars,namelen,this->name))
!         return cl->smethods[this->slot].access;
!     else{
!         mtable = ((struct cl_generic*)cl)->M;
! 	return mtable[this->slot].access;
!     }
! }
! 
! static int CountArgs(const Char *sig)
! {
!     const Char *p;
!     int   cnt;
! 
!     for (p=sig+1,cnt=0; *p!=')'; ){
!         if (*p=='L'){
! 	    while (*p++!=';');
! 	    cnt++;
! 	}
! 	else if (*p=='['){
! 	    p++;
! 	}
! 	else{
! 	    p++;
! 	    cnt++;
! 	}
      }
- 
-     return cnt;
  }
  
! Object	invoke_OaO_bCmp7(Object Harg1, Object obj, Object prArray) /* Unimplemented JDK1.1 */
  {
- 
-     unimpl("invoke_OaO_bCmp7");
- 
-   /*
      struct in_java_lang_reflect_Method *this=(struct in_java_lang_reflect_Method *)Harg1;
!     Object *params = ((struct aarray*)prArray)->data;
!     int    nParams = ((struct aarray*)prArray)->length;
!     int    i;
  
!     Class  cl;
!     int    namelen,isStatic;
!     struct mt_generic *m;
!     static char *errmsg="invoke";
! 
!     namelen = ((struct in_java_lang_String*)this->name)->count;
      cl = find_class(this->clazz);
-     if (this->slot<cl->nsmethods && SameAsJavaStr(cl->smethods[this->slot].name_chars,namelen,this->name)){
-         m = cl->smethods+this->slot;
- 	isStatic = 1;
-     }
-     else{
-         mtable = ((struct cl_generic*)cl)->M;
- 	m = mtable+this->slot;
- 	isStatic = 0;
-     }
- 
-     if (!isStatic && !obj)
-         throwNullPointerException(errmsg);
  
!     if (!isStatic && !instanceof(obj,cl,0) || nParams != CountArgs(m->sig_chars))
!         throwMesg(&cl_java_lang_IllegalArgumentException.C,errmsg);
! 
!     for (i=0;i<nParams;i++){
      }
!   */
  }
  
  
--- 1,77 ----
  #include <stddef.h>
  #include <string.h>
  #include <stdarg.h>
+ #include <assert.h>
  
  #include "toba.h"
  #include "java_lang_reflect_Method.h"
+ #include "runtime.h"
+ #include "reflect.h"
  
! Int
! getModifiers__3k65b(Object Harg1) /* Since JDK1.1 */
  {
      struct in_java_lang_reflect_Method *this=(struct in_java_lang_reflect_Method *)Harg1;
      Class  cl;
  
      cl = find_class(this->clazz);
!     if (FTS_isStaticSlot (this->slot)) {
!         return cl->smethods[FTS_extractStaticSlot(this->slot)].access;
!     } else {
! 	return (this->slot + ((struct cl_generic*)cl)->M)->access;
      }
  }
  
! Object
! invoke_OaO_bCmp7(Object Harg1, Object obj, Object prArray)
  {
      struct in_java_lang_reflect_Method *this=(struct in_java_lang_reflect_Method *)Harg1;
!     Object ret;                 /* Value we're returning */
!     Class  cl;                  /* Class of the method to invoke */
!     struct mt_generic *m;       /* Pointer to the data for the method to invoke */
  
!     /* Extract the class data for the reflected method. */
      cl = find_class(this->clazz);
  
!     /* Get a pointer to the method structure we're going to work with. */
!     if (FTS_isStaticSlot(this->slot)) {
!         /* Static method: stick with what the reflection said. */
!         m = cl->smethods + FTS_extractStaticSlot(this->slot);
!     } else {
!         struct mt_generic * mtable; /* Table in which we look things up. */
!         
!         /* Instance method: make sure we have an instance object, and that
!          * it's of a compatible type for the class of this method, then look
!          * up the method based on a name/sig match with the instance's
!          * method table.  We're OK with finding a non-local method. */
!         if (NULL == obj) {
!             throwNullPointerException(0);
!         }
!         if (! instanceof (obj, cl, 0)) {
!             throwIllegalArgumentException("object is not an instance of declaring class");
!         }
! 
!         /* Rest of this is done relative to the class of the object,
!          * not the one stored in the reflection pointer.  I.e., dynamic
!          * lookup allows overriding the method that is actually invoked. */
!         cl = ((struct in_generic *)obj)->class;
!         mtable = ((struct cl_generic*)cl)->M;
!         m = findMethodInTable (mtable + this->slot, mtable, cl->nimethods, JAVA_FALSE); 
      }
! 	
!     assert (2 <= m->sig_len);
!     /* Set the return value by invoking the method on the object with the
!      * appropriate parameters.  The invoker needs to know whether to
!      * return an actual value; does not if the signature indicates the
!      * method has a void return type. */
!     ret = invoke_c (m, obj,
!                     (struct aarray *) this->parameterTypes,
!                     (struct aarray *) prArray,
!                     ! FTS_isStaticSlot(this->slot),
!                     ((')' == m->sig_chars [m->sig_len - 2]) &&
!                      ('V' == m->sig_chars [m->sig_len - 1]))
!                     );
!     return ret;
  }
  
  
Index: toba-1.1/runtime/misc_VM.c
diff -c toba-1.1/runtime/misc_VM.c:1.1 toba-1.1/runtime/misc_VM.c:1.2
*** toba-1.1/runtime/misc_VM.c:1.1	Sat Apr 18 16:30:22 1998
--- toba-1.1/runtime/misc_VM.c	Thu Dec  3 11:55:31 1998
***************
*** 9,18 ****
--- 9,20 ----
  Int	getState__qIvGb(void)
  {
      error_VM();
+     /*NOTREACHED*/
  }
  Boolean	threadsSuspended__gOHyS(void)
  {
      error_VM();
+     /*NOTREACHED*/
  }
  Void	unsuspendThreads__oV8Xl(void)
  {
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.5
*** toba-1.1/runtime/net_PlainDatagramSocketImpl.c:1.2	Wed May  6 14:30:09 1998
--- toba-1.1/runtime/net_PlainDatagramSocketImpl.c	Thu Dec  3 11:55:31 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,48 ----
  #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 <assert.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 = 
***************
*** 19,27 ****
      struct sockaddr_in saddr;
      int res, adlen;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("bind");
  
      memset(&saddr, 0, sizeof(saddr));
      saddr.sin_family = AF_INET;
--- 52,62 ----
      struct sockaddr_in saddr;
      int res, adlen;
  
+     assert (NULL != this);
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
      memset(&saddr, 0, sizeof(saddr));
      saddr.sin_family = AF_INET;
***************
*** 61,67 ****
--- 96,107 ----
      struct sockaddr_in saddr;
      int res;
  
+     assert (NULL != this);
      fd = this->fd;
+     if (NULL == fd) {
+         throwSocketException("Socket closed");
+     }
+ 
      if(!fd || !packet || !packet->buf || !packet->address)
          throwNullPointerException("send");
      addr = (struct in_java_net_InetAddress *)packet->address;
***************
*** 108,113 ****
--- 148,157 ----
          (struct in_java_net_InetAddress *)Harg2;
      int port;
  
+     assert (NULL != this);
+     if (NULL == this->fd) {
+         throwSocketException("Socket closed");
+     }
      /* check who the next packet is from */
      do_recv(this->fd, addr, &port, 0, 0, MSG_PEEK);
      return port;
***************
*** 124,131 ****
      struct barray *buf;
      int res, port;
  
      fd = this->fd;
!     if(!fd || !packet || !packet->buf)
          throwNullPointerException("receive");
      buf = (struct barray *)packet->buf;
  
--- 168,180 ----
      struct barray *buf;
      int res, port;
  
+     assert (NULL != this);
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
! 
!     if(!packet || !packet->buf)
          throwNullPointerException("receive");
      buf = (struct barray *)packet->buf;
  
***************
*** 148,155 ****
      int res;
  
      fd = this->fd;
!     if (!fd)
!         throwNullPointerException("setTTL");
      unixfd = unix_fd(fd->fd);
      ttl = arg2;
      res = setsockopt(unixfd, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));
--- 197,206 ----
      int res;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
! 
      unixfd = unix_fd(fd->fd);
      ttl = arg2;
      res = setsockopt(unixfd, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));
***************
*** 168,175 ****
      int blen;
  
      fd = this->fd;
!     if (!fd)
!         throwNullPointerException("getTTL");
      unixfd = unix_fd(fd->fd);
      blen = sizeof(ttl);
      res = getsockopt(unixfd, IPPROTO_IP, IP_TTL, (char *)&ttl, &blen);
--- 219,228 ----
      int blen;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
! 
      unixfd = unix_fd(fd->fd);
      blen = sizeof(ttl);
      res = getsockopt(unixfd, IPPROTO_IP, IP_TTL, (char *)&ttl, &blen);
***************
*** 189,196 ****
      struct ip_mreq mreq;
  
      fd = this->fd;
!     if (!fd)
!         throwNullPointerException("join");
      unixfd = unix_fd(fd->fd);
      mreq.imr_multiaddr.s_addr = htonl(maddr->address);
      mreq.imr_interface.s_addr = INADDR_ANY;
--- 242,251 ----
      struct ip_mreq mreq;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
! 
      unixfd = unix_fd(fd->fd);
      mreq.imr_multiaddr.s_addr = htonl(maddr->address);
      mreq.imr_interface.s_addr = INADDR_ANY;
***************
*** 210,217 ****
      struct ip_mreq mreq;
  
      fd = this->fd;
!     if (!fd)
!         throwNullPointerException("leave");
      unixfd = unix_fd(fd->fd);
      mreq.imr_multiaddr.s_addr = htonl(maddr->address);
      mreq.imr_interface.s_addr = INADDR_ANY;
--- 265,274 ----
      struct ip_mreq mreq;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
! 
      unixfd = unix_fd(fd->fd);
      mreq.imr_multiaddr.s_addr = htonl(maddr->address);
      mreq.imr_interface.s_addr = INADDR_ANY;
***************
*** 228,235 ****
      int unixfd, reuse;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("datagramSocketCreate");
  
      unixfd = socket(AF_INET, SOCK_DGRAM, 0);
      if(unixfd == -1)
--- 285,293 ----
      int unixfd, reuse;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
      unixfd = socket(AF_INET, SOCK_DGRAM, 0);
      if(unixfd == -1)
***************
*** 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);
      }
  }
  
--- 315,344 ----
      struct in_java_net_InetAddress   *inetaddr;
      int unixfd, ival, ret;
      struct in_addr addr;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
! 
      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);
      }
  }
--- 350,378 ----
      struct sockaddr_in saddr;
      struct in_addr iaddr;
      int unixfd, ret, blen;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
      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);
+     /*NOTREACHED*/
  }
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.7
*** toba-1.1/runtime/net_PlainSocketImpl.c:1.5	Sat Apr 18 16:30:23 1998
--- toba-1.1/runtime/net_PlainSocketImpl.c	Mon Nov 30 11:21:52 1998
***************
*** 1,3 ****
--- 1,47 ----
+ /* $Id: net_PlainSocketImpl.c,v 1.7 1998/11/30 18:21:52 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 ----
***************
*** 26,42 ****
      int unixfd, type, reuse;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("socketCreate");
  
!     if(arg2 == JAVA_TRUE)
          type = SOCK_STREAM;
!     else
          type = SOCK_DGRAM;
  
      unixfd = socket(AF_INET, type, 0);    
!     if(unixfd == -1)
          throwIOException("socket", errno);
  
      reuse = 1;
      setsockopt(unixfd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse));
--- 61,80 ----
      int unixfd, type, reuse;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
!     if (JAVA_TRUE == arg2) {
          type = SOCK_STREAM;
!     } else {
          type = SOCK_DGRAM;
+     }
  
      unixfd = socket(AF_INET, type, 0);    
!     if(0 > unixfd) {
          throwIOException("socket", errno);
+     }
  
      reuse = 1;
      setsockopt(unixfd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse));
***************
*** 56,63 ****
      int res, adlen;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("socketConnect");
  
      set_address(addr, port, &saddr);
      res = connect(unix_fd(fd->fd), (struct sockaddr *)&saddr, sizeof(saddr));
--- 94,102 ----
      int res, adlen;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
      set_address(addr, port, &saddr);
      res = connect(unix_fd(fd->fd), (struct sockaddr *)&saddr, sizeof(saddr));
***************
*** 88,95 ****
      int res;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("socketBind");
      
      set_address(addr, port, &saddr);
      res = bind(unix_fd(fd->fd), (struct sockaddr *)&saddr, sizeof(saddr));
--- 127,135 ----
      int res;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
      
      set_address(addr, port, &saddr);
      res = bind(unix_fd(fd->fd), (struct sockaddr *)&saddr, sizeof(saddr));
***************
*** 107,114 ****
      int res;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("socketListen");
      
      res = listen(unix_fd(fd->fd), count);
      if(res == -1)
--- 147,155 ----
      int res;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
      
      res = listen(unix_fd(fd->fd), count);
      if(res == -1)
***************
*** 128,134 ****
      int adlen, res;
  
      fd = this->fd;
!     if(!fd || !s)
          throwNullPointerException("socketAccept");
      
      adlen = sizeof(saddr);
--- 169,178 ----
      int adlen, res;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
!     if(!s)
          throwNullPointerException("socketAccept");
      
      adlen = sizeof(saddr);
***************
*** 168,175 ****
      int val;
  
      fd = this->fd;
!     if(!fd)
!         throwNullPointerException("socketAvailable");
  
      if(ioctl(unix_fd(fd->fd), FIONREAD, &val) == -1)
          throwIOException("fionread", errno);
--- 212,220 ----
      int val;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
      if(ioctl(unix_fd(fd->fd), FIONREAD, &val) == -1)
          throwIOException("fionread", errno);
***************
*** 198,232 ****
      struct in_java_io_FileDescriptor *fd;
      struct linger l;
      int unixfd,ret;
-     char errmsg[64];
  
      fd = this->fd;
!     if (!fd)
!         throwNullPointerException("socketSetOption");
  
      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);
      }
  }
  
--- 243,276 ----
      struct in_java_io_FileDescriptor *fd;
      struct linger l;
      int unixfd,ret;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
      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);
  }
  
  
--- 282,323 ----
      struct sockaddr_in saddr;
      struct linger l;
      int unixfd,ret,onoff,blen;
  
      fd = this->fd;
!     if (NULL == fd) {
!         throwSocketException("Socket closed");
!     }
  
+     /* 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/net_SocketInputStream.c
diff -c toba-1.1/runtime/net_SocketInputStream.c:1.3 toba-1.1/runtime/net_SocketInputStream.c:1.5
*** toba-1.1/runtime/net_SocketInputStream.c:1.3	Mon Nov 24 11:11:13 1997
--- toba-1.1/runtime/net_SocketInputStream.c	Thu Dec  3 22:17:13 1998
***************
*** 11,18 ****
      struct in_java_net_SocketImpl *impl;
  
      impl = this->impl;
!     if(!impl)
          throwNullPointerException("socketRead");
  
      return fd_read_bytes(impl->fd, b, off, len);
  }
--- 11,22 ----
      struct in_java_net_SocketImpl *impl;
  
      impl = this->impl;
!     if (!impl) {
          throwNullPointerException("socketRead");
+     }
+     if (!impl->fd) {
+         throwSocketException ("Socket closed");
+     }
  
      return fd_read_bytes(impl->fd, b, off, len);
  }
Index: toba-1.1/runtime/net_SocketOutputStream.c
diff -c toba-1.1/runtime/net_SocketOutputStream.c:1.3 toba-1.1/runtime/net_SocketOutputStream.c:1.5
*** toba-1.1/runtime/net_SocketOutputStream.c:1.3	Mon Nov 24 11:11:13 1997
--- toba-1.1/runtime/net_SocketOutputStream.c	Thu Dec  3 22:17:13 1998
***************
*** 11,18 ****
      struct in_java_net_SocketImpl *impl;
  
      impl = (struct in_java_net_SocketImpl *)this->impl;
!     if(!impl)
          throwNullPointerException("socketWrite");
  
      fd_write_bytes(impl->fd, b, off, len);
  }
--- 11,22 ----
      struct in_java_net_SocketImpl *impl;
  
      impl = (struct in_java_net_SocketImpl *)this->impl;
!     if (!impl) {
          throwNullPointerException("socketWrite");
+     }
+     if (!impl->fd) {
+         throwSocketException ("Socket closed");
+     }
  
      fd_write_bytes(impl->fd, b, off, len);
  }
Index: toba-1.1/runtime/reflect.h
diff -c /dev/null toba-1.1/runtime/reflect.h:1.2
*** /dev/null	Thu Dec  3 22:21:44 1998
--- toba-1.1/runtime/reflect.h	Wed Nov 18 12:26:03 1998
***************
*** 0 ****
--- 1,110 ----
+ #ifndef _reflect_h_
+ #define _reflect_h_
+ 
+ /* Support for reflection.  JDK declares a "slot" variable which is supposed
+  * to identify the table slot for field and methods.  They obviously don't
+  * separate static and instance method tables.  We do.  Make sure we
+  * can tell which table we should use for slot lookup.  This is based
+  * on ( (x-y)=z iff (x-z)=y ). */
+ #define FTS_invalidSlot  (-1)
+ #define FTS_isStaticSlot(_v) (FTS_invalidSlot > (_v))
+ #define FTS_buildStaticSlot(_v) (FTS_invalidSlot - 1 - (_v))
+ #define FTS_extractStaticSlot(_v) FTS_buildStaticSlot(_v)
+ 
+ /* Find the last method in the table of the given length that matches
+  * the provided method in name and signature.  If needLocal is true,
+  * we further require that a match have the localp flag set.  Returns
+  * a pointer to the match, or NULL if there is none. */
+ struct mt_generic *
+ findMethodInTable (struct mt_generic * m, /* Method we're trying to match */
+                    struct mt_generic * mtable, /* Array of method structures to compare with */
+                    int nmtb,    /* Number of entries in mtable */
+                    int needLocal); /* Do we insist that the match have localp set? */
+ 
+ /* Structure to help map between primitive types and the object types
+  * that encode them for reflective invocation and other purposes. */
+ typedef struct PrimClassTriple {
+     char *name;                 /* Name of the primitive type */
+     int sigChar;                /* Character used to represent type in signatures */
+     Class primClass;            /* Class for primitive type */
+     Class objClass;             /* Class for object type */
+     size_t primSize;            /* Size of primitive type */
+     size_t objValOfs;           /* Offset in object instance of primitive value field */
+ } PrimClassTriple;
+ #define PCT_name(_pv) ((_pv)->name)
+ #define PCT_sigChar(_pv) ((_pv)->sigChar)
+ #define PCT_primClass(_pv) ((_pv)->primClass)
+ #define PCT_primClassClass(_pv) (&((_pv)->primClass)->classclass)
+ #define PCT_objClass(_pv) ((_pv)->objClass)
+ #define PCT_primSize(_pv) ((_pv)->primSize)
+ #define PCT_objPrimValAddr(_pv,_oi) ((void *)((char *)(_oi) + (_pv)->objValOfs))
+ 
+ /* A data region that can hold a value of any Java type, primitive or
+  * object.  Index using the signature character that identifies that
+  * type. */
+ typedef union
+ AnyJavaValue {
+     Boolean Z;
+     Byte B;
+     Char C;
+     Short S;
+     Int I;
+     Long J;
+     Float F;
+     Double D;
+     Object L;
+ } AnyJavaValue;
+ 
+ /* Given: a generic pointer to a primitive value and the Class
+  * corresponding to the (primitive or wrapper) type of that value, create a
+  * new instance of the corresponding wrapper class and copy the value into
+  * it.  Returns NULL iff the provided class has no primitive
+  * correspondent. */
+ Object
+ wrapPrimObject (Class primClass, /* Class denoting value; e.g. &cl_int */
+                 void * vaddr);
+ 
+ /* Given types and pointers-to-values for source and destination, assign the
+  * source to the destination through any widening conversion that is necessary.
+  * The types can be either the primitive type or the corresponding wrapper type.
+  * Iff either type is not a primitive type, or there is no valid widening
+  * conversion from the source to destination type, the function returns 0. */
+ int
+ widenConvert (Class stype,      /* Source type */
+               void * svp,       /* Pointer to primitive value in source type */
+               Class dtype,      /* Destination type */
+               void * dvp);      /* Pointer to storage for primitive value in destination type */
+ 
+ /* Look up class information given a pointer to the internal structure
+  * for the primitive class; e.g. &cl_boolean.  Returns NULL if the
+  * provided class isn't primitive. */
+ PrimClassTriple *
+ getPCTbyPrimClass (Class primcl);
+ 
+ /* Look up class information given the character by which the type is
+  * represented in signatures; e.g. 'Z'.  Returns NULL if the provided char
+  * doesn't represent a primitive type. */
+ PrimClassTriple *
+ getPCTbySigChar (int sch);
+ 
+ /* Look up class information given the java language level name of
+  * the type; e.g., boolean.  Returns NULL if the name doesn't
+  * name a primitive type. */
+ PrimClassTriple *
+ getPCTbyName (char *name);
+ 
+ /* Look up class information given a pointer to the internal structure
+  * for the object class; e.g. java.lang.Boolean.  Returns NULL if the
+  * provided class doesn't have a primitive analogue. */
+ PrimClassTriple *
+ getPCTbyObjClass (Class objcl);
+ 
+ Object
+ invoke_c (struct mt_generic *m,
+         Object iobj,
+         struct aarray *expectedArgs,
+         struct aarray *givenArgs,
+         Boolean isInstance,
+         Boolean useVoid);
+ 
+ #endif /* _reflect_h_ */
Index: toba-1.1/runtime/runtime.c
diff -c toba-1.1/runtime/runtime.c:1.20 toba-1.1/runtime/runtime.c:1.21
*** toba-1.1/runtime/runtime.c:1.20	Tue May 12 10:11:29 1998
--- toba-1.1/runtime/runtime.c	Thu Dec  3 11:55:31 1998
***************
*** 282,288 ****
      s = clg->M.toString__4d9OF.f(o);
      /* If this is a null pointer exception, and we know where it may have
       * been thrown, say so. */
!     if ((&cl_java_lang_NullPointerException == (void *) clg) &&
          (NULL != npe_file_name)) {
         fprintf(stderr,"\nuncaught exception: %s (maybe at %s/%d)\n", cstring(s),
                 npe_file_name, npe_file_line);
--- 282,288 ----
      s = clg->M.toString__4d9OF.f(o);
      /* If this is a null pointer exception, and we know where it may have
       * been thrown, say so. */
!     if ((((void *) &cl_java_lang_NullPointerException) == (void *) clg) &&
          (NULL != npe_file_name)) {
         fprintf(stderr,"\nuncaught exception: %s (maybe at %s/%d)\n", cstring(s),
                 npe_file_name, npe_file_line);
Index: toba-1.1/runtime/runtime.h
diff -c toba-1.1/runtime/runtime.h:1.22 toba-1.1/runtime/runtime.h:1.27
*** toba-1.1/runtime/runtime.h:1.22	Thu Jul 30 16:51:41 1998
--- toba-1.1/runtime/runtime.h	Thu Dec  3 19:11:53 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.1b"	/* 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. */
***************
*** 208,213 ****
--- 208,214 ----
  void throwFileNotFoundException(char *mesg, int xerrno);
  void throwIOException(char *mesg, int xerrno);
  void throwIllegalAccessException(char *mesg);
+ void throwIllegalArgumentException(char *mesg);
  void throwIncompatibleClassChangeError(Object o);
  void throwIndexOutOfBoundsException(char *mesg);
  void throwInstantiationException(Object o);
***************
*** 217,222 ****
--- 218,224 ----
  void throwNumberFormatException(char *mesg);
  void throwOutOfMemoryError(int nbytes);
  void throwUnknownHostException(char *mesg);
+ void throwSocketException(char *mesg);
  
  #endif /* _runtime_h_ */
  
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.14
*** toba-1.1/runtime/runtime_ClassRT.c:1.9	Tue May 12 08:27:03 1998
--- toba-1.1/runtime/runtime_ClassRT.c	Fri Nov 20 08:55:00 1998
***************
*** 1,5 ****
--- 1,7 ----
  /* Native routines to allow Java code to manipulate classes */
+ #include <stdio.h>
  #include <stddef.h>
+ #include <assert.h>
  
  #include "toba.h"
  
***************
*** 9,14 ****
--- 11,17 ----
  
  #include "toba_runtime_ClassRT.h"
  #include "toba_classfile_ClassData.h"
+ #include "toba_classfile_ClassRef.h"
  #include "toba_classfile_Field.h"
  #include "toba_classfile_Names.h"
  #include "toba_classfile_Method.h"
***************
*** 424,430 ****
--- 427,568 ----
      return;
  }
  
+ static void
+ setMTGenericData (struct mt_generic * mtp,
+                   struct in_toba_classfile_Field * f,
+                   long addr,
+                   Class cl)
+ {
+     static Class nullTermPtrList [] = { NULL };
+ 
+     mtp->itype = TMIT_native_code;
+     mtp->f = longToAddress(addr);
+     setCharLen (f->name, &mtp->name_chars, &mtp->name_len);
+     setCharLen (f->signature, &mtp->sig_chars, &mtp->sig_len);
+     /* Field is local iff it's in the array of classdata fields.
+      * We should have assigned the cldata pointer when we built this
+      * native class structure. */
+     if (NULL == cl->cldata) {
+         throwInternalError ("Class definition: missing ClassData structure");
+     }
+     mtp->localp = isInArray_aF_ppXbl (f, cl->cldata->methods);
+     mtp->access = f->access;
+     /* Default exception list: we'll fill it in with real stuff later,
+      * after we're sure the ClassRefs are resolved. */
+     mtp->xlist = nullTermPtrList;
+     return;
+ }
+ 
+ static void
+ setMTExceptList (struct mt_generic * mtp,
+                  struct in_toba_classfile_Field * f,
+                  Class cl)
+ {
+     struct in_toba_classfile_Method * md;
+     struct aarray * exlist;
+ 
+     md = f->tableObj;
+     if (NULL == md) {
+         Class scl;
+         struct mt_generic * scm;
+         struct mt_generic * imt;
+         struct mt_generic * simt;
+         
+         /* If there's no data, we must have inherited this method.
+          * Go to our superclass and use the xlist value in it's field. */
+         if (1 >= cl->nsupers) {
+             throwInternalError ("No method data for %s%s in base class %s\n",
+                                 cstring (f->name), cstring (f->signature), cstring (cl->name));
+         }
+         scl = cl->supers [0];
+         imt = ((struct cl_generic *)cl)->M;
+         simt = ((struct cl_generic *)scl)->M;
+         if ((imt <= mtp) &&
+             (mtp < (imt + cl->nimethods))) {
+             assert ((0 <= f->tableslot) && (f->tableslot < scl->nimethods));
+             assert ((mtp - imt) == f->tableslot);
+             scm = simt + f->tableslot;
+         } else {
+             assert ((cl->smethods <= mtp) &&
+                     (mtp < (cl->smethods + cl->nsmethods)));
+             assert ((0 <= f->tableslot) && (f->tableslot < scl->nsmethods));
+             assert ((mtp - cl->smethods) == f->tableslot);
+             scm = scl->smethods + f->tableslot;
+         }
+         assert (NULL != scm->xlist);
+         mtp->xlist = scm->xlist;
+     } else {
+         exlist = md->exthrown;
+         if (0 < exlist->length) {
+             Class * clp;
+             int i;
+         
+             /* exlist is a list of ClassRef instances which point to the
+              * jlClass structures for exceptions thrown by this method.
+              * The ClassRef values should have been resolved, resulting
+              * in a C class structure allocation, when the constant table
+              * for this method was walked.  Therefore, each of the ClassRef
+              * objects should have a valid refClass field.  We want to
+              * use those to create a null-terminated list of pointers
+              * to the C structures naming the exceptions that can be
+              * thrown. */
+ 
+             clp = mtp->xlist = allocate ((1 + exlist->length) * sizeof (Class));
+             i = 0;
+             while (i < exlist->length) {
+                 struct in_toba_classfile_ClassRef * crp;
+                 struct in_java_lang_Class * jcp;
+ 
+                 crp = exlist->data [i];
+                 if (NULL == crp) {
+                     throwInternalError ("Method exception list includes null class ref.");
+                 }
+                 jcp = crp->refClass;
+                 if (NULL == jcp) {
+                     throwInternalError ("Exception ClassRef is unresolved.");
+                 }
+                 *clp = find_class (jcp);
+                 ++i;
+                 ++clp;
+             }
+             *clp = NULL;
+         }
+     }
+ }
+ 
+ /* The generic method structures include a list of classes corresponding
+  * to exceptions that might be thrown by the method.  At the time the native
+  * class was built, the references to the exception classes may not have
+  * been resolved, so we need to come back later and fix them up. */
+ Void
+ updateMethodExceptionLi_C_qZkYU (Object arg1)
+ {
+     struct in_toba_classfile_ClassData *cd;
+     struct in_java_lang_Class *jcl;
+     Class cl;
+     struct mt_generic *mtable;
+     struct aarray * flist;
+     int i;
+ 
+     cd = arg1;
+     jcl = cd->javaClass;
+     cl = find_class (jcl);
+ 
+     mtable = (struct mt_generic *)((char *)cl + methodTableOffset());
+     flist = cd->imtable;
+     for (i = 0; i < cl->nimethods; i++) {
+         setMTExceptList (mtable + i, flist->data [i], cl);
+     }
+     
+     mtable = cl->smethods;
+     flist = cd->smtable;
+     for (i = 0; i < cl->nsmethods; i++) {
+         setMTExceptList (mtable + i, flist->data [i], cl);
+     }
  
+     return;
+ }
+                   
  Void setInstanceMethods_CaFal_C8R2B(Object arg1, Object arg2, Object arg3)
  {
      struct in_java_lang_Class *inst = arg1;
***************
*** 436,457 ****
  	(struct mt_generic *)((char *)cl + methodTableOffset());
      
      for (i = 0; i < methods->length; i++) {
! 	struct in_toba_classfile_Field *f = methods->data[i];
! 	struct mt_generic * mtp;
! 	
! 	mtp = mtable + i;
! 	mtp->itype = TMIT_native_code;
! 	mtp->f = longToAddress(addresses->data[i]);
!         setCharLen (f->name, &mtp->name_chars, &mtp->name_len);
!         setCharLen (f->signature, &mtp->sig_chars, &mtp->sig_len);
! 	/* Field is local iff it's in the array of classdata fields.
! 	 * We should have assigned the cldata pointer when we built this
! 	 * native class structure. */
! 	if (NULL == cl->cldata) {
! 	   throwInternalError ("Class definition: missing ClassData structure");
! 	}
! 	mtp->localp = isInArray_aF_ppXbl (f, cl->cldata->fields);
! 	mtp->access = f->access;
      }
      return;
  }
--- 574,580 ----
  	(struct mt_generic *)((char *)cl + methodTableOffset());
      
      for (i = 0; i < methods->length; i++) {
!         setMTGenericData (mtable + i, methods->data [i], addresses->data[i], cl);
      }
      return;
  }
***************
*** 468,489 ****
      stable = allocate(sizeof(struct mt_generic) * methods->length);
      
      for (i = 0; i < methods->length; i++) {
! 	struct in_toba_classfile_Field *f = methods->data[i];
! 	struct mt_generic * stp;
! 	
! 	stp = stable + i;
! 	stp->itype = TMIT_native_code;
! 	stp->f = longToAddress(addresses->data[i]);
!         setCharLen (f->name, &stp->name_chars, &stp->name_len);
!         setCharLen (f->signature, &stp->sig_chars, &stp->sig_len);
! 	/* Field is local iff it's in the array of classdata fields.
! 	 * We should have assigned the cldata pointer when we built this
! 	 * native class structure. */
! 	if (NULL == cl->cldata) {
! 	   throwInternalError ("Class definition: missing ClassData structure");
! 	}
! 	stp->localp = isInArray_aF_ppXbl (f, cl->cldata->fields);
! 	stp->access = f->access;
      }
  
      cl->smethods = stable;
--- 591,597 ----
      stable = allocate(sizeof(struct mt_generic) * methods->length);
      
      for (i = 0; i < methods->length; i++) {
!         setMTGenericData (stable + i, methods->data [i], addresses->data[i], cl);
      }
  
      cl->smethods = stable;
***************
*** 539,546 ****
  
      initclass(&cl_toba_runtime_ClassRT.C);
  
      if (0 == cl->ivars) {
! 	/* XXX */;
      }
  
      return cl->ivars[index].offset;
--- 647,657 ----
  
      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);
--- 665,675 ----
  
      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);
      }
--- 692,706 ----
      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/runtime/structs.c
diff -c toba-1.1/runtime/structs.c:1.9 toba-1.1/runtime/structs.c:1.10
*** toba-1.1/runtime/structs.c:1.9	Sat Apr 18 16:30:24 1998
--- toba-1.1/runtime/structs.c	Wed Nov 18 12:27:37 1998
***************
*** 69,75 ****
  #define CLASS(type,elemsize) \
  struct class cl_##type = { 0, IS_PRIMITIVE, &s_##type, \
      { &cl_java_lang_Class.C, 0 }, elemsize, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!     0, 0, 0, 0, &acl_##type.C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; \
  struct cl_java_lang_Object acl_##type = { 0, IS_ARRAY, &s_a##type, \
      { &cl_java_lang_Class.C, 0 }, elemsize, 0, 0, 0, 0, 1, &objptr, 0, 0, 0, \
      0, 0, 0, 0, 0, &cl_##type, 0, 0, 0, OBJ_INIT, OBJ_FINI, 0, 0, 0, 0, 0 };
--- 69,77 ----
  #define CLASS(type,elemsize) \
  struct class cl_##type = { 0, IS_PRIMITIVE, &s_##type, \
      { &cl_java_lang_Class.C, 0 }, elemsize, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!     0, 0, 0, 0, &acl_##type.C, 0, 0, 0, \
!     0, 0, 0, 0, \
!     0, 0, 0, 0 }; \
  struct cl_java_lang_Object acl_##type = { 0, IS_ARRAY, &s_a##type, \
      { &cl_java_lang_Class.C, 0 }, elemsize, 0, 0, 0, 0, 1, &objptr, 0, 0, 0, \
      0, 0, 0, 0, 0, &cl_##type, 0, 0, 0, OBJ_INIT, OBJ_FINI, 0, 0, 0, 0, 0 };
***************
*** 92,97 ****
--- 94,125 ----
  
  void initstructs(void)
  {
+     static struct cl_java_lang_Object * aob [] = {
+         &acl_boolean,
+         &acl_byte,
+         &acl_char,
+         &acl_short,
+         &acl_int,
+         &acl_long,
+         &acl_float,
+         &acl_double,
+         NULL
+     };
+     static Class pcl [] = {
+         &cl_boolean,
+         &cl_byte,
+         &cl_char,
+         &cl_short,
+         &cl_int,
+         &cl_long,
+         &cl_float,
+         &cl_double,
+         &cl_void,
+         NULL
+     };
+     Class * clp;
+     struct cl_java_lang_Object ** obp;
+ 
      /* sanity checks */
      assert(sizeof(Boolean) == 1);
      assert(sizeof(Char) == 2);
***************
*** 109,181 ****
             offsetof(struct iarray,data[0]) == offsetof(struct larray,data[0]) &&
             offsetof(struct larray,data[0]) == offsetof(struct sarray,data[0]));
      
-     memcpy(&acl_boolean.M, &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_char.M,    &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_byte.M,    &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_short.M,   &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_int.M,     &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_long.M,    &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_float.M,   &OBJ_METHODS, sizeof(OBJ_METHODS));
-     memcpy(&acl_double.M,  &OBJ_METHODS, sizeof(OBJ_METHODS));
- 
-     acl_boolean.C.nimethods = cl_java_lang_Object.C.nimethods;
-     acl_char.C.nimethods    = cl_java_lang_Object.C.nimethods;
-     acl_byte.C.nimethods    = cl_java_lang_Object.C.nimethods;
-     acl_short.C.nimethods   = cl_java_lang_Object.C.nimethods;
-     acl_int.C.nimethods     = cl_java_lang_Object.C.nimethods;
-     acl_long.C.nimethods    = cl_java_lang_Object.C.nimethods;
-     acl_float.C.nimethods   = cl_java_lang_Object.C.nimethods;
-     acl_double.C.nimethods  = cl_java_lang_Object.C.nimethods;
- 
-     acl_boolean.C.nsmethods = cl_java_lang_Object.C.nsmethods;
-     acl_boolean.C.smethods  = cl_java_lang_Object.C.smethods;
-     acl_char.C.nsmethods    = cl_java_lang_Object.C.nsmethods;
-     acl_char.C.smethods     = cl_java_lang_Object.C.smethods;
-     acl_byte.C.nsmethods    = cl_java_lang_Object.C.nsmethods;
-     acl_byte.C.smethods     = cl_java_lang_Object.C.smethods;
-     acl_short.C.nsmethods   = cl_java_lang_Object.C.nsmethods;
-     acl_short.C.smethods    = cl_java_lang_Object.C.smethods;
-     acl_int.C.nsmethods     = cl_java_lang_Object.C.nsmethods;
-     acl_int.C.smethods      = cl_java_lang_Object.C.smethods;
-     acl_long.C.nsmethods    = cl_java_lang_Object.C.nsmethods;
-     acl_long.C.smethods     = cl_java_lang_Object.C.smethods;
-     acl_float.C.nsmethods   = cl_java_lang_Object.C.nsmethods;
-     acl_float.C.smethods    = cl_java_lang_Object.C.smethods;
-     acl_double.C.nsmethods  = cl_java_lang_Object.C.nsmethods;
-     acl_double.C.smethods   = cl_java_lang_Object.C.smethods;
- 
-     acl_boolean.C.nivars    = cl_java_lang_Object.C.nivars;
-     acl_boolean.C.ivars     = cl_java_lang_Object.C.ivars;
-     acl_char.C.nivars       = cl_java_lang_Object.C.nivars;
-     acl_char.C.ivars        = cl_java_lang_Object.C.ivars;
-     acl_byte.C.nivars       = cl_java_lang_Object.C.nivars;
-     acl_byte.C.ivars        = cl_java_lang_Object.C.ivars;
-     acl_short.C.nivars      = cl_java_lang_Object.C.nivars;
-     acl_short.C.ivars       = cl_java_lang_Object.C.ivars;
-     acl_int.C.nivars        = cl_java_lang_Object.C.nivars;
-     acl_int.C.ivars         = cl_java_lang_Object.C.ivars;
-     acl_long.C.nivars       = cl_java_lang_Object.C.nivars;
-     acl_long.C.ivars        = cl_java_lang_Object.C.ivars;
-     acl_float.C.nivars      = cl_java_lang_Object.C.nivars;
-     acl_float.C.ivars       = cl_java_lang_Object.C.ivars;
-     acl_double.C.nivars     = cl_java_lang_Object.C.nivars;
-     acl_double.C.ivars      = cl_java_lang_Object.C.ivars;
- 
-     acl_boolean.C.ncvars    = cl_java_lang_Object.C.ncvars;
-     acl_boolean.C.cvars     = cl_java_lang_Object.C.cvars;
-     acl_char.C.ncvars       = cl_java_lang_Object.C.ncvars;
-     acl_char.C.cvars        = cl_java_lang_Object.C.cvars;
-     acl_byte.C.ncvars       = cl_java_lang_Object.C.ncvars;
-     acl_byte.C.cvars        = cl_java_lang_Object.C.cvars;
-     acl_short.C.ncvars      = cl_java_lang_Object.C.ncvars;
-     acl_short.C.cvars       = cl_java_lang_Object.C.cvars;
-     acl_int.C.ncvars        = cl_java_lang_Object.C.ncvars;
-     acl_int.C.cvars         = cl_java_lang_Object.C.cvars;
-     acl_long.C.ncvars       = cl_java_lang_Object.C.ncvars;
-     acl_long.C.cvars        = cl_java_lang_Object.C.cvars;
-     acl_float.C.ncvars      = cl_java_lang_Object.C.ncvars;
-     acl_float.C.cvars       = cl_java_lang_Object.C.cvars;
-     acl_double.C.ncvars     = cl_java_lang_Object.C.ncvars;
-     acl_double.C.cvars      = cl_java_lang_Object.C.cvars;
  
  }
--- 137,165 ----
             offsetof(struct iarray,data[0]) == offsetof(struct larray,data[0]) &&
             offsetof(struct larray,data[0]) == offsetof(struct sarray,data[0]));
      
  
+     obp = aob;
+     while (NULL != *obp) {
+         struct cl_java_lang_Object * ob;
+ 
+         ob = *obp;
+         ++obp;
+         memcpy (&ob->M, &OBJ_METHODS, sizeof (OBJ_METHODS));
+         ob->C.nimethods = cl_java_lang_Object.C.nimethods;
+         ob->C.nsmethods = cl_java_lang_Object.C.nsmethods;
+         ob->C.smethods = cl_java_lang_Object.C.smethods;
+         ob->C.nivars = cl_java_lang_Object.C.nivars;
+         ob->C.ivars = cl_java_lang_Object.C.ivars;
+         ob->C.ncvars = cl_java_lang_Object.C.ncvars;
+         ob->C.cvars = cl_java_lang_Object.C.cvars;
+     }
+ 
+     clp = pcl;
+     while (NULL != *clp) {
+         Class cl;
+ 
+         cl = *clp;
+         ++clp;
+         cl->constructor = cl->finalizer = throwInstantiationException;
+     }
  }
Index: toba-1.1/runtime/throw.c
diff -c toba-1.1/runtime/throw.c:1.7 toba-1.1/runtime/throw.c:1.11
*** toba-1.1/runtime/throw.c:1.7	Wed Jan 28 16:27:57 1998
--- toba-1.1/runtime/throw.c	Mon Nov 30 11:21:54 1998
***************
*** 38,49 ****
--- 38,51 ----
  #include "java_lang_ClassCircularityError.h"
  #include "java_lang_ClassNotFoundException.h"
  #include "java_lang_IllegalAccessException.h"
+ #include "java_lang_IllegalArgumentException.h"
  #include "java_lang_InternalError.h"
  #include "java_io_IOException.h"
  #include "java_io_FileNotFoundException.h"
  #include "java_io_InterruptedIOException.h"
  #include "java_io_EOFException.h"
  #include "java_net_UnknownHostException.h"
+ #include "java_net_SocketException.h"
  
  
  /*
***************
*** 116,122 ****
  
  void throwNegativeArraySizeException(int size)
  {
!     throwMesg(&cl_java_lang_NegativeArraySizeException.C, "%d", size);
  }
  
  
--- 118,124 ----
  
  void throwNegativeArraySizeException(int size)
  {
!     throwMesg(&cl_java_lang_NegativeArraySizeException.C, 0 /* "%d", size*/);
  }
  
  
***************
*** 227,232 ****
--- 229,241 ----
  void throwInstantiationException(Object o)
  /*ARGSUSED*/
  {
+     if (NULL != o) {
+         Class ocl;
+ 
+         ocl = ((struct in_generic *) o)->class;
+         throwMesg (&cl_java_lang_InstantiationException.C, cstring(ocl->name));
+     }
+ 
      throwMesg(&cl_java_lang_InstantiationException.C, 0);
  }
  
***************
*** 248,253 ****
--- 257,266 ----
      throwMesg(&cl_java_lang_IllegalAccessException.C, mesg);
  }
  
+ void throwIllegalArgumentException(char *mesg)
+ {
+     throwMesg(&cl_java_lang_IllegalArgumentException.C, mesg);
+ }
  
  void throwIncompatibleClassChangeError(Object o)
  /*ARGSUSED*/
***************
*** 263,265 ****
--- 276,284 ----
  {
      throwMesg(&cl_java_lang_Error.C, "exception in initializer");
  }
+ 
+ void throwSocketException(char *mesg)
+ {
+     throwMesg(&cl_java_net_SocketException.C, mesg);
+ }
+ 
Index: toba-1.1/runtime/toba.h
diff -c toba-1.1/runtime/toba.h:1.17 toba-1.1/runtime/toba.h:1.19
*** toba-1.1/runtime/toba.h:1.17	Sat Apr 25 18:19:55 1998
--- toba-1.1/runtime/toba.h	Thu Dec  3 11:55:31 1998
***************
*** 17,26 ****
  
  #include <setjmp.h>	/* used by generated code for try/catch */
  
  #ifdef SCOUT
  /* Scout doesn't define the convenience names that we generate.  Tsk. */
! #define setjmp _setjmp
! #define longjmp _longjmp
  
  /*
   * BIIIIG hack, since both Scout and Toba define Class
--- 17,36 ----
  
  #include <setjmp.h>	/* used by generated code for try/catch */
  
+ /* Let's humor the SGI compiler that doesn't like our fallback
+  * definition of the offsetof macro. */
+ #ifdef __sgi
+ #include <stddef.h>
+ #endif /* sgi */
+ 
  #ifdef SCOUT
  /* Scout doesn't define the convenience names that we generate.  Tsk. */
! #ifndef SIM
! # define setjmp _setjmp
! # define longjmp _longjmp
! #else
! # define main _main
! #endif
  
  /*
   * BIIIIG hack, since both Scout and Toba define Class
Index: toba-1.1/runtime/util_zip_Inflater.c
diff -c toba-1.1/runtime/util_zip_Inflater.c:1.4 toba-1.1/runtime/util_zip_Inflater.c:1.5
*** toba-1.1/runtime/util_zip_Inflater.c:1.4	Tue Jul 28 22:22:01 1998
--- toba-1.1/runtime/util_zip_Inflater.c	Thu Dec  3 11:55:31 1998
***************
*** 66,74 ****
  			  * Return 0 to request data
  			  */
                           return 0;
-     default :
-                          throwMesg(&cl_java_util_zip_DataFormatException.C,"inflate");
      }
  }
  
  Int	sy_getAdler__7GucY(Object Harg1) /* Since JDK1.1 */
--- 66,74 ----
  			  * Return 0 to request data
  			  */
                           return 0;
      }
+     throwMesg(&cl_java_util_zip_DataFormatException.C,"inflate");
+     /*NOTREACHED*/
  }
  
  Int	sy_getAdler__7GucY(Object Harg1) /* Since JDK1.1 */
Index: toba-1.1/test/demo.java
diff -c toba-1.1/test/demo.java:1.1.1.2 toba-1.1/test/demo.java:1.2
*** toba-1.1/test/demo.java:1.1.1.2	Wed Dec 18 17:08:33 1996
--- toba-1.1/test/demo.java	Thu Dec  3 11:55:31 1998
***************
*** 5,10 ****
--- 5,13 ----
  
  class demo {
  
+ int iva;
+ static int sva;
+ 
  public static void main(String a[])
  {
      System.out.println(new Date());
Index: toba-1.1/toba/classfile/ClassRef.java
diff -c toba-1.1/toba/classfile/ClassRef.java:1.3 toba-1.1/toba/classfile/ClassRef.java:1.4
*** toba-1.1/toba/classfile/ClassRef.java:1.3	Mon Nov 24 15:23:50 1997
--- toba-1.1/toba/classfile/ClassRef.java	Thu Nov 19 19:01:28 1998
***************
*** 10,15 ****
--- 10,23 ----
  
      static {
          rccache = new Hashtable ();
+         rccache.put (Void.TYPE, new ClassRef (Void.TYPE));
+         rccache.put (Boolean.TYPE, new ClassRef (Boolean.TYPE));
+         rccache.put (Byte.TYPE, new ClassRef (Byte.TYPE));
+         rccache.put (Character.TYPE, new ClassRef (Character.TYPE));
+         rccache.put (Short.TYPE, new ClassRef (Short.TYPE));
+         rccache.put (Integer.TYPE, new ClassRef (Integer.TYPE));
+         rccache.put (Float.TYPE, new ClassRef (Float.TYPE));
+         rccache.put (Double.TYPE, new ClassRef (Double.TYPE));
      }
  
      /* Use this to register class ref structures created elsewhere, e.g. in
***************
*** 40,56 ****
          return cr;
      }
  
      // The constructor called when parsing class files
      private ClassRef(String s) {
  	name = s;
  	refClass = null;
      }
      
      public boolean isResolved() {
! 	if (refClass == null)
! 	    return false;
! 	else
! 	    return true;
      }
  
      public void resolveTo(Class cl) {
--- 48,109 ----
          return cr;
      }
  
+     /* For this to work, ClassRefs in tobafied source files need to be added
+      * to the cache, else we'll duplicate (for example) interface class
+      * structures when we look them up by name at runtime. */
+     public static ClassRef
+     bySignature (String s)
+     {
+         ClassRef cr;
+         
+         cr = null;
+         switch (s.charAt (0)) {
+             case 'Z':
+                 cr = (ClassRef) rccache.get (Boolean.TYPE);
+                 break;
+             case 'B':
+                 cr = (ClassRef) rccache.get (Byte.TYPE);
+                 break;
+             case 'C':
+                 cr = (ClassRef) rccache.get (Character.TYPE);
+                 break;
+             case 'S':
+                 cr = (ClassRef) rccache.get (Short.TYPE);
+                 break;
+             case 'I':
+                 cr = (ClassRef) rccache.get (Integer.TYPE);
+                 break;
+             case 'J':
+                 cr = (ClassRef) rccache.get (Long.TYPE);
+                 break;
+             case 'F':
+                 cr = (ClassRef) rccache.get (Float.TYPE);
+                 break;
+             case 'D':
+                 cr = (ClassRef) rccache.get (Double.TYPE);
+                 break;
+             case 'L':
+                 cr = byName (s.substring (1, s.length() - 1));
+                 break;
+         }
+         return cr;
+     }
+ 
+ 
      // The constructor called when parsing class files
      private ClassRef(String s) {
  	name = s;
  	refClass = null;
      }
      
+     // The constructor called for installing primitive class refs
+     private ClassRef(Class cl) {
+ 	name = "<" + cl.getName () + ">";
+ 	refClass = cl;
+     }
+     
      public boolean isResolved() {
! 	return (null != refClass);
      }
  
      public void resolveTo(Class cl) {
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 + ")");
      }
  
Index: toba-1.1/toba/jit/Intel86JITCodeGen.java
diff -c toba-1.1/toba/jit/Intel86JITCodeGen.java:1.11 toba-1.1/toba/jit/Intel86JITCodeGen.java:1.12
*** toba-1.1/toba/jit/Intel86JITCodeGen.java:1.11	Mon Jun  1 13:50:37 1998
--- toba-1.1/toba/jit/Intel86JITCodeGen.java	Thu Nov 19 19:03:37 1998
***************
*** 1,5 ****
  /** use just-in-time compilation to generate code for methods
!   * @version $Id: Intel86JITCodeGen.java,v 1.11 1998/06/01 20:50:37 pab Exp $
    */
  
  /* This is part of the Just-In-Time compiler for the Toba system.  NB:
--- 1,5 ----
  /** use just-in-time compilation to generate code for methods
!   * @version $Id: Intel86JITCodeGen.java,v 1.12 1998/11/20 02:03:37 pab Exp $
    */
  
  /* This is part of the Just-In-Time compiler for the Toba system.  NB:
***************
*** 1814,1826 ****
                      ++iv;
                  }
  
                  /* Push the dimension values into the call stack */
                  setCallArgs (i.more[0]);
  
!                 /* Push number of specs that we pushed */
                  code.PUSH (new Immediate (i.more [0]));
  
!                 /* Push number of dimensions below top one */
                  code.PUSH (new Immediate (iv));
  
                  /* Push class ref */
--- 1814,1835 ----
                      ++iv;
                  }
  
+                 /* The underlying vmnewarray function wants the class
+                  * of the ultimate base type; get a reference to that. */
+                 cr = ClassRef.bySignature (cr.name.substring (iv));
+ 
                  /* Push the dimension values into the call stack */
                  setCallArgs (i.more[0]);
  
!                 /* Push number of specs that we pushed: ndim */
                  code.PUSH (new Immediate (i.more [0]));
  
!                 /* Push the rank of the array we're going to create.
!                  * Note that we're passing the ultimate element class
!                  * so the arraydim incorporates any dimensions that
!                  * were present in the base class the user wanted to
!                  * add ndim levels above.  Make sense?  Look at
!                  * alloc.c/vmnewarray for details. */
                  code.PUSH (new Immediate (iv));
  
                  /* Push class ref */
Index: toba-1.1/toba/jit/SPARCJITCodeGen.java
diff -c toba-1.1/toba/jit/SPARCJITCodeGen.java:1.5 toba-1.1/toba/jit/SPARCJITCodeGen.java:1.6
*** toba-1.1/toba/jit/SPARCJITCodeGen.java:1.5	Sat Apr 18 16:30:29 1998
--- toba-1.1/toba/jit/SPARCJITCodeGen.java	Thu Nov 19 19:03:38 1998
***************
*** 1,5 ****
  /** use just-in-time compilation to generate code for methods
!   * @version $Id: SPARCJITCodeGen.java,v 1.5 1998/04/18 23:30:29 pab Exp $
    */
  
  /* This is part of the Just-In-Time compiler for the Toba system. */
--- 1,5 ----
  /** use just-in-time compilation to generate code for methods
!   * @version $Id: SPARCJITCodeGen.java,v 1.6 1998/11/20 02:03:38 pab Exp $
    */
  
  /* This is part of the Just-In-Time compiler for the Toba system. */
***************
*** 1668,1673 ****
--- 1668,1677 ----
                      ++iv;
                  }
  
+                 /* The underlying vmnewarray function wants the class
+                  * of the ultimate base type; get a reference to that. */
+                 cr = ClassRef.bySignature (cr.name.substring (iv));
+ 
                  /* This is ugly: we have to call a varargs function.  So
                   * push the first, fixed args onto the stack, load them
                   * with our nice setCallArgs function, then load the rest
***************
*** 1677,1683 ****
                  /* Get a classref for this thing */
                  loadClassPointer (i, cr, 0, "%o7");
                  code.pushES ("%o7");
!                 /* Number of dimensions below top one */
                  code.MOV (iv, "%o7");
                  code.pushES ("%o7");
                  /* Number of dimension specs that follow */
--- 1681,1687 ----
                  /* Get a classref for this thing */
                  loadClassPointer (i, cr, 0, "%o7");
                  code.pushES ("%o7");
!                 /* Number of dimensions to create above element class */
                  code.MOV (iv, "%o7");
                  code.pushES ("%o7");
                  /* Number of dimension specs that follow */
Index: toba-1.1/toba/runtime/ClassRT.java
diff -c toba-1.1/toba/runtime/ClassRT.java:1.6 toba-1.1/toba/runtime/ClassRT.java:1.7
*** toba-1.1/toba/runtime/ClassRT.java:1.6	Tue May 12 08:27:11 1998
--- toba-1.1/toba/runtime/ClassRT.java	Fri Nov 20 08:55:37 1998
***************
*** 113,118 ****
--- 113,119 ----
      static native void setConstructor(Class c, long l);
      static native void setClassInitializer(Class c, long l);
      static native void setFinalizer(Class c, long l);
+     static native void updateMethodExceptionLists(ClassData cd);
  
      /** Return the offset in an instance of a given instance variable.
        * @param c class we're looking at
Index: toba-1.1/toba/runtime/Resolve.java
diff -c toba-1.1/toba/runtime/Resolve.java:1.6 toba-1.1/toba/runtime/Resolve.java:1.7
*** toba-1.1/toba/runtime/Resolve.java:1.6	Tue May 12 08:27:12 1998
--- toba-1.1/toba/runtime/Resolve.java	Fri Nov 20 08:55:37 1998
***************
*** 73,79 ****
  	if (cdata.state == ClassData.RES_CONSTANTS) {
  	    return;
          }
! //System.out.println (tabPrefix + "Resolve.resolveClass " + cdata.name);
  tabPrefix += " ";
  	cdata.state = ClassData.RES_CONSTANTS;
  
--- 73,79 ----
  	if (cdata.state == ClassData.RES_CONSTANTS) {
  	    return;
          }
! // System.out.println (tabPrefix + "Resolve.resolveClass " + cdata.name);
  tabPrefix += " ";
  	cdata.state = ClassData.RES_CONSTANTS;
  
***************
*** 95,131 ****
  	    }
  	}
  
!         if (false) {
! //System.out.println (tabPrefix + "recursive refclass Resolve.resolveClass " + cdata.name);
! 	// Now resolve references in the referenced classes
! 	for (int i = 0; i < cdata.constants.length; i++) {
! 	    Constant k = cdata.constants[i];
! 	    if (k != null && k.tag == Constant.CLASS) {
! 		ClassRef r = (ClassRef)k.value;
! 		Class refclass = r.getRefClass();
! 		ClassLoader refloader = ClassRT.getClassLoader(refclass);
! 		ClassData refdata = ClassRT.getClassData(refclass);
! 		resolveClass(refdata, refloader);
! 	    }
! 	}
! 
! //System.out.println (tabPrefix + "constant methvar Resolve.resolveClass " + cdata.name);
! 	// Resolve Method and Variable references
! 	for (int i = 0; i < cdata.constants.length; i++) {
! 	    Constant k = cdata.constants[i];
! 	    FieldRef r;
! 	    if (k != null) switch(k.tag) {
!                 case Constant.INTERFACE:
!                 case Constant.METHOD:
!                 case Constant.FIELD:
!                     r = (FieldRef)k.value;
!                     if (r.isResolved() == false) {
!                         Class cl = r.cl.getRefClass();
!                         r.resolveWith(ClassRT.getClassData(cl));
!                     }
! 	    }
! 	}
!         }
  
  //System.out.println (tabPrefix + "codegen Resolve.resolveClass " + cdata.name);
          /* We generated code based on entries in the method table; now go
--- 95,105 ----
  	    }
  	}
  
!         /* The methods of this class may have exception lists that included
!          * references to classes we had not yet loaded at the time the
!          * native class structure was built.  Go back and stick the correct
!          * class pointer into the exception lists for all methods. */
!         ClassRT.updateMethodExceptionLists (cdata);
  
  //System.out.println (tabPrefix + "codegen Resolve.resolveClass " + cdata.name);
          /* We generated code based on entries in the method table; now go
Index: toba-1.1/toba/translator/CFile.java
diff -c toba-1.1/toba/translator/CFile.java:1.16 toba-1.1/toba/translator/CFile.java:1.17
*** toba-1.1/toba/translator/CFile.java:1.16	Mon Jul 27 12:24:42 1998
--- toba-1.1/toba/translator/CFile.java	Thu Dec  3 11:55:32 1998
***************
*** 360,366 ****
  		  "," + (localp == 1 ? ("xt_" + f.cname) : "0") + "},");
      }
      if (c.smtable.length == 0)
! 	d.println("    {0}");
      d.println("};");
  }
  
--- 360,366 ----
  		  "," + (localp == 1 ? ("xt_" + f.cname) : "0") + "},");
      }
      if (c.smtable.length == 0)
! 	d.println("    {TMIT_undefined}");
      d.println("};");
  }
  
Index: toba-1.1/toba/translator/MethGen.java
diff -c toba-1.1/toba/translator/MethGen.java:1.6 toba-1.1/toba/translator/MethGen.java:1.7
*** toba-1.1/toba/translator/MethGen.java:1.6	Sat Apr 25 18:21:13 1998
--- toba-1.1/toba/translator/MethGen.java	Thu Dec  3 11:55:32 1998
***************
*** 37,43 ****
  
      // generate list of thrown exceptions
      d.println();
!     d.print("static Class xt_" + f.cname + "[] = { ");
      for (int i = 0; i < m.exthrown.length; i++) {
  	if (i % 3 == 2) 
  	    d.print("\n    ");
--- 37,47 ----
  
      // generate list of thrown exceptions
      d.println();
!     /* We'd like this thing to be static, since nobody else should care
!      * about it, but the Irix C compiler won't let us get away with that
!      * because we had to refer to the thing earlier in the file and it
!      * made us declare it extern beforehand.  See CFile.java. */
!     d.print("Class xt_" + f.cname + "[] = { ");
      for (int i = 0; i < m.exthrown.length; i++) {
  	if (i % 3 == 2) 
  	    d.print("\n    ");
***************
*** 184,189 ****
--- 188,196 ----
  	d.println("\tthrowNullPointerException(0);");
      }
  
+     // To shut up the Irix C compiler, let's make it clear that we don't
+     // actually ever get here. */
+     d.println("\t/*NOTREACHED*/");
      d.println("}");
  }
  

