Esempio n. 1
0
/**
 * shell_global_gc:
 * @global: A #ShellGlobal
 *
 * Start a garbage collection process.  For more information, see
 * https://developer.mozilla.org/En/JS_GC
 */
void
shell_global_gc (ShellGlobal *global)
{
  JSContext *context = gjs_context_get_native_context (global->js_context);

  JS_GC (context);
}
Esempio n. 2
0
/*
 * _gjs_profiler_new:
 * @context: The #GjsContext to profile
 *
 * This creates a new profiler for the #JSContext. It is important that
 * this instance is freed with _gjs_profiler_free() before the context is
 * destroyed.
 *
 * Call gjs_profiler_start() to enable the profiler, and gjs_profiler_stop()
 * when you have finished.
 *
 * The profiler works by enabling the JS profiler in spidermonkey so that
 * sample information is available. A POSIX timer is used to signal SIGPROF
 * to the process on a regular interval to collect the most recent profile
 * sample and stash it away. It is a programming error to mask SIGPROF from
 * the thread controlling the JS context.
 *
 * If another #GjsContext already has a profiler, or @context already has one,
 * then returns %NULL instead.
 *
 * Returns: (transfer full) (nullable): A newly allocated #GjsProfiler
 */
GjsProfiler *
_gjs_profiler_new(GjsContext *context)
{
    g_return_val_if_fail(context, nullptr);

    if (profiling_context == context) {
        g_critical("You can only create one profiler at a time.");
        return nullptr;
    }

    if (profiling_context) {
        g_message("Not going to profile GjsContext %p; you can only profile "
                  "one context at a time.", context);
        return nullptr;
    }

    GjsProfiler *self = g_new0(GjsProfiler, 1);

#ifdef ENABLE_PROFILER
    self->cx = static_cast<JSContext *>(gjs_context_get_native_context(context));
    self->pid = getpid();
#endif

    profiling_context = context;

    return self;
}
Esempio n. 3
0
static bool
bootstrap_coverage(GjsCoverage *coverage)
{
    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);

    JSContext *context = (JSContext *) gjs_context_get_native_context(priv->context);
    JSAutoRequest ar(context);

    JSObject *debuggee = gjs_get_import_global(context);
    JS::RootedObject debugger_compartment(context,
                                          gjs_create_global_object(context));
    {
        JSAutoCompartment compartment(context, debugger_compartment);
        JS::RootedObject debuggeeWrapper(context, debuggee);
        if (!JS_WrapObject(context, &debuggeeWrapper))
            return false;

        JS::RootedValue debuggeeWrapperValue(context, JS::ObjectValue(*debuggeeWrapper));
        if (!JS_SetProperty(context, debugger_compartment, "debuggee",
                            debuggeeWrapperValue) ||
            !gjs_define_global_properties(context, debugger_compartment,
                                          "coverage"))
            return false;

        /* Add a tracer, as suggested by jdm on #jsapi */
        JS_AddExtraGCRootsTracer(context, coverage_tracer, coverage);

        priv->compartment = debugger_compartment;
    }

    return true;
}
Esempio n. 4
0
static void
_gjs_unit_test_fixture_begin (GjsUnitTestFixture *fixture)
{
    fixture->gjs_context = gjs_context_new ();
    fixture->context = (JSContext *) gjs_context_get_native_context (fixture->gjs_context);
    JS_BeginRequest(fixture->context);
    JS_SetErrorReporter(fixture->context, test_error_reporter);
}
Esempio n. 5
0
JSContext*
gjs_runtime_peek_load_context(JSRuntime *runtime)
{
    GjsContext *context;

    context = gjs_runtime_get_data(runtime, "gjs-load-context");
    if (context == NULL) {
        return NULL;
    } else {
        return (JSContext*)gjs_context_get_native_context(context);
    }
}
Esempio n. 6
0
File: stack.c Progetto: goizueta/gjs
void
gjs_context_print_stack_to_buffer(GjsContext* context, void *initial, GString *buf)
{
    JSContext *js_context = (JSContext*)gjs_context_get_native_context(context);
    JSStackFrame* fp = initial;
    int num = 0;

    while (fp) {
        format_frame(js_context, fp, buf, num);
        num++;

	JS_FrameIterator(js_context, &fp);
    }
}
Esempio n. 7
0
static void
gjs_coverage_constructed(GObject *object)
{
    G_OBJECT_CLASS(gjs_coverage_parent_class)->constructed(object);

    GjsCoverage *coverage = GJS_COVERAGE(object);
    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
    new (&priv->compartment) JS::Heap<JSObject *>();

    if (!bootstrap_coverage(coverage)) {
        JSContext *context = static_cast<JSContext *>(gjs_context_get_native_context(priv->context));
        JSAutoCompartment compartment(context, gjs_get_import_global(context));
        gjs_log_exception(context);
    }
}
Esempio n. 8
0
static void
gjs_coverage_dispose(GObject *object)
{
    GjsCoverage *coverage = GJS_COVERAGE(object);
    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);

    /* Decomission objects inside of the JSContext before
     * disposing of the context */
    auto cx = static_cast<JSContext *>(gjs_context_get_native_context(priv->context));
    JS_RemoveExtraGCRootsTracer(cx, coverage_tracer, coverage);
    priv->compartment = nullptr;

    g_clear_object(&priv->context);

    G_OBJECT_CLASS(gjs_coverage_parent_class)->dispose(object);
}
Esempio n. 9
0
/**
 * shell_global_add_extension_importer:
 * @target_object_script: JavaScript code evaluating to a target object
 * @target_property: Name of property to use for importer
 * @directory: Source directory:
 * @error: A #GError
 *
 * This function sets a property named @target_property on the object
 * resulting from the evaluation of @target_object_script code, which
 * acts as a GJS importer for directory @directory.
 *
 * Returns: %TRUE on success
 */
gboolean
shell_global_add_extension_importer (ShellGlobal *global,
                                     const char  *target_object_script,
                                     const char  *target_property,
                                     const char  *directory,
                                     GError     **error)
{
  jsval target_object;
  JSObject *importer;
  JSContext *context = gjs_context_get_native_context (global->js_context);
  char *search_path[2] = { 0, 0 };

  // This is a bit of a hack; ideally we'd be able to pass our target
  // object directly into this function, but introspection doesn't
  // support that at the moment.  Instead evaluate a string to get it.
  if (!JS_EvaluateScript(context,
                         JS_GetGlobalObject(context),
                         target_object_script,
                         strlen (target_object_script),
                         "<target_object_script>",
                         0,
                         &target_object))
    {
      char *message;
      gjs_log_exception(context,
                        &message);
      g_set_error(error,
                  G_IO_ERROR,
                  G_IO_ERROR_FAILED,
                  "%s", message ? message : "(unknown)");
      g_free(message);
      return FALSE;
    }

  if (!JSVAL_IS_OBJECT (target_object))
    {
      g_error ("shell_global_add_extension_importer: invalid target object");
      return FALSE;
    }

  search_path[0] = (char*)directory;
  importer = gjs_define_importer (context, JSVAL_TO_OBJECT (target_object), target_property, (const char **)search_path, FALSE);
  return TRUE;
}
Esempio n. 10
0
/**
 * gjs_coverage_write_statistics:
 * @coverage: A #GjsCoverage
 * @output_directory: A directory to write coverage information to.
 *
 * Scripts which were provided as part of the #GjsCoverage:prefixes
 * construction property will be written out to @output_directory, in the same
 * directory structure relative to the source dir where the tests were run.
 *
 * This function takes all available statistics and writes them out to either
 * the file provided or to files of the pattern (filename).info in the same
 * directory as the scanned files. It will provide coverage data for all files
 * ending with ".js" in the coverage directories.
 */
void
gjs_coverage_write_statistics(GjsCoverage *coverage)
{
    auto priv = static_cast<GjsCoveragePrivate *>(gjs_coverage_get_instance_private(coverage));
    GError *error = nullptr;

    auto cx = static_cast<JSContext *>(gjs_context_get_native_context(priv->context));
    JSAutoCompartment ac(cx, gjs_get_import_global(cx));
    JSAutoRequest ar(cx);

    GjsAutoUnref<GFile> output_file = write_statistics_internal(coverage, cx, &error);
    if (!output_file) {
        g_critical("Error writing coverage data: %s", error->message);
        g_error_free(error);
        return;
    }

    GjsAutoChar output_file_path = g_file_get_path(output_file);
    g_message("Wrote coverage statistics to %s", output_file_path.get());
}
Esempio n. 11
0
/* The call context exists because when we call a closure, the scope
 * chain on the context is set to the original scope chain of the
 * closure. We want to avoid using any existing context (especially
 * the load context) because the closure "messes up" the scope chain
 * on the context.
 *
 * Unlike the load context, which is expected to be an eternal
 * singleton, we only cache the call context for efficiency. It would
 * be just as workable to recreate it for each call.
 */
JSContext*
gjs_runtime_get_call_context(JSRuntime *runtime)
{
    GjsContext *context;

    context = gjs_runtime_get_data(runtime, "gjs-call-context");
    if (context == NULL) {
        gjs_debug(GJS_DEBUG_CONTEXT,
                  "Creating call context for runtime %p",
                  runtime);
        context = g_object_new(GJS_TYPE_CONTEXT,
                               "runtime", runtime,
                               NULL);
        gjs_runtime_set_data(runtime,
                             "gjs-call-context",
                             context,
                             g_object_unref);
    }

    return (JSContext*)gjs_context_get_native_context(context);
}