diff --git a/JavaInJava/src/com/sun/max/AbstractScheme.java b/JavaInJava/src/com/sun/max/AbstractScheme.java
new file mode 100644
index 0000000..c1f4052
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/AbstractScheme.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+/**
+ * @author Bernd Mathiske
+ */
+public abstract class AbstractScheme {
+
+ public final String name;
+
+ protected AbstractScheme() {
+ name = getClass().getSimpleName();
+ }
+
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/BasePackage.java b/JavaInJava/src/com/sun/max/BasePackage.java
new file mode 100644
index 0000000..8125552
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/BasePackage.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class BasePackage extends MaxPackage {
+ protected BasePackage() {
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/MaxPackage.java b/JavaInJava/src/com/sun/max/MaxPackage.java
new file mode 100755
index 0000000..0254cfb
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/MaxPackage.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.sun.max.lang.*;
+import com.sun.max.program.*;
+
+/**
+ * Describes a package in the com.sun.max project,
+ * providing programmatic package information manipulation,
+ * which is lacking in java.lang.Package.
+ *
+ * You must create a class called 'Package extends MaxPackage'
+ * in each and every package in this project.
+ *
+ * For example you can call:
+ *
+ * new com.sun.max.program.Package().superPackage()
+ *
+ * Also make sure that you have a file called 'package-info.java' in every package.
+ * This is where you can put package-related JavaDoc comments.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public abstract class MaxPackage implements Comparable {
+
+ private final String packageName;
+ private static final Class[] NO_CLASSES = new Class[0];
+
+ protected MaxPackage() {
+ packageName = toJava().getName();
+ assert getClass().getSimpleName().equals(Package.class.getSimpleName());
+ }
+
+ /**
+ * Gets an instance of the class named "Package" in a named package.
+ *
+ * @param packageName denotes the name of a package which may contain a subclass of {@link MaxPackage} named
+ * "Package"
+ * @return an instance of the class name "Package" in {@code packageName}. If such a class does not exist or there
+ * was an error {@linkplain Class#newInstance() instantiating} it, then {@code null} is returned
+ */
+ public static MaxPackage fromName(String packageName) {
+ final String name = packageName + "." + Package.class.getSimpleName();
+ if (name.equals(java.lang.Package.class.getName())) {
+ // Special case!
+ return null;
+ }
+ try {
+ final Class packageClass = Class.forName(name);
+ return (MaxPackage) packageClass.newInstance();
+ } catch (ClassNotFoundException e) {
+ } catch (InstantiationException e) {
+ } catch (IllegalAccessException e) {
+ }
+ return null;
+ }
+
+ private MaxPackage(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public static MaxPackage fromJava(String name) {
+ return new MaxPackage(name) {
+ @Override
+ public java.lang.Package toJava() {
+ return java.lang.Package.getPackage(name());
+ }
+ };
+ }
+
+ public static MaxPackage fromClass(Class javaClass) {
+ final java.lang.Package javaPackage = javaClass.getPackage();
+ if (javaPackage == null) {
+ return null;
+ }
+ return fromName(javaPackage.getName());
+ }
+
+ public java.lang.Package toJava() {
+ return getClass().getPackage();
+ }
+
+ public String name() {
+ return packageName;
+ }
+
+ public String lastIdentifier() {
+ return packageName.substring(packageName.lastIndexOf('.') + 1);
+ }
+
+ public MaxPackage superPackage() {
+ final int end = name().lastIndexOf('.');
+ if (end < 0) {
+ return null;
+ }
+ return fromName(name().substring(0, end));
+ }
+
+ /**
+ * Gets the subclasses of {@code com.sun.max.unsafe.Word} in this package.
+ * The returned array must not include boxed (see com.sun.max.unsafe.Boxed)
+ * word types as they are derived from the name of the unboxed types.
+ */
+ public Class[] wordSubclasses() {
+ return NO_CLASSES;
+ }
+
+ public MaxPackage subPackage(String... suffices) {
+ String name = name();
+ for (String suffix : suffices) {
+ name += "." + suffix;
+ }
+ final MaxPackage subPackage = fromName(name);
+ ProgramError.check(subPackage != null, "Could not find sub-package of " + this + " named " + name);
+ return subPackage;
+ }
+
+ public boolean isSubPackageOf(MaxPackage superPackage) {
+ return name().startsWith(superPackage.name());
+ }
+
+ public List getTransitiveSubPackages(Classpath classpath) {
+ final Set packageNames = new TreeSet();
+ new ClassSearch() {
+ @Override
+ protected boolean visitClass(String className) {
+ final String pkgName = Classes.getPackageName(className);
+ if (pkgName.startsWith(name())) {
+ packageNames.add(pkgName);
+ }
+ return true;
+ }
+ }.run(classpath, name().replace('.', '/'));
+
+ final List packages = new ArrayList(packageNames.size());
+ for (String pkgName : packageNames) {
+ final MaxPackage maxPackage = MaxPackage.fromName(pkgName);
+ if (maxPackage == null) {
+ System.err.println("WARNING: missing Package class in package: " + pkgName);
+ } else {
+ packages.add(maxPackage);
+ }
+ }
+ return packages;
+ }
+
+ private Map, Class extends Scheme>> schemeTypeToImplementation;
+
+ /**
+ * Registers a class in this package that implements a given scheme type.
+ *
+ * @param schemeType a scheme type
+ * @param schemeImplementation a class that implements {@code schemType}
+ */
+ public synchronized void registerScheme(Class schemeType, Class extends S> schemeImplementation) {
+ assert schemeType.isInterface() || Modifier.isAbstract(schemeType.getModifiers());
+ assert schemeImplementation.getPackage().getName().equals(name()) : "cannot register implmentation class from another package: " + schemeImplementation;
+ if (schemeTypeToImplementation == null) {
+ schemeTypeToImplementation = new IdentityHashMap, Class extends Scheme>>();
+ }
+ Class extends Scheme> oldValue = schemeTypeToImplementation.put(schemeType, schemeImplementation);
+ assert oldValue == null;
+ }
+
+ /**
+ * Gets the class within this package implementing a given scheme type (represented as an abstract class or interface).
+ *
+ * @return the class directly within this package that implements {@code scheme} or null if no such class
+ * exists
+ */
+ public synchronized Class extends S> schemeTypeToImplementation(Class schemeType) {
+ if (schemeTypeToImplementation == null) {
+ return null;
+ }
+ final Class< ? extends Scheme> implementation = schemeTypeToImplementation.get(schemeType);
+ if (implementation == null) {
+ return null;
+ }
+ return implementation.asSubclass(schemeType);
+ }
+
+ public static boolean equal(MaxPackage p1, MaxPackage p2) {
+ if (p1 == null) {
+ return p2 == null;
+ }
+ return p1.equals(p2);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (other instanceof MaxPackage) {
+ return packageName.equals(((MaxPackage) other).packageName);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return name().hashCode();
+ }
+
+ public Set prerequisites() {
+ return Collections.emptySet();
+ }
+
+ /**
+ * Gets the set of packages excluded by this package. Excluded packages will not be loaded into a system that is
+ * configured by package loading (such as the Maxine VM) if the package represented by this object is loaded. Such a
+ * system should ensure that configuration fails if any excluded packages encountered on the class path before the
+ * package that excludes them.
+ */
+ public Set excludes() {
+ return Collections.emptySet();
+ }
+
+ public int compareTo(MaxPackage other) {
+ final Set myPrerequisites = prerequisites();
+ final Set otherPrerequisites = other.prerequisites();
+ if (myPrerequisites.isEmpty()) {
+ if (otherPrerequisites.isEmpty()) {
+ return packageName.compareTo(other.packageName);
+ }
+ return -1;
+ }
+ for (MaxPackage myPrerequisite : myPrerequisites) {
+ if (other.equals(myPrerequisite)) {
+ return 1;
+ }
+ }
+ if (otherPrerequisites.isEmpty()) {
+ return 1;
+ }
+ for (MaxPackage otherPrerequisite : otherPrerequisites) {
+ if (equals(otherPrerequisite)) {
+ return -1;
+ }
+ }
+ return packageName.compareTo(other.packageName);
+ }
+
+ public synchronized Class extends S> loadSchemeImplementation(Class schemeType) {
+ final Class extends S> schemeImplementation = schemeTypeToImplementation(schemeType);
+ if (schemeImplementation == null) {
+ ProgramError.unexpected("could not find subclass of " + schemeType + " in " + this);
+ } else {
+ final Class> loadedImplementation = Classes.load(schemeType.getClassLoader(), schemeImplementation.getName());
+ return loadedImplementation.asSubclass(schemeType);
+ }
+ return null;
+ }
+
+ /**
+ * Instantiates the scheme implementation class in this package implementing a given scheme type.
+ *
+ * @param schemeType the interface or abstract class defining a scheme type
+ * @return a new instance of the scheme implementation class
+ */
+ public synchronized S loadAndInstantiateScheme(Class schemeType) {
+ final Class extends S> schemeImplementation = loadSchemeImplementation(schemeType);
+ try {
+ return schemeImplementation.newInstance();
+ } catch (Throwable throwable) {
+ throw ProgramError.unexpected("could not instantiate class: " + schemeImplementation.getName(), throwable);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return name();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/Package.java b/JavaInJava/src/com/sun/max/Package.java
new file mode 100755
index 0000000..63cbee2
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/Package.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends BasePackage {
+}
diff --git a/JavaInJava/src/com/sun/max/PackageLoader.java b/JavaInJava/src/com/sun/max/PackageLoader.java
new file mode 100755
index 0000000..f79fd2e
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/PackageLoader.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+import java.util.*;
+
+import com.sun.max.lang.*;
+import com.sun.max.program.*;
+
+/**
+ * Loads all the classes in or under a given package.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public class PackageLoader {
+
+ public final Classpath classpath;
+ public final ClassLoader classLoader;
+ private int traceLevel = 1;
+
+ public PackageLoader(ClassLoader classLoader, Classpath classpath) {
+ this.classpath = classpath;
+ this.classLoader = classLoader;
+ }
+
+ public void setTraceLevel(int level) {
+ traceLevel = level;
+ }
+
+ /**
+ * Loads a given class.
+ * A subclass can override this method to omit loading of certain classes in a package
+ * which can result in this method returning {@code null}.
+ *
+ * @param className
+ * @return the {@code Class} instance for {@code className}
+ */
+ protected Class loadClass(String className) {
+ return Classes.load(classLoader, className);
+ }
+
+ /**
+ * Loads classes under a given package.
+ *
+ * @param packageName the name of the package from which classes are loaded
+ * @param recursive if true, then classes in sub-packages are loaded as well, otherwise only classes in the package
+ * denoted by {@code packageName} are loaded
+ * @return the loaded classes
+ */
+ public List load(final String packageName, final boolean recursive) {
+ Trace.line(traceLevel, "loading: " + packageName);
+ final List classes = new ArrayList();
+ String[] classNames = listClassesInPackage(packageName, recursive);
+ for (String className : classNames) {
+ final Class javaClass = loadClass(className);
+ if (javaClass != null) {
+ Classes.initialize(javaClass);
+ classes.add(javaClass);
+ }
+ }
+ ProgramWarning.check(classNames.length != 0, "no classes found in package: " + packageName);
+ return classes;
+ }
+
+ /**
+ * Lists the classes under a given package.
+ *
+ * @param packageName the name of the package to search
+ * @param recursive if true, then classes in sub-packages are listed as well
+ * @return the class names
+ */
+ public String[] listClassesInPackage(final String packageName, final boolean recursive) {
+ final HashSet classNames = new HashSet();
+ final ClassSearch classSearch = new ClassSearch() {
+ @Override
+ protected boolean visitClass(boolean isArchiveEntry, String className) {
+ if (!className.endsWith("package-info")) {
+ if (!classNames.contains(className)) {
+ if (recursive || Classes.getPackageName(className).equals(packageName)) {
+ classNames.add(className);
+ }
+ }
+ }
+ return true;
+ }
+ };
+ classSearch.run(classpath, packageName.replace('.', '/'));
+ return classNames.toArray(new String[classNames.size()]);
+ }
+
+ /**
+ * Loads classes under a given package.
+ *
+ * @param maxPackage the package from which classes are loaded
+ * @param recursive if true, then classes in sub-packages are loaded as well, otherwise only classes in
+ * {@code maxPackage} are loaded
+ * @return the loaded classes
+ */
+ public List load(MaxPackage maxPackage, boolean recursive) {
+ return load(maxPackage.name(), recursive);
+ }
+
+ /**
+ * Initializes the given class and all its inner classes, recursively.
+ */
+ private void initializeAll(Class outerClass) {
+ Classes.initialize(outerClass);
+ for (Class innerClass : outerClass.getDeclaredClasses()) {
+ initializeAll(innerClass);
+ }
+ }
+
+ public void loadAndInitializeAll(Class representative) {
+ try {
+ for (Class outerClass : load(MaxPackage.fromClass(representative), false)) {
+ initializeAll(outerClass);
+ }
+ } catch (Throwable throwable) {
+ ProgramError.unexpected(throwable);
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/Scheme.java b/JavaInJava/src/com/sun/max/Scheme.java
new file mode 100644
index 0000000..d17701c
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/Scheme.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+/**
+ * @author Bernd Mathiske
+ */
+public interface Scheme {
+
+ String name();
+
+}
diff --git a/JavaInJava/src/com/sun/max/Utils.java b/JavaInJava/src/com/sun/max/Utils.java
new file mode 100644
index 0000000..c843f9b
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/Utils.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max;
+
+import java.io.*;
+import java.util.*;
+
+import com.sun.max.program.*;
+
+/**
+ * Miscellaneous utility methods.
+ *
+ * @author Doug Simon
+ */
+public final class Utils {
+
+ private Utils() {
+ }
+
+ /**
+ * Gets the first element in a list.
+ */
+ public static T first(List list) {
+ if (list instanceof Queue) {
+ Queue queue = (Queue) list;
+ Class type = null;
+ T t = cast(type, queue.peek());
+ return t;
+ }
+ return list.get(0);
+ }
+
+ /**
+ * Gets the last element in a list.
+ */
+ public static T last(List list) {
+ if (list instanceof Deque) {
+ Deque deque = (Deque) list;
+ Class type = null;
+ T t = cast(type, deque.getLast());
+ return t;
+ }
+ return list.get(list.size() - 1);
+ }
+
+ /**
+ * Creates an array of a generic type.
+ *
+ * @param the type of the array elements
+ * @param length the length of the array to create
+ * @return a generic array of type {@code } with a length of {@code length}
+ */
+ public static T[] newArray(int length) {
+ return cast(new Object[length]);
+ }
+
+ /**
+ * Creates an array of a generic type.
+ *
+ * @param the type of the array elements
+ * @param type explicit class of {@code } needed due to javac bug (see {@link #cast(Class, Object)})
+ * @param length the length of the array to create
+ * @return a generic array of type {@code } with a length of {@code length}
+ */
+ public static T[] newArray(Class type, int length) {
+ return cast(type, new Object[length]);
+ }
+
+ /**
+ * Creates an array of a generic type and {@linkplain Arrays#asList(Object...) wraps} it with
+ * a fixed-size list.
+ *
+ * @param the type of the array elements
+ * @param length the length of the array to create
+ * @return a fixed-size list backed by a new generic array of type {@code } with a length of {@code length}
+ */
+ public static List newArrayAsList(int length) {
+ Class type = null;
+ T[] array = newArray(type, length);
+ return Arrays.asList(array);
+ }
+
+ /**
+ * Returns the index in {@code list} of the first occurrence identical to {@code value}, or -1 if
+ * {@code list} does not contain {@code value}. More formally, returns the lowest index
+ * {@code i} such that {@code (list.get(i) == value)}, or -1 if there is no such index.
+ */
+ public static int indexOfIdentical(List list, Object value) {
+ int i = 0;
+ for (Object element : list) {
+ if (element == value) {
+ return i;
+ }
+ ++i;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index in {@code array} of the first occurrence identical to {@code value}, or -1 if
+ * {@code array} does not contain {@code value}. More formally, returns the lowest index
+ * {@code i} such that {@code (array[i] == value)}, or -1 if there is no such index.
+ */
+ public static int indexOfIdentical(Object[] array, Object value) {
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] == value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Statically cast an object to an arbitrary type. The cast is still dynamically checked.
+ *
+ * This alternate version of {@link #cast(Object)} is required due to bug
+ * 6302954 in javac.
+ *
+ * The pattern for calling this method is:
+ *
+ *
+ */
+ @SuppressWarnings("unchecked")
+ public static T cast(Class type, Object object) {
+ return (T) object;
+ }
+
+ /**
+ * Statically cast an object to an arbitrary type. The cast is still dynamically checked.
+ */
+ @SuppressWarnings("unchecked")
+ public static T cast(Object object) {
+ return (T) object;
+ }
+
+ /**
+ * Concatenates two arrays.
+ *
+ * @param the type of elements in the source arrays
+ * @param head the prefix of the result array
+ * @param tail the elements to be concatenated to {@code head}
+ * @return the result of concatenating {@code tail} to the end of {@code head}
+ */
+ public static T[] concat(T[] head, T... tail) {
+ T[] result = Arrays.copyOf(head, head.length + tail.length);
+ System.arraycopy(tail, 0, result, head.length, tail.length);
+ return result;
+ }
+
+ /**
+ * Concatenates two arrays.
+ *
+ * @param the type of elements in the source arrays
+ * @param tail the elements to be concatenated to the end of {@code head}
+ * @param head the prefix of the result array
+ * @return the result of concatenating {@code tail} to the end of {@code head}
+ */
+ public static T[] prepend(T[] tail, T... head) {
+ return concat(head, tail);
+ }
+
+ /**
+ * Returns a string representation of the contents of the specified array.
+ * If the array contains other arrays as elements, they are converted to
+ * strings by the {@link Object#toString} method inherited from
+ * Object, which describes their identities rather than
+ * their contents.
+ *
+ * @param array the array whose string representation to return
+ * @param separator the separator to use
+ * @return a string representation of array
+ * @throws NullPointerException if {@code array} or {@code separator} is null
+ */
+ public static String toString(T[] array, String separator) {
+ if (array == null || separator == null) {
+ throw new NullPointerException();
+ }
+ if (array.length == 0) {
+ return "";
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append(array[0]);
+
+ for (int i = 1; i < array.length; i++) {
+ builder.append(separator);
+ builder.append(array[i]);
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Tests a given exception to see if it is an instance of a given exception type, casting and throwing it if so.
+ * Otherwise if the exception is an unchecked exception (i.e. an instance of a {@link RuntimeException} or
+ * {@link Error}) then it is cast to the appropriate unchecked exception type and thrown. Otherwise, it is wrapped
+ * in a {@link ProgramError} and thrown.
+ *
+ * This method declares a return type simply so that a call to this method can be the expression to a throw
+ * instruction.
+ */
+ public static T cast(Class exceptionType, Throwable exception) throws T {
+ if (exceptionType.isInstance(exception)) {
+ throw exceptionType.cast(exception);
+ }
+ if (exception instanceof Error) {
+ throw (Error) exception;
+ }
+ if (exception instanceof RuntimeException) {
+ throw (RuntimeException) exception;
+ }
+ throw ProgramError.unexpected(exception);
+ }
+
+ /**
+ * Gets the stack trace for a given exception as a string.
+ */
+ public static String stackTraceAsString(Throwable throwable) {
+ final StringWriter stringWriter = new StringWriter();
+ throwable.printStackTrace(new PrintWriter(stringWriter));
+ return stringWriter.getBuffer().toString();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/annotate/INLINE.java b/JavaInJava/src/com/sun/max/annotate/INLINE.java
new file mode 100644
index 0000000..4facc57
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/INLINE.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.annotate;
+import java.lang.annotation.*;
+
+/**
+ * Every thus annotated method is to be inlined unconditionally by the VM's optimizing compiler
+ * and the receiver is never null-checked.
+ *
+ * This annotation exists primarily for annotating methods that must be inlined
+ * for semantic reasons as opposed to those that could be inlined for performance reasons.
+ * Using this annotation for the latter should be done very rarely and only when
+ * profiling highlights a performance bottleneck or such a bottleneck is known a priori.
+ *
+ * If the {@linkplain #override() override} element of this annotation is set to true, then
+ * an annotated method must be {@code static} or {@code final} (implicitly or explicitly).
+ * Additionally, only a INLINE virtual method with this element set to true can be overridden.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface INLINE {
+
+ /**
+ * If true, this element specifies that the annotated method provides the prototypical implementation
+ * of the functionality expected (in the target VM) of every method that overrides
+ * the annotated method. That is, the code produced by the compiler for every overriding method
+ * must be functionality equivalent to the code produced for the prototypical method.
+ *
+ * WARNING: Setting this element to true implies that you guarantee that all overriders
+ * satisfy the above stated invariant. There is no (easy) way to test for violations of
+ * the invariant.
+ *
+ * A method annotated with INLINE should only be overridden for one of the following reasons:
+ *
+ * 1. To coerce the value returned by the overridden method to a subtype.
+ * See {@link MemberActor#holder()} and {@link FieldActor#holder()} for an example.
+ *
+ * 2. A method is overridden to make bootstrapping work.
+ * See {@link ClassActor#toJava()} and {@link ArrayClassActor#toJava()} for an example.
+ *
+ * 3. A method is overridden because a subclass can provide a more efficient implementation
+ * and it is known that certain call sites will be reduced to a constant receiver
+ * (not just a known receiver type but a known receiver object) via annotation driven
+ * compile-time {@linkplain FOLD folding}. This is how calls to the {@link GeneralLayout layout}
+ * interface methods are reduced to monomorphic calls at compile-time.
+ *
+ * See {@link ClassActor#toJava()} and {@link ArrayClassActor#toJava()} for an example.
+ */
+ boolean override() default false;
+
+ /**
+ * If true, this element specifies that inlining of the thus annotated method is only allowed
+ * after snippet compilation has concluded.
+ *
+ * @see CompilerScheme#areSnippetsCompiled()
+ */
+ boolean afterSnippetsAreCompiled() default false;
+}
diff --git a/JavaInJava/src/com/sun/max/annotate/INSPECTED.java b/JavaInJava/src/com/sun/max/annotate/INSPECTED.java
new file mode 100644
index 0000000..5a37bd6
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/INSPECTED.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.annotate;
+
+import java.lang.annotation.*;
+
+/**
+ * Marks a field, method or constructor that is reflected upon by the Inspector.
+ *
+ * The Inspector uses this annotation to auto-generate objects for accessing the
+ * annotated entity in the remote VM process. See the {@code TeleFields}
+ * and {@code TeleMethods} classes in the Tele project.
+ *
+ * @author Doug Simon
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD })
+public @interface INSPECTED {
+
+}
diff --git a/JavaInJava/src/com/sun/max/annotate/Package.java b/JavaInJava/src/com/sun/max/annotate/Package.java
new file mode 100755
index 0000000..e8e1252
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/Package.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.annotate;
+
+import com.sun.max.*;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends BasePackage {
+ public Package() {
+ super();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/annotate/RESET.java b/JavaInJava/src/com/sun/max/annotate/RESET.java
new file mode 100644
index 0000000..761bea2
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/RESET.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.annotate;
+
+import java.lang.annotation.*;
+
+/**
+ * Denotes a field whose value is reset to the default value for its type when it is copied into the Maxine boot image.
+ *
+ * @author Doug Simon
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface RESET {
+}
diff --git a/JavaInJava/src/com/sun/max/annotate/package-info.java b/JavaInJava/src/com/sun/max/annotate/package-info.java
new file mode 100644
index 0000000..6ac3db3
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * Annotations used throughout the Maxine project.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max.annotate;
diff --git a/JavaInJava/src/com/sun/max/gui/Package.java b/JavaInJava/src/com/sun/max/gui/Package.java
new file mode 100755
index 0000000..09ba7ef
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/gui/Package.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.gui;
+
+import com.sun.max.*;
+
+/**
+ * This package is not included in the bootstrap as it would drag in most of Swing.
+ *
+ * @author Doug Simon
+ */
+public class Package extends MaxPackage {
+ public Package() {
+ super();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/gui/SpringUtilities.java b/JavaInJava/src/com/sun/max/gui/SpringUtilities.java
new file mode 100644
index 0000000..cffa05d
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/gui/SpringUtilities.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.gui;
+
+import java.awt.*;
+
+import javax.swing.*;
+/**
+ * Partially copied from the "Swing Tutorial".
+ * Minor changes to comply with our CheckStyle settings.
+ *
+ * A 1.4 file that provides utility methods for
+ * creating form- or grid-style layouts with SpringLayout.
+ * These utilities are used by several programs, such as
+ * SpringBox and SpringCompactGrid.
+ *
+ * @author original SpringUtilities author
+ * @author Bernd Mathiske
+ */
+public final class SpringUtilities {
+ private SpringUtilities() {
+ }
+
+ /**
+ * A debugging utility that prints to stdout the component's
+ * minimum, preferred, and maximum sizes.
+ */
+ public static void printSizes(Component c) {
+ System.out.println("minimumSize = " + c.getMinimumSize());
+ System.out.println("preferredSize = " + c.getPreferredSize());
+ System.out.println("maximumSize = " + c.getMaximumSize());
+ }
+
+ /**
+ * Aligns the first {@code rows} * {@code cols}
+ * components of {@code parent} in
+ * a grid. Each component is as big as the maximum
+ * preferred width and height of the components.
+ * The parent is made just big enough to fit them all.
+ *
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param initialX x location to start the grid at
+ * @param initialY y location to start the grid at
+ * @param xPad x padding between cells
+ * @param yPad y padding between cells
+ */
+ public static void makeGrid(Container parent,
+ int rows, int cols,
+ int initialX, int initialY,
+ int xPad, int yPad) {
+ SpringLayout layout;
+ try {
+ layout = (SpringLayout) parent.getLayout();
+ } catch (ClassCastException exc) {
+ System.err.println("The first argument to makeGrid must use SpringLayout.");
+ return;
+ }
+
+ final Spring xPadSpring = Spring.constant(xPad);
+ final Spring yPadSpring = Spring.constant(yPad);
+ final Spring initialXSpring = Spring.constant(initialX);
+ final Spring initialYSpring = Spring.constant(initialY);
+ final int max = rows * cols;
+
+ //Calculate Springs that are the max of the width/height so that all
+ //cells have the same size.
+ Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).
+ getWidth();
+ Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).
+ getWidth();
+ for (int i = 1; i < max; i++) {
+ final SpringLayout.Constraints cons = layout.getConstraints(parent.getComponent(i));
+
+ maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
+ maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
+ }
+
+ //Apply the new width/height Spring. This forces all the
+ //components to have the same size.
+ for (int i = 0; i < max; i++) {
+ final SpringLayout.Constraints cons = layout.getConstraints(parent.getComponent(i));
+
+ cons.setWidth(maxWidthSpring);
+ cons.setHeight(maxHeightSpring);
+ }
+
+ //Then adjust the x/y constraints of all the cells so that they
+ //are aligned in a grid.
+ SpringLayout.Constraints lastCons = null;
+ SpringLayout.Constraints lastRowCons = null;
+ for (int i = 0; i < max; i++) {
+ final SpringLayout.Constraints cons = layout.getConstraints(parent.getComponent(i));
+ if (i % cols == 0) { //start of new row
+ lastRowCons = lastCons;
+ cons.setX(initialXSpring);
+ } else if (lastCons != null) { //x position depends on previous component
+ cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
+ xPadSpring));
+ }
+
+ if (i / cols == 0) { //first row
+ cons.setY(initialYSpring);
+ } else if (lastRowCons != null) { //y position depends on previous row
+ cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH),
+ yPadSpring));
+ }
+ lastCons = cons;
+ }
+
+ //Set the parent's size.
+ final SpringLayout.Constraints pCons = layout.getConstraints(parent);
+ if (lastCons != null) {
+ pCons.setConstraint(SpringLayout.SOUTH, Spring.sum(Spring.constant(yPad), lastCons.getConstraint(SpringLayout.SOUTH)));
+ pCons.setConstraint(SpringLayout.EAST, Spring.sum(Spring.constant(xPad), lastCons.getConstraint(SpringLayout.EAST)));
+ }
+ }
+
+ public static void makeGrid(Container parent, int numberOfColumns) {
+ makeGrid(parent, parent.getComponentCount() / numberOfColumns, numberOfColumns, 0, 0, 5, 5);
+ }
+
+ /* Used by makeCompactGrid. */
+ private static SpringLayout.Constraints getConstraintsForCell(
+ int row, int col,
+ Container parent,
+ int cols) {
+ final SpringLayout layout = (SpringLayout) parent.getLayout();
+ final Component c = parent.getComponent(row * cols + col);
+ return layout.getConstraints(c);
+ }
+
+ /**
+ * Aligns the first {@code rows} * {@code cols}
+ * components of {@code parent} in
+ * a grid. Each component in a column is as wide as the maximum
+ * preferred width of the components in that column;
+ * height is similarly determined for each row.
+ * The parent is made just big enough to fit them all.
+ *
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param initialX x location to start the grid at
+ * @param initialY y location to start the grid at
+ * @param xPad x padding between cells
+ * @param yPad y padding between cells
+ */
+ public static void makeCompactGrid(Container parent,
+ int rows, int cols,
+ int initialX, int initialY,
+ int xPad, int yPad) {
+ SpringLayout layout;
+ try {
+ layout = (SpringLayout) parent.getLayout();
+ } catch (ClassCastException exc) {
+ System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
+ return;
+ }
+
+ //Align all cells in each column and make them the same width.
+ Spring x = Spring.constant(initialX);
+ for (int c = 0; c < cols; c++) {
+ Spring width = Spring.constant(0);
+ for (int r = 0; r < rows; r++) {
+ width = Spring.max(width,
+ getConstraintsForCell(r, c, parent, cols).
+ getWidth());
+ }
+ for (int r = 0; r < rows; r++) {
+ final SpringLayout.Constraints constraints = getConstraintsForCell(r, c, parent, cols);
+ constraints.setX(x);
+ constraints.setWidth(width);
+ }
+ x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
+ }
+
+ //Align all cells in each row and make them the same height.
+ Spring y = Spring.constant(initialY);
+ for (int r = 0; r < rows; r++) {
+ Spring height = Spring.constant(0);
+ for (int c = 0; c < cols; c++) {
+ height = Spring.max(height,
+ getConstraintsForCell(r, c, parent, cols).
+ getHeight());
+ }
+ for (int c = 0; c < cols; c++) {
+ final SpringLayout.Constraints constraints = getConstraintsForCell(r, c, parent, cols);
+ constraints.setY(y);
+ constraints.setHeight(height);
+ }
+ y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
+ }
+
+ //Set the parent's size.
+ final SpringLayout.Constraints pCons = layout.getConstraints(parent);
+ pCons.setConstraint(SpringLayout.SOUTH, y);
+ pCons.setConstraint(SpringLayout.EAST, x);
+ }
+
+ public static void makeCompactGrid(Container parent, int numberOfColumns) {
+ makeCompactGrid(parent, parent.getComponentCount() / numberOfColumns, numberOfColumns, 0, 0, 3, 3);
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/gui/ThrowableDialog.java b/JavaInJava/src/com/sun/max/gui/ThrowableDialog.java
new file mode 100644
index 0000000..78ea1c7
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/gui/ThrowableDialog.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.gui;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+/**
+ * A dialog for displaying the details of an exception. Initially the dialog only shows the exception's
+ * {@linkplain Throwable#getMessage() message}. It includes a button for expanding the dialog to also show the stack
+ * trace. When the stack trace is shown, pressing the same button hides the stack trace.
+ *
+ * @author Doug Simon
+ * @author Aritra Bandyopadhyay
+ */
+public final class ThrowableDialog extends JDialog {
+
+ /**
+ * Creates a dialog to display the details of an exception and makes it visible.
+ *
+ * @param throwable the exception whose details are being displayed
+ * @param owner the {@code Frame} from which the dialog is displayed
+ * @param title the {@code String} to display in the dialog's title bar
+ */
+ public static void show(Throwable throwable, Frame owner, String title) {
+ new ThrowableDialog(throwable, owner, title).setVisible(true);
+ }
+
+ /**
+ * Creates a dialog to display the details of an exception and makes it visible on the
+ * {@linkplain SwingUtilities#invokeLater(Runnable) AWT dispatching thread}.
+ *
+ * @param throwable the exception whose details are being displayed
+ * @param owner the {@code Frame} from which the dialog is displayed
+ * @param title the {@code String} to display in the dialog's title bar
+ */
+ public static void showLater(Throwable throwable, Frame owner, String title) {
+ final ThrowableDialog dialog = new ThrowableDialog(throwable, owner, title);
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ dialog.setVisible(true);
+ }
+ });
+ }
+
+ /**
+ * Creates a dialog to display the details of an exception. The dialog is not displayed by this method.
+ *
+ * @param throwable the exception whose details are being displayed
+ * @param owner the {@code Frame} from which the dialog is displayed
+ * @param title the {@code String} to display in the dialog's title bar
+ */
+ private ThrowableDialog(Throwable throwable, Frame owner, String title) {
+ super(owner, title, true);
+ setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ setAlwaysOnTop(true);
+
+ final JToggleButton stackTraceButton = new JToggleButton("Show stack trace");
+ final JButton closeButton = new JButton("Close");
+ closeButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ setVisible(false);
+ dispose();
+ }
+ });
+
+ final JPanel buttonsPanel = new JPanel();
+ buttonsPanel.add(closeButton);
+ buttonsPanel.add(stackTraceButton);
+
+ final Container mainPane = getContentPane();
+ //mainPane.setLayout(new FlowLayout());
+ mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.PAGE_AXIS));
+ final JLabel message = new JLabel(throwable.getMessage());
+ final JPanel messagePanel = new JPanel();
+ messagePanel.add(message);
+ mainPane.add(messagePanel);
+ mainPane.add(buttonsPanel);
+ pack();
+
+ final Dimension dialogWithoutStackTracePreferredSize = getPreferredSize();
+
+ final JTextArea stackTraceText = new JTextArea(20, 40);
+ throwable.printStackTrace(new PrintWriter(new Writer() {
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ stackTraceText.append(new String(cbuf, off, len));
+ }
+ }));
+
+ final JScrollPane stackTracePanel = new JScrollPane(stackTraceText, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ final Dimension stackTraceTextPreferredSize = stackTraceText.getPreferredSize();
+ stackTracePanel.setBorder(new TitledBorder("Stack trace"));
+ final Dimension stackTracePanelPreferredSize = new Dimension(
+ stackTraceTextPreferredSize.width + stackTracePanel.getVerticalScrollBar().getPreferredSize().width * 2,
+ stackTraceTextPreferredSize.height + stackTracePanel.getHorizontalScrollBar().getPreferredSize().height);
+ stackTracePanel.setPreferredSize(stackTracePanelPreferredSize);
+ stackTracePanel.setVisible(false);
+
+ stackTraceButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (stackTraceButton.isSelected()) {
+ stackTraceButton.setText("Hide stack trace");
+ stackTracePanel.setVisible(true);
+ setSize(new Dimension(Math.max(dialogWithoutStackTracePreferredSize.width, stackTracePanelPreferredSize.width),
+ dialogWithoutStackTracePreferredSize.height + Math.min(1000, stackTracePanelPreferredSize.height)));
+ } else {
+ stackTraceButton.setText("Show stack trace");
+ stackTracePanel.setVisible(false);
+ setSize(dialogWithoutStackTracePreferredSize);
+ }
+ validate();
+ }
+ });
+ mainPane.add(stackTracePanel);
+
+ setSize(dialogWithoutStackTracePreferredSize);
+ pack();
+ setLocationRelativeTo(owner);
+ }
+
+ // Test code
+
+ public static void main(String[] args) {
+ try {
+ recurse(0);
+ } catch (RuntimeException runtimeException) {
+ new ThrowableDialog(runtimeException, null, "Runtime Exception");
+ }
+ }
+
+ static void recurse(int more) {
+ if (more > 345) {
+ throw new RuntimeException("This is a test. Repeat. This is a test.");
+ }
+ recurse(more + 1);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/gui/package-info.java b/JavaInJava/src/com/sun/max/gui/package-info.java
new file mode 100644
index 0000000..d7545f6
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/gui/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * GUI utilities.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max.gui;
diff --git a/JavaInJava/src/com/sun/max/io/CharArraySource.java b/JavaInJava/src/com/sun/max/io/CharArraySource.java
new file mode 100644
index 0000000..0edca3d
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/CharArraySource.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ *
+ *
+ * @author Doug Simon
+ */
+public class CharArraySource extends CharArrayWriter implements ReadableSource {
+
+ public CharArraySource() {
+ }
+
+ public CharArraySource(int initialSize) {
+ super(initialSize);
+ }
+
+ public Reader reader(boolean buffered) {
+ final Reader reader = new CharArrayReader(buf, 0, count);
+ return buffered ? new BufferedReader(reader) : reader;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/FileTraversal.java b/JavaInJava/src/com/sun/max/io/FileTraversal.java
new file mode 100644
index 0000000..97834cf
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/FileTraversal.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ * Provides a facility for walking a file system hierarchy similar to that provided by the Unix find(1) facility.
+ *
+ * @author Doug Simon
+ */
+public class FileTraversal {
+
+ private boolean stopped;
+
+ /**
+ * Handles a standard file resource encountered during the traversal.
+ *
+ * @param file a file resource for which {@link File#isFile()} returns {@code true}
+ */
+ protected void visitFile(File file) {
+ }
+
+ /**
+ * Handles a directory encountered during the traversal.
+ *
+ * @param directory a file resource for which {@link File#isDirectory()} returns {@code true}
+ * @return true if the traversal should process the file system hierarchy rooted at {@code directory}, false if it
+ * should be skipped
+ */
+ protected boolean visitDirectory(File directory) {
+ return true;
+ }
+
+ /**
+ * Handles a file resource encountered during the traversal that is neither a standard file or directory.
+ *
+ * @param other a file resource for which neither {@link File#isFile()} nor {@link File#isDirectory()} returns
+ * {@code true}
+ */
+ protected void visitOther(File other) {
+ }
+
+ /**
+ * Stops the traversal after the current file resource has been processed. This can be called from within an
+ * overriding implementation of {@link #visitFile(File)}, {@link #visitDirectory(File)} or
+ * {@link #visitOther(File)} to prematurely terminate a traversal.
+ */
+ protected final void stop() {
+ stopped = true;
+ }
+
+ /**
+ * Traverses the file hierarchy rooted at a given file. The {@linkplain #wasStopped() stopped} status of this
+ * traversal object is reset to {@code false} before the traversal begins.
+ *
+ * @param file the file or directory at which to start the traversal
+ */
+ public void run(File file) {
+ stopped = false;
+ visit(file);
+ }
+
+ /**
+ * Determines if the traversal was stopped before every file in the file hierarchy was traversed.
+ */
+ public boolean wasStopped() {
+ return stopped;
+ }
+
+ private boolean visit(File entry) {
+ File subdirectoryToTraverse = null;
+ if (entry.isFile()) {
+ visitFile(entry);
+ } else if (entry.isDirectory()) {
+ if (visitDirectory(entry)) {
+ subdirectoryToTraverse = entry;
+ }
+ } else {
+ visitOther(entry);
+ }
+ if (stopped) {
+ return false;
+ }
+ if (subdirectoryToTraverse != null) {
+ traverse(subdirectoryToTraverse);
+ if (stopped) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void traverse(File directory) {
+ final File[] entries = directory.listFiles();
+ if (entries != null) {
+ for (File entry : entries) {
+ if (!visit(entry)) {
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/Files.java b/JavaInJava/src/com/sun/max/io/Files.java
new file mode 100644
index 0000000..d9f8588
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/Files.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+import com.sun.max.program.*;
+import com.sun.max.util.*;
+
+/**
+ * @author Doug Simon
+ */
+public final class Files {
+
+ private Files() {
+ }
+
+ public static void copy(File from, File to) throws FileNotFoundException, IOException {
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ try {
+ inputStream = new FileInputStream(from);
+ outputStream = new FileOutputStream(to);
+ Streams.copy(inputStream, outputStream);
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ }
+ }
+
+ public static boolean equals(File file1, File file2) throws FileNotFoundException, IOException {
+ final long length1 = file1.length();
+ final long length2 = file2.length();
+ if (length1 != length2) {
+ return false;
+ }
+ if (length1 <= 0) {
+ return true;
+ }
+ InputStream inputStream1 = null;
+ InputStream inputStream2 = null;
+ try {
+ inputStream1 = new BufferedInputStream(new FileInputStream(file1), (int) length1);
+ inputStream2 = new BufferedInputStream(new FileInputStream(file2), (int) length2);
+ return Streams.equals(inputStream1, inputStream2);
+ } finally {
+ if (inputStream1 != null) {
+ inputStream1.close();
+ }
+ if (inputStream2 != null) {
+ inputStream2.close();
+ }
+ }
+ }
+
+ public static boolean equals(File file, Iterator lines) throws FileNotFoundException, IOException {
+ final BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
+ try {
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (!lines.hasNext()) {
+ return false;
+ }
+ if (!line.equals(lines.next())) {
+ return false;
+ }
+ }
+ } finally {
+ bufferedReader.close();
+ }
+ return !lines.hasNext();
+ }
+
+ public static byte[] toBytes(File file) throws IOException {
+ if (file.length() > Integer.MAX_VALUE) {
+ throw new IOException("file is too big to read into an array: " + file);
+ }
+ final InputStream stream = new BufferedInputStream(new FileInputStream(file), (int) file.length());
+ try {
+ return Streams.readFully(stream, new byte[(int) file.length()]);
+ } finally {
+ stream.close();
+ }
+ }
+
+ /**
+ * Creates/overwrites a file with a given string.
+ */
+ public static void fill(File file, String content) throws IOException {
+ final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
+ try {
+ bufferedWriter.write(content);
+ } finally {
+ bufferedWriter.close();
+ }
+ }
+
+ /**
+ * Creates/overwrites a file from a reader.
+ */
+ public static void fill(File file, Reader reader, boolean append) throws IOException {
+ final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
+ try {
+ int ch;
+ while ((ch = reader.read()) != -1) {
+ bufferedWriter.write(ch);
+ }
+ } finally {
+ bufferedWriter.close();
+ }
+ }
+
+ public static void readLines(File file, List lines) throws IOException {
+ final BufferedReader reader = new BufferedReader(new FileReader(file));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ lines.add(line);
+ }
+ reader.close();
+ }
+
+ public static List readLines(File file) throws IOException {
+ final List lines = new ArrayList();
+ readLines(file, lines);
+ return lines;
+ }
+
+ public static char[] toChars(File file) throws IOException {
+ if (file.length() > Integer.MAX_VALUE) {
+ throw new IOException("file is too big to read into an array: " + file);
+ }
+ int length = (int) file.length();
+ if (length == 0) {
+ return new char[0];
+ }
+ final Reader fileReader = new BufferedReader(new FileReader(file), length);
+ char[] chars = new char[length];
+ try {
+ chars = Streams.readFully(fileReader, chars);
+ } catch (TruncatedInputException truncatedInputException) {
+ // Must have been multi-byte characters in the file
+ length = truncatedInputException.inputLength();
+ final char[] oldChars = chars;
+ chars = new char[length];
+ System.arraycopy(oldChars, 0, chars, 0, length);
+ } finally {
+ fileReader.close();
+ }
+ return chars;
+ }
+
+ /**
+ * Updates the generated content part of a file. A generated content part is delimited by a line containing only
+ * {@code start} and a line containing only {@code end}. If the given file already exists and has these delimiters,
+ * the content between these lines is compared with {@code content} and replaced if it is different. If the file
+ * does not exist, a new file is created with {@code content} surrounded by the specified delimiters. If the file
+ * exists and does not currently have the specified delimiters, an IOException is thrown.
+ *
+ * @param file the file to be modified (or created) with some generated content
+ * @param content the generated content
+ * @param start the starting delimiter of the section in {@code file} to be updated with {@code content}
+ * @param start the ending delimiter of the section in {@code file} to be updated with {@code content}
+ * @param checkOnly if {@code true}, then {@code file} is not updated; the value returned by this method indicates
+ * whether it would have been updated were this argument {@code true}
+ * @return true if {@code file} was modified or created (or would have been if {@code checkOnly} was {@code false})
+ */
+ public static boolean updateGeneratedContent(File file, ReadableSource content, String start, String end, boolean checkOnly) throws IOException {
+
+ if (!file.exists()) {
+ if (checkOnly) {
+ return true;
+ }
+ final PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
+ try {
+ final Reader reader = content.reader(true);
+ try {
+ printWriter.println(start);
+ Streams.copy(reader, printWriter);
+ printWriter.println(end);
+ } finally {
+ reader.close();
+ }
+ } finally {
+ printWriter.close();
+ }
+ return true;
+ }
+
+ final File tempFile = File.createTempFile(file.getName() + ".", null);
+ PrintWriter printWriter = null;
+ BufferedReader contentReader = null;
+ BufferedReader existingFileReader = null;
+ try {
+ printWriter = new PrintWriter(new BufferedWriter(new FileWriter(tempFile)));
+ contentReader = (BufferedReader) content.reader(true);
+ existingFileReader = new BufferedReader(new FileReader(file));
+
+ // Copy existing file up to generated content opening delimiter
+ String line;
+ while ((line = existingFileReader.readLine()) != null) {
+ printWriter.println(line);
+ if (line.equals(start)) {
+ break;
+ }
+ }
+
+ if (line == null) {
+ throw new IOException("generated content starting delimiter \"" + start + "\" not found in existing file: " + file);
+ }
+
+ boolean changed = false;
+ boolean seenEnd = false;
+
+ // Copy new content, noting if it differs from existing generated content
+ while ((line = contentReader.readLine()) != null) {
+ if (!seenEnd) {
+ final String existingLine = existingFileReader.readLine();
+ if (existingLine != null) {
+ if (end.equals(existingLine)) {
+ seenEnd = true;
+ changed = true;
+ } else {
+ changed = changed || !line.equals(existingLine);
+ }
+ }
+ }
+ printWriter.println(line);
+ }
+
+ // Find the generated content closing delimiter
+ if (!seenEnd) {
+ while ((line = existingFileReader.readLine()) != null) {
+ if (line.equals(end)) {
+ seenEnd = true;
+ break;
+ }
+ changed = true;
+ }
+ if (!seenEnd) {
+ throw new IOException("generated content ending delimiter \"" + end + "\" not found in existing file: " + file);
+ }
+ }
+ printWriter.println(end);
+
+ // Copy existing file after generated content closing delimiter
+ while ((line = existingFileReader.readLine()) != null) {
+ printWriter.println(line);
+ }
+
+ printWriter.close();
+ printWriter = null;
+ existingFileReader.close();
+ existingFileReader = null;
+
+ if (changed) {
+ if (!checkOnly) {
+ copy(tempFile, file);
+ }
+ return true;
+ }
+ return false;
+ } finally {
+ quietClose(printWriter);
+ quietClose(contentReader);
+ quietClose(existingFileReader);
+ if (!tempFile.delete()) {
+ throw new IOException("could not delete file for update: " + file);
+ }
+ }
+ }
+
+ private static void quietClose(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static List find(File directory, final String suffix, List listing) {
+ final Predicate suffixPredicate = new Predicate() {
+ public boolean evaluate(File file) {
+ return file.getName().endsWith(suffix);
+ }
+
+ };
+ return find(directory, suffixPredicate, listing);
+ }
+
+ public static List find(File directory, Predicate filter, List listing) {
+ assert directory.isDirectory();
+ return find(directory, listing == null ? new LinkedList() : listing, filter);
+ }
+
+ private static List find(File directory, List listing, Predicate filter) {
+ assert directory.isDirectory();
+ final File[] entries = directory.listFiles();
+ if (entries != null) {
+ for (File entry : entries) {
+ if (!entry.isDirectory()) {
+ if (filter == null || filter.evaluate(entry)) {
+ listing.add(entry);
+ }
+ } else {
+ find(entry, listing, filter);
+ }
+ }
+ }
+ return listing;
+ }
+
+ public static void unzip(File zip, File destDir) {
+ if (!destDir.exists() && !destDir.mkdirs()) {
+ ProgramError.unexpected("Could not make directory " + destDir);
+ }
+ Enumeration entries;
+ ZipFile zipFile;
+ try {
+ Trace.line(2, "Extracting contents of " + zip.getAbsolutePath() + " to " + destDir);
+ zipFile = new ZipFile(zip);
+ entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ final ZipEntry entry = (ZipEntry) entries.nextElement();
+ final File parentDir;
+ if (entry.isDirectory()) {
+ parentDir = new File(destDir, entry.getName());
+ } else {
+ final String relParentDir = new File(entry.getName()).getParent();
+ if (relParentDir != null) {
+ parentDir = new File(destDir, relParentDir);
+ } else {
+ parentDir = destDir;
+ }
+ }
+ if (!parentDir.exists() && !parentDir.mkdirs()) {
+ ProgramError.unexpected("Could not make directory " + parentDir);
+ }
+ if (!entry.isDirectory()) {
+ final File destFile = new File(destDir, entry.getName());
+ Trace.line(2, " inflating: " + entry.getName() + " ...");
+ Streams.copy(zipFile.getInputStream(entry), new FileOutputStream(destFile));
+ }
+ }
+ zipFile.close();
+ } catch (IOException ioe) {
+ ProgramError.unexpected("Error extracting " + zip.getAbsolutePath() + " to " + destDir, ioe);
+ }
+ }
+
+ public static boolean compareFiles(File f1, File f2, String[] ignoredLinePatterns) {
+ try {
+ final BufferedReader f1Reader = new BufferedReader(new FileReader(f1));
+ final BufferedReader f2Reader = new BufferedReader(new FileReader(f2));
+ try {
+ String line1;
+ String line2;
+ nextLine:
+ while (true) {
+ line1 = f1Reader.readLine();
+ line2 = f2Reader.readLine();
+ if (line1 == null) {
+ if (line2 == null) {
+ return true;
+ }
+ return false;
+ }
+ if (!line1.equals(line2)) {
+ if (line2 == null) {
+ return false;
+ }
+ if (ignoredLinePatterns != null) {
+ for (String pattern : ignoredLinePatterns) {
+ if (line1.contains(pattern) && line2.contains(pattern)) {
+ continue nextLine;
+ }
+ }
+ }
+ return false;
+ }
+ }
+ } finally {
+ f1Reader.close();
+ f2Reader.close();
+ }
+ } catch (IOException e) {
+ return false;
+ }
+ }
+}
+
diff --git a/JavaInJava/src/com/sun/max/io/IndentWriter.java b/JavaInJava/src/com/sun/max/io/IndentWriter.java
new file mode 100644
index 0000000..93216b5
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/IndentWriter.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+import com.sun.max.program.*;
+
+/**
+ * A line oriented character writer that indents line output on the left.
+ *
+ * @author Bernd Mathiske
+ */
+public class IndentWriter {
+
+ private final PrintWriter writer;
+ private int lineCount;
+
+ /**
+ * Gets an IndentWriter that wraps the {@linkplain Trace#stream() trace stream}.
+ * @return
+ */
+ public static IndentWriter traceStreamWriter() {
+ return new IndentWriter(new OutputStreamWriter(Trace.stream()));
+ }
+
+ public IndentWriter(Writer writer) {
+ this.writer = (writer instanceof PrintWriter) ? (PrintWriter) writer : new PrintWriter(writer);
+ }
+
+ public void close() {
+ writer.close();
+ }
+
+ public void flush() {
+ writer.flush();
+ }
+
+ private int indentation = 4;
+
+ public int indentation() {
+ return indentation;
+ }
+
+ public void setIndentation(int indentation) {
+ this.indentation = indentation;
+ }
+
+ private int prefix;
+
+ public void indent() {
+ prefix += indentation;
+ }
+
+ public void outdent() {
+ prefix -= indentation;
+ assert prefix >= 0;
+ }
+
+ private boolean isCurrentLineIndented;
+
+ private void writeIndentation() {
+ if (!isCurrentLineIndented) {
+ for (int i = 0; i < prefix; i++) {
+ writer.print(" ");
+ }
+ isCurrentLineIndented = true;
+ }
+ }
+
+ public void printSpaces(int width) {
+ for (int i = 0; i < width; i++) {
+ writer.print(" ");
+ }
+ }
+
+ public void printFixedWidth(String s, int width) {
+ assert width > 0 : "width must be positive";
+ String text = s;
+ if (text.length() + 1 > width) {
+ if (width - 4 > 0) {
+ text = s.substring(0, width - 4) + "...";
+ } else {
+ text = s.substring(0, width);
+ }
+ }
+ writer.print(text);
+ printSpaces(width - text.length());
+ }
+
+ public void print(String s) {
+ writeIndentation();
+ writer.print(s);
+ }
+
+ public void println() {
+ writer.println();
+ isCurrentLineIndented = false;
+ ++lineCount;
+ }
+
+ public void println(String s) {
+ writeIndentation();
+ writer.println(s);
+ isCurrentLineIndented = false;
+ ++lineCount;
+ }
+
+ public void printLines(InputStream inputStream) {
+ printLines(new InputStreamReader(inputStream));
+ }
+
+ public void printLines(Reader reader) {
+ final BufferedReader bufferedReader = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
+ String line;
+ try {
+ while ((line = bufferedReader.readLine()) != null) {
+ println(line);
+ }
+ } catch (IOException e) {
+ ProgramWarning.message(e.toString());
+ }
+ }
+
+ public int lineCount() {
+ return lineCount;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/MultiOutputStream.java b/JavaInJava/src/com/sun/max/io/MultiOutputStream.java
new file mode 100644
index 0000000..04ead3c
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/MultiOutputStream.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ * Writes the same output to several streams.
+ *
+ * @author Bernd Mathiske
+ */
+public class MultiOutputStream extends OutputStream {
+
+ private final OutputStream[] streams;
+
+ public MultiOutputStream(OutputStream... streams) {
+ this.streams = streams;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ for (OutputStream stream : streams) {
+ stream.write(b);
+ }
+ }
+
+ @Override
+ public void write(byte[] bytes) throws IOException {
+ for (OutputStream stream : streams) {
+ stream.write(bytes);
+ }
+ }
+
+ @Override
+ public void write(byte[] bytes, int startOffset, int numberOfBytes) throws IOException {
+ for (OutputStream stream : streams) {
+ stream.write(bytes, startOffset, numberOfBytes);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ for (OutputStream stream : streams) {
+ stream.flush();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (OutputStream stream : streams) {
+ stream.close();
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/NullOutputStream.java b/JavaInJava/src/com/sun/max/io/NullOutputStream.java
new file mode 100644
index 0000000..5a1a0bb
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/NullOutputStream.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ * An output stream that discards everything written to it.
+ *
+ * @author Doug Simon
+ */
+public class NullOutputStream extends OutputStream {
+
+ @Override
+ public void write(int b) throws IOException {
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/Package.java b/JavaInJava/src/com/sun/max/io/Package.java
new file mode 100755
index 0000000..ddc44dc
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/Package.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import com.sun.max.*;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends BasePackage {
+ public Package() {
+ super();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/ReadableSource.java b/JavaInJava/src/com/sun/max/io/ReadableSource.java
new file mode 100644
index 0000000..8d9439a
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/ReadableSource.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ * A readable source is a character data source that provides a Reader to read the data.
+ *
+ * @author Doug Simon
+ */
+public interface ReadableSource {
+
+ /**
+ * @param buffered if true, the returned reader is guaranteed to be a BufferedReader
+ *
+ * @return a reader to read the character data represented by this source
+ */
+ Reader reader(boolean buffered) throws IOException;
+
+ public static final class Static {
+
+ private Static() {
+
+ }
+
+ /**
+ * Creates a ReadableSource to provides readers for the characters in a string.
+ */
+ public static ReadableSource fromString(final String s) {
+ return new ReadableSource() {
+ public Reader reader(boolean buffered) throws IOException {
+ return buffered ? new BufferedReader(new StringReader(s)) : new StringReader(s);
+ }
+ };
+ }
+
+ /**
+ * Creates a ReadableSource to provides readers for the characters in a file.
+ */
+ public static ReadableSource fromFile(final File file) {
+ return new ReadableSource() {
+ public Reader reader(boolean buffered) throws IOException {
+ return buffered ? new BufferedReader(new FileReader(file)) : new FileReader(file);
+ }
+ };
+
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/SeekableByteArrayOutputStream.java b/JavaInJava/src/com/sun/max/io/SeekableByteArrayOutputStream.java
new file mode 100644
index 0000000..a7f5a65
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/SeekableByteArrayOutputStream.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ * A {@link ByteArrayOutputStream} that can have its write position {@linkplain #seek(int) updated}.
+ *
+ * @author Doug Simon
+ */
+public class SeekableByteArrayOutputStream extends ByteArrayOutputStream {
+
+ private int highestCount;
+
+ /**
+ * @see ByteArrayOutputStream#ByteArrayOutputStream()
+ */
+ public SeekableByteArrayOutputStream() {
+ }
+
+ /**
+ * @see ByteArrayOutputStream#ByteArrayOutputStream(int)
+ */
+ public SeekableByteArrayOutputStream(int size) {
+ super(size);
+ }
+
+ /**
+ * Updates the write position of this stream. The stream can only be repositioned between 0 and the
+ * {@linkplain #endOfStream() end of the stream}.
+ *
+ * @param index
+ * the index to which the write position of this stream will be set
+ * @throws IllegalArgumentException
+ * if {@code index > highestSeekIndex()}
+ */
+ public void seek(int index) throws IllegalArgumentException {
+ if (endOfStream() < index) {
+ throw new IllegalArgumentException();
+ }
+ count = index;
+ }
+
+ /**
+ * Gets the index one past the highest index that has been written to in this stream.
+ */
+ public int endOfStream() {
+ if (highestCount < count) {
+ highestCount = count;
+ }
+ return highestCount;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ highestCount = 0;
+ }
+
+ /**
+ * Copies the {@code length} bytes of this byte array output stream starting at {@code offset} to {@code buf}
+ * starting at {@code bufOffset}.
+ */
+ public void copyTo(int offset, byte[] toBuffer, int toOffset, int length) {
+ System.arraycopy(this.buf, offset, toBuffer, toOffset, length);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/Streams.java b/JavaInJava/src/com/sun/max/io/Streams.java
new file mode 100644
index 0000000..3206a35
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/Streams.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+import com.sun.max.lang.*;
+
+/**
+ * Supplementary java.io utils.
+ *
+ * @author Bernd Mathiske
+ */
+public final class Streams {
+
+ private Streams() {
+ }
+
+ public static void copy(InputStream inputStream, OutputStream outputStream) throws IOException {
+ final byte[] buffer = new byte[8192];
+ int count;
+ while ((count = inputStream.read(buffer, 0, buffer.length)) > 0) {
+ outputStream.write(buffer, 0, count);
+ }
+ outputStream.flush();
+ }
+
+ public static void copy(Reader reader, Writer writer) throws IOException {
+ final char[] buffer = new char[8192];
+ int count;
+ while ((count = reader.read(buffer, 0, buffer.length)) > 0) {
+ writer.write(buffer, 0, count);
+ }
+ writer.flush();
+ }
+
+ public static boolean equals(InputStream inputStream1, InputStream inputStream2) throws IOException {
+ final int n = 8192;
+ final byte[] buffer1 = new byte[n];
+ final byte[] buffer2 = new byte[n];
+ while (true) {
+ final int n1 = inputStream1.read(buffer1, 0, n);
+ final int n2 = inputStream2.read(buffer2, 0, n);
+ if (n1 != n2) {
+ return false;
+ }
+ if (n1 <= 0) {
+ return true;
+ }
+ if (!Bytes.equals(buffer1, buffer2, n)) {
+ return false;
+ }
+ }
+ }
+
+ public static final class Redirector extends Thread {
+
+ private final InputStream inputStream;
+ private final OutputStream outputStream;
+ private final String name;
+ private final int maxLines;
+ private final Process process;
+ private boolean closed;
+
+ private Redirector(Process process, InputStream inputStream, OutputStream outputStream, String name, int maxLines) {
+ super("StreamRedirector{" + name + "}");
+ this.inputStream = inputStream;
+ this.outputStream = outputStream;
+ this.name = name;
+ this.maxLines = maxLines;
+ this.process = process;
+ start();
+ }
+
+ public void close() {
+ closed = true;
+ }
+
+ @Override
+ public void run() {
+ try {
+ try {
+ int line = 1;
+ while (!closed) {
+ if (inputStream.available() == 0) {
+ // A busy yielding loop is used so that this thread can be
+ // stopped via a call to close() by another thread. Otherwise,
+ // this thread could be blocked forever on an input stream
+ // that is not closed and does not have any available data.
+ // The prime example of course is System.in.
+ Thread.yield();
+ // wait for a few milliseconds to avoid eating too much CPU.
+ Thread.sleep(10);
+ continue;
+ }
+
+ final int b = inputStream.read();
+ if (b < 0) {
+ return;
+ }
+ if (line <= maxLines) {
+ outputStream.write(b);
+ }
+ if (b == '\n') {
+ if (line == maxLines) {
+ outputStream.write(("" + System.getProperty("line.separator", "\n")).getBytes());
+ }
+ ++line;
+ }
+ }
+ outputStream.flush();
+ } catch (IOException ioe) {
+ try {
+ process.exitValue();
+
+ // This just means the process was terminated and the relevant pipe no longer exists
+ } catch (IllegalThreadStateException e) {
+ // Some other unexpected IO error occurred -> rethrow
+ throw e;
+ }
+ }
+ } catch (Throwable throwable) {
+ if (name != null) {
+ System.err.println("Error while redirecting sub-process stream for \"" + name + "\"");
+ }
+ throwable.printStackTrace();
+ }
+ }
+
+ }
+
+ public static Redirector redirect(Process process, InputStream inputStream, OutputStream outputStream, String name, int maxLines) {
+ return new Redirector(process, inputStream, outputStream, name, maxLines);
+ }
+
+ public static Redirector redirect(Process process, InputStream inputStream, OutputStream outputStream, String name) {
+ return redirect(process, inputStream, outputStream, name, Integer.MAX_VALUE);
+ }
+
+ public static Redirector redirect(Process process, InputStream inputStream, OutputStream outputStream) {
+ return redirect(process, inputStream, outputStream, null, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Scans a given buffered input stream for a given sequence of bytes. If the sequence is found, then the read
+ * position of the stream is immediately after the sequence. Otherwise, the read position is at the end of the
+ * stream.
+ *
+ * @param stream
+ * the stream to search
+ * @param bytes
+ * the byte pattern to search for
+ * @return true if {@code bytes} is found in {@code stream}
+ */
+ public static boolean search(BufferedInputStream stream, byte[] bytes) throws IOException {
+ if (bytes.length == 0) {
+ return true;
+ }
+ int b1 = stream.read();
+ top:
+ while (b1 != -1) {
+ if (b1 == (bytes[0] & 0xff)) {
+ for (int i = 1; i < bytes.length; ++i) {
+ b1 = stream.read();
+ if (b1 != (bytes[i] & 0xff)) {
+ continue top;
+ }
+ }
+ return true;
+ }
+ b1 = stream.read();
+ }
+ return false;
+ }
+
+ /**
+ * Scans a given buffered reader for a given sequence of characters. If the sequence is found, then the read
+ * position of the reader is immediately after the sequence. Otherwise, the read position is at the end of the
+ * reader.
+ *
+ * @param reader
+ * the reader to search
+ * @param chars
+ * the char pattern to search for
+ * @return true if {@code chars} is found in {@code reader}
+ */
+ public static boolean search(BufferedReader reader, char[] chars) throws IOException {
+ if (chars.length == 0) {
+ return true;
+ }
+ int c1 = reader.read();
+ top:
+ while (c1 != -1) {
+ if (c1 == chars[0]) {
+ for (int i = 1; i < chars.length; ++i) {
+ c1 = reader.read();
+ if (c1 != chars[i]) {
+ continue top;
+ }
+ }
+ return true;
+ }
+ c1 = reader.read();
+ }
+ return false;
+ }
+
+ public static boolean startsWith(BufferedInputStream bufferedInputStream, byte[] bytes) throws IOException {
+ final byte[] data = new byte[bytes.length];
+ bufferedInputStream.mark(bytes.length);
+ try {
+ readFully(bufferedInputStream, data);
+ if (java.util.Arrays.equals(data, bytes)) {
+ return true;
+ }
+ } catch (IOException ioException) {
+ // This is OK
+ }
+ bufferedInputStream.reset();
+ return false;
+ }
+
+ public static boolean startsWith(BufferedReader bufferedReader, char[] chars) throws IOException {
+ final char[] data = new char[chars.length];
+ bufferedReader.mark(chars.length);
+ try {
+ readFully(bufferedReader, data);
+ if (java.util.Arrays.equals(data, chars)) {
+ return true;
+ }
+ } catch (IOException ioException) {
+ // This is OK
+ }
+ bufferedReader.reset();
+ return false;
+ }
+
+ /**
+ * @see DataInput#readFully(byte[])
+ */
+ public static byte[] readFully(InputStream stream, byte[] buffer) throws IOException {
+ return readFully(stream, buffer, 0, buffer.length);
+ }
+
+ /**
+ * @see DataInput#readFully(byte[], int, int)
+ */
+ public static byte[] readFully(InputStream stream, byte[] buffer, int offset, int length) throws IOException {
+ if (length < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int n = 0;
+ while (n < length) {
+ final int count = stream.read(buffer, offset + n, length - n);
+ if (count < 0) {
+ throw new EOFException((length - n) + " of " + length + " bytes unread");
+ }
+ n += count;
+ }
+ return buffer;
+ }
+
+ /**
+ * The analogous operation as {@link DataInput#readFully(byte[])} for {@link Reader}s.
+ */
+ public static char[] readFully(Reader reader, char[] buffer) throws IOException {
+ return readFully(reader, buffer, 0, buffer.length);
+ }
+
+ /**
+ * The analogous operation as {@link DataInput#readFully(byte[], int, int)} for {@link Reader}s.
+ */
+ public static char[] readFully(Reader reader, char[] buffer, int offset, int length) throws IOException {
+ if (length < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int n = 0;
+ while (n < length) {
+ final int count = reader.read(buffer, offset + n, length - n);
+ if (count < 0) {
+ throw new TruncatedInputException((length - n) + " of " + length + " characters unread", n);
+ }
+ n += count;
+ }
+ return buffer;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/TemporaryFiles.java b/JavaInJava/src/com/sun/max/io/TemporaryFiles.java
new file mode 100644
index 0000000..2296d41
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/TemporaryFiles.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+import com.sun.max.program.*;
+
+public final class TemporaryFiles {
+ private TemporaryFiles() {
+ }
+
+ public static void cleanup(final String prefix, final String suffix) {
+ if ((prefix == null || prefix.length() == 0) && (suffix == null || suffix.length() == 0)) {
+ return;
+ }
+ try {
+ final File tempFile = File.createTempFile(prefix, suffix);
+ final File directory = tempFile.getParentFile();
+ final FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (prefix != null && prefix.length() > 0 && !name.startsWith(prefix)) {
+ return false;
+ }
+ if (suffix != null && suffix.length() > 0 && !name.endsWith(suffix)) {
+ return false;
+ }
+ return true;
+ }
+ };
+ for (File file : directory.listFiles(filter)) {
+ if (!file.delete()) {
+ ProgramWarning.message("could not delete temporary file: " + file.getAbsolutePath());
+ }
+ }
+ } catch (IOException ioException) {
+ ProgramWarning.message("could not delete temporary files");
+ }
+ }
+
+ public static void cleanup(String prefix) {
+ cleanup(prefix, null);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/io/TruncatedInputException.java b/JavaInJava/src/com/sun/max/io/TruncatedInputException.java
new file mode 100644
index 0000000..5e024e4
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/TruncatedInputException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.io;
+
+import java.io.*;
+
+/**
+ * Unexpected EOF during input.
+ *
+ * @author Michael Van De Vanter
+ */
+public class TruncatedInputException extends EOFException {
+
+ private final int nRead;
+
+ /**
+ * @param s Exception message
+ * @param n Length of input read before EOF.
+ */
+ public TruncatedInputException(String s, int n) {
+ super(s);
+ nRead = n;
+ }
+
+ /**
+ *
+ * @return Length of input read before EOF.
+ */
+ public int inputLength() {
+ return nRead;
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/io/package-info.java b/JavaInJava/src/com/sun/max/io/package-info.java
new file mode 100644
index 0000000..6684cba
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/io/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * Supplementing java.io.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max.io;
diff --git a/JavaInJava/src/com/sun/max/lang/Bytes.java b/JavaInJava/src/com/sun/max/lang/Bytes.java
new file mode 100644
index 0000000..3ca16a6
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Bytes.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.io.*;
+
+import com.sun.max.io.*;
+import com.sun.max.util.*;
+
+/**
+ * Byte and byte array operations.
+ *
+ * @author Bernd Mathiske
+ * @author Michael Van De Vanter
+ */
+public final class Bytes {
+
+ private Bytes() {
+ }
+
+ public static final int SIZE = 1;
+ public static final int WIDTH = 8;
+ public static final int MASK = 0xff;
+
+ public static final Range VALUE_RANGE = new Range(Byte.MIN_VALUE, Byte.MAX_VALUE);
+
+ public static int zeroExtendedToInt(byte b) {
+ final char ch = (char) b;
+ return ch;
+ }
+
+ /**
+ * Returns the number of zero bits following the lowest-order ("rightmost")
+ * one-bit in the two's complement binary representation of the specified
+ * {@code byte} value. Returns 8 if the specified value has no
+ * one-bits in its two's complement representation, in other words if it is
+ * equal to zero.
+ *
+ * @return the number of zero bits following the lowest-order ("rightmost")
+ * one-bit in the two's complement binary representation of the
+ * specified {@code byte} value, or 8 if the value is equal
+ * to zero.
+ */
+ public static int numberOfTrailingZeros(byte b) {
+ // HD, Figure 5-14
+ int y;
+ int i = b & 0xFF;
+ if (i == 0) {
+ return 8;
+ }
+ int n = 7;
+ y = (i << 4) & 0xFF;
+ if (y != 0) {
+ n = n - 4;
+ i = y;
+ }
+ y = (i << 2) & 0xFF;
+ if (y != 0) {
+ n = n - 2;
+ i = y;
+ }
+ return n - (((i << 1) & 0xFF) >>> 7);
+ }
+
+ /**
+ * Are the bytes of an array, starting at some position, equal to the contents
+ * of a second array.
+ * @param array1 An array of bytes
+ * @param startIndex1 Index in {@code array1} at which to start comparison
+ * @param array2 An array of bytes to be compared
+ * @return tree iff the entire contents of {@code array2} are equal to
+ * the contents of {@code array1}, starting at {@code startIndex1}.
+ */
+ public static boolean equals(byte[] array1, int startIndex1, byte[] array2) {
+ if (array1.length < startIndex1 + array2.length) {
+ return false;
+ }
+ for (int i = 0; i < array2.length; i++) {
+ if (array1[startIndex1 + i] != array2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compares the first {@code length} bytes in two byte arrays
+ * for equality.
+ */
+ public static boolean equals(byte[] array1, byte[] array2, int length) {
+ if (array1.length < length || array2.length < length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (array1[i] != array2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compares the contents of two byte arrays for equality.
+ */
+ public static boolean equals(byte[] array1, byte[] array2) {
+ if (array1 == array2) {
+ return true;
+ }
+ if (array1.length != array2.length) {
+ return false;
+ }
+ return equals(array1, array2, array1.length);
+ }
+
+ public static void copy(byte[] fromArray, int fromStartIndex, byte[] toArray,
+ final int toStartIndex, int nBytes) {
+ for (int i = 0; i < nBytes; i++) {
+ toArray[toStartIndex + i] = fromArray[fromStartIndex + i];
+ }
+ }
+
+ public static void copy(byte[] fromArray, byte[] toArray, int nBytes) {
+ copy(fromArray, 0, toArray, 0, nBytes);
+ }
+
+ public static void copyAll(byte[] fromArray, byte[] toArray, int toStartIndex) {
+ copy(fromArray, 0, toArray, toStartIndex, fromArray.length);
+ }
+
+ public static void copyAll(byte[] fromArray, byte[] toArray) {
+ copy(fromArray, 0, toArray, 0, fromArray.length);
+ }
+
+ public static byte[] withLength(byte[] array, int length) {
+ final byte[] result = new byte[length];
+ if (length >= array.length) {
+ copyAll(array, result);
+ } else {
+ copy(array, result, length);
+ }
+ return result;
+ }
+
+ public static byte[] getSection(byte[] fromArray, int startIndex, int endIndex) {
+ final int length = endIndex - startIndex;
+ final byte[] result = new byte[length];
+ copy(fromArray, startIndex, result, 0, length);
+ return result;
+ }
+
+ /**
+ * Assigns zero to every byte in an array.
+ */
+ public static void clear(byte[] array) {
+ for (int i = 0; i < array.length; i++) {
+ array[i] = (byte) 0;
+ }
+ }
+
+ public static boolean areClear(byte[] array) {
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] != (byte) 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param value a byte
+ * @return A string representation of the byte in hexadecimal, e.g. "0x0A"
+ */
+ public static String toHexLiteral(byte value) {
+ String hexString = Integer.toHexString(value).toUpperCase();
+ if (hexString.length() == 1) {
+ hexString = "0" + hexString;
+ } else if (hexString.length() > 2) {
+ hexString = hexString.substring(hexString.length() - 2);
+ }
+ return "0x" + hexString;
+ }
+
+ /**
+ * @param values an array of bytes
+ * @return A string representation of the bytes in hexadecimal, e.g. "0x01A203"
+ */
+ public static String toHexLiteral(byte[] values) {
+ String s = "0x";
+ for (byte value : values) {
+ String hexString = Integer.toHexString(value).toUpperCase();
+ if (hexString.length() == 1) {
+ hexString = "0" + hexString;
+ }
+ s += hexString;
+ }
+ return s;
+ }
+
+ /**
+ * Returns a string representation of the contents of the specified array.
+ * Adjacent elements are separated by the specified separator. Elements are
+ * converted to strings with {@link #toHexLiteral(byte)}.
+ *
+ * @param array the array whose string representation to return
+ * @param separator the separator to use
+ * @return a string representation of array
+ * @throws NullPointerException if {@code array} or {@code separator} is null
+ */
+ public static String toHexString(byte[] array, String separator) {
+ if (array == null || separator == null) {
+ throw new NullPointerException();
+ }
+ if (array.length == 0) {
+ return "";
+ }
+
+ final StringBuilder buf = new StringBuilder();
+ buf.append(toHexLiteral(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ buf.append(separator);
+ buf.append(toHexLiteral(array[i]));
+ }
+
+ return buf.toString();
+ }
+
+ public static byte[] fromInputStream(InputStream inputStream) throws IOException {
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ Streams.copy(inputStream, outputStream);
+ return outputStream.toByteArray();
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Chars.java b/JavaInJava/src/com/sun/max/lang/Chars.java
new file mode 100644
index 0000000..f9b9986
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Chars.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import com.sun.max.util.*;
+
+/**
+ * @author Bernd Mathiske
+ */
+public final class Chars {
+
+ private Chars() {
+ }
+
+ public static final int SIZE = 2;
+
+ public static final Range VALUE_RANGE = new Range(Character.MIN_VALUE, Character.MAX_VALUE);
+
+ public static boolean isHexDigit(char c) {
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isOctalDigit(char c) {
+ if (c < '0') {
+ return false;
+ }
+ return c <= '7';
+ }
+
+ public static String toJavaLiteral(char c) {
+ if (c == '\n') {
+ return "'\\n'";
+ }
+ if (c == '\t') {
+ return "'\\t'";
+ }
+ if (c == '\r') {
+ return "'\\r'";
+ }
+ if (c < ' ' || c > 127) {
+ return "'\\" + Integer.toOctalString(c) + "'";
+ }
+ return "'" + c + "'";
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Classes.java b/JavaInJava/src/com/sun/max/lang/Classes.java
new file mode 100644
index 0000000..3bde311
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Classes.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.lang.reflect.*;
+
+import com.sun.max.*;
+
+/**
+ * Methods that might be members of java.lang.Class.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public final class Classes {
+
+ private Classes() {
+ }
+
+ /**
+ * Wraps a call to {@link ClassLoader#loadClass(String)} that is expected not to fail. Should a
+ * {@link ClassNotFoundException} occur, it is converted to {@link NoClassDefFoundError}
+ *
+ * @return the value returned by calling {@link ClassLoader#loadClass(String)} on {@code classLoader}
+ */
+ public static Class load(ClassLoader classLoader, String name) {
+ try {
+ return classLoader.loadClass(name);
+ } catch (ClassNotFoundException e) {
+ throw (NoClassDefFoundError) new NoClassDefFoundError(name).initCause(e);
+ }
+ }
+
+ /**
+ * Wraps a call to {@link Class#forName(String)} that is expected not to fail. Should a
+ * {@link ClassNotFoundException} occur, it is converted to {@link NoClassDefFoundError}
+ */
+ public static Class forName(String name) {
+ try {
+ return Class.forName(name);
+ } catch (ClassNotFoundException e) {
+ throw (NoClassDefFoundError) new NoClassDefFoundError(name).initCause(e);
+ }
+ }
+
+ /**
+ * Wraps a call to {@link Class#forName(String, boolean, ClassLoader)} that is expected not to fail. Should a
+ * {@link ClassNotFoundException} occur, it is converted to {@link NoClassDefFoundError}
+ */
+ public static Class forName(String name, boolean initialize, ClassLoader loader) {
+ try {
+ return Class.forName(name, initialize, loader);
+ } catch (ClassNotFoundException e) {
+ throw (NoClassDefFoundError) new NoClassDefFoundError(name).initCause(e);
+ }
+ }
+
+ /**
+ * Links a given class. If the class {@code c} has already been linked, then this method simply returns. Otherwise,
+ * the class is linked as described in the "Execution" chapter of the Java Language Specification.
+ *
+ * @param c the class to link
+ */
+ public static void link(Class c) {
+ if (c != null) {
+ try {
+ final Class> linkedClass = Class.forName(c.getName(), false, c.getClassLoader());
+ assert linkedClass == c;
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw (NoClassDefFoundError) new NoClassDefFoundError(c.getName()).initCause(classNotFoundException);
+ }
+ }
+ }
+
+ /**
+ * Initializes a given class. If the class {@code c} has already been initialized, then this method simply returns. Otherwise,
+ * the class is linked as described in the "Execution" chapter of the Java Language Specification.
+ *
+ * @param c the class to link
+ */
+ public static void initialize(Class c) {
+ try {
+ Class.forName(c.getName(), true, c.getClassLoader());
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw (NoClassDefFoundError) new NoClassDefFoundError(c.getName()).initCause(classNotFoundException);
+ }
+ }
+
+ public static boolean areRelated(Class> class1, Class> class2) {
+ return class1.isAssignableFrom(class2) || class2.isAssignableFrom(class1);
+ }
+
+ public static boolean areAssignableFrom(Class>[] superTypes, Class>... subTypes) {
+ if (superTypes.length != subTypes.length) {
+ return false;
+ }
+ for (int i = 0; i < superTypes.length; i++) {
+ if (!superTypes[i].isAssignableFrom(subTypes[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Extends the functionality of {@link Class#getConstructor(Class...)} to find a constructor whose formal parameter
+ * types are assignable from the types of a list of arguments.
+ *
+ * @param javaClass the class to search in
+ * @param arguments the list of arguments that will be passed to the constructor
+ * @return the first constructor in {@link Class#getConstructors() javaClass.getConstructors()} that will accept
+ * {@code arguments} or null if no such constructor exists
+ */
+ public static Constructor> findConstructor(Class> javaClass, Object... arguments) {
+ nextConstructor:
+ for (Constructor> constructor : javaClass.getConstructors()) {
+ final Class>[] parameterTypes = constructor.getParameterTypes();
+ if (parameterTypes.length == arguments.length) {
+ for (int i = 0; i != arguments.length; ++i) {
+ if (!parameterTypes[i].isAssignableFrom(arguments[i].getClass())) {
+ continue nextConstructor;
+ }
+ }
+ return constructor;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Extends the functionality of {@link Class#getMethod(String, Class...)} to find a method whose formal parameter
+ * types are assignable from the types of a list of arguments.
+ *
+ * @param javaClass the class to search in
+ * @param name the name of the method to search for
+ * @param arguments the list of arguments that will be passed to the constructor
+ * @return the first method in {@link Class#getMethods() javaClass.getMethods()} that will accept {@code arguments}
+ * or null if no such method exists
+ */
+ public static Method findMethod(Class> javaClass, String name, Object... arguments) {
+ nextMethod:
+ for (Method method : javaClass.getMethods()) {
+ final Class>[] parameterTypes = method.getParameterTypes();
+ if (method.getName().equals(name) && parameterTypes.length == arguments.length) {
+ for (int i = 0; i != arguments.length; ++i) {
+ if (!parameterTypes[i].isAssignableFrom(arguments[i].getClass())) {
+ continue nextMethod;
+ }
+ }
+ return method;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Extends the functionality of {@link Class#getDeclaredMethod(String, Class...)} to find a method whose formal
+ * parameter types are assignable from the types of a list of arguments.
+ *
+ * @param javaClass the class to search in
+ * @param name the name of the method to search for
+ * @param arguments the list of arguments that will be passed to the constructor
+ * @return the first method in {@link Class#getDeclaredMethods() javaClass.getDeclaredMethods()} that will accept
+ * {@code arguments} or null if no such method exists
+ */
+ public static Method findDeclaredMethod(Class> javaClass, String name, Object... arguments) {
+ nextMethod:
+ for (Method declaredMethod : javaClass.getDeclaredMethods()) {
+ final Class>[] parameterTypes = declaredMethod.getParameterTypes();
+ if (declaredMethod.getName().equals(name) && parameterTypes.length == arguments.length) {
+ for (int i = 0; i != arguments.length; ++i) {
+ if (!parameterTypes[i].isAssignableFrom(arguments[i].getClass())) {
+ continue nextMethod;
+ }
+ }
+ return declaredMethod;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Performs method resolution as detailed in section 5.4.3.3 of the JVM specification except for the accessibility
+ * checks detailed in section 5.4.4.
+ *
+ * @param javaClass the class to start the resolution from
+ * @param returnType the return type of the method to resolve
+ * @param name the name of the method to resolve
+ * @param parameterTypes the parameter types of the method to resolve
+ * @return the resolved method
+ * @throws NoSuchMethodError if the method resolution fails
+ * @throws AbstractMethodError if the resolved method is abstract
+ */
+ public static Method resolveMethod(Class> javaClass, Class returnType, String name, Class... parameterTypes) {
+ if (!name.equals("") && !name.equals("")) {
+ Class> declaringClass = javaClass;
+ if (javaClass.isInterface()) {
+ try {
+ return javaClass.getMethod(name, parameterTypes);
+ } catch (NoSuchMethodException e) {
+ throw new NoSuchMethodError(e.getMessage());
+ }
+ }
+ do {
+ try {
+ final Method method = getDeclaredMethod(declaringClass, returnType, name, parameterTypes);
+ if (Modifier.isAbstract(method.getModifiers()) && !Modifier.isAbstract(declaringClass.getModifiers())) {
+ throw new AbstractMethodError();
+ }
+ return method;
+ } catch (NoSuchMethodError e) {
+ declaringClass = declaringClass.getSuperclass();
+ }
+ } while (declaringClass != null);
+ }
+ throw new NoSuchMethodError(returnType.getName() + " " + javaClass.getName() + "." + name + "(" + Utils.toString(parameterTypes, ", ") + ")");
+ }
+
+ /**
+ * Performs field resolution as detailed in section 5.4.3.2 of the JVM specification except for the accessibility
+ * checks detailed in section 5.4.4.
+ * @param javaClass the class to start the resolution from
+ * @param type the type of the field to resolve
+ * @param name the name of the field to resolve
+ *
+ * @return the resolved field
+ * @throws NoSuchFieldError if the field resolution fails
+ */
+ public static Field resolveField(Class> javaClass, Class type, String name) {
+ Class> declaringClass = javaClass;
+ do {
+ try {
+ return getDeclaredField(declaringClass, name, type);
+ } catch (NoSuchFieldError e) {
+ for (Class superInterface : javaClass.getInterfaces()) {
+ try {
+ return resolveField(superInterface, type, name);
+ } catch (NoSuchFieldError noSuchFieldError) {
+ // Ignore
+ }
+ }
+ declaringClass = declaringClass.getSuperclass();
+ }
+ } while (declaringClass != null);
+ throw new NoSuchFieldError(type.getName() + " " + javaClass.getName() + "." + name);
+ }
+
+ /**
+ * Gets the class or interface that declares the method, field or constructor represented by {@code member}.
+ */
+ public static Class> getDeclaringClass(AccessibleObject member) {
+ if (member instanceof Method) {
+ final Method method = (Method) member;
+ return method.getDeclaringClass();
+ }
+ if (member instanceof Field) {
+ final Field field = (Field) member;
+ return field.getDeclaringClass();
+ }
+ assert member instanceof Constructor;
+ final Constructor constructor = (Constructor) member;
+ return constructor.getDeclaringClass();
+ }
+
+ /**
+ * Get hold of a non-public inner class.
+ */
+ public static Class getInnerClass(Class outerClass, String innerClassSimpleName) {
+ for (Class innerClass : outerClass.getDeclaredClasses()) {
+ if (innerClass.getSimpleName().equals(innerClassSimpleName)) {
+ return innerClass;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Extracts a package name from a fully qualified class name.
+ *
+ * @return "" if {@code className} denotes a class in the unnamed package
+ */
+ public static String getPackageName(String className) {
+ final int index = className.lastIndexOf('.');
+ if (index < 0) {
+ return "";
+ }
+ return className.substring(0, index);
+ }
+
+ /**
+ * Extracts a simple class name from a fully qualified class name.
+ */
+ public static String getSimpleName(String className) {
+ final int index = className.lastIndexOf('.');
+ if (index < 0) {
+ return className;
+ }
+ return className.substring(index + 1);
+ }
+
+ /**
+ * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for anonymous and local
+ * classes.
+ *
+ * @param clazz the class for which the simple name is being requested
+ * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) of the enclosing
+ * class/classes of {@code clazz} (if any). This option is ignored if {@code clazz} denotes an anonymous
+ * or local class.
+ * @return
+ */
+ public static String getSimpleName(Class> clazz, boolean withEnclosingClass) {
+ final String simpleName = clazz.getSimpleName();
+ if (simpleName.length() != 0) {
+ if (withEnclosingClass) {
+ String prefix = "";
+ Class enclosingClass = clazz;
+ while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) {
+ prefix = prefix + enclosingClass.getSimpleName() + ".";
+ }
+ return prefix + simpleName;
+ }
+ return simpleName;
+ }
+ // Must be an anonymous or local class
+ final String name = clazz.getName();
+ int index = name.indexOf('$');
+ if (index == -1) {
+ return name;
+ }
+ index = name.lastIndexOf('.', index);
+ if (index == -1) {
+ return name;
+ }
+ return name.substring(index + 1);
+ }
+
+ /**
+ * Similar to {@link Class#getDeclaredMethod(String, Class...)} except that
+ * the search takes into account the return type.
+ */
+ public static Method getDeclaredMethod(Class> clazz, Class returnType, String name, Class... parameterTypes) throws NoSuchMethodError {
+ for (Method javaMethod : clazz.getDeclaredMethods()) {
+ if (javaMethod.getName().equals(name) && javaMethod.getReturnType().equals(returnType)) {
+ final Class[] declaredParameterTypes = javaMethod.getParameterTypes();
+ if (java.util.Arrays.equals(declaredParameterTypes, parameterTypes)) {
+ return javaMethod;
+ }
+ }
+ }
+ throw new NoSuchMethodError(returnType.getName() + " " + clazz.getName() + "." + name + "(" + Utils.toString(parameterTypes, ",") + ")");
+ }
+
+ /**
+ * A wrapper for a call to {@link Class#getDeclaredMethod(String, Class...)} that must succeed.
+ */
+ public static Method getDeclaredMethod(Class> clazz, String name, Class... parameterTypes) {
+ try {
+ return clazz.getDeclaredMethod(name, parameterTypes);
+ } catch (NoSuchMethodException noSuchMethodException) {
+ throw (NoSuchMethodError) new NoSuchMethodError(clazz.getName() + "." + name + "(" + Utils.toString(parameterTypes, ",") + ")").initCause(noSuchMethodException);
+ }
+ }
+
+ /**
+ * A wrapper for a call to {@link Class#getDeclaredConstructor(Class...)} that must succeed.
+ */
+ public static Constructor getDeclaredConstructor(Class> clazz, Class... parameterTypes) {
+ try {
+ return clazz.getDeclaredConstructor(parameterTypes);
+ } catch (NoSuchMethodException noSuchMethodException) {
+ throw (NoSuchMethodError) new NoSuchMethodError(clazz.getName() + "(" + Utils.toString(parameterTypes, ",") + ")").initCause(noSuchMethodException);
+ }
+ }
+
+ /**
+ * A wrapper for a call to {@link Class#getDeclaredField(String)} that must succeed.
+ */
+ public static Field getDeclaredField(Class> clazz, String name) {
+ try {
+ return clazz.getDeclaredField(name);
+ } catch (NoSuchFieldException noSuchFieldException) {
+ throw (NoSuchFieldError) new NoSuchFieldError(clazz.getName() + "." + name).initCause(noSuchFieldException);
+ }
+ }
+
+ /**
+ * Similar to {@link Class#getDeclaredField(String)} except that the lookup takes into account a given field type.
+ */
+ public static Field getDeclaredField(Class> clazz, String name, Class type) throws NoSuchFieldError {
+ for (Field field : clazz.getDeclaredFields()) {
+ if (field.getName().equals(name) && field.getType().equals(type)) {
+ return field;
+ }
+ }
+ throw new NoSuchFieldError(type.getName() + " " + clazz.getName() + "." + name);
+ }
+
+ public static void main(Class> classToRun, String[] args) {
+ try {
+ final Method mainMethod = classToRun.getMethod("main", String[].class);
+ mainMethod.invoke(null, (Object) args);
+ } catch (Exception e) {
+ throw (Error) new Error().initCause(e);
+ }
+ }
+
+ public static void main(String classToRun, String[] args) {
+ main(forName(classToRun), args);
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Endianness.java b/JavaInJava/src/com/sun/max/lang/Endianness.java
new file mode 100644
index 0000000..6192538
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Endianness.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.io.*;
+import java.nio.*;
+
+/**
+ * Enumerated type with values for the most common more ways to arrange bits, bytes, etc.
+ *
+ * @author Bernd Mathiske
+ */
+public enum Endianness {
+
+ LITTLE {
+ @Override
+ public short readShort(InputStream stream) throws IOException {
+ final int low = readByte(stream) & 0xff;
+ final int high = readByte(stream);
+ return (short) ((high << 8) | low);
+ }
+
+ @Override
+ public int readInt(InputStream stream) throws IOException {
+ final int low = readShort(stream) & 0xffff;
+ final int high = readShort(stream);
+ return (high << 16) | low;
+ }
+
+ @Override
+ public long readLong(InputStream stream) throws IOException {
+ final long low = readInt(stream) & 0xffffffffL;
+ final long high = readInt(stream);
+ return (high << 32) | low;
+ }
+
+ @Override
+ public void writeShort(OutputStream stream, short value) throws IOException {
+ short v = value;
+ stream.write(v & 0xff);
+ v >>= 8;
+ stream.write(v & 0xff);
+ }
+
+ @Override
+ public void writeInt(OutputStream stream, int value) throws IOException {
+ int v = value;
+ stream.write(v & 0xff);
+ v >>= 8;
+ stream.write(v & 0xff);
+ v >>= 8;
+ stream.write(v & 0xff);
+ v >>= 8;
+ stream.write(v & 0xff);
+ }
+
+ @Override
+ public void writeLong(OutputStream stream, long value) throws IOException {
+ long v = value;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ v >>= 8;
+ stream.write((int) v & 0xff);
+ }
+
+ @Override
+ public byte[] toBytes(short value) {
+ short v = value;
+ final byte[] bytes = new byte[2];
+ bytes[0] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[1] = (byte) (v & 0xff);
+ return bytes;
+ }
+
+ @Override
+ public byte[] toBytes(int value) {
+ int v = value;
+ final byte[] bytes = new byte[4];
+ bytes[0] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[1] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[2] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[3] = (byte) (v & 0xff);
+ return bytes;
+ }
+
+ @Override
+ public byte[] toBytes(long value) {
+ long v = value;
+ final byte[] bytes = new byte[8];
+ bytes[0] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[1] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[2] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[3] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[4] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[5] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[6] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[7] = (byte) (v & 0xff);
+ return bytes;
+ }
+
+ @Override
+ public void toBytes(short value, byte[] result, int offset) {
+ short v = value;
+ for (int i = 0; i < Shorts.SIZE && i < result.length; i++) {
+ result[i + offset] = (byte) (v & 0xff);
+ v >>= 8;
+ }
+ }
+
+ @Override
+ public void toBytes(int value, byte[] result, int offset) {
+ int v = value;
+ for (int i = 0; i < Ints.SIZE && i < result.length; i++) {
+ result[i + offset] = (byte) (v & 0xff);
+ v >>= 8;
+ }
+ }
+
+ @Override
+ public void toBytes(long value, byte[] result, int offset) {
+ long v = value;
+ for (int i = 0; i < Longs.SIZE && i < result.length; i++) {
+ result[i + offset] = (byte) (v & 0xff);
+ v >>= 8;
+ }
+ }
+
+ @Override
+ public int offsetWithinWord(WordWidth wordWidth, WordWidth dataWidth) {
+ return 0;
+ }
+
+ @Override
+ public ByteOrder asByteOrder() {
+ return ByteOrder.LITTLE_ENDIAN;
+ }
+ },
+ BIG {
+ @Override
+ public short readShort(InputStream stream) throws IOException {
+ final int high = readByte(stream);
+ final int low = readByte(stream) & 0xff;
+ return (short) ((high << 8) | low);
+ }
+
+ @Override
+ public int readInt(InputStream stream) throws IOException {
+ final int high = readShort(stream);
+ final int low = readShort(stream) & 0xffff;
+ return (high << 16) | low;
+ }
+
+ @Override
+ public long readLong(InputStream stream) throws IOException {
+ final long high = readInt(stream);
+ final long low = readInt(stream) & 0xffffffffL;
+ return (high << 32) | low;
+ }
+
+ @Override
+ public void writeShort(OutputStream stream, short value) throws IOException {
+ stream.write((value >> 8) & 0xff);
+ stream.write(value & 0xff);
+ }
+
+ @Override
+ public void writeInt(OutputStream stream, int value) throws IOException {
+ stream.write((value >> 24) & 0xff);
+ stream.write((value >> 16) & 0xff);
+ stream.write((value >> 8) & 0xff);
+ stream.write(value & 0xff);
+ }
+
+ @Override
+ public void writeLong(OutputStream stream, long value) throws IOException {
+ stream.write((int) (value >> 56) & 0xff);
+ stream.write((int) (value >> 48) & 0xff);
+ stream.write((int) (value >> 40) & 0xff);
+ stream.write((int) (value >> 32) & 0xff);
+ stream.write((int) (value >> 24) & 0xff);
+ stream.write((int) (value >> 16) & 0xff);
+ stream.write((int) (value >> 8) & 0xff);
+ stream.write((int) value & 0xff);
+ }
+
+ @Override
+ public byte[] toBytes(short value) {
+ short v = value;
+ final byte[] bytes = new byte[2];
+ bytes[1] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[0] = (byte) (v & 0xff);
+ return bytes;
+ }
+
+ @Override
+ public byte[] toBytes(int value) {
+ int v = value;
+ final byte[] bytes = new byte[4];
+ bytes[3] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[2] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[1] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[0] = (byte) (v & 0xff);
+ return bytes;
+ }
+
+ @Override
+ public byte[] toBytes(long value) {
+ long v = value;
+ final byte[] bytes = new byte[8];
+ bytes[7] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[6] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[5] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[4] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[3] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[2] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[1] = (byte) (v & 0xff);
+ v >>= 8;
+ bytes[0] = (byte) (v & 0xff);
+ return bytes;
+ }
+
+ @Override
+ public void toBytes(short value, byte[] result, int offset) {
+ short v = value;
+ int toIndex = offset + Shorts.SIZE - 1;
+ for (int i = 1; i <= Shorts.SIZE && i <= result.length; i++) {
+ result[toIndex--] = (byte) (v & 0xff);
+ v >>= 8;
+ }
+ }
+
+ @Override
+ public void toBytes(int value, byte[] result, int offset) {
+ int v = value;
+ int toIndex = offset + Ints.SIZE - 1;
+ for (int i = 1; i <= Ints.SIZE && i <= result.length; i++) {
+ result[toIndex--] = (byte) (v & 0xff);
+ v >>= 8;
+ }
+ }
+
+ @Override
+ public void toBytes(long value, byte[] result, int offset) {
+ long v = value;
+ int toIndex = offset + Longs.SIZE - 1;
+ for (int i = 1; i <= Longs.SIZE && i <= result.length; i++) {
+ result[toIndex--] = (byte) (v & 0xff);
+ v >>= 8;
+ }
+ }
+
+ @Override
+ public int offsetWithinWord(WordWidth wordWidth, WordWidth dataWidth) {
+ assert wordWidth.numberOfBytes >= dataWidth.numberOfBytes;
+ return wordWidth.numberOfBytes - dataWidth.numberOfBytes;
+ }
+
+ @Override
+ public ByteOrder asByteOrder() {
+ return ByteOrder.BIG_ENDIAN;
+ }
+ };
+
+ @Override
+ public String toString() {
+ return name().toLowerCase();
+ }
+
+ public byte readByte(InputStream stream) throws IOException {
+ final int result = stream.read();
+ if (result < 0) {
+ throw new IOException();
+ }
+ return (byte) result;
+ }
+
+ public abstract short readShort(InputStream stream) throws IOException;
+
+ public abstract int readInt(InputStream stream) throws IOException;
+
+ public abstract long readLong(InputStream stream) throws IOException;
+
+ public abstract void writeShort(OutputStream stream, short value) throws IOException;
+
+ public abstract void writeInt(OutputStream stream, int value) throws IOException;
+
+ public abstract void writeLong(OutputStream stream, long value) throws IOException;
+
+ public byte[] toBytes(byte value) {
+ final byte[] bytes = new byte[1];
+ bytes[0] = value;
+ return bytes;
+ }
+
+ public abstract byte[] toBytes(short value);
+
+ public abstract byte[] toBytes(int value);
+
+ public abstract byte[] toBytes(long value);
+
+ public void toBytes(byte value, byte[] result, int offset) {
+ if (result.length > 0) {
+ result[0] = value;
+ }
+ }
+
+ public abstract void toBytes(short value, byte[] result, int offset);
+
+ public abstract void toBytes(int value, byte[] result, int offset);
+
+ public abstract void toBytes(long value, byte[] result, int offset);
+
+ public abstract int offsetWithinWord(WordWidth wordWith, WordWidth dataWidth);
+
+ public abstract ByteOrder asByteOrder();
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Function.java b/JavaInJava/src/com/sun/max/lang/Function.java
new file mode 100644
index 0000000..b6c44e9
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Function.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.util.concurrent.*;
+
+/**
+ * Creates a function wrapper for a method that returns a value and may throw a checked exception.
+ * This interface extends {@link Callable} so that {@code Function}s can be used with an {@link ExecutorService}.
+ *
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public interface Function extends Callable {
+
+ /**
+ * Computes a result, or throws an exception if unable to do so.
+ *
+ * @return computed result (which will be {@code null} if {@code Result_Type} is {@link Void})
+ * @throws Exception if unable to compute a result
+ */
+ T call() throws Exception;
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Ints.java b/JavaInJava/src/com/sun/max/lang/Ints.java
new file mode 100644
index 0000000..a746847
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Ints.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import com.sun.max.annotate.*;
+import com.sun.max.util.*;
+
+/**
+ * Additional methods that one might want in java.lang.Integer
+ * and int array stuff.
+ *
+ * @author Bernd Mathiske
+ * @author Paul Caprioli
+ */
+public final class Ints {
+
+ // Utility classes should not be instantiated.
+ private Ints() {
+ }
+
+ public static final int SIZE = 4;
+ public static final int WIDTH = 32;
+
+ public static final Range VALUE_RANGE = new Range(Integer.MIN_VALUE, Integer.MAX_VALUE);
+
+ public static final int K = 1024;
+ public static final int M = K * K;
+
+ public static int compare(int greater, int lesser) {
+ if (greater > lesser) {
+ return 1;
+ }
+ if (greater == lesser) {
+ return 0;
+ }
+ return -1;
+ }
+
+ public static int numberOfEffectiveSignedBits(int signed) {
+ if (signed >= 0) {
+ return 33 - Integer.numberOfLeadingZeros(signed);
+ }
+ return 33 - Integer.numberOfLeadingZeros(~signed);
+ }
+
+ public static int numberOfEffectiveUnsignedBits(int unsigned) {
+ return 32 - Integer.numberOfLeadingZeros(unsigned);
+ }
+
+ /**
+ * Returns an integer with all the bits in its two's complement binary representation that are at index {@code
+ * highestBitIndex} or lower set to 1.
+ *
+ * @param highestBitIndex the index of the highest bit to be set in the returned value. Only the low 5 bits of {@code
+ * highestBitIndex} are used. That is, if {@code highestBitIndex > 31} or {@code highestBitIndex < 0} then
+ * the highest bit to be set is given by {@code highestBitSet & 0x1F}.
+ */
+ public static int lowBitsSet(int highestBitIndex) {
+ final int n = highestBitIndex & 0x1f;
+ return (1 << n) | ((1 << n) - 1);
+ }
+
+ /**
+ * Returns an integer with all the bits in its two's complement binary representation that are at index {@code
+ * lowestBitIndex} or higher set to 1.
+ *
+ * @param lowestBitIndex the index of the lowest bit to be set in the returned value. Only the low 5 bits of {@code
+ * lowestBitIndex} are used. That is, if {@code lowestBitIndex > 31} or {@code lowestBitIndex < 0} then
+ * the lowest bit to be set is given by {@code lowestBitSet & 0x1F}.
+ */
+ public static int highBitsSet(int lowestBitIndex) {
+ return ~((1 << lowestBitIndex) - 1);
+ }
+
+ /**
+ * Determines if a given number is zero or a power of two.
+ */
+ public static boolean isPowerOfTwoOrZero(int n) {
+ return Integer.lowestOneBit(n) == n;
+ }
+
+ public static int log2(int n) {
+ if (n <= 0) {
+ throw new ArithmeticException();
+ }
+ return 31 - Integer.numberOfLeadingZeros(n);
+ }
+
+ public static int roundUp(int value, int by) {
+ final int rest = value % by;
+ if (rest == 0) {
+ return value;
+ }
+ if (value < 0) {
+ return value - rest;
+ }
+ return value + (by - rest);
+ }
+
+ /**
+ * Calculates an unsigned integer which is greater than or equal to {@code value} and
+ * is a multiple of {@code by}. Results are undefined if {@code by} is not
+ * a power of two.
+ * @param value the unsigned integer which is to be rounded upwards.
+ * @param by a positive power of two.
+ * @return the unsigned integer calculated by rounding upwards to a multiple of {@code by}.
+ */
+ @INLINE
+ public static int roundUnsignedUpByPowerOfTwo(int value, int by) {
+ assert isPowerOfTwoOrZero(by);
+ final int mask = by - 1;
+ return (value + mask) & ~mask;
+ }
+
+ /**
+ * Returns the hexadecimal string representation of the given value with at least 8 digits, e.g. 0x0000CAFE.
+ */
+ public static String toHexLiteral(int value) {
+ return "0x" + toPaddedHexString(value, '0');
+ }
+
+ /**
+ * Returns the given value as a hexadecimal number with at least 8 digits, e.g. 0000CAFE.
+ */
+ public static String toPaddedHexString(int n, char pad) {
+ final String s = Integer.toHexString(n).toUpperCase();
+ return Strings.times(pad, 8 - s.length()) + s;
+ }
+
+ public static boolean contains(int[] array, int value) {
+ for (int element : array) {
+ if (element == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static int[] append(int[] array, int element) {
+ final int resultLength = array.length + 1;
+ final int[] result = new int[resultLength];
+ System.arraycopy(array, 0, result, 0, array.length);
+ result[array.length] = element;
+ return result;
+ }
+
+ public static int[] append(int[] head, int[] tail) {
+ final int[] result = new int[head.length + tail.length];
+ System.arraycopy(head, 0, result, 0, head.length);
+ System.arraycopy(tail, 0, result, head.length, tail.length);
+ return result;
+ }
+
+ public static int[] createRange(int first, int last) {
+ if (first > last) {
+ throw new IllegalArgumentException();
+ }
+ final int n = last + 1 - first;
+ final int[] result = new int[n];
+ for (int i = 0; i < n; i++) {
+ result[i] = first + i;
+ }
+ return result;
+ }
+
+ public static void copyAll(int[] fromArray, int[] toArray) {
+ for (int i = 0; i < fromArray.length; i++) {
+ toArray[i] = fromArray[i];
+ }
+ }
+
+ /**
+ * Returns a string representation of the contents of the specified array.
+ * Adjacent elements are separated by the specified separator. Elements are
+ * converted to strings as by String.valueOf(int).
+ *
+ * @param array the array whose string representation to return
+ * @param separator the separator to use
+ * @return a string representation of array
+ * @throws NullPointerException if {@code array} or {@code separator} is null
+ */
+ public static String toString(int[] array, String separator) {
+ if (array == null || separator == null) {
+ throw new NullPointerException();
+ }
+ if (array.length == 0) {
+ return "";
+ }
+
+ final StringBuilder buf = new StringBuilder();
+ buf.append(array[0]);
+
+ for (int i = 1; i < array.length; i++) {
+ buf.append(separator);
+ buf.append(array[i]);
+ }
+
+ return buf.toString();
+ }
+
+ private static final int [] sizeBase10Table = {
+ 9,
+ 99,
+ 999,
+ 9999,
+ 99999,
+ 999999,
+ 9999999,
+ 99999999,
+ 999999999, Integer.MAX_VALUE
+ };
+
+ /**
+ * Computes the numbers of characters in the base-10 string representation of a given integer, including the '-'
+ * prefix for a negative integer. That is, this method computes the length of the String returned by
+ * {@link Integer#toString(int)} without requiring a String object to be created.
+ *
+ * @param i an integer
+ * @return the length of the string that would be returned by calling {@link Integer#toString(int)} with {@code i}
+ * as the argument
+ */
+ public static int sizeOfBase10String(int x) {
+ if (x == Integer.MIN_VALUE) {
+ return "-2147483648".length();
+ }
+ final int posX = x < 0 ? -x : x;
+ for (int i = 0;; i++) {
+ if (posX <= sizeBase10Table[i]) {
+ if (x < 0) {
+ return i + 2;
+ }
+ return i + 1;
+ }
+ }
+ }
+
+ /**
+ * @see Longs#toUnitsString(long, boolean)
+ */
+ public static String toUnitsString(long number, boolean onlyPowerOfTwo) {
+ return Longs.toUnitsString(number, onlyPowerOfTwo);
+ }
+
+ /**
+ * Computes the minimum value in an array of integers.
+ *
+ * @param ints the array of integers from which the minimum is computed. This array must have at least one element.
+ * @return the minimum value in {@code ints}
+ * @throws ArrayIndexOutOfBoundsException if {@code ints.length == 0}
+ */
+ public static int min(int[] ints) {
+ int min = ints[0];
+ for (int n : ints) {
+ if (n < min) {
+ min = n;
+ }
+ }
+ return min;
+ }
+
+ /**
+ * Computes the maximum value in an array of integers.
+ *
+ * @param ints the array of integers from which the maximum is computed. This array must have at least one element.
+ * @return the maximum value in {@code ints}
+ * @throws ArrayIndexOutOfBoundsException if {@code ints.length == 0}
+ */
+ public static int max(int[] ints) {
+ int max = ints[0];
+ for (int n : ints) {
+ if (n > max) {
+ max = n;
+ }
+ }
+ return max;
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Longs.java b/JavaInJava/src/com/sun/max/lang/Longs.java
new file mode 100644
index 0000000..26533fe
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Longs.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+/**
+ * Additional methods that one might want in java.lang.Long.
+ *
+ * @author Bernd Mathiske
+ */
+public final class Longs {
+
+ private Longs() {
+ }
+
+ public static final int SIZE = 8;
+ public static final int WIDTH = 64;
+
+ public static final long INT_MASK = 0xffffffffL;
+
+ public static int compare(long greater, long lesser) {
+ if (greater > lesser) {
+ return 1;
+ }
+ if (greater == lesser) {
+ return 0;
+ }
+ return -1;
+ }
+
+ public static int numberOfEffectiveSignedBits(long signed) {
+ if (signed >= 0) {
+ return 65 - Long.numberOfLeadingZeros(signed);
+ }
+ return 65 - Long.numberOfLeadingZeros(~signed);
+ }
+
+ public static int numberOfEffectiveUnsignedBits(long unsigned) {
+ return 64 - Long.numberOfLeadingZeros(unsigned);
+ }
+
+ public static byte getByte(long value, int index) {
+ return (byte) ((value >> (index * 8)) & 0xffL);
+ }
+
+ public static String toPaddedHexString(long n, char pad) {
+ final String s = Long.toHexString(n);
+ return Strings.times(pad, 16 - s.length()) + s;
+ }
+
+ /**
+ * Determines if a given number is zero or a power of two.
+ */
+ public static boolean isPowerOfTwoOrZero(long n) {
+ return Long.lowestOneBit(n) == n;
+ }
+
+ public static final long K = 1024;
+ public static final long M = K * K;
+ public static final long G = M * K;
+ public static final long T = G * K;
+ public static final long P = T * K;
+
+ /**
+ * Converts a positive number to a string using unit suffixes to reduce the
+ * number of digits to three or less using base 2 for sizes.
+ *
+ * @param number the number to convert to a string
+ * @param onlyPowerOfTwo if {@code true}, then a unit suffix is only used if {@code number} is an exact power of 2
+ */
+ public static String toUnitsString(long number, boolean onlyPowerOfTwo) {
+ if (number < 0) {
+ throw new IllegalArgumentException(String.valueOf(number));
+ }
+ if (onlyPowerOfTwo && !isPowerOfTwoOrZero(number)) {
+ return String.valueOf(number);
+ }
+ if (number >= P) {
+ return number / P + "P";
+ }
+ if (number >= T) {
+ return number / T + "T";
+ }
+ if (number >= G) {
+ return number / G + "G";
+ }
+ if (number >= M) {
+ return number / M + "M";
+ }
+ if (number >= K) {
+ return number / K + "K";
+ }
+ return Long.toString(number);
+ }
+
+ /**
+ * Parse a size specification nX, where X := {K, M, G, T, P, k, m, g, t, p}.
+ *
+ * @param value a string containing a long number that can be parsed by {@link Long#parseLong(String)} followed by
+ * an optional scaling character
+ * @return the scaled value
+ * @throws NumberFormatException if {@code value} does not contain a parsable {@code long} or has an invalid scale
+ * suffix
+ */
+ public static long parseScaledValue(String value) throws NumberFormatException {
+ char lastChar = value.charAt(value.length() - 1);
+ if (!Character.isDigit(lastChar)) {
+ long result = Long.parseLong(value.substring(0, value.length() - 1));
+ switch (lastChar) {
+ case 'K':
+ case 'k': {
+ return result * Longs.K;
+ }
+ case 'M':
+ case 'm': {
+ return result * Longs.M;
+ }
+ case 'G':
+ case 'g': {
+ return result * Longs.G;
+ }
+ case 'T':
+ case 't': {
+ return result * Longs.T;
+ }
+ case 'P':
+ case 'p': {
+ return result * Longs.P;
+ }
+ default: {
+ throw new NumberFormatException("Number with unknown scale suffix: " + value);
+ }
+ }
+ }
+ return Long.parseLong(value);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/lang/MutableInnerClassGlobal.java b/JavaInJava/src/com/sun/max/lang/MutableInnerClassGlobal.java
new file mode 100644
index 0000000..1ebc933
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/MutableInnerClassGlobal.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+/**
+ * Globals to inner classes must be final, so we need to box them somehow
+ * if we want them to have a mutable global.
+ *
+ * @author Bernd Mathiske
+ */
+public class MutableInnerClassGlobal {
+
+ private T value;
+
+ public T value() {
+ return value;
+ }
+
+ public MutableInnerClassGlobal() {
+ }
+
+ public MutableInnerClassGlobal(T value) {
+ this.value = value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Package.java b/JavaInJava/src/com/sun/max/lang/Package.java
new file mode 100644
index 0000000..bc31413
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Package.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import com.sun.max.*;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends BasePackage {
+ public Package() {
+ super();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Procedure.java b/JavaInJava/src/com/sun/max/lang/Procedure.java
new file mode 100644
index 0000000..e2696ca
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Procedure.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+/**
+ * @author Bernd Mathiske
+ */
+public interface Procedure {
+
+ void run(T argument);
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Shorts.java b/JavaInJava/src/com/sun/max/lang/Shorts.java
new file mode 100644
index 0000000..1a335fa
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Shorts.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import com.sun.max.util.*;
+
+/**
+ * @author Bernd Mathiske
+ */
+public final class Shorts {
+
+ private Shorts() {
+ }
+
+ public static final int SIZE = 2;
+ public static final int WIDTH = 16;
+ public static final int MASK = 0xffff;
+
+ public static final Range VALUE_RANGE = new Range(Short.MIN_VALUE, Short.MAX_VALUE);
+}
diff --git a/JavaInJava/src/com/sun/max/lang/StaticFieldLiteral.java b/JavaInJava/src/com/sun/max/lang/StaticFieldLiteral.java
new file mode 100644
index 0000000..76e26a4
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/StaticFieldLiteral.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.lang.reflect.*;
+
+import com.sun.max.program.*;
+
+public interface StaticFieldLiteral {
+
+ String literal();
+
+ void setLiteral(String literal);
+
+ Class literalClass();
+
+ void setLiteralClass(Class literalClass);
+
+ public static final class Static {
+
+ private Static() {
+ }
+
+ public static void initialize(Class staticFieldLiteralClass) {
+ for (Field field : staticFieldLiteralClass.getDeclaredFields()) {
+ if ((field.getModifiers() & Modifier.STATIC) != 0 && StaticFieldLiteral.class.isAssignableFrom(field.getType())) {
+ field.setAccessible(true);
+ try {
+ final StaticFieldLiteral staticFieldLiteral = (StaticFieldLiteral) field.get(staticFieldLiteralClass);
+ staticFieldLiteral.setLiteral(field.getName());
+ staticFieldLiteral.setLiteralClass(staticFieldLiteralClass);
+ } catch (IllegalAccessException illegalAccessException) {
+ ProgramError.unexpected("could not name literal of field: " + field);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/StaticFieldName.java b/JavaInJava/src/com/sun/max/lang/StaticFieldName.java
new file mode 100644
index 0000000..d0cb9d4
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/StaticFieldName.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.sun.max.program.*;
+
+public interface StaticFieldName {
+
+ String name();
+
+ void setName(String name);
+
+ public interface StringFunction {
+ String function(String string);
+ }
+
+ public interface Procedure {
+ void procedure(StaticFieldName staticFieldName);
+ }
+
+ public static final class Static {
+
+ private Static() {
+ }
+
+ public static List initialize(Class staticNameFieldClass, StringFunction stringFunction, Procedure procedure) {
+ final List sequence = new LinkedList();
+ for (Field field : staticNameFieldClass.getDeclaredFields()) {
+ if ((field.getModifiers() & Modifier.STATIC) != 0 && StaticFieldName.class.isAssignableFrom(field.getType())) {
+ field.setAccessible(true);
+ try {
+ final StaticFieldName value = (StaticFieldName) field.get(null);
+ if (value.name() == null) {
+ String name = field.getName();
+ if (stringFunction != null) {
+ name = stringFunction.function(name);
+ }
+ value.setName(name);
+ }
+ if (procedure != null) {
+ procedure.procedure(value);
+ }
+ sequence.add(value);
+ } catch (IllegalAccessException illegalAccessException) {
+ ProgramError.unexpected("could not name value of field: " + field);
+ }
+ }
+ }
+ return sequence;
+ }
+
+ public static List initialize(Class staticNameFieldClass, StringFunction stringFunction) {
+ return initialize(staticNameFieldClass, stringFunction, null);
+ }
+
+ public static List initialize(Class staticNameFieldClass, Procedure procedure) {
+ return initialize(staticNameFieldClass, null, procedure);
+ }
+
+ public static List initialize(Class staticNameFieldClass) {
+ return initialize(staticNameFieldClass, null, null);
+ }
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Strings.java b/JavaInJava/src/com/sun/max/lang/Strings.java
new file mode 100644
index 0000000..37a585c
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Strings.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Additional String-related operations.
+ *
+ * @author Bernd Mathiske
+ */
+public final class Strings {
+
+ private Strings() {
+ }
+
+ /**
+ * @param stream
+ * the input stream to be read in its entirety and then closed
+ * @return the contents of the input stream as a String, with line breaks
+ * @throws IOException
+ * as usual
+ */
+ public static String fromInputStream(InputStream stream) throws IOException {
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+ final StringBuffer result = new StringBuffer();
+ final String lineSeparator = System.getProperty("line.separator");
+ while (true) {
+ final String line = reader.readLine();
+ if (line == null) {
+ stream.close();
+ return result.toString();
+ }
+ result.append(line);
+ result.append(lineSeparator);
+ }
+ }
+
+ public static String firstCharToLowerCase(String s) {
+ if (s == null || s.length() == 0) {
+ return s;
+ }
+ return s.substring(0, 1).toLowerCase() + s.substring(1);
+ }
+
+ public static String firstCharToUpperCase(String s) {
+ if (s == null || s.length() == 0) {
+ return s;
+ }
+ return s.substring(0, 1).toUpperCase() + s.substring(1);
+ }
+
+ public static String times(char ch, int nTimes) {
+ if (nTimes <= 0) {
+ return "";
+ }
+ final char[] chars = new char[nTimes];
+ for (int i = 0; i < nTimes; i++) {
+ chars[i] = ch;
+ }
+ return new String(chars);
+ }
+
+ private static final char[] SPACES;
+ static {
+ SPACES = new char[200];
+ java.util.Arrays.fill(SPACES, ' ');
+ }
+
+ public static String spaces(int nSpaces) {
+ if (nSpaces <= 0) {
+ return "";
+ }
+ if (nSpaces <= SPACES.length) {
+ return new String(SPACES, 0, nSpaces);
+ }
+ return times(' ', nSpaces);
+ }
+
+ /**
+ * @return The String {@code s} padded out to {@code length}, if needed, by appending space characters
+ */
+ public static String padLengthWithSpaces(String s, int length) {
+ if (s.length() >= length) {
+ return s;
+ }
+ return s + spaces(length - s.length());
+ }
+
+ /**
+ * @return The string {@code s} padded out to {@code length}, if needed, by prepending space characters
+ */
+ public static String padLengthWithSpaces(int length, String s) {
+ if (s.length() >= length) {
+ return s;
+ }
+ return spaces(length - s.length()) + s;
+ }
+
+ private static final char[] ZEROES;
+ static {
+ ZEROES = new char[200];
+ java.util.Arrays.fill(ZEROES, '0');
+ }
+
+ public static String zeroes(int nZeroes) {
+ if (nZeroes <= 0) {
+ return "";
+ }
+ if (nZeroes <= ZEROES.length) {
+ return new String(ZEROES, 0, nZeroes);
+ }
+ return times(' ', nZeroes);
+ }
+
+ /**
+ * @return The String {@code s} padded out to {@code length}, if needed, by appending zero characters
+ */
+ public static String padLengthWithZeroes(String s, int length) {
+ if (s.length() >= length) {
+ return s;
+ }
+ return s + zeroes(length - s.length());
+ }
+
+ /**
+ * @return The string {@code s} padded out to {@code length}, if needed, by prepending zero characters
+ */
+ public static String padLengthWithZeroes(int length, String s) {
+ if (s.length() >= length) {
+ return s;
+ }
+ return zeroes(length - s.length()) + s;
+ }
+
+ /**
+ * Finds the index of the first non-escaped instance of {@code c} in {@code s} starting at {@code fromIndex}.
+ * The search takes into account that the escape char (i.e. {@code '\'}) may itself be escaped.
+ *
+ * @return -1 if the char could not be found
+ */
+ public static int indexOfNonEscapedChar(char c, String s, int fromIndex) {
+ int index = s.indexOf(c, fromIndex);
+ while (index != -1) {
+ if (index > 0 && (s.charAt(index - 1) != '\\') || (index > 1 && s.charAt(index - 2) == '\\')) {
+ return index;
+ }
+ index = s.indexOf(c, index + 1);
+ }
+ return -1;
+ }
+
+ /**
+ * Parses a command line into a string array appropriate for calling {@link Runtime#exec(String[])}.
+ * The given command line is tokenized around {@link Character#isWhitespace(char) whitespaces}
+ * except for sequences of characters enclosed in non-escaped double quotes (after the double
+ * quotes are removed).
+ */
+ public static String[] splitCommand(String command) {
+ final List parts = new ArrayList();
+
+ boolean escapedChar = false;
+ boolean insideQuotes = false;
+
+ final char[] buffer = new char[command.length()];
+ int pos = 0;
+
+ for (int index = 0; index < command.length(); ++index) {
+ final char ch = command.charAt(index);
+ if (escapedChar) {
+ escapedChar = false;
+ } else {
+ if (ch == '\\') {
+ escapedChar = true;
+ } else {
+ if (insideQuotes) {
+ if (ch == '"') {
+ insideQuotes = false;
+ continue;
+ }
+ } else {
+ if (ch == '"') {
+ insideQuotes = true;
+ continue;
+ } else if (Character.isWhitespace(ch)) {
+ if (pos != 0) {
+ parts.add(new String(buffer, 0, pos));
+ pos = 0;
+ }
+ continue;
+
+ }
+ }
+ }
+ }
+ buffer[pos++] = ch;
+ }
+
+ if (insideQuotes) {
+ throw new IllegalArgumentException("unclosed quotes");
+ }
+ if (escapedChar) {
+ throw new IllegalArgumentException("command line cannot end with escape char '\\'");
+ }
+ if (pos != 0) {
+ parts.add(new String(buffer, 0, pos));
+ }
+ return parts.toArray(new String[parts.size()]);
+ }
+
+ public static String truncate(String s, int maxLength) {
+ if (maxLength < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (s.length() <= maxLength) {
+ return s;
+ }
+ return s.substring(0, maxLength) + "...";
+ }
+
+ /**
+ * Capitalizes the first character in a given string.
+ *
+ * @param string the string to process
+ * @param lowercaseTail if true, the remaining characters in {@code string} are converted to lower case
+ */
+ public static String capitalizeFirst(String string, boolean lowercaseTail) {
+ final String tail = string.substring(1);
+ return Character.toUpperCase(string.charAt(0)) + (lowercaseTail ? tail.toLowerCase() : tail);
+ }
+
+ /**
+ * Chops the last {@code count} from a given string.
+ *
+ * @param s the string to chop
+ * @param count the number of characters to chop from the end of {@code s}
+ * @return the chopped string
+ * @throws IndexOutOfBoundsException if {@code count < 0} or {@code count > s.length()}
+ */
+ public static String chopSuffix(String s, int count) {
+ return s.substring(0, s.length() - count);
+ }
+
+ /**
+ * Chops the last {@code suffix.length()} from a given string. Calling this method is
+ * equivalent to {@link #chopSuffix(String, int) chop(s, suffix.length())}.
+ */
+ public static String chopSuffix(String s, String suffix) {
+ return chopSuffix(s, suffix.length());
+ }
+
+ /**
+ * Prepends {@code n} space characters to every line in String {@code lines},
+ * including a possibly non-empty line following the final newline.
+ * Returns {@code lines} if {@code spaces <= 0}
+ */
+ public static String indent(String lines, int spaces) {
+ return indent(lines, spaces(spaces));
+ }
+
+ /**
+ * Prepends the String {@code indentation} to every line in String {@code lines},
+ * including a possibly non-empty line following the final newline.
+ */
+ public static String indent(String lines, String indentation) {
+ if (lines.length() == 0) {
+ return lines;
+ }
+ final String newLine = "\n";
+ if (lines.endsWith(newLine)) {
+ return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
+ }
+ return indentation + lines.replace(newLine, newLine + indentation);
+ }
+
+ public static String formatParagraphs(String s, int leftJust, int pindent, int width) {
+ final int len = s.length();
+ int indent = pindent;
+ indent += leftJust;
+ int consumed = indent + leftJust;
+ final String indstr = space(indent);
+ final String ljstr = space(leftJust);
+ final StringBuffer buf = new StringBuffer(s.length() + 50);
+ buf.append(indstr);
+ int lastSp = -1;
+ for (int cntr = 0; cntr < len; cntr++) {
+ final char c = s.charAt(cntr);
+ if (c == '\n') {
+ buf.append('\n');
+ consumed = indent;
+ buf.append(indstr);
+ continue;
+ } else if (Character.isWhitespace(c)) {
+ lastSp = buf.length();
+ }
+ buf.append(c);
+ consumed++;
+
+ if (consumed > width) {
+ if (lastSp >= 0) {
+ buf.setCharAt(lastSp, '\n');
+ buf.insert(lastSp + 1, ljstr);
+ consumed = buf.length() - lastSp + leftJust - 1;
+ }
+ }
+ }
+ return buf.toString();
+ }
+
+ protected static final String[] spacers = {
+ "", // 0
+ " ", // 1
+ " ", // 2
+ " ", // 3
+ " ", // 4
+ " ", // 5
+ " ", // 6
+ " ", // 7
+ " ", // 8
+ " ", // 9
+ " ", // 10
+ };
+
+ public static void appendFract(StringBuffer buf, double val, int digits) {
+ int cntr = 0;
+ for (int radix = 10; cntr < digits; radix = radix * 10, cntr++) {
+ if (cntr == 0) {
+ buf.append('.');
+ }
+ final int digit = (int) (val * radix) % 10;
+ buf.append((char) (digit + '0'));
+ }
+ }
+
+ public static String fixedDouble(double fval, int places) {
+ if (Double.isInfinite(fval)) {
+ return "(inf)";
+ }
+ if (Double.isNaN(fval)) {
+ return "(NaN)";
+ }
+
+ final StringBuffer buf = new StringBuffer(places + 5);
+ // append the whole part
+ final long val = (long) fval;
+ buf.append(val);
+ // append the fractional part
+ final double fract = fval >= 0 ? fval - val : val - fval;
+ appendFract(buf, fract, places);
+
+ return buf.toString();
+ }
+
+ public static String space(int len) {
+ if (len <= 0) {
+ return "";
+ }
+ if (len < spacers.length) {
+ return spacers[len];
+ }
+ return times(' ', len);
+ }
+
+ public static void space(StringBuffer buf, int len) {
+ int i = 0;
+ while (i++ < len) {
+ buf.append(' ');
+ }
+ }
+
+ public static String concat(String first, String second, String separator) {
+ if (!first.isEmpty()) {
+ return first + separator + second;
+ }
+ return second;
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/lang/WordWidth.java b/JavaInJava/src/com/sun/max/lang/WordWidth.java
new file mode 100644
index 0000000..86c4c88
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/WordWidth.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.util.*;
+
+/**
+ * A word width value describes how many bits there are in a machine word.
+ *
+ * @author Bernd Mathiske
+ */
+public enum WordWidth {
+
+ BITS_8(8, byte.class, Byte.MIN_VALUE, Byte.MAX_VALUE, 3),
+ BITS_16(16, short.class, Short.MIN_VALUE, Short.MAX_VALUE, 4),
+ BITS_32(32, int.class, Integer.MIN_VALUE, Integer.MAX_VALUE, 5),
+ BITS_64(64, long.class, Long.MIN_VALUE, Long.MAX_VALUE, 6);
+
+ public static final List VALUES = java.util.Arrays.asList(values());
+
+ /**
+ * Number of bits in a Word.
+ * This must be a positive power of two.
+ */
+ public final int numberOfBits;
+
+ /**
+ * Log2 of the number of bits.
+ */
+ public final int log2numberOfBits;
+
+ /**
+ * Log2 of the number of bytes.
+ */
+ public final int log2numberOfBytes;
+
+ /**
+ * Number of bytes in a Word.
+ * This must be a positive power of two.
+ */
+ public final int numberOfBytes;
+
+ public final Class canonicalPrimitiveType;
+ public final long min;
+ public final long max;
+
+ private WordWidth(int numberOfBits, Class canonicalPrimitiveType, long min, long max, int log2numberOfBits) {
+ this.numberOfBits = numberOfBits;
+ this.numberOfBytes = numberOfBits / 8;
+ this.canonicalPrimitiveType = canonicalPrimitiveType;
+ this.min = min;
+ this.max = max;
+ this.log2numberOfBits = log2numberOfBits;
+ this.log2numberOfBytes = log2numberOfBits - 3;
+ }
+
+ public boolean lessThan(WordWidth other) {
+ return numberOfBits < other.numberOfBits;
+ }
+
+ public boolean lessEqual(WordWidth other) {
+ return numberOfBits <= other.numberOfBits;
+ }
+
+ public boolean greaterThan(WordWidth other) {
+ return numberOfBits > other.numberOfBits;
+ }
+
+ public boolean greaterEqual(WordWidth other) {
+ return numberOfBits >= other.numberOfBits;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(numberOfBits);
+ }
+
+ public static WordWidth fromInt(int wordWidth) {
+ if (wordWidth <= 8) {
+ return WordWidth.BITS_8;
+ }
+ if (wordWidth <= 16) {
+ return WordWidth.BITS_16;
+ }
+ if (wordWidth <= 32) {
+ return WordWidth.BITS_32;
+ }
+ return WordWidth.BITS_64;
+ }
+
+ /**
+ * @return which word width is minimally required to represent all the non-one bits in the signed argument, and a sign bit
+ */
+ public static WordWidth signedEffective(int signed) {
+ return fromInt(Ints.numberOfEffectiveSignedBits(signed));
+ }
+
+ /**
+ * @return which word width is minimally required to represent all the non-zero bits in the unsigned argument
+ */
+ public static WordWidth unsignedEffective(int unsigned) {
+ return fromInt(Ints.numberOfEffectiveUnsignedBits(unsigned));
+ }
+
+ /**
+ * @return which word width is minimally required to represent all the non-one bits in the signed argument, and a sign bit
+ */
+ public static WordWidth signedEffective(long signed) {
+ return fromInt(Longs.numberOfEffectiveSignedBits(signed));
+ }
+
+ /**
+ * @return which word width is minimally required to represent all the non-zero bits in the unsigned argument
+ */
+ public static WordWidth unsignedEffective(long unsigned) {
+ return fromInt(Longs.numberOfEffectiveUnsignedBits(unsigned));
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/lang/package-info.java b/JavaInJava/src/com/sun/max/lang/package-info.java
new file mode 100644
index 0000000..fc2ee2f
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * Supplementing java.lang.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max.lang;
diff --git a/JavaInJava/src/com/sun/max/package-info.java b/JavaInJava/src/com/sun/max/package-info.java
new file mode 100644
index 0000000..a1ac5be
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * Project Maxine software
+ *
+ * The top level package contains classes that provide package info manipulation operations.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max;
diff --git a/JavaInJava/src/com/sun/max/program/ClassSearch.java b/JavaInJava/src/com/sun/max/program/ClassSearch.java
new file mode 100644
index 0000000..bfb2e9b
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/ClassSearch.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+import com.sun.max.lang.*;
+
+/**
+ * Provides a facility for finding classes reachable on a given {@linkplain Classpath classpath}.
+ *
+ * @author Doug Simon
+ */
+public class ClassSearch extends ClasspathTraversal {
+
+ private final HashSet classes;
+
+ public ClassSearch() {
+ this(false);
+ }
+
+ /**
+ * Creates a class search object.
+ *
+ * @param omitDuplicates if true, then each argument passed to {@link #visitClass(String)} is guaranteed to be unique.
+ */
+ public ClassSearch(boolean omitDuplicates) {
+ if (omitDuplicates) {
+ classes = new HashSet();
+ } else {
+ classes = null;
+ }
+ }
+
+ /**
+ * Handles a class file encountered during the traversal.
+ *
+ * @param className
+ * the name of the class denoted by the class file
+ * @return true if the traversal should continue, false if it should terminate
+ */
+ protected boolean visitClass(String className) {
+ return true;
+ }
+
+ /**
+ * Handles a class file encountered during the traversal. Unless this object was initialized to omit duplicates,
+ * this method may be called more than once for the same class as class files are not guaranteed to be unique in a
+ * classpath.
+ *
+ * @param isArchiveEntry true if the class is in a .zip or .jar file, false if it is a file in a directory
+ * @param className the name of the class denoted by the class file
+ * @return true if the traversal should continue, false if it should terminate
+ */
+ protected boolean visitClass(boolean isArchiveEntry, String className) {
+ if (classes != null) {
+ if (classes.contains(className)) {
+ return true;
+ }
+ classes.add(className);
+ }
+ return visitClass(className);
+ }
+
+ protected boolean visit(boolean isArchiveEntry, String dottifiedResource) {
+ if (dottifiedResource.endsWith(".class")) {
+ final String className = Strings.chopSuffix(dottifiedResource, ".class");
+ return visitClass(isArchiveEntry, className);
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean visitArchiveEntry(ZipFile archive, ZipEntry resource) {
+ return visit(true, resource.getName().replace('/', '.'));
+ }
+
+ @Override
+ protected boolean visitFile(File parent, String resource) {
+ return visit(false, resource.replace(File.separatorChar, '.'));
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/Classpath.java b/JavaInJava/src/com/sun/max/program/Classpath.java
new file mode 100755
index 0000000..c909a93
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/Classpath.java
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+import com.sun.max.io.*;
+
+/**
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public class Classpath {
+
+ private static final List EMPTY_LIST = Collections.emptyList();
+
+ public static final Classpath EMPTY = new Classpath(EMPTY_LIST);
+
+ private final List entries;
+
+ private final Map classpathFileMap = new HashMap();
+
+ /**
+ * An entry in a classpath is a file system path that denotes an existing {@linkplain Directory directory},
+ * an existing {@linkplain Archive zip/jar} file or a {@linkplain PlainFile neither}.
+ */
+ public abstract static class Entry {
+
+ /**
+ * Gets the string representing the underlying path of this entry.
+ */
+ public final String path() {
+ return file().getPath();
+ }
+
+ /**
+ * Gets the File object representing the underlying path of this entry.
+ */
+ public abstract File file();
+
+ /**
+ * Gets the contents of a file denoted by a given path that is relative to this classpath entry. If the denoted
+ * file does not exist under this classpath entry then {@code null} is returned. Any IO exception that occurs
+ * when reading is silently ignored.
+ *
+ * @param path a file path relative to this classpath entry. This values uses the '/' character as the path
+ * separator regardless of the {@linkplain File#separatorChar default} for the underlying platform.
+ */
+ abstract ClasspathFile readFile(String path);
+
+ public boolean isDirectory() {
+ return false;
+ }
+
+ public boolean isArchive() {
+ return false;
+ }
+
+ public boolean isPlainFile() {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return path();
+ }
+
+ public ZipFile zipFile() {
+ return null;
+ }
+ }
+
+ /**
+ * Represents a classpath entry that is neither an existing directory nor an existing zip/jar archive file.
+ */
+ static final class PlainFile extends Entry {
+
+ private final File file;
+
+ public PlainFile(File file) {
+ this.file = file;
+ }
+
+ @Override
+ ClasspathFile readFile(String path) {
+ return null;
+ }
+
+ @Override
+ public File file() {
+ return file;
+ }
+
+ @Override
+ public boolean isPlainFile() {
+ return true;
+ }
+ }
+
+ /**
+ * Represents a classpath entry that is a path to an existing directory.
+ */
+ static final class Directory extends Entry {
+ private final File directory;
+
+ public Directory(File directory) {
+ this.directory = directory;
+ }
+
+ @Override
+ ClasspathFile readFile(String path) {
+ final File file = new File(directory, File.separatorChar == '/' ? path : path.replace('/', File.separatorChar));
+ if (file.exists()) {
+ try {
+ return new ClasspathFile(Files.toBytes(file), this);
+ } catch (IOException ioException) {
+ ProgramWarning.message("Error reading from " + file + ": " + ioException);
+ return null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public File file() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return true;
+ }
+ }
+
+ /**
+ * Represents a classpath entry that is a path to an existing zip/jar archive file.
+ */
+ static final class Archive extends Entry {
+
+ private final File file;
+ private ZipFile zipFile;
+
+ public Archive(File file) {
+ this.file = file;
+ }
+
+ @Override
+ public ZipFile zipFile() {
+ if (zipFile == null && file != null) {
+ try {
+ zipFile = new ZipFile(file);
+ } catch (IOException e) {
+ ProgramWarning.message("Error opening ZIP file: " + file.getPath());
+ e.printStackTrace();
+ }
+ }
+ return zipFile;
+ }
+
+ @Override
+ ClasspathFile readFile(String path) {
+ final ZipFile zf = zipFile();
+ if (zf == null) {
+ return null;
+ }
+ try {
+ final ZipEntry zipEntry = zf.getEntry(path);
+ if (zipEntry != null) {
+ return new ClasspathFile(readZipEntry(zf, zipEntry), this);
+ }
+ } catch (IOException ioException) {
+ //ProgramWarning.message("could not read ZIP file: " + file);
+ }
+ return null;
+ }
+
+ @Override
+ public File file() {
+ return file;
+ }
+
+ @Override
+ public boolean isArchive() {
+ return true;
+ }
+ }
+
+ /**
+ * Gets the ordered entries from which this classpath is composed.
+ *
+ * @return a sequence of {@code Entry} objects
+ */
+ public List entries() {
+ return entries;
+ }
+
+ /**
+ * Creates a classpath {@link Entry} from a given file system path.
+ *
+ * @param path a file system path denoting a classpath entry
+ */
+ public static Entry createEntry(String path) {
+ final File pathFile = new File(path);
+ if (pathFile.isDirectory()) {
+ return new Directory(pathFile);
+ } else if (path.endsWith(".zip") || path.endsWith(".jar")) {
+ if (pathFile.exists() && pathFile.isFile()) {
+ return new Archive(pathFile);
+ }
+ }
+ //ProgramWarning.message("Class path entry is neither a directory nor a JAR file: " + path);
+ return new PlainFile(pathFile);
+ }
+
+ /**
+ * Creates a new classpath from an array of classpath entries.
+ *
+ * @param paths an array of classpath entries
+ */
+ public Classpath(String[] paths) {
+ final Entry[] entryArray = new Entry[paths.length];
+ for (int i = 0; i < paths.length; ++i) {
+ final String path = paths[i];
+ entryArray[i] = createEntry(path);
+ }
+ this.entries = Arrays.asList(entryArray);
+ }
+
+ /**
+ * Creates a new classpath from a sequence of classpath entries.
+ *
+ * @param paths a sequence of classpath entries
+ */
+ public Classpath(List entries) {
+ this.entries = entries;
+ }
+
+ /**
+ * Creates a new classpath by parsing a string of classpath entries separated by the system dependent
+ * {@linkplain File#pathSeparator path separator}.
+ *
+ * @param paths a string of classpath entries separated by ':' or ';'
+ */
+ public Classpath(String paths) {
+ this(paths.split(File.pathSeparator));
+ }
+
+ /**
+ * Gets the classpath derived from the value of the {@code "java.ext.dirs"} system property.
+ *
+ * @see "http://java.sun.com/javase/6/docs/technotes/guides/extensions/extensions.html"
+ */
+ private static String extensionClasspath() {
+ final String extDirs = System.getProperty("java.ext.dirs");
+ if (extDirs != null) {
+ final StringBuilder buf = new StringBuilder();
+ for (String extDirPath : extDirs.split(File.pathSeparator)) {
+ final File extDir = new File(extDirPath);
+ if (extDir.isDirectory()) {
+ for (File file : extDir.listFiles()) {
+ if (file.isDirectory() ||
+ (file.isFile() && (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")))) {
+ if (buf.length() != 0) {
+ buf.append(File.pathSeparatorChar);
+ }
+ buf.append(file.getAbsolutePath());
+ }
+ }
+ } else {
+ // Ignore non-directory
+ }
+ }
+ if (buf.length() != 0) {
+ buf.append(File.pathSeparatorChar);
+ return buf.toString();
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Gets a classpath corresponding to the class search order used by the application class loader.
+ */
+ public static Classpath fromSystem() {
+ final String value = System.getProperty("sun.boot.class.path") + File.pathSeparator + extensionClasspath() + System.getProperty("java.class.path");
+ return new Classpath(value.split(File.pathSeparator));
+ }
+
+ /**
+ * Gets a classpath corresponding to the class search order used by the boot class loader.
+ */
+ public static Classpath bootClassPath() {
+ final String value = System.getProperty("sun.boot.class.path");
+ if (value == null) {
+ return EMPTY;
+ }
+ return new Classpath(value.split(File.pathSeparator));
+ }
+
+ /**
+ * Gets a new classpath obtained by prepending a given classpath to this class classpath.
+ *
+ * @param classpath the classpath to prepend to this classpath
+ * @return the result of prepending {@code classpath} to this classpath
+ */
+ public Classpath prepend(Classpath classpath) {
+ ArrayList entries = new ArrayList(this.entries.size() + classpath.entries.size());
+ entries.addAll(classpath.entries);
+ entries.addAll(this.entries);
+ return new Classpath(entries);
+ }
+
+ /**
+ * Gets a new classpath obtained by prepending a given classpath to this class classpath.
+ *
+ * @param classpath the classpath to prepend to this classpath
+ * @return the result of prepending {@code classpath} to this classpath
+ */
+ public Classpath prepend(String path) {
+ ArrayList entries = new ArrayList(this.entries.size());
+ entries.add(createEntry(path));
+ entries.addAll(this.entries);
+ return new Classpath(entries);
+ }
+
+ /**
+ * Searches for a class file denoted by a given class name on this classpath and returns its contents in a byte array if
+ * found. Any IO exception that occurs when reading is silently ignored.
+ *
+ * @param className a fully qualified class name (e.g. "java.lang.Class")
+ * @return the contents of the file available on the classpath whose name is computed as
+ * {@code className.replace('.', '/')}. If no such file is available on this class path or if
+ * reading the file produces an IO exception, then null is returned.
+ */
+ public ClasspathFile readClassFile(String className) {
+ return readFile(className, ".class");
+ }
+
+ /**
+ * Searches for a file denoted by a given class name on this classpath and returns its contents in a byte array if
+ * found. Any IO exception that occurs when reading is silently ignored.
+ *
+ * @param className a fully qualified class name (e.g. "java.lang.Class")
+ * @param extension a file extension
+ * @return the contents of the file available on the classpath whose name is computed as
+ * {@code className.replace('.', '/') + extension}. If no such file is available on this class path or if
+ * reading the file produces an IO exception, then null is returned.
+ */
+ public ClasspathFile readFile(String className, String extension) {
+ final String path = className.replace('.', '/') + extension;
+ for (Entry entry : entries()) {
+ ClasspathFile classpathFile = null;
+ classpathFile = entry.readFile(path);
+ if (classpathFile != null) {
+ recordPackage(className, classpathFile);
+ return classpathFile;
+ }
+ }
+ return null;
+ }
+
+ private void recordPackage(String className, ClasspathFile classpathFile) {
+ final int ix = className.lastIndexOf('.');
+ final String packageName = ix < 0 ? "/" : className.substring(0, ix + 1).replace('.', '/');
+ if (!classpathFileMap.containsKey(packageName)) {
+ classpathFileMap.put(packageName, classpathFile);
+ }
+ }
+
+ /**
+ * Searches for an existing file corresponding to an directory entry in this classpath composed with a given path
+ * suffix.
+ *
+ * @param suffix a file path relative to a directory entry of this classpath
+ * @return a file corresponding to the {@linkplain File#File(File, String) composition} of the first directory entry
+ * of this classpath with {@code suffix} that denotes an existing file or null if so such file exists
+ */
+ public File findFile(String suffix) {
+ for (Entry entry : entries()) {
+ if (entry instanceof Directory) {
+ final File file = new File(((Directory) entry).directory, suffix);
+ if (file.exists()) {
+ return file;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static byte[] readZipEntry(ZipFile zipFile, ZipEntry zipEntry) throws IOException {
+ final byte[] bytes = new byte[(int) zipEntry.getSize()];
+ final InputStream zipStream = new BufferedInputStream(zipFile.getInputStream(zipEntry), bytes.length);
+ try {
+ int offset = 0;
+ while (offset < bytes.length) {
+ final int n = zipStream.read(bytes, offset, bytes.length - offset);
+ if (n <= 0) {
+ //ProgramWarning.message("truncated ZIP file: " + zipFile);
+ }
+ offset += n;
+ }
+ } finally {
+ zipStream.close();
+ }
+ return bytes;
+ }
+
+ @Override
+ public String toString() {
+ if (entries == null || entries.isEmpty()) {
+ return "";
+ }
+ String s = entries.toString().replace(", ", File.pathSeparator);
+ return s.substring(1, s.length() - 1);
+ }
+
+ public ClasspathFile classpathFileForPackage(String name) {
+ return classpathFileMap.get(name);
+ }
+
+ /**
+ * Converts this object to a String array with one array element for each classpath entry.
+ *
+ * @return the newly created String array with one element per classpath entry
+ */
+ public String[] toStringArray() {
+ final String[] result = new String[entries().size()];
+ int z = 0;
+ for (Classpath.Entry e : entries()) {
+ result[z] = e.path();
+ z++;
+ }
+ return result;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/ClasspathFile.java b/JavaInJava/src/com/sun/max/program/ClasspathFile.java
new file mode 100644
index 0000000..495e740
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/ClasspathFile.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+import com.sun.max.program.Classpath.*;
+
+/**
+ * Encapulates the contents of a file loaded from an {@linkplain Entry entry} on a {@linkplain Classpath classpath}.
+ *
+ * @author Doug Simon
+ */
+public final class ClasspathFile {
+
+ /**
+ * The bytes of the file represented by this object.
+ */
+ public final byte[] contents;
+
+ /**
+ * The classpath entry from which the file represented by this object was read.
+ */
+ public final Entry classpathEntry;
+
+ /**
+ * Creates an object encapsulating the bytes of a file read via a classpath entry.
+ *
+ * @param contents the bytes of the file that was read
+ * @param classpathEntry the entry from which the file was read
+ */
+ public ClasspathFile(byte[] contents, Entry classpathEntry) {
+ this.classpathEntry = classpathEntry;
+ this.contents = contents;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/ClasspathTraversal.java b/JavaInJava/src/com/sun/max/program/ClasspathTraversal.java
new file mode 100644
index 0000000..071e671
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/ClasspathTraversal.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+import com.sun.max.io.*;
+import com.sun.max.program.Classpath.*;
+
+/**
+ * Provides a facility for processing all the resources reachable on a given {@linkplain Classpath classpath}.
+ *
+ * @author Doug Simon
+ */
+public class ClasspathTraversal {
+
+ /**
+ * Handles a standard file resource encountered during the traversal.
+ *
+ * @param parent the classpath directory entry under which the resource is located
+ * @param resource the path of the resource relative to {@code parent}. The
+ * {@linkplain File#separatorChar platform specific} character is used as the path separator in this
+ * value.
+ * @return true if the traversal should continue, false if it should terminate
+ */
+ protected boolean visitFile(File parent, String resource) {
+ return true;
+ }
+
+ /**
+ * Handles an archive entry resource encountered during the traversal.
+ *
+ * @param archive the classpath .zip or .jar entry in which the resource is located
+ * @param resource the archive entry holding the resource
+ * @return true if the traversal should continue, false if it should terminate
+ */
+ protected boolean visitArchiveEntry(ZipFile archive, ZipEntry resource) {
+ return true;
+ }
+
+ /**
+ * Traverses all the resources reachable on a given classpath.
+ *
+ * @param classpath the classpath to search
+ */
+ public void run(final Classpath classpath) {
+ run(classpath, null);
+ }
+
+ /**
+ * Traverses all the resources reachable on a given classpath.
+ *
+ * @param classpath the classpath to search
+ * @param resourcePrefixFilter if non-null, then only resources whose name begins with this value are traversed. The
+ * '/' character must be used in this value as the path separator regardless of the
+ * {@linkplain File#separatorChar default} for the underlying platform.
+ */
+ public void run(final Classpath classpath, String resourcePrefixFilter) {
+ for (final Entry entry : classpath.entries()) {
+ if (entry.isDirectory()) {
+ final String prefix = entry.path() + File.separator;
+ final File startFile;
+ if (resourcePrefixFilter == null) {
+ startFile = entry.file();
+ } else {
+ if (File.separatorChar != '/') {
+ startFile = new File(entry.file(), resourcePrefixFilter.replace('/', File.separatorChar));
+ } else {
+ startFile = new File(entry.file(), resourcePrefixFilter);
+ }
+ }
+
+ final FileTraversal fileTraversal = new FileTraversal() {
+ @Override
+ protected void visitFile(File file) {
+ final String path = file.getPath();
+ assert path.startsWith(prefix);
+ final String resource = path.substring(prefix.length());
+ if (!ClasspathTraversal.this.visitFile(entry.file(), resource)) {
+ stop();
+ }
+ }
+ };
+ fileTraversal.run(startFile);
+ if (fileTraversal.wasStopped()) {
+ return;
+ }
+ } else if (entry.isArchive()) {
+ final ZipFile zipFile = entry.zipFile();
+ if (zipFile != null) {
+ for (final Enumeration extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) {
+ final ZipEntry zipEntry = e.nextElement();
+ if (resourcePrefixFilter == null || zipEntry.getName().startsWith(resourcePrefixFilter)) {
+ if (!visitArchiveEntry(zipFile, zipEntry)) {
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/Package.java b/JavaInJava/src/com/sun/max/program/Package.java
new file mode 100755
index 0000000..fa2a430
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/Package.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+import com.sun.max.*;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends BasePackage {
+ public Package() {
+ super();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/ProgramError.java b/JavaInJava/src/com/sun/max/program/ProgramError.java
new file mode 100755
index 0000000..e21f653
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/ProgramError.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+/**
+ * A collection of static methods for reporting errors indicating some fatal condition.
+ * In the target VM, these errors can be made to perform a hard exit of the VM by
+ * redirecting them via a {@linkplain #setHandler(Handler) registered} error handler.
+ *
+ * @author Bernd Mathiske
+ * @author Paul Caprioli
+ * @author Doug Simon
+ * @author Michael Van De Vanter
+ */
+
+public final class ProgramError extends Error {
+
+ /**
+ * Implemented by a client that can {@linkplain ProgramError#setHandler(Handler) register}
+ * itself to handle program errors instead of having them result in a {@link ProgramError}
+ * instance raised.
+ */
+ public static interface Handler {
+
+ /**
+ * Handles a given error condition. This method should never return normally.
+ *
+ * @param message a message describing the error condition. This value may be {@code null}
+ * @param throwable an exception given more detail on the cause of the error condition. This value may be {@code null}
+ */
+ void handle(String message, Throwable throwable);
+ }
+
+ /**
+ * Registers a handler to which error reporting is redirected. Any previously registered handler
+ * is overwritten and discarded.
+ *
+ * @param h if non-null, this object's {@link Handler#handle(String, Throwable)} method is messaged instead of
+ * raising a ProgramError.
+ */
+ public static void setHandler(Handler h) {
+ handler = h;
+ }
+
+ private ProgramError(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Checks a given condition and if it's {@code false}, the appropriate error handling action is taken.
+ * The message reported to this action is {@code "Program Error"}.
+ *
+ * @param condition a condition to test
+ */
+ public static void check(boolean condition) {
+ if (!condition) {
+ unexpected(null, null);
+ }
+ }
+
+ /**
+ * Checks a given condition and if it's {@code false}, the appropriate error handling action is taken.
+ *
+ * @param condition a condition to test
+ * @param message a message describing the error condition being tested
+ */
+ public static void check(boolean condition, String message) {
+ if (!condition) {
+ unexpected(message, null);
+ }
+ }
+
+ /**
+ * Checks a given condition and if it's {@code false}, the appropriate error handling action is taken.
+ *
+ * @param condition a condition to test
+ * @param message a message describing the error condition being tested
+ * @param object an object whose string description is to be appended to the message
+ */
+ public static void check(boolean condition, String message, Object object) {
+ if (!condition) {
+ unexpected(message + object.toString(), null);
+ }
+ }
+
+ /**
+ * Reports the occurrence of some error condition triggering the appropriate error handling action
+ * to be taken. By default, this action is to raise a {@link ProgramError} exception. However,
+ * if an alternative error handler has been {@linkplain #setHandler(Handler) registered}, its
+ * {@link Handler#handle(String, Throwable)} method is called instead.
+ *
+ * This method never returns normally.
+ *
+ * @param message a message describing the error condition. This value may be {@code null}.
+ * @param throwable an exception given more detail on the cause of the error condition. This value may be {@code null}.
+ */
+ public static ProgramError unexpected(String message, Throwable throwable) {
+ if (handler != null) {
+ handler.handle(message, throwable);
+ }
+ if (message == null) {
+ throw new ProgramError("Unexpected Program Error:", throwable);
+ }
+ throw new ProgramError("Unexpected Program Error: " + message, throwable);
+ }
+
+ /**
+ * Reports the occurrence of some error condition.
+ *
+ * This method never returns normally.
+ *
+ * @param message a message describing the error condition. This value may be {@code null}.
+ * @see #unexpected(String, Throwable)
+ */
+ public static ProgramError unexpected(String message) {
+ throw unexpected(message, null);
+ }
+
+ /**
+ * Reports the occurrence of some error condition.
+ *
+ * This method never returns normally.
+ *
+ * @param throwable an exception given more detail on the cause of the error condition. This value may be {@code null}
+ * @see #unexpected(String, Throwable)
+ */
+ public static ProgramError unexpected(Throwable throwable) {
+ throw unexpected(null, throwable);
+ }
+
+ /**
+ * Reports the occurrence of some error condition.
+ *
+ * This method never returns normally.
+ *
+ * @param throwable an exception given more detail on the cause of the error condition. This value may be {@code null}
+ * @see #unexpected(String, Throwable)
+ */
+ public static ProgramError unexpected() {
+ throw unexpected((String) null);
+ }
+
+ /**
+ * Reports that a {@code switch} statement encountered a {@code case} value it was not expecting.
+ *
+ * This method never returns normally.
+ *
+ * @see #unexpected(String, Throwable)
+ */
+ public static ProgramError unknownCase() {
+ throw unexpected("unknown switch case");
+ }
+
+ /**
+ * Reports that a {@code switch} statement encountered a {@code case} value it was not expecting.
+ *
+ * This method never returns normally.
+ *
+ * @param caseValue the unexpected {@code case} value as a string
+ * @see #unexpected(String, Throwable)
+ */
+ public static ProgramError unknownCase(String caseValue) {
+ throw unexpected("unknown switch case: " + caseValue);
+ }
+
+ // Checkstyle: stop
+ private static Handler handler = null;
+}
diff --git a/JavaInJava/src/com/sun/max/program/ProgramWarning.java b/JavaInJava/src/com/sun/max/program/ProgramWarning.java
new file mode 100755
index 0000000..5a7a3bf
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/ProgramWarning.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+/**
+ * A collection of static methods for reporting a warning when an unexpected, non-fatal condition is encountered.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public final class ProgramWarning {
+
+ /**
+ * Implemented by a client that can {@linkplain ProgramWarning#setHandler(Handler) register}
+ * itself to handle program warnings instead of having them printed to {@link System#err}.
+ */
+ public static interface Handler {
+
+ /**
+ * Handles display a given warning message.
+ *
+ * @param message a warning message
+ */
+ void handle(String message);
+ }
+
+ /**
+ * Registers a handler to which warnings are redirected. Any previously registered handler
+ * is overwritten and discarded.
+ *
+ * @param h if non-null, this object's {@link Handler#handle(String)} method is messaged instead of
+ * printing the warning to {@link System#err} a ProgramError.
+ */
+ public static void setHandler(Handler h) {
+ handler = h;
+ }
+
+ private static Handler handler;
+
+ private ProgramWarning() {
+ }
+
+ /**
+ * Prints a given warning message.
+ *
+ * @param warning the warning message to print
+ */
+ public static void message(String warning) {
+ if (handler != null) {
+ handler.handle(warning);
+ } else {
+ System.err.println("WARNING: " + warning);
+ }
+ }
+
+ /**
+ * Checks a given condition and if it's {@code false}, the appropriate warning message is printed.
+ *
+ * @param condition a condition to test
+ * @param message the warning message to be printed if {@code condition == false}
+ */
+ public static void check(boolean condition, String warning) {
+ if (!condition) {
+ message(warning);
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/Trace.java b/JavaInJava/src/com/sun/max/program/Trace.java
new file mode 100755
index 0000000..90200bc
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/Trace.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program;
+
+import java.io.*;
+
+import com.sun.max.annotate.*;
+import com.sun.max.io.*;
+import com.sun.max.program.option.*;
+
+/**
+ * Tracing output for debugging purposes. No performance impact when disabled. Some performance impact when active, even
+ * without output. Possibly significant performance impact when producing a lot of output.
+ *
+ * @author Bernd Mathiske
+ */
+public final class Trace {
+
+ private Trace() {
+ // do nothing.
+ }
+
+ private static PrintStream stream;
+
+ public static PrintStream stream() {
+ return stream;
+ }
+
+ public static void setStream(PrintStream stream) {
+ Trace.stream = stream;
+ }
+
+ private static final boolean showThread;
+
+ static {
+ showThread = System.getProperty("max.trace.showThread") != null;
+ final String traceFileName = System.getProperty("max.trace.file");
+ stream = System.out;
+ if (traceFileName != null) {
+ final File traceFile = new File(traceFileName);
+ try {
+ final OutputStream fileStream = new BufferedOutputStream(new FileOutputStream(traceFile));
+ if (System.getProperty("max.trace.noconsole") != null) {
+ stream = new PrintStream(fileStream);
+ } else {
+ stream = new PrintStream(new MultiOutputStream(fileStream, System.out));
+ }
+ } catch (IOException ioException) {
+ System.err.println("Could not open file for trace output: " + traceFile.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Static master switch. Set by source code editing only (for now).
+ *
+ * Set '_enabled' to 'true' to enable tracing output, according to your other trace-related settings.
+ *
+ * Set '_enabled' to 'false' to prevent any tracing. All tracing routines will thus become dead code. The optimizing
+ * compiler should then be able to eliminate the runtime overhead.
+ */
+ private static final boolean ENABLED = true;
+
+ public static void addTo(OptionSet options) {
+ options.addOption(new Option("trace", 0, OptionTypes.INT_TYPE, "Sets tracing level.") {
+ @Override
+ public void setValue(Integer value) {
+ super.setValue(value);
+ level = value;
+ }
+ });
+ }
+
+ /**
+ * Dynamically sets tracing level, causing trace commands at this or lower levels to produce output.
+ */
+ public static void on(int newLevel) {
+ assert newLevel >= 0;
+ level = newLevel;
+ }
+
+ /**
+ * Dynamically turns tracing on for all levels.
+ */
+ public static void on() {
+ on(Integer.MAX_VALUE);
+ }
+
+ @RESET
+ private static long count;
+
+ /**
+ * The threshold of trace calls before traces are actually sent to the trace stream.
+ *
+ * This field can be updated by the inspector.
+ */
+ @RESET
+ @INSPECTED
+ private static long threshold;
+
+ /**
+ * The current trace level.
+ *
+ * This field can be updated by the inspector.
+ */
+ @RESET
+ @INSPECTED
+ private static int level;
+
+ /**
+ * Dynamically sets the current tracing level to the greater of the current level or the specified new level.
+ */
+ public static void atLeast(int l) {
+ if (l > level) {
+ level = l;
+ }
+ }
+
+ /**
+ * Dynamically turns tracing off by setting current level to zero.
+ */
+ public static void off() {
+ level = 0;
+ }
+
+ /**
+ * @return current tracing level, which must equal or exceed the level specified by trace commands for output to be produced.
+ */
+ public static int level() {
+ return level;
+ }
+
+ /**
+ * Does the current tracing level equal or exceed the specified level.
+ */
+ public static boolean hasLevel(int requiredLevel) {
+ count++;
+ return level >= requiredLevel && count >= threshold;
+ }
+
+ private static final int MAX_INDENTATION = 10;
+
+ @RESET
+ private static int indentation;
+
+ private static void printInt(int n) {
+ if (n < 10) {
+ stream.write(((char) n) + '0');
+ } else {
+ final int m = n / 10;
+ printInt(m);
+ printInt(n - (m * 10));
+ }
+ }
+
+ /**
+ * This should not cause allocation/GC.
+ */
+ private static void printPrefix(int requiredLevel) {
+ if (showThread) {
+ stream.print(Thread.currentThread().getName() + " ");
+ for (int i = 0; i < indentation; i++) {
+ stream.print(" ");
+ }
+ }
+
+ /**
+ * Prints a newline on trace output if tracing is globally enabled and current tracing level is at least the level required.
+ */
+ public static void line(int requiredLevel) {
+ if (ENABLED) {
+ if (hasLevel(requiredLevel)) {
+ stream.println();
+ stream.flush();
+ }
+ }
+ }
+
+ /**
+ * Prints a line of trace output if tracing is globally enabled and if current tracing level is at least the level required.
+ */
+ public static void line(int requiredLevel, Object message) {
+ if (ENABLED) {
+ if (hasLevel(requiredLevel)) {
+ printPrefix(requiredLevel);
+ stream.println(message);
+ stream.flush();
+ }
+ }
+ }
+
+ /**
+ * Prints a "BEGIN" line of trace output if tracing is globally enabled and if current tracing level is at least the level required; increases indentation.
+ */
+ public static void begin(int requiredLevel, Object message) {
+ if (ENABLED) {
+ if (hasLevel(requiredLevel)) {
+ printPrefix(requiredLevel);
+ stream.print("BEGIN: ");
+ stream.println(message);
+ stream.flush();
+ indentation++;
+ }
+ }
+ }
+
+ /**
+ * Prints an "END" line of trace output if tracing is globally enabled and if current tracing level is at least the level required; decreases indentation.
+ */
+ public static void end(int requiredLevel, Object message) {
+ end(requiredLevel, message, 0);
+ }
+
+ /**
+ * Prints an "END" line of trace output if tracing is globally enabled and if current tracing level is at least the level required; decreases indentation;
+ * appends a timing message, expressed in milliseconds, if a non-zero starting time is supplied.
+ * @param requiredLevel
+ * @param message
+ * @param startTimeMillis a starting time, output from {@link System#currentTimeMillis()}; no timing message appears if zero.
+ */
+ public static void end(int requiredLevel, Object message, long startTimeMillis) {
+ if (ENABLED) {
+ if (hasLevel(requiredLevel)) {
+ final long endTimeMillis = System.currentTimeMillis();
+ indentation--;
+ // It's quite possible for indentation to go negative in a multithreaded environment
+ //assert _indentation >= 0;
+ printPrefix(requiredLevel);
+ stream.print("END: ");
+ if (startTimeMillis > 0) {
+ stream.print(message);
+ stream.print(" (");
+ stream.print(endTimeMillis - startTimeMillis);
+ stream.println("ms)");
+ } else {
+ stream.println(message);
+ stream.flush();
+ }
+ }
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/option/FieldOption.java b/JavaInJava/src/com/sun/max/program/option/FieldOption.java
new file mode 100644
index 0000000..3401538
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/option/FieldOption.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program.option;
+
+import com.sun.max.*;
+import com.sun.max.program.ProgramError;
+
+import java.lang.reflect.Field;
+
+/**
+ * This class implements a command line option that stores its value in a field
+ * via reflection.
+ *
+ * @author Ben L. Titzer
+ */
+public class FieldOption extends Option {
+
+ protected final Object object;
+ protected final Field field;
+ protected T nullValue;
+
+ public FieldOption(String name, Object object, Field field, T defaultValue, Type type, String help) {
+ super(name, defaultValue, type, help);
+ this.object = object;
+ this.field = field;
+ this.nullValue = defaultValue;
+ }
+
+ /**
+ * Gets the value of this option. This implementation stores the field's value in a reflected field
+ * and access requires a reflective access.
+ * @return the value of this option
+ */
+ @Override
+ public T getValue() {
+ try {
+ return Utils.cast(field.get(object));
+ } catch (IllegalAccessException e) {
+ throw ProgramError.unexpected(e);
+ }
+ }
+
+ /**
+ * Sets the value of this option. This implementation stores the field's value in a reflected field
+ * and thus setting the value requires a reflective access.
+ * @param value the value to set the new value to
+ */
+ @Override
+ public void setValue(T value) {
+ try {
+ if (value == null) {
+ field.set(object, nullValue);
+ } else {
+ field.set(object, value);
+ }
+ } catch (Exception e) {
+ throw ProgramError.unexpected("Error updating the value of " + field, e);
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/option/MaxPackageOptionType.java b/JavaInJava/src/com/sun/max/program/option/MaxPackageOptionType.java
new file mode 100644
index 0000000..78ec5a3
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/option/MaxPackageOptionType.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program.option;
+
+import com.sun.max.*;
+
+/**
+ * The {@code MaxPackageOptionType} class.
+ * Created Nov 20, 2007
+ *
+ * @author Ben L. Titzer
+ */
+public class MaxPackageOptionType extends Option.Type {
+ public final MaxPackage superPackage;
+ public final Class classType;
+
+ public MaxPackageOptionType(MaxPackage superPackage, Class classType) {
+ super(MaxPackage.class, "vm-package");
+ this.superPackage = superPackage;
+ this.classType = classType;
+ }
+ @Override
+ public MaxPackage parseValue(String string) {
+ final String fullName = superPackage.name() + "." + string;
+ if (string != null && string.length() > 0) {
+ MaxPackage result = MaxPackage.fromName(fullName);
+ if (result == null) {
+ result = MaxPackage.fromName(string);
+ }
+ if (result == null) {
+ throw new Option.Error("MaxPackage not found: " + string + " (or " + fullName + ")");
+ }
+ return result;
+ }
+ return null;
+ }
+
+ @Override
+ public String getValueFormat() {
+ return "";
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/option/Option.java b/JavaInJava/src/com/sun/max/program/option/Option.java
new file mode 100644
index 0000000..8cf4beb
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/option/Option.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program.option;
+
+import com.sun.max.*;
+
+/**
+ * The {@code Option} class represents a command-line or other configuration
+ * option with a particular name, type, and description.
+ *
+ * @author Ben L. Titzer
+ */
+public class Option implements Cloneable {
+
+ /**
+ * The {@code Option.Type} class represents a type for an option. This class
+ * implements method for parsing and unparsing values from strings.
+ */
+ public abstract static class Type {
+ protected final String typeName;
+ public final Class type;
+
+ protected Type(Class type, String typeName) {
+ this.typeName = typeName;
+ this.type = type;
+ }
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public String unparseValue(T value) {
+ return String.valueOf(value);
+ }
+
+ public abstract T parseValue(String string) throws Option.Error;
+
+ public abstract String getValueFormat();
+
+ public Option cast(Option option) {
+ return Utils.cast(option);
+ }
+ }
+
+ public static class Error extends java.lang.Error {
+
+ public Error(String message) {
+ super(message);
+ }
+ }
+
+ protected final String name;
+ protected T defaultValue;
+ protected final Type type;
+ protected final String help;
+ protected T value;
+
+ /**
+ * The constructor for the {@code Option} class creates constructs a new
+ * option with the specified parameters.
+ *
+ * @param name the name of the option as a string
+ * @param defaultValue the default value of the option
+ * @param type the type of the option, which is used for parsing and unparsing values
+ * @param help a help description which is usually used to generate a formatted
+ * help output
+ */
+ public Option(String name, T defaultValue, Type type, String help) {
+ this.defaultValue = defaultValue;
+ this.name = name;
+ this.type = type;
+ this.help = help;
+ value = null;
+ }
+
+ /**
+ * The {@code getName()} method returns the name of this option as a string.
+ *
+ * @return the name of this option
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the default value for this option,
+ * which is the value that the option retains if no assignment is made.
+ *
+ * @param val the default value of the option
+ */
+ public void setDefaultValue(T val) {
+ defaultValue = val;
+ }
+
+ /**
+ * The {@code getDefaultValue()} method returns the default value for this option,
+ * which is the value that the option retains if no assignment is made.
+ *
+ * @return the default value of the option
+ */
+ public T getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * The {@code getValue()} method retrieves the current value of this option.
+ *
+ * @return the current value of this option
+ */
+ public T getValue() {
+ return !assigned ? defaultValue : value;
+ }
+
+ private boolean assigned;
+
+ /**
+ * The {@code setValue()) method sets the value of this option.
+ *
+ * @param value the new value to this option
+ */
+ public void setValue(T value) {
+ assigned = true;
+ this.value = value;
+ }
+
+ /**
+ * The {@code setValue()} method sets the value of this option, given a string value.
+ * The type of this option is used to determine how to parse the string into a value
+ * of the appropriate type. Thus this method may potentially throw runtime exceptions
+ * if parsing fails.
+ *
+ * @param string the new value of this option as a string
+ */
+ public void setString(String string) {
+ setValue(type.parseValue(string));
+ }
+
+ /**
+ * The {@code getType()} method returns the type of this option.
+ * @return the type of this option.
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * The {@code getString()} method retrieves the value of this option as a string.
+ * The type of this option is used to determine how to unparse the value into a string.
+ *
+ * @return the value of this option as a string
+ */
+ public String getString() {
+ return type.unparseValue(getValue());
+ }
+
+ public String getHelp() {
+ return help;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/program/option/OptionSet.java b/JavaInJava/src/com/sun/max/program/option/OptionSet.java
new file mode 100644
index 0000000..1a763b7
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/program/option/OptionSet.java
@@ -0,0 +1,746 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.program.option;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import com.sun.max.*;
+import com.sun.max.lang.*;
+import com.sun.max.program.*;
+import com.sun.max.program.option.gui.*;
+
+/**
+ * The {@code OptionSet} class parses and collects options from the command line and
+ * configuration files.
+ *
+ * @author Ben L. Titzer
+ */
+public class OptionSet {
+ /**
+ * The {@code Syntax} enum allows different options to be parsed differently,
+ * depending on their usage.
+ */
+ public enum Syntax {
+ REQUIRES_EQUALS {
+ @Override
+ public String getUsage(Option option) {
+ return "-" + option.getName() + "=" + option.getType().getValueFormat();
+ }
+ },
+ EQUALS_OR_BLANK {
+ @Override
+ public String getUsage(Option option) {
+ return "-" + option.getName() + "[=" + option.getType().getValueFormat() + "]";
+ }
+ },
+ REQUIRES_BLANK {
+ @Override
+ public String getUsage(Option option) {
+ return "-" + option.getName();
+ }
+ },
+ CONSUMES_NEXT {
+ @Override
+ public String getUsage(Option option) {
+ return "-" + option.getName() + " " + option.getType().getValueFormat();
+ }
+ };
+
+ public abstract String getUsage(Option option);
+ }
+
+ protected final Map optionMap;
+ protected final Map optionSyntax;
+ protected final Map optionValues;
+ protected final boolean allowUnrecognizedOptions;
+
+ protected static final String[] NO_ARGUMENTS = {};
+
+ protected String[] arguments = NO_ARGUMENTS;
+
+ /**
+ * Creates an option set that does not allow unrecognized options to be present when
+ * {@linkplain #parseArguments(String[]) parsing command line arguments} or
+ * {@linkplain #loadOptions(OptionSet) loading options from another option set}.
+ */
+ public OptionSet() {
+ this(false);
+ }
+
+ /**
+ * Creates an option set.
+ *
+ * @param allowUnrecognizedOptions
+ * specifies if this option set allows unrecognized options to be present when
+ * {@linkplain #parseArguments(String[]) parsing command line arguments} or
+ * {@linkplain #loadOptions(OptionSet) loading options from another option set}.
+ */
+ public OptionSet(boolean allowUnrecognizedOptions) {
+ optionValues = new HashMap();
+ // Using a LinkedHashMap to preserve insertion order when iterating over values
+ optionMap = new LinkedHashMap();
+ optionSyntax = new HashMap();
+ this.allowUnrecognizedOptions = allowUnrecognizedOptions;
+ }
+
+ /**
+ * Converts this option set into a list of command line arguments, to be used, for example, to pass to an external
+ * tool. For each option in this set that has been explicitly set this method will prepend an appropriate option
+ * string of appropriate syntactic form (e.g. "-name=value") to the array of arguments passed.
+ *
+ * @return a new array of program arguments that includes these options
+ */
+ public String[] asArguments() {
+ String[] newArgs = Arrays.copyOf(arguments, arguments.length + optionValues.size());
+ int i = 0;
+ for (String name : optionValues.keySet()) {
+ final String value = optionValues.get(name);
+ final Syntax syntax = optionSyntax.get(name);
+ if (syntax == Syntax.REQUIRES_BLANK) {
+ newArgs[i++] = "-" + name;
+ } else if (syntax == Syntax.CONSUMES_NEXT) {
+ newArgs = Arrays.copyOf(newArgs, newArgs.length + 1);
+ newArgs[i++] = "-" + name;
+ newArgs[i++] = value;
+ } else {
+ newArgs[i++] = "-" + name + "=" + value;
+ }
+ }
+ return newArgs;
+ }
+
+ /**
+ * Gets an option set derived from this option set that contains all the unrecognized options that have been loaded
+ * or parsed into this option set. The returned option set also includes a copy of the
+ * {@linkplain #getArguments() non-option arguments} from this option set.
+ * @return a new option set encapsulating all the arguments and options
+ */
+ public OptionSet getArgumentsAndUnrecognizedOptions() {
+ final OptionSet argumentsAndUnrecognizedOptions = new OptionSet(true);
+ for (Map.Entry entry : optionValues.entrySet()) {
+ if (!optionMap.containsKey(entry.getKey())) {
+ argumentsAndUnrecognizedOptions.optionValues.put(entry.getKey(), entry.getValue());
+ }
+ }
+ argumentsAndUnrecognizedOptions.arguments = arguments;
+ return argumentsAndUnrecognizedOptions;
+ }
+
+ /**
+ * Handles an Option.Error raised while loading or parsing values into this option set.
+ *
+ * This default implementation is to print a usage message and the call {@link System#exit(int)}.
+ * @param error the error that occurred
+ * @param optionName the name of the option being parsed
+ */
+ protected void handleErrorDuringParseOrLoad(Option.Error error, String optionName) {
+ System.out.println("Error parsing option -" + optionName + ": " + error.getMessage());
+ printHelp(System.out, 78);
+ System.exit(1);
+ }
+
+ /**
+ * Parses a list of command line arguments, processing the leading options (i.e. arguments that start with '-')
+ * and returning the "leftover" arguments to the caller. The longest tail of {@code arguments} that starts with a non-option argument can be retrieved after parsing with {@link #getArguments()}.
+ *
+ * @param args
+ * the arguments
+ * @return this option set
+ */
+ public OptionSet parseArguments(String[] args) {
+ // parse the options
+ int i = 0;
+ for (; i < args.length; i++) {
+ final String argument = args[i];
+ if (argument.charAt(0) == '-') {
+ // is the beginning of a valid option.
+ final int index = argument.indexOf('=');
+ final String optionName = getOptionName(argument, index);
+ String value = getOptionValue(argument, index);
+ final Syntax syntax = optionSyntax.get(optionName);
+ // check the syntax of this option
+ try {
+ checkSyntax(optionName, syntax, value);
+ if (syntax == Syntax.CONSUMES_NEXT) {
+ value = args[++i];
+ }
+ setValue(optionName, value);
+ } catch (Option.Error error) {
+ handleErrorDuringParseOrLoad(error, optionName);
+ }
+ } else {
+ // is not an option, therefore the start of arguments
+ break;
+ }
+ }
+
+ final int left = args.length - i;
+ arguments = new String[left];
+ System.arraycopy(args, i, arguments, 0, left);
+
+ if (System.getProperty("useProgramOptionDialog") != null) {
+ OptionsDialog.show(null, this);
+ }
+ return this;
+ }
+
+ /**
+ * The {@code getArguments()} method gets the leftover command line options
+ * from the last call to {@code parseArguments}.
+ *
+ * @return the leftover command line options
+ */
+ public String[] getArguments() {
+ if (arguments.length == 0) {
+ return arguments;
+ }
+ return Arrays.copyOf(arguments, arguments.length);
+ }
+
+ /**
+ * Determines if this option set allows parsing or loading of unrecognized options.
+ * @return {@code true} if this option set allows unrecognized options
+ */
+ public boolean allowsUnrecognizedOptions() {
+ return allowUnrecognizedOptions;
+ }
+
+ /**
+ * The {@code loadSystemProperties()} method loads the value of the valid
+ * options from the systems properties with the specified prefix.
+ *
+ * @param prefix the prefix of each system property, used to disambiguate
+ * these options from other system properties.
+ * @return this option set
+ */
+ public OptionSet loadSystemProperties(String prefix) {
+ final Properties systemProperties = System.getProperties();
+ final Properties properties = new Properties();
+ for (String key : systemProperties.stringPropertyNames()) {
+ if (key.startsWith(prefix)) {
+ properties.setProperty(key.substring(prefix.length()), systemProperties.getProperty(key));
+ }
+ }
+ return loadProperties(properties, true);
+ }
+
+ /**
+ * The {@code storeSystemProperties()} method stores these option values
+ * into the system properties.
+ *
+ * @param prefix the prefix to append to all option names when inserting them
+ * into the systems properties
+ */
+ public void storeSystemProperties(String prefix) {
+ for (Map.Entry entry : optionValues.entrySet()) {
+ System.setProperty(prefix + entry.getKey(), entry.getValue());
+ }
+ }
+
+ /**
+ * Loads the specified properties into this set of options.
+ *
+ * @param p
+ * the properties set to load into this set of options
+ * @param loadall
+ * true if this method should load all properties in the property set into this option set; false if this
+ * method should only load properties for options already in this option set
+ * @return this option set
+ */
+ public OptionSet loadProperties(Properties p, boolean loadall) {
+ if (loadall) {
+ // if loadall is specified, load all properties in the set
+ for (Object object : p.keySet()) {
+ final String name = (String) object;
+ final String val = p.getProperty(name);
+ try {
+ setValue(name, val);
+ } catch (Option.Error error) {
+ handleErrorDuringParseOrLoad(error, name);
+ }
+ }
+ } else {
+ // if loadall is not specified, only load options that are in this option set.
+ for (Object o : p.keySet()) {
+ final String name = (String) o;
+ if (optionMap.containsKey(name)) {
+ final String val = p.getProperty(name);
+ try {
+ setValue(name, val);
+ } catch (Option.Error error) {
+ handleErrorDuringParseOrLoad(error, name);
+ }
+ }
+ }
+ }
+ if (System.getProperty("useProgramOptionDialog") != null) {
+ OptionsDialog.show(null, this);
+ }
+ return this;
+ }
+
+ /**
+ * The {@code loadFile()} method parses properties from a file and loads them into this set of options.
+ *
+ * @param fname
+ * the filename from while to load the properties
+ * @param loadall
+ * true if this method should load all properties in the property set into this option set; false if this
+ * method should only load properties for options already in this option set
+ * @return this option set
+ * @throws java.io.IOException
+ * if there is a problem opening or reading the file
+ * @throws Option.Error
+ * if there is a problem parsing an option
+ */
+ public OptionSet loadFile(String fname, boolean loadall) throws IOException, Option.Error {
+ final Properties defs = new Properties();
+ final FileInputStream stream = new FileInputStream(new File(fname));
+ defs.load(stream);
+ stream.close();
+ return loadProperties(defs, loadall);
+ }
+
+ /**
+ * Loads a set of options and {@linkplain #getArguments() arguments} from another option set.
+ *
+ * @param options the option set from which to load the option values
+ * @return this option set
+ */
+ public OptionSet loadOptions(OptionSet options) {
+ for (Map.Entry entry : options.optionValues.entrySet()) {
+ try {
+ setValue(entry.getKey(), entry.getValue());
+ } catch (Option.Error error) {
+ handleErrorDuringParseOrLoad(error, entry.getKey());
+ }
+ }
+ arguments = options.arguments;
+
+ if (System.getProperty("useProgramOptionDialog") != null) {
+ OptionsDialog.show(null, this);
+ }
+ return this;
+ }
+
+ protected void checkSyntax(String optname, Syntax syntax, String value) {
+ if (syntax == Syntax.REQUIRES_BLANK && value != null) {
+ throw new Option.Error("syntax error: \"-" + optname + "\" required");
+ }
+ if (syntax == Syntax.REQUIRES_EQUALS && value == null) {
+ throw new Option.Error("syntax error: \"-" + optname + "=value\" required");
+ }
+ if (syntax == Syntax.CONSUMES_NEXT && value != null) {
+ throw new Option.Error("syntax error: \"-" + optname + " value\" required");
+ }
+ }
+
+ protected String getOptionName(String argument, int equalIndex) {
+ if (equalIndex < 0) { // naked option
+ return argument.substring(1, argument.length());
+ }
+ return argument.substring(1, equalIndex);
+ }
+
+ protected String getOptionValue(String argument, int equalIndex) {
+ if (equalIndex < 0) { // naked option
+ return null;
+ }
+ return argument.substring(equalIndex + 1);
+ }
+
+ /**
+ * Adds the options of an {@link OptionSet} to this set.
+ * @param optionSet the set of options to add
+ */
+ public void addOptions(OptionSet optionSet) {
+ for (Option> option : optionSet.getOptions()) {
+ final Syntax syntax = optionSet.optionSyntax.get(option.getName());
+ addOption(option, syntax);
+ }
+ }
+
+ /**
+ * The {@code addOption()} method adds an option with the {@link Syntax#REQUIRES_EQUALS} syntax to this option set.
+ *
+ * @param option the new option to add to this set
+ * @return the option passed as the argument, after it has been added to this option set
+ */
+ public Option addOption(Option option) {
+ return addOption(option, Syntax.REQUIRES_EQUALS);
+ }
+
+ /**
+ * The {@code addOption()} method adds an option to this option set.
+ *
+ * @param option the new option to add to this set
+ * @param syntax the syntax of the option, which specifies how to parse the option
+ * from command line parameters
+ * @return the option passed as the argument, after it has been added to this option set
+ */
+ public Option addOption(Option option, Syntax syntax) {
+ final String name = option.getName();
+ final Option existingOption = optionMap.put(name, option);
+ if (existingOption != null) {
+ throw ProgramError.unexpected("Cannot register more than one option under the same name: " + option.getName());
+ }
+ optionSyntax.put(name, syntax);
+ return option;
+ }
+
+ /**
+ * The {@code setSyntax()} method sets the syntax of a particular option.
+ *
+ * @param option the option for which to change the syntax
+ * @param syntax the new syntax for the instruction
+ */
+ public void setSyntax(Option option, Syntax syntax) {
+ optionSyntax.put(option.getName(), syntax);
+ }
+
+ /**
+ * The {@code setValue()} method sets the value of the specified option in
+ * this option set. If there is no option by the specified name, the name/value
+ * pair will simply be remembered.
+ *
+ * @param name the name of the option
+ * @param value the new value of the option as a string
+ * @throws Option.Error if {@code name} denotes an unrecognized option and this
+ */
+ public void setValue(String name, String value) {
+ final String v = value == null ? "" : value;
+ final Option opt = optionMap.get(name);
+ if (opt != null) {
+ opt.setString(v);
+ } else {
+ if (!allowUnrecognizedOptions) {
+ throw new Option.Error("unrecognized option -" + name);
+ }
+ }
+ optionValues.put(name, v);
+ }
+
+ public void setValuesAgain() {
+ for (String name : optionValues.keySet()) {
+ final Option opt = optionMap.get(name);
+ opt.setString(optionValues.get(name));
+ }
+ }
+
+ public String getStringValue(String name) {
+ return optionValues.get(name);
+ }
+
+ /**
+ * The {@code hasOptionSpecified()} method checks whether an option with the specified
+ * name has been assigned to. An option as been "assigned to" if its value has been set
+ * by either parsing arguments (the {@code parseArguments() method} or loading properties
+ * from a file or the system properties.
+ *
+ * @param name the name of the option to query
+ * @return true if an option with the specified name has been set; false otherwise
+ */
+ public boolean hasOptionSpecified(String name) {
+ return optionValues.containsKey(name);
+ }
+
+ /**
+ * Retrieves the options from this option
+ * set, in the order in which they were added.
+ * @return an iterable collection of {@code Option} instances, sorted according to insertion order
+ */
+ public Iterable