--- /dev/null	2009-01-20 02:47:31.000000000 -0800
+++ new/src/share/projects/meth/src/impl/java/dyn/util/Wrappers.java	2009-01-20 02:47:31.000000000 -0800
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package impl.java.dyn.util;
+
+import java.util.HashMap;
+
+public class Wrappers {
+
+    private Wrappers() { }  // cannot instantiate
+
+    /** If {@code type} is a primitive type, return the corresponding
+     *  wrapper type, else return {@code type} unchanged.
+     */
+    public static <T> Class<T> asWrapperType(Class<T> type) {
+        if (!type.isPrimitive()) {
+            return type;
+        }
+        if (wrappers.isEmpty()) {
+            fillWrappers();
+        }
+        Object[] memo = wrappers.get(type);
+        assert (memo != null);
+        return (Class<T>) memo[0];  // unchecked warning is OK here
+    }
+
+    /** If {@code type} is a wrapper type, return the corresponding
+     *  primitive type, else return {@code type} unchanged.
+     */
+    public static <T> Class<T> asPrimitiveType(Class<T> type) {
+        if (type.isPrimitive()) {
+            return type;
+        }
+        if (wrappers.isEmpty()) {
+            fillWrappers();
+        }
+        Object[] memo = wrappers.get(type);
+        if (memo == null) {
+            return type;
+        }
+        return (Class<T>) memo[1];  // unchecked warning is OK here
+    }
+
+    public static boolean isWrapperType(Class<?> type) {
+        return asPrimitiveType(type) != type;
+    }
+
+    public static boolean isPrimitiveType(Class<?> type) {
+        return type.isPrimitive();
+    }
+
+    public static char basicTypeChar(Class<?> type) {
+        if (!type.isPrimitive()) {
+            return 'L';
+        }
+        if (wrappers.isEmpty()) {
+            fillWrappers();
+        }
+        Object[] memo = wrappers.get(type);
+        assert (memo != null);
+        return (char) (Character) memo[2];
+    }
+
+    static final String PRIMITIVE_BITS_TABLE = "LZBCSFIZZDJ";
+    //                                         "--01234  78"
+
+    /** Return the number of bits in the given type, or zero for refs. */
+    public static int bitWidth(Class<?> type) {
+        return bitWidth(basicTypeChar(type));
+    }
+
+    /** Return the number of bits in the given basic type, or zero for refs. */
+    public static int bitWidth(char c) {
+        int i = PRIMITIVE_BITS_TABLE.indexOf(c);
+        if (i < 0)  throw new IllegalArgumentException("not a basic type char: "+c);
+        i -= 2;
+        switch (i) {
+            case -2: return 0; // L
+            case -1: return 1; // Z
+            case 0:  return 8; // B
+            default: return (i + (i & 1)) * 8;
+        }
+    }
+
+    static final String PRIMITIVE_SIGN_TABLE = "JZICSZB";
+    //                                         "SuSuS S"
+    /** Return whether the given type is a signed integral type. */
+    public static boolean isSigned(Class<?> type) {
+        return isSigned(basicTypeChar(type));
+    }
+
+    /** Return whether the given type is a signed integral type. */
+    public static boolean isSigned(char c) {
+        int i = PRIMITIVE_SIGN_TABLE.indexOf(c);
+        return (i & 1) == 0;
+    }
+
+    /** Return whether the given type is a unsigned integral type. */
+    public static boolean isUnsigned(Class<?> type) {
+        return isUnsigned(basicTypeChar(type));
+    }
+
+    /** Return whether the given type is a unsigned integral type. */
+    public static boolean isUnsigned(char c) {
+        int i = PRIMITIVE_SIGN_TABLE.indexOf(c);
+        return (i & 0x11) == 1;
+    }
+
+    /** Return whether the given type is an integral type. */
+    public static boolean isIntegral(Class<?> type) {
+        return isIntegral(basicTypeChar(type));
+    }
+
+    /** Return whether the given type is an integral type. */
+    public static boolean isIntegral(char c) {
+        int i = PRIMITIVE_SIGN_TABLE.indexOf(c);
+        return i >= 0;
+    }
+
+    /** Report if the type is one of int, boolean, byte, char, or short. */
+    public static boolean isSubwordOrInt(Class<?> type) {
+        return isSubwordOrInt(basicTypeChar(type));
+    }
+
+    /** Report if the type char is one of "IZBCS". */
+    public static boolean isSubwordOrInt(char c) {
+        return PRIMITIVE_SIGN_TABLE.indexOf(c) > 0;
+    }
+
+    /** Return whether the given type is a floating primitive type. */
+    public static boolean isFloating(Class<?> type) {
+        return isFloating(basicTypeChar(type));
+    }
+
+    /** Return whether the given type is a floating primitive type. */
+    public static boolean isFloating(char c) {
+        return c == 'F' || c == 'D';
+    }
+
+    /** Return the primitive type that corresponds to the given bytecode
+     *  signature character.  Return {@code Object.class} for the character
+     *  'L', and null for any non-signature character or '['.
+     */
+    public static Class<?> basicTypeFromChar(char c) {
+        if (c == 'L') {
+            return Object.class;
+        }
+//        if (c == '[') {
+//            return Object[].class;
+//        }
+        if (wrappers.isEmpty()) {
+            fillWrappers();
+        }
+        Object[] memo = wrappers.get((Character)c);
+        if (memo == null)
+            return null;   // random junk character
+        return (Class<?>) memo[1];
+    }
+
+    public static Object zeroValue(Class<?> type) {
+        if (!type.isPrimitive()) {
+            return null;
+        }
+        if (wrappers.isEmpty()) {
+            fillWrappers();
+        }
+        Object[] memo = wrappers.get(type);
+        assert (memo != null);
+        return memo[3];
+    }
+
+    public static <T> T wrap(Object x, Class<T> numClass) {
+        if (wrappers.isEmpty()) {
+            fillWrappers();
+        }
+        Object[] memo = wrappers.get(numClass);
+        if (memo == null)  return numClass.cast(x);  // no change
+        Class<T> wrapType = (Class<T>) memo[0];  // unchecked warning is OK here
+        return wrapType.cast(wrap(x, (Character) memo[2]));
+    }
+    public static Object wrap(Object x, char c) {
+        Number xn = numberValue(x);
+        switch (c) {
+        case 'I': return Integer.valueOf(xn.intValue());
+        case 'J': return Long.valueOf(xn.longValue());
+        case 'F': return Float.valueOf(xn.floatValue());
+        case 'D': return Double.valueOf(xn.doubleValue());
+        case 'S': return Short.valueOf((short) xn.intValue());
+        case 'B': return Byte.valueOf((byte) xn.intValue());
+        case 'C': return Character.valueOf((char) xn.intValue());
+        case 'Z': return Boolean.valueOf(boolValue(xn.longValue()));
+        case 'V': return null;
+        }
+        return xn;
+    }
+
+    private static Number numberValue(Object x) {
+        if (x instanceof Number)     return (Number)x;
+        if (x instanceof Character)  return (int)(Character)x;
+        if (x instanceof Boolean)    return (Boolean)x ? 1 : 0;
+        // Remaining allowed case of void:  Must be a null reference.
+        return (Number)x;
+    }
+    private static boolean boolValue(long bits) {
+        bits &= 1;  // simple 31-bit zero extension
+        return (bits != 0);
+    }
+
+    private static final HashMap<Object, Object[]> wrappers
+        = new HashMap<Object, Object[]>(20);
+
+    private static void fillWrappers() {
+        Object[][] memos = {
+            {Boolean.class, Boolean.TYPE, 'Z', (Boolean) false},
+            {Character.class, Character.TYPE, 'C', (Character) '\000'},
+            {Byte.class, Byte.TYPE, 'B', (Byte) (byte) 0},
+            {Short.class, Short.TYPE, 'S', (Short) (short) 0},
+            {Integer.class, Integer.TYPE, 'I', (Integer) 0},
+            {Long.class, Long.TYPE, 'J', (Long) 0L},
+            {Float.class, Float.TYPE, 'F', (Float) 0.0F},
+            {Double.class, Double.TYPE, 'D', (Double) 0.0},
+            {Void.class, Void.TYPE, 'V', null}
+        };
+        for (Object[] memo : memos) {
+            wrappers.put(memo[0], memo);
+            wrappers.put(memo[1], memo);
+            wrappers.put(memo[2], memo);
+        }
+    }
+
+    // TO DO:  Put these into a unit test.
+    private static Class<Integer> PTYPE = int.class, WTYPE = Integer.class;
+    static {
+        assert(PTYPE != WTYPE);
+        assert(asPrimitiveType(PTYPE) == PTYPE);
+        assert(asPrimitiveType(WTYPE) == PTYPE);
+        assert(  asWrapperType(PTYPE) == WTYPE);
+        assert(  asWrapperType(WTYPE) == WTYPE);
+
+        assert(bitWidth(String.class) == 0);
+        assert(bitWidth(Integer.class) == 0);
+        assert(bitWidth(int.class) == 32);
+        assert(bitWidth(char.class) == 16);
+        assert(bitWidth(short.class) == 16);
+        assert(bitWidth(byte.class) == 8);
+        assert(bitWidth(boolean.class) == 1);
+        assert(bitWidth(double.class) == 64);
+        assert(bitWidth(float.class) == 32);
+    }
+}
