/*
 * Copyright (c) 2004, 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *  
 */

// shorter names for SA packages


// SA package name abbreviations are kept in 'sapkg' object
// to avoid global namespace pollution
var sapkg = new Object();

sapkg.hotspot = Packages.sun.jvm.hotspot;
sapkg.asm = sapkg.hotspot.asm;
sapkg.c1 = sapkg.hotspot.c1;
sapkg.code = sapkg.hotspot.code;
sapkg.compiler = sapkg.hotspot.compiler;

// 'debugger' is a JavaScript keyword, but ES5 relaxes the
// restriction of using keywords as property name
sapkg.debugger = sapkg.hotspot.debugger;

sapkg.interpreter = sapkg.hotspot.interpreter;
sapkg.jdi = sapkg.hotspot.jdi;
sapkg.memory = sapkg.hotspot.memory;
sapkg.oops = sapkg.hotspot.oops;
sapkg.runtime = sapkg.hotspot.runtime;
sapkg.tools = sapkg.hotspot.tools;
sapkg.types = sapkg.hotspot.types;
sapkg.ui = sapkg.hotspot.ui;
sapkg.utilities = sapkg.hotspot.utilities;

// SA singletons are kept in 'sa' object
var sa = new Object();
sa.vm = sapkg.runtime.VM.getVM();
sa.dbg = sa.vm.getDebugger();
sa.cdbg = sa.dbg.CDebugger;
sa.heap = sa.vm.universe.heap();
sa.systemDictionary = sa.vm.systemDictionary;
sa.sysDict = sa.systemDictionary;
sa.symbolTable = sa.vm.symbolTable;
sa.symTbl = sa.symbolTable;
sa.threads = sa.vm.threads;
sa.interpreter = sa.vm.interpreter;
sa.typedb = sa.vm.typeDataBase;
sa.codeCache = sa.vm.codeCache;
// 'objHeap' is different from 'heap'!. 
// This is SA's Oop factory and heap-walker
sa.objHeap = sa.vm.objectHeap;

// few useful global variables
var OS = sa.vm.OS;
var CPU = sa.vm.CPU;
var LP64 = sa.vm.LP64;
var isClient = sa.vm.clientCompiler;
var isServer = sa.vm.serverCompiler;
var isCore = sa.vm.isCore();
var addressSize = sa.vm.addressSize;
var oopSize = sa.vm.oopSize;

// this "main" function is called immediately
// after loading this script file
function main(globals, jvmarg) {
  // wrap a sun.jvm.hotspot.utilities.soql.ScriptObject
  // object so that the properties of it can be accessed
  // in natural object.field syntax.
  function wrapScriptObject(so) {
    function unwrapScriptObject(wso) {
      var objType = typeof(wso);
      if ((objType == 'object' ||
           objType == 'function')
          && "__wrapped__" in wso) {
        return wso.__wrapped__;
      } else {
        return wso;
      }
    }

    function prepareArgsArray(array) {
      var args = new Array(array.length);
      for (var a = 0; a < array.length; a++) {
        var elem = array[a];
        elem = unwrapScriptObject(elem);
        if (typeof(elem) == 'function') {
          args[a] = new sapkg.utilities.soql.Callable() {
            call: function(myargs) {
              var tmp = new Array(myargs.length);
              for (var i = 0; i < myargs.length; i++) {
                tmp[i] = wrapScriptObject(myargs[i]);
              }
              return elem.apply(this, tmp);
            }
          }
        } else {
          args[a] = elem;
        }
      }
      return args;
    }

    // Handle __has__ specially to avoid metacircularity problems
    // when called from __get__.
    // Calling
    //   this.__has__(name)
    // will in turn call
    //   this.__call__('__has__', name)
    // which is not handled below
    function __has__(name) {
      if (typeof(name) == 'number') {
        return so["has(int)"](name);
      } else {
        if (name == '__wrapped__') {
          return true;
        } else if (so["has(java.lang.String)"](name)) {
          return true;
        } else if (name.equals('toString')) {
          return true;
        } else {
          return false;
        }
      }
    }

    if (so instanceof sapkg.utilities.soql.ScriptObject) {
      return new JSAdapter() {
        __getIds__: function() {
          return so.getIds();
        },
  
        __has__ : __has__,
  
        __delete__ : function(name) {
          if (typeof(name) == 'number') {
            return so["delete(int)"](name);
          } else {
            return so["delete(java.lang.String)"](name);
          }
        },
  
        __get__ : function(name) {
	      // don't call this.__has__(name); see comments above function __has__
          if (! __has__.call(this, name)) {
            return undefined;
          }
          if (typeof(name) == 'number') {
            return wrapScriptObject(so["get(int)"](name));
          } else {
            if (name == '__wrapped__') {
              return so;
            } else {
              var value = so["get(java.lang.String)"](name);
              if (value instanceof sapkg.utilities.soql.Callable) {
                return function() {
                  var args = prepareArgsArray(arguments);
                  var r;
                  try {
                    r = value.call(Java.to(args, 'java.lang.Object[]'));
                  } catch (e) {
                    println("call to " + name + " failed!");
                    throw e;
                  }
                  return wrapScriptObject(r);
                }
              } else if (name == 'toString') {
                return function() { 
                  return so.toString();
                }
              } else {
                return wrapScriptObject(value);
              }
            }
          }
        }
      };
    } else {
      return so;
    }
  }

  // set "jvm" global variable that wraps a 
  // sun.jvm.hotspot.utilities.soql.JSJavaVM instance
  if (jvmarg != null) {
    jvm = wrapScriptObject(jvmarg);
    // expose "heap" global variable
    heap = jvm.heap;
  }

  // expose all "function" type properties of
  // sun.jvm.hotspot.utilitites.soql.JSJavaScriptEngine
  // as global functions here.
  globals = wrapScriptObject(globals);
  for (var prop in globals) {    
    if (typeof(globals[prop]) == 'function') {
      this[prop] = globals[prop];
    }    
  }

  // define "writeln" and "write" if not defined
  if (typeof(println) == 'undefined') {
    println = function (str) {
      java.lang.System.out.println(String(str));
    }
  }

  if (typeof(print) == 'undefined') {
    print = function (str) {
      java.lang.System.out.print(String(str));
    }
  }

  if (typeof(writeln) == 'undefined') {
    writeln = println;
  }

  if (typeof(write) == 'undefined') {
    write = print;
  }

  // "registerCommand" function is defined if we
  // are running as part of "CLHSDB" tool. CLHSDB
  // tool exposes Unix-style commands. 

  // if "registerCommand" function is defined
  // then register few global functions as "commands".
  if (typeof(registerCommand) == 'function') {
    this.jclass = function(name) {
      if (typeof(name) == "string") {
         var clazz = sapkg.utilities.SystemDictionaryHelper.findInstanceKlass(name);
         if (clazz) {
             writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString());
         } else {
             writeln("class not found: " + name);
         } 
      } else {
         writeln("Usage: class name");
      }
    }
    registerCommand("class", "class name", "jclass");

    this.jclasses = function() {
      forEachKlass(function (clazz) {
        writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString()); 
      });
    }
    registerCommand("classes", "classes", "jclasses");

    this.dclass = function(clazz, dir) {
      if (!clazz) {
         writeln("Usage: dumpclass { address | name } [ directory ]");
      } else {
         if (!dir) { dir = "."; }
         dumpClass(clazz, dir);
      }
    }
    registerCommand("dumpclass", "dumpclass { address | name } [ directory ]", "dclass");
    registerCommand("dumpheap", "dumpheap [ file ]", "dumpHeap");

    this.jseval = function(str) {
      if (!str) {
         writeln("Usage: jseval script");
      } else {
         var res = eval(str);
         if (res) { writeln(res); }
      }
    }
    registerCommand("jseval", "jseval script", "jseval");

    this.jsload = function(file) {
      if (!file) {
         writeln("Usage: jsload file");
      } else {
         load(file);
      }
    }
    registerCommand("jsload", "jsload file", "jsload");

    this.printMem = function(addr, len) {
      if (!addr) {
         writeln("Usage: mem [ length ]");
      } else {
         mem(addr, len);
      }
    }
    registerCommand("mem", "mem address [ length ]", "printMem");

    this.sysProps = function() {
      for (var i in jvm.sysProps) {
         writeln(i + ' = ' + jvm.sysProps[i]);
      }
    }
    registerCommand("sysprops", "sysprops", "sysProps");

    this.printWhatis = function(addr) {
      if (!addr) {
         writeln("Usage: whatis address");
      } else {
         writeln(whatis(addr));
      }
    }
    registerCommand("whatis", "whatis address", "printWhatis");
  }  
}

// debugger functionality

// string-to-Address
function str2addr(str) {
   return sa.dbg.parseAddress(str);
}

// number-to-Address
if (addressSize == 4) {
   eval("function num2addr(num) { \
            return str2addr('0x' + java.lang.Integer.toHexString(0xffffffff & num)); \
         }");
} else {
   eval("function num2addr(num) { \
            return str2addr('0x' + java.lang.Long.toHexString(num));  \
         }");
}

// generic any-type-to-Address
// use this convenience function to accept address in any
// format -- number, string or an Address instance.
function any2addr(addr) {
   var type = typeof(addr);
   if (type == 'number') {
      return num2addr(addr);
   } else if (type == 'string') {         
      return str2addr(addr);
   } else {
      return addr;
   }
}

// Address-to-string
function addr2str(addr) {
   if (addr == null) {
      return (addressSize == 4)? '0x00000000' : '0x0000000000000000';
   } else {
      return addr + '';
   }
}

// Address-to-number
function addr2num(addr) {
   return sa.dbg.getAddressValue(addr);
}

// symbol-to-Address
function sym2addr(dso, sym) {
   return sa.dbg.lookup(dso, sym);
}

// returns the ClosestSymbol or null
function closestSymbolFor(addr) {
   if (sa.cdbg == null) {
      // no CDebugger support, return null
      return null;
   } else {
      var dso = sa.cdbg.loadObjectContainingPC(addr);
      if (dso != null) {
         return dso.closestSymbolToPC(addr);
      } else {
         return null;
      }
   }
}

// Address-to-symbol
// returns nearest symbol as string if found
// else returns address as string
function addr2sym(addr) {
    var sym = closestSymbolFor(addr);
    if (sym != null)  {
       return sym.name + '+' + sym.offset;
    } else {
       return addr2str(addr);
    }
}

// read 'num' words at 'addr' and return an array as result.
// returns Java long[] type result and not a JavaScript array.
function readWordsAt(addr, num) {
   addr = any2addr(addr);
   var res = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, num);
   var i;
   for (i = 0; i < num; i++) {
      res[i] = addr2num(addr.getAddressAt(i * addressSize));
   }
   return res;
}

// read the 'C' string at 'addr'
function readCStrAt(addr) {
   addr = any2addr(addr);
   return sapkg.utilities.CStringUtilities.getString(addr);
}

// read the length of the 'C' string at 'addr'
function readCStrLen(addr) {
   addr = any2addr(addr);
   return sapkg.utilities.CStringUtilities.getStringLength(addr);
}

// iterate through ThreadList of CDebugger
function forEachThread(callback) {
   if (sa.cdbg == null) {
      // no CDebugger support
      return;
   } else {
      var itr = sa.cdbg.threadList.iterator();
      while (itr.hasNext()) {
         if (callback(itr.next()) == false) return;
      }
   }
}

// read register set of a ThreadProxy as name-value pairs
function readRegs(threadProxy) {
   var ctx = threadProxy.context;
   var num = ctx.numRegisters;
   var res = new Object();
   var i;
   for (i = 0; i < num; i++) {
      res[ctx.getRegisterName(i)]= addr2str(ctx.getRegisterAsAddress(i));
   }
   return res;
}

// print register set for a given ThreaProxy
function regs(threadProxy) {
   var res = readRegs(threadProxy);
   for (i in res) {
      writeln(i, '=', res[i]);
   }
}

// iterate through each CFrame of a given ThreadProxy
function forEachCFrame(threadProxy, callback) {   
   if (sa.cdbg == null) {
      // no CDebugger support
      return;
   } else {
      var cframe = sa.cdbg.topFrameForThread(threadProxy);
      while (cframe != null) {
         if (callback(cframe) == false) return;
         cframe = cframe.sender();
      }
   }
}

// iterate through list of load objects (DLLs, DSOs)
function forEachLoadObject(callback) {
   if (sa.cdbg == null) {
      // no CDebugger support
      return;
   } else {
      var itr = sa.cdbg.loadObjectList.iterator();
      while (itr.hasNext()) {
         if (callback(itr.next()) == false) return;
      }
   }
}

// print 'num' words at 'addr'
function mem(addr, num) {
   if (num == undefined) {
      num = 1;
   }
   addr = any2addr(addr);   
   var i;
   for (i = 0; i < num; i++) {
      var value = addr.getAddressAt(0);      
      writeln(addr2sym(addr) + ':', addr2str(value)); 
      addr = addr.addOffsetTo(addressSize);      
   }
   writeln();
}

// System dictionary functions

// find InstanceKlass by name
function findInstanceKlass(name) {
   return sapkg.utilities.SystemDictionaryHelper.findInstanceKlass(name);
}

// get Java system loader (i.e., application launcher loader)
function systemLoader() {
   return sa.sysDict.javaSystemLoader();
}

// iterate system dictionary for each 'Klass' 
function forEachKlass(callback) {
   var VisitorClass = sapkg.memory.SystemDictionary.ClassVisitor;
   var visitor = new VisitorClass() { visit: callback };
   sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassVisitor)"](visitor);
}

// iterate system dictionary for each 'Klass' and initiating loader
function forEachKlassAndLoader(callback) {
   var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
   var visitor = new VisitorClass() { visit: callback };
   sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassAndLoaderVisitor)"](visitor);
}

// iterate system dictionary for each primitive array klass
function forEachPrimArrayKlass(callback) {
   var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
   sa.sysDict.primArrayClassesDo(new VisitorClass() { visit: callback });
}

// 'oop' to higher-level java object wrapper in which for(i in o) 
// works by iterating java level fields and javaobject.javafield
// syntax works.
function oop2obj(oop) {
   return object(addr2str(oop.handle));
}

// higher level java object wrapper to oop
function obj2oop(obj) {
   return addr2oop(str2addr(address(obj)));
}

// Java heap iteration

// iterates Java heap for each Oop
function forEachOop(callback) {
   function empty() { }
   sa.objHeap.iterate(new sapkg.oops.HeapVisitor() {
       prologue: empty,
       doObj: callback,
       epilogue: empty
   });
}

// iterates Java heap for each Oop of given 'klass'.
// 'includeSubtypes' tells whether to include objects 
// of subtypes of 'klass' or not
function forEachOopOfKlass(callback, klass, includeSubtypes) {
   if (klass == undefined) {
       klass = findInstanceKlass("java.lang.Object");
   }

   if (includeSubtypes == undefined) {
      includeSubtypes = true;
   }

   function empty() { }
   sa.objHeap.iterateObjectsOfKlass(
        new sapkg.oops.HeapVisitor() {
            prologue: empty,
            doObj: callback,
            epilogue: empty
        },
        klass, includeSubtypes);
}

// Java thread

// iterates each Thread
function forEachJavaThread(callback) {
   var threads = sa.threads;
   var thread = threads.first();
   while (thread != null) {
      if (callback(thread) == false) return;
      thread = thread.next();
   }  
}

// iterate Frames of a given thread
function forEachFrame(javaThread, callback) {
   var fr = javaThread.getLastFrameDbg();
   while (fr != null) { 
     if (callback(fr) == false) return;
     fr = fr.sender();
   }
}

// iterate JavaVFrames of a given JavaThread
function forEachVFrame(javaThread, callback) {
   var vfr = javaThread.getLastJavaVFrameDbg();
   while (vfr != null) {
      if (callback(vfr) == false) return;
      vfr = vfr.javaSender();
   }
}

function printStackTrace(javaThread) {
   write("Thread ");
   javaThread.printThreadIDOn(java.lang.System.out);
   writeln();
   forEachVFrame(javaThread, function (vf) {
      var method = vf.method;
      write(' - ', method.externalNameAndSignature(), '@bci =', vf.getBCI());
      var line = method.getLineNumberFromBCI(vf.getBCI());
      if (line != -1) { write(', line=', line); }
      if (vf.isCompiledFrame()) { write(" (Compiled Frame)"); }
      if (vf.isInterpretedFrame()) { write(" (Interpreted Frame)"); }
      writeln();
   });
   writeln();
   writeln();
}

// print Java stack trace for all threads
function where(javaThread) {
   if (javaThread == undefined) {
      forEachJavaThread(function (jt) { printStackTrace(jt); });
   } else {
      printStackTrace(javaThread);
   }
}

// vmStructs access -- type database functions

// find a VM type
function findVMType(typeName) {
   return sa.typedb.lookupType(typeName);
}

// iterate VM types
function forEachVMType(callback) {
   var itr = sa.typedb.types;
   while (itr.hasNext()) {
      if (callback(itr.next()) == false) return;
   }
}

// find VM int constant
function findVMIntConst(name) {
   return sa.typedb.lookupIntConstant(name);
}

// find VM long constant
function findVMLongConst(name) {
   return sa.typedb.lookupLongConstant(name);
}

// iterate VM int constants
function forEachVMIntConst(callback) {
   var itr = sa.typedb.intConstants;
   while (itr.hasNext()) {
      if (callback(itr.next()) == false) return;
   } 
}

// iterate VM long constants
function forEachVMLongConst(callback) {
   var itr = sa.typedb.longConstants;
   while (itr.hasNext()) {
      if (callback(itr.next()) == false) return;
   } 
}

// returns VM Type at address
function vmTypeof(addr) {
   addr = any2addr(addr);
   return sa.typedb.guessTypeForAddress(addr);
}

// does the given 'addr' points to an object of given 'type'?
// OR any valid Type at all (if type is undefined)
function isOfVMType(addr, type) {
   addr = any2addr(addr);
   if (type == undefined) {
      return vmTypeof(addr) != null;
   } else {
      if (typeof(type) == 'string') {
         type = findVMType(type);
      } 
      return sa.typedb.addressTypeIsEqualToType(addr, type);
   }
}

// reads static field value
function readVMStaticField(field) {
   var type = field.type;
   if (type.isCIntegerType() || type.isJavaPrimitiveType()) {
      return field.value;
   } else if (type.isPointerType()) {
      return field.address;
   } else if (type.isOopType()) {
      return field.oopHandle;      
   } else {
      return field.staticFieldAddress;
   }
}

// reads given instance field of VM object at 'addr'
function readVMInstanceField(field, addr) {
   var type = field.type;
   if (type.isCIntegerType() || type.isJavaPrimitiveType()) {
      return field.getValue(addr);
   } else if (type.isPointerType()) {
      return field.getAddress(addr);
   } else if (type.isOopType()) {
      return field.getOopHandle(addr);
   } else {
      return addr.addOffsetTo(field.offset);
   }
}

// returns name-value of pairs of VM type at given address.
// If address is unspecified, reads static fields as name-value pairs.
function readVMType(type, addr) {
   if (typeof(type) == 'string') {
      type = findVMType(type);
   }
   if (addr != undefined) {
      addr = any2addr(addr);
   }

   var result = new Object();
   var staticOnly = (addr == undefined);
   while (type != null) {
      var itr = type.fields;
      while (itr.hasNext()) {
         var field = itr.next();
         var isStatic = field.isStatic();
         if (staticOnly && isStatic) {
            result[field.name] = readVMStaticField(field);
         } else if (!staticOnly && !isStatic) {
            result[field.name] = readVMInstanceField(field, addr);
         }
      }
      type = type.superclass;
   } 
   return result;
}

function printVMType(type, addr) {
   if (typeof(type) == 'string') {
      type = findVMType(type);
   }
   var obj = readVMType(type, addr);
   while (type != null) {
      var itr = type.fields;
      while (itr.hasNext()) {
         var field = itr.next();
         var name = field.name;
         var value = obj[name];
         if (value != undefined) {
            writeln(field.type.name, type.name + '::' + name, '=', value);
         }
      }
      type = type.superclass;  
   }
}

// define readXXX and printXXX functions for each VM struct/class Type
tmp = new Object();
tmp.itr = sa.typedb.types;
while (tmp.itr.hasNext()) {
   tmp.type = tmp.itr.next();
   tmp.name = tmp.type.name;
   if (tmp.type.isPointerType() || tmp.type.isOopType() ||
      tmp.type.isCIntegerType() || tmp.type.isJavaPrimitiveType() ||
      tmp.name.equals('address') ||
      tmp.name.equals("<opaque>")) {
         // ignore;
         continue;
   } else {
      // some type names have ':', '<', '>', '*', ' '. replace to make it as a
      // JavaScript identifier
      tmp.name = ("" + tmp.name).replace(/[:<>* ]/g, '_');
      eval("function read" + tmp.name + "(addr) {" +
           "   return readVMType('" + tmp.name + "', addr);}"); 
      eval("function print" + tmp.name + "(addr) {" + 
           "   printVMType('" + tmp.name + "', addr); }");

      /* FIXME: do we need this?
      if (typeof(registerCommand) != 'undefined') {
          var name = "print" + tmp.name;
          registerCommand(name, name + " [address]", name);
      }
      */
   }
}
//clean-up the temporary
delete tmp;

// VMObject factory

// VM type to SA class map
var  vmType2Class = new Object();

// C2 only classes
try{
  vmType2Class["ExceptionBlob"] = sapkg.code.ExceptionBlob;
  vmType2Class["UncommonTrapBlob"] = sapkg.code.UncommonTrapBlob;
} catch(e) {
  // Ignore exception. C2 specific objects might be not 
  // available in client VM
}


// This is *not* exhaustive. Add more if needed.
// code blobs
vmType2Class["BufferBlob"] = sapkg.code.BufferBlob;
vmType2Class["nmethod"] = sapkg.code.NMethod;
vmType2Class["RuntimeStub"] = sapkg.code.RuntimeStub;
vmType2Class["SafepointBlob"] = sapkg.code.SafepointBlob;
vmType2Class["C2IAdapter"] = sapkg.code.C2IAdapter;
vmType2Class["DeoptimizationBlob"] = sapkg.code.DeoptimizationBlob;
vmType2Class["I2CAdapter"] = sapkg.code.I2CAdapter;
vmType2Class["OSRAdapter"] = sapkg.code.OSRAdapter;
vmType2Class["PCDesc"] = sapkg.code.PCDesc;

// interpreter
vmType2Class["InterpreterCodelet"] = sapkg.interpreter.InterpreterCodelet;

// Java Threads
vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
vmType2Class["SurrogateLockerThread"] = sapkg.runtime.JavaThread;
vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;

// gc
vmType2Class["GenCollectedHeap"] = sapkg.memory.GenCollectedHeap;
vmType2Class["DefNewGeneration"] = sapkg.memory.DefNewGeneration;
vmType2Class["TenuredGeneration"] = sapkg.memory.TenuredGeneration;

// generic VMObject factory for a given address
// This is equivalent to VirtualConstructor.
function newVMObject(addr) {
   addr = any2addr(addr);
   var result = null;
   forEachVMType(function (type) {
                    if (isOfVMType(addr, type)) {
                       var clazz = vmType2Class[type.name];
                       if (clazz != undefined) {
                          result = new clazz(addr);
                       }
                       return false;
                    } else {
                       return true;
                    }
                 });
   return result;
}

function vmobj2addr(vmobj) {
   return vmobj.address;
}

function addr2vmobj(addr) {
   return newVMObject(addr);
}     

// Miscellaneous utilities

// returns PointerLocation that describes the given pointer
function findPtr(addr) {
   addr = any2addr(addr);
   return sapkg.utilities.PointerFinder.find(addr);
}

// is given address a valid Oop?
function isOop(addr) {
   addr = any2addr(addr);
   var oopHandle = addr.addOffsetToAsOopHandle(0);
   return sapkg.utilities.RobustOopDeterminator.oopLooksValid(oopHandle);
}

// returns description of given pointer as a String
function whatis(addr) {
   addr = any2addr(addr);
   var ptrLoc = findPtr(addr);
   if (ptrLoc.isUnknown()) {
      var vmType = vmTypeof(addr);
      if (vmType != null) {
         return "pointer to " + vmType.name;
      } else {
         var sym = closestSymbolFor(addr);
         if (sym != null) {
            return sym.name + '+' + sym.offset;
         } else {
            return ptrLoc.toString();
         }
      }
   } else {
      return ptrLoc.toString();
   }
}
