summaryrefslogtreecommitdiff
path: root/loaders/lua5.1/peas-plugin-loader-lua.c
diff options
context:
space:
mode:
Diffstat (limited to 'loaders/lua5.1/peas-plugin-loader-lua.c')
-rw-r--r--loaders/lua5.1/peas-plugin-loader-lua.c297
1 files changed, 55 insertions, 242 deletions
diff --git a/loaders/lua5.1/peas-plugin-loader-lua.c b/loaders/lua5.1/peas-plugin-loader-lua.c
index d477ecb..32c6418 100644
--- a/loaders/lua5.1/peas-plugin-loader-lua.c
+++ b/loaders/lua5.1/peas-plugin-loader-lua.c
@@ -2,7 +2,7 @@
* peas-plugin-loader-lua.c
* This file is part of libpeas
*
- * Copyright (C) 2014 - Garrett Regier
+ * Copyright (C) 2014-2015 - Garrett Regier
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published by
@@ -32,6 +32,7 @@
#include <lauxlib.h>
#include <lualib.h>
+#include "peas-lua-internal.h"
#include "peas-lua-utils.h"
@@ -64,173 +65,6 @@ peas_register_types (PeasObjectModule *module)
PEAS_TYPE_PLUGIN_LOADER_LUA);
}
-static gboolean
-_lua_add_package_path (lua_State *L,
- const gchar *package_path)
-{
- luaL_checkstack (L, 3, "");
-
- lua_getglobal (L, "package");
- lua_getfield (L, -1, "path");
-
- if (!lua_isstring (L, -1))
- {
- g_warning ("Invalid Lua package.path: %s", lua_tostring (L, -1));
-
- /* Pop path and package */
- lua_pop (L, 2);
- return FALSE;
- }
-
- /* ";package_path/?.lua;package_path/?/init.lua" */
- lua_pushliteral (L, ";");
- lua_pushstring (L, package_path);
- lua_pushliteral (L, G_DIR_SEPARATOR_S "?.lua;");
- lua_pushstring (L, package_path);
- lua_pushliteral (L, G_DIR_SEPARATOR_S "?" G_DIR_SEPARATOR_S "init.lua");
- lua_concat (L, 5);
-
- if (strstr (lua_tostring (L, -2), lua_tostring (L, -1)) != NULL)
- {
- /* Pop new path and path */
- lua_pop (L, 2);
- }
- else
- {
- /* Update package.path */
- lua_concat (L, 2);
- lua_setfield (L, -2, "path");
- }
-
- /* Pop package */
- lua_pop (L, 1);
- return TRUE;
-}
-
-static gboolean
-_lua_has_package (lua_State *L,
- const gchar *package_name)
-{
- gboolean has_package;
-
- luaL_checkstack (L, 3, "");
-
- lua_getglobal (L, "package");
- lua_getfield (L, -1, "loaded");
- lua_getfield (L, -1, package_name);
-
- has_package = !lua_isnil (L, -1);
-
- /* Pop package, loaded and package's table */
- lua_pop (L, 3);
- return has_package;
-}
-
-static gboolean
-_lua_pushinstance (lua_State *L,
- const gchar *namespace_,
- const gchar *name,
- GType gtype,
- gpointer instance)
-{
- luaL_checkstack (L, 3, "");
-
- if (!peas_lua_utils_require (L, "lgi"))
- return FALSE;
-
- lua_getfield (L, -1, namespace_);
- lua_getfield (L, -1, name);
-
- /* Remove the namespace and lgi's module table */
- lua_replace (L, -2);
- lua_replace (L, -2);
-
- lua_pushlightuserdata (L, instance);
- lua_pushboolean (L, FALSE);
-
- /* new(addr[, already_own[, no_sink]]) */
- if (lua_pcall (L, 2, 1, 0) != 0)
- {
- g_warning ("Failed to create Lua object of type '%s': %s",
- g_type_name (gtype), lua_tostring (L, -1));
-
- /* Pop the error */
- lua_pop (L, 1);
- return FALSE;
- }
-
- /* Check that the Lua object was created correctly */
- lua_getfield (L, -1, "_native");
- g_assert (lua_islightuserdata (L, -1));
- g_assert (lua_touserdata (L, -1) == instance);
- lua_pop (L, 1);
-
- return TRUE;
-}
-
-static GType
-_lua_get_gtype (lua_State *L,
- int index)
-{
- GType gtype = G_TYPE_INVALID;
-
- luaL_checkstack (L, 1, "");
-
- lua_getfield (L, index, "_gtype");
-
- if (lua_type (L, -1) == LUA_TLIGHTUSERDATA)
- gtype = (GType) lua_touserdata (L, -1);
-
- /* Pop _gtype */
- lua_pop (L, 1);
- return gtype;
-}
-
-static GType
-_lua_find_extension_type (lua_State *L,
- PeasPluginInfo *info,
- GType exten_type)
-{
- GType found_type = G_TYPE_INVALID;
-
- luaL_checkstack (L, 3, "");
-
- /* Get the module's table */
- lua_pushstring (L, info->filename);
- lua_rawget (L, LUA_REGISTRYINDEX);
-
- /* Must always have a valid key */
- lua_pushnil (L);
- while (lua_next (L, -2) != 0)
- {
- if (lua_istable (L, -1))
- {
- found_type = _lua_get_gtype (L, -1);
-
- if (found_type != G_TYPE_INVALID)
- {
- if (!g_type_is_a (found_type, exten_type))
- {
- found_type = G_TYPE_INVALID;
- }
- else
- {
- /* Pop value and key */
- lua_pop (L, 2);
- break;
- }
- }
- }
-
- /* Pop the value but keep the key for the next iteration */
- lua_pop (L, 1);
- }
-
- /* Pop the module's table */
- lua_pop (L, 1);
- return found_type;
-}
-
static lua_State *
thread_enter (PeasPluginLoaderLua *lua_loader,
PeasPluginInfo *info)
@@ -277,6 +111,33 @@ thread_leave (PeasPluginLoaderLua *lua_loader,
priv->lgi_leave_func (priv->lgi_lock);
}
+static GType
+find_lua_extension_type (lua_State *L,
+ PeasPluginInfo *info,
+ GType exten_type)
+{
+ luaL_checkstack (L, 2, "");
+ lua_pushstring (L, info->filename);
+ lua_pushlightuserdata (L, GSIZE_TO_POINTER (exten_type));
+
+ if (peas_lua_internal_call (L, "find_extension_type",
+ 2, LUA_TLIGHTUSERDATA))
+ {
+ GType extension_type;
+
+ extension_type = (GType) lua_touserdata (L, -1);
+ lua_pop (L, 1);
+
+ if (g_type_is_a (extension_type, exten_type))
+ return extension_type;
+
+ g_warning ("Found invalid extension type '%s' for '%s'",
+ g_type_name (extension_type), g_type_name (exten_type));
+ }
+
+ return G_TYPE_INVALID;
+}
+
static gboolean
peas_plugin_loader_lua_provides_extension (PeasPluginLoader *loader,
PeasPluginInfo *info,
@@ -284,14 +145,14 @@ peas_plugin_loader_lua_provides_extension (PeasPluginLoader *loader,
{
PeasPluginLoaderLua *lua_loader = PEAS_PLUGIN_LOADER_LUA (loader);
lua_State *L;
- GType extension_type;
+ GType the_type;
L = thread_enter (lua_loader, info);
- extension_type = _lua_find_extension_type (L, info, exten_type);
+ the_type = find_lua_extension_type (L, info, exten_type);
thread_leave (lua_loader, info, &L);
- return extension_type != G_TYPE_INVALID;
+ return the_type != G_TYPE_INVALID;
}
static PeasExtension *
@@ -308,16 +169,10 @@ peas_plugin_loader_lua_create_extension (PeasPluginLoader *loader,
L = thread_enter (lua_loader, info);
- the_type = _lua_find_extension_type (L, info, exten_type);
+ the_type = find_lua_extension_type (L, info, exten_type);
if (the_type == G_TYPE_INVALID)
goto out;
- if (!g_type_is_a (the_type, exten_type))
- {
- g_warn_if_fail (g_type_is_a (the_type, exten_type));
- goto out;
- }
-
object = g_object_newv (the_type, n_parameters, parameters);
if (object == NULL)
goto out;
@@ -328,29 +183,12 @@ peas_plugin_loader_lua_create_extension (PeasPluginLoader *loader,
g_object_set_qdata (object, extension_type_quark (),
GSIZE_TO_POINTER (exten_type));
- luaL_checkstack (L, 3, "");
-
- if (!_lua_pushinstance (L, "GObject", "Object", the_type, object))
- {
- g_clear_object (&object);
- goto out;
- }
-
- lua_getfield (L, -1, "priv");
-
- if (!_lua_pushinstance (L, "Peas", "PluginInfo",
- PEAS_TYPE_PLUGIN_INFO, info))
- {
- g_clear_object (&object);
- }
- else
- {
- /* Set the plugin info as self.priv.plugin_info */
- lua_setfield (L, -2, "plugin_info");
- }
+ luaL_checkstack (L, 2, "");
+ lua_pushlightuserdata (L, object);
+ lua_pushlightuserdata (L, info);
- /* Pop priv and object */
- lua_pop (L, 2);
+ if (!peas_lua_internal_call (L, "setup_extension", 2, LUA_TNIL))
+ g_clear_object (&object);
out:
@@ -364,53 +202,21 @@ peas_plugin_loader_lua_load (PeasPluginLoader *loader,
{
PeasPluginLoaderLua *lua_loader = PEAS_PLUGIN_LOADER_LUA (loader);
lua_State *L;
- gboolean success;
+ gboolean success = FALSE;
L = thread_enter (lua_loader, info);
- luaL_checkstack (L, 2, "");
-
- /* Get the module's table */
+ luaL_checkstack (L, 3, "");
lua_pushstring (L, info->filename);
- lua_rawget (L, LUA_REGISTRYINDEX);
+ lua_pushstring (L, peas_plugin_info_get_module_dir (info));
+ lua_pushstring (L, peas_plugin_info_get_module_name (info));
- if (!lua_isnil (L, -1))
- {
- success = lua_istable (L, -1);
- }
- else
+ if (peas_lua_internal_call (L, "load", 3, LUA_TBOOLEAN))
{
- const gchar *module_dir, *module_name;
-
- module_dir = peas_plugin_info_get_module_dir (info);
- module_name = peas_plugin_info_get_module_name (info);
-
- /* Must push the key back onto the stack */
- lua_pushstring (L, info->filename);
-
- /* Push something that isn't a table */
- lua_pushboolean (L, FALSE);
-
- if (_lua_has_package (L, module_name))
- {
- g_warning ("Error loading plugin '%s': "
- "module name '%s' has already been used",
- info->filename, module_name);
- }
- else if (_lua_add_package_path (L, module_dir) &&
- peas_lua_utils_require (L, module_name))
- {
- /* Remove the boolean */
- lua_replace (L, -2);
- }
-
- success = lua_istable (L, -1);
- lua_rawset (L, LUA_REGISTRYINDEX);
+ success = lua_toboolean (L, -1);
+ lua_pop (L, 1);
}
- /* Pop the module's table */
- lua_pop (L, 1);
-
thread_leave (lua_loader, info, &L);
return success;
}
@@ -433,9 +239,9 @@ peas_plugin_loader_lua_unload (PeasPluginLoader *loader,
lua_pushnil (L);
lua_rawset (L, LUA_REGISTRYINDEX);
- priv->lgi_leave_func (priv->lgi_lock);
-
info->loader_data = NULL;
+
+ priv->lgi_leave_func (priv->lgi_lock);
}
static void
@@ -447,7 +253,7 @@ peas_plugin_loader_lua_garbage_collect (PeasPluginLoader *loader)
priv->lgi_enter_func (priv->lgi_lock);
- lua_gc (L, LUA_GCCOLLECT, 0);
+ peas_lua_internal_call (L, "garbage_collect", 0, LUA_TNIL);
priv->lgi_leave_func (priv->lgi_lock);
}
@@ -515,6 +321,12 @@ peas_plugin_loader_lua_initialize (PeasPluginLoader *loader)
/* Pop lgi's module table */
lua_pop (L, 1);
+ if (!peas_lua_internal_setup (L))
+ {
+ /* Already warned */
+ return FALSE;
+ }
+
/* Assert that no values were leaked to the stack */
g_assert_cmpint (lua_gettop (L), ==, 0);
@@ -548,6 +360,7 @@ peas_plugin_loader_lua_finalize (GObject *object)
if (priv->lgi_enter_func != NULL)
priv->lgi_enter_func (priv->lgi_lock);
+ peas_lua_internal_shutdown (priv->L);
g_clear_pointer (&priv->L, (GDestroyNotify) lua_close);
G_OBJECT_CLASS (peas_plugin_loader_lua_parent_class)->finalize (object);