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

📄 jsexn.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
     * the backtrace procedure, not result in a failure of this constructor.     */    checkAccess = cx->runtime->checkObjectAccess;    if (checkAccess) {        older = JS_SetErrorReporter(cx, NULL);        state = JS_SaveExceptionState(cx);    }#ifdef __GNUC__         /* suppress bogus gcc warnings */    else {        older = NULL;        state = NULL;    }#endif    callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);    /*     * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes     * the next free jschar slot, and with room for at most stackmax non-null     * jschars.  If stackbuf is non-null, it always contains an extra slot for     * the null terminator we'll store at the end, as a backstop.     *     * All early returns must goto done after this point, till the after-loop     * cleanup code has run!     */    stackbuf = NULL;    stacklen = stackmax = 0;    ok = JS_TRUE;#define APPEND_CHAR_TO_STACK(c)                                               \    JS_BEGIN_MACRO                                                            \        if (stacklen == stackmax) {                                           \            void *ptr_;                                                       \            stackmax = stackmax ? 2 * stackmax : 64;                          \            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \            if (!ptr_) {                                                      \                ok = JS_FALSE;                                                \                goto done;                                                    \            }                                                                 \            stackbuf = ptr_;                                                  \        }                                                                     \        stackbuf[stacklen++] = (c);                                           \    JS_END_MACRO#define APPEND_STRING_TO_STACK(str)                                           \    JS_BEGIN_MACRO                                                            \        JSString *str_ = str;                                                 \        size_t length_ = JSSTRING_LENGTH(str_);                               \        if (stacklen + length_ > stackmax) {                                  \            void *ptr_;                                                       \            stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_));            \            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \            if (!ptr_) {                                                      \                ok = JS_FALSE;                                                \                goto done;                                                    \            }                                                                 \            stackbuf = ptr_;                                                  \        }                                                                     \        js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_);       \        stacklen += length_;                                                  \    JS_END_MACRO    for (fp = cx->fp; fp; fp = fp->down) {        if (checkAccess) {            v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL;            if (!JSVAL_IS_PRIMITIVE(v)) {                ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v);                if (!ok) {                    ok = JS_TRUE;                    break;                }            }        }        if (fp->fun) {            if (fp->fun->atom)                APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom));            APPEND_CHAR_TO_STACK('(');            for (i = 0; i < fp->argc; i++) {                /* Avoid toSource bloat and fallibility for object types. */                v = fp->argv[i];                if (JSVAL_IS_PRIMITIVE(v)) {                    argsrc = js_ValueToSource(cx, v);                } else if (JSVAL_IS_FUNCTION(cx, v)) {                    /* XXX Avoid function decompilation bloat for now. */                    argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v));                    if (!argsrc)                        argsrc = js_ValueToSource(cx, v);                } else {                    /* XXX Avoid toString on objects, it takes too long and                           uses too much memory, for too many classes (see                           Mozilla bug 166743). */                    char buf[100];                    JS_snprintf(buf, sizeof buf, "[object %s]",                                OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name);                    argsrc = JS_NewStringCopyZ(cx, buf);                }                if (!argsrc) {                    ok = JS_FALSE;                    goto done;                }                if (i > 0)                    APPEND_CHAR_TO_STACK(',');                APPEND_STRING_TO_STACK(argsrc);            }            APPEND_CHAR_TO_STACK(')');        }        APPEND_CHAR_TO_STACK('@');        if (fp->script && fp->script->filename) {            for (cp = fp->script->filename; *cp; cp++)                APPEND_CHAR_TO_STACK(*cp);        }        APPEND_CHAR_TO_STACK(':');        if (fp->script && fp->pc) {            ulineno = js_PCToLineNumber(cx, fp->script, fp->pc);            JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno);            for (cp = ulnbuf; *cp; cp++)                APPEND_CHAR_TO_STACK(*cp);        } else {            APPEND_CHAR_TO_STACK('0');        }        APPEND_CHAR_TO_STACK('\n');    }#undef APPEND_CHAR_TO_STACK#undef APPEND_STRING_TO_STACKdone:    if (checkAccess) {        if (ok)            JS_RestoreExceptionState(cx, state);        else            JS_DropExceptionState(cx, state);        JS_SetErrorReporter(cx, older);    }    if (!ok) {        JS_free(cx, stackbuf);        return JS_FALSE;    }    if (!stackbuf) {        stack = cx->runtime->emptyString;    } else {        /* NB: if stackbuf was allocated, it has room for the terminator. */        JS_ASSERT(stacklen <= stackmax);        if (stacklen < stackmax) {            /*             * Realloc can fail when shrinking on some FreeBSD versions, so             * don't use JS_realloc here; simply let the oversized allocation             * be owned by the string in that rare case.             */            void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar));            if (shrunk)                stackbuf = shrunk;        }        stackbuf[stacklen] = 0;        stack = js_NewString(cx, stackbuf, stacklen, 0);        if (!stack) {            JS_free(cx, stackbuf);            return JS_FALSE;        }    }    return JS_DefineProperty(cx, obj, js_stack_str,                             STRING_TO_JSVAL(stack),                             NULL, NULL, JSPROP_ENUMERATE);}static JSBoolException(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSBool ok;    jsval pval;    int32 lineno;    JSString *message, *filename;    if (cx->creatingException)        return JS_FALSE;    cx->creatingException = JS_TRUE;    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {        /*         * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when         * called as functions, without operator new.  But as we do not give         * each constructor a distinct JSClass, whose .name member is used by         * js_NewObject to find the class prototype, we must get the class         * prototype ourselves.         */        ok = OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]),                              (jsid)cx->runtime->atomState.classPrototypeAtom,                              &pval);        if (!ok)            goto out;        obj = js_NewObject(cx, &ExceptionClass, JSVAL_TO_OBJECT(pval), NULL);        if (!obj) {            ok = JS_FALSE;            goto out;        }        *rval = OBJECT_TO_JSVAL(obj);    }    /*     * If it's a new object of class Exception, then null out the private     * data so that the finalizer doesn't attempt to free it.     */    if (OBJ_GET_CLASS(cx, obj) == &ExceptionClass)        OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, JSVAL_VOID);    /* Set the 'message' property. */    if (argc != 0) {        message = js_ValueToString(cx, argv[0]);        if (!message) {            ok = JS_FALSE;            goto out;        }        argv[0] = STRING_TO_JSVAL(message);    } else {        message = cx->runtime->emptyString;    }    /* Set the 'fileName' property. */    if (argc > 1) {        filename = js_ValueToString(cx, argv[1]);        if (!filename) {            ok = JS_FALSE;            goto out;        }        argv[1] = STRING_TO_JSVAL(filename);    } else {        filename = cx->runtime->emptyString;    }    /* Set the 'lineNumber' property. */    if (argc > 2) {        ok = js_ValueToInt32(cx, argv[2], &lineno);        if (!ok)            goto out;    } else {        lineno = 0;    }    ok = InitExceptionObject(cx, obj, message, filename, lineno);out:    cx->creatingException = JS_FALSE;    return ok;}/* * Convert to string. * * This method only uses JavaScript-modifiable properties name, message.  It * is left to the host to check for private data and report filename and line * number information along with this message. */static JSBoolexn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsval v;    JSString *name, *message, *result;    jschar *chars, *cp;    size_t name_length, message_length, length;    if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))        return JS_FALSE;    name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;    if (!JS_GetProperty(cx, obj, js_message_str, &v))        return JS_FALSE;    message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)                                 : cx->runtime->emptyString;    if (JSSTRING_LENGTH(message) != 0) {        name_length = JSSTRING_LENGTH(name);        message_length = JSSTRING_LENGTH(message);        length = (name_length ? name_length + 2 : 0) + message_length;        cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));        if (!chars)            return JS_FALSE;        if (name_length) {            js_strncpy(cp, JSSTRING_CHARS(name), name_length);            cp += name_length;            *cp++ = ':'; *cp++ = ' ';        }        js_strncpy(cp, JSSTRING_CHARS(message), message_length);        cp += message_length;        *cp = 0;        result = js_NewString(cx, chars, length, 0);        if (!result) {            JS_free(cx, chars);            return JS_FALSE;        }    } else {        result = name;    }    *rval = STRING_TO_JSVAL(result);    return JS_TRUE;}#if JS_HAS_TOSOURCE/* * Return a string that may eval to something similar to the original object. */static JSBoolexn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsval v;    JSString *name, *message, *filename, *lineno_as_str, *result;    int32 lineno;    size_t lineno_length, name_length, message_length, filename_length, length;    jschar *chars, *cp;    if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))        return JS_FALSE;    name = js_ValueToString(cx, v);    if (!name)        return JS_FALSE;    if (!JS_GetProperty(cx, obj, js_message_str, &v) ||        !(message = js_ValueToSource(cx, v))) {        return JS_FALSE;    }    if (!JS_GetProperty(cx, obj, js_filename_str, &v) ||        !(filename = js_ValueToSource(cx, v))) {        return JS_FALSE;    }    if (!JS_GetProperty(cx, obj, js_lineno_str, &v) ||        !js_ValueToInt32 (cx, v, &lineno)) {        return JS_FALSE;    }    if (lineno != 0) {        if (!(lineno_as_str = js_ValueToString(cx, v))) {            return JS_FALSE;        }        lineno_length = JSSTRING_LENGTH(lineno_as_str);    } else {        lineno_as_str = NULL;        lineno_length = 0;    }    /* Magic 8, for the characters in ``(new ())''. */    name_length = JSSTRING_LENGTH(name);    message_length = JSSTRING_LENGTH(message);    length = 8 + name_length + message_length;    filename_length = JSSTRING_LENGTH(filename);    if (filename_length != 0) {        /* append filename as ``, {filename}'' */        length += 2 + filename_length;        if (lineno_as_str) {            /* append lineno as ``, {lineno_as_str}'' */            length += 2 + lineno_length;        }    } else {        if (lineno_as_str) {            /*

⌨️ 快捷键说明

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