Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a %TypedArray% instance in a different realm #418

Closed
annevk opened this issue Feb 26, 2016 · 12 comments
Closed

Creating a %TypedArray% instance in a different realm #418

annevk opened this issue Feb 26, 2016 · 12 comments
Labels

Comments

@annevk
Copy link
Member

annevk commented Feb 26, 2016

For structured cloning we need a way to create a %TypedArray% instance in a different realm based on an existing %TypedArray% instance.

I can define my own abstract operation that does "Let defaultConstructor be the intrinsic object listed in column one of Table 50 for the value of exemplar's [[TypedArrayName]] internal slot." (from TypedArraySpeciesCreate, which apart from @@species does mostly what I want I think) in a different realm, but I wonder how stable that reference to Table 50 will be over time.

It's also not entirely clear to me if that constructor is guaranteed to be the built-in one or can be from userland doing something entirely different.

@annevk
Copy link
Member Author

annevk commented Feb 26, 2016

I think this is roughly the algorithm I need (coupled with cloning the various slots and passing those to TypedArrayCreate):

  1. Let constructor be the intrinsic object listed in column one of Table 50 for the value of input's [[TypedArrayName]] internal slot in targetRealm.
  2. Return ? TypedArrayCreate(constructor, « ... »).

@domenic
Copy link
Member

domenic commented Feb 26, 2016

I haven't looked at #410 but based on the name it might impact things.

It's also not entirely clear to me if that constructor is guaranteed to be the built-in one or can be from userland doing something entirely different.

The defining characteristics of intrinsics is that they cannot be changed in userland.

@annevk
Copy link
Member Author

annevk commented Feb 26, 2016

That PR does not seem to impact this. I'm going with something homegrown for now, but would love input if we could factor out the Table 50 reference somehow.

@domenic
Copy link
Member

domenic commented Feb 26, 2016

I guess you could say "The TypedArray Constructors table" and link to #table-49. (Note: the _s in the caption are a bug in the current ES spec output that we should expect to eventually be fixed.)

@annevk
Copy link
Member Author

annevk commented Apr 18, 2017

This is the language we have now in HTML:

[S]et value to a new typed array object, using the constructor given by input.[[Constructor]], whose [[ViewedArrayBuffer]] internal slot value is deserializedArrayBuffer, whose [[TypedArrayName]] internal slot value is input.[[Constructor]], whose [[ByteLength]] internal slot value is serialized.[[ByteLength]], whose [[ByteOffset]] internal slot value is serialized.[[ByteOffset]], and whose [[ArrayLength]] internal slot value is serialized.[[ArrayLength]]

Which matches language we also use for other objects:

Set value to a new Map object in targetRealm whose [[MapData]] internal slot value is a new empty List.

If TC39 considers that precise enough this issue can be closed.

@annevk
Copy link
Member Author

annevk commented Apr 18, 2017

I guess we need to ad "in targetRealm" at the very least. Will fix that.

@allenwb
Copy link
Member

allenwb commented Apr 18, 2017

The ECMAScript spec. has never defined an explicit directed association from ordinary objects to realms because it had so semantics that required such an association. The closest thing to such an association is the selection of an intrinsic object (associated with some realm) that is to be the initial value of a new object's [[Prototype]] internal slot. Most (all?) object creation algorithms in ECMA-262 select the appropriate intrinsics based upon the "current realm".

Which matches language we also use for other objects:
Set value to a new Map object in targetRealm whose [[MapData]] internal slot value is a new empty List.

The above language is not precise enough, because the meaning of the phrase "a new X object in targetRealm" not precisely defined.

It seems to me, that what you need to precisely specify this is something like a realm parameterized version of OrdinaryObjectCreate. For example:

   CreateOrdinaryObjectFromRealmIntrinsicConstructor(realm, instrinsicName [,internalSlotList])

where intrinsicName is the Intrinsic Name of a constructor as listed in Table 7. Note that unlike OrdinaryCreateFromConstructor, an intrinsicDefaultProto parameter is not needed. The reason is that the prototype property of intrinsic constructors is always non-writable'non-configurable so we know that we can get the initial [[Prototype]] value from the constructor.

The specification of of this new abstract operation would be just like OrdinaryObjectCreate except that it's first step is would retrieve the appropriate intrinsic constructor from realm.[[Intrinsics]]. In step 2, null can be used in place of intrinsicDefaultProto.

Using this new abstract operation, the above quoted structured clone language would be replaced by something like:

  1. Let value be ?CreateOrdinaryObjecgtFromRealmIntrinsic(targetRealm,"%Map", « [[MapData]] »).
  2. Set value.[[MapData]] to a new empty List.

Whether this new abstract operation is part of the HTML structured clone spec or part of ECMA-262 is something for the appropriate editors to negotiate. If it was up to me I would place in the clone spec since it isn't currently needed by ECMA-262.

I haven't worked through the details for typed arrays, but the basic idea should be the same except that the intrinsicName is obtained from [[TypedArrayName]].

@domenic
Copy link
Member

domenic commented Apr 18, 2017

Yes, something like that would be reasonable for formalizing things, but I don't think we want to duplicate and keep in sync the list of internal slots. Also we don't want to have to duplicate and keep in sync the default values for the internal slots, which are currently set in the constructors. (E.g. an empty list for [[MapData]]; [[TypedArrayName]] for typed arrays.)

Currently the only ES type for which this is easy is arrays, which have ArrayCreate(length[, proto]), which we use. (And I guess ObjectCreate, which we don't use, but could.) "Properly" creating the other built-ins all involve a lot of boilerplate and error-prone duplication.

As such we went for "a new X object in targetRealm" as a signifier for "using the intrinsic from targetRealm and the defaults for the usual internal slots"; so far we have not had any interoperability issues or implementer questions.

It would be great to make it more precise if the ES spec was willing to expose the right hooks, certainly.

@annevk
Copy link
Member Author

annevk commented Apr 18, 2017

@allenwb I suggest that for this issue we focus exclusively on the prototype implications of the realm. #573 is about the mapping from ordinary objects to a realm, if there is to be such a thing.

@allenwb
Copy link
Member

allenwb commented Apr 18, 2017

@domenic
Invoking the constructor is probably the easiest way to avoid duplicating the work to establish the internal invariants of the various objects.

You could define "a new %Foo% object for targetRealm [with args]" as meaning:

  1. Let ctor be the %Foo% intrinsic constructor from targetRealm.[[Intrinsics]].
  2. If args was not included, let args be « ».
  3. return ? Construct(ctor, args)

The parameters to the constructor are the only tricky parts. For the structured clone use case an empty argument list exactly what you need. But for others, such as typed arrays you would need to supply an actual argument (for example, the length of the array).

@domenic
Copy link
Member

domenic commented Apr 18, 2017

Oh, thanks @allenwb. I'm not sure why that didn't occur to us... it seems perfectly serviceable. Maybe I was confused by all the extra steps that many constructors contain? But skimming through, they seem to be a non-issue when you pass an empty arguments list. I very much appreciate you walking us to the right conclusion here.

Let me open an issue on HTML to rigorize our definitions and then I'll close this one.

@annevk
Copy link
Member Author

annevk commented Apr 19, 2017

(@allenwb, by the way, wanted to thank you off-topic and wasn't quite sure where to mention it. We have revised structured cloning to be separate serialization and deserialization algorithms (object <> Record structure) as you've suggested ages ago and it's great.)

inikulin pushed a commit to HTMLParseErrorWG/html that referenced this issue May 9, 2017
inikulin pushed a commit to HTMLParseErrorWG/html that referenced this issue May 9, 2017
alice pushed a commit to alice/html that referenced this issue Jan 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants