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

📄 jsobj.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
                    if (attrs & JSPROP_GETTER)                        val = (jsval) ((JSScopeProperty*)prop)->getter;                    if (attrs & JSPROP_SETTER) {                        if (val != JSVAL_NULL) {                            /* Mark the getter, then set val to setter. */                            ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),                                                   NULL)                                  != NULL);                        }                        val = (jsval) ((JSScopeProperty*)prop)->setter;                    }                } else {                    ok = OBJ_GET_PROPERTY(cx, obj, id, &val);                }            }            OBJ_DROP_PROPERTY(cx, obj2, prop);#else            ok = OBJ_GET_PROPERTY(cx, obj, id, &val);#endif            if (!ok)                break;            if (!JSVAL_IS_PRIMITIVE(val) &&                !MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) {                ok = JS_FALSE;                break;            }        }        if (!ok || !idap)            JS_DestroyIdArray(cx, ida);        if (!ok)            return NULL;    } else {        sharpid = JS_PTR_TO_UINT32(he->value);        if (sharpid == 0) {            sharpid = ++map->sharpgen << SHARP_ID_SHIFT;            he->value = JS_UINT32_TO_PTR(sharpid);        }        ida = NULL;    }    if (idap)        *idap = ida;    return he;}JSHashEntry *js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,                    jschar **sp){    JSSharpObjectMap *map;    JSHashTable *table;    JSIdArray *ida;    JSHashNumber hash;    JSHashEntry *he, **hep;    jsatomid sharpid;    char buf[20];    size_t len;    /* Set to null in case we return an early error. */    *sp = NULL;    map = &cx->sharpObjectMap;    table = map->table;    if (!table) {        table = JS_NewHashTable(8, js_hash_object, JS_CompareValues,                                JS_CompareValues, NULL, NULL);        if (!table) {            JS_ReportOutOfMemory(cx);            return NULL;        }        map->table = table;    }    ida = NULL;    if (map->depth == 0) {        he = MarkSharpObjects(cx, obj, &ida);        if (!he)            goto bad;        JS_ASSERT (!IS_SHARP (he));        if (!idap) {            JS_DestroyIdArray(cx, ida);            ida = NULL;        }    } else {        hash = js_hash_object(obj);        hep = JS_HashTableRawLookup(table, hash, obj);        he = *hep;        /*         * It's possible that the value of a property has changed from the         * first time the object's properties are traversed (when the property         * ids are entered into the hash table) to the second (when they are         * converted to strings), i.e., the OBJ_GET_PROPERTY() call is not         * idempotent.         */        if (!he) {            he = JS_HashTableRawAdd(table, hep, hash, obj, NULL);            if (!he) {                JS_ReportOutOfMemory(cx);                goto bad;            }            *sp = NULL;            sharpid = 0;            goto out;        }    }    sharpid = JS_PTR_TO_UINT32(he->value);    if (sharpid == 0) {        *sp = NULL;    } else {        len = JS_snprintf(buf, sizeof buf, "#%u%c",                          sharpid >> SHARP_ID_SHIFT,                          (sharpid & SHARP_BIT) ? '#' : '=');        *sp = js_InflateString(cx, buf, len);        if (!*sp) {            if (ida)                JS_DestroyIdArray(cx, ida);            goto bad;        }    }out:    JS_ASSERT(he);    if ((sharpid & SHARP_BIT) == 0) {        if (idap && !ida) {            ida = JS_Enumerate(cx, obj);            if (!ida) {                if (*sp) {                    JS_free(cx, *sp);                    *sp = NULL;                }                goto bad;            }        }        map->depth++;    }    if (idap)        *idap = ida;    return he;bad:    /* Clean up the sharpObjectMap table on outermost error. */    if (map->depth == 0) {        map->sharpgen = 0;        JS_HashTableDestroy(map->table);        map->table = NULL;    }    return NULL;}voidjs_LeaveSharpObject(JSContext *cx, JSIdArray **idap){    JSSharpObjectMap *map;    JSIdArray *ida;    map = &cx->sharpObjectMap;    JS_ASSERT(map->depth > 0);    if (--map->depth == 0) {        map->sharpgen = 0;        JS_HashTableDestroy(map->table);        map->table = NULL;    }    if (idap) {        ida = *idap;        if (ida) {            JS_DestroyIdArray(cx, ida);            *idap = NULL;        }    }}#define OBJ_TOSTRING_EXTRA      3       /* for 3 local GC roots */#if JS_HAS_INITIALIZERS || JS_HAS_TOSOURCEJSBooljs_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                jsval *rval){    JSBool ok, outermost;    JSHashEntry *he;    JSIdArray *ida;    jschar *chars, *ochars, *vsharp;    const jschar *idstrchars, *vchars;    size_t nchars, idstrlength, gsoplength, vlength, vsharplength;    char *comma;    jsint i, j, length, valcnt;    jsid id;#if JS_HAS_GETTER_SETTER    JSObject *obj2;    JSProperty *prop;    uintN attrs;#endif    jsval val[2];    JSString *gsop[2];    JSAtom *atom;    JSString *idstr, *valstr, *str;    int stackDummy;    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);        return JS_FALSE;    }    /*     * obj_toString for 1.2 calls toSource, and doesn't want the extra parens     * on the outside.     */    outermost = (cx->version != JSVERSION_1_2 && cx->sharpObjectMap.depth == 0);    he = js_EnterSharpObject(cx, obj, &ida, &chars);    if (!he)        return JS_FALSE;    if (IS_SHARP(he)) {        /*         * We didn't enter -- obj is already "sharp", meaning we've visited it         * already in our depth first search, and therefore chars contains a         * string of the form "#n#".         */        JS_ASSERT(!ida);#if JS_HAS_SHARP_VARS        nchars = js_strlen(chars);#else        chars[0] = '{';        chars[1] = '}';        chars[2] = 0;        nchars = 2;#endif        goto make_string;    }    JS_ASSERT(ida);    ok = JS_TRUE;    if (!chars) {        /* If outermost, allocate 4 + 1 for "({})" and the terminator. */        chars = (jschar *) malloc(((outermost ? 4 : 2) + 1) * sizeof(jschar));        nchars = 0;        if (!chars)            goto error;        if (outermost)            chars[nchars++] = '(';    } else {        /* js_EnterSharpObject returned a string of the form "#n=" in chars. */        MAKE_SHARP(he);        nchars = js_strlen(chars);        chars = (jschar *)            realloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));        if (!chars) {            free(ochars);            goto error;        }        if (outermost) {            /*             * No need for parentheses around the whole shebang, because #n=             * unambiguously begins an object initializer, and never a block             * statement.             */            outermost = JS_FALSE;        }    }    chars[nchars++] = '{';    comma = NULL;    for (i = 0, length = ida->length; i < length; i++) {        /* Get strings for id and value and GC-root them via argv. */        id = ida->vector[i];#if JS_HAS_GETTER_SETTER        ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);        if (!ok)            goto error;        valcnt = 0;        if (prop) {            ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);            if (!ok) {                OBJ_DROP_PROPERTY(cx, obj2, prop);                goto error;            }            if (OBJ_IS_NATIVE(obj2) &&                (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {                if (attrs & JSPROP_GETTER) {                    val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter;#ifdef OLD_GETTER_SETTER                    gsop[valcnt] =                        ATOM_TO_STRING(cx->runtime->atomState.getterAtom);#else                    gsop[valcnt] =                        ATOM_TO_STRING(cx->runtime->atomState.getAtom);#endif                    valcnt++;                }                if (attrs & JSPROP_SETTER) {                    val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter;#ifdef OLD_GETTER_SETTER                    gsop[valcnt] =                        ATOM_TO_STRING(cx->runtime->atomState.setterAtom);#else                    gsop[valcnt] =                        ATOM_TO_STRING(cx->runtime->atomState.setAtom);#endif                    valcnt++;                }            } else {                valcnt = 1;                gsop[0] = NULL;                ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);            }            OBJ_DROP_PROPERTY(cx, obj2, prop);        }#else  /* !JS_HAS_GETTER_SETTER */        valcnt = 1;        gsop[0] = NULL;        ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);#endif /* !JS_HAS_GETTER_SETTER */        if (!ok)            goto error;        /* Convert id to a jsval and then to a string. */        atom = JSVAL_IS_INT(id) ? NULL : (JSAtom *)id;        id = ID_TO_VALUE(id);        idstr = js_ValueToString(cx, id);        if (!idstr) {            ok = JS_FALSE;            goto error;        }        argv[0] = STRING_TO_JSVAL(idstr);        /*         * If id is a string that's a reserved identifier, or else id is not         * an identifier at all, then it needs to be quoted.  Also, negative         * integer ids must be quoted.         */        if (atom            ? (ATOM_KEYWORD(atom) || !js_IsIdentifier(idstr))            : JSVAL_TO_INT(id) < 0) {            idstr = js_QuoteString(cx, idstr, (jschar)'\'');            if (!idstr) {                ok = JS_FALSE;                goto error;            }            argv[0] = STRING_TO_JSVAL(idstr);        }        idstrchars = JSSTRING_CHARS(idstr);        idstrlength = JSSTRING_LENGTH(idstr);        for (j = 0; j < valcnt; j++) {            /* Convert val[j] to its canonical source form. */            valstr = js_ValueToSource(cx, val[j]);            if (!valstr) {                ok = JS_FALSE;                goto error;            }            argv[1+j] = STRING_TO_JSVAL(valstr);            vchars = JSSTRING_CHARS(valstr);            vlength = JSSTRING_LENGTH(valstr);#ifndef OLD_GETTER_SETTER            /* Remove 'function ' from beginning of valstr. */            if (gsop[j]) {                int n = strlen(js_function_str) + 1;                vchars += n;                vlength -= n;            }#endif            /* If val[j] is a non-sharp object, consider sharpening it. */            vsharp = NULL;            vsharplength = 0;#if JS_HAS_SHARP_VARS            if (!JSVAL_IS_PRIMITIVE(val[j]) && vchars[0] != '#') {                he = js_EnterSharpObject(cx, JSVAL_TO_OBJECT(val[j]), NULL,                                         &vsharp);                if (!he) {                    ok = JS_FALSE;                    goto error;                }                if (IS_SHARP(he)) {                    vchars = vsharp;                    vlength = js_strlen(vchars);                } else {                    if (vsharp) {                        vsharplength = js_strlen(vsharp);                        MAKE_SHARP(he);                    }                    js_LeaveSharpObject(cx, NULL);                }            }#endif            /* Allocate 1 + 1 at end for closing brace and terminating 0. */            chars = (jschar *)                realloc((ochars = chars),                        (nchars + (comma ? 2 : 0) +                         idstrlength + 1 +                         (gsop[j] ? 1 + JSSTRING_LENGTH(gsop[j]) : 0) +                         vsharplength + vlength +                         (outermost ? 2 : 1) + 1) * sizeof(jschar));            if (!chars) {                /* Save code space on error: let JS_free ignore null vsharp. */                JS_free(cx, vsharp);                free(ochars);                goto error;            }            if (comma) {                chars[nchars++] = comma[0];                chars[nchars++] = comma[1];            }            comma = ", ";#ifdef OLD_GETTER_SETTER            js_strncpy(&chars[nchars], idstrchars, idstrlength);            nchars += idstrlength;            if (gsop[j]) {                chars[nchars++] = ' ';                gsoplength = JSSTRING_LENGTH(gsop[j]);                js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);                nchars += gsoplength;            }            chars[nchars++] = ':';#else            if (gsop[j]) {                gsoplength = JSSTRING_LENGTH(gsop[j]);

⌨️ 快捷键说明

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