コード例 #1
0
ファイル: IGUIObject.cpp プロジェクト: Rektosauros/0ad
void IGUIObject::RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI* pGUI)
{
	if(!GetGUI())
		throw PSERROR_GUI_OperationNeedsGUIObject();

	JSContext* cx = pGUI->GetScriptInterface()->GetContext();
	JSAutoRequest rq(cx);
	JS::RootedValue globalVal(cx, pGUI->GetGlobalObject());
	JS::RootedObject globalObj(cx, &globalVal.toObject());

	const int paramCount = 1;
	const char* paramNames[paramCount] = { "mouse" };

	// Location to report errors from
	CStr CodeName = GetName()+" "+Action;

	// Generate a unique name
	static int x = 0;
	char buf[64];
	sprintf_s(buf, ARRAY_SIZE(buf), "__eventhandler%d (%s)", x++, Action.c_str());

	JS::CompileOptions options(cx);
	options.setFileAndLine(CodeName.c_str(), 0);
	options.setCompileAndGo(true);

	JS::RootedFunction func(cx, JS_CompileFunction(cx, globalObj,
		buf, paramCount, paramNames, Code.c_str(), Code.length(), options));

	if (!func)
		return; // JS will report an error message

	JS::RootedObject funcObj(cx, JS_GetFunctionObject(func));
	SetScriptHandler(Action, funcObj);
}
コード例 #2
0
//---------------------------------------------------------------------------
inline JSBool ejs_throw_error(JSContext *cx, JSObject *obj, const char *msg) {
    JSString *jsstr;

    // if we get errors during error reporting we report those
    if (((jsstr = JS_NewStringCopyZ(cx, msg))) &&
        (JS_AddNamedRoot(cx, &jsstr, "jsstr"))) {
        jsval dummy;
        // We can't use JS_EvaluateScript since the stack would be wrong
        JSFunction *func;
        JSObject   *fobj;
        const char *fbody      = "throw new Error(msg);";
        const char *argnames[] = { "msg" };
        if ((func = JS_CompileFunction(cx, obj, NULL,
                                       1, argnames,
                                       fbody, strlen(fbody),
                                       NULL, 0))) {
            // root function
            if (((fobj = JS_GetFunctionObject(func))) &&
                (JS_AddNamedRoot(cx, &fobj, "fobj"))) {
                jsval args[] = { STRING_TO_JSVAL(jsstr) };
                JS_CallFunction(cx, obj, func, 1, args, &dummy);
                JS_RemoveRoot(cx, &fobj);
            }
        }
        JS_RemoveRoot(cx, &jsstr);
    }

    return JS_FALSE;
}//---------------------------------------------------------------------------
コード例 #3
0
ファイル: spidermonkey.c プロジェクト: Efreak/elinks
int
spidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter,
			   struct string *code)
{
	JSContext *ctx;
	JSFunction *fun;
	jsval rval;
	int ret;

	assert(interpreter);
	if (!js_module_init_ok) return 0;
	ctx = interpreter->backend_data;
	interpreter->ret = NULL;
	fun = JS_CompileFunction(ctx, NULL, "", 0, NULL, code->source,
				 code->length, "", 0);
	if (!fun)
		return -1;

#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
	interpreter->heartbeat = add_heartbeat(interpreter);
#elif defined(HAVE_JS_SETBRANCHCALLBACK)
	setup_safeguard(interpreter, ctx);
#endif
	ret = JS_CallFunction(ctx, NULL, fun, 0, NULL, &rval);
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
	done_heartbeat(interpreter->heartbeat);
#endif
	if (ret == 2) { /* onClick="history.back()" */
		return 0;
	}
	if (ret == JS_FALSE) {
		return -1;
	}
	if (JSVAL_IS_VOID(rval)) {
		/* Undefined value. */
		return -1;
	}

	return jsval_to_boolean(ctx, &rval);
}
コード例 #4
0
ファイル: jsapi-util-error.c プロジェクト: sjokkis/gjs
/*
 * See:
 * https://bugzilla.mozilla.org/show_bug.cgi?id=166436
 * https://bugzilla.mozilla.org/show_bug.cgi?id=215173
 *
 * Very surprisingly, jsapi.h lacks any way to "throw new Error()"
 *
 * So here is an awful hack inspired by
 * http://egachine.berlios.de/embedding-sm-best-practice/embedding-sm-best-practice.html#error-handling
 */
static void
gjs_throw_valist(JSContext       *context,
                    const char      *format,
                    va_list          args)
{
    char *s;
    jsval retval;
    jsval argv[1];
    JSFunction *func;
    const char *body;
    JSBool result;
    const char *names[] = { "message" };
    guint options;

    s = g_strdup_vprintf(format, args);

    JS_BeginRequest(context);

    if (JS_IsExceptionPending(context)) {
        /* Often it's unclear whether a given jsapi.h function
         * will throw an exception, so we will throw ourselves
         * "just in case"; in those cases, we don't want to
         * overwrite an exception that already exists.
         * (Do log in case our second exception adds more info,
         * but don't log as topic ERROR because if the exception is
         * caught we don't want an ERROR in the logs.)
         */
        gjs_debug(GJS_DEBUG_CONTEXT,
                  "Ignoring second exception: '%s'",
                  s);
        g_free(s);
        return;
    }

    result = JS_FALSE;

    JS_EnterLocalRootScope(context);

    if (!gjs_string_from_utf8(context, s, -1, &argv[0])) {
        JS_ReportError(context, "Failed to copy exception string");
        goto out;
    }

    body = "throw new Error(message);";
    func = JS_CompileFunction(context,
                              JS_GetGlobalObject(context), /* parent object (scope chain) */
                              NULL, /* name of function if we wanted to define it in parent */
                              1, /* nargs */
                              &names[0], /* array of arg names if we had args */
                              body,
                              strlen(body),
                              "gjs_throw", /* file */
                              0); /* line */

    if (func == NULL) {
        JS_ReportError(context, "Failed to compile function");
        goto out;
    }

    /* we need JS_CallFunctionValue() to leave the exception set */
    options = JS_GetOptions(context);
    if (!(options & JSOPTION_DONT_REPORT_UNCAUGHT)) {
        JS_SetOptions(context, options | JSOPTION_DONT_REPORT_UNCAUGHT);
    }

    retval = JSVAL_VOID;

    /* note the return value is whether function succeeded, which it shouldn't, since it
     * throws...
     */
    JS_CallFunctionValue(context,
                         JS_GetGlobalObject(context),
                         OBJECT_TO_JSVAL(JS_GetFunctionObject(func)),
                         1, &argv[0],
                         &retval);

    if (!(options & JSOPTION_DONT_REPORT_UNCAUGHT)) {
        JS_SetOptions(context, options);
    }

    if (!JS_IsExceptionPending(context)) {
        JS_ReportError(context,
                       "Failed to set exception by calling our exception-setting function");
        goto out;
    }

    result = JS_TRUE;

 out:

    JS_LeaveLocalRootScope(context);

    if (!result) {
        /* try just reporting it to error handler? should not
         * happen though pretty much
         */
        JS_ReportError(context,
                       "Failed to throw exception '%s'",
                       s);
    }
    g_free(s);

    JS_EndRequest(context);
}
コード例 #5
0
ファイル: engine_spidermonkey.cpp プロジェクト: xrogaan/mongo
    JSFunction * _compileFunction( const char * raw , JSObject * assoc , const char *& gcName ) {
        if ( ! assoc )
            assoc = JS_GetGlobalObject( _context );

        while (isspace(*raw)) {
            raw++;
        }

        stringstream fname;
        fname << "cf_";
        static int fnum = 1;
        fname << "_" << fnum++ << "_";


        if ( ! hasFunctionIdentifier( raw ) ) {
            string s = raw;
            if ( isSimpleStatement( s ) ) {
                s = "return " + s;
            }
            gcName = "cf anon";
            fname << "anon";
            return JS_CompileFunction( _context , assoc , fname.str().c_str() , 0 , 0 , s.c_str() , strlen( s.c_str() ) , "nofile_a" , 0 );
        }

        string code = raw;

        size_t start = code.find( '(' );
        assert( start != string::npos );

        fname << "_f_" << trim( code.substr( 9 , start - 9 ) );

        code = code.substr( start + 1 );
        size_t end = code.find( ')' );
        assert( end != string::npos );

        string paramString = trim( code.substr( 0 , end ) );
        code = code.substr( end + 1 );

        vector<string> params;
        while ( paramString.size() ) {
            size_t c = paramString.find( ',' );
            if ( c == string::npos ) {
                params.push_back( paramString );
                break;
            }
            params.push_back( trim( paramString.substr( 0 , c ) ) );
            paramString = trim( paramString.substr( c + 1 ) );
            paramString = trim( paramString );
        }

        boost::scoped_array<const char *> paramArray (new const char*[params.size()]);
        for ( size_t i=0; i<params.size(); i++ )
            paramArray[i] = params[i].c_str();

        JSFunction * func = JS_CompileFunction( _context , assoc , fname.str().c_str() , params.size() , paramArray.get() , code.c_str() , strlen( code.c_str() ) , "nofile_b" , 0 );

        if ( ! func ) {
            cout << "compile failed for: " << raw << endl;
            return 0;
        }
        gcName = "cf normal";
        return func;
    }