jscntxt.c

来自「java script test programing source code」· C语言 代码 · 共 1,230 行 · 第 1/3 页

C
1,230
字号
{    /*     * Check the error report, and set a JavaScript-catchable exception     * if the error is defined to have an associated exception.  If an     * exception is thrown, then the JSREPORT_EXCEPTION flag will be set     * on the error report, and exception-aware hosts should ignore it.     */    JS_ASSERT(reportp);    if (reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)        reportp->flags |= JSREPORT_EXCEPTION;    /*     * Call the error reporter only if an exception wasn't raised.     *     * If an exception was raised, then we call the debugErrorHook     * (if present) to give it a chance to see the error before it     * propagates out of scope.  This is needed for compatability     * with the old scheme.     */    if (!js_ErrorToException(cx, message, reportp)) {        js_ReportErrorAgain(cx, message, reportp);    } else if (cx->runtime->debugErrorHook && cx->errorReporter) {        JSDebugErrorHook hook = cx->runtime->debugErrorHook;        /* test local in case debugErrorHook changed on another thread */        if (hook)            hook(cx, message, reportp, cx->runtime->debugErrorHookData);    }}/* * We don't post an exception in this case, since doing so runs into * complications of pre-allocating an exception object which required * running the Exception class initializer early etc. * Instead we just invoke the errorReporter with an "Out Of Memory" * type message, and then hope the process ends swiftly. */voidjs_ReportOutOfMemory(JSContext *cx){    JSStackFrame *fp;    JSErrorReport report;    JSErrorReporter onError = cx->errorReporter;    /* Get the message for this error, but we won't expand any arguments. */    const JSErrorFormatString *efs =        js_GetLocalizedErrorMessage(cx, NULL, NULL, JSMSG_OUT_OF_MEMORY);    const char *msg = efs ? efs->format : "Out of memory";    /* Fill out the report, but don't do anything that requires allocation. */    memset(&report, 0, sizeof (struct JSErrorReport));    report.flags = JSREPORT_ERROR;    report.errorNumber = JSMSG_OUT_OF_MEMORY;    /*     * Walk stack until we find a frame that is associated with some script     * rather than a native frame.     */    for (fp = cx->fp; fp; fp = fp->down) {        if (fp->script && fp->pc) {            report.filename = fp->script->filename;            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);            break;        }    }    /*     * If debugErrorHook is present then we give it a chance to veto     * sending the error on to the regular ErrorReporter.     */    if (onError) {        JSDebugErrorHook hook = cx->runtime->debugErrorHook;        if (hook &&            !hook(cx, msg, &report, cx->runtime->debugErrorHookData)) {            onError = NULL;        }    }    if (onError)        onError(cx, msg, &report);}JSBooljs_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap){    char *message;    jschar *ucmessage;    size_t messagelen;    JSStackFrame *fp;    JSErrorReport report;    JSBool warning;    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))        return JS_TRUE;    message = JS_vsmprintf(format, ap);    if (!message)        return JS_FALSE;    messagelen = strlen(message);    memset(&report, 0, sizeof (struct JSErrorReport));    report.flags = flags;    report.errorNumber = JSMSG_USER_DEFINED_ERROR;    report.ucmessage = ucmessage = js_InflateString(cx, message, &messagelen);    /* Find the top-most active script frame, for best line number blame. */    for (fp = cx->fp; fp; fp = fp->down) {        if (fp->script && fp->pc) {            report.filename = fp->script->filename;            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);            break;        }    }    warning = JSREPORT_IS_WARNING(report.flags);    if (warning && JS_HAS_WERROR_OPTION(cx)) {        report.flags &= ~JSREPORT_WARNING;        warning = JS_FALSE;    }    ReportError(cx, message, &report);    free(message);    JS_free(cx, ucmessage);    return warning;}/* * The arguments from ap need to be packaged up into an array and stored * into the report struct. * * The format string addressed by the error number may contain operands * identified by the format {N}, where N is a decimal digit. Each of these * is to be replaced by the Nth argument from the va_list. The complete * message is placed into reportp->ucmessage converted to a JSString. * * Returns true if the expansion succeeds (can fail if out of memory). */JSBooljs_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,                        void *userRef, const uintN errorNumber,                        char **messagep, JSErrorReport *reportp,                        JSBool *warningp, JSBool charArgs, va_list ap){    const JSErrorFormatString *efs;    int i;    int argCount;    *warningp = JSREPORT_IS_WARNING(reportp->flags);    if (*warningp && JS_HAS_WERROR_OPTION(cx)) {        reportp->flags &= ~JSREPORT_WARNING;        *warningp = JS_FALSE;    }    *messagep = NULL;    /* Most calls supply js_GetErrorMessage; if this is so, assume NULL. */    if (!callback || callback == js_GetErrorMessage)        efs = js_GetLocalizedErrorMessage(cx, userRef, NULL, errorNumber);    else        efs = callback(userRef, NULL, errorNumber);    if (efs) {        size_t totalArgsLength = 0;        size_t argLengths[10]; /* only {0} thru {9} supported */        argCount = efs->argCount;        JS_ASSERT(argCount <= 10);        if (argCount > 0) {            /*             * Gather the arguments into an array, and accumulate             * their sizes. We allocate 1 more than necessary and             * null it out to act as the caboose when we free the             * pointers later.             */            reportp->messageArgs = (const jschar **)                JS_malloc(cx, sizeof(jschar *) * (argCount + 1));            if (!reportp->messageArgs)                return JS_FALSE;            reportp->messageArgs[argCount] = NULL;            for (i = 0; i < argCount; i++) {                if (charArgs) {                    char *charArg = va_arg(ap, char *);                    size_t charArgLength = strlen(charArg);                    reportp->messageArgs[i]                        = js_InflateString(cx, charArg, &charArgLength);                    if (!reportp->messageArgs[i])                        goto error;                } else {                    reportp->messageArgs[i] = va_arg(ap, jschar *);                }                argLengths[i] = js_strlen(reportp->messageArgs[i]);                totalArgsLength += argLengths[i];            }            /* NULL-terminate for easy copying. */            reportp->messageArgs[i] = NULL;        }        /*         * Parse the error format, substituting the argument X         * for {X} in the format.         */        if (argCount > 0) {            if (efs->format) {                jschar *buffer, *fmt, *out;                int expandedArgs = 0;                size_t expandedLength;                size_t len = strlen(efs->format);                buffer = fmt = js_InflateString (cx, efs->format, &len);                if (!buffer)                    goto error;                expandedLength = len                                 - (3 * argCount)       /* exclude the {n} */                                 + totalArgsLength;                /*                * Note - the above calculation assumes that each argument                * is used once and only once in the expansion !!!                */                reportp->ucmessage = out = (jschar *)                    JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));                if (!out) {                    JS_free (cx, buffer);                    goto error;                }                while (*fmt) {                    if (*fmt == '{') {                        if (isdigit(fmt[1])) {                            int d = JS7_UNDEC(fmt[1]);                            JS_ASSERT(d < argCount);                            js_strncpy(out, reportp->messageArgs[d],                                       argLengths[d]);                            out += argLengths[d];                            fmt += 3;                            expandedArgs++;                            continue;                        }                    }                    *out++ = *fmt++;                }                JS_ASSERT(expandedArgs == argCount);                *out = 0;                JS_free (cx, buffer);                *messagep =                    js_DeflateString(cx, reportp->ucmessage,                                     (size_t)(out - reportp->ucmessage));                if (!*messagep)                    goto error;            }        } else {            /*             * Zero arguments: the format string (if it exists) is the             * entire message.             */            if (efs->format) {                size_t len;                *messagep = JS_strdup(cx, efs->format);                if (!*messagep)                    goto error;                len = strlen(*messagep);                reportp->ucmessage = js_InflateString(cx, *messagep, &len);                if (!reportp->ucmessage)                    goto error;            }        }    }    if (*messagep == NULL) {        /* where's the right place for this ??? */        const char *defaultErrorMessage            = "No error message available for error number %d";        size_t nbytes = strlen(defaultErrorMessage) + 16;        *messagep = (char *)JS_malloc(cx, nbytes);        if (!*messagep)            goto error;        JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);    }    return JS_TRUE;error:    if (reportp->messageArgs) {        /* free the arguments only if we allocated them */        if (charArgs) {            i = 0;            while (reportp->messageArgs[i])                JS_free(cx, (void *)reportp->messageArgs[i++]);        }        JS_free(cx, (void *)reportp->messageArgs);        reportp->messageArgs = NULL;    }    if (reportp->ucmessage) {        JS_free(cx, (void *)reportp->ucmessage);        reportp->ucmessage = NULL;    }    if (*messagep) {        JS_free(cx, (void *)*messagep);        *messagep = NULL;    }    return JS_FALSE;}JSBooljs_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,                       void *userRef, const uintN errorNumber,                       JSBool charArgs, va_list ap){    JSStackFrame *fp;    JSErrorReport report;    char *message;    JSBool warning;    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))        return JS_TRUE;    memset(&report, 0, sizeof (struct JSErrorReport));    report.flags = flags;    report.errorNumber = errorNumber;    /*     * If we can't find out where the error was based on the current frame,     * see if the next frame has a script/pc combo we can use.     */    for (fp = cx->fp; fp; fp = fp->down) {        if (fp->script && fp->pc) {            report.filename = fp->script->filename;            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);            break;        }    }    if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,                                 &message, &report, &warning, charArgs, ap)) {        return JS_FALSE;    }    ReportError(cx, message, &report);    if (message)        JS_free(cx, message);    if (report.messageArgs) {        /*         * js_ExpandErrorArguments owns its messageArgs only if it had to         * inflate the arguments (from regular |char *|s).         */        if (charArgs) {            int i = 0;            while (report.messageArgs[i])                JS_free(cx, (void *)report.messageArgs[i++]);        }        JS_free(cx, (void *)report.messageArgs);    }    if (report.ucmessage)        JS_free(cx, (void *)report.ucmessage);    return warning;}JS_FRIEND_API(void)js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp){    JSErrorReporter onError;    if (!message)        return;    if (cx->lastMessage)        free(cx->lastMessage);    cx->lastMessage = JS_strdup(cx, message);    if (!cx->lastMessage)        return;    onError = cx->errorReporter;    /*     * If debugErrorHook is present then we give it a chance to veto     * sending the error on to the regular ErrorReporter.     */    if (onError) {        JSDebugErrorHook hook = cx->runtime->debugErrorHook;        if (hook &&            !hook(cx, cx->lastMessage, reportp,                  cx->runtime->debugErrorHookData)) {            onError = NULL;        }    }    if (onError)        onError(cx, cx->lastMessage, reportp);}voidjs_ReportIsNotDefined(JSContext *cx, const char *name){    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_DEFINED, name);}#if defined DEBUG && defined XP_UNIX/* For gdb usage. */void js_traceon(JSContext *cx)  { cx->tracefp = stderr; }void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }#endifJSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {#define MSG_DEF(name, number, count, exception, format) \    { format, count, exception } ,#include "js.msg"#undef MSG_DEF};const JSErrorFormatString *js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber){    if ((errorNumber > 0) && (errorNumber < JSErr_Limit))        return &js_ErrorFormatString[errorNumber];    return NULL;}

⌨️ 快捷键说明

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