canvas + chrome + content

I am writing an extension that attaches a div and a canvas to content pages, and in the process of trying to tune it for performance, I ran into bug 339587. I submitted a patch for that bug, but I ran into another problem, which is that my patch causes the ImageData to be wrapped (it becomes a SafeJSObjectWrapper), which means that subsequent putImageData calls are foiled; the object doesn’t look like an object anymore, and especially, the data member doesn’t look like an array, so eventually an exception is thrown. putImageData could be made more robust, but the cost might not be worth it… here’s the obvious workaround. You needn’t actually call createImageData, ever (at least not currently — this might change??); instead, you can build a JS object that looks and works precisely like an ImageData object in your own code. Since you’ll be setting the pixels yourself anyway, I suspect that creating your own image data is actually a tiny bit faster than using createImageData. Here’s what I did:

let imgData = { width: width, height: height };
imgData.data = new Array(width * height * 4); // make sure your array never needs to grow dynamically
//.... initialization loop ....

This probably seems like an obvious workaround, but it might not be obvious to those who haven’t inspected the get/putImageData code.

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.

extend this!

I’ve been working on something fun for the last couple of days (in between patch-revs on other bugs I can’t talk about yet), and I thought I’d blog about it. It’s cool (at least to me) and useful:

John Resig and others involved in the standardization process for the new ECMAScript language proposals have been going back and forth lately over the design of a new language library feature, to facilitate copying properties of one object to another. Object.extend() — essentially you pass an object (the one you mean to extend), and a series of objects (from which you want properties copied), and you get a new object with all the goodness of the others:

From the spidermonkey JS shell:
js> var a = { get x () { print("foo"); return 3 } }
js> var b = [ 1, 2, 3 ]
js> var c = { foo: "bar" }
js> var result = Object.extend({}, a, b, c)
js> result.toSource()
({get x () {print("foo");return 3;}, 0:1, 1:2, 2:3, foo:"bar"})

Notice the getter itself is copied, not the result of its evaluation.

I hope this feature makes it into the standard(s), I think it’s a very powerful, useful, and flexible one. So much so that many of the existing AJAX libraries already have a 5-or-10 line version of it included, under any of a number of names, and with a few variations in semantics. In my opinion, a number of the other features being discussed in lieu of it (like Object.clone) can be implemented trivially in terms of it). A good, consistent semantic for a feature this convenient seems like a great thing for the “library” side of JS, to me. I’d love to land this for 1.9.1, it seems like it would, at least, be handy for extension authors. I hope it survives the committees!

Also, thanks to John for writing a nice test-suite for the feature.

million

This is a brilliant idea that rewards public school students with cell-phone air-time, credits for music purchases, etc., in exchange for educational performance, and is useful as an educational tool during classtime.

Here’s a video about the project.

Did I mention it’s self-sustaining, and funded by advertising?

stone soup

Perhaps everyone has encountered this story before me, but tonight was my first time. I found myself reading it to my sons and thinking a lot about how much it feels like what I do at work. The version I read was by a childrens’ author named Jon J. Muth. If you get a chance to read it, I highly recommend it. There are a couple of online renditions available, too.

Evolving from the JavaScript of today to the JavaScript of tomorrow (ES3 -> ES4)

Lars Hansen of Adobe has written a really great tutorial for ES4 that describes the evolution of a library project written in JS using current technologies, as it incrementally incorporates features of the new language to simplify and improve the code for readability, integrity and performance.

That sounds like a lot of weasel-words. The tutorial demonstrates a library which otherwise has no requirement to be modified at all, but which gradually, simply, and piece-by-piece, as its author’s see fit, improves itself — and the environment to which it exposes its clients — over time, by incorporating some of the new, powerful features of ECMAScript4.

The tutorial is very approachable; even if you don’t consider yourself a language geek, you should check it out. If you’re curious as to what the designers behind ES4 are thinking about, and how they plan to shape the future of the web with the new version of the language, this paper provides some great clues.

The Solar System Doesn’t Work as Well with IE

Seen in a Google Gadget, this morning:

Most installations of the Solar System don’t work as well with Internet Explorer. If you are still using IE this would be a good time to switch to the Firefox browser.

Deeply philosophical.

dtrace on Leopard

So good.

Not quite ready for primetime yet, but close enough to be useful for Mozilla/Firefox developers. Check it out.

Black Hat

This will be my first year at the Black Hat conference in Las Vegas. I’m exited. The fact that Jesse Ruderman is nervous, makes me nervous. :)

elinks

A text-mode browser that does JavaScript (using Spidermonkey)? Neat.