Browse Source

Drafting conventions for C modules and DLLs

weak-references
Sami Vaarala 10 years ago
parent
commit
ccfbff9dbb
  1. 114
      doc/c-module-convention.rst
  2. 29
      doc/modules.rst

114
doc/c-module-convention.rst

@ -0,0 +1,114 @@
===========================
Duktape C module convention
===========================
Overview
========
This document provides a recommended convention for writing an init function
for a C module. The convention allows a module to be initialized manually
when using static linking, or as part of loading the module from a DLL.
Modules can be initialized either as part of CommonJS module loading or
outside of it.
The convention is in no way mandatory and it's perfectly fine to use different
module loader conventions. However, modules following this convention will be
easier to share between projects.
Module init function
====================
The init function for a module ``my_module`` should contain an initialization
function of the following form::
duk_ret_t dukopen_my_module(duk_context *ctx) {
/* Initialize module in whatever way is most appropriate.
* Called as a Duktape/C function.
*
* Push the module result (e.g. an object with methods) on
* top of the value stack and return 1 to indicate there's
* a return value. Temporary values can be left below the
* return value like in normal Duktape/C functions.
*/
duk_push_object(ctx); /* module result */
duk_put_function_list(ctx, -1, my_module_funcs);
duk_push_int(ctx, 42);
duk_put_prop_string(ctx, -2, "meaningOfLife");
return 1; /* return module value */
}
The init function is called as a Duktape/C function. When initializing
the module manually, you should use::
duk_push_c_function(ctx, dukopen_my_module, 0 /*nargs*/);
duk_call(ctx, 0); /* or duk_pcall() if you want to catch errors */
/* Stack top contains module value */
A DLL loader should use the same convention to call the init function
after figuring out the init function name and locating it from the DLL
symbol table.
DLL name
========
When a C module is compiled into a DLL, the DLL filename should include
the module name (``my_module`` in the running example) with any platform
specific prefix and suffix. For example::
my_module.so # Linux
my_module.dll # Windows
A DLL loader should assume that the init function name is ``dukopen_``
followed by the module name part extracted from the DLL filename (here,
``dukopen_my_module()``).
Module name
===========
To avoid case conversion and special character issues, module names should
have the form::
[a-zA-Z_][0-9a-zA-Z_-]*
This should minimize platform issues.
Mixed Ecmascript / C modules
============================
When a module is being initialized by a CommonJS aware module loader, the
loader should support mixed modules containing both C and Ecmascript code.
For example::
my_module.so # C module
my_module.js # Ecmascript module (CommonJS)
Such a combined module should be loaded as follows:
* First load the C module normally, yielding a return value RET.
* If RET is an object, use it to initialize the CommonJS ``exports`` value
before loading the Ecmascript module. The Ecmascript module can then
use whatever symbols the C modules registered, and add further symbols to
the same exports value.
* If RET is not an object, ignore it and load the Ecmascript module normally.
**FIXME: at the moment the module loader cannot replace the ``exports``
value, so it needs copy symbols from RET into ``exports`` one by one.**
Limitations
===========
* This convention may not work on all platforms where Duktape itself ports to.
For instance, a platform might have no DLL support or have filename
restrictions that don't allow DLLs to be named as specified above.
* The convention is not "CommonJS native": a C module doesn't get an exports
table and cannot load sub-modules (at least relative to its own CommonJS
identifier). This is intentional to keep the C module convention as simple
as possible.

29
doc/modules.rst

@ -19,8 +19,10 @@ built into Duktape:
module search function. module search function.
* C modules, static or DLL-based, can be implemented on top of the module * C modules, static or DLL-based, can be implemented on top of the module
search function by user code. Because DLL handling is inherently search function by user code. There is no built-in C module support in
unportable, there is no built-in DLL support at the moment. the main Duktape library to avoid portability issues for exotic platforms.
However, there is a recommended convention which works on most platforms
and allows both static and DLL loading, see ``c-module-convention.rst``.
Using modules from Ecmascript code (require) Using modules from Ecmascript code (require)
============================================ ============================================
@ -214,6 +216,21 @@ Duktape doesn't currently support assignment to ``module.exports``.
C modules and DLLs C modules and DLLs
================== ==================
Recommended convention
----------------------
``c-module-convention.rst`` describes a recommended convention for defining
an init function for a C module. The convention allows a C module to be
initialized manually when using static linking, or as part of loading the
module from a DLL.
The recommendation is in no way mandatory and you can easily write a module
loader with your own conventions (see below). However, modules following
the recommended convention will be easier to share between projects.
Implementing a C module / DLL loader
------------------------------------
The user provided module search function can be used to implement DLL support. The user provided module search function can be used to implement DLL support.
Simply load the DLL based on the module identifier, and call some kind of init Simply load the DLL based on the module identifier, and call some kind of init
function in the DLL to register module symbols into the 'exports' table given function in the DLL to register module symbols into the 'exports' table given
@ -235,10 +252,6 @@ Limitations:
(e.g. through a finalizer) is **not** enough because other modules can (e.g. through a finalizer) is **not** enough because other modules can
copy references to individual exported values. copy references to individual exported values.
.. note:: At the moment there are no recommended conventions for DLLs or
what a module initialization function should look like. These
conventions will be provided in a future version. See future work.
Background Background
========== ==========
@ -355,10 +368,6 @@ Several ideas to improve the C module support:
* Provide a default DLL loading helper for at least POSIX and Windows. * Provide a default DLL loading helper for at least POSIX and Windows.
* Provide suggested module initialization conventions that work both with
static linking and DLLs, and allow Duktape modules to be more easily
exchanged between projects.
Module unloading support Module unloading support
------------------------ ------------------------

Loading…
Cancel
Save