I want to look at an interesting topic: what subset of JavaScript do we intend to support for parallel execution, and how long will it take to get that working? As my dear and loyal readers already know, our current engine supports a simple subset of JavaScript but we will want to expand it and make the result more predictable.

From my point of view, the subset below includes basically all the JavaScript syntax that I ever use. There are two primary limitations that I think people will encounter in practice:

The fact that mutating shared state boots you out of parallel mode. This restriction is (I think) easy to understand, but it will often take some restructuring to obey it. The fact that strings and many native objects (regular expressions, DOM objects, etc) are currently not supported. I expect we’ll improve the support for strings in the near term and also for some native objects, but for others—notably DOM—it will be very challenging to make things work in parallel, due to the many complex implementation details.

OK, let’s get to the details. In the list that follows, we often refer to a plain old JavaScript object (POJO), which means an object defined in JavaScript, not a built-in object. It should be created either with a literal ( {...} , [...] ) or a new C expression where C is a user-defined function. I’ve also written bug for cases where the current implementation is more limited than it should be.

a : Variable access You should be able to access any variable in scope, so long as you do not use with or eval . I think this all works fine today, though there may be errors in the implementation today relating to infrequently used access patterns, such as "use strict" .

: Variable access a.b : Property access If a is a POJO and b is a data property no getters (should work someday)

: Property access a[e] : Element access If a is a POJO or a TypedArray

: Element access a + b , a - b , etc: Binary operators for any primitive values (someday we should be able to support all objects) bug: today, only works if a and b are both numbers or bools (in any combination)

, , etc: Binary operators a === b , a !== b : Strict equality and unequality always works

, : Strict equality and unequality a == b , a > b , etc: Loose relational operators works if a and b are both numbers or bools (in any combination)

, , etc: Loose relational operators a[i] = b : Numeric property assignment if a is a POJO or TypedArray owned by current task, and i <= a.length (no holes—not yet, anyway) bug: today, we must successfully predict that a will be an array or typed array. In practice, this preciction is reasonably successful, but problems arise when the same function is called many times from different contexts.

: Numeric property assignment a.e = b or a["e"] = b : String property assignment if a is a POJO owned by the current task bug: today, we must successfully predict the offset of e within a . In practice, this prediction often fails, as the code must be written very, very carefully for it to work.

or : String property assignment {...} , [...] , new C(...) : object literals and creation for new C(...) , C must be a JavaScript function

, , : object literals and creation f() and a.m(...) : Function and method calls If the function being called is a user-implemented function, or one of the functions in the following list: higher-order functions like map , reduce , etc parallel higher-order functions like pmap , preduce , etc Array.push (presuming the receiver is writable) bug: today only a[a.length] = e works, not a.push(e) Math.* bug: today, most but not all Math functions work, and only if we predict the function that will be called and are able to inline it. In practice, this prediction is almost always successful. (more to come)

and : Function and method calls function(a, b) { ... } or (a, b) => { ... } : closure creation this should basically always work, I think bug: the => syntax doesn’t work yet in parallel execution, I don’t believe

or : closure creation if , while , etc works fine

, , etc

One caveat I should point out in the current implementation: even if you stick to the above subset, it is possible that some parallel iterations will abort, generally because of mispredicted types or other transient errors. But I consider a parallel abort to be ok if the engine will eventually stabilize and all subsequent runs will be successful. This is the same as what happens with JIT engines, which often generate code that is later invalidated and recompiled.