jswrap (C++ love for Spidermonkey)

A couple of years ago I started and then abandoned a project that implemented what I thought then were a couple of cute ideas to do with using boost (the outstanding C++ libraries found at boost.org) to automatically generate wrappers for C++ objects to be used in Spidermonkey. I’ve shared pieces of the code before, to people who needed a C++-style error-reporter for Spidermonkey, or whatever, but I’ve never bothered actually sharing the whole thing. Well, that seems silly, so I’m sharing it now.

There is a lot left to be done here; as I said, I abandoned the project. All I’ve done since then is a tweak here or there, and a couple of cleanups I made today.

As I said, though, it implements some cute ideas:

  • You can get a simple JS program running in two or three lines of C++ code (snipped from demo.cpp):
    
        jswrap::jswrap_ptr js = jswrap::jswrap_ptr(new jswrap());
        jsval rval;
        js->runfile("test.js", &rval);
    
    
  • Wrapping member function calls is a matter of one line of code, and can happen right inside your JSFunctionSpec array (this example is taken from pgsqljs.cpp):
    
        { "status", cmember0<PGconn_wrap, int,
          &PGconn_wrap::status>().call,
          0, DEF_PROP_FLAGS, 0 },
        { "transaction_status", cmember0<PGconn_wrap, int,
          &PGconn_wrap::transaction_status>().call,
          0, DEF_PROP_FLAGS, 0 },
        { "parameter_status", cmember1<PGconn_wrap, const char *, const char *,
          &PGconn_wrap::parameter_status>().call,
          1, DEF_PROP_FLAGS, 0 },
    

    Essentially, I am creating template-classes (I couldn’t figure out how to make this magic work with template-functions — help wanted!) for each member function. The instantiated template class has one static function which knows how to marshall parameters and return values. I also handles exceptions by propagating JS-exceptions as C++-exceptions, and vice versa. This is a little hairy, but I think is an interesting approach. It means no IDL and no external help (other than some rather egregious abuse of the C pre-processor, thanks largely to help from Boost.Preprocessor). It also means you don’t have to maintain a separate call-through layer by hand. Better still, this actually works for C++ member-functions of C++ objects, not only static member functions, so foo.bar() in C++ is still foo.bar() in JS.

  • It includes a sample embedding of the C PostgreSQL API, encapsulated in a C++ class.
  • It handles rooting for you (or at least, I think it does, I haven’t tested very carefully).
  • It provides an error-reporter and a stack-dumping facility, written in C++; both of which can be handy for debugging, or just as “recipes” for external projects. Steal at will.
  • It’s amazingly terse, compared to the usual process for embedding spidermonkey. I’d love to see it get even moreso, while retaining flexibility.

It needs some cleanup and extension. It could also benefit from some additional love in the template department. I’d really like the member function spec lines to look like this, instead:

    { "status", wrappedfunc<&PGconn_wrap::status>, 0, DEF_PROP_FLAGS, 0 },
    { "transaction_status", wrappedfunc<&PGconn_wrap::transaction_status>, 0, DEF_PROP_FLAGS, 0 },
    { "parameter_status", wrappedfunc<&PGconn_wrap::parameter_status>(), 1, DEF_PROP_FLAGS, 0 },

I’d really like to have a better story for properties (ie., data-members) of C++ objects.
I’d really like to have an autoconf-based build environment that works with Mozilla-build (+boost?).
I wrote a boost::asio wrapper. It isn’t included here, but it would be neat to get it back on its feet and wrapped a little more cleanly than I had it before.
It needs more testing and feedback (which is why I am releasing it.)

Here it is. I’m pretty sure you’ll need Boost 1.35 (at a minimum) to build it, and you’ll have to tweak the Jamfile and some other spots to suit your own directory structure (look for the string “crowder”) and file/library locations. Feedback and patches are welcome and appreciated.

The Conversation {4 comments}

  1. Sanjay Mukherjee {Thursday April 30, 2009 @ 3:37 am}

    Hi,

    Its really a good blog as i was searching something like this .

    I require one help from you .
    Actually one thing that i am interested is can i get Ajax object data to my c++ code using Spider Monkey?

    thanks

  2. bcrowder {Thursday April 30, 2009 @ 9:19 am}

    Well, nothing here implements anything like XHR, if that’s what you mean, but it wouldn’t be to hard to add, I think, if you have a good HTTP library handy.

  3. atupac {Sunday May 31, 2009 @ 5:20 pm}

    Hi, so u love embedding things like me! Well, i have an app written in C/C++ for loading images in a Caroussel presentation. But it wasn’t very beautiful & fast because of loading images on the fly!

    So, as a lot of Very Beautiful Carousels already exist on internet (written in javascript…), i decided to spare time by using those existing scripts!

    What i wanted is to embed javascript in may C++ app, and Spidermonkey seems to be the Solution (note: i use the “libjs.a” library for Wii Hombrew develeppement, which is here: http://wiibrew.org/wiki/SpiderMonkey).
    I’ve red and followed the template & example on mozilla and so on…But, after successfully compiling all, and loading it on the Wii: nothing at all show up on Tv screen…

    So if u think u can make & upload here a template project (just showing a simple text or image in middle of screen…) written in C++ that embeds SMonkey javascript code, it will be helpfull!

    PS: i develop on “devkitpro”.

    Thanks.

  4. Raji {Monday November 2, 2009 @ 8:18 pm}

    Hi
    I m into a project were its required to incorporate AJAX object (XHR) in spidermonkey(C).Can you suggest any good HTTP library. Can I use any idl s for XHR and if yes kindly suggest one.

Leave a Comment

  • Comment Policy:Could go here if there's a nagging need Login Instructions: Would go here if there's a desire.