changeset 196:bdeda4baf684

Irccd: use the shared_ptr directly in Module
author David Demelier <markand@malikania.fr>
date Tue, 07 Jun 2016 20:49:47 +0200
parents 1c22fcce1662
children 1b3365343b18
files lib/irccd/mod-directory.cpp lib/irccd/mod-directory.hpp lib/irccd/mod-elapsed-timer.cpp lib/irccd/mod-elapsed-timer.hpp lib/irccd/mod-file.cpp lib/irccd/mod-file.hpp lib/irccd/mod-irccd.cpp lib/irccd/mod-irccd.hpp lib/irccd/mod-logger.cpp lib/irccd/mod-logger.hpp lib/irccd/mod-plugin.cpp lib/irccd/mod-plugin.hpp lib/irccd/mod-server.cpp lib/irccd/mod-server.hpp lib/irccd/mod-system.cpp lib/irccd/mod-system.hpp lib/irccd/mod-timer.cpp lib/irccd/mod-timer.hpp lib/irccd/mod-unicode.cpp lib/irccd/mod-unicode.hpp lib/irccd/mod-util.cpp lib/irccd/mod-util.hpp lib/irccd/module.hpp lib/irccd/plugin-js.cpp tests/js-elapsedtimer/main.cpp tests/js-file/main.cpp tests/js-irccd/main.cpp tests/js-logger/main.cpp tests/js-system/main.cpp tests/js-unicode/main.cpp tests/js-util/main.cpp
diffstat 31 files changed, 186 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/lib/irccd/mod-directory.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-directory.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -369,21 +369,21 @@
 {
 }
 
-void DirectoryModule::load(Irccd &, JsPlugin &plugin)
+void DirectoryModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_c_function(plugin.context(), constructor, 2);
-	duk_put_number_list(plugin.context(), -1, constants);
-	duk_put_function_list(plugin.context(), -1, functions);
-	dukx_push_std_string(plugin.context(), std::string{fs::separator()});
-	duk_put_prop_string(plugin.context(), -2, "separator");
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, methods);
-	duk_put_prop_string(plugin.context(), -2, "prototype");
-	duk_put_prop_string(plugin.context(), -2, "Directory");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_c_function(plugin->context(), constructor, 2);
+	duk_put_number_list(plugin->context(), -1, constants);
+	duk_put_function_list(plugin->context(), -1, functions);
+	dukx_push_std_string(plugin->context(), std::string{fs::separator()});
+	duk_put_prop_string(plugin->context(), -2, "separator");
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, methods);
+	duk_put_prop_string(plugin->context(), -2, "prototype");
+	duk_put_prop_string(plugin->context(), -2, "Directory");
+	duk_pop(plugin->context());
 }
 
 } // !irccd
--- a/lib/irccd/mod-directory.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-directory.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -44,7 +44,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/mod-elapsed-timer.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-elapsed-timer.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -143,19 +143,19 @@
 {
 }
 
-void ElapsedTimerModule::load(Irccd &, JsPlugin &plugin)
+void ElapsedTimerModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_c_function(plugin.context(), constructor, 0);
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, methods);
-	duk_push_c_function(plugin.context(), destructor, 1);
-	duk_set_finalizer(plugin.context(), -2);
-	duk_put_prop_string(plugin.context(), -2, "prototype");
-	duk_put_prop_string(plugin.context(), -2, "ElapsedTimer");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_c_function(plugin->context(), constructor, 0);
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, methods);
+	duk_push_c_function(plugin->context(), destructor, 1);
+	duk_set_finalizer(plugin->context(), -2);
+	duk_put_prop_string(plugin->context(), -2, "prototype");
+	duk_put_prop_string(plugin->context(), -2, "ElapsedTimer");
+	duk_pop(plugin->context());
 }
 
 } // !irccd
--- a/lib/irccd/mod-elapsed-timer.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-elapsed-timer.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -42,7 +42,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/mod-file.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-file.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -634,23 +634,23 @@
 {
 }
 
-void FileModule::load(Irccd &, JsPlugin &plugin)
+void FileModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_c_function(plugin.context(), constructor, 2);
-	duk_put_number_list(plugin.context(), -1, constants);
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, methods);
-	duk_push_c_function(plugin.context(), destructor, 1);
-	duk_set_finalizer(plugin.context(), -2);
-	duk_dup(plugin.context(), -1);
-	duk_put_global_string(plugin.context(), Prototype);
-	duk_put_prop_string(plugin.context(), -2, "prototype");
-	duk_put_prop_string(plugin.context(), -2, "File");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_c_function(plugin->context(), constructor, 2);
+	duk_put_number_list(plugin->context(), -1, constants);
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, methods);
+	duk_push_c_function(plugin->context(), destructor, 1);
+	duk_set_finalizer(plugin->context(), -2);
+	duk_dup(plugin->context(), -1);
+	duk_put_global_string(plugin->context(), Prototype);
+	duk_put_prop_string(plugin->context(), -2, "prototype");
+	duk_put_prop_string(plugin->context(), -2, "File");
+	duk_pop(plugin->context());
 }
 
 void dukx_new_file(duk_context *ctx, File *fp)
--- a/lib/irccd/mod-file.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-file.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -150,7 +150,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 /**
--- a/lib/irccd/mod-irccd.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-irccd.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -70,39 +70,39 @@
 {
 }
 
-void IrccdModule::load(Irccd &irccd, JsPlugin &plugin)
+void IrccdModule::load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
 	// Irccd.
-	duk_push_object(plugin.context());
+	duk_push_object(plugin->context());
 
 	// Version.
-	duk_push_object(plugin.context());
-	duk_push_int(plugin.context(), IRCCD_VERSION_MAJOR);
-	duk_put_prop_string(plugin.context(), -2, "major");
-	duk_push_int(plugin.context(), IRCCD_VERSION_MINOR);
-	duk_put_prop_string(plugin.context(), -2, "minor");
-	duk_push_int(plugin.context(), IRCCD_VERSION_PATCH);
-	duk_put_prop_string(plugin.context(), -2, "patch");
-	duk_put_prop_string(plugin.context(), -2, "version");
+	duk_push_object(plugin->context());
+	duk_push_int(plugin->context(), IRCCD_VERSION_MAJOR);
+	duk_put_prop_string(plugin->context(), -2, "major");
+	duk_push_int(plugin->context(), IRCCD_VERSION_MINOR);
+	duk_put_prop_string(plugin->context(), -2, "minor");
+	duk_push_int(plugin->context(), IRCCD_VERSION_PATCH);
+	duk_put_prop_string(plugin->context(), -2, "patch");
+	duk_put_prop_string(plugin->context(), -2, "version");
 
 	// Create the SystemError that inherits from Error.
-	duk_push_c_function(plugin.context(), constructor, 2);
-	duk_push_object(plugin.context());
-	duk_get_global_string(plugin.context(), "Error");
-	duk_get_prop_string(plugin.context(), -1, "prototype");
-	duk_remove(plugin.context(), -2);
-	duk_set_prototype(plugin.context(), -2);
-	duk_put_prop_string(plugin.context(), -2, "prototype");
-	duk_put_prop_string(plugin.context(), -2, "SystemError");
+	duk_push_c_function(plugin->context(), constructor, 2);
+	duk_push_object(plugin->context());
+	duk_get_global_string(plugin->context(), "Error");
+	duk_get_prop_string(plugin->context(), -1, "prototype");
+	duk_remove(plugin->context(), -2);
+	duk_set_prototype(plugin->context(), -2);
+	duk_put_prop_string(plugin->context(), -2, "prototype");
+	duk_put_prop_string(plugin->context(), -2, "SystemError");
 
 	// Set Irccd as global.
-	duk_put_global_string(plugin.context(), "Irccd");
+	duk_put_global_string(plugin->context(), "Irccd");
 
 	// Store global instance.
-	duk_push_pointer(plugin.context(), &irccd);
-	duk_put_global_string(plugin.context(), "\xff""\xff""irccd-ref");
+	duk_push_pointer(plugin->context(), &irccd);
+	duk_put_global_string(plugin->context(), "\xff""\xff""irccd-ref");
 }
 
 Irccd &duk_get_irccd(duk_context *ctx)
--- a/lib/irccd/mod-irccd.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-irccd.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -79,7 +79,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 /**
--- a/lib/irccd/mod-logger.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-logger.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -88,15 +88,15 @@
 {
 }
 
-void LoggerModule::load(Irccd &, JsPlugin &plugin)
+void LoggerModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_put_prop_string(plugin.context(), -2, "Logger");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_put_prop_string(plugin->context(), -2, "Logger");
+	duk_pop(plugin->context());
 }
 
 } // !irccd
--- a/lib/irccd/mod-logger.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-logger.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -42,7 +42,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/mod-plugin.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-plugin.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -188,21 +188,33 @@
 {
 }
 
-void PluginModule::load(Irccd &, JsPlugin &plugin)
+void PluginModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_push_pointer(plugin.context(), &plugin);
-	duk_put_global_string(plugin.context(), PluginGlobal);
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_push_object(plugin.context());
-	duk_put_prop_string(plugin.context(), -2, "config");
-	duk_push_object(plugin.context());
-	duk_put_prop_string(plugin.context(), -2, "format");
-	duk_put_prop_string(plugin.context(), -2, "Plugin");
-	duk_pop(plugin.context());
+	duk_push_pointer(plugin->context(), new std::shared_ptr<JsPlugin>(plugin));
+	duk_put_global_string(plugin->context(), PluginGlobal);
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_push_object(plugin->context());
+	duk_put_prop_string(plugin->context(), -2, "config");
+	duk_push_object(plugin->context());
+	duk_put_prop_string(plugin->context(), -2, "format");
+	duk_put_prop_string(plugin->context(), -2, "Plugin");
+	duk_pop(plugin->context());
+}
+
+void PluginModule::unload(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
+{
+	StackAssert sa(plugin->context());
+
+	duk_push_global_object(plugin->context());
+	duk_get_prop_string(plugin->context(), -1, PluginGlobal);
+	delete static_cast<std::shared_ptr<JsPlugin> *>(duk_to_pointer(plugin->context(), -1));
+	duk_pop(plugin->context());
+	duk_del_prop_string(plugin->context(), -1, PluginGlobal);
+	duk_pop(plugin->context());
 }
 
 std::shared_ptr<JsPlugin> duk_get_plugin(duk_context *ctx)
@@ -210,10 +222,10 @@
 	StackAssert sa(ctx);
 
 	duk_get_global_string(ctx, PluginGlobal);
-	auto plugin = std::static_pointer_cast<JsPlugin>(static_cast<JsPlugin *>(duk_to_pointer(ctx, -1))->shared_from_this());
+	auto plugin = static_cast<std::shared_ptr<JsPlugin> *>(duk_to_pointer(ctx, -1));
 	duk_pop(ctx);
 
-	return plugin;
+	return *plugin;
 }
 
 } // !irccd
--- a/lib/irccd/mod-plugin.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-plugin.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -43,7 +43,12 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
+
+	/**
+	 * \copydoc Module::unload
+	 */
+	IRCCD_EXPORT void unload(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 /**
--- a/lib/irccd/mod-server.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-server.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -266,7 +266,7 @@
  */
 duk_ret_t join(duk_context *ctx)
 {
-	self(ctx)->join(duk_require_string(ctx, 0), duk_get_string(ctx, 1));
+	self(ctx)->join(duk_require_string(ctx, 0), dukx_get_std_string(ctx, 1));
 
 	return 0;
 }
@@ -284,7 +284,7 @@
  */
 duk_ret_t kick(duk_context *ctx)
 {
-	self(ctx)->kick(duk_require_string(ctx, 0), duk_require_string(ctx, 1), duk_get_string(ctx, 2));
+	self(ctx)->kick(duk_require_string(ctx, 0), duk_require_string(ctx, 1), dukx_get_std_string(ctx, 2));
 
 	return 0;
 }
@@ -400,7 +400,7 @@
  */
 duk_ret_t part(duk_context *ctx)
 {
-	self(ctx)->part(duk_require_string(ctx, 0), duk_get_string(ctx, 1));
+	self(ctx)->part(duk_require_string(ctx, 0), dukx_get_std_string(ctx, 1));
 
 	return 0;
 }
@@ -639,22 +639,22 @@
 {
 }
 
-void ServerModule::load(Irccd &, JsPlugin &plugin)
+void ServerModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_c_function(plugin.context(), constructor, 1);
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, methods);
-	duk_push_c_function(plugin.context(), destructor, 1);
-	duk_set_finalizer(plugin.context(), -2);
-	duk_dup_top(plugin.context());
-	duk_put_global_string(plugin.context(), Prototype);
-	duk_put_prop_string(plugin.context(), -2, "prototype");
-	duk_put_prop_string(plugin.context(), -2, "Server");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_c_function(plugin->context(), constructor, 1);
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, methods);
+	duk_push_c_function(plugin->context(), destructor, 1);
+	duk_set_finalizer(plugin->context(), -2);
+	duk_dup_top(plugin->context());
+	duk_put_global_string(plugin->context(), Prototype);
+	duk_put_prop_string(plugin->context(), -2, "prototype");
+	duk_put_prop_string(plugin->context(), -2, "Server");
+	duk_pop(plugin->context());
 }
 
 void duk_push_server(duk_context *ctx, std::shared_ptr<Server> server)
--- a/lib/irccd/mod-server.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-server.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -44,7 +44,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 /**
--- a/lib/irccd/mod-system.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-system.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -49,7 +49,7 @@
  */
 duk_ret_t env(duk_context *ctx)
 {
-	dukx_push_std_string(ctx, sys::env(duk_get_string(ctx, 0)));
+	dukx_push_std_string(ctx, sys::env(dukx_get_std_string(ctx, 0)));
 
 	return 1;
 }
@@ -229,15 +229,15 @@
 {
 }
 
-void SystemModule::load(Irccd &, JsPlugin &plugin)
+void SystemModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_put_prop_string(plugin.context(), -2, "System");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_put_prop_string(plugin->context(), -2, "System");
+	duk_pop(plugin->context());
 }
 
 } // !irccd
--- a/lib/irccd/mod-system.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-system.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -42,7 +42,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/mod-timer.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-timer.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -190,20 +190,20 @@
 {
 }
 
-void TimerModule::load(Irccd &, JsPlugin &plugin)
+void TimerModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_c_function(plugin.context(), constructor, 3);
-	duk_put_number_list(plugin.context(), -1, constants);
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, methods);
-	duk_put_prop_string(plugin.context(), -2, "prototype");
-	duk_put_prop_string(plugin.context(), -2, "Timer");
-	duk_pop(plugin.context());
-	duk_push_object(plugin.context());
-	duk_put_global_string(plugin.context(), CallbackTable);
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_c_function(plugin->context(), constructor, 3);
+	duk_put_number_list(plugin->context(), -1, constants);
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, methods);
+	duk_put_prop_string(plugin->context(), -2, "prototype");
+	duk_put_prop_string(plugin->context(), -2, "Timer");
+	duk_pop(plugin->context());
+	duk_push_object(plugin->context());
+	duk_put_global_string(plugin->context(), CallbackTable);
 }
 
 } // !irccd
--- a/lib/irccd/mod-timer.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-timer.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -42,7 +42,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/mod-unicode.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-unicode.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -138,15 +138,15 @@
 {
 }
 
-void UnicodeModule::load(Irccd &, JsPlugin &plugin)
+void UnicodeModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_put_prop_string(plugin.context(), -2, "Unicode");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_put_prop_string(plugin->context(), -2, "Unicode");
+	duk_pop(plugin->context());
 }
 
 } // !irccd
--- a/lib/irccd/mod-unicode.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-unicode.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -42,7 +42,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/mod-util.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-util.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -48,7 +48,7 @@
 		if (dukx_get_std_string(ctx, -2) == "date")
 			params.time = static_cast<time_t>(duk_get_number(ctx, -1) / 1000);
 		else
-			params.keywords.insert({duk_get_string(ctx, -2), duk_get_string(ctx, -1)});
+			params.keywords.insert({dukx_get_std_string(ctx, -2), dukx_get_std_string(ctx, -1)});
 	});
 
 	return params;
@@ -135,15 +135,15 @@
 {
 }
 
-void UtilModule::load(Irccd &, JsPlugin &plugin)
+void UtilModule::load(Irccd &, const std::shared_ptr<JsPlugin> &plugin)
 {
-	StackAssert sa(plugin.context());
+	StackAssert sa(plugin->context());
 
-	duk_get_global_string(plugin.context(), "Irccd");
-	duk_push_object(plugin.context());
-	duk_put_function_list(plugin.context(), -1, functions);
-	duk_put_prop_string(plugin.context(), -2, "Util");
-	duk_pop(plugin.context());
+	duk_get_global_string(plugin->context(), "Irccd");
+	duk_push_object(plugin->context());
+	duk_put_function_list(plugin->context(), -1, functions);
+	duk_put_prop_string(plugin->context(), -2, "Util");
+	duk_pop(plugin->context());
 }
 
 } // !irccd
--- a/lib/irccd/mod-util.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/mod-util.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -42,7 +42,7 @@
 	/**
 	 * \copydoc Module::load
 	 */
-	IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override;
+	IRCCD_EXPORT void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin) override;
 };
 
 } // !irccd
--- a/lib/irccd/module.hpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/module.hpp	Tue Jun 07 20:49:47 2016 +0200
@@ -30,6 +30,7 @@
  */
 
 #include <cassert>
+#include <memory>
 
 #include "sysconfig.hpp"
 #include "util.hpp"
@@ -79,7 +80,7 @@
 	 * \param irccd the irccd instance
 	 * \param plugin the plugin
 	 */
-	virtual void load(Irccd &irccd, JsPlugin &plugin)
+	virtual void load(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin)
 	{
 		util::unused(irccd, plugin);
 	}
@@ -90,7 +91,7 @@
 	 * \param irccd the irccd instance
 	 * \param plugin the plugin
 	 */
-	virtual void unload(Irccd &irccd, JsPlugin &plugin)
+	virtual void unload(Irccd &irccd, const std::shared_ptr<JsPlugin> &plugin)
 	{
 		util::unused(irccd, plugin);
 	}
--- a/lib/irccd/plugin-js.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/lib/irccd/plugin-js.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -54,8 +54,10 @@
 
 void JsPlugin::putModules(Irccd &irccd)
 {
+	m_modules = irccd.moduleService().modules();
+
 	for (const auto &module : irccd.moduleService().modules())
-		module->load(irccd, *this);
+		module->load(irccd, std::static_pointer_cast<JsPlugin>(shared_from_this()));
 }
 
 void JsPlugin::putVars()
@@ -434,8 +436,8 @@
 
 	call("onUnload");
 
-	for (const auto &module : irccd.moduleService().modules())
-		module->unload(irccd, *this);
+	for (const auto &module : m_modules)
+		module->unload(irccd, std::static_pointer_cast<JsPlugin>(shared_from_this()));
 }
 
 void JsPlugin::onWhois(Irccd &, const std::shared_ptr<Server> &server, const ServerWhois &whois)
--- a/tests/js-elapsedtimer/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-elapsedtimer/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -37,8 +37,8 @@
 	TestElapsedTimer()
 		: m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.ElapsedTimer")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.ElapsedTimer")->load(m_irccd, m_plugin);
 	}
 };
 
--- a/tests/js-file/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-file/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -36,8 +36,8 @@
 	TestJsFile()
 		: m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.File")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.File")->load(m_irccd, m_plugin);
 	}
 };
 
--- a/tests/js-irccd/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-irccd/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -34,7 +34,7 @@
 	TestJsIrccd()
 		: m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
 	}
 };
 
--- a/tests/js-logger/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-logger/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -62,9 +62,9 @@
 	TestJsLogger()
 		: m_plugin(std::make_shared<JsPlugin>("test", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.Plugin")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.Logger")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.Plugin")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.Logger")->load(m_irccd, m_plugin);
 	}
 };
 
--- a/tests/js-system/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-system/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -36,9 +36,9 @@
 	TestJsSystem()
 		: m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.File")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.System")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.File")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.System")->load(m_irccd, m_plugin);
 	}
 };
 
--- a/tests/js-unicode/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-unicode/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -39,8 +39,8 @@
 	TestJsUnicode()
 		: m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.Unicode")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.Unicode")->load(m_irccd, m_plugin);
 	}
 };
 
--- a/tests/js-util/main.cpp	Tue Jun 07 14:19:27 2016 +0200
+++ b/tests/js-util/main.cpp	Tue Jun 07 20:49:47 2016 +0200
@@ -35,8 +35,8 @@
 	TestJsUtil()
 		: m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js"))
 	{
-		m_irccd.moduleService().get("Irccd")->load(m_irccd, *m_plugin);
-		m_irccd.moduleService().get("Irccd.Util")->load(m_irccd, *m_plugin);
+		m_irccd.moduleService().get("Irccd")->load(m_irccd, m_plugin);
+		m_irccd.moduleService().get("Irccd.Util")->load(m_irccd, m_plugin);
 	}
 };