Thursday, September 17, 2009

with (foo) { function bar() {} } fubared

The last two days I've been working on a test suite for my webworker shim and found a couple of wrinkles.

The first was that messages were being lost when they were sent immediately after the worker creation.

For example:

var w = new Worker("foo.js");
w.onmessage = function (event) {

The message "foo" would never reach the worker. This was solved simply enough by queueing messages when the communication channel is not ready. Which brought me back to looking at the spec for MessagePort and MessageChannel, but that's not important right now.

The really wrinkly thing that I'm seeing now is based on this test:

function testImportScripts () {
   importScripts("../scripts/import.js"); // declares function importedFunction
   assertNotUndefined(importedFunction,"imported function is defined");

First I was getting reference errors telling me that importScripts was undefined. I was able to get around that by surrounding the call to importScripts in a with (this) {} block. That worried me. And importedFunction was still undefined.

So I write a simple worker script:

onmessage = function (event) {
 postMessage("received: " +;


No importedFunction. However, with importedFunction assigned instead of declared -- viola! function declarations inside of with blocks are not supported according to ECMA-262 3rd edition. It makes sense, but it puts a bit of a crimp in my plans. (I found this post which confirmed my suspicion, I didn't actually dig through the spec to find out!

The current version of the WorkerGlobalScope uses this code inside of it's _executed method for all internal executions:

Function("with (this) { " + source + " }").call(this);

I strongly prefer to maintain the use of with so for now I am modifying the code passed to the worker to make function declarations function assigments. The latest version of the code and the tests so far are checked in to SVN.

No comments:

Post a Comment