[webkit-dev] Passing data structures through postMessage()

Maciej Stachowiak mjs at apple.com
Thu Sep 10 17:21:47 PDT 2009


On Sep 10, 2009, at 3:12 PM, Chris Campbell wrote:

> Hi All,
>
> I had it in mind to implement support for passing data structures
> through postMessage() using the "structured clone" algorithm laid out
> in the HTML5 spec:
>
> http://dev.w3.org/html5/spec/Overview.html#posting-messages
> http://dev.w3.org/html5/spec/Overview.html#safe-passing-of-structured-data
>
> I've had some brief discussion with Dave Levin and Drew Wilson on
> #chromium IRC about this, and have an approach in mind that follows
> and elaborates on their suggestions, but there are still some holes in
> it and I'd very much like input from people familiar with this area.
>
> Currently, there are several postMessage() handlers (in
> MessagePort.idl, DOMWindow.idl, DedicatedWorkerContext.idl, and
> Worker.idl), and they all take a DOMString for the message parameter.
>
> The general idea is to change that message parameter from a DOMString
> to a new AttributeIterator type that allows walking of any sort of JS
> structure/type.  AttributeIterator would essentially be an adapter to
> translate native V8 or JSC JavaScript objects to an agnostic interface
> suitable for walking the structure and serializing it.  I'm thinking
> it would look something like this:
>
> interface AttributeIterator {
>    bool isUndefined();
>    bool isNull();
>    bool isFalse();
>    bool isTrue();
>    bool isNumber();
>    String getNumber();
>    bool isString();
>
>    // ... cover the other types including Date, RegExp, ImageData,
>    // File, FileData, and FileList ...
>
>    // Retrieve the key for the next property (for Objects and Arrays)
>    String nextEnumerableProperty();
>
>    AttributeIterator getPropertyValue(key);
> }

Some thoughts off the cuff:

I think it would be better to write custom code for doing the cloning  
for each JS engine. For one thing, turning everything into a string is  
not necessarily the most efficient way to do things. It might be  
possible to clone the object graph more directly in a threadsafe way.  
Also, things like File and ImageData fundamentally can't be turned  
into a string (well ImageData can)

Second, to be really agnostic about it, postMessage should take a  
generic Message object that has some methods that can be used to do  
the cross-thread clone without building in the assumption that it  
serializes to a string in the middle.

Third, using a stateful iterator for this instead of an interface  
representing a value is not a great design. Iterators are not good  
when what you are traversing is in general a graph.

Fourth, this doesn't give a way to detect if an object graph is not in  
fact legal to clone.

It's kind of a shame that we have the baggage of multiple JavaScript  
engines to contend with. Trying to do things in a generic way will  
make this task needlessly more difficult.

You may also want to get input on this from Oliver Hunt, who wrote the  
JSC JSON parse/stringify code; from past discussions I know has  
opinions on how cross-thread cloning should work.


>
>
> I'm also thinking that depending on compile-time flags, the
> contstructor for AttributeIterator would either take a
> v8::Handle<v8::Value> or JSC::JSvalue value.
>
> Then in each implementation of postMessage() the AttributeIterator
> instance could be passed to the structured clone serializer, which
> would return a string.  Thereafter, no changes would be required to
> WebCore internals since they already pass strings around... until on
> the receiving end we get to MessageEvent.data where we would do the
> deserialization in a custom getter.
>
>
> Open questions:
>
> (1) Is passing an AttributeIterator type into postMessage() really the
> best way to go?  Drew mentioned that this might incur a bunch of ObjC
> binding work on the JSC side...
>
> (2) Where should AttributeIterator live in the source tree?
>
> (3) Where should the serialization and deserialization routines live
> in the source tree?
>
> (3) I haven't addressed the specifics of the serialized string format.
> Plain JSON is not quite sufficient since it doesn't retain type
> information for Date, RegExp, etc..  However, I'm not too worried
> about coming up with a suitable format for this.
>
>
> Comments, advice, admonitions welcome!  :)

In general I'm not sure this approach is workable. At the very least  
File, FileData, FileList and ImageData need to be passed as something  
other than strings. And I think the value of making the object graph  
traversal code generic while everything else is JS-engine-specific is  
pretty low. In addition, I do not think the proposed interface is  
adequate to implement the cloning algorithm.

Regards,
Maciej




More information about the webkit-dev mailing list