Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-03-18 Thread Tom Van Cutsem
Ok, somehow I had completely missed 9.3.10 TestIntegrityLevel (O, level)
which does exactly the derived computation for sealed and frozen objects.

I think André is right though about the bug in 8.3.3 step 2.a.

Cheers,
Tom

2013/3/17 Allen Wirfs-Brock al...@wirfs-brock.com

 Tom recently suggested that that we really don't need MOP-level or trap
 operations from freezing, sealing and testing those states.  Also, there
 seems to be minimal support for having explicit freeze/sealed integrity
 states or for adding integrity integrity states.  So I'm probably going to
 go make to an style design.  We'll only have [[IsExtensible]] and
 [[PreventExtensions]] MOP/trap/Reflect operations.
  Object.freeze/seal/isFrozen/isSealed will be derived operations.

 Allen



 On Mar 17, 2013, at 10:16 AM, Tom Van Cutsem wrote:

 Hi,

 Allen's latest draft (Rev. 14) contains the change where
 [[Freeze]],[[Seal]] and [[PreventExtensions]] have been consolidated into
 [[HasIntegrity]]/[[SetIntegrity]]. While no changes were made to the Proxy
 API (i.e. no has/getIntegrity traps yet), the definition of
 Object.{freeze,seal,preventExtensions} did change, and this is sufficient
 to expose an incompatibility with ES5, namely:

 Object.isFrozen(Object.preventExtensions({})) // true in ES5, false in ES6
 Rev14 draft

 I still feel like the consolidation isn't worth this incompatibility.

  Allen, could you clarify what your intent is? Is it your intent that
 this incompatibility will be fixed with further spec changes?

 Cheers,
 Tom

 2013/2/21 Brendan Eich bren...@mozilla.com

 Tom Van Cutsem wrote:

 That said, I don't think this is enough evidence either for or against
 the breaking change.


 I have a hard time believing we can break ES5. It has been shipping for
 years (plural, at least in one case) in major browsers that evergreen their
 user bases.

 /be




___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-03-18 Thread Tom Van Cutsem
Allen and I had a conversation that clarified things.

Essentially, the plan is to only have
[[PreventExtensions]]/[[IsExtensible]] internal MOP methods, and to only
have the corresponding preventExtensions/isExtensible traps for proxies.

Proxies won't have isSealed, isFrozen, seal and frozen traps and there will
be no corresponding Reflect.{isSealed,isFrozen,seal,frozen} methods.

Calling Object.freeze(proxy) instead triggers the proxy's
getOwnPropertyNames trap and then updates each own property of the proxy
via defineProperty. Similar story for Object.isFrozen(proxy).

Pro:
- We get rid of 4 MOP methods
([[Freeze]],[[Seal]],[[IsFrozen]],[[IsSealed]]). This simplifies both the
internal MOP and the Proxy API.
- Freezing and sealing always behave consistently, even in the face of
proxies. There's no chance for a proxy to implement multiple traps
inconsistently.

Con:
- Object.freeze(proxy) and Object.isFrozen(proxy) must observably iterate
over all own properties of the proxy (same for seal/isSealed).

Cheers,
Tom

2013/3/18 Tom Van Cutsem tomvc...@gmail.com

 Ok, somehow I had completely missed 9.3.10 TestIntegrityLevel (O, level)
 which does exactly the derived computation for sealed and frozen objects.

 I think André is right though about the bug in 8.3.3 step 2.a.

 Cheers,
 Tom


 2013/3/17 Allen Wirfs-Brock al...@wirfs-brock.com

 Tom recently suggested that that we really don't need MOP-level or trap
 operations from freezing, sealing and testing those states.  Also, there
 seems to be minimal support for having explicit freeze/sealed integrity
 states or for adding integrity integrity states.  So I'm probably going to
 go make to an style design.  We'll only have [[IsExtensible]] and
 [[PreventExtensions]] MOP/trap/Reflect operations.
  Object.freeze/seal/isFrozen/isSealed will be derived operations.

 Allen



 On Mar 17, 2013, at 10:16 AM, Tom Van Cutsem wrote:

 Hi,

 Allen's latest draft (Rev. 14) contains the change where
 [[Freeze]],[[Seal]] and [[PreventExtensions]] have been consolidated into
 [[HasIntegrity]]/[[SetIntegrity]]. While no changes were made to the Proxy
 API (i.e. no has/getIntegrity traps yet), the definition of
 Object.{freeze,seal,preventExtensions} did change, and this is sufficient
 to expose an incompatibility with ES5, namely:

 Object.isFrozen(Object.preventExtensions({})) // true in ES5, false in
 ES6 Rev14 draft

 I still feel like the consolidation isn't worth this incompatibility.

  Allen, could you clarify what your intent is? Is it your intent that
 this incompatibility will be fixed with further spec changes?

 Cheers,
 Tom

 2013/2/21 Brendan Eich bren...@mozilla.com

 Tom Van Cutsem wrote:

 That said, I don't think this is enough evidence either for or against
 the breaking change.


 I have a hard time believing we can break ES5. It has been shipping for
 years (plural, at least in one case) in major browsers that evergreen their
 user bases.

 /be





___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-03-17 Thread Tom Van Cutsem
Hi,

Allen's latest draft (Rev. 14) contains the change where
[[Freeze]],[[Seal]] and [[PreventExtensions]] have been consolidated into
[[HasIntegrity]]/[[SetIntegrity]]. While no changes were made to the Proxy
API (i.e. no has/getIntegrity traps yet), the definition of
Object.{freeze,seal,preventExtensions} did change, and this is sufficient
to expose an incompatibility with ES5, namely:

Object.isFrozen(Object.preventExtensions({})) // true in ES5, false in ES6
Rev14 draft

I still feel like the consolidation isn't worth this incompatibility.

Allen, could you clarify what your intent is? Is it your intent that this
incompatibility will be fixed with further spec changes?

Cheers,
Tom

2013/2/21 Brendan Eich bren...@mozilla.com

 Tom Van Cutsem wrote:

 That said, I don't think this is enough evidence either for or against
 the breaking change.


 I have a hard time believing we can break ES5. It has been shipping for
 years (plural, at least in one case) in major browsers that evergreen their
 user bases.

 /be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-03-17 Thread André Bargull
The incompatibility you've noticed is just a spec bug in 
[[HasIntegrity]]. In step 2a of 8.3.3, the value of [[Extensible]] needs 
to be inverted. With that change applied, the code snippet will return 
`true`.


- André



Hi,

Allen's latest draft (Rev. 14) contains the change where
[[Freeze]],[[Seal]] and [[PreventExtensions]] have been consolidated into
[[HasIntegrity]]/[[SetIntegrity]]. While no changes were made to the Proxy
API (i.e. no has/getIntegrity traps yet), the definition of
Object.{freeze,seal,preventExtensions} did change, and this is sufficient
to expose an incompatibility with ES5, namely:

Object.isFrozen(Object.preventExtensions({})) // true in ES5, false in ES6
Rev14 draft

I still feel like the consolidation isn't worth this incompatibility.

Allen, could you clarify what your intent is? Is it your intent that this
incompatibility will be fixed with further spec changes?

Cheers,
Tom

2013/2/21 Brendan Eich brendan at mozilla.com  
https://mail.mozilla.org/listinfo/es-discuss

/  Tom Van Cutsem wrote:
//
//  That said, I don't think this is enough evidence either for or against
//  the breaking change.
//
//
//  I have a hard time believing we can break ES5. It has been shipping for
//  years (plural, at least in one case) in major browsers that evergreen their
//  user bases.
//
//  /be
/
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-03-17 Thread Allen Wirfs-Brock
Tom recently suggested that that we really don't need MOP-level or trap 
operations from freezing, sealing and testing those states.  Also, there seems 
to be minimal support for having explicit freeze/sealed integrity states or for 
adding integrity integrity states.  So I'm probably going to go make to an 
style design.  We'll only have [[IsExtensible]] and [[PreventExtensions]] 
MOP/trap/Reflect operations.  Object.freeze/seal/isFrozen/isSealed will be 
derived operations.

Allen


On Mar 17, 2013, at 10:16 AM, Tom Van Cutsem wrote:

 Hi,
 
 Allen's latest draft (Rev. 14) contains the change where [[Freeze]],[[Seal]] 
 and [[PreventExtensions]] have been consolidated into 
 [[HasIntegrity]]/[[SetIntegrity]]. While no changes were made to the Proxy 
 API (i.e. no has/getIntegrity traps yet), the definition of 
 Object.{freeze,seal,preventExtensions} did change, and this is sufficient to 
 expose an incompatibility with ES5, namely:
 
 Object.isFrozen(Object.preventExtensions({})) // true in ES5, false in ES6 
 Rev14 draft
 
 I still feel like the consolidation isn't worth this incompatibility.
 
 Allen, could you clarify what your intent is? Is it your intent that this 
 incompatibility will be fixed with further spec changes?
 
 Cheers,
 Tom
 
 2013/2/21 Brendan Eich bren...@mozilla.com
 Tom Van Cutsem wrote:
 That said, I don't think this is enough evidence either for or against the 
 breaking change.
 
 I have a hard time believing we can break ES5. It has been shipping for years 
 (plural, at least in one case) in major browsers that evergreen their user 
 bases.
 
 /be
 

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-21 Thread Brendan Eich

Tom Van Cutsem wrote:
That said, I don't think this is enough evidence either for or against 
the breaking change.


I have a hard time believing we can break ES5. It has been shipping for 
years (plural, at least in one case) in major browsers that evergreen 
their user bases.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Tom Van Cutsem
2013/2/18 Andreas Rossberg rossb...@google.com

 On 16 February 2013 20:36, Allen Wirfs-Brock al...@wirfs-brock.com
 wrote:

   It's to simplify the MOP and that simplification is directly reflected
 as a simplification to the Proxy hander interface. Instead of  6 traps
 (preventExtensions, isExtensible, freeze, isFrozen, seal, isSealed) only
 two are needed.
 
  Also, having an explicit frozen object state simplifies some of the
 object invariants which would otherwise perform explicitly specified
 accesses to the target object which would be observable (if the target is
 itself a proxy).

 Well, that is either a breaking change, such that implementations can
 not actually be lazy about it, or it doesn't really remove complexity,
 since you still need to infer the state as a fallback (i.e., it's just
 an optimisation).

 I don't necessarily oppose making that breaking change, but we have to
 be aware that, even though it's an optimisation, the change is yet
 another complication of the object model. The additional state
 modifies the meaning of per-property descriptors on a second level.
 IIUC, defineProperty now has to check against that state, and
 getOwnPropertyDescriptor somehow has to take it into account, too. For
 direct proxies, the respective traps have to extend their validation
 logic. Overall, not a simplification, as far as I can see.


I've been thinking some more about get/setIntegrity and I've come to the
same conclusion. While get/setIntegrity gets rid of 4 traps
(sealed/isSealed/frozen/isFrozen), it does so at the expense of extra
complexity in other parts of the MOP, in particular, adding yet more state
to check and update in [[GetOwnProperty]] and [[DefineOwnProperty]].

Allen, in light of this, wouldn't you agree that it's better to keep the
extra traps?

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Allen Wirfs-Brock

On Feb 20, 2013, at 9:24 AM, Tom Van Cutsem wrote:

 2013/2/18 Andreas Rossberg rossb...@google.com
 On 16 February 2013 20:36, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 
   It's to simplify the MOP and that simplification is directly reflected as 
 a simplification to the Proxy hander interface. Instead of  6 traps 
 (preventExtensions, isExtensible, freeze, isFrozen, seal, isSealed) only two 
 are needed.
 
  Also, having an explicit frozen object state simplifies some of the object 
  invariants which would otherwise perform explicitly specified accesses to 
  the target object which would be observable (if the target is itself a 
  proxy).
 
 Well, that is either a breaking change, such that implementations can
 not actually be lazy about it, or it doesn't really remove complexity,
 since you still need to infer the state as a fallback (i.e., it's just
 an optimisation).
 
 I don't necessarily oppose making that breaking change, but we have to
 be aware that, even though it's an optimisation, the change is yet
 another complication of the object model. The additional state
 modifies the meaning of per-property descriptors on a second level.
 IIUC, defineProperty now has to check against that state, and
 getOwnPropertyDescriptor somehow has to take it into account, too. For
 direct proxies, the respective traps have to extend their validation
 logic. Overall, not a simplification, as far as I can see.
 
 I've been thinking some more about get/setIntegrity and I've come to the same 
 conclusion. While get/setIntegrity gets rid of 4 traps 
 (sealed/isSealed/frozen/isFrozen), it does so at the expense of extra 
 complexity in other parts of the MOP, in particular, adding yet more state to 
 check and update in [[GetOwnProperty]] and [[DefineOwnProperty]].
 
 Allen, in light of this, wouldn't you agree that it's better to keep the 
 extra traps?

Actually, no.  Reducing API complexity (in this case, the Proxy handler API) at 
the expense of a little bit of added spec. complexity seems like a very 
reasonable trade-off.  Plus, we are talking about spec. complexity, not 
necessarily implementation complexity.  An implementation is free to distribute 
the complexity however it chooses.  For example, if an implementation always 
sets all of an objet's  property descriptors to configurable: false when 
[[SetIntegrity]](frozen) is performed (which Object.freeze is specified to do 
in ES5) then there shouldn't be any extra work that needs to be done in the 
ordinary implementations of  [[GetOwnProperty]] or [[DefineOwnProperty]].

Also, I'm concerned that we have been overloading the meaning of the 
[[Extensible]] state by hanging other meanings off of it, because it is the 
only integrity state we currently have at the object level.  For example, we 
have tentative agreement at the timevalue of Date objects can not be modified 
if [[Extensible]] is false and that RegExp.prototype.compile will not update an 
RegExp instance if [[Extensible]] is false.  Both of these seem like things 
that would be better to associate with an explicit frozen object state. We 
are also, from ES5, using [[Extensible]] to control whether [[Prototype]] can 
be modified.  This is a case where I think a new state might be appropriate as 
it seems very reasonable for an object to want to fix [[Prototype]] but still 
allow own properties to be added

Finally, I still think we should further consider the feasibly of a breaking 
change where 
 Object.preventExtensions(obj); for ( let k of 
Object.getOwnPropertyKeys(obj)) 
Object.defineProperty(obj,k,{configurable:false});
is no longer equivalent to 
  Object.freeze(obj)
in terms of causing Object.isFrozen(obj) to return false.

I think I previously asked if anybody is aware of situations where 
Object.isFrozen tests are done but Object.freeze is not used to set objects to 
the frozen state.  So far, no answers.  Anybody?

Allen







 
 Cheers,
 Tom

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Nathan Wall
Allen Wirfs-Brock wrote:
 I think I previously asked if anybody is aware of situations where 
 Object.isFrozen tests are done but Object.freeze is not used to set 
 objects to the frozen state. So far, no answers. Anybody? 

Speaking just from my own experience as a user of ES5, I have not found 
`Object.isFrozen` to be helpful yet.  If I want to see if I can configure a 
property, I check `Object.isExtensible` and 
`!Object.prototype.hasOwnProperty.call(obj, key) || 
Object.getOwnPropertyDescriptor(obj, key).configurable`.

`Object.isFrozen` and `Object.isSealed` don't really seem that helpful to me 
for the very reasons you've discussed: They don't represent any real object 
state, so they don't accurately tell me what can be done with an object.  If I 
could I would argue in favor of their removal, though I know it's too late for 
that.

I would be curious to see legitimate uses of `isFrozen` and `isSealed` in 
existing code if anyone has anything to offer.

Nathan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Kevin Reid
On Wed, Feb 20, 2013 at 11:52 AM, Nathan Wall nathan.w...@live.com wrote:

 `Object.isFrozen` and `Object.isSealed` don't really seem that helpful to
 me for the very reasons you've discussed: They don't represent any real
 object state, so they don't accurately tell me what can be done with an
 object.  If I could I would argue in favor of their removal, though I know
 it's too late for that.

 I would be curious to see legitimate uses of `isFrozen` and `isSealed` in
 existing code if anyone has anything to offer.


I just took a look at uses of Object.isFrozen in Caja and I find that all
but one are either in tests (test that something is frozen) or in sanity
checks (if this isn't frozen, do not proceed further, or freeze it and
warn).

The remaining one is in a WeakMap abstraction used for trademarking: an
object cannot be given a trademark after it is frozen. (The rationale here,
while not written down, I assume is that a defensive object's “interface”
should not change, and it is an implementation detail that this particular
information is not stored in the object.) There is a comment there
suggesting we might strengthen this check to only permitting _extensible_
objects to be marked.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread David Bruant

Le 20/02/2013 21:08, Kevin Reid a écrit :
On Wed, Feb 20, 2013 at 11:52 AM, Nathan Wall nathan.w...@live.com 
mailto:nathan.w...@live.com wrote:


`Object.isFrozen` and `Object.isSealed` don't really seem that
helpful to me for the very reasons you've discussed: They don't
represent any real object state, so they don't accurately tell me
what can be done with an object.  If I could I would argue in
favor of their removal, though I know it's too late for that.

I would be curious to see legitimate uses of `isFrozen` and
`isSealed` in existing code if anyone has anything to offer.


I just took a look at uses of Object.isFrozen in Caja and I find that 
all but one are either in tests (test that something is frozen) or in 
sanity checks (if this isn't frozen, do not proceed further, or freeze 
it and warn).


The remaining one is in a WeakMap abstraction used for trademarking: 
an object cannot be given a trademark after it is frozen. (The 
rationale here, while not written down, I assume is that a defensive 
object's interface should not change, and it is an implementation 
detail that this particular information is not stored in the object.) 
There is a comment there suggesting we might strengthen this check to 
only permitting _extensible_ objects to be marked.

And in an ES6 world, you'll probably use an actual WeakMap anyway?

Thanks for sharing this experience from Caja,

David

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Kevin Reid
On Wed, Feb 20, 2013 at 12:15 PM, David Bruant bruan...@gmail.com wrote:

 And in an ES6 world, you'll probably use an actual WeakMap anyway?


Using an actual WeakMap does not change matters: the intent is that after
Object.freeze(o), you can't add new trademarks to o. Since the trademark
info is not stored on the object but in the WeakMap (whether emulated or
actual), we have to add an explicit test.

If 'private properties' (in whatever form they come to ES6) were available
to us, then it would be natural to use them instead for this purpose (at
least, so it seems to me at the moment) and so we would not need a test
since non-extensibility would presumably reject the addition of a new
private property.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Mark S. Miller
(I do not yet have an overall opinion about get/setIntegrity. Here, I'm
just answering and clarifying, not advocating.)


On Wed, Feb 20, 2013 at 10:57 AM, Allen Wirfs-Brock
al...@wirfs-brock.comwrote:
[...]

 Also, I'm concerned that we have been overloading the meaning of the
 [[Extensible]] state by hanging other meanings off of it, because it is the
 only integrity state we currently have at the object level.  For example,
 we have tentative agreement at the timevalue of Date objects can not be
 modified if [[Extensible]] is false and that RegExp.prototype.compile will
 not update an RegExp instance if [[Extensible]] is false.  Both of these
 seem like things that would be better to associate with an explicit
 frozen object state.


Another instance of the same issue in a different guise is the restriction
in Object.observe (for ES7) that you cannot obtain from a frozen object the
right to notify its observers. In this case, in order to be more
permissive, we did attach the restriction to frozenness rather than just
extensibility. However, when frozenness is a complex test for a pattern of
restrictions that may or may not be accidental, this seems weird.

In other words, if an object is purposely frozen, no problem. But let's say
that in v1 of a program, object A is non-extensible, its foo property is
non-configurable, non-writable, and its bar property is writable. A later
refactoring realizes it doesn't need the bar property, and so deletes it.
It is weird that this would break previously correct code to obtain the
right to notify observers.



 We are also, from ES5, using [[Extensible]] to control whether
 [[Prototype]] can be modified.  This is a case where I think a new state
 might be appropriate as it seems very reasonable for an object to want to
 fix [[Prototype]] but still allow own properties to be added


While sensible in theory, I don't think that case is worth yet another
state bit. If, like Object.observe, we had attached this restriction to
frozenness, we could not consider attaching this to an explicit frozenness
bit.



 Finally, I still think we should further consider the feasibly of a
 breaking change where
  Object.preventExtensions(obj); for ( let k of
 Object.getOwnPropertyKeys(obj))
 Object.defineProperty(obj,k,{configurable:false});
 is no longer equivalent to
   Object.freeze(obj)
 in terms of causing Object.isFrozen(obj) to return false.

 I think I previously asked if anybody is aware of situations where
 Object.isFrozen tests are done but Object.freeze is not used to set objects
 to the frozen state.  So far, no answers.  Anybody?


I know of no uses of Object.isFrozen beyond those Kevin lists. None of
these would be broken by this change.

As for the rationale for the trademark restriction, more on that in a
separate email.


-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:
Actually, no.  Reducing API complexity (in this case, the Proxy 
handler API) at the expense of a little bit of added spec. complexity 
seems like a very reasonable trade-off.  Plus, we are talking about 
spec. complexity, not necessarily implementation complexity.


Sure, but the spec is the first implementation. If implementors will 
not add another state bit (I predict they won't) then the spec is doing 
a disservice here.


The Proxy API is complex already, due to ES5 in this case. It is not 
that much less complex with setIntegrity. I don't think the trade-off is 
worth it, and I suggest the all implementors ignore the spec 
complexity condition is one to avoid.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: get/setIntegrity trap (Was: A case for removing the seal/freeze/isSealed/isFrozen traps)

2013-02-20 Thread Tom Van Cutsem
2013/2/20 Allen Wirfs-Brock al...@wirfs-brock.com

 Finally, I still think we should further consider the feasibly of a
 breaking change where
  Object.preventExtensions(obj); for ( let k of
 Object.getOwnPropertyKeys(obj))
 Object.defineProperty(obj,k,{configurable:false});
 is no longer equivalent to
   Object.freeze(obj)
 in terms of causing Object.isFrozen(obj) to return false.

 I think I previously asked if anybody is aware of situations where
 Object.isFrozen tests are done but Object.freeze is not used to set objects
 to the frozen state.  So far, no answers.  Anybody?


I did a little code search via GitHub on uses of Object.isFrozen in JS
code. The large majority seems to occur in test cases (incl. Test262) or
libraries involving ES5 shims for ES3. There's no doubt this breaking
change will get noticed, as Test262 contains code such as:

assertEq(Object.isFrozen(Object.preventExtensions({})), true);

However, here and there you can find some code that branches on frozenness,
although it's not always clear what the rationale behind it is, e.g.:

https://github.com/petekinnecom/portfolio_chaplin/blob/b241300968fe6011c54548f24e0c8cfcd5d6d663/app/views/tube_view.coffee#L39


That said, I don't think this is enough evidence either for or against the
breaking change.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-18 Thread Andreas Rossberg
On 16 February 2013 20:36, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 On Feb 14, 2013, at 11:46 AM, Andreas Rossberg wrote:

 On 14 February 2013 01:05, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 Where do without, means replaced with  set/getIntegrity traps and objects
 have explicit internal state whose value is one of
 normal/non-extensible/sealed/frozen  (and possibly)  fixed-inheritance
 between normal and non-extensible to freeze [[Prototype]]).

 [[SetIntegrity]] can increase the integrity level but not decrease it.

 The perf and invariant complexity concerns come from the fact that the
 sealed/frozen status of an object can only be inferred by inspecting all of
 its methods. Having an explicit state eliminates the need to do this
 inspection.  It also simplifies the MOP by merging all of the
 extensible/sealed/frozen related MOP operations into only two ops.  But, one
 way or another, these object state transitions must be accounted for in the
 MOP.

 For this to fly, implementation have to be able to expand their current 1
 bit of of extensible state to at least 2 bits (3 would be better).  Or
 perhaps not, I suppose we could just introduce the MOP level changes and a
 lazy implementation could continue to infer the state by examining all its
 methods.

 I still must be missing something. Why should the language be changed
 when the proposed change is equivalent anyway? Why is this an
 optimisation that the spec should worry about instead of the
 implementations?

 It's to simplify the MOP and that simplification is directly reflected as a 
 simplification to the Proxy hander interface. Instead of  6 traps 
 (preventExtensions, isExtensible, freeze, isFrozen, seal, isSealed) only two 
 are needed.

 Also, having an explicit frozen object state simplifies some of the object 
 invariants which would otherwise perform explicitly specified accesses to the 
 target object which would be observable (if the target is itself a proxy).

Well, that is either a breaking change, such that implementations can
not actually be lazy about it, or it doesn't really remove complexity,
since you still need to infer the state as a fallback (i.e., it's just
an optimisation).

I don't necessarily oppose making that breaking change, but we have to
be aware that, even though it's an optimisation, the change is yet
another complication of the object model. The additional state
modifies the meaning of per-property descriptors on a second level.
IIUC, defineProperty now has to check against that state, and
getOwnPropertyDescriptor somehow has to take it into account, too. For
direct proxies, the respective traps have to extend their validation
logic. Overall, not a simplification, as far as I can see.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-18 Thread Nathan Wall
David Bruant wrote:
 ...
 Security is very loaded with emotions of people afraid to have their
 password stolen and cyber attacks. It's also loaded with the notion of
 human safety and human integrity which, as human beings are sensitive to.
 Maybe I should start using a different word...


Great explanation, David. That's everything I've wanted to say but haven't been 
able to find the words. Thanks for this!

Also, I've started using the word integrity to describe this kind of code, to 
get away from the loadedness of security.  For instance, Mark Miller's 
low-integrity puzzle[1]:

    function makeTable() {
      var array = [];
      return Object.freeze({
        add: function(v) { array.push(v); },
        store: function(i, v) { array[i] = v; },
        get: function(i) { return array[i]; }
      });
    }

as a high-integrity function:

    var freeze = Object.freeze,
        push = Function.prototype.call.bind(Array.prototype.push);
    function makeTable() {
      var array = [];
      return freeze({
        add: function(v) { push(array, v); },
        store: function(i, v) { array[i  0] = v; },
        get: function(i) { return array[i  0]; }
      });
    }

Of course, you don't want to write this way all the time. I think it's good for 
library code.

[1] http://mail.mozilla.org/pipermail/es-discuss/2011-November/017964.html

Nathan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-18 Thread Claus Reinke

as a high-integrity function:

var freeze = Object.freeze,
push = Function.prototype.call.bind(Array.prototype.push);
function makeTable() {
  var array = [];
  return freeze({
add: function(v) { push(array, v); },
store: function(i, v) { array[i  0] = v; },
get: function(i) { return array[i  0]; }
  });
}


Careful there, you're not done!-) With nodejs, adding the following

   var table = makeTable();
   table.add(1);
   table.add(2);
   table.add(3);

   var secret;
   Object.defineProperty(Array.prototype,42,{get:function(){ secret = this;}});

   table.get(42);
   console.log(secret);
   secret[5] = me, too!;

   console.log( table.get(5) );

to your code prints

   $ node integrity.js
   [ 1, 2, 3 ]
   me, too!

Couldn't resist,
Claus

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-18 Thread Nathan Wall
Claus Reinke wrote:
 Careful there, you're not done!-) With nodejs, adding the following

 var table = makeTable();
 table.add(1);
 table.add(2);
 table.add(3);

 var secret;
 Object.defineProperty(Array.prototype,42,{get:function(){ secret = this;}});

 table.get(42);
 console.log(secret);
 secret[5] = me, too!;

 console.log( table.get(5) );

 to your code prints

 $ node integrity.js
 [ 1, 2, 3 ]
 me, too!

 Couldn't resist,
 Claus


Nice! This is not something I had considered. Aside from freezing 
Array.prototype, I can only really think of one solution: not use an array.

    var create = Object.create,
        freeze = Object.freeze,
        push = Function.prototype.call.bind(Array.prototype.push);
    function makeTable() {
      var array = create(null);
      return freeze({
        add: function(v) { push(array, v); },
        store: function(i, v) { array[i  0] = v; },
        get: function(i) { return array[i  0]; }
      });
    }

I suppose the array isn't really needed since we're not using methods inherited 
from Array.prototype. Downside: Browsers won't know to optimize the object as 
an array.

(Side note: Mark's original post was in the context of frozen Array.prototype 
on non-compliant implementations which allow writing to inherited non-writable 
properties. I find this a fun exercise without frozen Array.prototype, though.)

Nathan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-18 Thread Mark S. Miller
On Mon, Feb 18, 2013 at 2:27 PM, Nathan Wall nathan.w...@live.com wrote:

 Claus Reinke wrote:
  Careful there, you're not done!-) With nodejs, adding the following
 
  var table = makeTable();
  table.add(1);
  table.add(2);
  table.add(3);
 
  var secret;
  Object.defineProperty(Array.prototype,42,{get:function(){ secret =
 this;}});
 
  table.get(42);
  console.log(secret);
  secret[5] = me, too!;
 
  console.log( table.get(5) );
 
  to your code prints
 
  $ node integrity.js
  [ 1, 2, 3 ]
  me, too!
 
  Couldn't resist,
  Claus
 

 Nice! This is not something I had considered. Aside from freezing
 Array.prototype, I can only really think of one solution: not use an array.

 var create = Object.create,
 freeze = Object.freeze,
 push = Function.prototype.call.bind(Array.prototype.push);
 function makeTable() {
   var array = create(null);
   return freeze({
 add: function(v) { push(array, v); },
 store: function(i, v) { array[i  0] = v; },


In all seriousness, I suggest
array[+i] = v;
rather than
array[i  0] = v;
because the latter is too verbose to become a habit. I recommend this even
though I agree that the more verbose one has the better semantics.



 get: function(i) { return array[i  0]; }
   });
 }

 I suppose the array isn't really needed since we're not using methods
 inherited from Array.prototype. Downside: Browsers won't know to optimize
 the object as an array.

 (Side note: Mark's original post was in the context of frozen
 Array.prototype on non-compliant implementations which allow writing to
 inherited non-writable properties. I find this a fun exercise without
 frozen Array.prototype, though.)


Note that Jorge's attack at
https://mail.mozilla.org/pipermail/es-discuss/2011-November/017979.htmlworks
even on compliant browsers.




 Nathan
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-16 Thread Allen Wirfs-Brock

On Feb 14, 2013, at 11:46 AM, Andreas Rossberg wrote:

 On 14 February 2013 01:05, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 Where do without, means replaced with  set/getIntegrity traps and objects
 have explicit internal state whose value is one of
 normal/non-extensible/sealed/frozen  (and possibly)  fixed-inheritance
 between normal and non-extensible to freeze [[Prototype]]).
 
 [[SetIntegrity]] can increase the integrity level but not decrease it.
 
 The perf and invariant complexity concerns come from the fact that the
 sealed/frozen status of an object can only be inferred by inspecting all of
 its methods. Having an explicit state eliminates the need to do this
 inspection.  It also simplifies the MOP by merging all of the
 extensible/sealed/frozen related MOP operations into only two ops.  But, one
 way or another, these object state transitions must be accounted for in the
 MOP.
 
 For this to fly, implementation have to be able to expand their current 1
 bit of of extensible state to at least 2 bits (3 would be better).  Or
 perhaps not, I suppose we could just introduce the MOP level changes and a
 lazy implementation could continue to infer the state by examining all its
 methods.
 
 I still must be missing something. Why should the language be changed
 when the proposed change is equivalent anyway? Why is this an
 optimisation that the spec should worry about instead of the
 implementations?

It's to simplify the MOP and that simplification is directly reflected as a 
simplification to the Proxy hander interface. Instead of  6 traps 
(preventExtensions, isExtensible, freeze, isFrozen, seal, isSealed) only two 
are needed.

Also, having an explicit frozen object state simplifies some of the object 
invariants which would otherwise perform explicitly specified accesses to the 
target object which would be observable (if the target is itself a proxy). 

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-16 Thread Allen Wirfs-Brock

On Feb 14, 2013, at 1:14 AM, Tom Van Cutsem wrote:

 2013/2/14 Allen Wirfs-Brock al...@wirfs-brock.com
 
 On Feb 13, 2013, at 12:53 PM, David Bruant wrote:
 
 Interesting.
 
 So what would happen when calling Object.isFrozen on a proxy? Would 
 Object.isFrozen/isSealed/isExtensible reach out directly to the target? or a 
 unique state trap returning a string for all of them? (state is too 
 generic of a name, but you get the idea)
 
 This is a question regarding proxy design, rather than the MOP. Either 
 get/setIntegrity traps to the handler or it forwards directly to the target.  
 That's would be a design issue for Tom, but my starting point is to simply 
 follow the current design decisions made for 
 [[PreventExtensions]]/[[IsExtensible]]
 
 A get/setIntegrity trap with the invariant constraints of 
 isExtensible/preventExtensions would be the obvious path to take.
 
 One thing that remains unclear to me: if the state of an object becomes 
 explicit, we introduce the risk for this state to become inconsistent with 
 the state from which it is derived.
 
 For example, setting the integrity of an object to frozen must still make 
 all own properties non-configurable, i.e.
 
 Reflect.setIntegrity(obj, frozen)
 
 should have the same effect as
 
 Object.freeze(obj)

yes, Object.freeze(obj) would be specified as performing:  
obj.[[SetIntegrity]](frozen)

 
 Likewise, turning the last configurable property of a non-extensible object 
 into a non-configurable property should automagically change the state to 
 frozen, i.e.
 
 Object.defineProperty(obj, lastProperty, { configurable: false }) // must 
 update internal state as well as the property
 Reflect.getIntegrity(obj) === frozen

If I was starting fresh, I would say that Object.isFrozen(obj) is true only if 
Object.freeze(obj) (or equivalent Reflect.setIntegrity) has previous been 
performed and that Object.preventExtensions() followed by setting every 
property to non-configurable is not equivalent to performing Object.freeze. 

I wonder if we can make that change for ES6 without breaking anything.  Does 
anybody know of code that does Object.isFrozen(obj) checks without also having 
the expectation that obj would have been explicitly frozen using Object.freeze?


 
 Will this not just shift the current complexity someplace else?

Well, it means that for 100% backwards compatibility, Object.isFrozen would 
have to be something like:

1.  Let state = obj.[[GetIntegrity]]();
2   If state is frozen return true;
3   If state is sealed or non-extensible, then return true if all 
properties are non-configurable and  non-writable
4  return false.

The real complexity saving is in simplifying the MOP/Proxy handler interface 
and also in making Proxy invariants  only sensitive to the explicit integrity 
state of an object.


 
 Regardless on the final decision on (full) notification proxies, maybe these 
 operations (isSealed/isFrozen) could have notification trap. The invariant 
 is that the answer has to be the target one (all the time), so the trap 
 return value is irrelevant. Like the getPrototypeOf trap.
 
 Right, one way or another these operations need to be part of the MOP.
 
 If we go for get/setIntegrity I wouldn't re-introduce all the derived 
 operations as notification traps. Then we might as well leave things the way 
 they are.

I meant either get/setIntegrity or 
isExtensible/preventExtensions/isFrozen/freeze/isSealed/seal need to be part of 
the MOP.  If we have get/setIntegrity we don't need the others (at the 
MOP/proxy trap level)

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-16 Thread David Bruant

Le 16/02/2013 23:31, Allen Wirfs-Brock a écrit :

Will this not just shift the current complexity someplace else?
Well, it means that for 100% backwards compatibility, Object.isFrozen 
would have to be something like:


1.  Let state = obj.[[GetIntegrity]]();
2   If state is frozen return true;
3   If state is sealed or non-extensible, then return true if all 
properties are non-configurable and  non-writable

nit: You can save the state to frozen before returning true.

4  return false.

The real complexity saving is in simplifying the MOP/Proxy handler 
interface and also in making Proxy invariants  only sensitive to the 
explicit integrity state of an object.


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread Mariusz Nowak

I've worked a lot with ECMAScript5 features in last two years, and I must say
I never found a good use case for Object.freeze/seal/preventExtensions, it
actually raised more issues than it actually helped (those few times when I
decided to use it). Currently I think that's not JavaScript'y approach and
use cases mentioning untrusted parties sounds logical just in theory, in
practice when actually we never include untrusted modules in our code base
does not make much sense.

However, main point I want to raise is that several times I had a use case
for very close functionality, that with current API seem not possible: 
I'd like to be able to *prevent accidental object extensions*. I want to
control all enumerable properties of the object, so they can only be set via
defineProperty, but any direct assignment of non existing prop e.g.
'x.notDefinedYet = value'  will throw. Imagine some ORM implementation, that
via setters propagates changes to underlying persistent layer, at this time
we cannot prevent accidental property sets that may occur before property
was actually defined (therefore not caught by the setter)
I assume that proxies will make such functionality possible, but maybe some
Object.preventUndefinedExtensions will be even better.


Brendan Eich-3 wrote:
 
 Andreas Rossberg wrote:
 On 14 February 2013 19:16, David Bruantbruan...@gmail.com  wrote:
 Le 14/02/2013 18:11, Andreas Rossberg a écrit :
 You're being vastly over-optimistic about the performance and the
 amount of optimisation that can realistically be expected for proxies.
 Proxies are inherently unstructured, higher-order, and effectful,
 which defeats most sufficiently simple static analyses. A compiler has
 to work much, much harder to get useful results. Don't expect anything
 anytime soon.
  var handler = {set: function(){throw new TypeError}}
  var p = new Proxy({a: 32}, handler);

  p.a;

 It's possible *at runtime* to notice that the handler of p doesn't have
 a
 get trap, optimize p.[[Get]] as target.[[Get]] and guard this
 optimization
 on handler modifications. Obviously, do that only if the code is hot.
 I feel it's not that much work than what JS engines do currently and the
 useful result is effectively getting rid of the forwarding overhead.
 Is this vastly over-optimistic?

 Yes. Proxies hook into many different basic operations, and there are
 many special cases you could potentially optimise for each of them,
 many of which don't come for free. I very much doubt that any vendor
 currently has serious plans to go down that rathole instead of
 spending their energy elsewhere. Certainly not before it is clear how
 (and how much) proxies will actually be used in practice.
 
 You're right in general, and we have not optimized, e.g. inlining 
 scripted trap calls.
 
 We did do something special for our new DOM bindings I wanted to pass 
 along, in case anyone is interested:
 
 https://bugzilla.mozilla.org/show_bug.cgi?id=769911
 
 Thanks to bz for the link. This is yet another inline cache 
 specialization for expandos on nodelists.
 
 /be
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 
 

-
Mariusz Nowak

https://github.com/medikoo
-- 
View this message in context: 
http://old.nabble.com/A-case-for-removing-the-seal-freeze-isSealed-isFrozen-traps-tp35013883p35026595.html
Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at 
Nabble.com.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread Axel Rauschmayer
I like this direction: it would distinguish the user-level operation 
_assignment_ from the meta-level operation _definition_. I’m not sure where 
`delete` fits in, but it’s much less common, so less of a potential problem.

On Feb 15, 2013, at 11:03 , Mariusz Nowak medikoo+mozilla@medikoo.com 
wrote:

 
 I've worked a lot with ECMAScript5 features in last two years, and I must say
 I never found a good use case for Object.freeze/seal/preventExtensions, it
 actually raised more issues than it actually helped (those few times when I
 decided to use it). Currently I think that's not JavaScript'y approach and
 use cases mentioning untrusted parties sounds logical just in theory, in
 practice when actually we never include untrusted modules in our code base
 does not make much sense.
 
 However, main point I want to raise is that several times I had a use case
 for very close functionality, that with current API seem not possible: 
 I'd like to be able to *prevent accidental object extensions*. I want to
 control all enumerable properties of the object, so they can only be set via
 defineProperty, but any direct assignment of non existing prop e.g.
 'x.notDefinedYet = value'  will throw. Imagine some ORM implementation, that
 via setters propagates changes to underlying persistent layer, at this time
 we cannot prevent accidental property sets that may occur before property
 was actually defined (therefore not caught by the setter)
 I assume that proxies will make such functionality possible, but maybe some
 Object.preventUndefinedExtensions will be even better.

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread David Bruant

Le 15/02/2013 11:03, Mariusz Nowak a écrit :

I've worked a lot with ECMAScript5 features in last two years, and I must say
I never found a good use case for Object.freeze/seal/preventExtensions, it
actually raised more issues than it actually helped (those few times when I
decided to use it). Currently I think that's not JavaScript'y approach and
use cases mentioning untrusted parties sounds logical just in theory, in
practice when actually we never include untrusted modules in our code base
does not make much sense.

However, main point I want to raise is that several times I had a use case
for very close functionality, that with current API seem not possible:
I'd like to be able to *prevent accidental object extensions*.
If something *accidental* can happen, then untrusted parties is more 
than theorical ;-)

Brendan says it better [1]:
In a programming-in-the-large setting, a writable data property is 
inviting Murphy's Law. I'm not talking about security in a mixed-trust 
environment specifically. Large programs become mixed trust, even when 
it's just me, myself, and I (over time) hacking the large amount of code.


Security and untrusted parties aren't about terrorists groups trying 
to hack your application to get a copy of your database or corrupt it or 
your choice to use some code downloaded from a dark-backgrounded website.
They're about you trying to meet a deadline and not having time to read 
carefully the documentation and comments of every single line of modules 
you're delegating to.
Trust isn't an all-or-nothing notion. Anytime I say untrusted, I 
should probably say partially trusted instead.
Trust also changes over time, mostly because as times passes, our brains 
forget the invariants and assumptions we baked in our code and if those 
aren't enforced at compile time or runtime, we'll probably violate them 
at one point or another and thus create bugs. Or we just make mistakes, 
because we're human and that's exactly the case you're explaining.
Security and untrusted parties are about our inability as human 
beings to remember everything we do and our inability to be perfect. Any 
security mechanism is a mechanism to protect against hostile outsiders 
but also and probably mostly ourselves over time.


It is usually not considered so, but separation of concerns is a 
security mechanism in my opinion. So are most object-oriented so-called 
good practices.


Security is very loaded with emotions of people afraid to have their 
password stolen and cyber attacks. It's also loaded with the notion of 
human safety and human integrity which, as human beings are sensitive to.

Maybe I should start using a different word...


I want to
control all enumerable properties of the object, so they can only be set via
defineProperty, but any direct assignment of non existing prop e.g.
'x.notDefinedYet = value'  will throw. Imagine some ORM implementation, that
via setters propagates changes to underlying persistent layer, at this time
we cannot prevent accidental property sets that may occur before property
was actually defined (therefore not caught by the setter)
I assume that proxies will make such functionality possible, but maybe some
Object.preventUndefinedExtensions will be even better.
The problem is that there are probably dozens of use cases like yours 
[2] and the Object built-in can't welcome them all.
Hence proxies as an extension mechanism of any random 
micro-abstraction (as Andreas Rossberg puts it ;-) )


David

[1] https://mail.mozilla.org/pipermail/es-discuss/2013-February/028724.html
[2] When I learned JS, how many time did I mistyped .innerHTML and 
wasted hours not understanding where some undefined string in my UI 
came from.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread medikoo
David, that's great clarification, and indeed it looks a bit different from
that perspective.

Still the only use case I see for freezing/sealing whole object (the way it
works now) is when we expose some constant dictionary object on which each
property counts, and that's very rare use case.
I don't see much good in disallowing extensions to prototypes we expose.
it's not JS way. We can prevent accidental modifications of *existing* API's
but disallowing custom extensions is too restrictive and not friendly in my
opinion.




--
View this message in context: 
http://mozilla.6506.n7.nabble.com/A-case-for-removing-the-seal-freeze-isSealed-isFrozen-traps-tp272443p272674.html
Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at 
Nabble.com.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread Brandon Benvie
I definitely agree that something like preventAccidentalExtensions (disallows 
new properties through [[Put]] but not [[DefineOwnProperty]]) has more common 
uses cases than preventExtensions, and for the precise reasons that David said. 
The security is against bugs usually, not attackers. PreventExtensions is a 
clumsy tool for managing capabilities because it leaves no room for giving 
*some* code permission while preventing other code, which is exactly what we 
want when the clueful *me* of now is writing code to manage the clueless *I* of 
the future.

On Feb 15, 2013, at 6:31 AM, medikoo medikoo+mozilla@medikoo.com wrote:

 David, that's great clarification, and indeed it looks a bit different from
 that perspective.
 
 Still the only use case I see for freezing/sealing whole object (the way it
 works now) is when we expose some constant dictionary object on which each
 property counts, and that's very rare use case.
 I don't see much good in disallowing extensions to prototypes we expose.
 it's not JS way. We can prevent accidental modifications of *existing* API's
 but disallowing custom extensions is too restrictive and not friendly in my
 opinion.
 
 
 
 
 --
 View this message in context: 
 http://mozilla.6506.n7.nabble.com/A-case-for-removing-the-seal-freeze-isSealed-isFrozen-traps-tp272443p272674.html
 Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at 
 Nabble.com.
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread Erik Arvidsson
... and security sensitive code could just ban/alter the reflection methods.
On Feb 15, 2013 8:29 AM, Brandon Benvie bben...@mozilla.com wrote:

 I definitely agree that something like preventAccidentalExtensions
 (disallows new properties through [[Put]] but not [[DefineOwnProperty]])
 has more common uses cases than preventExtensions, and for the precise
 reasons that David said. The security is against bugs usually, not
 attackers. PreventExtensions is a clumsy tool for managing capabilities
 because it leaves no room for giving *some* code permission while
 preventing other code, which is exactly what we want when the clueful *me*
 of now is writing code to manage the clueless *I* of the future.

 On Feb 15, 2013, at 6:31 AM, medikoo medikoo+mozilla@medikoo.com
 wrote:

  David, that's great clarification, and indeed it looks a bit different
 from
  that perspective.
 
  Still the only use case I see for freezing/sealing whole object (the way
 it
  works now) is when we expose some constant dictionary object on which
 each
  property counts, and that's very rare use case.
  I don't see much good in disallowing extensions to prototypes we expose.
  it's not JS way. We can prevent accidental modifications of *existing*
 API's
  but disallowing custom extensions is too restrictive and not friendly in
 my
  opinion.
 
 
 
 
  --
  View this message in context:
 http://mozilla.6506.n7.nabble.com/A-case-for-removing-the-seal-freeze-isSealed-isFrozen-traps-tp272443p272674.html
  Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at
 Nabble.com.
  ___
  es-discuss mailing list
  es-discuss@mozilla.org
  https://mail.mozilla.org/listinfo/es-discuss
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread Russell Leggett
On Fri, Feb 15, 2013 at 9:24 AM, Erik Arvidsson erik.arvids...@gmail.comwrote:

 ... and security sensitive code could just ban/alter the reflection
 methods.
 On Feb 15, 2013 8:29 AM, Brandon Benvie bben...@mozilla.com wrote:

 I definitely agree that something like preventAccidentalExtensions
 (disallows new properties through [[Put]] but not [[DefineOwnProperty]])
 has more common uses cases than preventExtensions, and for the precise
 reasons that David said. The security is against bugs usually, not
 attackers. PreventExtensions is a clumsy tool for managing capabilities
 because it leaves no room for giving *some* code permission while
 preventing other code, which is exactly what we want when the clueful *me*
 of now is writing code to manage the clueless *I* of the future.


I think this would fit a really common use case, but I would say that the
current attempted way to solve this problem is private names. Last I
checked, private names (or the weak map variant) would not be frozen after
an Object.freeze, but only trusted parties (like methods,getters/setters,
and potentially those with the shared name) could modify it.

The pattern I would like to see optimized for using Object.freeze is the
functional approach. I think the tools are there. Object.freeze makes
immutable objects, and using Object.create to use frozen objects as
prototypes, and store just the differences in the child object could
potentially be an elegant way of doing persistent data structures. I
haven't really tested the performance of it now, but I wonder how optimized
it could get. The prototype chains could get very deep, but seeing as they
would all be frozen all the way up, I wonder if it could be made more
efficient.

- Russ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-15 Thread Andreas Rossberg
On 15 February 2013 14:29, Brandon Benvie bben...@mozilla.com wrote:
 I definitely agree that something like preventAccidentalExtensions 
 (disallows new properties through [[Put]] but not [[DefineOwnProperty]]) has 
 more common uses cases than preventExtensions, and for the precise reasons 
 that David said. The security is against bugs usually, not attackers. 
 PreventExtensions is a clumsy tool for managing capabilities because it 
 leaves no room for giving *some* code permission while preventing other code, 
 which is exactly what we want when the clueful *me* of now is writing code to 
 manage the clueless *I* of the future.

If you need private extensibility, just complement preventExtensions
with installing a private map or expando object.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread Tom Van Cutsem
2013/2/14 Allen Wirfs-Brock al...@wirfs-brock.com


 On Feb 13, 2013, at 12:53 PM, David Bruant wrote:

  Interesting.

 So what would happen when calling Object.isFrozen on a proxy? Would
 Object.isFrozen/isSealed/isExtensible reach out directly to the target? or
 a unique state trap returning a string for all of them? (state is too
 generic of a name, but you get the idea)


 This is a question regarding proxy design, rather than the MOP. Either
 get/setIntegrity traps to the handler or it forwards directly to the
 target.  That's would be a design issue for Tom, but my starting point is
 to simply follow the current design decisions made for
 [[PreventExtensions]]/[[IsExtensible]]


A get/setIntegrity trap with the invariant constraints of
isExtensible/preventExtensions would be the obvious path to take.

One thing that remains unclear to me: if the state of an object becomes
explicit, we introduce the risk for this state to become inconsistent with
the state from which it is derived.

For example, setting the integrity of an object to frozen must still make
all own properties non-configurable, i.e.

Reflect.setIntegrity(obj, frozen)

should have the same effect as

Object.freeze(obj)

Likewise, turning the last configurable property of a non-extensible object
into a non-configurable property should automagically change the state to
frozen, i.e.

Object.defineProperty(obj, lastProperty, { configurable: false }) // must
update internal state as well as the property
Reflect.getIntegrity(obj) === frozen

Will this not just shift the current complexity someplace else?


 Regardless on the final decision on (full) notification proxies, maybe
 these operations (isSealed/isFrozen) could have notification trap. The
 invariant is that the answer has to be the target one (all the time), so
 the trap return value is irrelevant. Like the getPrototypeOf trap.


 Right, one way or another these operations need to be part of the MOP.


If we go for get/setIntegrity I wouldn't re-introduce all the derived
operations as notification traps. Then we might as well leave things the
way they are.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread Andreas Rossberg
On 13 February 2013 13:39, David Bruant bruan...@gmail.com wrote:
 Warning: In this post, I'll be diverging a bit from the main topic.

 Le 12/02/2013 14:29, Brendan Eich a écrit :

 Loss of identity, extra allocations, and forwarding overhead remain
 problems.

 I'm doubtful loss of identity matters often enough to be a valid argument
 here. I'd be interested in being proved wrong, though.

 I understand the point about extra allocation. I'll talk about that below.

 The forwarding overhead can be made inexistent in the very case I've exposed
 because in the handler, the traps you care about are absent from the
 handler, so engines are free to optimize the [[Get]]friends as operations
 applied directly to the target.

You're being vastly over-optimistic about the performance and the
amount of optimisation that can realistically be expected for proxies.
Proxies are inherently unstructured, higher-order, and effectful,
which defeats most sufficiently simple static analyses. A compiler has
to work much, much harder to get useful results. Don't expect anything
anytime soon.


 I've seen this in a previous experience on a Chrome extension where someone
 would seal an object as a form of documentation to express I need these
 properties to stay in the object. It looked like:
 function C(){
 // play with |this|
 return Object.seal(this)
 }

 My point here is that people do want to protect their object integrity
 against untrusted parties which in that case was just people who'll
 contribute to this code in the future.

 Anecdotally, the person removed the Object.seal before the return because of
 performance reasons, based on a JSPerf test [3].
 Interestingly, a JSPerf test with a proxy-based solution [4] might have
 convinced to do proxies instead of Object.seal.

Take all these JSPerf micro benchmark games with two grains of salt;
lots of them focus on premature optimisation. Also, seal and freeze
are far more likely to see decent treat than proxies.

But more importantly, I think you get too hung up on proxies as the
proverbial hammer. Proxies are very much an expert feature. Using them
for random micro abstractions is like shooting birds with a nuke. A
language that makes that necessary would be a terrible language. All
programmers messing with home-brewed proxies on a daily basis is a
very scary vision, if you ask me.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread David Bruant

Le 14/02/2013 18:11, Andreas Rossberg a écrit :

On 13 February 2013 13:39, David Bruant bruan...@gmail.com wrote:

Warning: In this post, I'll be diverging a bit from the main topic.

Le 12/02/2013 14:29, Brendan Eich a écrit :


Loss oread onlyf identity, extra allocations, and forwarding overhead remain
problems.

I'm doubtful loss of identity matters often enough to be a valid argument
here. I'd be interested in being proved wrong, though.

I understand the point about extra allocation. I'll talk about that below.

The forwarding overhead can be made inexistent in the very case I've exposed
because in the handler, the traps you care about are absent from the
handler, so engines are free to optimize the [[Get]]friends as operations
applied directly to the target.

You're being vastly over-optimistic about the performance and the
amount of optimisation that can realistically be expected for proxies.
Proxies are inherently unstructured, higher-order, and effectful,
which defeats most sufficiently simple static analyses. A compiler has
to work much, much harder to get useful results. Don't expect anything
anytime soon.

var handler = {set: function(){throw new TypeError}}
var p = new Proxy({a: 32}, handler);

p.a;

It's possible *at runtime* to notice that the handler of p doesn't have 
a get trap, optimize p.[[Get]] as target.[[Get]] and guard this 
optimization on handler modifications. Obviously, do that only if the 
code is hot.
I feel it's not that much work than what JS engines do currently and the 
useful result is effectively getting rid of the forwarding overhead.

Is this vastly over-optimistic?


I've seen this in a previous experience on a Chrome extension where someone
would seal an object as a form of documentation to express I need these
properties to stay in the object. It looked like:
 function C(){
 // play with |this|
 return Object.seal(this)
 }

My point here is that people do want to protect their object integrity
against untrusted parties which in that case was just people who'll
contribute to this code in the future.

Anecdotally, the person removed the Object.seal before the return because of
performance reasons, based on a JSPerf test [3].
Interestingly, a JSPerf test with a proxy-based solution [4] might have
convinced to do proxies instead of Object.seal.

Take all these JSPerf micro benchmark games with two grains of salt;

... that's exactly what I said right after :-/
But that's a JSPerf test and it doesn't really measure the GC overhead 
of extra objects.
JSPerf only measures one part of perf the story and its nice conclusion 
graph should be taken with a pinch of salt.



lots of them focus on premature optimisation.
I'm quite aware. I fear the Sphinx [1]. I wrote might have convinced to 
do proxies instead of Object.seal. I didn't say I agreed. and I 
actually don't.



Also, seal and freeze
are far more likely to see decent treat than proxies.

Why so?


But more importantly, I think you get too hung up on proxies as the
proverbial hammer. Proxies are very much an expert feature. Using them
for random micro abstractions is like shooting birds with a nuke. A
language that makes that necessary would be a terrible language. All
programmers messing with home-brewed proxies on a daily basis is a
very scary vision, if you ask me.

hmm... maybe.

David

[1] https://twitter.com/ubench_sphinx
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread Andreas Rossberg
On 14 February 2013 19:16, David Bruant bruan...@gmail.com wrote:
 Le 14/02/2013 18:11, Andreas Rossberg a écrit :
 You're being vastly over-optimistic about the performance and the
 amount of optimisation that can realistically be expected for proxies.
 Proxies are inherently unstructured, higher-order, and effectful,
 which defeats most sufficiently simple static analyses. A compiler has
 to work much, much harder to get useful results. Don't expect anything
 anytime soon.

 var handler = {set: function(){throw new TypeError}}
 var p = new Proxy({a: 32}, handler);

 p.a;

 It's possible *at runtime* to notice that the handler of p doesn't have a
 get trap, optimize p.[[Get]] as target.[[Get]] and guard this optimization
 on handler modifications. Obviously, do that only if the code is hot.
 I feel it's not that much work than what JS engines do currently and the
 useful result is effectively getting rid of the forwarding overhead.
 Is this vastly over-optimistic?

Yes. Proxies hook into many different basic operations, and there are
many special cases you could potentially optimise for each of them,
many of which don't come for free. I very much doubt that any vendor
currently has serious plans to go down that rathole instead of
spending their energy elsewhere. Certainly not before it is clear how
(and how much) proxies will actually be used in practice.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread Andreas Rossberg
On 14 February 2013 01:05, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 Where do without, means replaced with  set/getIntegrity traps and objects
 have explicit internal state whose value is one of
 normal/non-extensible/sealed/frozen  (and possibly)  fixed-inheritance
 between normal and non-extensible to freeze [[Prototype]]).

 [[SetIntegrity]] can increase the integrity level but not decrease it.

 The perf and invariant complexity concerns come from the fact that the
 sealed/frozen status of an object can only be inferred by inspecting all of
 its methods. Having an explicit state eliminates the need to do this
 inspection.  It also simplifies the MOP by merging all of the
 extensible/sealed/frozen related MOP operations into only two ops.  But, one
 way or another, these object state transitions must be accounted for in the
 MOP.

 For this to fly, implementation have to be able to expand their current 1
 bit of of extensible state to at least 2 bits (3 would be better).  Or
 perhaps not, I suppose we could just introduce the MOP level changes and a
 lazy implementation could continue to infer the state by examining all its
 methods.

I still must be missing something. Why should the language be changed
when the proposed change is equivalent anyway? Why is this an
optimisation that the spec should worry about instead of the
implementations?

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread Brendan Eich

Andreas Rossberg wrote:

But more importantly, I think you get too hung up on proxies as the
proverbial hammer. Proxies are very much an expert feature. Using them
for random micro abstractions is like shooting birds with a nuke. A
language that makes that necessary would be a terrible language. All
programmers messing with home-brewed proxies on a daily basis is a
very scary vision, if you ask me.


This.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-14 Thread Brendan Eich

Andreas Rossberg wrote:

On 14 February 2013 19:16, David Bruantbruan...@gmail.com  wrote:

Le 14/02/2013 18:11, Andreas Rossberg a écrit :

You're being vastly over-optimistic about the performance and the
amount of optimisation that can realistically be expected for proxies.
Proxies are inherently unstructured, higher-order, and effectful,
which defeats most sufficiently simple static analyses. A compiler has
to work much, much harder to get useful results. Don't expect anything
anytime soon.

 var handler = {set: function(){throw new TypeError}}
 var p = new Proxy({a: 32}, handler);

 p.a;

It's possible *at runtime* to notice that the handler of p doesn't have a
get trap, optimize p.[[Get]] as target.[[Get]] and guard this optimization
on handler modifications. Obviously, do that only if the code is hot.
I feel it's not that much work than what JS engines do currently and the
useful result is effectively getting rid of the forwarding overhead.
Is this vastly over-optimistic?


Yes. Proxies hook into many different basic operations, and there are
many special cases you could potentially optimise for each of them,
many of which don't come for free. I very much doubt that any vendor
currently has serious plans to go down that rathole instead of
spending their energy elsewhere. Certainly not before it is clear how
(and how much) proxies will actually be used in practice.


You're right in general, and we have not optimized, e.g. inlining 
scripted trap calls.


We did do something special for our new DOM bindings I wanted to pass 
along, in case anyone is interested:


https://bugzilla.mozilla.org/show_bug.cgi?id=769911

Thanks to bz for the link. This is yet another inline cache 
specialization for expandos on nodelists.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-13 Thread David Bruant

Warning: In this post, I'll be diverging a bit from the main topic.

Le 12/02/2013 14:29, Brendan Eich a écrit :
Loss of identity, extra allocations, and forwarding overhead remain 
problems.
I'm doubtful loss of identity matters often enough to be a valid 
argument here. I'd be interested in being proved wrong, though.


I understand the point about extra allocation. I'll talk about that below.

The forwarding overhead can be made inexistent in the very case I've 
exposed because in the handler, the traps you care about are absent from 
the handler, so engines are free to optimize the [[Get]]friends as 
operations applied directly to the target.
A handler-wise write barrier can deoptimize but in most practical cases, 
the deoptimization won't happen because in most practical cases handlers 
don't change.


It seems to me that you are focusing too much on share ... to 
untrusted parties.

Your very own recent words [1]:
In a programming-in-the-large setting, a writable data property is 
inviting Murphy's Law. I'm not talking about security in a mixed-trust 
environment specifically. Large programs become mixed trust, even when 
it's just me, myself, and I (over time) hacking the large amount of code.

...to which I agree with (obviously?)

And Be a better language for writing complex applications is in the 
first goals [2]


Maybe I should use another word than untrusted parties. What I mean is 
any code that will manipulate something without necessarily caring to 
learn about what this something expects as precondition and own invariants.
This includes security issues of course, but also buggy code (which, in 
big applications, are often related to mismatch between a 
precondition/expectation and how something is used).


I've seen this in a previous experience on a Chrome extension where 
someone would seal an object as a form of documentation to express I 
need these properties to stay in the object. It looked like:

function C(){
// play with |this|
return Object.seal(this)
}

My point here is that people do want to protect their object integrity 
against untrusted parties which in that case was just people who'll 
contribute to this code in the future.


Anecdotally, the person removed the Object.seal before the return 
because of performance reasons, based on a JSPerf test [3].
Interestingly, a JSPerf test with a proxy-based solution [4] might have 
convinced to do proxies instead of Object.seal.
But that's a JSPerf test and it doesn't really measure the GC overhead 
of extra objects. Are there data on this? Are there methodologies to 
measure this overhead? I understand it, but I find myself unable to pull 
up numbers on this topic and convincing arguments that JSPerf only 
measures one part of perf the story and its nice conclusion graph should 
be taken with a pinch of salt.


It's true you want either a membrane or an already-frozen object in 
such a setting.
Not a membrane, just a proxy that protects its target. Objects linked 
from the proxy likely came from somewhere else. They're in charge of 
deciding of their own integrity policy.


And outside of untrusted parties, frozen objects have their uses -- 
arguably more over time with safe parallelism in JS.

Arguably indeed. I would love to see this happen.
Still, if (deeply) frozen POJSO could be part shared among contexts, I 
think we can agree that it wouldn't apply to frozen proxies for a long 
time (ever?)



I went a bit too far suggesting frozen objects could de-facto disappear 
with proxies.
I'm still unclear on the need for specific seal/freeze/isSealed/isFrozen 
traps


David

[1] https://mail.mozilla.org/pipermail/es-discuss/2013-February/028724.html
[2] http://wiki.ecmascript.org/doku.php?id=harmony:harmony#goals
[3] jsperf.com/object-seal-freeze/
[4] http://jsperf.com/object-seal-freeze/2


/be

David Bruant wrote:

Hi,

The main use case (correct me if I'm wrong) for freezing/sealing an 
object is sharing an object to untrusted parties while preserving the 
object integrity. There is also the tamper-proofing of objects 
everyone has access to (Object.prototype in the browser)


In a world with proxies, it's easy to build new objects with high 
integrity without Object.freeze: build your object, share only a 
wrapped version to untrusted parties, the handler takes care of the 
integrity.


function thrower(){
throw new Error('nope');
}
var frozenHandler = {
set: thrower,
defineProperty: thrower,
delete: thrower
};

function makeFrozen(o){
return new Proxy(o, frozenHandler);
}

This is true to a point that I wonder why anyone would call 
Object.freeze on script-created objects any longer... By design and 
for good reasons, proxies are a subset of script-created objects, 
so my previous sentence contained: I wonder why anyone would call 
Object.freeze on proxies...


There were concerned about Object.freeze/seal being costly on proxies 
if 

Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-13 Thread Tom Van Cutsem
Hi David,

2013/2/13 David Bruant bruan...@gmail.com

 Le 12/02/2013 14:29, Brendan Eich a écrit :

 Loss of identity, extra allocations, and forwarding overhead remain
 problems.

 I'm doubtful loss of identity matters often enough to be a valid argument
 here. I'd be interested in being proved wrong, though.


I do think identity is an issue in practice, especially without a membrane
in-place to preserve object identity across the membrane. Also:


  It's true you want either a membrane or an already-frozen object in such
 a setting.

 Not a membrane, just a proxy that protects its target. Objects linked from
 the proxy likely came from somewhere else. They're in charge of deciding of
 their own integrity policy.


Freezing an object by handing out a read-only view is fragile without a
full membrane: what if a method of the wrapped object returns |this|, or
passes its |this| argument to some client-provided callback? It's all too
easy for a direct reference to the target to escape, thus bypassing the
read-only view. This is not the case with frozen objects.

I went a bit too far suggesting frozen objects could de-facto disappear
 with proxies.
 I'm still unclear on the need for specific seal/freeze/isSealed/isFrozen
 traps


I think Allen and I reached consensus that we might do without those traps.
In addition, Allen was considering an alternative design where the state
of an object (i.e. extensible, non-extensible, sealed or frozen) is
represented explicitly as an internal property, so that Object.isFrozen and
Object.isSealed must not derive the state of an object from its
properties.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-13 Thread David Bruant

Le 13/02/2013 20:36, Tom Van Cutsem a écrit :

Hi David,

I went a bit too far suggesting frozen objects could de-facto
disappear with proxies.
I'm still unclear on the need for specific
seal/freeze/isSealed/isFrozen traps


I think Allen and I reached consensus that we might do without those 
traps.

Excellent!

In addition, Allen was considering an alternative design where the 
state of an object (i.e. extensible, non-extensible, sealed or 
frozen) is represented explicitly as an internal property, so that 
Object.isFrozen and Object.isSealed must not derive the state of an 
object from its properties.

Interesting.
So what would happen when calling Object.isFrozen on a proxy? Would 
Object.isFrozen/isSealed/isExtensible reach out directly to the target? 
or a unique state trap returning a string for all of them? (state is 
too generic of a name, but you get the idea)


Regardless on the final decision on (full) notification proxies, maybe 
these operations (isSealed/isFrozen) could have notification trap. The 
invariant is that the answer has to be the target one (all the time), so 
the trap return value is irrelevant. Like the getPrototypeOf trap.


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-13 Thread Allen Wirfs-Brock

On Feb 13, 2013, at 12:53 PM, David Bruant wrote:

 Le 13/02/2013 20:36, Tom Van Cutsem a écrit :
 Hi David,
 
 I went a bit too far suggesting frozen objects could de-facto disappear with 
 proxies.
 I'm still unclear on the need for specific seal/freeze/isSealed/isFrozen 
 traps
 
 I think Allen and I reached consensus that we might do without those traps.
 Excellent!

Where do without, means replaced with  set/getIntegrity traps and objects 
have explicit internal state whose value is one of 
normal/non-extensible/sealed/frozen  (and possibly)  fixed-inheritance 
between normal and non-extensible to freeze [[Prototype]]).

[[SetIntegrity]] can increase the integrity level but not decrease it. 

The perf and invariant complexity concerns come from the fact that the 
sealed/frozen status of an object can only be inferred by inspecting all of its 
methods. Having an explicit state eliminates the need to do this inspection.  
It also simplifies the MOP by merging all of the extensible/sealed/frozen 
related MOP operations into only two ops.  But, one way or another, these 
object state transitions must be accounted for in the MOP.

For this to fly, implementation have to be able to expand their current 1 bit 
of of extensible state to at least 2 bits (3 would be better).  Or perhaps not, 
I suppose we could just introduce the MOP level changes and a lazy 
implementation could continue to infer the state by examining all its methods.



 
 In addition, Allen was considering an alternative design where the state 
 of an object (i.e. extensible, non-extensible, sealed or frozen) is 
 represented explicitly as an internal property, so that Object.isFrozen and 
 Object.isSealed must not derive the state of an object from its properties.
 Interesting.
 So what would happen when calling Object.isFrozen on a proxy? Would 
 Object.isFrozen/isSealed/isExtensible reach out directly to the target? or a 
 unique state trap returning a string for all of them? (state is too 
 generic of a name, but you get the idea)

This is a question regarding proxy design, rather than the MOP. Either 
get/setIntegrity traps to the handler or it forwards directly to the target.  
That's would be a design issue for Tom, but my starting point is to simply 
follow the current design decisions made for 
[[PreventExtensions]]/[[IsExtensible]]

 
 Regardless on the final decision on (full) notification proxies, maybe these 
 operations (isSealed/isFrozen) could have notification trap. The invariant is 
 that the answer has to be the target one (all the time), so the trap return 
 value is irrelevant. Like the getPrototypeOf trap.

Right, one way or another these operations need to be part of the MOP.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-12 Thread David Bruant

Hi,

The main use case (correct me if I'm wrong) for freezing/sealing an 
object is sharing an object to untrusted parties while preserving the 
object integrity. There is also the tamper-proofing of objects everyone 
has access to (Object.prototype in the browser)


In a world with proxies, it's easy to build new objects with high 
integrity without Object.freeze: build your object, share only a wrapped 
version to untrusted parties, the handler takes care of the integrity.


function thrower(){
throw new Error('nope');
}
var frozenHandler = {
set: thrower,
defineProperty: thrower,
delete: thrower
};

function makeFrozen(o){
return new Proxy(o, frozenHandler);
}

This is true to a point that I wonder why anyone would call 
Object.freeze on script-created objects any longer... By design and for 
good reasons, proxies are a subset of script-created objects, so my 
previous sentence contained: I wonder why anyone would call 
Object.freeze on proxies...


There were concerned about Object.freeze/seal being costly on proxies if 
defined as preventExtension + enumerate + nbProps*defineProperty. 
Assuming Object.freeze becomes de-facto deprecated in favor of 
proxy-wrapping for high-integrity use cases, maybe that cost is not that 
big of a deal.


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A case for removing the seal/freeze/isSealed/isFrozen traps

2013-02-12 Thread Brendan Eich
Loss of identity, extra allocations, and forwarding overhead remain 
problems.


It seems to me that you are focusing too much on share ... to untrusted 
parties. It's true you want either a membrane or an already-frozen 
object in such a setting. But the latter case, already-frozen object, 
does not want a membrane, both to avoid identity change and to avoid the 
allocation and forwarding overheads. And outside of untrusted parties, 
frozen objects have their uses -- arguably more over time with safe 
parallelism in JS.


/be

David Bruant wrote:

Hi,

The main use case (correct me if I'm wrong) for freezing/sealing an 
object is sharing an object to untrusted parties while preserving the 
object integrity. There is also the tamper-proofing of objects 
everyone has access to (Object.prototype in the browser)


In a world with proxies, it's easy to build new objects with high 
integrity without Object.freeze: build your object, share only a 
wrapped version to untrusted parties, the handler takes care of the 
integrity.


function thrower(){
throw new Error('nope');
}
var frozenHandler = {
set: thrower,
defineProperty: thrower,
delete: thrower
};

function makeFrozen(o){
return new Proxy(o, frozenHandler);
}

This is true to a point that I wonder why anyone would call 
Object.freeze on script-created objects any longer... By design and 
for good reasons, proxies are a subset of script-created objects, so 
my previous sentence contained: I wonder why anyone would call 
Object.freeze on proxies...


There were concerned about Object.freeze/seal being costly on proxies 
if defined as preventExtension + enumerate + nbProps*defineProperty. 
Assuming Object.freeze becomes de-facto deprecated in favor of 
proxy-wrapping for high-integrity use cases, maybe that cost is not 
that big of a deal.


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss