[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