[Harmony Proxies] Proposal: Property fixing

classic Classic list List threaded Threaded
140 messages Options
12345 ... 7
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

David Bruant-4
Le 13/05/2011 01:20, Cameron McCormack a écrit :

> Tom Van Cutsem:
>> invariants that are enforced:
> …
>> - unconfigurable [[Class]] (Object or Function, respectively)
> Web IDL requires [[Class]] to take on values other than these two, for
> example it should be "HTMLDivElement" for an HTMLDivElement object.  I
> have a feeling that the web requires this, as opposed to just having a
> custom toString function.
>
> http://google.com/codesearch?q=Object.prototype.toString.call+lang:javascript
> brings up some libraries that use Object.prototype.toString on DOM
> objects.
>
> Is it palatable to have proxies control [[Class]] or is there another
> way we can help proxies over this hurdle?
DOM objects are defined in ECMAScript as "host objects". As such, they
can do whatever they want with [[Class]] (as they always have). There is
no need for proxies to change.

Anyway, I think that the idea is to define the DOM as ECMAScript
(proxies included). Following this path, maybe that WebIDL could do a
willful violation as it's sometimes done in HTML5.

Another idea is that Object.prototype.toString could return different
things for DOM objects. This can certainly be implemented in pure
ES.next with WeakMaps. It's duck-typing, so a bit ugly, but possible anyway.

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Cameron McCormack-4
David Bruant:
> DOM objects are defined in ECMAScript as "host objects". As such, they
> can do whatever they want with [[Class]] (as they always have). There is
> no need for proxies to change.

Except of course for the desire to implement the DOM using proxies.

> Anyway, I think that the idea is to define the DOM as ECMAScript
> (proxies included). Following this path, maybe that WebIDL could do a
> willful violation as it's sometimes done in HTML5.

It could (and probably will have to if there’s no way other way to get
Object.prototype.toString to return the right values), but I thought
proxies were developed precisely (well, as one of their main goals) so
that we didn’t need to do this.

> Another idea is that Object.prototype.toString could return different
> things for DOM objects. This can certainly be implemented in pure
> ES.next with WeakMaps. It's duck-typing, so a bit ugly, but possible anyway.

True, that would be one way around it.

--
Cameron McCormack ≝ http://mcc.id.au/
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Rick Waldron
In reply to this post by David Bruant-4
David, 

For clarification, can you give a working example (ie runable in FF nightly) of this:

"Object.prototype.toString could return different
things for DOM objects. This can certainly be implemented in pure
ES.next with WeakMaps. "

Thanks in advance!

Rick



-- Sent from my Palm Pre


On May 12, 2011 8:12 PM, David Bruant <[hidden email]> wrote:

Le 13/05/2011 01:20, Cameron McCormack a écrit :

> Tom Van Cutsem:
>> invariants that are enforced:
> …
>> - unconfigurable [[Class]] (Object or Function, respectively)
> Web IDL requires [[Class]] to take on values other than these two, for
> example it should be "HTMLDivElement" for an HTMLDivElement object. I
> have a feeling that the web requires this, as opposed to just having a
> custom toString function.
>
> http://google.com/codesearch?q=Object.prototype.toString.call+lang:javascript
> brings up some libraries that use Object.prototype.toString on DOM
> objects.
>
> Is it palatable to have proxies control [[Class]] or is there another
> way we can help proxies over this hurdle?
DOM objects are defined in ECMAScript as "host objects". As such, they
can do whatever they want with [[Class]] (as they always have). There is
no need for proxies to change.

Anyway, I think that the idea is to define the DOM as ECMAScript
(proxies included). Following this path, maybe that WebIDL could do a
willful violation as it's sometimes done in HTML5.

Another idea is that Object.prototype.toString could return different
things for DOM objects. This can certainly be implemented in pure
ES.next with WeakMaps. It's duck-typing, so a bit ugly, but possible anyway.

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Allen Wirfs-Brock
In reply to this post by Tom Van Cutsem-3
Thanks Tom,

As you point out, the are plenty of other implicit invariants that proxies don't enforce. For example:
   - a configurable property can be deleted
   - a [[Put]] to a non-writable data property does not change the value observable via [[Get]]
   - the attributes of a configurable property can be changed
   - obj.hasOwnProperty("foo")===obj.hasOwnProperty("foo")  //is true
   -Object.getOwnPropertyDescriptor(obj,"foo").hasOwnProperty("value) ) && obj.foo===obj.foo  //is true, ignoring NaN case
or lots of other consistency invariants among sequences of traps

I also wanted to point out that no modern browser fully respects the configurable invariants.  Every browser implements RegExp.prototype.compile and the de-facto standard  for its behavior blatantly  modifies the properties specified in 15.10.7  which are defined to be configurable false and writable: false.  The discussions that have occurred concerning  this method concluded that it (with that behavior) is essential to the web and that it should be included in the next ES edition.  I haven't figured out how we will reconcile this.  Probably by turning the affected properties into accessors.


On May 12, 2011, at 5:40 AM, Tom Van Cutsem wrote:

...

Most of the enforced properties have to do with classification: instanceof, typeof and === are operators used to classify objects, and classifications typically come with some implied invariants (I'm aware of the fact that instanceof tests can be non-monotonic in JS).

For {freeze|seal|preventExtensions}, one can make the case that defensive programming is one of their main use cases. Allowing proxies to gratuitously break them feels like taking away a lot of the usefulness of these primitives.

Generally, ES is not a hand holding language.  In particular, I don't see why these invariants are more important to enforce than some of those I mention above.  A buggy implementation can violate these invariants (and as I mentioned above, all browser implementations are to some degree buggy).  A buggy library can forget to freeze even though it is spec'ed do so.  I don't see why a buggy proxy is any more of a problem. 

My understanding was that a major motivation for these operations was  to create objects that can be passed to untrusted code while being safe from tampering.  The work around in the presences of proxies would seem to be don't pass any such buggy proxies or to create your own trusted proxy that wrappers the potentially buggy proxy.

The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.


You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.


W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.

I don't like Sean's API because it requires the trapping infrastructure to build and perform validation against a potentially large data structure (per object table of all property names that have been set non-confgurable).   That's the sort of complex invariant maintenance that I don't think belongs at the implementation level of a dynamic language.  Consider as a use case the ES5 String object.  String objects have a "virtual" property foe each character of their underlying string value.  Each of these character properties is non-configurable but the String object itself is extensible.  A string value potentially has millions of such character properties and they routinely have thousands of them.  Using Proxies to implement this style of virtual properties over some fixed data source seems like a great use case. It should be possible and it should burden the underlying runtime with the overhead of validating a complex invariant that is practice would likely only fail during debugging of the Proxy.


Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:
- allow proxies to emulate/intercept non-configurable properties without checking
- introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.

This seems like a reasonable approach.

I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".  Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


Allen


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Allen Wirfs-Brock
In reply to this post by Cameron McCormack-4

On May 12, 2011, at 4:20 PM, Cameron McCormack wrote:

> Tom Van Cutsem:
>> invariants that are enforced:
> …
>> - unconfigurable [[Class]] (Object or Function, respectively)
>
> Web IDL requires [[Class]] to take on values other than these two, for
> example it should be "HTMLDivElement" for an HTMLDivElement object.  I
> have a feeling that the web requires this, as opposed to just having a
> custom toString function.


I'm still hopeful that I can eliminate [[Class]] entirely from the ES.next specification.

What is WebIDL really trying to accomplish when it specifies class values.  Parameterizing toString.  Trademarking objects?  Something else.  All the use cases I have seen for [[class]] an be accomplished some other way rather than by over-loading this specification device with additional meanings.

Allen
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Allen Wirfs-Brock

On May 12, 2011, at 6:52 PM, Allen Wirfs-Brock wrote:


I'm still hopeful that I can eliminate [[Class]] entirely from the ES.next specification


allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Mark S. Miller-2
In reply to this post by Tom Van Cutsem-3
Hi Tom, thanks for putting these lists together. It will really help clarify why we decided to enforce some invariants and not others. The crucial distinction is that between 
1) "momentarily invariant between two successive steps, i.e., given no interleaving with other code". 
2) "eternally invariant for all time" vs 
Let's take the first two examples from each of your lists:

a) proxies can't take on the identity of other objects (i.e. '===' can't be intercepted)
b) has('foo') returning true while getPropertyDescriptor('foo') returns undefined

Let's write a test expressing each of the four combinations. In the following code, assume the bindings of assertTrue, Object.getPropertyDescriptor, and the test functions defined below are stable, as varying them to cause the test to fail does not demonstrate a violation of the invariant being tested.

  function test1a(p1, p2) {
    assertTrue((p1 === p2) === (p1 === p2));
  }

In ES5, I claim that there is no way I can call test1a that will cause it to fail, even with conforming host objects. This establishes only that === is stable between consecutive steps, i.e., without any interleaving.

  function test2a(p1, p2, interleave) {
    "use strict";
    var sameBefore = (p1 === p2);
    interleave();
    assertTrue(sameBefore === (p1 === p2));
  }

In ES5, I claim that there is no way I can call test2a that will cause it to fail, even with conforming host objects. This establishes that the invariant is robust across interleavings with other code. (The "use strict" above is only to suppress a loophole that would actually be besides the point: Otherwise, interleave could modify test2a.arguments[0], causing test2a to fail for reasons other than violation of the invariant we're testing.)

  function test1b(p1, name) {
    "use strict";
    name = String(name); // possible interleaving here, which is why we need "use strict" above
    assertTrue((name in p1) === (Object.getPropertyDescriptor(p1, name) !== undefined));
  }

In ES5 augmented with only Object.getPropertyDescriptor, I claim that there is no way I can call test1b that will cause it to fail, even with conforming host objects. This establishes invariant #b in the absence of interleaving.

  function test2b(p1, name, interleave) {
    "use strict";
    name = String(name);
    var hasBefore = (name in p1);
    interleave();
    assertTrue(hasBefore === (Object.getPropertyDescriptor(p1, name) !== undefined));
  }

In ES5 augmented with only Object.getPropertyDescriptor, I can cause this test to fail as follows:

  var x = {foo: 8};
  test2b(x, 'foo', function(){ delete x.foo; });

So #a is eternally invariant while #b is only momentarily invariant.

The most significant weakening that proxies introduce, relative to our ability to reason in ES5, is introducing more potential interleaving points. In ES5, ('foo' in p1) could not cause code elsewhere to run, well, unless p1 is a host object. Since proxies introduce so many new interleaving points, it should not be surprising that proxies can break momentary invariants -- they could anyway by the same means that we broke test2b. The important question is: Which eternal invariants are we willing to lose? Let's go through your list again and see which elements of which list break which kind of invariant:


On Thu, May 12, 2011 at 5:40 AM, Tom Van Cutsem <tomvc.be@gmail.com> wrote:
I thought it might be productive to try and list the relevant "invariants" that proxies may or may not violate. Here is an initial list, which I do not claim is complete. If people think it's useful I can also record them on the wiki.

invariants that are enforced:

- proxies can't take on the identity of other objects (i.e. '===' can't be intercepted)


Eternal.
 

- immutable [[Prototype]]


Eternal for frozen objects. Not guaranteed eternal for non-frozen objects, but interleavings can only violate this invariant by using non-standard non-portable operations. Where these operations are available, this is a momentary invariant. Elsewhere it is eternal.
 

- unconfigurable instanceof (Proxy.create(handler, f.prototype) implies proxy instanceof f, function proxies are instanceof Function)


In ES5, (p1 instanceof F) is eternally stable only once p1's [[Prototype]] chain is immutable and F.prototype is frozen. If F.prototype is not frozen, then (p1 instanceof F) is not stable even when p1 is a proxy. 

ES5 does specify that Function.prototype is frozen, so if p1 is a function and p1.[[Prototype]] cannot be modified (for whatever reason), then (p1 instanceof Function) is eternally stable.

 

- unconfigurable typeof (typeof objectproxy === "object", typeof functionproxy === "function")


typeof is eternally stable. The specified constraints on typeof's value are therefore eternal invariants.

 

- unconfigurable [[Class]] (Object or Function, respectively)


[[Class]] is eternally stable. The specified constraints on [[Class]]'s value are therefore eternal invariants.


 

- once preventExtensions, seal, freeze is called on a proxy, its properties are fixed, so the invariants associated with these operations are maintained (e.g. can't add new properties, can't delete existing properties, …)


In both cases, given that these operations return successfully rather than throw. Eternal.

 


controversial invariant:

- proxies can't emulate non-configurable properties. If they would, proxies could still update attributes of non-configurable properties.


The ES5 constraints on updating non configurable properties are eternal invariants.

 


invariants that can be broken:

- general inconsistencies between traps

  - e.g. has('foo') returning true while getPropertyDescriptor('foo') returns undefined


Momentary, as established in the intro.
 

  - e.g. has('foo') returning true while getPropertyNames() doesn't contain it


Momentary.
 

  - e.g. get('foo') returning 42 while getOwnPropertyDescriptor('foo').value returns 24 (with no assignment operations happening in between)


The parenthetical acknowledges the momentary nature of the invariant. Since the whole point of proxies is to interleave code anyway, the handler could have simply performed said assignment.

 

- traps that return values of the wrong type, e.g. getOwnPropertyNames not returning an array, getOwnPropertyDescriptor not returning a valid property descriptor


Eternal. I grant that this breaks the pattern.

 

- inheritance: traps are free to ignore the proxy's prototype when it comes to property lookup


There are some implied eternal invariants that this does break. We should enumerate them. But the obvious ones are momentary.

 

- duplicate property names in the property listing traps (enumerate, get{Own}PropertyNames)


Eternal
 

- the keys/enumerate traps should only return enumerable property names


Momentary

 

- the keys/getOwnPropertyNames traps should only return "own" property names


Momentary

 

- the result of getOwnPropertyNames should be a proper subset of the result of getPropertyNames (same for enumerate/keys)


Momentary

 

- ... (I did not try to be exhaustive)


;)


So I'm rather calm about proxies breaking momentary invariants. We should be very careful when we consider breaking eternal invariants.

 

Because the ES5 spec is very implicit about most of these invariants, any distinction between which invariants to uphold and which not will be necessarily vague. However, I can discern some logic in the current distinction:

Most of the enforced properties have to do with classification: instanceof, typeof and === are operators used to classify objects, and classifications typically come with some implied invariants (I'm aware of the fact that instanceof tests can be non-monotonic in JS).

For {freeze|seal|preventExtensions}, one can make the case that defensive programming is one of their main use cases. Allowing proxies to gratuitously break them feels like taking away a lot of the usefulness of these primitives. The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.


W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.


Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:

- allow proxies to emulate/intercept non-configurable properties without checking

- introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.


Whether or not ESObject should or could be fully defined in either the engine or in Javascript is an orthogonal issue.



This still enables the attacker to give to the defender an object that breaks the old eternal invariants that the defender may have been relying on.

 


Cheers,

Tom


2011/5/11 David Bruant <[hidden email]>
Le 11/05/2011 08:41, Allen Wirfs-Brock a écrit :

I think we are dancing around one of the key differences between static languages and dynamic languages.  Static languages make guarantees about a set of potentially complex invariants  (for example, subtype conformance).   They can do this because the necessary work to detect violations of those invariants is performed ahead of time before the program is allowed to execute.  Dynamic languages do most invariant validation as the program runs and hence generally restrict themselves to guaranteeing simple invariants (for example, memory safety) that can be cheaply performed many times as the program runs.  Dynamic languages generally avoid expense checking of complex invariants and instead assume that any critical violation of complex invariants will ultimately manifest  themselves as violations of the simple invariants that are checked.

A related difference is that a static language generally rejects programs when it proves the set of all possible program inputs produces some states that violate the language's invariants.  The program is rejected, even if the input states that produce the invariant violations will never occur in practice.  This is a conservative (or pessimistic) approach -- if a program might fail, we assume it will fail.  Dynamic languages generally only reject programs (at runtime) when the actual data values used by the program violates the language's invariants.  This is a permissive (or optimistic) approach -- if a program might work, we give it the benefit of the doubt and let it run up to the point it begins to misbehave.

The configurability restrictions on Proxies seems to be trying to apply a static language perspective to the very dynamic ES language.  They are based upon a complex invariant (what can/cannot be assumed after  observing the state of a configurable attribute).  Because, there is at best difficult to guarantee that user written proxy handlers will correctly enforce the invariants associated with of configurable:false it is forbidden for a proxy to set configurable to that state.  It is pessimistic, it says that because somebody might write a buggy proxy setting configurable we won't let them write any proxy that sets configurable.  An alternative that has been proposed is to try to dynamically enforce the configurable invariants.  But that is an example, of moving expensive (and probably highly redundant)  complex invariants checks into runtime.  While it would catch buggy programs, but has the potential of imposing a significant runtime performance penalty on valid programs.
 The normal dynamic language approach to this sort of problem is to be optimistic about the validity of the program while continuing to guarantee memory safety, and depending upon conventional testing procedure to detect more complex error conditions.
I understand the rationale that leads to the difference you describe in static/dynamic languages design. I understand it and I think these are good reasons. However, I can't help asking you some sort of proof. Has some research been done in the area?
Are there dynamic languages that tried to enforce invariants at run-time? What lessons did they learn from that experience?
Was the cost on valid program big enough to question these checks?
Are there examples of dynamic languages interpreter with static analysis that were able to diminish this cost? Diminishing the cost to make the program "as fast in the long term"? (I quote, because I know that "as fast" and "in the long term" are vague notions)

David


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Cameron McCormack-4
In reply to this post by Allen Wirfs-Brock
Allen Wirfs-Brock:
> I'm still hopeful that I can eliminate [[Class]] entirely from the
> ES.next specification.
>
> What is WebIDL really trying to accomplish when it specifies class
> values. Parameterizing toString. Trademarking objects? Something else.
> All the use cases I have seen for [[class]] an be accomplished some
> other way rather than by over-loading this specification device with
> additional meanings.

All it is trying to accomplish is making
Object.prototype.toString.call(object) return the kinds of values that
websites expect.  Websites are doing that to check the type of the
object they’ve got, yes.

> See
> http://wiki.ecmascript.org/doku.php?id=strawman:es5_internal_nominal_typing
> for a sketch of what I have in mind

Being able to parameterise Object.prototype.toString is all that’d be
needed.  I suppose that can’t be done just with a self-contained Proxies
spec, but requires changes to the Object.prototype.toString definition.

--
Cameron McCormack ≝ http://mcc.id.au/
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Mark S. Miller-2
In reply to this post by Allen Wirfs-Brock


On Thu, May 12, 2011 at 6:48 PM, Allen Wirfs-Brock <[hidden email]> wrote:
Thanks Tom,

As you point out, the are plenty of other implicit invariants that proxies don't enforce. For example:
   - a configurable property can be deleted

In ES5, cannot a conforming host object already break this invariant?

 
   - a [[Put]] to a non-writable data property does not change the value observable via [[Get]]

By the classification of the message I just sent, whether the property is a non-writable data property at the time of [[Put]] is
Momentary.

 
   - the attributes of a configurable property can be changed

Conforming host objects can already violate this.

 
   - obj.hasOwnProperty("foo")===obj.hasOwnProperty("foo")  //is true

Momentary.

 
   -Object.getOwnPropertyDescriptor(obj,"foo").hasOwnProperty("value) ) && obj.foo===obj.foo  //is true, ignoring NaN case
or lots of other consistency invariants among sequences of traps

Momentary.
 

I also wanted to point out that no modern browser fully respects the configurable invariants.  Every browser implements RegExp.prototype.compile and the de-facto standard  for its behavior blatantly  modifies the properties specified in 15.10.7  which are defined to be configurable false and writable: false.  The discussions that have occurred concerning  this method concluded that it (with that behavior) is essential to the web and that it should be included in the next ES edition.  I haven't figured out how we will reconcile this.  Probably by turning the affected properties into accessors.

Fortunately, RegExp.prototype.compile is deletable on all major browsers. (I know because initSES.js deletes it.)

 


On May 12, 2011, at 5:40 AM, Tom Van Cutsem wrote:

...

Most of the enforced properties have to do with classification: instanceof, typeof and === are operators used to classify objects, and classifications typically come with some implied invariants (I'm aware of the fact that instanceof tests can be non-monotonic in JS).

For {freeze|seal|preventExtensions}, one can make the case that defensive programming is one of their main use cases. Allowing proxies to gratuitously break them feels like taking away a lot of the usefulness of these primitives.

Generally, ES is not a hand holding language.  In particular, I don't see why these invariants are more important to enforce than some of those I mention above.  A buggy implementation can violate these invariants (and as I mentioned above, all browser implementations are to some degree buggy).  A buggy library can forget to freeze even though it is spec'ed do so.  I don't see why a buggy proxy is any more of a problem. 

My understanding was that a major motivation for these operations was  to create objects that can be passed to untrusted code while being safe from tampering.  The work around in the presences of proxies would seem to be don't pass any such buggy proxies or to create your own trusted proxy that wrappers the potentially buggy proxy.

The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.


You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.


W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.

I don't like Sean's API because it requires the trapping infrastructure to build and perform validation against a potentially large data structure (per object table of all property names that have been set non-confgurable).   That's the sort of complex invariant maintenance that I don't think belongs at the implementation level of a dynamic language.  Consider as a use case the ES5 String object.  String objects have a "virtual" property foe each character of their underlying string value.  Each of these character properties is non-configurable but the String object itself is extensible.  A string value potentially has millions of such character properties and they routinely have thousands of them.  Using Proxies to implement this style of virtual properties over some fixed data source seems like a great use case. It should be possible and it should burden the underlying runtime with the overhead of validating a complex invariant that is practice would likely only fail during debugging of the Proxy.


Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:
- allow proxies to emulate/intercept non-configurable properties without checking
- introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.

This seems like a reasonable approach.

I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".  Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


Allen


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Mark S. Miller-2
In reply to this post by Allen Wirfs-Brock
On Thu, May 12, 2011 at 6:48 PM, Allen Wirfs-Brock <[hidden email]> wrote:

My understanding was that a major motivation for these operations was  to create objects that can be passed to untrusted code while being safe from tampering.  The work around in the presences of proxies would seem to be don't pass any such buggy proxies or to create your own trusted proxy that wrappers the potentially buggy proxy. 

The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.


You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.

This is equivalent to saying that attacks can choose to be nice to defenders. If attackers aren't nice, then their code is buggy, so problem solved.


 


W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.

I don't like Sean's API because it requires the trapping infrastructure to build and perform validation against a potentially large data structure (per object table of all property names that have been set non-confgurable).   That's the sort of complex invariant maintenance that I don't think belongs at the implementation level of a dynamic language.  Consider as a use case the ES5 String object.  String objects have a "virtual" property foe each character of their underlying string value.  Each of these character properties is non-configurable but the String object itself is extensible.  A string value potentially has millions of such character properties and they routinely have thousands of them.  Using Proxies to implement this style of virtual properties over some fixed data source seems like a great use case. It should be possible and it should burden the underlying runtime with the overhead of validating a complex invariant that is practice would likely only fail during debugging of the Proxy.


Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:
- allow proxies to emulate/intercept non-configurable properties without checking
- introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.

This seems like a reasonable approach.

I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".  Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


Allen


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Mark S. Miller-2
On Thu, May 12, 2011 at 7:18 PM, Mark S. Miller <[hidden email]> wrote:
On Thu, May 12, 2011 at 6:48 PM, Allen Wirfs-Brock <[hidden email]> wrote:

[...] 
You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.

This is equivalent to saying that attacks can choose to be nice to defenders. If attackers aren't nice, then their code is buggy, so problem solved.

s/attacks/attackers/

 
--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Oliver Hunt-2
In reply to this post by Allen Wirfs-Brock
Mark already commented on these, but i'll just add an additional comment
 * hasOwnProperty and getOwnPropertyDescriptor, like all of these meta object functions were not added as immutable properties, so none of them can be trusted and there's no way (pending the modules proposal?) to guarantee that you are getting a real version of the function.  So their semantics are basically not trustworthy.

That out of the way, I think there's one thing that I am still not 100% clear on which is what the correct behaviour for host object properties is meant to be in the case of those properties that aren't essentially standard properties.

My recollection of this discussion from a long time ago was that:
* If a property value may change it must be reported as writable, even if it cannot be assigned to
* If a property may disappear it must be configurable, even if it cannot be deleted.

(Totally ignoring the problems of preventExtensions, seal and freeze.)

But I recall seeing something a while back that made me question this behaviour, so I'm curious as to whether someone could clarify.

--Oliver

On May 12, 2011, at 6:48 PM, Allen Wirfs-Brock wrote:

Thanks Tom,

As you point out, the are plenty of other implicit invariants that proxies don't enforce. For example:
   - a configurable property can be deleted
   - a [[Put]] to a non-writable data property does not change the value observable via [[Get]]
   - the attributes of a configurable property can be changed
   - obj.hasOwnProperty("foo")===obj.hasOwnProperty("foo")  //is true
   -Object.getOwnPropertyDescriptor(obj,"foo").hasOwnProperty("value) ) && obj.foo===obj.foo  //is true, ignoring NaN case
or lots of other consistency invariants among sequences of traps

I also wanted to point out that no modern browser fully respects the configurable invariants.  Every browser implements RegExp.prototype.compile and the de-facto standard  for its behavior blatantly  modifies the properties specified in 15.10.7  which are defined to be configurable false and writable: false.  The discussions that have occurred concerning  this method concluded that it (with that behavior) is essential to the web and that it should be included in the next ES edition.  I haven't figured out how we will reconcile this.  Probably by turning the affected properties into accessors.


On May 12, 2011, at 5:40 AM, Tom Van Cutsem wrote:

...

Most of the enforced properties have to do with classification: instanceof, typeof and === are operators used to classify objects, and classifications typically come with some implied invariants (I'm aware of the fact that instanceof tests can be non-monotonic in JS).

For {freeze|seal|preventExtensions}, one can make the case that defensive programming is one of their main use cases. Allowing proxies to gratuitously break them feels like taking away a lot of the usefulness of these primitives.

Generally, ES is not a hand holding language.  In particular, I don't see why these invariants are more important to enforce than some of those I mention above.  A buggy implementation can violate these invariants (and as I mentioned above, all browser implementations are to some degree buggy).  A buggy library can forget to freeze even though it is spec'ed do so.  I don't see why a buggy proxy is any more of a problem. 

My understanding was that a major motivation for these operations was  to create objects that can be passed to untrusted code while being safe from tampering.  The work around in the presences of proxies would seem to be don't pass any such buggy proxies or to create your own trusted proxy that wrappers the potentially buggy proxy.

The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.


You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.


W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.

I don't like Sean's API because it requires the trapping infrastructure to build and perform validation against a potentially large data structure (per object table of all property names that have been set non-confgurable).   That's the sort of complex invariant maintenance that I don't think belongs at the implementation level of a dynamic language.  Consider as a use case the ES5 String object.  String objects have a "virtual" property foe each character of their underlying string value.  Each of these character properties is non-configurable but the String object itself is extensible.  A string value potentially has millions of such character properties and they routinely have thousands of them.  Using Proxies to implement this style of virtual properties over some fixed data source seems like a great use case. It should be possible and it should burden the underlying runtime with the overhead of validating a complex invariant that is practice would likely only fail during debugging of the Proxy.


Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:
- allow proxies to emulate/intercept non-configurable properties without checking
- introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.

This seems like a reasonable approach.

I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".  Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Mark S. Miller-2
In reply to this post by Allen Wirfs-Brock
On Thu, May 12, 2011 at 6:48 PM, Allen Wirfs-Brock <[hidden email]> wrote:
[...] 
I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".

I think this is the central point of agreement. If conforming host objects can violate it, then it isn't an ES5 invariant. We should be most suspicious of violating eternal invariants that even conforming ES5 host objects must obey.

 
 Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

Further constraining a handler to only be able to emulate a conforming native object is a great use for such a wrapper. This use does not invert the threat model.

 

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


Allen


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Mark S. Miller-2
In reply to this post by Oliver Hunt-2
On Thu, May 12, 2011 at 7:23 PM, Oliver Hunt <[hidden email]> wrote:
Mark already commented on these, but i'll just add an additional comment
 * hasOwnProperty and getOwnPropertyDescriptor, like all of these meta object functions were not added as immutable properties, so none of them can be trusted and there's no way (pending the modules proposal?) to guarantee that you are getting a real version of the function.  So their semantics are basically not trustworthy.

That out of the way, I think there's one thing that I am still not 100% clear on which is what the correct behaviour for host object properties is meant to be in the case of those properties that aren't essentially standard properties.

My recollection of this discussion from a long time ago was that:
* If a property value may change it must be reported as writable, even if it cannot be assigned to

either writable, configurable, or described as an accessor property, yes. Flipped around is clearer: Once a host object describes a property as a non-writable non-configurable data property, then it must report that property as having a stable value and stable attributes. Thus, caching logic can use this test to reliably cache such values without worrying about becoming confused by buggy or malicious clients. (Those unconcerned about malice should at least ask whether they care about defensiveness in the face of bugs.)

 
* If a property may disappear it must be configurable, even if it cannot be deleted.

yes
 

(Totally ignoring the problems of preventExtensions, seal and freeze.)

But I recall seeing something a while back that made me question this behaviour, so I'm curious as to whether someone could clarify.

--Oliver

On May 12, 2011, at 6:48 PM, Allen Wirfs-Brock wrote:

Thanks Tom,

As you point out, the are plenty of other implicit invariants that proxies don't enforce. For example:
   - a configurable property can be deleted
   - a [[Put]] to a non-writable data property does not change the value observable via [[Get]]
   - the attributes of a configurable property can be changed
   - obj.hasOwnProperty("foo")===obj.hasOwnProperty("foo")  //is true
   -Object.getOwnPropertyDescriptor(obj,"foo").hasOwnProperty("value) ) && obj.foo===obj.foo  //is true, ignoring NaN case
or lots of other consistency invariants among sequences of traps

I also wanted to point out that no modern browser fully respects the configurable invariants.  Every browser implements RegExp.prototype.compile and the de-facto standard  for its behavior blatantly  modifies the properties specified in 15.10.7  which are defined to be configurable false and writable: false.  The discussions that have occurred concerning  this method concluded that it (with that behavior) is essential to the web and that it should be included in the next ES edition.  I haven't figured out how we will reconcile this.  Probably by turning the affected properties into accessors.


On May 12, 2011, at 5:40 AM, Tom Van Cutsem wrote:

...

Most of the enforced properties have to do with classification: instanceof, typeof and === are operators used to classify objects, and classifications typically come with some implied invariants (I'm aware of the fact that instanceof tests can be non-monotonic in JS).

For {freeze|seal|preventExtensions}, one can make the case that defensive programming is one of their main use cases. Allowing proxies to gratuitously break them feels like taking away a lot of the usefulness of these primitives.

Generally, ES is not a hand holding language.  In particular, I don't see why these invariants are more important to enforce than some of those I mention above.  A buggy implementation can violate these invariants (and as I mentioned above, all browser implementations are to some degree buggy).  A buggy library can forget to freeze even though it is spec'ed do so.  I don't see why a buggy proxy is any more of a problem. 

My understanding was that a major motivation for these operations was  to create objects that can be passed to untrusted code while being safe from tampering.  The work around in the presences of proxies would seem to be don't pass any such buggy proxies or to create your own trusted proxy that wrappers the potentially buggy proxy.

The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.


You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.


W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.

I don't like Sean's API because it requires the trapping infrastructure to build and perform validation against a potentially large data structure (per object table of all property names that have been set non-confgurable).   That's the sort of complex invariant maintenance that I don't think belongs at the implementation level of a dynamic language.  Consider as a use case the ES5 String object.  String objects have a "virtual" property foe each character of their underlying string value.  Each of these character properties is non-configurable but the String object itself is extensible.  A string value potentially has millions of such character properties and they routinely have thousands of them.  Using Proxies to implement this style of virtual properties over some fixed data source seems like a great use case. It should be possible and it should burden the underlying runtime with the overhead of validating a complex invariant that is practice would likely only fail during debugging of the Proxy.


Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:
- allow proxies to emulate/intercept non-configurable properties without checking
- introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.

This seems like a reasonable approach.

I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".  Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

David Bruant-4
In reply to this post by Rick Waldron
Le 13/05/2011 02:55, Rick Waldron a écrit :
> David,
>
> For clarification, can you give a working example (ie runable in FF
> nightly) of this:
>
> "Object.prototype.toString could return different
> things for DOM objects. This can certainly be implemented in pure
> ES.next with WeakMaps. "
Sure. Here is an example of what I was thinking:
https://gist.github.com/970223
I run it directly on the webconsole and it works like a charm (Tested on
latest FF nightly on Windows 7 64bits)
A couple of things to keep in mind:
- I have no idea which DOM "classes" people expect and what particular
values of [[Class]] are set for them.
- I do not create objects respecting the DOM interfaces (it shouldn't
make any difference, but tell me if you think it does)
- My sole purpose was to prove feasbility. I am aware that the solution
I show is suboptimal in several ways (especially the several
redefinitions of Object.prototype.toString)
- The same could have been achieved with arrays instead of weak maps,
but would have led to memory leaks.
- I assume the "environment setting" code to run in a fresh conforming
ES environment (ES5.1 + current implicit consensus on WeakMaps)

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

David Bruant-4
In reply to this post by Cameron McCormack-4
Le 13/05/2011 04:09, Cameron McCormack a écrit :

> Allen Wirfs-Brock:
>> I'm still hopeful that I can eliminate [[Class]] entirely from the
>> ES.next specification.
>>
>> What is WebIDL really trying to accomplish when it specifies class
>> values. Parameterizing toString. Trademarking objects? Something else.
>> All the use cases I have seen for [[class]] an be accomplished some
>> other way rather than by over-loading this specification device with
>> additional meanings.
> All it is trying to accomplish is making
> Object.prototype.toString.call(object) return the kinds of values that
> websites expect.  Websites are doing that to check the type of the
> object they’ve got, yes.
>
>> See
>> http://wiki.ecmascript.org/doku.php?id=strawman:es5_internal_nominal_typing
>> for a sketch of what I have in mind
> Being able to parameterise Object.prototype.toString is all that’d be
> needed.  I suppose that can’t be done just with a self-contained Proxies
> spec, but requires changes to the Object.prototype.toString definition.
Yes and no. In https://gist.github.com/970223 , I indeed redefine
Object.prototype.toString, but this change is transparent and
un-noticeable from user code (since it only affects objects for
constructor the DOM environment controls). From the way I see it, a web
browser ES environment works like this (of course, this is a naive view):
1) Initialize a fresh ES-compliant environment (built-in defined in the
spec (including global object))
2) Initialize the DOM environment (all constructors (Node, Element...)
and basic objects (window (global object extension), document...))
3) Start parsing HTML (appending DOM elements along the way) and run
scripts as they arrive (what I call "user code").

So if phase 2 changes any built-in in a way that is not noticeable from
user code, I don't think it's a problem. In my code, the only way I see
that some code could understand that Object.prototype.toString has been
changed is by comparing object identities. But since user code only
occur after phase 2 is completed, it cannot get the ES built-in
Object.prototype.toString identity to compare afterward.

So, my example changes Object.prototype.toString definition strictly
speaking, but not as far as web authors are concerned.
Given that my 3 phases model is correct, in my opinion, WebIDL, in its
effort to define the DOM in terms of ECMAScript 5 (+ Harmony proxies
[1]) can take all liberty to make changes to the definition of built-ins
as long as the ES environment looks fresh after phase 2. This would
allow duck-typing when necessary. This would allow to define a couple of
consistently implemented non-standard methods which belong in web
browsers more than ECMAScript (see five last String.prototype.* methods
in [2]).
Of course, this would be just for spec purposes and implementations
would have all liberty to implement differently than what the spec says.

David

[1] WeakMaps aren't necessary since we're dealing with a spec not an
actual implementation
[2] http://kangax.github.com/es5-compat-table/non-standard/
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Rick Waldron
In reply to this post by David Bruant-4
David,

This is awesome, thank you for taking the time to put this together. If I have any specific questions for you, should I ask them here (perhaps others would benefit) or should I email you directly?

Thanks again

Rick



-- Sent from my Palm Pre


On May 13, 2011 5:09 AM, David Bruant <[hidden email]> wrote:

Le 13/05/2011 02:55, Rick Waldron a écrit :
> David,
>
> For clarification, can you give a working example (ie runable in FF
> nightly) of this:
>
> "Object.prototype.toString could return different
> things for DOM objects. This can certainly be implemented in pure
> ES.next with WeakMaps. "
Sure. Here is an example of what I was thinking:
https://gist.github.com/970223
I run it directly on the webconsole and it works like a charm (Tested on
latest FF nightly on Windows 7 64bits)
A couple of things to keep in mind:
- I have no idea which DOM "classes" people expect and what particular
values of [[Class]] are set for them.
- I do not create objects respecting the DOM interfaces (it shouldn't
make any difference, but tell me if you think it does)
- My sole purpose was to prove feasbility. I am aware that the solution
I show is suboptimal in several ways (especially the several
redefinitions of Object.prototype.toString)
- The same could have been achieved with arrays instead of weak maps,
but would have led to memory leaks.
- I assume the "environment setting" code to run in a fresh conforming
ES environment (ES5.1 + current implicit consensus on WeakMaps)

David

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

David Bruant-4
Le 13/05/2011 14:28, Rick Waldron a écrit :
David,

This is awesome, thank you for taking the time to put this together.
No problem. I think it's important to prove that things work by doing them. And this attitude seems to be widely shared on this list which is a good thing.

If I have any specific questions for you, should I ask them here (perhaps others would benefit) or should I email you directly?
I'm fine with both. I think that any question related to ECMAScript may benefit to the list. Depending on your question, other people may respond in my place if they feel they know the answer or start a debate if they disagree with my answers. I think a debate is good when it's transparent and constructive.
However if don't feel comfortable writing on the list, there is no problem to ask me your questions directly.

David


Thanks again

Rick



-- Sent from my Palm Pre


On May 13, 2011 5:09 AM, David Bruant [hidden email] wrote:

Le 13/05/2011 02:55, Rick Waldron a écrit :
> David,
>
> For clarification, can you give a working example (ie runable in FF
> nightly) of this:
>
> "Object.prototype.toString could return different
> things for DOM objects. This can certainly be implemented in pure
> ES.next with WeakMaps. "
Sure. Here is an example of what I was thinking:
https://gist.github.com/970223
I run it directly on the webconsole and it works like a charm (Tested on
latest FF nightly on Windows 7 64bits)
A couple of things to keep in mind:
- I have no idea which DOM "classes" people expect and what particular
values of [[Class]] are set for them.
- I do not create objects respecting the DOM interfaces (it shouldn't
make any difference, but tell me if you think it does)
- My sole purpose was to prove feasbility. I am aware that the solution
I show is suboptimal in several ways (especially the several
redefinitions of Object.prototype.toString)
- The same could have been achieved with arrays instead of weak maps,
but would have led to memory leaks.
- I assume the "environment setting" code to run in a fresh conforming
ES environment (ES5.1 + current implicit consensus on WeakMaps)

David


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Tom Van Cutsem-3
In reply to this post by David Bruant-4
2011/5/12 David Bruant <[hidden email]>
Le 12/05/2011 14:40, Tom Van Cutsem a écrit :
> controversial invariant:
>
> - proxies can't emulate non-configurable properties. If they would,
> proxies could still update attributes of non-configurable properties.
>
Currently, proxies can emulate configurable properties (they are forced
to, but that's not my point). Still, a proxy can ignore
Object.defineProperty calls in the case of a re-configuration and also
ignore deletions, giving the impression that the property is
non-configurable even though Object.getOwnPropertyDescriptor would say
that configurable is set to "true".
Proxies being able to lie about configurability is the exact mirror of
proxies being able to lie about non-configurability. However, one is
allowed, the other isn't.

Good point. However, Mark's distinction between eternal and momentary invariants sheds some light on the differences. According to Mark's classification, configurable:false comes with eternal guarantees, while configurable:true does not. In other words: any assumptions that a program makes that are based on the fact that a property is configurable are necessarily momentary, since the property can become non-configurable later. The reverse is not true.
 
I need to think more about the rest of your message.
Good work on the invariant enumeration. It may be incomplete as you
point out, but that's a good start anyway.

Among the enforced invariants, maybe that "property names being strings"
could be added if that is enforced. If it is, it requries to cast all
property names arguments to strings before trap calls. However,
enforcing this invariant may require to do the same on the array
returned by get{Own}PropertyNames/enumerate/keys. (maybe that it should
rather be in the controversial part :-) )

Proxies do coerce all property names to strings, e.g. proxy[obj] will trigger the 'get' trap with 'obj' coerced to a String. This is not actually enforced by the proxy spec, but rather by ES5 (e.g. [[Get]] assumes that its argument P is bound to a property name (a String)). At one point we suggested removing this restriction, so that "proxy[obj]" would give the get trap direct access to obj (which would be particularly useful when intercepting numeric indices on array-like proxies). IIRC, we didn't pursue this option since engines rely on property names being strings in other places, and widening the type of property names to cover arbitrary objects would be problematic.

Cheers,
Tom
 

David


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: [Harmony Proxies] Proposal: Property fixing

Brendan Eich-3
On May 18, 2011, at 7:28 AM, Tom Van Cutsem wrote:

> Proxies do coerce all property names to strings, e.g. proxy[obj] will trigger the 'get' trap with 'obj' coerced to a String. This is not actually enforced by the proxy spec, but rather by ES5 (e.g. [[Get]] assumes that its argument P is bound to a property name (a String)). At one point we suggested removing this restriction, so that "proxy[obj]" would give the get trap direct access to obj (which would be particularly useful when intercepting numeric indices on array-like proxies). IIRC, we didn't pursue this option since engines rely on property names being strings in other places, and widening the type of property names to cover arbitrary objects would be problematic.

SpiderMonkey has a wider internal property name type, which can accomodate at least int and object names. The int case is an optimization, commonly done. The object case is for E4X and perhaps private names.

Oliver wrote in the thread at the time that he thought allowing any value to be used as a property name (in brackets) and passed through uncoerced to proxies was implementable without trouble for JavaScriptCore, IIRC.

/be

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12345 ... 7