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

📄 jsexn.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JS standard exception implementation. */#include "jsstddef.h"#include <stdlib.h>#include <string.h>#include "jstypes.h"#include "jsbit.h"#include "jsutil.h" /* Added by JSIFY */#include "jsprf.h"#include "jsapi.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsexn.h"#include "jsfun.h"#include "jsinterp.h"#include "jsopcode.h"#include "jsnum.h"#include "jsscript.h"#if JS_HAS_ERROR_EXCEPTIONS#if !JS_HAS_EXCEPTIONS# error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS"#endif/* XXX consider adding rt->atomState.messageAtom */static char js_message_str[]  = "message";static char js_filename_str[] = "fileName";static char js_lineno_str[]   = "lineNumber";static char js_stack_str[]    = "stack";/* Forward declarations for ExceptionClass's initializer. */static JSBoolException(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static voidexn_finalize(JSContext *cx, JSObject *obj);static JSClass ExceptionClass = {    "Error",    JSCLASS_HAS_PRIVATE,    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   exn_finalize,    NULL,             NULL,             NULL,             Exception,    NULL,             NULL,             NULL,             0};/* * A copy of the JSErrorReport originally generated. */typedef struct JSExnPrivate {    JSErrorReport *errorReport;} JSExnPrivate;/* * Undo all the damage done by exn_newPrivate. */static voidexn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData){    JSErrorReport *report;    const jschar **args;    if (!privateData)        return;    report = privateData->errorReport;    if (report) {        if (report->uclinebuf)            JS_free(cx, (void *)report->uclinebuf);        if (report->filename)            JS_free(cx, (void *)report->filename);        if (report->ucmessage)            JS_free(cx, (void *)report->ucmessage);        if (report->messageArgs) {            args = report->messageArgs;            while (*args != NULL)                JS_free(cx, (void *)*args++);            JS_free(cx, (void *)report->messageArgs);        }        JS_free(cx, report);    }    JS_free(cx, privateData);}/* * Copy everything interesting about an error into allocated memory. */static JSExnPrivate *exn_newPrivate(JSContext *cx, JSErrorReport *report){    intN i;    JSExnPrivate *newPrivate;    JSErrorReport *newReport;    size_t capacity;    newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate));    if (!newPrivate)        return NULL;    memset(newPrivate, 0, sizeof (JSExnPrivate));    /* Copy the error report */    newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport));    if (!newReport)        goto error;    memset(newReport, 0, sizeof (JSErrorReport));    newPrivate->errorReport = newReport;    if (report->filename != NULL) {        newReport->filename = JS_strdup(cx, report->filename);        if (!newReport->filename)            goto error;    } else {        newReport->filename = NULL;    }    newReport->lineno = report->lineno;    /*     * We don't need to copy linebuf and tokenptr, because they     * point into the deflated string cache.  (currently?)     */    newReport->linebuf = report->linebuf;    newReport->tokenptr = report->tokenptr;    /*     * But we do need to copy uclinebuf, uctokenptr, because they're     * pointers into internal tokenstream structs, and may go away.     */    if (report->uclinebuf != NULL) {        capacity = js_strlen(report->uclinebuf) + 1;        newReport->uclinebuf =            (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));        if (!newReport->uclinebuf)            goto error;        js_strncpy((jschar *)newReport->uclinebuf, report->uclinebuf, capacity);        newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -                                                        report->uclinebuf);    } else {        newReport->uclinebuf = newReport->uctokenptr = NULL;    }    if (report->ucmessage != NULL) {        capacity = js_strlen(report->ucmessage) + 1;        newReport->ucmessage = (const jschar *)            JS_malloc(cx, capacity * sizeof(jschar));        if (!newReport->ucmessage)            goto error;        js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, capacity);        if (report->messageArgs) {            for (i = 0; report->messageArgs[i] != NULL; i++)                continue;            JS_ASSERT(i);            newReport->messageArgs =                (const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *));            if (!newReport->messageArgs)                goto error;            for (i = 0; report->messageArgs[i] != NULL; i++) {                capacity = js_strlen(report->messageArgs[i]) + 1;                newReport->messageArgs[i] =                    (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));                if (!newReport->messageArgs[i])                    goto error;                js_strncpy((jschar *)(newReport->messageArgs[i]),                           report->messageArgs[i], capacity);            }            newReport->messageArgs[i] = NULL;        } else {            newReport->messageArgs = NULL;        }    } else {        newReport->ucmessage = NULL;        newReport->messageArgs = NULL;    }    newReport->errorNumber = report->errorNumber;    /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */    newReport->flags = report->flags;    return newPrivate;error:    exn_destroyPrivate(cx, newPrivate);    return NULL;}static voidexn_finalize(JSContext *cx, JSObject *obj){    JSExnPrivate *privateData;    jsval privateValue;    privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);    if (!JSVAL_IS_VOID(privateValue)) {        privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);        if (privateData)            exn_destroyPrivate(cx, privateData);    }}JSErrorReport *js_ErrorFromException(JSContext *cx, jsval exn){    JSObject *obj;    JSExnPrivate *privateData;    jsval privateValue;    if (JSVAL_IS_PRIMITIVE(exn))        return NULL;    obj = JSVAL_TO_OBJECT(exn);    if (OBJ_GET_CLASS(cx, obj) != &ExceptionClass)        return NULL;    privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);    if (JSVAL_IS_VOID(privateValue))        return NULL;    privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);    if (!privateData)        return NULL;    JS_ASSERT(privateData->errorReport);    return privateData->errorReport;}/* * This must be kept in synch with the exceptions array below. * XXX use a jsexn.tbl file a la jsopcode.tbl */typedef enum JSExnType {    JSEXN_NONE = -1,      JSEXN_ERR,        JSEXN_INTERNALERR,        JSEXN_EVALERR,        JSEXN_RANGEERR,        JSEXN_REFERENCEERR,        JSEXN_SYNTAXERR,        JSEXN_TYPEERR,        JSEXN_URIERR,        JSEXN_LIMIT} JSExnType;struct JSExnSpec {    int protoIndex;    const char *name;    JSNative native;};/* * All *Error constructors share the same JSClass, ExceptionClass.  But each * constructor function for an *Error class must have a distinct native 'call' * function pointer, in order for instanceof to work properly across multiple * standard class sets.  See jsfun.c:fun_hasInstance. */#define MAKE_EXCEPTION_CTOR(name)                                             \const char js_##name##_str[] = #name;                                         \static JSBool                                                                 \name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)      \{                                                                             \    return Exception(cx, obj, argc, argv, rval);                              \}MAKE_EXCEPTION_CTOR(Error)MAKE_EXCEPTION_CTOR(InternalError)MAKE_EXCEPTION_CTOR(EvalError)MAKE_EXCEPTION_CTOR(RangeError)MAKE_EXCEPTION_CTOR(ReferenceError)MAKE_EXCEPTION_CTOR(SyntaxError)MAKE_EXCEPTION_CTOR(TypeError)MAKE_EXCEPTION_CTOR(URIError)#undef MAKE_EXCEPTION_CTORstatic struct JSExnSpec exceptions[] = {    { JSEXN_NONE,       js_Error_str,           Error },    { JSEXN_ERR,        js_InternalError_str,   InternalError },    { JSEXN_ERR,        js_EvalError_str,       EvalError },    { JSEXN_ERR,        js_RangeError_str,      RangeError },    { JSEXN_ERR,        js_ReferenceError_str,  ReferenceError },    { JSEXN_ERR,        js_SyntaxError_str,     SyntaxError },    { JSEXN_ERR,        js_TypeError_str,       TypeError },    { JSEXN_ERR,        js_URIError_str,        URIError },    {0,NULL,NULL}};static JSBoolInitExceptionObject(JSContext *cx, JSObject *obj, JSString *message,                    JSString *filename, uintN lineno){    JSCheckAccessOp checkAccess;    JSErrorReporter older;    JSExceptionState *state;    jschar *stackbuf;    size_t stacklen, stackmax;    JSStackFrame *fp;    jsval callerid, v;    JSBool ok;    JSString *argsrc, *stack;    uintN i, ulineno;    const char *cp;    char ulnbuf[11];    if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message),                           NULL, NULL, JSPROP_ENUMERATE)) {        return JS_FALSE;    }    if (!JS_DefineProperty(cx, obj, js_filename_str,                           STRING_TO_JSVAL(filename),                           NULL, NULL, JSPROP_ENUMERATE)) {        return JS_FALSE;    }    if (!JS_DefineProperty(cx, obj, js_lineno_str,                           INT_TO_JSVAL(lineno),                           NULL, NULL, JSPROP_ENUMERATE)) {        return JS_FALSE;    }    /*     * Set the 'stack' property.     *     * First, set aside any error reporter for cx and save its exception state     * so we can suppress any checkAccess failures.  Such failures should stop

⌨️ 快捷键说明

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