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

📄 jsexn.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sw=4 et tw=78: * * ***** 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 "jsdbgapi.h"#include "jsexn.h"#include "jsfun.h"#include "jsinterp.h"#include "jsnum.h"#include "jsopcode.h"#include "jsscript.h"/* Forward declarations for js_ErrorClass's initializer. */static JSBoolException(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static voidexn_finalize(JSContext *cx, JSObject *obj);static uint32exn_mark(JSContext *cx, JSObject *obj, void *arg);static voidexn_finalize(JSContext *cx, JSObject *obj);static JSBoolexn_enumerate(JSContext *cx, JSObject *obj);static JSBoolexn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,            JSObject **objp);JSClass js_ErrorClass = {    js_Error_str,    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |    JSCLASS_HAS_CACHED_PROTO(JSProto_Error),    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,    exn_enumerate,    (JSResolveOp)exn_resolve, JS_ConvertStub, exn_finalize,    NULL,             NULL,             NULL,             Exception,    NULL,             NULL,             exn_mark,         NULL};typedef struct JSStackTraceElem {    JSString            *funName;    size_t              argc;    const char          *filename;    uintN               ulineno;} JSStackTraceElem;typedef struct JSExnPrivate {    /* A copy of the JSErrorReport originally generated. */    JSErrorReport       *errorReport;    JSString            *message;    JSString            *filename;    uintN               lineno;    size_t              stackDepth;    JSStackTraceElem    stackElems[1];} JSExnPrivate;static JSString *StackTraceToString(JSContext *cx, JSExnPrivate *priv);static JSErrorReport *CopyErrorReport(JSContext *cx, JSErrorReport *report){    /*     * We use a single malloc block to make a deep copy of JSErrorReport with     * the following layout:     *   JSErrorReport     *   array of copies of report->messageArgs     *   jschar array with characters for all messageArgs     *   jschar array with characters for ucmessage     *   jschar array with characters for uclinebuf and uctokenptr     *   char array with characters for linebuf and tokenptr     *   char array with characters for filename     * Such layout together with the properties enforced by the following     * asserts does not need any extra alignment padding.     *///    JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char *) == 0);//    JS_STATIC_ASSERT(sizeof(const char *) % sizeof(jschar) == 0);    size_t filenameSize;    size_t linebufSize;    size_t uclinebufSize;    size_t ucmessageSize;    size_t i, argsArraySize, argsCopySize, argSize;    size_t mallocSize;    JSErrorReport *copy;    uint8 *cursor;#define JS_CHARS_SIZE(jschars) ((js_strlen(jschars) + 1) * sizeof(jschar))    filenameSize = report->filename ? strlen(report->filename) + 1 : 0;    linebufSize = report->linebuf ? strlen(report->linebuf) + 1 : 0;    uclinebufSize = report->uclinebuf ? JS_CHARS_SIZE(report->uclinebuf) : 0;    ucmessageSize = 0;    argsArraySize = 0;    argsCopySize = 0;    if (report->ucmessage) {        ucmessageSize = JS_CHARS_SIZE(report->ucmessage);        if (report->messageArgs) {            for (i = 0; report->messageArgs[i]; ++i)                argsCopySize += JS_CHARS_SIZE(report->messageArgs[i]);            /* Non-null messageArgs should have at least one non-null arg. */            JS_ASSERT(i != 0);            argsArraySize = (i + 1) * sizeof(const jschar *);        }    }    /*     * The mallocSize can not overflow since it represents the sum of the     * sizes of already allocated objects.     */    mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +                 ucmessageSize + uclinebufSize + linebufSize + filenameSize;    cursor = (uint8 *)JS_malloc(cx, mallocSize);    if (!cursor)        return NULL;    copy = (JSErrorReport *)cursor;    memset(cursor, 0, sizeof(JSErrorReport));    cursor += sizeof(JSErrorReport);    if (argsArraySize != 0) {        copy->messageArgs = (const jschar **)cursor;        cursor += argsArraySize;        for (i = 0; report->messageArgs[i]; ++i) {            copy->messageArgs[i] = (const jschar *)cursor;            argSize = JS_CHARS_SIZE(report->messageArgs[i]);            memcpy(cursor, report->messageArgs[i], argSize);            cursor += argSize;        }        copy->messageArgs[i] = NULL;        JS_ASSERT(cursor == (uint8 *)copy->messageArgs[0] + argsCopySize);    }    if (report->ucmessage) {        copy->ucmessage = (const jschar *)cursor;        memcpy(cursor, report->ucmessage, ucmessageSize);        cursor += ucmessageSize;    }    if (report->uclinebuf) {        copy->uclinebuf = (const jschar *)cursor;        memcpy(cursor, report->uclinebuf, uclinebufSize);        cursor += uclinebufSize;        if (report->uctokenptr) {            copy->uctokenptr = copy->uclinebuf + (report->uctokenptr -                                                  report->uclinebuf);        }    }    if (report->linebuf) {        copy->linebuf = (const char *)cursor;        memcpy(cursor, report->linebuf, linebufSize);        cursor += linebufSize;        if (report->tokenptr) {            copy->tokenptr = copy->linebuf + (report->tokenptr -                                              report->linebuf);        }    }    if (report->filename) {        copy->filename = (const char *)cursor;        memcpy(cursor, report->filename, filenameSize);    }    JS_ASSERT(cursor + filenameSize == (uint8 *)copy + mallocSize);    /* Copy non-pointer members. */    copy->lineno = report->lineno;    copy->errorNumber = report->errorNumber;    /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */    copy->flags = report->flags;#undef JS_CHARS_SIZE    return copy;}static jsval *GetStackTraceValueBuffer(JSExnPrivate *priv){    /*     * We use extra memory after JSExnPrivateInfo.stackElems to store jsvals     * that helps to produce more informative stack traces. The following     * assert allows us to assume that no gap after stackElems is necessary to     * align the buffer properly.     *///    JS_STATIC_ASSERT(sizeof(JSStackTraceElem) % sizeof(jsval) == 0);    return (jsval *)(priv->stackElems + priv->stackDepth);}static JSBoolInitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,               JSString *filename, uintN lineno, JSErrorReport *report){    JSCheckAccessOp checkAccess;    JSErrorReporter older;    JSExceptionState *state;    jsval callerid, v;    JSStackFrame *fp, *fpstop;    size_t stackDepth, valueCount, size;    JSBool overflow;    JSExnPrivate *priv;    JSStackTraceElem *elem;    jsval *values;    JS_ASSERT(OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass);    /*     * Prepare stack trace data.     *     * Set aside any error reporter for cx and save its exception state     * so we can suppress any checkAccess failures.  Such failures should stop     * the backtrace procedure, not result in a failure of this constructor.     */    checkAccess = cx->runtime->checkObjectAccess;    older = JS_SetErrorReporter(cx, NULL);    state = JS_SaveExceptionState(cx);    callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);    stackDepth = 0;    valueCount = 0;    for (fp = cx->fp; fp; fp = fp->down) {        if (fp->fun && fp->argv) {            if (checkAccess) {                v = fp->argv[-2];                if (!JSVAL_IS_PRIMITIVE(v) &&                    !checkAccess(cx, JSVAL_TO_OBJECT(v), callerid,                                 JSACC_READ, &v /* ignored */)) {                    break;                }            }            valueCount += fp->argc;        }        ++stackDepth;    }    JS_RestoreExceptionState(cx, state);    JS_SetErrorReporter(cx, older);    fpstop = fp;    size = offsetof(JSExnPrivate, stackElems);    overflow = (stackDepth > ((size_t)-1 - size) / sizeof(JSStackTraceElem));    size += stackDepth * sizeof(JSStackTraceElem);    overflow |= (valueCount > ((size_t)-1 - size) / sizeof(jsval));    size += valueCount * sizeof(jsval);    if (overflow) {        JS_ReportOutOfMemory(cx);        return JS_FALSE;    }    priv = (JSExnPrivate *)JS_malloc(cx, size);    if (!priv)        return JS_FALSE;    /*     * We initialize errorReport with a copy of report after setting the     * private slot, to prevent GC accessing a junk value we clear the field     * here.     */    priv->errorReport = NULL;    priv->message = message;    priv->filename = filename;    priv->lineno = lineno;    priv->stackDepth = stackDepth;    values = GetStackTraceValueBuffer(priv);    elem = priv->stackElems;    for (fp = cx->fp; fp != fpstop; fp = fp->down) {        if (!fp->fun) {            elem->funName = NULL;            elem->argc = 0;        } else {            elem->funName = fp->fun->atom                            ? ATOM_TO_STRING(fp->fun->atom)                            : cx->runtime->emptyString;            elem->argc = fp->argc;            memcpy(values, fp->argv, fp->argc * sizeof(jsval));            values += fp->argc;        }        elem->ulineno = 0;        elem->filename = NULL;        if (fp->script) {            elem->filename = fp->script->filename;            if (fp->pc)                elem->ulineno = js_PCToLineNumber(cx, fp->script, fp->pc);        }        ++elem;    }    JS_ASSERT(priv->stackElems + stackDepth == elem);    JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values);    OBJ_SET_SLOT(cx, exnObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(priv));    if (report) {        /*         * Construct a new copy of the error report struct. We can't use the         * error report struct that was passed in, because it's allocated on         * the stack, and also because it may point to transient data in the         * JSTokenStream.         */        priv->errorReport = CopyErrorReport(cx, report);        if (!priv->errorReport) {            /* The finalizer realeases priv since it is in the private slot. */            return JS_FALSE;        }    }    return JS_TRUE;}static JSExnPrivate *GetExnPrivate(JSContext *cx, JSObject *obj){    jsval privateValue;    JSExnPrivate *priv;    JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ErrorClass);    privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);    if (JSVAL_IS_VOID(privateValue))        return NULL;    priv = (JSExnPrivate *)JSVAL_TO_PRIVATE(privateValue);    JS_ASSERT(priv);    return priv;}static uint32exn_mark(JSContext *cx, JSObject *obj, void *arg){    JSExnPrivate *priv;    JSStackTraceElem *elem;    size_t vcount, i;    jsval *vp, v;    priv = GetExnPrivate(cx, obj);    if (priv) {        GC_MARK(cx, priv->message, "exception message");        GC_MARK(cx, priv->filename, "exception filename");        elem = priv->stackElems;        for (vcount = i = 0; i != priv->stackDepth; ++i, ++elem) {            if (elem->funName)                GC_MARK(cx, elem->funName, "stack trace function name");            if (elem->filename)                js_MarkScriptFilename(elem->filename);            vcount += elem->argc;        }        vp = GetStackTraceValueBuffer(priv);        for (i = 0; i != vcount; ++i, ++vp) {            v = *vp;            if (JSVAL_IS_GCTHING(v))                GC_MARK(cx, JSVAL_TO_GCTHING(v), "stack trace argument");        }    }    return 0;}static voidexn_finalize(JSContext *cx, JSObject *obj){    JSExnPrivate *priv;    priv = GetExnPrivate(cx, obj);    if (priv) {        if (priv->errorReport)            JS_free(cx, priv->errorReport);        JS_free(cx, priv);    }}static JSBoolexn_enumerate(JSContext *cx, JSObject *obj){    JSAtomState *atomState;    uintN i;    JSAtom *atom;    JSObject *pobj;    JSProperty *prop;    //    JS_STATIC_ASSERT(sizeof(JSAtomState) <= (size_t)(uint16)-1);    static const uint16 offsets[] = {        (uint16)offsetof(JSAtomState, messageAtom),        (uint16)offsetof(JSAtomState, fileNameAtom),        (uint16)offsetof(JSAtomState, lineNumberAtom),        (uint16)offsetof(JSAtomState, stackAtom),    };    atomState = &cx->runtime->atomState;    for (i = 0; i != JS_ARRAY_LENGTH(offsets); ++i) {        atom = *(JSAtom **)((uint8 *)atomState + offsets[i]);         if (!js_LookupProperty(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop))            return JS_FALSE;        if (prop)            OBJ_DROP_PROPERTY(cx, pobj, prop);    }    return JS_TRUE;}static JSBoolexn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,

⌨️ 快捷键说明

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