~aperezdc/kiln

992f457b569967afff32c38fa28c96153e134df4 — Adrian Perez de Castro 4 years ago cd4ac15
loader: Allow bootstrapping the loader into a JSCContext

Support making a loader itself available as a module in the JS context.
3 files changed, 120 insertions(+), 0 deletions(-)

M libkn/kiln-loader.c
M libkn/kiln-loader.h
M shell/main.c
M libkn/kiln-loader.c => libkn/kiln-loader.c +112 -0
@@ 564,3 564,115 @@ kiln_loader_add_module (KilnLoader        *self,
    g_hash_table_insert (self->modules, g_strdup (module_name), module);
    return module;
}

static JSCValue* kiln_loader_open_in_context (JSCContext*, GError**, void*);

KilnModule*
kiln_loader_bootstrap (KilnLoader *self,
                       const char *module_name,
                       GError    **error)
{
    return kiln_loader_add_module (self,
                                   module_name,
                                   kiln_loader_open_in_context,
                                   self,
                                   error);
}


static JSCValue*
js_kiln_loader_get_paths (KilnLoader *self)
{
    unsigned i = 0;
    JSCContext *context = jsc_context_get_current ();
    JSCValue *array = jsc_value_new_array (context, G_TYPE_NONE);
    for (GList *iter = g_list_first (self->module_paths); iter; iter = g_list_next (iter)) {
        g_autoptr(JSCValue) str = jsc_value_new_string (context, iter->data);
        jsc_value_object_set_property_at_index (array, i++, str);
    }
    return array;
}

static JSCValue*
js_kiln_loader_load_module (KilnLoader *self,
                            const char *module_name)
{
    g_autoptr(GError) error = NULL;
    JSCValue *value = kiln_loader_load_module (self, module_name, &error);
    if (!value) {
        jsc_context_throw_with_name_printf (jsc_context_get_current (),
                                            "KilnError",
                                            "Cannot open module '%s': %s.",
                                            module_name,
                                            error->message);
    }
    return value;
}

static JSCValue*
kiln_loader_open_in_context (JSCContext *context,
                             GError    **error,
                             void       *userdata)
{
    KilnLoader *self = userdata;

    g_autoptr(JSCClass) cls = jsc_context_register_class (context,
                                                          "KilnLoader",
                                                          NULL,
                                                          NULL,
                                                          g_object_unref);
    jsc_class_add_method (cls,
                          "getPaths",
                          G_CALLBACK (js_kiln_loader_get_paths),
                          NULL,  /* userdata */
                          NULL,  /* destroy_notify */
                          JSC_TYPE_VALUE,
                          0);

    jsc_class_add_method (cls,
                          "hasPath",
                          G_CALLBACK (kiln_loader_has_path),
                          NULL,  /* userdata */
                          NULL,  /* destroy_notify */
                          G_TYPE_BOOLEAN,
                          1,
                          G_TYPE_STRING);

    jsc_class_add_method (cls,
                          "appendPath",
                          G_CALLBACK (kiln_loader_append_path),
                          NULL,  /* userdata */
                          NULL,  /* destroy_notify */
                          G_TYPE_NONE,
                          1,
                          G_TYPE_STRING);

    jsc_class_add_method (cls,
                          "prependPath",
                          G_CALLBACK (kiln_loader_prepend_path),
                          NULL,  /* userdata */
                          NULL,  /* destroy_notify */
                          G_TYPE_NONE,
                          1,
                          G_TYPE_STRING);

    jsc_class_add_method (cls,
                          "loadModule",
                          G_CALLBACK (js_kiln_loader_load_module),
                          NULL,  /* userdata */
                          NULL,  /* destroy_notify */
                          JSC_TYPE_VALUE,
                          1,
                          G_TYPE_STRING);

    g_autoptr(JSCValue) ctor =
        jsc_class_add_constructor (cls,
                                   NULL,  /* name */
                                   G_CALLBACK (g_object_ref),
                                   g_object_ref (self),
                                   g_object_unref,
                                   KILN_TYPE_LOADER,
                                   0);

    return jsc_value_constructor_call (ctor, G_TYPE_NONE);
}

M libkn/kiln-loader.h => libkn/kiln-loader.h +4 -0
@@ 75,6 75,10 @@ gboolean    kiln_loader_open_module  (KilnLoader *self,
                                      const char *module_name,
                                      GError    **error);

KilnModule* kiln_loader_bootstrap    (KilnLoader *self,
                                      const char *module_name,
                                      GError    **error);

KilnModule* kiln_loader_add_module   (KilnLoader        *self,
                                      const char        *module_name,
                                      KilnModuleOpenFunc callback,

M shell/main.c => shell/main.c +4 -0
@@ 95,6 95,10 @@ open_builtin_modules (KilnLoader *loader,
        "console",
    };

    if (!kiln_loader_bootstrap (loader, "kiln", error) ||
        !kiln_loader_open_module (loader, "kiln", error))
            return false;

    for (unsigned i = 0; i < G_N_ELEMENTS (builtins); ++i) {
        g_autoptr(JSCValue) ns_value =
            kiln_loader_load_module (loader, builtins[i], error);