Пример #1
0
void
gjs_explain_scope(JSContext  *context,
                  const char *title)
{
    JSContext *load_context;
    JSContext *call_context;
    JSObject *global;
    JSObject *parent;
    GString *chain;

    gjs_debug(GJS_DEBUG_SCOPE,
              "=== %s ===",
              title);

    load_context = gjs_runtime_peek_load_context(JS_GetRuntime(context));
    call_context = gjs_runtime_peek_call_context(JS_GetRuntime(context));

    JS_BeginRequest(context);
    JS_BeginRequest(load_context);
    JS_BeginRequest(call_context);

    JS_EnterLocalRootScope(context);

    gjs_debug(GJS_DEBUG_SCOPE,
              "  Context: %p %s",
              context,
              context == load_context ? "(LOAD CONTEXT)" :
              context == call_context ? "(CALL CONTEXT)" :
              "");

    global = JS_GetGlobalObject(context);
    gjs_debug(GJS_DEBUG_SCOPE,
              "  Global: %p %s",
              global, gjs_value_debug_string(context, OBJECT_TO_JSVAL(global)));

    parent = JS_GetScopeChain(context);
    chain = g_string_new(NULL);
    while (parent != NULL) {
        const char *debug;
        debug = gjs_value_debug_string(context, OBJECT_TO_JSVAL(parent));

        if (chain->len > 0)
            g_string_append(chain, ", ");

        g_string_append_printf(chain, "%p %s",
                               parent, debug);
        parent = JS_GetParent(context, parent);
    }
    gjs_debug(GJS_DEBUG_SCOPE,
              "  Chain: %s",
              chain->str);
    g_string_free(chain, TRUE);

    JS_LeaveLocalRootScope(context);

    JS_EndRequest(call_context);
    JS_EndRequest(load_context);
    JS_EndRequest(context);
}
Пример #2
0
/* Mimick the behaviour exposed by standard Error objects
   (http://mxr.mozilla.org/mozilla-central/source/js/src/jsexn.cpp#554)
*/
static char*
jsvalue_to_string(JSContext* cx, jsval val, gboolean* is_string)
{
    char* value = NULL;
    JSString* value_str = NULL;

    if (JSVAL_IS_PRIMITIVE(val)) {
      value_str = JS_ValueToSource(cx, val);
    } else {
      JSObject *obj = JSVAL_TO_OBJECT(val);

      if (JS_ObjectIsFunction(cx, obj)) {
	JSFunction *fn = JS_ValueToFunction(cx, val);
	value_str = JS_GetFunctionId(fn);

	if (!value_str)
	  value = g_strdup("[unknown function]");
      } else {
	value = g_strdup_printf("[object %s]", JS_GetClass(cx, obj)->name);
      }
    }

    if (!value && value_str)
      value = gjs_value_debug_string(cx, val);

    if (is_string)
        *is_string = JSVAL_IS_STRING(val);

    return value;
}
Пример #3
0
void
gjs_log_object_props(JSContext      *context,
                     JSObject       *obj,
                     GjsDebugTopic   topic,
                     const char     *prefix)
{
    JSObject *props_iter;
    jsid prop_id;

    JS_BeginRequest(context);

    /* We potentially create new strings, plus the property iterator,
     * that could get collected as we go through this process. So
     * create a local root scope.
     */
    JS_EnterLocalRootScope(context);

    props_iter = JS_NewPropertyIterator(context, obj);
    if (props_iter == NULL) {
        gjs_debug(GJS_DEBUG_ERROR,
                  "Failed to create property iterator for object props");
        goto done;
    }

    prop_id = JSVAL_VOID;
    if (!JS_NextProperty(context, props_iter, &prop_id))
        goto done;

    while (prop_id != JSVAL_VOID) {
        jsval nameval;
        const char *name;
        jsval propval;

        if (!JS_IdToValue(context, prop_id, &nameval))
            goto next;

        if (!gjs_get_string_id(nameval, &name))
            goto next;

        if (!gjs_object_get_property(context, obj, name, &propval))
            goto next;

        gjs_debug(topic,
                  "%s%s = '%s'",
                  prefix, name,
                  gjs_value_debug_string(context, propval));

    next:
        prop_id = JSVAL_VOID;
        if (!JS_NextProperty(context, props_iter, &prop_id))
            break;
    }

 done:
    JS_LeaveLocalRootScope(context);
    JS_EndRequest(context);
}
Пример #4
0
JSBool
gjs_console_interact(JSContext *context,
                     uintN      argc,
                     jsval     *vp)
{
    JSObject *object = JS_THIS_OBJECT(context, vp);
    gboolean eof = FALSE;
    JSObject *script = NULL;
    jsval result;
    JSString *str;
    GString *buffer = NULL;
    char *temp_buf = NULL;
    gunichar2 *u16_buffer;
    glong u16_buffer_len;
    int lineno;
    int startline;
    GError *error = NULL;
    FILE *file = stdin;

    JS_SetErrorReporter(context, gjs_console_error_reporter);

        /* It's an interactive filehandle; drop into read-eval-print loop. */
    lineno = 1;
    do {
        /*
         * Accumulate lines until we get a 'compilable unit' - one that either
         * generates an error (before running out of source) or that compiles
         * cleanly.  This should be whenever we get a complete statement that
         * coincides with the end of a line.
         */
        startline = lineno;
        buffer = g_string_new("");
        do {
            if (!gjs_console_readline(context, &temp_buf, file,
                                      startline == lineno ? "gjs> " : ".... ")) {
                eof = JS_TRUE;
                break;
            }
            g_string_append(buffer, temp_buf);
            g_free(temp_buf);
            lineno++;
        /* Note in this case, we are trying to parse the buffer as
         * ISO-8859-1 which is broken for non-ASCII.
         */
        } while (!JS_BufferIsCompilableUnit(context, object, buffer->str, buffer->len));

        if ((u16_buffer = g_utf8_to_utf16 (buffer->str, buffer->len, NULL, &u16_buffer_len, &error)) == NULL) {
            g_printerr ("%s\n", error->message);
            g_clear_error (&error);
            continue;
        }

        script = JS_CompileUCScript(context, object, u16_buffer, u16_buffer_len, "typein",
                                    startline);
        g_free (u16_buffer);

        if (script)
            JS_ExecuteScript(context, object, script, &result);

        if (JS_GetPendingException(context, &result)) {
            str = JS_ValueToString(context, result);
            JS_ClearPendingException(context);
        } else if (JSVAL_IS_VOID(result)) {
            goto next;
        } else {
            str = JS_ValueToString(context, result);
        }

        if (str) {
            char *display_str;
            display_str = gjs_value_debug_string(context, result);
            if (display_str != NULL) {
                g_fprintf(stdout, "%s\n", display_str);
                g_free(display_str);
            }
        }

 next:
        g_string_free(buffer, TRUE);
    } while (!eof);

    g_fprintf(stdout, "\n");

    if (file != stdin)
        fclose(file);

    return JS_TRUE;
}
Пример #5
0
JSBool
gjs_console_interact(JSContext *context,
                     unsigned   argc,
                     jsval     *vp)
{
    JSObject *object = JS_THIS_OBJECT(context, vp);
    gboolean eof = FALSE;
    jsval result;
    JSString *str;
    GString *buffer = NULL;
    char *temp_buf = NULL;
    int lineno;
    int startline;
    FILE *file = stdin;

    JS_SetErrorReporter(context, gjs_console_error_reporter);

        /* It's an interactive filehandle; drop into read-eval-print loop. */
    lineno = 1;
    do {
        /*
         * Accumulate lines until we get a 'compilable unit' - one that either
         * generates an error (before running out of source) or that compiles
         * cleanly.  This should be whenever we get a complete statement that
         * coincides with the end of a line.
         */
        startline = lineno;
        buffer = g_string_new("");
        do {
            if (!gjs_console_readline(context, &temp_buf, file,
                                      startline == lineno ? "cjs> " : ".... ")) {
                eof = JS_TRUE;
                break;
            }
            g_string_append(buffer, temp_buf);
            g_free(temp_buf);
            lineno++;
        } while (!JS_BufferIsCompilableUnit(context, object, buffer->str, buffer->len));

        JS::CompileOptions options(context);
        options.setUTF8(true)
               .setFileAndLine("typein", startline);
        js::RootedObject rootedObj(context, object);
        JS::Evaluate(context, rootedObj, options, buffer->str, buffer->len,  &result);

        gjs_schedule_gc_if_needed(context);

        if (JS_GetPendingException(context, &result)) {
            str = JS_ValueToString(context, result);
            JS_ClearPendingException(context);
        } else if (JSVAL_IS_VOID(result)) {
            goto next;
        } else {
            str = JS_ValueToString(context, result);
        }

        if (str) {
            char *display_str;
            display_str = gjs_value_debug_string(context, result);
            if (display_str != NULL) {
                g_fprintf(stdout, "%s\n", display_str);
                g_free(display_str);
            }
        }

 next:
        g_string_free(buffer, TRUE);
    } while (!eof);

    g_fprintf(stdout, "\n");

    if (file != stdin)
        fclose(file);

    return JS_TRUE;
}