> Should the last line trigger copy-on-write around `a.__proto__`?
Yes. I get that you think of this as "dreadful action-at-a-distance", but
that kind of thing already happens any time the primitive value (including
root-level object references) of a property on the prototype changes. The
intent of this proposal is to treat the whole of the object that exists on
a property of `__proto__` as if it were a primitive. Any attempt to change
it in part or whole forces it to become an instance-specific value first.
The technique used in the example of this proposal ensures that object
reference in `b` isn't invalidated in the process.
The net result is that you don't get to **accidentally** mutate a
prototype. If you want to change some value in a prototype, get access to
it directly first. Using your example, do this:
```js
var a = { __proto__: { foo: { bar: 2 } } } with safe-prototype;
var b = Object.getPrototypeOf(a).foo;
b.bar = 3;
```
This would skip the new behavior, causing the prototype to be modified
directly.
> Unless you have deep knowledge of the internal state and/or the
implementation of the modified object (which you don’t have in case of a
user-implementated one), you cannot reliably detect when an object is
mutated.
I accounted for that with Symbol.UnsafeProto. All prototypes of native
functions will have this flag on them, preventing any attempt at the new
behavior. Further, any behavior that cannot be caught by a Membrane is
beyond the scope of this effort. Given the insanely flexible nature of ES,
it's unrealistic to thing that 100% of all possible implementation details
can be tracked. However, what this proposal seeks to provide is elimination
of the foot-gun for the most common cases. Even in non-interpreted
languages, some objects are impossible to clone completely due to the use
of external resources. This can't be helped.
For objects having such complicated implementations, the developer will
always be able to add Symbol.UnsafeProto to ensure that no attempt to
duplicate it ever occurs. Proper use of the 2 symbols will ensure that
whenever reasonable, the foot-gun cannot appear.
On Wed, Nov 28, 2018 at 3:36 PM Claude Pache <[email protected]> wrote:
> Sorry, I didn’t read the thread thoroughly (so maybe I’ll repeat someone).
> But here are some serious issues with your proposal:
>
> ------
>
> 1. Assignment of properties deep in the object hierarchy split in two
> instructions:
>
> ```js
> var a = { __proto__: { foo: { bar: 2 } } } with safe-prototype;
> var b = a.foo;
> b.bar = 3;
> ```
> Should the last line trigger copy-on-write around `a.__proto__`?
>
> If you say ”no”, it means that the meaning of the code is changed
> unexpectedly with an apparent innocuous code refactoring.
>
> If you say ”yes”, it is dreadful action-at-distance, because the two last
> lines of code may be very distant, indeed even in two distinct files. — It
> would be less an issue if prototypes were, say, just abstract templates.
> But they are not, they are concrete objects, so:
>
> ```js
> var proto = { foo: { bar: 2 } };
> var a1 = { __proto__: proto } with safe-prototype;
> var a2 = { __proto__: proto } with safe-prototype;
> var b1 = a1.foo;
> var b2 = a2.foo
> b1 === b2; // true
> b1.bar = 3;
> b1 === b2; // ???
> ```
>
> ------
>
> 2. Object mutations unrelated to the value of its properties:
>
> ```js
> var a = { __proto__: { foo: new Map([ [ 'bar', 2 ] ]) } } with
> safe-prototype;
> a.foo.set('bar', 3);
> ```
>
> Unless you have deep knowledge of the internal state and/or the
> implementation of the modified object (which you don’t have in case of a
> user-implementated one), you cannot reliably detect when an object is
> mutated.
>
> Note the subtle difference between:
> * `[].push(1)` — You will detect object mutation, because it will add a
> concrete property on the Array object.
> * `(new Set).add(1)` — You won’t detect mutation, because only internal
> state of the Set object is modified.
> * `(new RandomUserDefinedCollection).put(1)` — That depends on the
> implementation of the `RandomUserDefinedCollection` class.
>
>
>
> —Claude
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss