⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptruntime.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Patrick Beard *   Norris Boyd *   Igor Bukanov *   Ethan Hugg *   Roger Lawrence *   Terry Lucas *   Frank Mitchell *   Milen Nankov *   Andrew Wason * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript;import java.lang.reflect.*;import java.text.MessageFormat;import java.util.Locale;import java.util.ResourceBundle;import org.mozilla.javascript.xml.XMLObject;import org.mozilla.javascript.xml.XMLLib;import org.mozilla.javascript.continuations.Continuation;/** * This is the class that implements the runtime. * * @author Norris Boyd */public class ScriptRuntime {    /**     * No instances should be created.     */    protected ScriptRuntime() {    }    /*     * There's such a huge space (and some time) waste for the Foo.class     * syntax: the compiler sticks in a test of a static field in the     * enclosing class for null and the code for creating the class value.     * It has to do this since the reference has to get pushed off til     * executiontime (i.e. can't force an early load), but for the     * 'standard' classes - especially those in java.lang, we can trust     * that they won't cause problems by being loaded early.     */    public final static Class        BooleanClass      = Kit.classOrNull("java.lang.Boolean"),        ByteClass         = Kit.classOrNull("java.lang.Byte"),        CharacterClass    = Kit.classOrNull("java.lang.Character"),        ClassClass        = Kit.classOrNull("java.lang.Class"),        DoubleClass       = Kit.classOrNull("java.lang.Double"),        FloatClass        = Kit.classOrNull("java.lang.Float"),        IntegerClass      = Kit.classOrNull("java.lang.Integer"),        LongClass         = Kit.classOrNull("java.lang.Long"),        NumberClass       = Kit.classOrNull("java.lang.Number"),        ObjectClass       = Kit.classOrNull("java.lang.Object"),        ShortClass        = Kit.classOrNull("java.lang.Short"),        StringClass       = Kit.classOrNull("java.lang.String"),        DateClass         = Kit.classOrNull("java.util.Date");    public final static Class        ContextClass            = Kit.classOrNull("org.mozilla.javascript.Context"),        ContextFactoryClass            = Kit.classOrNull("org.mozilla.javascript.ContextFactory"),        FunctionClass            = Kit.classOrNull("org.mozilla.javascript.Function"),        ScriptableClass            = Kit.classOrNull("org.mozilla.javascript.Scriptable"),        ScriptableObjectClass            = Kit.classOrNull("org.mozilla.javascript.ScriptableObject");    private static final String        XML_INIT_CLASS = "org.mozilla.javascript.xmlimpl.XMLLibImpl";    private static final String[] lazilyNames = {        "RegExp",        "org.mozilla.javascript.regexp.NativeRegExp",        "Packages",      "org.mozilla.javascript.NativeJavaTopPackage",        "java",          "org.mozilla.javascript.NativeJavaTopPackage",        "getClass",      "org.mozilla.javascript.NativeJavaTopPackage",        "JavaAdapter",   "org.mozilla.javascript.JavaAdapter",        "JavaImporter",  "org.mozilla.javascript.ImporterTopLevel",        "XML",           XML_INIT_CLASS,        "XMLList",       XML_INIT_CLASS,        "Namespace",     XML_INIT_CLASS,        "QName",         XML_INIT_CLASS,    };    private static final Object LIBRARY_SCOPE_KEY = new Object();    public static boolean isRhinoRuntimeType(Class cl)    {        if (cl.isPrimitive()) {            return (cl != Character.TYPE);        } else {            return (cl == StringClass || cl == BooleanClass                    || NumberClass.isAssignableFrom(cl)                    || ScriptableClass.isAssignableFrom(cl));        }    }    public static ScriptableObject initStandardObjects(Context cx,                                                       ScriptableObject scope,                                                       boolean sealed)    {        if (scope == null) {            scope = new NativeObject();        }        scope.associateValue(LIBRARY_SCOPE_KEY, scope);        (new ClassCache()).associate(scope);        BaseFunction.init(scope, sealed);        NativeObject.init(scope, sealed);        Scriptable objectProto = ScriptableObject.getObjectPrototype(scope);        // Function.prototype.__proto__ should be Object.prototype        Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope);        functionProto.setPrototype(objectProto);        // Set the prototype of the object passed in if need be        if (scope.getPrototype() == null)            scope.setPrototype(objectProto);        // must precede NativeGlobal since it's needed therein        NativeError.init(scope, sealed);        NativeGlobal.init(cx, scope, sealed);        NativeArray.init(scope, sealed);        NativeString.init(scope, sealed);        NativeBoolean.init(scope, sealed);        NativeNumber.init(scope, sealed);        NativeDate.init(scope, sealed);        NativeMath.init(scope, sealed);        NativeWith.init(scope, sealed);        NativeCall.init(scope, sealed);        NativeScript.init(scope, sealed);        boolean withXml = cx.hasFeature(Context.FEATURE_E4X);        for (int i = 0; i != lazilyNames.length; i += 2) {            String topProperty = lazilyNames[i];            String className = lazilyNames[i + 1];            if (!withXml && className == XML_INIT_CLASS) {                continue;            }            new LazilyLoadedCtor(scope, topProperty, className, sealed);        }        Continuation.init(scope, sealed);        return scope;    }    public static ScriptableObject getLibraryScopeOrNull(Scriptable scope)    {        ScriptableObject libScope;        libScope = (ScriptableObject)ScriptableObject.                       getTopScopeValue(scope, LIBRARY_SCOPE_KEY);        return libScope;    }    // It is public so NativeRegExp can access it .    public static boolean isJSLineTerminator(int c)    {        // Optimization for faster check for eol character:        // they do not have 0xDFD0 bits set        if ((c & 0xDFD0) != 0) {            return false;        }        return c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029;    }    public static Boolean wrapBoolean(boolean b)    {        return b ? Boolean.TRUE : Boolean.FALSE;    }    public static Integer wrapInt(int i)    {        return new Integer(i);    }    public static Number wrapNumber(double x)    {        if (x != x) {            return ScriptRuntime.NaNobj;        }        return new Double(x);    }    /**     * Convert the value to a boolean.     *     * See ECMA 9.2.     */    public static boolean toBoolean(Object val)    {        for (;;) {            if (val instanceof Boolean)                return ((Boolean) val).booleanValue();            if (val == null || val == Undefined.instance)                return false;            if (val instanceof String)                return ((String) val).length() != 0;            if (val instanceof Number) {                double d = ((Number) val).doubleValue();                return (d == d && d != 0.0);            }            if (val instanceof Scriptable) {                if (Context.getContext().isVersionECMA1()) {                    // pure ECMA                    return true;                }                // ECMA extension                val = ((Scriptable) val).getDefaultValue(BooleanClass);                if (val instanceof Scriptable)                    throw errorWithClassName("msg.primitive.expected", val);                continue;            }            warnAboutNonJSObject(val);            return true;        }    }    public static boolean toBoolean(Object[] args, int index) {        return (index < args.length) ? toBoolean(args[index]) : false;    }    /**     * Convert the value to a number.     *     * See ECMA 9.3.     */    public static double toNumber(Object val)    {        for (;;) {            if (val instanceof Number)                return ((Number) val).doubleValue();            if (val == null)                return +0.0;            if (val == Undefined.instance)                return NaN;            if (val instanceof String)                return toNumber((String) val);            if (val instanceof Boolean)                return ((Boolean) val).booleanValue() ? 1 : +0.0;            if (val instanceof Scriptable) {                val = ((Scriptable) val).getDefaultValue(NumberClass);                if (val instanceof Scriptable)                    throw errorWithClassName("msg.primitive.expected", val);                continue;            }            warnAboutNonJSObject(val);            return NaN;        }    }    public static double toNumber(Object[] args, int index) {        return (index < args.length) ? toNumber(args[index]) : NaN;    }    // Can not use Double.NaN defined as 0.0d / 0.0 as under the Microsoft VM,    // versions 2.01 and 3.0P1, that causes some uses (returns at least) of    // Double.NaN to be converted to 1.0.    // So we use ScriptRuntime.NaN instead of Double.NaN.    public static final double        NaN = Double.longBitsToDouble(0x7ff8000000000000L);    // A similar problem exists for negative zero.    public static final double        negativeZero = Double.longBitsToDouble(0x8000000000000000L);    public static final Double NaNobj = new Double(NaN);    /*     * Helper function for toNumber, parseInt, and TokenStream.getToken.     */    static double stringToNumber(String s, int start, int radix) {        char digitMax = '9';        char lowerCaseBound = 'a';        char upperCaseBound = 'A';        int len = s.length();        if (radix < 10) {            digitMax = (char) ('0' + radix - 1);        }        if (radix > 10) {            lowerCaseBound = (char) ('a' + radix - 10);            upperCaseBound = (char) ('A' + radix - 10);        }        int end;        double sum = 0.0;        for (end=start; end < len; end++) {            char c = s.charAt(end);            int newDigit;            if ('0' <= c && c <= digitMax)                newDigit = c - '0';            else if ('a' <= c && c < lowerCaseBound)                newDigit = c - 'a' + 10;            else if ('A' <= c && c < upperCaseBound)                newDigit = c - 'A' + 10;            else                break;            sum = sum*radix + newDigit;        }        if (start == end) {            return NaN;        }        if (sum >= 9007199254740992.0) {            if (radix == 10) {                /* If we're accumulating a decimal number and the number                 * is >= 2^53, then the result from the repeated multiply-add                 * above may be inaccurate.  Call Java to get the correct                 * answer.                 */                try {                    return Double.valueOf(s.substring(start, end)).doubleValue();                } catch (NumberFormatException nfe) {                    return NaN;                }            } else if (radix == 2 || radix == 4 || radix == 8 ||                       radix == 16 || radix == 32)            {                /* The number may also be inaccurate for one of these bases.                 * This happens if the addition in value*radix + digit causes                 * a round-down to an even least significant mantissa bit                 * when the first dropped bit is a one.  If any of the                 * following digits in the number (which haven't been added                 * in yet) are nonzero then the correct action would have                 * been to round up instead of down.  An example of this                 * occurs when reading the number 0x1000000000000081, which                 * rounds to 0x1000000000000000 instead of 0x1000000000000100.                 */                int bitShiftInChar = 1;                int digit = 0;                final int SKIP_LEADING_ZEROS = 0;                final int FIRST_EXACT_53_BITS = 1;                final int AFTER_BIT_53         = 2;                final int ZEROS_AFTER_54 = 3;                final int MIXED_AFTER_54 = 4;                int state = SKIP_LEADING_ZEROS;                int exactBitsLimit = 53;                double factor = 0.0;                boolean bit53 = false;                // bit54 is the 54th bit (the first dropped from the mantissa)                boolean bit54 = false;                for (;;) {                    if (bitShiftInChar == 1) {                        if (start == end)                            break;                        digit = s.charAt(start++);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -