📄 jscntxt.c
字号:
js_ReportOutOfMemory(JSContext *cx, JSErrorCallback callback){ JSStackFrame *fp; JSErrorReport report; JSErrorReporter onError = cx->errorReporter; /* Get the message for this error, but we won't expand any arguments. */ const JSErrorFormatString *efs = callback(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 *last; JSStackFrame *fp; JSErrorReport report; JSBool warning; if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) return JS_TRUE; last = JS_vsmprintf(format, ap); if (!last) return JS_FALSE; memset(&report, 0, sizeof (struct JSErrorReport)); report.flags = flags; /* 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, last, &report); free(last); 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; if (callback) { 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 *); reportp->messageArgs[i] = js_InflateString(cx, charArg, strlen(charArg)); 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) { const char *fmt; const jschar *arg; jschar *out; int expandedArgs = 0; size_t expandedLength = strlen(efs->format) - (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) goto error; fmt = efs->format; while (*fmt) { if (*fmt == '{') { if (isdigit(fmt[1])) { int d = JS7_UNDEC(fmt[1]); JS_ASSERT(expandedArgs < argCount); arg = reportp->messageArgs[d]; js_strncpy(out, arg, argLengths[d]); out += argLengths[d]; fmt += 3; expandedArgs++; continue; } } /* * is this kosher? */ *out++ = (unsigned char)(*fmt++); } JS_ASSERT(expandedArgs == argCount); *out = 0; *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) { *messagep = JS_strdup(cx, efs->format); if (!*messagep) goto error; reportp->ucmessage = js_InflateString(cx, *messagep, strlen(*messagep)); 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) { 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) { 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] = {#if JS_HAS_DFLT_MSG_STRINGS#define MSG_DEF(name, number, count, exception, format) \ { format, count } ,#else#define MSG_DEF(name, number, count, exception, format) \ { NULL, count } ,#endif#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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -