gt:         int wordOffset = offset + CS.firstVariable;
context: /*
   * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
   * 
   * This code is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2
   * only, as published by the Free Software Foundation.
   * 
   * This code is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License version 2 for more details (a copy is
   * included in the LICENSE file that accompanied this code).
   * 
   * You should have received a copy of the GNU General Public License
   * version 2 along with this work; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA
   * 
   * Please contact Sun Microsystems, Inc., 16 Network Circle, Menlo
   * Park, CA 94025 or visit www.sun.com if you need additional
   * information or have any questions.
   */
  
  package com.sun.squawk;
  
  import com.sun.squawk.debugger.*;
  import com.sun.squawk.debugger.DataType.*;
  import com.sun.squawk.util.*;
  import com.sun.squawk.vm.*;
  
  /**
   * Provides support for the Squawk Debugger Agent {@link com.sun.squawk.debugger.sda.SDA}
   * Some of this is to fit in to package encapsulation.
   */
  public class DebuggerSupport {
  
      /**
       * Return the JDWP.ThreadStatus value for the given thread's internal state.
       *
       * @param vmThread VMThread
       * @return the JDWP.ThreadStatus value
       */
      public static int getThreadJDWPState(VMThread vmThread) {
  /*if[ENABLE_SDA_DEBUGGER]*/
          int combinedState = vmThread.getInternalStatus();
          int inqueue = (combinedState) & 0xFF;
  
          if (vmThread.isAlive()) {
              switch (inqueue) {
                  case VMThread.Q_TIMER:           return JDWP.ThreadStatus_SLEEPING;
                  case VMThread.Q_MONITOR:         return JDWP.ThreadStatus_MONITOR;
                  case VMThread.Q_CONDVAR:
                  case VMThread.Q_ISOLATEJOIN:
                  case VMThread.Q_JOIN:            return JDWP.ThreadStatus_WAIT;
                  case VMThread.Q_NONE:
                  case VMThread.Q_RUN:
                  case VMThread.Q_EVENT:           return JDWP.ThreadStatus_RUNNING;
                  case VMThread.Q_HIBERNATEDRUN:   return JDWP.ThreadStatus_ZOMBIE;
                  default: throw Assert.shouldNotReachHere();
              }
          } else {
              return JDWP.ThreadStatus_ZOMBIE;
          }
  /*else[ENABLE_SDA_DEBUGGER]*/
  //        return JDWP.ThreadStatus_ZOMBIE;
  /*end[ENABLE_SDA_DEBUGGER]*/
  
      }
  
      /**
       * Gets the JNI signature of a klass. This conversion substitutes the
       * appropriate primitive type for the Squawk primitives.
       *
       * @param klass  a class
       * @return the JNI signature for <code>klass</code>
       *
       * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/types.html">JNI Signatures</a>
       */
      public static String getJNISignature(Klass klass) {
          if (klass.isSquawkPrimitive()) {
              return Klass.SQUAWK_64 ? Klass.LONG.getSignature() :
                                       Klass.INT.getSignature();
          }
  
          if (!klass.isArray()) {
              return klass.getSignature();
          }
  
          return "[" + getJNISignature(klass.getComponentType());
      }
  
      /**
       * Gets the JNI signature of a field's type.
       *
       * @param field  a field
       * @return the JNI signature for <code>field</code>
       *
       * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/types.html">JNI Signatures</a>
       */
      public static String getJNISignature(Field field) {
          return getJNISignature(field.getType());
      }
  
      /**
       * Gets the JNI signature of a method's parameters and return type.
       *
       * @param method  a method
       * @return the JNI signature for <code>method</code>
       *
       * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/types.html">JNI Signatures</a>
       */
      public static String getJNISignature(Method method) {
          StringBuffer buf = new StringBuffer("(");
          Klass[] parameters = method.getParameterTypes();
          for (int i = 0; i != parameters.length; ++i) {
              buf.append(getJNISignature(parameters[i]));
          }
          buf.append(')').
              append(getJNISignature(method.getReturnType()));
          return buf.toString();
      }
  
      /**
       * Determines if a given object is in a read-only memory and returns
       * a non-zero identifier for the object if it is. The identifier can be
       * decoded by calling {@link #getROMObjectForID}
       *
       * @param object the object to test
       * @return  a non-zero positive identifier for <code>object</code> if it's in a read-only memory otherwise 0
       */
      public static int getIDForROMObject(Object object) {
          Address address = Address.fromObject(object);
          int id;
          if (VM.inRom(address)) {
              // ROM object IDs are relative to beginning of ROM
              Offset offset = VM.getOffsetInRom(address).bytesToWords();
              id = offset.toInt();
              Assert.that(id > 0);
          } else if (GC.inNvm(address)) {
              // NVM object IDs are relative to beginning of NVM plus the size of ROM
              int romSizeInWords = VM.getRomEnd().diff(VM.getRomStart()).bytesToWords().toInt();
              Offset offset = GC.getOffsetInNvm(address).bytesToWords();
              id = offset.toInt() + romSizeInWords;
          } else {
              id = 0;
          }
          return id;
      }
  
      /**
       * Gets the object in read-only memory corresponding to an identifier that was
       * returned from a call to {@link #getIDForROMObject}.
       *
       * @param id   an identifier for an object in read-only memory (must be positive)
       * @return the object corresponding to <code>id</code>
       */
      public static Object getROMObjectForID(int id) {
          Assert.that(id > 0);
          int romSizeInWords = VM.getRomEnd().diff(VM.getRomStart()).bytesToWords().toInt();
          if (id <= romSizeInWords) {
              Offset offset = Offset.fromPrimitive(id).wordsToBytes();
              return VM.getObjectInRom(offset);
          } else {
              Offset offset = Offset.fromPrimitive(id - romSizeInWords).wordsToBytes();
              return GC.getObjectInNvm(offset);
          }
      }
  
      /**
       * Determines if a given class is initialized in a given isolate.
       *
       * @param klass   the class to test
       * @param isolate the isolate context
       * @return true if <code>klass</code> is intialized in <code>isolate</code>
       */
      public static boolean isInitialized(Klass klass, Isolate isolate) {
          return klass.getState() == Klass.STATE_CONVERTED && (!klass.mustClinit() || isolate.getClassState(klass) != null);
      }
  
      /**
       * Reads a static reference variable.
       *
       * @param isolate  the isolate context to use for variable lookup
       * @param klass  the class of the variable
       * @param offset the offset (in words) to the variable
       * @return the value
       */
      public static Object getStaticOop(Isolate isolate, Klass klass, int offset) {
          int wordOffset = offset + CS.firstVariable;
          Object ks = isolate.getClassState(klass);
          if (ks == null) {
              // Class is not yet initialized
              return null;
          }
          return NativeUnsafe.getObject(ks, wordOffset);
      }
  
      /**
       * Reads a static int variable.
       *
       * @param isolate  the isolate context to use for variable lookup
       * @param klass  the class of the variable
       * @param offset the offset (in words) to the variable
       * @return the value
       */
      public static int getStaticInt(Isolate isolate, Klass klass, int offset) {
          int wordOffset = offset + CS.firstVariable;
          Object ks = isolate.getClassState(klass);
          if (ks == null) {
              // Class is not yet initialized
              return 0;
          }
          return (int) NativeUnsafe.getUWord(ks, wordOffset).toPrimitive();
      }
  
      /**
       * Reads a static long variable.
       *
       * @param isolate  the isolate context to use for variable lookup
       * @param klass  the class of the variable
       * @param offset the offset (in words) to the variable
       * @return the value
       */
      public static long getStaticLong(Isolate isolate, Klass klass, int offset) {
          int wordOffset = offset + CS.firstVariable;
          Object ks = isolate.getClassState(klass);
          if (ks == null) {
              // Class is not yet initialized
              return 0L;
          }
          return NativeUnsafe.getLongAtWord(ks, wordOffset);
      }
  
      /**
       * Writes a static reference variable.
       *
       * @param isolate  the isolate context to use for variable lookup
       * @param klass  the class of the variable
       * @param offset the offset (in words) to the variable
       * @param value
       */
      public static void setStaticOop(Isolate isolate, Klass klass, int offset, Object value) {
          int wordOffset = offset + CS.firstVariable;
          Object ks = isolate.getClassState(klass);
          if (ks == null) {
              // Class is not yet initialized
              return;
          }
          NativeUnsafe.setObject(ks, wordOffset, value);
      }
  
      /**
       * Writes a static int variable.
       *
       * @param isolate  the isolate context to use for variable lookup
       * @param klass  the class of the variable
       * @param offset the offset (in words) to the variable
       * @param value
       */
      public static void setStaticInt(Isolate isolate, Klass klass, int offset, int value) {
          int wordOffset = offset + CS.firstVariable;
          Object ks = isolate.getClassState(klass);
          if (ks == null) {
              // Class is not yet initialized
              return;
          }
          NativeUnsafe.setUWord(ks, wordOffset, UWord.fromPrimitive(value));
      }
  
      /**
       * Writes a static long variable.
       *
       * @param isolate  the isolate context to use for variable lookup
       * @param klass  the class of the variable
       * @param offset the offset (in words) to the variable
       * @param value
       */
      public static void setStaticLong(Isolate isolate, Klass klass, int offset, long value) {
  