NAME
Inline::SLang::Details - How Inline::SLang works
DESCRIPTION
This document is intended to provide details of how Inline::SLang weaves its magic. It's probably going to be most use in cases when you find apparently bizarre behaviour and wonder if it is a bug or a feature.
The implementation for Inline::SLang was initally based on the code found in Neil Watkiss' Inline::Python and Inline::Ruby modules. However, all bugs are my own creation.
What happens when Perl starts?
If the Perl code has not been evaluated before - or if it has been changed since the previous run - the Inline code kicks in to evaluate the S-Lang code. This involves:
The S-Lang interpreter is started and queried to find out all functions that are defined in the namespaces listed in the
BIND_NS
configuration option. The user-supplied S-Lang code is then evaluated and the same set of namespaces are again queried for the names of defined functions. We also pick up any new namespaces that may have been defined if theBIND_NS
option is set toAll
.The names of the new functions - i.e. those functions added by the user-supplied S-Lang code which the S-Lang function
_apropos()
lists when the flag value is set to 3 - are stored for later use.Complications:
The
_inline
namespace is ignored since this is used by the module and should be considered off-limits.The list of functions in
bind_slfuncs
is added to the list of functions to bind. This list can include functions defined as part of the S-Lang Run-Time Library.The fact that the module allows users to change the name that namespaces and (some) functions have when mapped to Perl.
The list of defined S-Lang data types is found. This includes user-defined types added by any imported modules and "named" structures created via a S-Lang
typedef
statement.Utility functions are created in Perl in the
Inline::SLang
package which are wrappers around calls to theDataType_Type
constructor. This allows users to sayInline::SLang::UShort_Type()
rather thanDataType_Type->new("UShort_Type")
.For those types we do not recognise - essentially all user-defined types - we create objects with names equal to the S-Lang variable name. The objects have very few methods, and are just a way of carrying around a reference to the S-Lang variable within Perl. The S-Lang variable is saved in an associative array within the
_inline
namespace, to ensure that it is not destroyed, and this is used when the Perl variable is sent to a S-Lang function. The "native" S-Lang types included in this list are:Any_Type
,Ref_Type
,BString_Type
,File_Type
, andFD_Type
. It would be useful if we could handle these directly, but it is not easy (for instance I believe it would be hard to use the file handles withPerlIO
code sincePerlIO
makes assumptions about who has opened the file).The conversion between S-Lang and PDL types - e.g. what type of piddle should an
Int_Type
array be converted to - has only been tested on 32-bit machines. It may well fail on 64 bit machines.The information - including the S-Lang source code - is written to a configuration file by Inline. The default location for the file is within the _Inline/ directory, but this can be changed, as discussed in the Inline documentation.
If the code has previously been run then this information can just be read from the configuration file. The information - whether read from file or calculated directly - is used to:
Set up the bindings between Perl and S-Lang functions.
Set up the Perl classes to handle the various datatypes that can not be processed natively within Perl.
Set up the functions and variables in the
_inline
namespace (these should never be accessed by user code).
Once the S-Lang code has been processed the Perl code is run.
CALLING A S-LANG FUNCTION
For each S-Lang function we want to bind to Perl, a small Perl subroutine is created which pushes the S-Lang function name (including any necessary namespace) onto the start of the stack and then calls the Inline::SLang::sl_call_function()
subroutine (which is defined in Slang.xs and should never be called directly). By including the S-Lang function name on the stack we allow the Perl and S-Lang names to be different, as required by the BIND_SLFUNCS
and BIND_NS
configuration options.
The sl_call_function()
routine performs 4 operations:
The S-Lang interpreter is checked to see if the routine is defined (this step could be removed).
The remaining items on the Perl stack (the arguments to the function) are converted to S-Lang variables and pushed onto the S-Lang stack. The conversion from Perl to S-Lang types is done by the
pl2sl()
routine which is defined in pl2sl.c.The S-Lang function is called. The S-Lang error hook is used to catch any errors that the S-Lang interpreter may throw; these are converted to Perl errors by calling the
croak()
function so that they can be trapped by Perl'seval()
routine.The S-Lang stack is examined and any variables returned by the function are popped off, converted to Perl variables, and pushed onto the Perl stack. The order of the S-Lang stack is reversed when creating the Perl stack so that the S-Lang statement
( x, y ) = some_func();
can be converted to
( my $x, my $y ) = some_func();
The conversion from S-Lang to Perl types is done by the
sl2pl()
routine which is defined in sl2pl.c.
The major part of the whole module is the conversion between Perl and S-Lang variables, namely the pl2sl()
and sl2pl()
routines. The routines are not pretty - they could be re-written to allow additional convertors to be "plugged in" - but they seem to work.
NOTES
How to find out what S-Lang functions and datatypes are recognised
The info
option of Inline can be used to find out what functions and data types are bound to Perl. If the code is stored in the file script.pl, use
perl -MInline=info script.pl
Further details are available in the Inline::SLang::Config documentation.
Execution of S-Lang code
The S-Lang code is executed before any Perl code. This can be seen in the following example (available as examples/order.pl in the source distribution):
use Inline 'SLang' => 'message("This is S-Lang");';
print "This is Perl\n";
When run, the script displays:
This is S-Lang
This is Perl
Exporting symbols
The system used to bind functions to Perl - in particular to make the symbols available to Perl - is a "simplified" version of the Exporter Perl module (since I have been unable to successfully use Exporter directly).