[Harmony Proxies] Proposal: Property fixing

Mark S. Miller erights at google.com
Fri Jun 17 09:45:11 PDT 2011


On Fri, Jun 17, 2011 at 4:53 AM, David Bruant <david.bruant at labri.fr> wrote:

> **
> Le 17/06/2011 02:38, Mark S. Miller a écrit :
>
> Another useful line of question is: Why are these invariants in the spec?
> This is useful to discuss, but is a separate matter.
>
> This is what I was asking, sorry for the confusion. [...] Why each of these
> 5 bullets points is in the spec?
>


Hi David, thanks for asking. I think of them as seven points, divided into
the first four and the last three. The last two have no bullets on them in
the text but are the two paragraphs following the bulleted list at the end
of 8.6.2. Renumbering, so that we can refer back to them:

1) Universal property constraints:

  a) If a property is described as a data property and it may return
different values over time, then either or both of the [[Writable]] and
[[Configurable]] attributes must be true even if no mechanism to change
the value is exposed via the other internal methods.

  b) If a property is described as a data property and its [[Writable]] and
[[Configurable]] are both false, then the SameValue (according to 9.12) must
be returned for the [[Value]] attribute of the property on all calls to
[[GetOwnProperty]].

  c) If the attributes other than [[Writable]] may change over time or if
the property might disappear, then the [[Configurable]] attribute must be
true. *[The "disappear" clause here is also partially a universal object
constraint, and so is relevant to the next list. Alternatively, we could
consider non-existence to be a state of a property.]*

  d) If the [[Writable]] attribute may change from false to true, then the
[[Configurable]] attribute must be true.


2) Universal object constraints:

  a) If the value of the host object‘s [[Extensible]] internal property has
been observed by ECMAScript code to be false, then if a call to
[[GetOwnProperty]] describes a property as non-existent all subsequent
calls must also describe that property as non-existent.

  b) The [[DefineOwnProperty]] internal method [...] must not permit the
addition of a new property to a [...] object if the [[Extensible]] internal
property of that [...] object has been observed by ECMAScript code to be
false.

  c) If the [[Extensible]] internal property of that [...] object has been
observed by ECMAScript code to be false then it must not subsequently become
true.


    ["host" replaced with [...] above for the following reasons]

Although the ES5.1 text describes these only as constraints on non-native
(i.e., "host") objects, I label these as "universal" above, since the
detailed behavior that ES5.1 specifies for all native objects, both normal
and abnormal, all imply these constraints. Put another way, if any object O
on system X violates these constraints, then system X is not a conformant
ES5.1 system. Either O is native, in which case it violates some specific
specified native behavior spec, or O is non-native, in which case it
directly violates the above text from 8.6.2.



> What is the rational behind each of these?
>

One of JavaScript's great virtues is that it is a highly reflective
language, leading programmers and framework builders to engage in a wide
range of meta-programming patterns. One of JavaScript's great flaws is that
its property state space is complex, leading such meta-programmers into a
case explosion. Prior to ES5, there were so few guarantees of any stability
properties over this state space, especially for non-native ("host")
objects, that robust programming was almost impossible.

For example, Caja on ES3, to uphold its own invariants, must handle
non-native objects very carefully. Given the unspecified nature of native
objects, we cannot both handle these objects and maintain our security,
while depending only on specified behavior. To figure out how to handle them
safely enough, we rely on lore and testing as well, relying on observed
regularities not guaranteed by any spec. To diminish the cases we need to
worry about, Caja pays substantial costs to ensure that untrusted code never
gets a direct reference to any non-native object, not even "alert". This ice
is too thin.

How does ES5.1 help make robust meta-programming practical? The following
text from Chapter 4 of <http://erights.org/talks/thesis/> seems relevant:

 In the human world, when you plan for yourself, you make assumptions about
> future situations in which your plan will unfold. Occasionally, someone
> else’s plan may interfere with yours, invalidating the assumptions on which
> your plan is based. To plan successfully, you need some sense of which
> assumptions are usually safe from such disruption. But you do not need to
> anticipate every possible contingency. If someone does something you did not
>  expect, you will probably be better able to figure out how to cope at that
> time anyway.
>


> When programmers write programs, they express plans for machines to
> execute. To formulate such plans, programmers must also make assumptions.
> When separately formulated plans are composed, conflicting assumptions can
> cause the run-time situation to become inconsistent with a given plan’s
> assumptions, corrupting its continued execution. Such corrupted executions
> likely violate assumptions on which other programs depend, potentially
> spreading corruption throughout a system. To program successfully,
> programmers use abstraction and modularity mechanisms to limit (usually
> implicitly) which assumptions must be made, and to structure these
> assumptions so they are more likely to mesh without conflict. Beyond these
> assumptions, correct programs must handle all remaining relevant contingencies.
> *The case analysis burden this requires must be kept reasonable, or robust
>  programming becomes impractical. *

[emphasis added]



In ES5.1, across normal native, abnormal native, and non-native, we reliably
contain the property state space to <
http://wiki.ecmascript.org/doku.php?id=es3.1:attribute_states>. Only the
transition *labels* in this diagram are specific to normal native. If we
erase only these transition labels, keeping the state labels and everything
else, then this diagram is universal and directly reflects the "Universal
property constraints" from 8.6.2. *Open problem: What are the
non-equivalences if any between this diagram and the universal property
constraints? How are these constraints either stronger or weaker than the
diagram?* If there are substantial non-equivalences, then we should revisit
this.

Once we erase the transition labels, then we can without further loss of
info also erase the blue transition arc currently labeled "put" and keep
only the two transitions currently labeled "defineProperty". Even this state
space is distressingly large and hard to think about. But we've learned to
deal with it. Let's not make it any worse.


-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110617/be865c95/attachment.html>


More information about the es-discuss mailing list