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

📄 jsarray.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
}static JSBoolarray_pop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsuint index;    jsid id;    jsval junk;    if (!js_GetLengthProperty(cx, obj, &index))        return JS_FALSE;    if (index > 0) {        index--;        if (!IndexToId(cx, index, &id))            return JS_FALSE;        /* Get the to-be-deleted property's value into rval. */        if (!OBJ_GET_PROPERTY(cx, obj, id, rval))            return JS_FALSE;        if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))            return JS_FALSE;    }    return js_SetLengthProperty(cx, obj, index);}static JSBoolarray_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsuint length, i;    jsid id, id2;    jsval v, junk;    if (!js_GetLengthProperty(cx, obj, &length))        return JS_FALSE;    if (length > 0) {        length--;        id = JSVAL_ZERO;        /* Get the to-be-deleted property's value into rval ASAP. */        if (!OBJ_GET_PROPERTY(cx, obj, id, rval))            return JS_FALSE;        /*         * Slide down the array above the first element.         */        if (length > 0) {            for (i = 1; i <= length; i++) {                if (!IndexToId(cx, i, &id))                    return JS_FALSE;                if (!IndexToId(cx, i - 1, &id2))                    return JS_FALSE;                if (!OBJ_GET_PROPERTY(cx, obj, id, &v))                    return JS_FALSE;                if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))                    return JS_FALSE;            }        }        /* Delete the only or last element. */        if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))            return JS_FALSE;    }    return js_SetLengthProperty(cx, obj, length);}static JSBoolarray_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,              jsval *rval){    jsuint length, last;    uintN i;    jsid id, id2;    jsval v;#if JS_HAS_SPARSE_ARRAYS    JSObject *obj2;    JSProperty *prop;#endif    if (!js_GetLengthProperty(cx, obj, &length))        return JS_FALSE;    if (argc > 0) {        /* Slide up the array to make room for argc at the bottom. */        if (length > 0) {            last = length;            while (last--) {                if (!IndexToId(cx, last, &id))                    return JS_FALSE;                if (!IndexToId(cx, last + argc, &id2))                    return JS_FALSE;#if JS_HAS_SPARSE_ARRAYS                if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))                    return JS_FALSE;                if (!prop) {                    OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */                    continue;                }                OBJ_DROP_PROPERTY(cx, obj2, prop);#endif                if (!OBJ_GET_PROPERTY(cx, obj, id, &v))                    return JS_FALSE;                if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))                    return JS_FALSE;            }        }        /* Copy from argv to the bottom of the array. */        for (i = 0; i < argc; i++) {            if (!IndexToId(cx, i, &id))                return JS_FALSE;            if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))                return JS_FALSE;        }        /* Follow Perl by returning the new array length. */        length += argc;        if (!js_SetLengthProperty(cx, obj, length))            return JS_FALSE;    }    return IndexToValue(cx, length, rval);}static JSBoolarray_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsuint length, begin, end, count, delta, last;    uintN i;    jsdouble d;    jsid id, id2;    jsval v;    JSObject *obj2;    /* Nothing to do if no args.  Otherwise lock and load length. */    if (argc == 0)        return JS_TRUE;    if (!js_GetLengthProperty(cx, obj, &length))        return JS_FALSE;    /* Convert the first argument into a starting index. */    if (!js_ValueToNumber(cx, *argv, &d))        return JS_FALSE;    d = js_DoubleToInteger(d);    if (d < 0) {        d += length;        if (d < 0)            d = 0;    } else if (d > length) {        d = length;    }    begin = (jsuint)d; /* d has been clamped to uint32 */    argc--;    argv++;    /* Convert the second argument from a count into a fencepost index. */    delta = length - begin;    if (argc == 0) {        count = delta;        end = length;    } else {        if (!js_ValueToNumber(cx, *argv, &d))            return JS_FALSE;        d = js_DoubleToInteger(d);        if (d < 0)            d = 0;        else if (d > delta)            d = delta;        count = (jsuint)d;        end = begin + count;        argc--;        argv++;    }    if (count == 1 && cx->version == JSVERSION_1_2) {        /*         * JS lacks "list context", whereby in Perl one turns the single         * scalar that's spliced out into an array just by assigning it to         * @single instead of $single, or by using it as Perl push's first         * argument, for instance.         *         * JS1.2 emulated Perl too closely and returned a non-Array for         * the single-splice-out case, requiring callers to test and wrap         * in [] if necessary.  So JS1.3, default, and other versions all         * return an array of length 1 for uniformity.         */        if (!IndexToId(cx, begin, &id))            return JS_FALSE;        if (!OBJ_GET_PROPERTY(cx, obj, id, rval))            return JS_FALSE;    } else {        if (cx->version != JSVERSION_1_2 || count > 0) {            /*             * Create a new array value to return.  Our ECMA v2 proposal specs             * that splice always returns an array value, even when given no             * arguments.  We think this is best because it eliminates the need             * for callers to do an extra test to handle the empty splice case.             */            obj2 = js_NewArrayObject(cx, 0, NULL);            if (!obj2)                return JS_FALSE;            *rval = OBJECT_TO_JSVAL(obj2);            /* If there are elements to remove, put them into the return value. */            if (count > 0) {                for (last = begin; last < end; last++) {                    if (!IndexToId(cx, last, &id))                        return JS_FALSE;                    if (!IndexToId(cx, last - begin, &id2))                        return JS_FALSE;                    if (!OBJ_GET_PROPERTY(cx, obj, id, &v))                        return JS_FALSE;                    if (!OBJ_SET_PROPERTY(cx, obj2, id2, &v))                        return JS_FALSE;                }            }        }    }    /* Find the direction (up or down) to copy and make way for argv. */    if (argc > count) {        delta = (jsuint)argc - count;        last = length;        /* (uint) end could be 0, so can't use vanilla >= test */        while (last-- > end) {            if (!IndexToId(cx, last, &id))                return JS_FALSE;            if (!IndexToId(cx, last + delta, &id2))                return JS_FALSE;            if (!OBJ_GET_PROPERTY(cx, obj, id, &v))                return JS_FALSE;            if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))                return JS_FALSE;        }        length += delta;    } else if (argc < count) {        delta = count - (jsuint)argc;        for (last = end; last < length; last++) {            if (!IndexToId(cx, last, &id))                return JS_FALSE;            if (!IndexToId(cx, last - delta, &id2))                return JS_FALSE;            if (!OBJ_GET_PROPERTY(cx, obj, id, &v))                return JS_FALSE;            if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))                return JS_FALSE;        }        length -= delta;    }    /* Copy from argv into the hole to complete the splice. */    for (i = 0; i < argc; i++) {        if (!IndexToId(cx, begin + i, &id))            return JS_FALSE;        if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))            return JS_FALSE;    }    /* Update length in case we deleted elements from the end. */    return js_SetLengthProperty(cx, obj, length);}#endif /* JS_HAS_MORE_PERL_FUN */#if JS_HAS_SEQUENCE_OPS/* * Python-esque sequence operations. */static JSBoolarray_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSObject *nobj, *aobj;    jsuint length, alength, slot;    uintN i;    jsval v;    jsid id, id2;    /* Treat obj as the first argument; see ECMA 15.4.4.4. */    --argv;    JS_ASSERT(obj == JSVAL_TO_OBJECT(argv[0]));    /* Create a new Array object and store it in the rval local root. */    nobj = js_NewArrayObject(cx, 0, NULL);    if (!nobj)        return JS_FALSE;    *rval = OBJECT_TO_JSVAL(nobj);    /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */    length = 0;    for (i = 0; i <= argc; i++) {        v = argv[i];        if (JSVAL_IS_OBJECT(v)) {            aobj = JSVAL_TO_OBJECT(v);            if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) {                if (!OBJ_GET_PROPERTY(cx, aobj,                                      (jsid)cx->runtime->atomState.lengthAtom,                                      &v)) {                    return JS_FALSE;                }                if (!ValueIsLength(cx, v, &alength))                    return JS_FALSE;                for (slot = 0; slot < alength; slot++) {                    if (!IndexToId(cx, slot, &id))                        return JS_FALSE;                    if (!IndexToId(cx, length + slot, &id2))                        return JS_FALSE;                    if (!OBJ_GET_PROPERTY(cx, aobj, id, &v))                        return JS_FALSE;                    if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))                        return JS_FALSE;                }                length += alength;                continue;            }        }        if (!IndexToId(cx, length, &id))            return JS_FALSE;        if (!OBJ_SET_PROPERTY(cx, nobj, id, &v))            return JS_FALSE;        length++;    }    return JS_TRUE;}static JSBoolarray_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSObject *nobj;    jsuint length, begin, end, slot;    jsdouble d;    jsid id, id2;    jsval v;    nobj = js_NewArrayObject(cx, 0, NULL);    if (!nobj)        return JS_FALSE;    if (!js_GetLengthProperty(cx, obj, &length))        return JS_FALSE;    begin = 0;    end = length;    if (argc > 0) {        if (!js_ValueToNumber(cx, argv[0], &d))            return JS_FALSE;        d = js_DoubleToInteger(d);        if (d < 0) {            d += length;            if (d < 0)                d = 0;        } else if (d > length) {            d = length;        }        begin = (jsuint)d;        if (argc > 1) {            if (!js_ValueToNumber(cx, argv[1], &d))                return JS_FALSE;            d = js_DoubleToInteger(d);            if (d < 0) {                d += length;                if (d < 0)                    d = 0;            } else if (d > length) {                d = length;            }            end = (jsuint)d;        }    }    for (slot = begin; slot < end; slot++) {        if (!IndexToId(cx, slot, &id))            return JS_FALSE;        if (!IndexToId(cx, slot - begin, &id2))            return JS_FALSE;        if (!OBJ_GET_PROPERTY(cx, obj, id, &v))            return JS_FALSE;        if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))            return JS_FALSE;    }    *rval = OBJECT_TO_JSVAL(nobj);    return JS_TRUE;}#endif /* JS_HAS_SEQUENCE_OPS */static JSFunctionSpec array_methods[] = {#if JS_HAS_TOSOURCE    {js_toSource_str,       array_toSource,         0,0,0},#endif    {js_toString_str,       array_toString,         0,0,0},    {js_toLocaleString_str, array_toLocaleString,   0,0,0},    /* Perl-ish methods. */#if JS_HAS_SOME_PERL_FUN    {"join",                array_join,             1,0,0},    {"reverse",             array_reverse,          0,0,0},    {"sort",                array_sort,             1,0,0},#endif#if JS_HAS_MORE_PERL_FUN    {"push",                array_push,             1,0,0},    {"pop",                 array_pop,              0,0,0},    {"shift",               array_shift,            0,0,0},    {"unshift",             array_unshift,          1,0,0},    {"splice",              array_splice,           1,0,0},#endif    /* Python-esque sequence methods. */#if JS_HAS_SEQUENCE_OPS    {"concat",              array_concat,           0,0,0},    {"slice",               array_slice,            0,0,0},#endif    {0,0,0,0,0}};static JSBoolArray(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsuint length;    jsval *vector;    /* If called without new, replace obj with a new Array object. */    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {        obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);        if (!obj)            return JS_FALSE;        *rval = OBJECT_TO_JSVAL(obj);    }    if (argc == 0) {        length = 0;        vector = NULL;    } else if (cx->version == JSVERSION_1_2) {        length = (jsuint) argc;        vector = argv;    } else if (argc > 1) {        length = (jsuint) argc;        vector = argv;    } else if (!JSVAL_IS_NUMBER(argv[0])) {        length = 1;        vector = argv;    } else {        if (!ValueIsLength(cx, argv[0], &length))            return JS_FALSE;        vector = NULL;    }    return InitArrayObject(cx, obj, length, vector);}JSObject *js_InitArrayClass(JSContext *cx, JSObject *obj){    JSObject *proto;    proto = JS_InitClass(cx, obj, NULL, &js_ArrayClass, Array, 1,                         NULL, array_methods, NULL, NULL);    /* Initialize the Array prototype object so it gets a length property. */    if (!proto || !InitArrayObject(cx, proto, 0, NULL))        return NULL;    return proto;}JSObject *js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector){    JSObject *obj;    obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);    if (!obj)        return NULL;    if (!InitArrayObject(cx, obj, length, vector)) {        cx->newborn[GCX_OBJECT] = NULL;        return NULL;    }    return obj;}

⌨️ 快捷键说明

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