?? nativejavaobject.java
字號:
else if (type.isInterface() && value instanceof Callable) { // Try to use function as implementation of Java interface. // // XXX: Curently only instances of ScriptableObject are // supported since the resulting interface proxies should // be reused next time conversion is made and generic // Callable has no storage for it. Weak references can // address it but for now use this restriction. if (value instanceof ScriptableObject) { ScriptableObject so = (ScriptableObject)value; Object key = Kit.makeHashKeyFromPair( COERCED_INTERFACE_KEY, type); Object old = so.getAssociatedValue(key); if (old != null) { // Function was already wrapped return old; } Context cx = Context.getContext(); Object glue = InterfaceAdapter.create(cx, type, (Callable)value); // Store for later retrival glue = so.associateValue(key, glue); return glue; } reportConversionError(value, type); } else { reportConversionError(value, type); } break; } return value; } private static Object coerceToNumber(Class type, Object value) { Class valueClass = value.getClass(); // Character if (type == Character.TYPE || type == ScriptRuntime.CharacterClass) { if (valueClass == ScriptRuntime.CharacterClass) { return value; } return new Character((char)toInteger(value, ScriptRuntime.CharacterClass, (double)Character.MIN_VALUE, (double)Character.MAX_VALUE)); } // Double, Float if (type == ScriptRuntime.ObjectClass || type == ScriptRuntime.DoubleClass || type == Double.TYPE) { return valueClass == ScriptRuntime.DoubleClass ? value : new Double(toDouble(value)); } if (type == ScriptRuntime.FloatClass || type == Float.TYPE) { if (valueClass == ScriptRuntime.FloatClass) { return value; } else { double number = toDouble(value); if (Double.isInfinite(number) || Double.isNaN(number) || number == 0.0) { return new Float((float)number); } else { double absNumber = Math.abs(number); if (absNumber < (double)Float.MIN_VALUE) { return new Float((number > 0.0) ? +0.0 : -0.0); } else if (absNumber > (double)Float.MAX_VALUE) { return new Float((number > 0.0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY); } else { return new Float((float)number); } } } } // Integer, Long, Short, Byte if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE) { if (valueClass == ScriptRuntime.IntegerClass) { return value; } else { return new Integer((int)toInteger(value, ScriptRuntime.IntegerClass, (double)Integer.MIN_VALUE, (double)Integer.MAX_VALUE)); } } if (type == ScriptRuntime.LongClass || type == Long.TYPE) { if (valueClass == ScriptRuntime.LongClass) { return value; } else { /* Long values cannot be expressed exactly in doubles. * We thus use the largest and smallest double value that * has a value expressible as a long value. We build these * numerical values from their hexidecimal representations * to avoid any problems caused by attempting to parse a * decimal representation. */ final double max = Double.longBitsToDouble(0x43dfffffffffffffL); final double min = Double.longBitsToDouble(0xc3e0000000000000L); return new Long(toInteger(value, ScriptRuntime.LongClass, min, max)); } } if (type == ScriptRuntime.ShortClass || type == Short.TYPE) { if (valueClass == ScriptRuntime.ShortClass) { return value; } else { return new Short((short)toInteger(value, ScriptRuntime.ShortClass, (double)Short.MIN_VALUE, (double)Short.MAX_VALUE)); } } if (type == ScriptRuntime.ByteClass || type == Byte.TYPE) { if (valueClass == ScriptRuntime.ByteClass) { return value; } else { return new Byte((byte)toInteger(value, ScriptRuntime.ByteClass, (double)Byte.MIN_VALUE, (double)Byte.MAX_VALUE)); } } return new Double(toDouble(value)); } private static double toDouble(Object value) { if (value instanceof Number) { return ((Number)value).doubleValue(); } else if (value instanceof String) { return ScriptRuntime.toNumber((String)value); } else if (value instanceof Scriptable) { if (value instanceof Wrapper) { // XXX: optimize tail-recursion? return toDouble(((Wrapper)value).unwrap()); } else { return ScriptRuntime.toNumber(value); } } else { Method meth; try { meth = value.getClass().getMethod("doubleValue", null); } catch (NoSuchMethodException e) { meth = null; } catch (SecurityException e) { meth = null; } if (meth != null) { try { return ((Number)meth.invoke(value, null)).doubleValue(); } catch (IllegalAccessException e) { // XXX: ignore, or error message? reportConversionError(value, Double.TYPE); } catch (InvocationTargetException e) { // XXX: ignore, or error message? reportConversionError(value, Double.TYPE); } } return ScriptRuntime.toNumber(value.toString()); } } private static long toInteger(Object value, Class type, double min, double max) { double d = toDouble(value); if (Double.isInfinite(d) || Double.isNaN(d)) { // Convert to string first, for more readable message reportConversionError(ScriptRuntime.toString(value), type); } if (d > 0.0) { d = Math.floor(d); } else { d = Math.ceil(d); } if (d < min || d > max) { // Convert to string first, for more readable message reportConversionError(ScriptRuntime.toString(value), type); } return (long)d; } static void reportConversionError(Object value, Class type) { // It uses String.valueOf(value), not value.toString() since // value can be null, bug 282447. throw Context.reportRuntimeError2( "msg.conversion.not.allowed", String.valueOf(value), JavaMembers.javaSignature(type)); } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); if (javaObject != null) { Class joClass = javaObject.getClass(); if (joClass.getName().startsWith("adapter")) { out.writeBoolean(true); if (adapter_writeAdapterObject == null) { throw new IOException(); } Object[] args = { javaObject, out }; try { adapter_writeAdapterObject.invoke(null, args); } catch (Exception ex) { throw new IOException(); } } else { out.writeBoolean(false); out.writeObject(javaObject); } } else { out.writeBoolean(false); out.writeObject(javaObject); } if (staticType != null) { out.writeObject(staticType.getClass().getName()); } else { out.writeObject(null); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); if (in.readBoolean()) { if (adapter_readAdapterObject == null) throw new ClassNotFoundException(); Object[] args = { this, in }; try { javaObject = adapter_readAdapterObject.invoke(null, args); } catch (Exception ex) { throw new IOException(); } } else { javaObject = in.readObject(); } String className = (String)in.readObject(); if (className != null) { staticType = Class.forName(className); } else { staticType = null; } initMembers(); } /** * The prototype of this object. */ protected Scriptable prototype; /** * The parent scope of this object. */ protected Scriptable parent; protected transient Object javaObject; protected transient Class staticType; protected transient JavaMembers members; private transient Hashtable fieldAndMethods; private static final Object COERCED_INTERFACE_KEY = new Object(); private static Method adapter_writeAdapterObject; private static Method adapter_readAdapterObject; static { // Reflection in java is verbose Class[] sig2 = new Class[2]; Class cl = Kit.classOrNull("org.mozilla.javascript.JavaAdapter"); if (cl != null) { try { sig2[0] = ScriptRuntime.ObjectClass; sig2[1] = Kit.classOrNull("java.io.ObjectOutputStream"); adapter_writeAdapterObject = cl.getMethod("writeAdapterObject", sig2); sig2[0] = ScriptRuntime.ScriptableClass; sig2[1] = Kit.classOrNull("java.io.ObjectInputStream"); adapter_readAdapterObject = cl.getMethod("readAdapterObject", sig2); } catch (Exception ex) { adapter_writeAdapterObject = null; adapter_readAdapterObject = null; } } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -