Object.seal, read references, and code reliability
Jerry Schulteis
jdschulteis at yahoo.com
Mon Aug 14 22:20:33 UTC 2017
I'm ok with the basic idea. I don't think "lock" is a good name for it. Nothing about "Object.lock(myObj)" suggests that future access to a non-existent property of myObj will throw. Also "lock" carries a well-established, unrelated meaning in computer science.
Could this be done with an additional argument to Object.seal(), Object.freeze(), and Object.preventExtensions()?Like so: "Object.seal(myObj, Object.THROW_ON_ABSENT_PROPERTY_READ)"--wordy, but the intent is unmistakable.
On Monday, August 14, 2017, 1:16:39 PM CDT, Alex Kodat <akodat at rocketsoftware.com> wrote:
#yiv9333647376 #yiv9333647376 -- _filtered #yiv9333647376 {panose-1:2 4 5 3 5 4 6 3 2 4;} _filtered #yiv9333647376 {font-family:Calibri;panose-1:2 15 5 2 2 2 4 3 2 4;} _filtered #yiv9333647376 {panose-1:2 11 6 9 4 5 4 2 2 4;}#yiv9333647376 #yiv9333647376 p.yiv9333647376MsoNormal, #yiv9333647376 li.yiv9333647376MsoNormal, #yiv9333647376 div.yiv9333647376MsoNormal {margin:0in;margin-bottom:.0001pt;font-size:12.0pt;}#yiv9333647376 a:link, #yiv9333647376 span.yiv9333647376MsoHyperlink {color:blue;text-decoration:underline;}#yiv9333647376 a:visited, #yiv9333647376 span.yiv9333647376MsoHyperlinkFollowed {color:purple;text-decoration:underline;}#yiv9333647376 p.yiv9333647376MsoListParagraph, #yiv9333647376 li.yiv9333647376MsoListParagraph, #yiv9333647376 div.yiv9333647376MsoListParagraph {margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:.5in;margin-bottom:.0001pt;font-size:12.0pt;}#yiv9333647376 p.yiv9333647376CodeExample, #yiv9333647376 li.yiv9333647376CodeExample, #yiv9333647376 div.yiv9333647376CodeExample {margin:0in;margin-bottom:.0001pt;font-size:12.0pt;color:#0070C0;}#yiv9333647376 p.yiv9333647376msonormal0, #yiv9333647376 li.yiv9333647376msonormal0, #yiv9333647376 div.yiv9333647376msonormal0 {margin-right:0in;margin-left:0in;font-size:12.0pt;}#yiv9333647376 span.yiv9333647376EmailStyle19 {color:#1F497D;}#yiv9333647376 .yiv9333647376MsoChpDefault {} _filtered #yiv9333647376 {margin:1.0in 1.0in 1.0in 1.0in;}#yiv9333647376 div.yiv9333647376WordSection1 {}#yiv9333647376 _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {margin-left:1.0in;} _filtered #yiv9333647376 {margin-left:1.25in;} _filtered #yiv9333647376 {margin-left:1.75in;} _filtered #yiv9333647376 {margin-left:2.25in;} _filtered #yiv9333647376 {margin-left:2.75in;} _filtered #yiv9333647376 {margin-left:3.25in;} _filtered #yiv9333647376 {margin-left:3.75in;} _filtered #yiv9333647376 {margin-left:4.25in;} _filtered #yiv9333647376 {margin-left:4.75in;} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {} _filtered #yiv9333647376 {}#yiv9333647376 ol {margin-bottom:0in;}#yiv9333647376 ul {margin-bottom:0in;}#yiv9333647376
FWIW, I’m not sure I agree with your OrdinaryGet steps. Also, not sure I like readExtensible as it doesn’t really have anything to do with extensibility. Maybe readStrict? But maybe I’m thinking about extensibility wrong?
In any case, I think the description of [[Get]] would have to be like (sorry, I’ve never done this sort of spec pseudo code so some of this is probably syntactically incorrect):
[[Get]] (P, Receiver, ReadStrict)
- Return ? OrdinaryGet(O, P, Receiver, ReadStrict).
And OrdinaryGet would be like:
OrdinaryGet (O, P, Receiver, ReadStrict)#
- Assert: IsPropertyKey(P) is true.
- Let desc be ? O.[[GetOwnProperty]](P).
- If desc is undefined, then
- Let readStrict be ? O.IsReadStrict(Receiver) || ReadStrict
- Let parent be ? O.[[GetPrototypeOf]]().
- If parent is null then
i. Assert: readStrict is false
ii. return undefined.
- Return ? parent.[[Get]](P, Receiver, readStrict).
- If IsDataDescriptor(desc) is true, return desc.[[Value]].
- Assert: IsAccessorDescriptor(desc) is true.
- Let getter be desc.[[Get]].
- If getter is undefined, return undefined.
- Return ? Call(getter, Receiver).
Probably adjustments need to be made to other references to [[Get]] and OrdinaryGet, passing false for ReadStrict.
I guess this pseudo code also points out an issue as to whether Object.lock would affect a dynamic property with no getter. Intuitively, it seems to me that it should.
------
Alex Kodat
Senior Product Architect
Rocket Software
t: +1 781 684 2294 • m: +1 315 527 4764 • w: www.rocketsoftware.com
From: T.J. Crowder [mailto:tj.crowder at farsightsoftware.com]
Sent: Monday, August 14, 2017 12:00 PM
To: Alex Kodat <akodat at rocketsoftware.com>
Cc: es-discuss at mozilla.org
Subject: Re: Object.seal, read references, and code reliability
On Mon, Aug 14, 2017 at 5:32 PM, Alex Kodat <akodat at rocketsoftware.com> wrote:
> Is there any reason that there’s no flavor of Object.seal that
> would throw an exception on read references to properties that are
> not found on the specified object?
This sounds like a good idea at a high level. Will be very interested to know what implementers have to say about it from an implementation perspective.
In spec terms, at first glance it's mostly just a new pair of steps in [OrdinaryGet ordinary object internal function][1] (added Step 3.a and 3.b):
```text
1. Assert: IsPropertyKey(P) is true.
2. Let desc be ? O.[[GetOwnProperty]](P).
3. If desc is undefined, then
a. Let readExtendable be ? IsReadExtensible(Receiver).
b. If readExtendable is false, throw TypeError.
c. Let parent be ? O.[[GetPrototypeOf]]().
d. If parent is null, return undefined.
e. Return ? parent.[[Get]](P, Receiver).
4. If IsDataDescriptor(desc) is true, return desc.[[Value]].
5. Assert: IsAccessorDescriptor(desc) is true.
6. Let getter be desc.[[Get]].
7. If getter is undefined, return undefined.
8. Return ? Call(getter, Receiver).
```
...where `IsReadExtensible` is an op to test the new flag. *(Used `pre` markdown to avoid the `[[...](.)` being treated as links without having to add `\` for those not reading the rendered version.)*
One concern is people already have trouble keeping sealed and frozen straight (or is that just me?). Adding a locked (or whatever) makes that even more confusing. But the semantics of sealed and frozen can't be changed to include this now.
-- T.J. Crowder
[1]: https://tc39.github.io/ecma262/#sec-ordinaryget
================================
Rocket Software, Inc. and subsidiaries ■ 77 Fourth Avenue, Waltham MA 02451 ■ Main Office Toll Free Number: +1 877.328.2932
Contact Customer Support: https://my.rocketsoftware.com/RocketCommunity/RCEmailSupport
Unsubscribe from Marketing Messages/Manage Your Subscription Preferences - http://www.rocketsoftware.com/manage-your-email-preferences
Privacy Policy - http://www.rocketsoftware.com/company/legal/privacy-policy
================================
This communication and any attachments may contain confidential information of Rocket Software, Inc. All unauthorized use, disclosure or distribution is prohibited. If you are not the intended recipient, please notify Rocket Software immediately and destroy all copies of this communication. Thank you.
_______________________________________________
es-discuss mailing list
es-discuss at mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170814/3399adf3/attachment-0001.html>
More information about the es-discuss
mailing list