Re: [heycam/webidl] Is internal method setup in object creation correct? (#657)

I'm going to try to clarify my comment a bit. So the present issue here is that we are assigning internal methods as if they can be changed at any time, even after we have already called the old internal methods on that object. ES never really explicitly forbids that, but they never do it in practice, so we perhaps shouldn't either. Implementation internals more or less agree with this restriction, though the differences are not observable to JavaScript.

However, fixing this isn't as straightforward as just moving all the internal method assignment steps to be right after step 9, due to the desire to make the "define" algorithms otherwise unobservable to these overridden internal methods. So realistically we would have to do two things:

1. Move the internal method override assignments to be right after step 9.
2. Change the "define" algorithms to not call internal methods when assigning own properties. E.g., instead of [saying](https://heycam.github.io/webidl/#define-the-operations):
   > 1. Let *desc* be the PropertyDescriptor{[[Value]]: *method*, [[Writable]]: *modifiable*, [[Enumerable]]: **true**, [[Configurable]]: *modifiable*}.
   > 1. Let *id* be *op*’s identifier.
   > 1. Perform ! DefinePropertyOrThrow(*target*, *id*, *desc*).

   Say something like
   > 1. Let *desc* be the PropertyDescriptor{[[Value]]: *method*, [[Writable]]: *modifiable*, [[Enumerable]]: **true**, [[Configurable]]: *modifiable*}.
   > 1. Let *id* be *op*’s identifier.
   > 1. Assert: Object *target* does not have an own property with key *id*.
   > 1. Create an own data property named *id* of object *target* whose [[Value]], [[Writable]], [[Enumerable]] and [[Configurable]] attribute values are described by *desc*.

   or (without creating the intermediate Property Descriptor Record)

   > 1. Let *id* be *op*’s identifier.
   > 1. Assert: Object *target* does not have an own property with key *id*.
   > 1. Create an own data property named *id* of object *target* whose [[Value]] attribute is *method*, [[Writable]] attribute is *modifiable*, [[Enumerable]] attribute is **true**, and [[Configurable]] attribute is *modifiable*.

   or (without mucking with own properties ourselves and use ES's abstract operations as much as possible)

   > 1. Let *id* be *op*’s identifier.
   > 1. Let *current* be ! OrdinaryGetOwnProperty(*target*, *id*).
   > 1. Assert: *current* is **undefined**.
   > 1. Let *desc* be the PropertyDescriptor{[[Value]]: *method*, [[Writable]]: *modifiable*, [[Enumerable]]: **true**, [[Configurable]]: *modifiable*}.
   > 1. Perform ! ValidateAndApplyPropertyDescriptor(*target*, *id*, **true**, *desc*, *current*).

   I personally prefer the second variant, as it's the most concise.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/heycam/webidl/issues/657#issuecomment-467133302

Received on Monday, 25 February 2019 18:52:02 UTC