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

Editorial: clarify ordinary and exotic object definitions and creation #1460

Merged
merged 1 commit into from
Feb 3, 2020

Conversation

domenic
Copy link
Member

@domenic domenic commented Feb 28, 2019

Closes #1453. Closes #1437.

Main changes

  • Defines ordinary objects as having the ordinary internal methods, and exotic objects as not having the ordinary internal methods.

  • Introduces AllocateBasicObject, which now is the only source of object creation, centralizing the undefined phrase "a newly created object" or "newly created X exotic object" into one location.

  • Introduces explicit definitions for every type of exotic object in terms of how they override the internal methods. This makes phrases like "x is an Array exotic object" well-defined.

  • Renames ObjectCreate to OrdinaryObjectCreate, and clarifies how it should be used.

Related changes to object creation

  • Fixes immutable prototype exotic objects to not inaccurately state that they always have default internal methods besides [[SetPrototypeOf]]; this is not the case for web platform objects, for example. This involved then expanding the definition of %ObjectPrototype% a bit to be more explicit about its internal slots and methods.

  • Improves missing or contradictory internal slot installation, e.g. the introduction for function objects said they had "the same internal slots" as other ordinary objects, but FunctionAllocate installed a list of slots that was missing [[Prototype]] and [[Extensible]].

  • Deduplicates setting [[Extensible]] to its default true value.

  • Clarifies with a note that CreateUnmappedArgumentsObject does not create an exotic object, despite being in the "Arguments Exotic Objects" clause.

  • Slightly reduces the coupling between IntegerIndexedObjectCreate and CreateTypedArray by changing how arguments are passed.

Drive-by fixes

  • Uses the phrase "bound function exotic object" uniformly instead of sometimes "bound function" or "bound function object".

This will involve changes to both HTML and Web IDL, mostly the renaming of ObjectCreate, but possibly others.

One thing I am waffling on is whether AllocateBasicObject should take a proto parameter at all. I am thinking probably it is best to remove. Since you have to pass [[Prototype]] anyway, AllocateBasicObject(« [[x]], [[Prototype]] », proto) is not much worse than a two steps where the second explicitly sets [[Prototype]], and it makes AllocateBasicObject more basic and less coupled.

Edit: I flipped it to remove the proto parameter.

Note that technically "a newly created TypeError object" and its ilk are still ill-defined after this change, but that's pretty minor.

I'll also note that I didn't touch the built-in function objects section, which is kind of a mess of underdefined and confusing things as witnessed by many previous GitHub and es-discuss threads.

Editorial thoughts especially welcome; I think there were some choices e.g. about referencing tables vs. listing slots explicitly, or how to write the intro paragraphs for each type of exotic object, which could be revisited or better.

spec.html Outdated

<emu-alg>
1. Let _obj_ be a newly created object with an internal slot for each name in _internalSlotsList_.
1. Set _obj_'s essential internal methods to the default ordinary object definitions specified in <emu-xref href="#sec-ordinary-object-internal-methods-and-internal-slots"></emu-xref>.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should explicitly say that after returning from this operation only the direct caller of
AllocateBaseObject may modify the definition of the returned object's essential internal methods.

Basely, we don't what to imply that it is possible for internal method definitions to change at arbitrary times during the entire lifetime of an object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thank you! Also added more asserts on callers relating to the interaction with non-overridden methods.

spec.html Outdated
</emu-alg>

<emu-note>
<p>Apart from being slightly easier to call than AllocateBasicObject, using OrdinaryObjectCreate communicates the intention to create an ordinary object, and not an exotic one. Thus, it must not be called as part as of an algorithm that subsequently modifies the internal methods of the object in ways that would make the result non-ordinary. In such cases, use AllocateBasicObject. (Even if it means having to include [[Prototype]] and [[Extensible]] in the internal slots list manually.)</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this somewhat covers the point I mentioned about mutating the set of essential internal methods. I think it is good to say it both places.

@ljharb ljharb removed the request for review from bterlson February 28, 2019 19:51
spec.html Outdated

<p>Immutable prototype exotic objects have the same internal slots as ordinary objects. They are exotic only in the following internal methods. All other internal methods of immutable prototype exotic objects that are not explicitly defined below are instead defined as in <a href="#sec-ordinary-object-internal-methods-and-internal-slots">ordinary objects.</a></p>
<emu-note>
<p>Unlike other exotic objects, there is not a dedicated creation abstract operation provided for immutable prototype exotic objects. This is because they are only used by %ObjectPrototype% and by host environments, and in host environments, the relevant objects are potentially exotic in other ways and thus need their own dedicated creation operation.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered whether we should add an ImmutablePrototypeObjCreate, but I'm ok with not having it for now since we would host object to define there on xxxCreate operations that incorporate this. Perhaps the sort of thing that should be explained in a FAQ on defining "host objects"

Suggested change
<p>Unlike other exotic objects, there is not a dedicated creation abstract operation provided for immutable prototype exotic objects. This is because they are only used by %ObjectPrototype% and by host environments, and in host environments, the relevant objects are potentially exotic in other ways and thus need their own dedicated creation operation.</p>
<p>Unlike other exotic objects, there is not a dedicated creation abstract operation provided for immutable prototype exotic objects. This is because they are only used by %ObjectPrototype% and by host environments, and in host environments, the relevant objects are potentially exotic in other ways and thus need their own dedicated creation operation.</p>

Copy link
Member

@allenwb allenwb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General looks good, but see a couple comments.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 28, 2019

@domenic, in a comment in issue #1453:

One thing I have run into is that per https://tc39.github.io/ecma262/#sec-ecmascript-function-objects, we say that function objects are ordinary objects.

It actually says that ECMAScript function objects are ordinary objects. ECMAScript function objects are a proper subset of the function objects specified by the ECMAScript spec. (See Issue #1273 for some discussion.)

However, they have an overriden [[Call]] internal method.

I wouldn't say "overridden". They certainly do have a [[Call]] internal method, but it doesn't override some prior behaviour.

So I guess the definition of "ordinary object" (besides the glib one) is "has the default internal methods, or maybe has a [[Call]] as specified for function objects". Kind of unsatisfying, but I will not change anything for now.

How it seems to work in 6.1.7.2 Object Internal Methods and Internal Slots is that if an object has a [[Call]] internal method, then [[Call]] is an essential internal method for that object. Similarly for [[Construct]] (although some of the wording around Table 6 implies that [[Construct]] is essential for all function objects, which of course it isn't).

So you could say that an ordinary object "has the default behaviour for all of its essential internal methods" and that will include [[Call]] and [[Construct]] as appropriate. (Mind you, the spec doesn't currently say it that way.)

Copy link
Member

@zenparsing zenparsing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would definitely like to see the OrdinaryObjectCreate rename. I think that's a clear, easy win. I'm a bit less sure of the other changes and will need more time to think about them.

Would you be opposed to submitting that change as it's own PR?

@domenic
Copy link
Member Author

domenic commented Feb 28, 2019

I'm sorry to say I would be. Personally, I think the rename is sad, because of all the churn it will cause. But I would be willing to take that hit if we also actually clarified the attendant issues. For example, adding normative requirements that OrdinaryObjectCreate should only use be used to create ordinary objects, and providing clear instructions for how to create exotic objects.

Just renaming by itself doesn't improve clarity, and causes lots of specs to need updates. Indeed, I think it would reduce clarity, since now we'd have something named OrdinaryObjectCreate which does the exact same three steps as many exotic object creation routines also include.

Copy link
Member

@zenparsing zenparsing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@domenic Totally understand, and thanks for this PR. After reading through, I like everything here, except perhaps for a nit over the name "AllocateBasicObject". As a reader, I'm not really sure what "basic" implies, since it's not used elsewhere. Do you have any thoughts on the naming? Would "AllocateObject" be sufficient?

@allenwb
Copy link
Member

allenwb commented Mar 1, 2019

How about AllocateObjectStructure or AllocateObjectFoundation or AllocateObjectCore or AllocateCommonObjectCore or ...

Or perhaps substitute "Make" for "Allocate" in any of the above.

the point is that this operation isn't trying to introduce a new kind of entity into the spec. It is just there to factor common behavior out of the xxxObjectCreate operations

@domenic
Copy link
Member Author

domenic commented Mar 1, 2019

I am happy with any of those names, and if the editor(s) can come to a final decision, I will change it. Just don't want to do it twice :).

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 2, 2019

@zenparsing

I like everything here, except perhaps for a nit over the name "AllocateBasicObject". As a reader, I'm not really sure what "basic" implies, since it's not used elsewhere.

That's what I was thinking too. Maybe replace "basic" with "default" (e.g. AllocateDefaultObject or MakeDefaultObject), alluding to the default ordinary definitions for the essential internal methods.

@allenwb
Copy link
Member

allenwb commented Mar 2, 2019

I think MakeDefaultObject is the best alternative.

I prefer "Make" over "Allocate" because "Allocate" sounds too concrete and suggestive of an implementation detail.

@domenic

This comment has been minimized.

@jmdyck

This comment has been minimized.

@jmdyck

This comment has been minimized.

@ljharb

This comment has been minimized.

spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
@jmdyck
Copy link
Collaborator

jmdyck commented Jan 9, 2020

Now, it may well be that this is the consensus mental model of the committee. If so, I think the spec should do a better job of making sure the reader gets the same mental model.

What is unclear about the internal-methods-vtable-as-brand approach that the reader doesn't get this mental model, and what would help? Would a paragraph explicitly describing the intention of the internal methods vtable being tantamount to a brand suffice?

I'll have to think about that.

@syg
Copy link
Contributor

syg commented Jan 9, 2020

I don't find this discussion very productive. This is the usual structural typing that JS is at home with, except operating on spec metafunctions -- the current lack of clarity around exotic objects is creating friction for downstream specs, and AFAICT no downstream spec considers exotic objects to be some behavioral thing and not a branding thing. Absent concrete verbiage suggestions, this PR is ready to merge.

@allenwb
Copy link
Member

allenwb commented Jan 10, 2020

@jmdyck

I completely agree with what @syg said in #1460 (comment)

Well then I'm puzzled, because over here you agreed that your position was essentially: the set of objects that qualify as "Array exotic objects" includes only those objects that are behaviorally [observably] indistinguishable from the Array objects created by the spec.

I didn't actually say that, you did. You have to look at the context to unravel what I meant. What I actually said was: "Yes, that is essentially my position, particularly if by 'behaviorally' you also mean 'observably' . That was referring to the following statement from you:

I think your position is something like: the set of objects that qualify as "Array exotic objects" includes only those objects that are behaviorally indistinguishable from the Array objects created by the spec.

So, I was actually suggesting replacing the work "behaviorally" with "observability". And this was in the context of me arguing that all instantiations of exotic objects within the specification should be specified as an invocation of a xxxCreate abstract operations such as ArrayCreate. The reason for use of the xxxCreate operations is to be clearer in the specification when the instantiation of a specific kind of exotic object was required. The observable characteristics of such objects include the "meta-branding" of the sort being discussed in this thread.

You also said: "You also have to take into account all the other characteristics established by ArrayCreate," which this PR's approach doesn't do.

Simply implementing the specified behavior of a specified exotic internal method is not enough to make that thing be "the internal method defined in X.Y.Z". The implementor must have the intent of implementing what was defined in "X.Y.Z".

So you're saying that the spec is making distinctions that depend on knowing the implementor's intent?

I think @syg covered this. The spec. isn't an engine or a reference implementation. It doesn't do anything other than establish requirements of conforming implementation. If an implementation wants to define language/library extensions that create objects that are "Array exotic objects" and hence will be recognized as such in all the places that specification requires such recognition then the implementation must ensure that those objects are observability (to the implementation) no different (including meta-branding) from objects created by the implementation in satisfaction of ArrayCreate's requirements.

@syg
Copy link
Contributor

syg commented Jan 10, 2020

@allenwb Thanks for the clarification! I misunderstood your position earlier and retract my statement above that you had also wanted observational equivalence.

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 10, 2020

What is unclear about the internal-methods-vtable-as-brand approach that the reader doesn't get this mental model, and what would help? Would a paragraph explicitly describing the intention of the internal methods vtable being tantamount to a brand suffice?

I'll have to think about that.

Okay, I think the simplest and most direct way to address this is to rewind to here and change the suggested paragraph to something like this:

In some algorithms, there are steps of the form "If object is an X exotic object, ...", where X names a kind of exotic object such as Array, Bound Function, or Proxy. Certainly, an implementation must provide X exotic objects, and must recognize them as such in steps of this form. But it is also possible for an implementation to provide additional objects (or to allow the host to define objects) that exhibit behaviour that conforms to the requirements for X exotic objects; despite this behavioural conformance, implementations are not required to recognize them as X exotic objects.

(That wording suggests that it's implementation-dependent whether it does or not -- do we want to require that such objects do not satisfy such conditions?)

@syg
Copy link
Contributor

syg commented Jan 10, 2020

do we want to require that such objects do not satisfy such conditions?

Yes, for the same reason as the vtable-as-brand reasoning. If the implementation provides a behaviorally equivalent object that has a different vtable that happens to be behaviorally the same, it should not be recognized as one of the in-spec branded exotic objects.

As for your paragraph, it sounds mostly fine to me though a bit verbose. I'll try to cut it down a bit.

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 10, 2020

Okay, that's an easy tweak to my suggestion.

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 10, 2020

There could also be a Note to the effect that this implies vtable-as-brand semantics, but I'm not sure how one would word it.

jmdyck
jmdyck previously requested changes Jan 23, 2020
Copy link
Collaborator

@jmdyck jmdyck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments relating to lines that don't appear in the diff:

  • line 9384: Need para: "An object is an integer-indexed exotic object if ..."

  • line 9609: Need para: "An object is a module namespace exotic object if ..."

  • line 18114: "ObjectCreate" -> "OrdinaryObjectCreate". (I warned about this here and @ljharb took care of it in 492886d, but it must have regressed in a subsequent rebase.)

  • line 26404: Change "bound function" to "bound function exotic object" as described in the main commit message?


Comments relating to multiple lines:

  • Occurrences of "other internal methods" should probably be "other essential internal methods".

  • Referring to specific versions/variants of the essential internal methods as "implementations" conflicts with the usage in the sense of an ECMAScript implementation or a conforming implementation. Instead, refer to them as "definitions"? "algorithms"?

E.g.: "... and its other essential internal methods use the definitions found in [9.1]"


Comments relating to the main commit message:

  • Change "AllocateBasicObject" to "MakeBasicObject".

  • Drop the line about giving "array index" a definition.

spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated
<p>Bound function objects do not have the internal slots of ECMAScript function objects defined in <emu-xref href="#table-27"></emu-xref>. Instead they have the internal slots defined in <emu-xref href="#table-28"></emu-xref>.</p>
<p>A bound function is an exotic object that wraps another function object. A bound function is callable (it has a [[Call]] internal method and may have a [[Construct]] internal method). Calling a bound function generally results in a call of its wrapped function.</p>

<p>An object is a <dfn id="bound-function-exotic-object">bound function exotic object</dfn> if its [[Call]] and [[Construct]] internal methods use the following implementations, and its other internal methods use the implementations found in <emu-xref href="#sec-ordinary-object-internal-methods-and-internal-slots"></emu-xref>. These methods are installed in BoundFunctionCreate.</p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>An object is a <dfn id="bound-function-exotic-object">bound function exotic object</dfn> if its [[Call]] and [[Construct]] internal methods use the following implementations, and its other internal methods use the implementations found in <emu-xref href="#sec-ordinary-object-internal-methods-and-internal-slots"></emu-xref>. These methods are installed in BoundFunctionCreate.</p>
<p>An object is a <dfn id="bound-function-exotic-object">bound function exotic object</dfn> if its [[Call]] and (if applicable) [[Construct]] internal methods use the following implementations, and its other internal methods use the implementations found in <emu-xref href="#sec-ordinary-object-internal-methods-and-internal-slots"></emu-xref>. These methods are installed in BoundFunctionCreate.</p>

(since it doesn't necessarily have a [[Construct]] internal method)

spec.html Outdated Show resolved Hide resolved
spec.html Outdated
<p>An <dfn id="ordinary-object">ordinary object</dfn> is an object that satisfy all of the following criteria:</p>
<ul>
<li>
Its internal methods are those defined in <emu-xref href="#sec-ordinary-object-internal-methods-and-internal-slots"></emu-xref>.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Sorry, my suggested wording wasn't quite right.) Saying that its internal methods are those defined in 9.1 means that it doesn't have [[Call]] and [[Construct]], because those aren't defined in 9.1. So it would be better to say something like:

For the internal methods listed in [Table 6], it uses the definitions in [9.1].

@syg
Copy link
Contributor

syg commented Jan 30, 2020

Rebased and squashed to fix up commit message.

</emu-alg>

<emu-note>
<p>Within this specification, exotic objects are created in abstract operations such as ArrayCreate and BoundFunctionCreate by first calling MakeBasicObject to obtain a basic, foundational object, and then overriding some or all of that object's internal methods. In order to encapsulate exotic object creation, the object's essential internal methods are never modified outside those operations.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm.

MakeConstructor is passed a function object and sets its [[Construct]] internal method, and OrdinaryFunctionCreate obtains a function object by calling OrdinaryObjectCreate and sets its [[Call]] internal method.

I guess those technically are not creating exotic objects, so this is not technically wrong, but I find it misleading (which is to say, it misled me) in light of the above. I believe those are the only two places where the internal slots of an object are manipulated by a method other than the one which invoked MakeBasicObject. Perhaps (as a followup) we can refactor things so that those two cases go away, so that this note would apply to all objects (and we could get rid of the "Thus, it is not called by any algorithm that subsequently modifies the internal methods of the object in ways that would make the result non-ordinary." part of the note on OrdinaryObjectCreate below, since it would then be redundant).

I'm not asking for changes right now, just noting I found this misleading.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess those technically are not creating exotic objects

Right. For OrdinaryFunctionCreate, it's clear from the name. For MakeConstructor, the first step asserts that F is an ECMAScript (i.e., ordinary) function object.

but I find it misleading (which is to say, it misled me)

What were you misled to think/expect?

Copy link
Contributor

@bakkot bakkot Feb 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What were you misled to think/expect?

I assumed that the essential internal methods of any object would never be manipulated except by the method which called MakeBasicObject. That's not actually true, and is not quite what this line says, but (unless I've missed some other cases) it is very close to being true. And it's what I expected this to say, so on first reading I missed that it says something slightly different.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A followup PR sounds good to me.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakkot: Rather than refactoring to make those two cases go away, an easier alternative (or interim aid) would be to identify them in another Note after OrdinaryObjectCreate (and/or possibly modify the existing one).

spec.html Show resolved Hide resolved
spec.html Show resolved Hide resolved
</emu-alg>

<emu-note>
<p>Although OrdinaryObjectCreate does little more than call MakeBasicObject, its use communicates the intention to create an ordinary object, and not an exotic one. Thus, it is not called by any algorithm that subsequently modifies the internal methods of the object in ways that would make the result non-ordinary. Operations that create exotic objects invoke MakeBasicObject directly.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Is not called" implicitly makes a claim about other specifications. I think this should either be "is not called within this specification", or "should not be called".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually when the spec talks about algorithms, it implicitly means algorithms defined in the spec. But sometimes it makes that explicit, and I agree it's worthwhile to do so here. My suggestion would be to change "Thus," to "Thus, within this specification,".

(The problem with "should not" is that it sounds like a requirement on implementations, which it isn't.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

Copy link
Contributor

@bakkot bakkot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than relatively minor comments below. I agree with the "internal methods have meta-identity" approach.

@syg
Copy link
Contributor

syg commented Feb 2, 2020

Addressed @bakkot's review and rebased.

tc39#1460)

Closes tc39#1453.

* Defines ordinary objects as having the ordinary internal methods, and exotic objects as not having the ordinary internal methods.

* Introduces MakeBasicObject, which now is the only source of object creation, centralizing the undefined phrase "a newly created object" or "newly created X exotic object" into one location.

* Introduces explicit definitions for every type of exotic object in terms of how they override the internal methods. This makes phrases like "x is an Array exotic object" well-defined.

* Renames ObjectCreate to OrdinaryObjectCreate, and clarifies how it should be used.

* Fixes immutable prototype exotic objects to not inaccurately state that they always have default internal methods besides [[SetPrototypeOf]]; this is not the case for web platform objects, for example. This involved then expanding the definition of %ObjectPrototype% a bit to be more explicit about its internal slots and methods.

* Improves missing or contradictory internal slot installation, e.g. the introduction for function objects said they had "the same internal slots" as other ordinary objects, but FunctionAllocate installed a list of slots that was missing [[Prototype]] and [[Extensible]].

* Deduplicates setting [[Extensible]] to its default true value.

* Clarifies with a note that CreateUnmappedArgumentsObject does not create an exotic object, despite being in the "Arguments Exotic Objects" clause.

* Slightly reduces the coupling between IntegerIndexedObjectCreate and CreateTypedArray by changing how arguments are passed.* Uses the phrase "bound function exotic object" uniformly instead of sometimes "bound function" or "bound function object".

Co-authored-by: Domenic Denicola <d@domenic.me>
Co-authored-by: Shu-yu Guo <syg@chromium.org>
@ljharb ljharb dismissed jmdyck’s stale review February 3, 2020 05:06

concerns appear to be addressed; any changes can be done in a followup

@ljharb ljharb merged commit e3707ac into tc39:master Feb 3, 2020
domenic pushed a commit to whatwg/webidl that referenced this pull request Apr 16, 2020
These replaced ObjectCreate and the undefined phrases around "newly created ECMAScript objects" in tc39/ecma262#1460.
@domenic domenic deleted the explicit-exotics branch April 16, 2020 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Define exotic object from first principles