typed objects and value types

C. Scott Ananian ecmascript at cscott.net
Thu Apr 3 06:39:03 PDT 2014


On Thu, Apr 3, 2014 at 9:09 AM, Andreas Rossberg <rossberg at google.com> wrote:
> On 3 April 2014 14:57, C. Scott Ananian <ecmascript at cscott.net> wrote:
> Unfortunately, that only works for primitives because the respective
> constructor/wrapper class is known to exist in all realms, it is known
> to be "the same" everywhere, and because the language can hence apply
> some magic to "rebind" it when primitives cross realm boundaries. For
> user-defined values, no such guarantees exist. Hence, no similar
> rebinding magic can be applied, and values have to hold on to their
> original constructor.

I'm waving my hands here, but it seems to me that a two-part solution
could work:

1) by default, objects passed between realms retain their original
"uvalue type id" (realm id + id of uvalue in that realm") but become
new anonymous uvalue types with no prototype (although field names and
types are preserved.)  Equality between types in different realms
work, because they share the same "uvalue type id", and if the value
is passed back into the original realm the prototype can be re-linked.

This lets uvalues become new "opaque types" when passed between realms.

2) a "cross-realm registry" that allows user code to opt-in to
associate a given local prototype with a certain "uvalue type id".
For cooperating codebases, this lets "Colors" be manipulated as
"Colors" in both realms.  Since the fundamental nature of the uvalue
is structural equality on the contents + "uvalue type id",
reassociating a prototype with a "uvalue type id" is just a
convenience.

2a) One alternative here is to make a general feature out of the map
from "uvalue type id" to prototype.  Given a uvalue, setting
`uvalue.__proto__` will change the prototype used for all uvalues of
that type.  This is rather frightening in its power.  Obviously,
`1.__proto__` should be made read-only!  But on the other hand, it
surfaces the conceptual framework already underlying method dispatch
on primitives.

2b) Another alternative is to define a special "transferable uvalue"
type, which (unlike other uvalues) inherits from `[Transferable]`.
Transferable uvalues register a string or symbol as their "handle"
when the type is created.  This is used to link up uvalues between
realms.  As described in (1), uvalues with a `Symbol` as their handle
are transferable, but are treated as opaque uvalues in other realms.
There is no rebinding of the prototype after the type is created.
(Presumably the 'handle' is an optional parameter to the uvalue type
constructor?)

2c) Like 2b, but all uvalues are transferable, and are created by
default with a new `Symbol` as their handle.  You can transfer the
`Symbol` across realms if you want/need to link up uvalues between
realms (or use the option to specify a `String` handle to trade-off
namespace security for convenience).
 --scott


[Transferable]: https://developer.mozilla.org/en-US/docs/Web/API/Transferable


More information about the es-discuss mailing list