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

📄 jsarray.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
    chars[nchars] = 0;    str = js_NewString(cx, chars, nchars, 0);    if (!str) {        free(chars);        return JS_FALSE;    }    *rval = STRING_TO_JSVAL(str);    return JS_TRUE;}static jschar   comma_space_ucstr[] = {',', ' ', 0};static jschar   comma_ucstr[]       = {',', 0};static JSString comma_space         = {2, comma_space_ucstr};static JSString comma               = {1, comma_ucstr};#if JS_HAS_TOSOURCEstatic JSBoolarray_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,               jsval *rval){    return array_join_sub(cx, obj, &comma_space, JS_TRUE, rval, JS_FALSE);}#endifstatic JSBoolarray_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,               jsval *rval){    JSBool literalize;    /*     * JS1.2 arrays convert to array literals, with a comma followed by a space     * between each element.     */    literalize = (cx->version == JSVERSION_1_2);    return array_join_sub(cx, obj, literalize ? &comma_space : &comma,                          literalize, rval, JS_FALSE);}static JSBoolarray_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,               jsval *rval){    /*     *  Passing comma here as the separator. Need a way to get a     *  locale-specific version.     */    return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_TRUE);}static JSBoolInitArrayElements(JSContext *cx, JSObject *obj, jsuint length, jsval *vector){    jsuint index;    jsid id;    for (index = 0; index < length; index++) {        if (!IndexToId(cx, index, &id))            return JS_FALSE;        if (!OBJ_SET_PROPERTY(cx, obj, id, &vector[index]))            return JS_FALSE;    }    return JS_TRUE;}static JSBoolInitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector){    jsval v;    jsid id;    if (!IndexToValue(cx, length, &v))        return JS_FALSE;    id = (jsid) cx->runtime->atomState.lengthAtom;    if (!OBJ_DEFINE_PROPERTY(cx, obj, id, v,                             array_length_getter, array_length_setter,                             JSPROP_PERMANENT,                             NULL)) {          return JS_FALSE;    }    if (!vector)        return JS_TRUE;    return InitArrayElements(cx, obj, length, vector);}#if JS_HAS_SOME_PERL_FUN/* * Perl-inspired join, reverse, and sort. */static JSBoolarray_join(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSString *str;    if (JSVAL_IS_VOID(argv[0]))        return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_FALSE);    str = js_ValueToString(cx, argv[0]);    if (!str)        return JS_FALSE;    argv[0] = STRING_TO_JSVAL(str);    return array_join_sub(cx, obj, str, JS_FALSE, rval, JS_FALSE);}static JSBoolarray_reverse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,              jsval *rval){    jsuint len, half, i;    jsid id, id2;    jsval v, v2;    if (!js_GetLengthProperty(cx, obj, &len))        return JS_FALSE;    half = len / 2;    for (i = 0; i < half; i++) {        if (!IndexToId(cx, i, &id))            return JS_FALSE;        if (!IndexToId(cx, len - i - 1, &id2))            return JS_FALSE;        if (!OBJ_GET_PROPERTY(cx, obj, id, &v))            return JS_FALSE;        if (!OBJ_GET_PROPERTY(cx, obj, id2, &v2))            return JS_FALSE;#if JS_HAS_SPARSE_ARRAYS        /* This part isn't done yet. */        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_SET_PROPERTY(cx, obj, id, &v2))            return JS_FALSE;        if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))            return JS_FALSE;    }    *rval = OBJECT_TO_JSVAL(obj);    return JS_TRUE;}typedef struct HSortArgs {    void         *vec;    size_t       elsize;    void         *pivot;    JSComparator cmp;    void         *arg;    JSBool       fastcopy;} HSortArgs;static intsort_compare(const void *a, const void *b, void *arg);static intsort_compare_strings(const void *a, const void *b, void *arg);static voidHeapSortHelper(JSBool building, HSortArgs *hsa, size_t lo, size_t hi){    void *pivot, *vec, *vec2, *arg, *a, *b;    size_t elsize;    JSComparator cmp;    JSBool fastcopy;    size_t j, hiDiv2;    pivot = hsa->pivot;    vec = hsa->vec;    elsize = hsa->elsize;    vec2 =  (char *)vec - 2 * elsize;    cmp = hsa->cmp;    arg = hsa->arg;    fastcopy = hsa->fastcopy;#define MEMCPY(p,q,n) \    (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n))    if (lo == 1) {        j = 2;        b = (char *)vec + elsize;        if (j < hi && cmp(vec, b, arg) < 0)            j++;        a = (char *)vec + (hi - 1) * elsize;        b = (char *)vec2 + j * elsize;        /*          * During sorting phase b points to a member of heap that cannot be         * bigger then biggest of vec[0] and vec[1], and cmp(a, b, arg) <= 0         * always holds.         */        if ((building || hi == 2) && cmp(a, b, arg) >= 0)            return;        MEMCPY(pivot, a, elsize);        MEMCPY(a, b, elsize);        lo = j;    } else {        a = (char *)vec2 + lo * elsize;        MEMCPY(pivot, a, elsize);    }    hiDiv2 = hi/2;    while (lo <= hiDiv2) {        j = lo + lo;        a = (char *)vec2 + j * elsize;        b = (char *)vec + (j - 1) * elsize;        if (j < hi && cmp(a, b, arg) < 0)            j++;        b = (char *)vec2 + j * elsize;        if (cmp(pivot, b, arg) >= 0)            break;        a = (char *)vec2 + lo * elsize;        MEMCPY(a, b, elsize);        lo = j;    }    a = (char *)vec2 + lo * elsize;    MEMCPY(a, pivot, elsize);#undef MEMCPY}JSBooljs_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg) {    void *pivot;    HSortArgs hsa;    size_t i;    pivot = malloc(elsize);    if (!pivot)        return JS_FALSE;    hsa.vec = vec;    hsa.elsize = elsize;    hsa.pivot = pivot;    hsa.cmp = cmp;    hsa.arg = arg;    hsa.fastcopy = (cmp == sort_compare || cmp == sort_compare_strings);    for (i = nel/2; i != 0; i--)        HeapSortHelper(JS_TRUE, &hsa, i, nel);    while (nel > 2)        HeapSortHelper(JS_FALSE, &hsa, 1, --nel);    free(pivot);    return JS_TRUE;}typedef struct CompareArgs {    JSContext  *context;    jsval      fval;    JSBool     status;} CompareArgs;static intsort_compare(const void *a, const void *b, void *arg){    jsval av = *(const jsval *)a, bv = *(const jsval *)b;    CompareArgs *ca = (CompareArgs *) arg;    JSContext *cx = ca->context;    jsdouble cmp = -1;    jsval fval, argv[2], rval;    JSBool ok;    fval = ca->fval;    if (fval == JSVAL_NULL) {        JSString *astr, *bstr;        if (av == bv) {            cmp = 0;        } else if (av == JSVAL_VOID || bv == JSVAL_VOID) {            /* Put undefined properties at the end. */            cmp = (av == JSVAL_VOID) ? 1 : -1;        } else if ((astr = js_ValueToString(cx, av)) != NULL &&                   (bstr = js_ValueToString(cx, bv)) != NULL) {            cmp = js_CompareStrings(astr, bstr);        } else {            ca->status = JS_FALSE;        }    } else {        argv[0] = av;        argv[1] = bv;        ok = js_InternalCall(cx,                             OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),                             fval, 2, argv, &rval);        if (ok) {            ok = js_ValueToNumber(cx, rval, &cmp);            /* Clamp cmp to -1, 0, 1. */            if (JSDOUBLE_IS_NaN(cmp)) {                /* XXX report some kind of error here?  ECMA talks about                 * 'consistent compare functions' that don't return NaN, but is                 * silent about what the result should be.  So we currently                 * ignore it.                 */                cmp = 0;            } else if (cmp > 0) {                cmp = 1; 	    } else if (cmp < 0) {		cmp = -1;	    } else {		cmp = 0;            }        } else {            ca->status = ok;        }    }    return (int)cmp;}static intsort_compare_strings(const void *a, const void *b, void *arg){    jsval av = *(const jsval *)a, bv = *(const jsval *)b;    return (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv));}/* XXXmccabe do the sort helper functions need to take int?  (Or can we claim * that 2^32 * 32 is too large to worry about?)  Something dumps when I change * to unsigned int; is qsort using -1 as a fencepost? */static JSBoolarray_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsval fval;    CompareArgs ca;    jsuint len, newlen, i;    jsval *vec;    jsid id;    size_t nbytes;    /*     * Optimize the default compare function case if all of obj's elements     * have values of type string.     */    JSBool all_strings;    if (argc > 0) {        if (JSVAL_IS_PRIMITIVE(argv[0])) {            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                 JSMSG_BAD_SORT_ARG);            return JS_FALSE;        }        fval = argv[0];        all_strings = JS_FALSE; /* non-default compare function */    } else {        fval = JSVAL_NULL;        all_strings = JS_TRUE;  /* check for all string values */    }    if (!js_GetLengthProperty(cx, obj, &len))        return JS_FALSE;    if (len == 0) {        *rval = OBJECT_TO_JSVAL(obj);        return JS_TRUE;    }    /*     * Test for size_t overflow, which could lead to indexing beyond the end     * of the malloc'd vector.     */    nbytes = len * sizeof(jsval);    if ((double) nbytes < (double) len * sizeof(jsval)) {        JS_ReportOutOfMemory(cx);        return JS_FALSE;    }    vec = (jsval *) JS_malloc(cx, nbytes);    if (!vec)        return JS_FALSE;#if JS_HAS_SPARSE_ARRAYS    newlen = 0;#else    newlen = len;#endif    for (i = 0; i < len; i++) {        ca.status = IndexToId(cx, i, &id);        if (!ca.status)            goto out;#if JS_HAS_SPARSE_ARRAYS        {            JSObject *obj2;            JSProperty *prop;            ca.status = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);            if (!ca.status)                goto out;            if (!prop) {                vec[i] = JSVAL_VOID;                continue;            }            OBJ_DROP_PROPERTY(cx, obj2, prop);            newlen++;        }#endif        ca.status = OBJ_GET_PROPERTY(cx, obj, id, &vec[i]);        if (!ca.status)            goto out;        /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */        all_strings &= JSVAL_IS_STRING(vec[i]);     }    ca.context = cx;    ca.fval = fval;    ca.status = JS_TRUE;    if (!js_HeapSort(vec, (size_t) len, sizeof(jsval),                     all_strings ? sort_compare_strings : sort_compare,                     &ca)) {        JS_ReportOutOfMemory(cx);        ca.status = JS_FALSE;    }    if (ca.status) {        ca.status = InitArrayElements(cx, obj, newlen, vec);        if (ca.status)            *rval = OBJECT_TO_JSVAL(obj);#if JS_HAS_SPARSE_ARRAYS        /* set length of newly-created array object to old length. */        if (ca.status && newlen < len) {            ca.status = js_SetLengthProperty(cx, obj, len);            /* Delete any leftover properties greater than newlen. */            while (ca.status && newlen < len) {                jsval junk;                ca.status = !IndexToId(cx, newlen, &id) ||                    !OBJ_DELETE_PROPERTY(cx, obj, id, &junk);                newlen++;            }        }#endif    }out:    if (vec)        JS_free(cx, vec);    return ca.status;}#endif /* JS_HAS_SOME_PERL_FUN */#if JS_HAS_MORE_PERL_FUN/* * Perl-inspired push, pop, shift, unshift, and splice methods. */static JSBoolarray_push(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsuint length;    uintN i;    jsid id;    if (!js_GetLengthProperty(cx, obj, &length))        return JS_FALSE;    for (i = 0; i < argc; i++) {        if (!IndexToId(cx, length + i, &id))            return JS_FALSE;        if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))            return JS_FALSE;    }    /*     * If JS1.2, follow Perl4 by returning the last thing pushed.  Otherwise,     * return the new array length.     */    length += argc;    if (cx->version == JSVERSION_1_2) {        *rval = argc ? argv[argc-1] : JSVAL_VOID;    } else {        if (!IndexToValue(cx, length, rval))            return JS_FALSE;    }    return js_SetLengthProperty(cx, obj, length);

⌨️ 快捷键说明

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