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

📄 nativearray.java

📁 javascript语言的解释器源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                Object[] e = getIds(); // will only find in object itself                for (int i=0; i < e.length; i++) {                    Object id = e[i];                    if (id instanceof String) {                        // > MAXINT will appear as string                        String strId = (String)id;                        long index = toArrayIndex(strId);                        if (index >= longVal)                            delete(strId);                    } else {                        int index = ((Integer)id).intValue();                        if (index >= longVal)                            delete(index);                    }                }            } else {                // assume a dense representation                for (long i = longVal; i < length; i++) {                    deleteElem(this, i);                }            }        }        length = longVal;    }    /* Support for generic Array-ish objects.  Most of the Array     * functions try to be generic; anything that has a length     * property is assumed to be an array.     * getLengthProperty returns 0 if obj does not have the length property     * or its value is not convertible to a number.     */    static long getLengthProperty(Context cx, Scriptable obj) {        // These will both give numeric lengths within Uint32 range.        if (obj instanceof NativeString) {            return ((NativeString)obj).getLength();        } else if (obj instanceof NativeArray) {            return ((NativeArray)obj).getLength();        } else if (!(obj instanceof Scriptable)) {            return 0;        }        return ScriptRuntime.toUint32(            ScriptRuntime.getObjectProp(obj, "length", cx));    }    private static Object setLengthProperty(Context cx, Scriptable target,                                            long length)    {        return ScriptRuntime.setObjectProp(                   target, "length", ScriptRuntime.wrapNumber(length), cx);    }    /* Utility functions to encapsulate index > Integer.MAX_VALUE     * handling.  Also avoids unnecessary object creation that would     * be necessary to use the general ScriptRuntime.get/setElem     * functions... though this is probably premature optimization.     */    private static void deleteElem(Scriptable target, long index) {        int i = (int)index;        if (i == index) { target.delete(i); }        else { target.delete(Long.toString(index)); }    }    private static Object getElem(Context cx, Scriptable target, long index)    {        if (index > Integer.MAX_VALUE) {            String id = Long.toString(index);            return ScriptRuntime.getObjectProp(target, id, cx);        } else {            return ScriptRuntime.getObjectIndex(target, (int)index, cx);        }    }    private static void setElem(Context cx, Scriptable target, long index,                                Object value)    {        if (index > Integer.MAX_VALUE) {            String id = Long.toString(index);            ScriptRuntime.setObjectProp(target, id, value, cx);        } else {            ScriptRuntime.setObjectIndex(target, (int)index, value, cx);        }    }    private static String toStringHelper(Context cx, Scriptable scope,                                         Scriptable thisObj,                                         boolean toSource, boolean toLocale)    {        /* It's probably redundant to handle long lengths in this         * function; StringBuffers are limited to 2^31 in java.         */        long length = getLengthProperty(cx, thisObj);        StringBuffer result = new StringBuffer(256);        // whether to return '4,unquoted,5' or '[4, "quoted", 5]'        String separator;        if (toSource) {            result.append('[');            separator = ", ";        } else {            separator = ",";        }        boolean haslast = false;        long i = 0;        boolean toplevel, iterating;        if (cx.iterating == null) {            toplevel = true;            iterating = false;            cx.iterating = new ObjToIntMap(31);        } else {            toplevel = false;            iterating = cx.iterating.has(thisObj);        }        // Make sure cx.iterating is set to null when done        // so we don't leak memory        try {            if (!iterating) {                cx.iterating.put(thisObj, 0); // stop recursion.                for (i = 0; i < length; i++) {                    if (i > 0) result.append(separator);                    Object elem = getElem(cx, thisObj, i);                    if (elem == null || elem == Undefined.instance) {                        haslast = false;                        continue;                    }                    haslast = true;                    if (toSource) {                        result.append(ScriptRuntime.uneval(cx, scope, elem));                    } else if (elem instanceof String) {                        String s = (String)elem;                        if (toSource) {                            result.append('\"');                            result.append(ScriptRuntime.escapeString(s));                            result.append('\"');                        } else {                            result.append(s);                        }                    } else {                        if (toLocale && elem != Undefined.instance &&                            elem != null)                        {                            Callable fun;                            Scriptable funThis;                            fun = ScriptRuntime.getPropFunctionAndThis(                                      elem, "toLocaleString", cx);                            funThis = ScriptRuntime.lastStoredScriptable(cx);                            elem = fun.call(cx, scope, funThis,                                            ScriptRuntime.emptyArgs);                        }                        result.append(ScriptRuntime.toString(elem));                    }                }            }        } finally {            if (toplevel) {                cx.iterating = null;            }        }        if (toSource) {            //for [,,].length behavior; we want toString to be symmetric.            if (!haslast && i > 0)                result.append(", ]");            else                result.append(']');        }        return result.toString();    }    /**     * See ECMA 15.4.4.3     */    private static String js_join(Context cx, Scriptable thisObj,                                  Object[] args)    {        String separator;        long llength = getLengthProperty(cx, thisObj);        int length = (int)llength;        if (llength != length) {            throw Context.reportRuntimeError1(                "msg.arraylength.too.big", String.valueOf(llength));        }        // if no args, use "," as separator        if (args.length < 1 || args[0] == Undefined.instance) {            separator = ",";        } else {            separator = ScriptRuntime.toString(args[0]);        }        if (length == 0) {            return "";        }        String[] buf = new String[length];        int total_size = 0;        for (int i = 0; i != length; i++) {            Object temp = getElem(cx, thisObj, i);            if (temp != null && temp != Undefined.instance) {                String str = ScriptRuntime.toString(temp);                total_size += str.length();                buf[i] = str;            }        }        total_size += (length - 1) * separator.length();        StringBuffer sb = new StringBuffer(total_size);        for (int i = 0; i != length; i++) {            if (i != 0) {                sb.append(separator);            }            String str = buf[i];            if (str != null) {                // str == null for undefined or null                sb.append(str);            }        }        return sb.toString();    }    /**     * See ECMA 15.4.4.4     */    private static Scriptable js_reverse(Context cx, Scriptable thisObj,                                         Object[] args)    {        long len = getLengthProperty(cx, thisObj);        long half = len / 2;        for(long i=0; i < half; i++) {            long j = len - i - 1;            Object temp1 = getElem(cx, thisObj, i);            Object temp2 = getElem(cx, thisObj, j);            setElem(cx, thisObj, i, temp2);            setElem(cx, thisObj, j, temp1);        }        return thisObj;    }    /**     * See ECMA 15.4.4.5     */    private static Scriptable js_sort(Context cx, Scriptable scope,                                      Scriptable thisObj, Object[] args)    {        long length = getLengthProperty(cx, thisObj);        if (length <= 1) { return thisObj; }        Object compare;        Object[] cmpBuf;        if (args.length > 0 && Undefined.instance != args[0]) {            // sort with given compare function            compare = args[0];            cmpBuf = new Object[2]; // Buffer for cmp arguments        } else {            // sort with default compare            compare = null;            cmpBuf = null;        }        // Should we use the extended sort function, or the faster one?        if (length >= Integer.MAX_VALUE) {            heapsort_extended(cx, scope, thisObj, length, compare, cmpBuf);        }        else {            int ilength = (int)length;            // copy the JS array into a working array, so it can be            // sorted cheaply.            Object[] working = new Object[ilength];            for (int i = 0; i != ilength; ++i) {                working[i] = getElem(cx, thisObj, i);            }            heapsort(cx, scope, working, ilength, compare, cmpBuf);            // copy the working array back into thisObj            for (int i = 0; i != ilength; ++i) {                setElem(cx, thisObj, i, working[i]);            }        }        return thisObj;    }    // Return true only if x > y    private static boolean isBigger(Context cx, Scriptable scope,                                    Object x, Object y,                                    Object cmp, Object[] cmpBuf)    {        if (cmp == null) {            if (cmpBuf != null) Kit.codeBug();        } else {            if (cmpBuf == null || cmpBuf.length != 2) Kit.codeBug();        }        Object undef = Undefined.instance;        // sort undefined to end        if (undef == y) {            return false; // x can not be bigger then undef        } else if (undef == x) {            return true; // y != undef here, so x > y        }        if (cmp == null) {            // if no cmp function supplied, sort lexicographically            String a = ScriptRuntime.toString(x);            String b = ScriptRuntime.toString(y);            return a.compareTo(b) > 0;        }        else {            // assemble args and call supplied JS cmp function            cmpBuf[0] = x;            cmpBuf[1] = y;            Callable fun = ScriptRuntime.getValueFunctionAndThis(cmp, cx);            Scriptable funThis = ScriptRuntime.lastStoredScriptable(cx);            Object ret = fun.call(cx, scope, funThis, cmpBuf);            double d = ScriptRuntime.toNumber(ret);            // XXX what to do when cmp function returns NaN?  ECMA states            // that it's then not a 'consistent compararison function'... but            // then what do we do?  Back out and start over with the generic            // cmp function when we see a NaN?  Throw an error?            // for now, just ignore it:            return d > 0;        }    }/** Heapsort implementation. * See "Introduction to Algorithms" by Cormen, Leiserson, Rivest for details. * Adjusted for zero based indexes. */    private static void heapsort(Context cx, Scriptable scope,                                 Object[] array, int length,                                 Object cmp, Object[] cmpBuf)    {        if (length <= 1) Kit.codeBug();        // Build heap        for (int i = length / 2; i != 0;) {            --i;            Object pivot = array[i];            heapify(cx, scope, pivot, array, i, length, cmp, cmpBuf);        }        // Sort heap        for (int i = length; i != 1;) {            --i;            Object pivot = array[i];            array[i] = array[0];            heapify(cx, scope, pivot, array, 0, i, cmp, cmpBuf);        }    }/** pivot and child heaps of i should be made into heap starting at i, * original array[i] is never used to have less array access during sorting. */    private static void heapify(Context cx, Scriptable scope,                                Object pivot, Object[] array, int i, int end,                                Object cmp, Object[] cmpBuf)    {        for (;;) {            int child = i * 2 + 1;            if (child >= end) {                break;            }            Object childVal = array[child];            if (child + 1 < end) {                Object nextVal = array[child + 1];                if (isBigger(cx, scope, nextVal, childVal, cmp, cmpBuf)) {                    ++child; childVal = nextVal;                }            }            if (!isBigger(cx, scope, childVal, pivot, cmp, cmpBuf)) {                break;            }            array[i] = childVal;            i = child;        }        array[i] = pivot;    }/** Version of heapsort that call getElem/setElem on target to query/assign * array elements instead of Java array access */    private static void heapsort_extended(Context cx, Scriptable scope,                                          Scriptable target, long length,                                          Object cmp, Object[] cmpBuf)    {        if (length <= 1) Kit.codeBug();

⌨️ 快捷键说明

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