コード例 #1
0
ファイル: jsd_stak.c プロジェクト: lofter2011/Icefox
JSString*
jsd_ValToStringInStackFrame(JSDContext* jsdc, 
                            JSDThreadState* jsdthreadstate,
                            JSDStackFrameInfo* jsdframe,
                            jsval val)
{
    JSBool valid;
    JSString* retval;
    JSExceptionState* exceptionState;
    JSContext* cx;

    JSD_LOCK_THREADSTATES(jsdc);
    valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
    JSD_UNLOCK_THREADSTATES(jsdc);

    if( ! valid )
        return NULL;

    cx = jsdthreadstate->context;
    JS_ASSERT(cx);

    exceptionState = JS_SaveExceptionState(cx);
    retval = JS_ValueToString(cx, val);
    JS_RestoreExceptionState(cx, exceptionState);

    return retval;
}
コード例 #2
0
ファイル: jsd_val.c プロジェクト: MozillaOnline/gecko-dev
JSString*
jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSExceptionState* exceptionState;

    if(!jsdval->string)
    {
        /* if the jsval is a string, then we don't need to double root it */
        if(JSVAL_IS_STRING(jsdval->val))
            jsdval->string = JSVAL_TO_STRING(jsdval->val);
        else
        {
            JS_BeginRequest(cx);
            exceptionState = JS_SaveExceptionState(cx);
            jsdval->string = JS_ValueToString(cx, jsdval->val);
            JS_RestoreExceptionState(cx, exceptionState);
            if(jsdval->string)
            {
                if(!JS_AddNamedRoot(cx, &jsdval->string, "ValueString"))
                    jsdval->string = NULL;
            }
            JS_EndRequest(cx);
        }
    }
    return jsdval->string;
}
コード例 #3
0
ファイル: jsd_val.c プロジェクト: moussa1/mozilla-central
JSBool
jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSFunction* fun;
    JSExceptionState* exceptionState;
    JSCrossCompartmentCall *call = NULL;

    if(jsd_IsValueFunction(jsdc, jsdval))
    {
        JSBool ok = JS_FALSE;
        JS_BeginRequest(cx);
        call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, JSVAL_TO_OBJECT(jsdval->val));
        if(!call) {
            JS_EndRequest(cx);

            return JS_FALSE;
        }

        exceptionState = JS_SaveExceptionState(cx);
        fun = JSD_GetValueFunction(jsdc, jsdval);
        JS_RestoreExceptionState(cx, exceptionState);
        if(fun)
            ok = JS_GetFunctionScript(cx, fun) ? JS_FALSE : JS_TRUE;
        JS_LeaveCrossCompartmentCall(call);
        JS_EndRequest(cx);
        JS_ASSERT(fun);
        return ok;
    }
    return !JSVAL_IS_PRIMITIVE(jsdval->val);
}
コード例 #4
0
ファイル: jsd_val.c プロジェクト: moussa1/mozilla-central
JSString*
jsd_GetValueFunctionId(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSFunction* fun;
    JSExceptionState* exceptionState;
    JSCrossCompartmentCall *call = NULL;

    if(!jsdval->funName && jsd_IsValueFunction(jsdc, jsdval))
    {
        JS_BeginRequest(cx);

        call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, JSVAL_TO_OBJECT(jsdval->val));
        if(!call) {
            JS_EndRequest(cx);

            return NULL;
        }

        exceptionState = JS_SaveExceptionState(cx);
        fun = JSD_GetValueFunction(jsdc, jsdval);
        JS_RestoreExceptionState(cx, exceptionState);
        JS_LeaveCrossCompartmentCall(call);
        JS_EndRequest(cx);
        if(!fun)
            return NULL;
        jsdval->funName = JS_GetFunctionId(fun);

        /* For compatibility we return "anonymous", not an empty string here. */
        if (!jsdval->funName)
            jsdval->funName = JS_GetAnonymousString(jsdc->jsrt);
    }
    return jsdval->funName;
}
コード例 #5
0
ファイル: jsd_val.cpp プロジェクト: mvarie/Spidermonkey
JSDScript*
jsd_GetScriptForValue(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JS::RootedValue val(cx, jsdval->val);
    JSFunction* fun = NULL;
    JSExceptionState* exceptionState;
    JS::RootedScript script(cx);
    JSDScript* jsdscript;
    JSCompartment* oldCompartment = NULL;

    if (!jsd_IsValueFunction(jsdc, jsdval))
        return NULL;

    JS_BeginRequest(cx);
    oldCompartment = JS_EnterCompartment(cx, JSVAL_TO_OBJECT(val));
    exceptionState = JS_SaveExceptionState(cx);
    fun = JSD_GetValueFunction(jsdc, jsdval);
    JS_RestoreExceptionState(cx, exceptionState);
    if (fun)
        script = JS_GetFunctionScript(cx, fun);
    JS_LeaveCompartment(cx, oldCompartment);
    JS_EndRequest(cx);

    if (!script)
        return NULL;

    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = jsd_FindJSDScript(jsdc, script);
    JSD_UNLOCK_SCRIPTS(jsdc);
    return jsdscript;
}
コード例 #6
0
ファイル: jsd_val.cpp プロジェクト: mvarie/Spidermonkey
JSBool
jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JS::RootedFunction fun(cx);
    JSExceptionState* exceptionState;
    JSCompartment* oldCompartment = NULL;

    if(jsd_IsValueFunction(jsdc, jsdval))
    {
        JSBool ok = JS_FALSE;
        JS_BeginRequest(cx);
        oldCompartment = JS_EnterCompartment(cx, JSVAL_TO_OBJECT(jsdval->val));
        exceptionState = JS_SaveExceptionState(cx);
        fun = JSD_GetValueFunction(jsdc, jsdval);
        JS_RestoreExceptionState(cx, exceptionState);
        if(fun)
            ok = JS_GetFunctionScript(cx, fun) ? JS_FALSE : JS_TRUE;
        JS_LeaveCompartment(cx, oldCompartment);
        JS_EndRequest(cx);
        JS_ASSERT(fun);
        return ok;
    }
    return !JSVAL_IS_PRIMITIVE(jsdval->val);
}
コード例 #7
0
ファイル: jsd_val.c プロジェクト: MozillaOnline/gecko-dev
JSDScript*
jsd_GetScriptForValue(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    jsval val = jsdval->val;
    JSFunction* fun;
    JSExceptionState* exceptionState;
    JSScript* script = NULL;
    JSDScript* jsdscript;

    if (!jsd_IsValueFunction(jsdc, jsdval))
        return NULL;

    JS_BeginRequest(cx);
    exceptionState = JS_SaveExceptionState(cx);
    fun = JS_ValueToFunction(cx, val);
    JS_RestoreExceptionState(cx, exceptionState);
    if (fun)
        script = JS_GetFunctionScript(cx, fun);
    JS_EndRequest(cx);

    if (!script)
        return NULL;

    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = jsd_FindJSDScript(jsdc, script);
    JSD_UNLOCK_SCRIPTS(jsdc);
    return jsdscript;
}
コード例 #8
0
ファイル: jsd_val.c プロジェクト: moussa1/mozilla-central
JSString*
jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSExceptionState* exceptionState;
    JSCrossCompartmentCall *call = NULL;
    jsval stringval;
    JSString *string;
    JSBool needWrap;
    JSObject *scopeObj;

    if(jsdval->string)
        return jsdval->string;

    /* Reuse the string without copying or re-rooting it */
    if(JSVAL_IS_STRING(jsdval->val)) {
        jsdval->string = JSVAL_TO_STRING(jsdval->val);
        return jsdval->string;
    }

    JS_BeginRequest(cx);

    /* Objects call JS_ValueToString in their own compartment. */
    scopeObj = JSVAL_IS_OBJECT(jsdval->val) ? JSVAL_TO_OBJECT(jsdval->val) : jsdc->glob;
    call = JS_EnterCrossCompartmentCall(cx, scopeObj);
    if(!call) {
        JS_EndRequest(cx);
        return NULL;
    }
    exceptionState = JS_SaveExceptionState(cx);

    string = JS_ValueToString(cx, jsdval->val);

    JS_RestoreExceptionState(cx, exceptionState);
    JS_LeaveCrossCompartmentCall(call);
    call = NULL;

    if(string) {
        stringval = STRING_TO_JSVAL(string);
        call = JS_EnterCrossCompartmentCall(cx, jsdc->glob);
    }
    if(!string || !call || !JS_WrapValue(cx, &stringval)) {
        if(call)
            JS_LeaveCrossCompartmentCall(call);
        JS_EndRequest(cx);
        return NULL;
    }

    jsdval->string = JSVAL_TO_STRING(stringval);
    if(!JS_AddNamedStringRoot(cx, &jsdval->string, "ValueString"))
        jsdval->string = NULL;

    JS_LeaveCrossCompartmentCall(call);
    JS_EndRequest(cx);

    return jsdval->string;
}
コード例 #9
0
ファイル: context.c プロジェクト: RavetcoFX/cjs
static JSBool
gjs_print_parse_args(JSContext *context,
                     uintN      argc,
                     jsval     *argv,
                     char     **buffer)
{
    GString *str;
    gchar *s;
    guint n;

    JS_BeginRequest(context);

    str = g_string_new("");
    (void)JS_EnterLocalRootScope(context);
    for (n = 0; n < argc; ++n) {
        JSExceptionState *exc_state;
        JSString *jstr;

        /* JS_ValueToString might throw, in which we will only
         * log that the value could be converted to string */
        exc_state = JS_SaveExceptionState(context);

        jstr = JS_ValueToString(context, argv[n]);
        if (jstr != NULL)
            argv[n] = STRING_TO_JSVAL(jstr); // GC root

        JS_RestoreExceptionState(context, exc_state);

        if (jstr != NULL) {
            if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(jstr), &s)) {
                JS_LeaveLocalRootScope(context);
                JS_EndRequest(context);
                g_string_free(str, TRUE);
                return JS_FALSE;
            }

            g_string_append(str, s);
            g_free(s);
            if (n < (argc-1))
                g_string_append_c(str, ' ');
        } else {
            JS_LeaveLocalRootScope(context);
            JS_EndRequest(context);
            *buffer = g_string_free(str, TRUE);
            if (!*buffer)
                *buffer = g_strdup("<invalid string>");
            return JS_TRUE;
        }

    }
    JS_LeaveLocalRootScope(context);
    *buffer = g_string_free(str, FALSE);

    JS_EndRequest(context);
    return JS_TRUE;
}
コード例 #10
0
ファイル: jsd_val.cpp プロジェクト: mvarie/Spidermonkey
JSString*
jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSExceptionState* exceptionState;
    JSCompartment* oldCompartment = NULL;
    jsval stringval;
    JS::RootedString string(cx);
    JS::RootedObject scopeObj(cx);

    if(jsdval->string)
        return jsdval->string;

    /* Reuse the string without copying or re-rooting it */
    if(JSVAL_IS_STRING(jsdval->val)) {
        jsdval->string = JSVAL_TO_STRING(jsdval->val);
        return jsdval->string;
    }

    JS_BeginRequest(cx);

    /* Objects call JS_ValueToString in their own compartment. */
    scopeObj = !JSVAL_IS_PRIMITIVE(jsdval->val) ? JSVAL_TO_OBJECT(jsdval->val) : jsdc->glob;
    oldCompartment = JS_EnterCompartment(cx, scopeObj);
    exceptionState = JS_SaveExceptionState(cx);

    string = JS_ValueToString(cx, jsdval->val);

    JS_RestoreExceptionState(cx, exceptionState);
    JS_LeaveCompartment(cx, oldCompartment);
    oldCompartment = NULL;

    if(string) {
        stringval = STRING_TO_JSVAL(string);
        oldCompartment = JS_EnterCompartment(cx, jsdc->glob);
    }
    if(!string || !JS_WrapValue(cx, &stringval)) {
        if(oldCompartment)
            JS_LeaveCompartment(cx, oldCompartment);
        JS_EndRequest(cx);
        return NULL;
    }

    jsdval->string = JSVAL_TO_STRING(stringval);
    if(!JS_AddNamedStringRoot(cx, &jsdval->string, "ValueString"))
        jsdval->string = NULL;

    JS_LeaveCompartment(cx, oldCompartment);
    JS_EndRequest(cx);

    return jsdval->string;
}
コード例 #11
0
ファイル: context.c プロジェクト: RavetcoFX/cjs
static JSBool
gjs_log_error(JSContext *context,
              uintN      argc,
              jsval     *vp)
{
    jsval *argv = JS_ARGV(context, vp);
    char *s;
    JSExceptionState *exc_state;
    JSString *jstr;
    jsval exc;

    if (argc != 2) {
        gjs_throw(context, "Must pass an exception and message string to logError()");
        return JS_FALSE;
    }

    JS_BeginRequest(context);

    exc = argv[0];

    /* JS_ValueToString might throw, in which we will only
     *log that the value could be converted to string */
    exc_state = JS_SaveExceptionState(context);
    jstr = JS_ValueToString(context, argv[1]);
    if (jstr != NULL)
        argv[1] = STRING_TO_JSVAL(jstr);    // GC root
    JS_RestoreExceptionState(context, exc_state);

    if (jstr == NULL) {
        gjs_debug(GJS_DEBUG_ERROR, "<cannot convert value to string>");
        gjs_log_exception_props(context, exc);
        JS_EndRequest(context);
        return JS_TRUE;
    }

    if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(jstr), &s)) {
        JS_EndRequest(context);
        return JS_FALSE;
    }

    gjs_debug(GJS_DEBUG_ERROR, "%s", s);
    gjs_log_exception_props(context, exc);
    g_free(s);

    JS_EndRequest(context);
    JS_SET_RVAL(context, vp, JSVAL_VOID);
    return JS_TRUE;
}
コード例 #12
0
JSBool
xpc_DumpEvalInJSStackFrame(JSContext* cx, JSUint32 frameno, const char* text)
{
    JSStackFrame* fp;
    JSStackFrame* iter = nsnull;
    JSUint32 num = 0;

    if(!cx || !text)
    {
        puts("invalid params passed to xpc_DumpEvalInJSStackFrame!");
        return JS_FALSE;
    }

    printf("js[%d]> %s\n", frameno, text);

    while(nsnull != (fp = JS_FrameIterator(cx, &iter)))
    {
        if(num == frameno)
            break;
        num++;
    }

    if(!fp)
    {
        puts("invalid frame number!");
        return JS_FALSE;
    }

    JSAutoRequest ar(cx);

    JSExceptionState* exceptionState = JS_SaveExceptionState(cx);
    JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter);

    jsval rval;
    JSString* str;
    JSAutoByteString bytes;
    if(JS_EvaluateInStackFrame(cx, fp, text, strlen(text), "eval", 1, &rval) &&
       nsnull != (str = JS_ValueToString(cx, rval)) &&
       bytes.encode(cx, str))
    {
        printf("%s\n", bytes.ptr());
    }
    else
        puts("eval failed!");
    JS_SetErrorReporter(cx, older);
    JS_RestoreExceptionState(cx, exceptionState);
    return JS_TRUE;
}
コード例 #13
0
JSBool
xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text)
{
    if (!cx || !text) {
        DebugDump("%s", "invalid params passed to xpc_DumpEvalInJSStackFrame!\n");
        return false;
    }

    DebugDump("js[%d]> %s\n", frameno, text);

    uint32_t num = 0;

    JSAbstractFramePtr frame = JSNullFramePtr();

    JSBrokenFrameIterator iter(cx);
    while (!iter.done()) {
        if (num == frameno) {
            frame = iter.abstractFramePtr();
            break;
        }
        ++iter;
        num++;
    }

    if (!frame) {
        DebugDump("%s", "invalid frame number!\n");
        return false;
    }

    JSAutoRequest ar(cx);

    JSExceptionState* exceptionState = JS_SaveExceptionState(cx);
    JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter);

    jsval rval;
    JSString* str;
    JSAutoByteString bytes;
    if (frame.evaluateInStackFrame(cx, text, strlen(text), "eval", 1, &rval) &&
        nullptr != (str = JS_ValueToString(cx, rval)) &&
        bytes.encode(cx, str)) {
        DebugDump("%s\n", bytes.ptr());
    } else
        DebugDump("%s", "eval failed!\n");
    JS_SetErrorReporter(cx, older);
    JS_RestoreExceptionState(cx, exceptionState);
    return true;
}
コード例 #14
0
char*
xpc_PrintJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals,
                 JSBool showThisProps)
{
    char* buf;
    JSExceptionState *state = JS_SaveExceptionState(cx);
    if(!state)
        puts("Call to a debug function modifying state!");

    JS_ClearPendingException(cx);

    buf = FormatJSStackDump(cx, nsnull, showArgs, showLocals, showThisProps);
    if(!buf)
        puts("Failed to format JavaScript stack for dump");

    JS_RestoreExceptionState(cx, state);
    return buf;
}
コード例 #15
0
ファイル: jsd_val.c プロジェクト: MozillaOnline/gecko-dev
const char*
jsd_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSFunction* fun;
    JSExceptionState* exceptionState;

    if(!jsdval->funName && jsd_IsValueFunction(jsdc, jsdval))
    {
        JS_BeginRequest(cx);
        exceptionState = JS_SaveExceptionState(cx);
        fun = JS_ValueToFunction(cx, jsdval->val);
        JS_RestoreExceptionState(cx, exceptionState);
        JS_EndRequest(cx);
        if(!fun)
            return NULL;
        jsdval->funName = JS_GetFunctionName(fun);
    }
    return jsdval->funName;
}
コード例 #16
0
ファイル: xpcdebug.cpp プロジェクト: nioman/weaponry
JSBool
xpc_DumpJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals, JSBool showThisProps)
{
    char* buf;
    JSExceptionState *state = JS_SaveExceptionState(cx);
    if(!state)
        puts("Call to a debug function modifying state!");

    JS_ClearPendingException(cx);

    buf = FormatJSStackDump(cx, nsnull, showArgs, showLocals, showThisProps);
    if(buf)
    {
        fputs(buf, stdout);
        JS_smprintf_free(buf);
    }
    else
        puts("Failed to format JavaScript stack for dump");

    JS_RestoreExceptionState(cx, state);
    return JS_TRUE;
}
コード例 #17
0
ファイル: jsd_val.c プロジェクト: moussa1/mozilla-central
JSDScript*
jsd_GetScriptForValue(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    jsval val = jsdval->val;
    JSFunction* fun = NULL;
    JSExceptionState* exceptionState;
    JSScript* script = NULL;
    JSDScript* jsdscript;
    JSCrossCompartmentCall *call = NULL;

    if (!jsd_IsValueFunction(jsdc, jsdval))
        return NULL;

    JS_BeginRequest(cx);
    call = JS_EnterCrossCompartmentCall(cx, JSVAL_TO_OBJECT(val));
    if (!call) {
        JS_EndRequest(cx);

        return NULL;
    }

    exceptionState = JS_SaveExceptionState(cx);
    fun = JSD_GetValueFunction(jsdc, jsdval);
    JS_RestoreExceptionState(cx, exceptionState);
    if (fun)
        script = JS_GetFunctionScript(cx, fun);
    JS_LeaveCrossCompartmentCall(call);
    JS_EndRequest(cx);

    if (!script)
        return NULL;

    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = jsd_FindJSDScript(jsdc, script);
    JSD_UNLOCK_SCRIPTS(jsdc);
    return jsdscript;
}
コード例 #18
0
ファイル: jsd_val.c プロジェクト: MozillaOnline/gecko-dev
JSBool
jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    jsval val = jsdval->val;
    JSFunction* fun;
    JSExceptionState* exceptionState;

    if(jsd_IsValueFunction(jsdc, jsdval))
    {
        JSBool ok = JS_FALSE;
        JS_BeginRequest(cx);
        exceptionState = JS_SaveExceptionState(cx);
        fun = JS_ValueToFunction(cx, val);
        JS_RestoreExceptionState(cx, exceptionState);
        if(fun)
            ok = JS_GetFunctionScript(cx, fun) ? JS_FALSE : JS_TRUE;
        JS_EndRequest(cx);
        JS_ASSERT(fun);
        return ok;
    }
    return !JSVAL_IS_PRIMITIVE(val);
}
コード例 #19
0
ファイル: jsapi-util.c プロジェクト: sjokkis/gjs
/* Checks whether an object has a property; unlike JS_GetProperty(),
 * never sets an exception. Treats a property with a value of JSVAL_VOID
 * the same as an absent property and returns false in both cases.
 * Always initializes *value_p, if only to JSVAL_VOID, even if it
 * returns FALSE.
 */
gboolean
gjs_object_get_property(JSContext  *context,
                        JSObject   *obj,
                        const char *property_name,
                        jsval      *value_p)
{
    jsval value;
    JSExceptionState *state;

    JS_BeginRequest(context);

    value = JSVAL_VOID;
    state = JS_SaveExceptionState(context);
    JS_GetProperty(context, obj, property_name, &value);
    JS_RestoreExceptionState(context, state);

    if (value_p)
        *value_p = value;

    JS_EndRequest(context);

    return value != JSVAL_VOID;
}
コード例 #20
0
ファイル: jsd_stak.c プロジェクト: lofter2011/Icefox
JSBool
jsd_EvaluateScriptInStackFrame(JSDContext* jsdc, 
                               JSDThreadState* jsdthreadstate,
                               JSDStackFrameInfo* jsdframe,
                               const char *bytes, uintN length,
                               const char *filename, uintN lineno,
                               JSBool eatExceptions, jsval *rval)
{
    JSBool retval;
    JSBool valid;
    JSExceptionState* exceptionState = NULL;
    JSContext *cx;

    JS_ASSERT(JSD_CURRENT_THREAD() == jsdthreadstate->thread);

    JSD_LOCK_THREADSTATES(jsdc);
    valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
    JSD_UNLOCK_THREADSTATES(jsdc);

    if (!valid)
        return JS_FALSE;

    cx = jsdthreadstate->context;
    JS_ASSERT(cx);

    if (eatExceptions)
        exceptionState = JS_SaveExceptionState(cx);
    JS_ClearPendingException(cx);
    jsd_StartingEvalUsingFilename(jsdc, filename);
    retval = JS_EvaluateInStackFrame(cx, jsdframe->fp, bytes, length,
                                     filename, lineno, rval);
    jsd_FinishedEvalUsingFilename(jsdc, filename);
    if (eatExceptions)
        JS_RestoreExceptionState(cx, exceptionState);

    return retval;
}
コード例 #21
0
ファイル: jsexn.cpp プロジェクト: ahadzi/celtx
static JSBool
InitExnPrivate(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) {
            v = JSVAL_NULL;
            if (checkAccess &&
                !checkAccess(cx, fp->callee, callerid, JSACC_READ, &v)) {
                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_ReportAllocationOverflow(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->regs)
                elem->ulineno = js_PCToLineNumber(cx, fp->script, fp->regs->pc);
        }
        ++elem;
    }
    JS_ASSERT(priv->stackElems + stackDepth == elem);
    JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values);

    STOBJ_SET_SLOT(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;
}
コード例 #22
0
ファイル: jsexn.c プロジェクト: DmitrySigaev/DSMedia
static JSBool
InitExceptionObject(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
     * the backtrace procedure, not result in a failure of this constructor.
     */
    checkAccess = cx->runtime->checkObjectAccess;
    if (checkAccess) {
        older = JS_SetErrorReporter(cx, NULL);
        state = JS_SaveExceptionState(cx);
    }
#ifdef __GNUC__         /* suppress bogus gcc warnings */
    else {
        older = NULL;
        state = NULL;
    }
#endif
    callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);

    /*
     * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes
     * the next free jschar slot, and with room for at most stackmax non-null
     * jschars.  If stackbuf is non-null, it always contains an extra slot for
     * the null terminator we'll store at the end, as a backstop.
     *
     * All early returns must goto done after this point, till the after-loop
     * cleanup code has run!
     */
    stackbuf = NULL;
    stacklen = stackmax = 0;
    ok = JS_TRUE;

#define APPEND_CHAR_TO_STACK(c)                                               \
    JS_BEGIN_MACRO                                                            \
        if (stacklen == stackmax) {                                           \
            void *ptr_;                                                       \
            stackmax = stackmax ? 2 * stackmax : 64;                          \
            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
            if (!ptr_) {                                                      \
                ok = JS_FALSE;                                                \
                goto done;                                                    \
            }                                                                 \
            stackbuf = ptr_;                                                  \
        }                                                                     \
        stackbuf[stacklen++] = (c);                                           \
    JS_END_MACRO

#define APPEND_STRING_TO_STACK(str)                                           \
    JS_BEGIN_MACRO                                                            \
        JSString *str_ = str;                                                 \
        size_t length_ = JSSTRING_LENGTH(str_);                               \
        if (stacklen + length_ > stackmax) {                                  \
            void *ptr_;                                                       \
            stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_));            \
            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
            if (!ptr_) {                                                      \
                ok = JS_FALSE;                                                \
                goto done;                                                    \
            }                                                                 \
            stackbuf = ptr_;                                                  \
        }                                                                     \
        js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_);       \
        stacklen += length_;                                                  \
    JS_END_MACRO

    for (fp = cx->fp; fp; fp = fp->down) {
        if (checkAccess) {
            v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL;
            if (!JSVAL_IS_PRIMITIVE(v)) {
                ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v);
                if (!ok) {
                    ok = JS_TRUE;
                    break;
                }
            }
        }

        if (fp->fun) {
            if (fp->fun->atom)
                APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom));

            APPEND_CHAR_TO_STACK('(');
            for (i = 0; i < fp->argc; i++) {
                argsrc = js_ValueToSource(cx, fp->argv[i]);
                if (!argsrc) {
                    ok = JS_FALSE;
                    goto done;
                }
                if (i > 0)
                    APPEND_CHAR_TO_STACK(',');
                APPEND_STRING_TO_STACK(argsrc);
            }
            APPEND_CHAR_TO_STACK(')');
        }

        APPEND_CHAR_TO_STACK('@');
        if (fp->script && fp->script->filename) {
            for (cp = fp->script->filename; *cp; cp++)
                APPEND_CHAR_TO_STACK(*cp);
        }
        APPEND_CHAR_TO_STACK(':');
        if (fp->script && fp->pc) {
            ulineno = js_PCToLineNumber(fp->script, fp->pc);
            JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno);
            for (cp = ulnbuf; *cp; cp++)
                APPEND_CHAR_TO_STACK(*cp);
        } else {
            APPEND_CHAR_TO_STACK('0');
        }
        APPEND_CHAR_TO_STACK('\n');
    }

#undef APPEND_CHAR_TO_STACK
#undef APPEND_STRING_TO_STACK

done:
    if (checkAccess) {
        if (ok)
            JS_RestoreExceptionState(cx, state);
        else
            JS_DropExceptionState(cx, state);
        JS_SetErrorReporter(cx, older);
    }
    if (!ok) {
        JS_free(cx, stackbuf);
        return JS_FALSE;
    }

    if (!stackbuf) {
        stack = cx->runtime->emptyString;
    } else {
        /* NB: if stackbuf was allocated, it has room for the terminator. */
        JS_ASSERT(stacklen <= stackmax);
        if (stacklen < stackmax) {
            /*
             * Realloc can fail when shrinking on some FreeBSD versions, so
             * don't use JS_realloc here; simply let the oversized allocation
             * be owned by the string in that rare case.
             */
            void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar));
            if (shrunk)
                stackbuf = shrunk;
        }
        stackbuf[stacklen] = 0;
        stack = js_NewString(cx, stackbuf, stacklen, 0);
        if (!stack) {
            JS_free(cx, stackbuf);
            return JS_FALSE;
        }
    }
    return JS_DefineProperty(cx, obj, js_stack_str,
                             STRING_TO_JSVAL(stack),
                             NULL, NULL, JSPROP_ENUMERATE);
}
コード例 #23
0
/* void CompileFile (in nsILocalFile aFile, in PRBool strict); */
NS_IMETHODIMP nsXPCToolsCompiler::CompileFile(nsILocalFile *aFile, PRBool strict)
{
    // use the xpccallcontext stuff to get the current JSContext
    
    // get the xpconnect service
    nsresult rv;
    nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
    if(NS_FAILED(rv))
        return NS_ERROR_FAILURE;

    // get the xpconnect native call context
    nsCOMPtr<nsIXPCNativeCallContext> callContext;
    xpc->GetCurrentNativeCallContext(getter_AddRefs(callContext));
    if(!callContext)
        return NS_ERROR_FAILURE;

    // verify that we are being called from JS (i.e. the current call is
    // to this object - though we don't verify that it is to this exact method)
    nsCOMPtr<nsISupports> callee;
    callContext->GetCallee(getter_AddRefs(callee));
    if(!callee || callee.get() != (nsISupports*)this)
        return NS_ERROR_FAILURE;

    // Get JSContext of current call
    JSContext* cx;
    rv = callContext->GetJSContext(&cx);
    if(NS_FAILED(rv) || !cx)
        return NS_ERROR_FAILURE;

    FILE* handle;
    if(NS_FAILED(aFile->OpenANSIFileDesc("r", &handle)))
        return NS_ERROR_FAILURE;

    JSObject* glob = JS_NewObject(cx, &global_class, NULL, NULL);
    if (!glob)
        return NS_ERROR_FAILURE;
    if (!JS_InitStandardClasses(cx, glob))
        return NS_ERROR_FAILURE;

    nsCAutoString path;
    if(NS_FAILED(aFile->GetNativePath(path)))
        return NS_ERROR_FAILURE;

    uint32 oldoptions = JS_GetOptions(cx);
    JS_SetOptions(cx, JSOPTION_WERROR | (strict ? JSOPTION_STRICT : 0));
    JSErrorReporter older = JS_SetErrorReporter(cx, ErrorReporter);
    JSExceptionState *es =JS_SaveExceptionState(cx);

    if(!JS_CompileFileHandle(cx, glob, path.get(), handle))
    {
        jsval v;
        JSErrorReport* report;
        if(JS_GetPendingException(cx, &v) &&
           nsnull != (report = JS_ErrorFromException(cx, v)))
        {
            JSString* str;
            const char* msg = "Error";
            str = JS_ValueToString(cx, v);
            if(str)
                msg = JS_GetStringBytes(str);
            printf("%s [%s,%d]\n\n",
                    msg,
                    report->filename, 
                    (int)report->lineno);            
        }
        else
        {
            printf("no script and no error report!\n");
        }
        
    }    
    JS_RestoreExceptionState(cx, es);
    JS_SetErrorReporter(cx, older);
    JS_SetOptions(cx, oldoptions);
        
    return NS_OK;
}