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 + -
显示快捷键?