System.out.println("X_getfield: ERROR, cannot find class " + declaringClassName + " in the class hierarchy for this object");
  void X_getfield(Object ref) {    int index = byte_codes.fetch2BytesUnsigned();          mapVM mappedObject = (mapVM) ref;    // if (traceInterpreter >= 2)     // System.out.println("X_getfield: constant pool index " + index + " of current class " + getCurrentClass() + ", for mapped object " + mappedObject);    // (1) Compute pointer to the VM_Type, which should be VM_Class since we expect an object    int addr = VM_ObjectModel.getTIB(this,mappedObject.getAddress());    // int addr = JDPObjectModel.getTIBFromPlatform(mappedObject.getAddress());    addr = Platform.readmem(addr);               // System.out.println("X_getfield: candidate object VM_Class @ " + Integer.toHexString(addr));    // (1a) This may not be the right VM_Class because the method may belong to the superclass    // so check the class name and traverse up the class hierarchy if necessary    String declaringClassName = getCurrentClass().getDescriptor().toString();        // This should be an infinite loop, but use a count for now to be sure    for (int i=0; i<20; i++) {        int nameAddr =  Platform.readmem(addr + mapVM.VMClassName_offset);      String realName = mapVM.getVMAtomString(nameAddr);      if (declaringClassName.equals(realName)) {	break;      } else {	addr = Platform.readmem(addr + mapVM.VMClassSuper_offset);	if (addr==0) {	  System.out.println("X_getfield: ERROR, cannot find class " + declaringClassName +			     " in the class hierarchy for this object");	  break;	}      }    }    // System.out.println("X_getfield: actual object VM_Class @ " + Integer.toHexString(addr));    // (2) Compute pointer to the class constant pool array    addr = Platform.readmem(addr + mapVM.VMClassConstantPool_offset);    // System.out.println("X_getfield: class constant pool @ " + Integer.toHexString(addr));    // (3) Read the constant pool entry: get an index to the VM_Field dictionary    addr = Platform.readmem(addr + index*4);    // System.out.println("X_getfield: VM_Field dictionary index " + addr);    // (4) Read the VM_Field dictionary entry: get a VM_field object    addr = Platform.readmem(addr*4 + mapVM.FieldDictionary_values);    // System.out.println("X_getfield: VM_Field @ " + Integer.toHexString(addr));    // (5) Get the offset to the desired field of the mapped object    int mappedFieldOffset = Platform.readmem(addr + mapVM.VMFieldOffset_offset);    // System.out.println("X_getfield: field offset "  + mappedFieldOffset);    // (6) Get the type of the desired field of the mapped object    int mappedFieldTypeAddress = Platform.readmem(addr + mapVM.VMFieldType_offset);    // System.out.println("X_getfield: VM_Type of field @ " + Integer.toHexString(mappedFieldTypeAddress));    // (7) VM_Type object + VM_TypeDescriptor_offset  -> VM_Atom object    int typeAtomAddress = Platform.readmem(mappedFieldTypeAddress + mapVM.VMTypeDescriptor_offset);    // (8) get the type descriptor for this field    String mappedFieldType = mapVM.getVMAtomString(typeAtomAddress);    // System.out.println("X_getfield: field type " + mappedFieldType);    // convert the type string to the VM_ structure in the external world    VM_Atom fieldDescriptor = VM_Atom.findOrCreateAsciiAtom(mappedFieldType);    VM_Type fieldType = VM_ClassLoader.findOrCreateType(fieldDescriptor,VM_SystemClassLoader.getVMClassLoader());        // Decode the field type to decide what to do, we have three cases:    int mappedFieldValue, mappedFieldValue1;    // (1) if it's a reference, create a new mapVM object and put it on the stack    if (fieldType.isClassType()) {      mappedFieldValue = Platform.readmem(mappedObject.getAddress() + mappedFieldOffset);      mapVM newMappedReference = new mapVM(fieldType, mappedFieldValue, mapVM.PointerSize);      stack.push(newMappedReference);      if (traceExtension)		System.out.println("X_getfield: reference @ " + Integer.toHexString(mappedFieldValue));      return;    }     // (2) if it's an array, create a new mapVM object with the right element size and put on stack    if (fieldType.isArrayType()) {      int logsize = fieldType.asArray().getLogElementSize();      int size=1;      for (int i=0; i<logsize; i++)   // do this because we don't have 2^n	size *= 2;      mappedFieldValue = Platform.readmem(mappedObject.getAddress() + mappedFieldOffset);      mapVM newMappedReference = new mapVM(fieldType, mappedFieldValue, size);      stack.push(newMappedReference);      if (traceExtension)	        System.out.println("X_getfield: array @ " + Integer.toHexString(mappedFieldValue));      return;    }    // (3) if it's a primitive value, find its size,     // read the actual value from the JVM memory,     // convert it to the correct type and put it on the stack    // To find the field size, we refer back to the VM_Field in the external side    // System.out.println("X_getfield: primitive at index " + index);    int si = getCurrentClass().getMethodRefId(index);    // constant pool entry    VM_Field ifield = VM_FieldDictionary.getValue(si);   // index into the field dictionary    int size = ifield.getSize();    mapVM newMappedPrimitive = new mapVM(fieldType, 					 mappedObject.getAddress() + mappedFieldOffset,					 size);    try {      stack.pushMappedPrimitiveToStack(newMappedPrimitive);    } catch (Exception e) {      // do we have a problem extracting from the mapped JVM side?      System.out.println("X_getfield: " + e.getMessage());      debug();    }  }