*** /dev/null Sat Nov 23 08:52:11 2024
--- - Sat Nov 23 08:52:27 2024
***************
*** 0 ****
--- 1,345 ----
+ <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+ <html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Vladimir Livshits">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
+ <title>PerlConnect Documentation</title>
+ <style>
+ A:link {text-decoration: none}
+ A:visited {text-decoration: none}
+ </style>
+ </head>
+ <body background="bg.jpg">
+
+ <center>
+ <h3>
+ P<font size=-1>ERL</font>C<font size=-1>ONNECT AND </font>JS<font size=+0>.PM</font></h3></center>
+
+ <center>U<font size=-1>SER-LEVEL </font><font size=+1>D</font><font size=-1>OCUMENTATION</font>
+ <br><a href="mailto:livshits@cs.stanford.edu">Vladimir Livshits</a>
+ <br>
+ <hr SIZE=1 NOSHADE WIDTH="100%"></center>
+
+ <ol>
+ <li>
+ <a href="#History">Update history</a></li>
+
+ <li>
+ <a href="#Overview">Overview</a></li>
+
+ <li>
+ <a href="#Features">Features</a></li>
+
+ <li>
+ <a href="#Design">Design</a></li>
+
+ <li>
+ <a href="#Installation">Installation</a></li>
+
+ <li>
+ <a href="#Limitations">Current Limitations and Further Work</a></li>
+ </ol>
+
+ <h4>
+ <a NAME="History"></a>Update History</h4>
+
+ <ul>
+ <li>
+ 3/8/99 -- added some more details, especially pertaining to <tt>PerlConnect.pm</tt></li>
+
+ <li>
+ 8/98 -- this document created</li>
+ </ul>
+
+ <h4>
+ <a NAME="Overview"></a>Overview</h4>
+ PerlConnect provides glue for the developer between JavaScript and Perl.
+ It currently consists of two parts, PerlConnect implemented in C and JS.pm,
+ a Perl module written using XSUBs. PerlConnect and JS.pm allow calling
+ Perl from JS and JS from Perl, respectively. Whenever possible, it is attempted
+ to achieve the maximum level of transparency for calling one language
+ from the other. This is done by converting values between the two languages,
+ creating wrappers around objects, and emulating the standard language syntax.
+ <h4>
+ <a NAME="Features"></a>PerlConnect Features</h4>
+ PerlConnect allows running a Perl interpreter concurrently with your JavaScript
+ embedding and executing Perl commands from JavaScript. You usually need
+ to create a Perl interpreter by doing something like this:
+ <blockquote><tt>p = new Perl('Sys::Hostname', 'Test::Harness')</tt></blockquote>
+ In addition to creating an interpreter, this will also include the libraries
+ you pass to the Perl constructor, which is equivalent to <tt>use Sys::Hostname;
+ use Test::Harness</tt>. You can always include libraries explicitly by
+ using <tt>p.eval('use Sys::Hostname; use Test::Harness')</tt>. There is
+ also another way to do this: <tt>p.use('Sys::Hostname', 'Test::Harness')</tt>.
+ As you can see, TMTOWTDI.
+ <p><b>Note: </b>If the statements above fail on you saying something about
+ libraries not found in the search path, you need to make sure the modules
+ PerlConnect uses, JS.pm and PerlConnect.pm live in some directory accessible
+ from the search path. Search path can be set by adjusting the value of PERLLIB
+ and PERL5LIB environment variables. See <a href="#Installation">installation</a>
+ for more details.
+ <p><b>Note: </b>Despite the illusion p = new Perl(...) syntax might create,
+ there is actually only one version of the Perl interpreter running. I.e.
+ if you create two interpreters like this:
+ <blockquote><tt>p = new Perl; q = new Perl;</tt>
+ <br><tt>p.eval("$a='ha-'x20");</tt></blockquote>
+ Now you'll see that <tt>q["$a"]</tt> will give you <tt>$a</tt>'s value
+ from <tt>p</tt>.
+ <p>Naturally, you will want to look at the result of your function calls
+ and <tt>eval</tt> statements. Suppose, you do something like this:
+ <blockquote><tt>line = p.eval("'-' x 80")</tt></blockquote>
+ Perl's eval returns the last statement evaluated, unless you explicitly
+ say <tt>return</tt>. So now <tt>line</tt> contains 80 dashes. You can do
+ similar things with non-scalar data types:
+ <blockquote><tt>p.use('Time::gmtime');</tt>
+ <br><tt>t = p.eval('Time::gmtime::gmtime') // returns
+ [49,0,4,24,6,98,5,204,0]</tt></blockquote>
+ assigns a Perl array to <tt>t</tt>. You can print <tt>t</tt>, use the <tt>for/in</tt>
+ syntax to walk through it, compute its length, etc. You can read and assign
+ to individual elements using the standard syntax. However, PerlValues,
+ that is, the value we get from Perl, don't support all the standard operations,
+ for instance, don't expect <tt>t.reverse()</tt> to work. Hashes can also
+ be returned from Perl:
+ <blockquote><tt>info=p.eval("{ver=>$], pid=>$$}")</tt></blockquote>
+ Now you can look at individual hash keys like this:
+ <blockquote><tt>info["ver"]</tt> or <tt>info.pid</tt></blockquote>
+ Suppose you want to use Perl to perform pattern-based string replacement.
+ Here's how you can do it from JavaScript:
+ <blockquote><tt>p.eval("\</tt>
+ <br><tt> sub perl_replace(){\</tt>
+ <br><tt> my($string, $find, $replace)
+ = @_;\</tt>
+ <br><tt> eval(\"\\$string =~
+ s/$find/$replace/g;\");\</tt>
+ <br><tt> return $string;\</tt>
+ <br><tt> }"</tt>
+ <br><tt>);</tt></blockquote>
+ and now
+ <blockquote><tt>p.perl_replace('Quick brown fox jumped over a lazy dog',
+ 'dog', 'rhino')</tt></blockquote>
+ produces what you'd expect.
+ <p>You can use the same syntax to call procedures defined in modules other
+ than<tt> main. </tt>The example with<tt> gmtime </tt>can be rewritten like
+ this:
+ <blockquote><tt>p.use('Time::gmtime');</tt>
+ <br><tt>t = p.Time.gmtime.gmtime() // returns [49,0,4,24,6,98,5,204,0]</tt></blockquote>
+ You can reference variables exported by modules other than <tt>main</tt>
+ like this:
+ <blockquote><tt>a=p.Foo.$bar </tt>or<tt> a=p.Foo["$bar"] </tt>or
+ <br><tt>a=p.Foo["@bar"]</tt>or<tt> a=p.Foo["%bar"]</tt></blockquote>
+ Each of the above statements return either an immediate JS value, for
+ scalar types, or a PerlValue for compound types. <tt>a.type </tt>contains
+ the type of the PerlValue in <tt>a</tt>. <i>This may change because we
+ may end up separating Perl hashes and arrays into separate classes.</i>
+ <h4>
+ JS.pm Features</h4>
+ <i>JS.pm is much less tested then PerlConnect.</i> You should be able to
+ do similar things from Perl. Just say
+ <blockquote><tt>use JS;</tt>
+ <br><tt>$js = <b>new</b> JS();</tt></blockquote>
+ and now you can do something like this:
+ <blockquote><tt>$js-><b>eval</b>(q/</tt>
+ <blockquote><tt>Object o = {};</tt>
+ <br><tt>o.a = 'p';</tt>
+ <br><tt>o.b = 'q';</tt>
+ <br><tt>return o;</tt></blockquote>
+ <tt>/);</tt></blockquote>
+ <b>Note:</b> Please see test.js and test.pl, test scripts that test and
+ demonstrate various features of PerlConnect and JS.pm, respectively. They
+ will help get you started.
+ <h4>
+ <a NAME="Design"></a>PerlConnect Design</h4>
+ PerlConnect is written in C. It uses both JavaScript and Perl APIs and
+ implements a mapping between the two. The following JavaScript objects
+ are implemented by PerlConnect:
+ <br>
+ <center><table BORDER COLS=2 WIDTH="80%" >
+ <tr ALIGN=CENTER BGCOLOR="#CCCCCC">
+ <td ALIGN=CENTER VALIGN=CENTER WIDTH="20%"><b>Object</b></td>
+
+ <td><b>What it does</b></td>
+ </tr>
+
+ <tr ALIGN=CENTER VALIGN=CENTER>
+ <td WIDTH="30"><tt>Perl</tt></td>
+
+ <td ALIGN=LEFT VALIGN=TOP>Perl Interpreter Object. Its prototype type
+ is PerlModule, it corresponds to <tt>main::</tt>. Supports <tt>eval</tt>,
+ <tt>call</tt>,
+ <tt>use</tt>.</td>
+ </tr>
+
+ <tr ALIGN=CENTER VALIGN=CENTER>
+ <td><tt>PerlModule</tt></td>
+
+ <td ALIGN=LEFT VALIGN=TOP>Implements JS-like syntax for Perl modules. Doesn't
+ export provide any methods. <tt>path</tt> property shows the name of the
+ Perl module the object represents.</td>
+ </tr>
+
+ <tr ALIGN=CENTER VALIGN=CENTER>
+ <td><tt>PerlValue</tt></td>
+
+ <td ALIGN=LEFT VALIGN=TOP>Represents a value returned from <tt>eval</tt>,
+ <tt>call</tt>,
+ or obtained by using the subscript notation (<tt>p.Foo["@bar"]</tt>). Its
+ Perl type is stored in the <tt>type</tt> property.</td>
+ </tr>
+ </table></center>
+
+ <p>See comments in the code, <tt>jsperl.c</tt> and <tt>JS.pm</tt> for more
+ info.
+ <br><b>Note: </b> PerlConnect heavily relies on PerlConnect.pm, which
+ does some background magic for it. PerlConnect.pm should <i>not</i> be
+ <tt>use</tt>d. Use JS.pm instead.
+ <h4>
+ JS.pm Design</h4>
+ JSConnect is written using XSUBs, the language in which Perl extensions
+ are implemented. See the output of <tt>man perlxs/perlguts/perlembed/perlxstut</tt>
+ for more details. The source files are <tt>JS.xs</tt> and <tt>typemap</tt>.
+ After processing them using the XSUBs compiler, <tt>xsubpp</tt>, the resulting
+ C file should be compiled into a DLL. See <tt>JS.xs</tt> for more details
+ on how to to run the XSUBS compiler. You will need a sufficiently recent
+ version of Perl to run JS.pm successfully. <tt>JS.pm</tt> provides bootstrapping
+ mechanism to load this DLL.
+ <p>The following Perl packages (objects) are implemented:
+ <br>
+ <center><table BORDER COLS=2 WIDTH="80%" >
+ <tr ALIGN=CENTER BGCOLOR="#CCCCCC">
+ <td ALIGN=CENTER VALIGN=CENTER WIDTH="20%"><b>Package</b></td>
+
+ <td><b>What it contains</b></td>
+ </tr>
+
+ <tr ALIGN=CENTER VALIGN=CENTER>
+ <td><tt>JS</tt></td>
+
+ <td ALIGN=LEFT VALIGN=TOP>Doesn't do anything in particular at this
+ point except defining a constructor. So one can say <tt>$js = <b>new</b>
+ JS()</tt>, which will create a new runtime, add a context to it and return
+ that Context. JS also defines a bunch of private functions called from
+ C by PerlConnect. They are not exposed by default, but pushed onto <tt>@EXPORT_OK</tt>
+ array instead.</td>
+ </tr>
+
+ <tr ALIGN=CENTER VALIGN=CENTER>
+ <td><tt>JS::Runtime</tt></td>
+
+ <td ALIGN=LEFT VALIGN=TOP>Corresponds to <tt>JSRuntime*</tt> struct. Provides
+ a constructor and destructor. The destructor is invoked automatically,
+ so you don't have to worry about Runtime deallocation. Constructor syntax
+ is the following: <tt>$rt = <b>new</b> JS::Runtime(10_000)</tt>, where
+ the parameter is the same number you pass to <tt>JS_NewRuntime</tt>. There
+ are many private functions created in <tt>JS.xs</tt> that are not exported
+ by default.</td>
+ </tr>
+
+ <tr ALIGN=CENTER VALIGN=CENTER>
+ <td><tt>JS::Context</tt></td>
+
+ <td ALIGN=LEFT VALIGN=TOP>Corresponds to <tt>JSContext*</tt> struct. Provides
+ a constructor and destructor. The destructor is invoked automatically,
+ so you don't have to worry about Context deallocation. Constructor syntax
+ is the following: <tt>$rt = <b>new</b> JS::Context($rt, 1_000)</tt>, where
+ the parameter is the same number you pass to <tt>JS_NewContext</tt>. There
+ are many private functions created in <tt>JS.xs</tt> that are not exported
+ by default.</td>
+ </tr>
+
+ <tr>
+ <td ALIGN=CENTER><tt>JS::Object</tt></td>
+
+ <td>Corresponds to <tt>JSObject*</tt> struct. There is not that much here
+ yet. This object is intended as a wrapper around the <tt>JSObject* struct</tt>.
+ Support for tying hashes and possibly arrays with <tt>JS::Object</tt>s
+ is coming.</td>
+ </tr>
+
+ <tr>
+ <td ALIGN=CENTER><i><tt><font color="#000000">[JS::Array]</font></tt></i></td>
+
+ <td><i>I am not quite sure if this is needed. One might probably get away
+ with just <tt>JS::Object</tt> defined. If it's implemented, it will be
+ very much similar to <tt>JS::Object</tt> above.</i></td>
+ </tr>
+ </table></center>
+
+ <p>All the modules above follow the convention of storing the variable
+ they return in the <tt>$this</tt> variable of the current class. So <tt>$JS::Context::this</tt>
+ will always be the last context created. <i>Currently, this is where JS
+ API function that require contexts get it.</i>
+ <h4>
+ <a NAME="Installation"></a>PerlConnect Installation</h4>
+ PerlConnect requires <tt>js/src</tt> and the Perl libraries and headers.
+ The only <tt>js/src</tt> file that must be included in <tt>jsapi.h </tt>in
+ the top level directory. You need to compile it together with Perl libraries.
+ Refer to the <tt>perlembed</tt> man page for more details.
+ <br><b>On WINNT:</b>
+ <br>There are MSDEV Workspace and project files in the main PerlConnect
+ directory. There are three projects included in the PerlConnect workspace:
+ JS, PerlConnect and PerlConnectShell. You can use the latter to test PerlConnect.
+ You will probably need to adjust the library and include paths. Set PERL_SRC
+ environment variable to point to the directory where you unpacked and compiled
+ Perl sources. It is assumed that the directory structure is more or less
+ fixed, that is, you have PerlConnect in
+ <tt>js/src/perlconnect</tt>. PerlConnect
+ project produces <tt>PerlConnect.dll</tt>, you should make sure it and
+ <tt>perl.dll</tt> are in your path for PerlConnectShell to work.
+ <p>JS also builds a DLL, <tt>JS.dll</tt> which is supposed to reside where
+ Perl's DynaLoader can find it. On my machine I put it under <tt>c:\perl\lib\auto\JS\JS.dll</tt>.
+ You can also put it in <tt>c:\perl\lib\</tt>. You can probably adjust PERLLIB
+ to achieve the desired result. See Perl's DynaLoader documentation for
+ more info on how dynamic libraries are found.
+ <p><b>On UNIX:</b>
+ <br>We are currently working on a UNIX makefile. Please <a href="mailto:livshits@cs.stanford.edu">contact
+ me</a> for more details.
+ <h4>
+ On the MAC:</h4>
+ We never really thought of supporting the Mac. If anyone is really interested
+ in seeing Mac support, <a href="mailto:livshits@cs.stanford.edu">drop me a line</a>.
+ <h4>
+ <a NAME="Limitations"></a>Current Limitations and Further Work</h4>
+
+ <ol>
+ <li>
+ Perl variables currently can't be assigned to, that is, <tt>p["$a"]=100</tt>
+ doesn't do anything.</li>
+
+ <li>
+ You can only have one interpreter running at a time. Despite the fact that
+ you can create multiple Perl objects on JavaScript, they all share the
+ same namespace. We can probably use <tt>Safe.pm</tt> to implement independent
+ namespaces.</li>
+
+ <li>
+ Module name resolution reports an error only when you try to evaluate
+ the last element of the resolution chain. Here is what I mean: if you reference
+ <tt>p.Foo.Bar.Var</tt> and <tt>For</tt> or <tt>Bar</tt> don't exist, it
+ will only complain that p.Foo.Bar.Var is not a valid variable. Perl 5.005
+ provides <tt>exists Foo::{Bar::}</tt> to check if Foo::Bar is a valid package.</li>
+
+ <li>
+ Dynamic loading of the Perl interpreter only if it is required.</li>
+
+ <li>
+ Recursive printing of Perl's arrays and hashes can be added. See Data::Dumper.pm</li>
+
+ <li>
+ Full support for tied hashes and arrays in Perl</li>
+
+ <li>
+ Calling JavaScript functions and accessing variables from Perl. JavaScript
+ calling syntax support using AUTOLOADing.</li>
+
+ <li>
+ JS can be made a directory with <tt>Object.pm</tt>, <tt>Context.pm</tt>,
+ etc. in it. See how C or Tk are organized on CPAN</li>
+
+ <li>
+ Distribution model for JS.pm. Perl provides something by default. See <tt>h2xs</tt>
+ man page, for example.</li>
+ </ol>
+
+ </body>
+ </html>
|