Browse Source

Lots of RST indent fixes in hobject algs doc

v1.0-maintenance
Sami Vaarala 10 years ago
parent
commit
2851b1c6e5
  1. 150
      doc/hobject-algorithms.rst

150
doc/hobject-algorithms.rst

@ -37,26 +37,42 @@ Related sections of E5 specification
For raw property algorithms:
* E5 Section 8.12: the default algorithms
* E5 Section 8.6.2: one paragraph lists exotic behaviors (page 33, PDF page 43)
* E5 Section 10.6: arguments object
* E5 Section 15.5.5.2: String object
* E5 Section 15.3.4.5.3, 15.3.5.3, 15.3.5.4: Function object
* E5 Section 15.4.5.1: Array object
For other algorithms:
* E5 Section 8.10.4: FromPropertyDescriptor
* E5 Section 8.10.5: ToPropertyDescriptor
* E5 Section 8.7.1: GetValue
* E5 Section 8.7.2: PutValue
* E5 Section 11.2.1: property accessor expression
* E5 Section 11.13: assignment operators (note that several other places
also "evaluate" property accessor expressions)
* E5 Section 11.4.1: ``delete`` operator
* E5 Section 11.8.6: ``instanceof`` operator
* E5 Section 11.8.7: ``in`` operator
* E5 Section 15.2.3.3: ``Object.getOwnPropertyDescriptor()``
* E5 Section 15.2.3.6: ``Object.defineProperty()``
* E5 Section 15.2.3.7: ``Object.defineProperties()``
Algorithm overview
@ -359,13 +375,17 @@ internal name which corresponds to the bytecode instruction:
* ``Object.getOwnPropertyDescriptor()``
+ But not ``[[GetOwnProperty]]`` or ``[[GetProperty]]`` directly
+ Not "fast path" so implementation should be compact
+ Only throwing variant (``Throw`` is ``true``)
* ``Object.defineProperty()`` and ``Object.defineProperties()``
+ But not ``[[DefineOwnProperty]]`` directly
+ Not "fast path" so implementation should be compact
+ Only throwing variant (``Throw`` is ``true``)
These are used to implement the basic property related run-time operations
@ -402,31 +422,51 @@ Notes
``GetValue()`` from various places:
+ Array initializer
+ Object initializer
+ Grouping operator (parentheses)
+ Property accessor (e.g. ``x['foo']['bar']``)
+ ``new`` operator
+ Function calls
+ Postfix and prefix increment/decrement
+ ``void`` operator
+ Unary operators (plus, minus, bitwise and logical NOT)
+ Binary operators (additive and multiplicative expressions, bitwise,
logical, and comparison operations)
+ ``instanceof`` operator
+ ``in`` operator
+ Conditional operator (``?:``)
+ Simple and compound assignment (right hand side)
+ Comma operator (``,``)
+ Variable declaration initializer
+ ``if``, ``do-while``, ``while``, ``for``, ``for-in``, ``with`` statements
+ ``throw`` statement
* Property references are used as left-hand-side values and written using
``PutValue()`` from various places:
+ Postfix and prefix increment/decrement
+ Simple and compound assignment
+ Variable declaration initializer
+ ``for`` and ``for-in`` statements
Exotic behaviors
@ -448,7 +488,9 @@ GetOwnProperty
Related E5 sections:
* E5 Section 8.12.1: default algorithm
* E5 Section 15.5.5: ``String``
* E5 Section 10.5: arguments object
Default algorithm
@ -530,8 +572,11 @@ after the normal property check is as follows:
c. If ``P`` is ``"length"``, return a Property Descriptor with the values:
* ``[[Value]]: len`` (a number)
* ``[[Enumerable]]: false``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
d. If ``P`` is not an array index (E5 Section 15.4), return ``undefined``.
@ -548,8 +593,11 @@ after the normal property check is as follows:
h. Return a Property Descriptor with the values:
* ``[[Value]]: resultStr``
* ``[[Enumerable]]: true``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
2. Let ``D`` be a newly created Property Descriptor with no fields.
@ -604,8 +652,11 @@ The exotic behavior can be appended to the above algorithm as follows:
c. If ``P`` is ``"length"``, return a Property Descriptor with the values:
* ``[[Value]]: len`` (a number)
* ``[[Enumerable]]: false``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
d. If ``P`` is not an array index (E5 Section 15.4), return ``undefined``.
@ -622,8 +673,11 @@ The exotic behavior can be appended to the above algorithm as follows:
h. Return a Property Descriptor with the values:
* ``[[Value]]: resultStr``
* ``[[Enumerable]]: true``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
2. Let ``D`` be a newly created Property Descriptor with no fields.
@ -706,8 +760,11 @@ Final version with some cleanup and simplification:
1. Return a Property Descriptor with the values:
* ``[[Value]]: len`` (a primitive number)
* ``[[Enumerable]]: false``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
d. If ``P`` is an array index (E5 Section 15.4):
@ -718,8 +775,11 @@ Final version with some cleanup and simplification:
* ``[[Value]]:`` a primitive string of length 1, containing one character
from ``str`` at position ``index`` (zero based index)
* ``[[Enumerable]]: true``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
e. Return ``undefined``.
@ -768,7 +828,9 @@ Get
Related E5 sections:
* E5 Section 8.12.3: default algorithm
* E5 Section 10.5: arguments object
* E5 Section 15.3.5.4: ``Function``
Default algorithm
@ -951,7 +1013,9 @@ DefineOwnProperty
Related E5 sections:
* E5 Section 8.12.9: default algorithm
* E5 Section 15.4.5: ``Array``
* E5 Section 10.5: arguments object
Note that ``String`` exotic properties are taken into account by
@ -1345,7 +1409,7 @@ First, for ``P`` == ``length``:
This is equivalent to:
- Jumping to step 5.
+ Jumping to step 5.
* Step 3.f.1:
If ``newLen`` validation succeeds and new length is not shorter
@ -1489,11 +1553,13 @@ helper in the implementation too) as it's relatively tricky. It is
instead isolated into ``ShortenArray()`` internal helper with inputs:
* old length
* new length
and outputs:
* success flag (``false`` if some element couldn't be deleted)
* final array length to be updated into ``"length"`` property
Adding ``Array`` object exotic behavior
@ -1922,6 +1988,7 @@ Delete
Related E5 sections:
* E5 Section 8.12.7: default algorithm
* E5 Section 10.5: arguments object
Default algorithm
@ -1979,7 +2046,7 @@ This is easy to incorporate and results in:
b. If the result of calling the ``[[GetOwnProperty]]`` internal method
of ``map`` passing ``P`` as the argument is not ``undefined``, then:
a. Call the ``[[Delete]]`` internal method of ``map`` passing ``P``,
1. Call the ``[[Delete]]`` internal method of ``map`` passing ``P``,
and ``false`` as the arguments. (This removes the magic binding
for ``P``.)
@ -2320,8 +2387,11 @@ The following inlines ``[[GetOwnProperty]]`` with all exotic behaviors:
1. Return a Property Descriptor with the values:
* ``[[Value]]: len`` (a primitive number)
* ``[[Enumerable]]: false``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
d. If ``P`` is an array index (E5 Section 15.4):
@ -2330,10 +2400,13 @@ The following inlines ``[[GetOwnProperty]]`` with all exotic behaviors:
2. If ``index`` < ``len``, return a Property Descriptor with the values:
* ``[[Value]]:`` a primitive string of length 1, containing one character
from ``str`` at position ``index`` (zero based index)
* ``[[Value]]:`` a primitive string of length 1, containing one
character from ``str`` at position ``index`` (zero based index)
* ``[[Enumerable]]: true``
* ``[[Writable]]: false``
* ``[[Configurable]]: false``
e. Goto NOTFOUND.
@ -2615,24 +2688,35 @@ exists. The property value is updated with a call to
We can assume that:
* The property exists (checked by ``[[Put]]``)
* The property is a data property (checked by ``[[Put]]``)
* The property cannot be non-writable (checked by ``[[Put]]``, using
``[[CanPut]]``)
* The property descriptor is a data descriptor
* The property descriptor is of the form: ``{ [[Value]]: val }``
* Because the property exists, the ``length`` of an ``Array`` object
cannot change by a write to an array index; however, a write to
``"length"`` may delete array elements
More specifically, we know that in the ``[[DefineOwnProperty]]`` algorithm:
* ``current`` is not ``undefined``
* ``IsGenericDescriptor(current)`` is ``false``
* ``IsDataDescriptor(current)`` is ``true``
* ``IsAccessorDescriptor(current)`` is ``false``
* ``IsGenericDescriptor(Desc)`` is ``false``
* ``IsDataDescriptor(Desc)`` is ``true``
* ``IsAccessorDescriptor(Desc)`` is ``false``
* ``current`` is not ``undefined``
* ``IsGenericDescriptor(current)`` is ``false``
* ``IsDataDescriptor(current)`` is ``true``
* ``IsAccessorDescriptor(current)`` is ``false``
* ``IsGenericDescriptor(Desc)`` is ``false``
* ``IsDataDescriptor(Desc)`` is ``true``
* ``IsAccessorDescriptor(Desc)`` is ``false``
Taking the ``[[DefineOwnProperty]]`` with all exotic behaviors included,
using the above assumptions, eliminating any unnecessary steps, cleaning
@ -2765,13 +2849,19 @@ See E5 Section 8.12.5, step 6.
We can assume that:
* The property does not exist (checked by ``[[Put]]``)
* The object is extensible (checked by ``[[Put]]``)
* The property descriptor is a data descriptor
* The property descriptor has the fields:
+ ``[[Value]]: val``
+ ``[[Writable]]: true``
+ ``[[Enumerable]]: true``
+ ``[[Configurable]]: true``
+ If the object is an ``Array``, the property name ``P`` cannot be
@ -2902,8 +2992,11 @@ We'll refine one more time, by eliminating references to ``Desc`` and using
are:
* ``[[Value]]: val``
* ``[[Writable]]: true``
* ``[[Enumerable]]: true``
* ``[[Configurable]]: true``
3. Return ``true``.
@ -2935,8 +3028,11 @@ Because user code has not had any access to the object, we can narrow down
the possibilities a great deal. Here we assume that:
* Object is extensible
* Property does not exist
* Property does not have exotic behavior and is not virtual
* Property descriptor is a data descriptor, which is fully populated
With these assumptions, eliminating any unnecessary steps, the algorithm is
@ -3338,13 +3434,13 @@ Property descriptor algorithms
E5 Section 8.10 describes descriptor related algorithms:
* ``IsAccessorDescriptor(desc)``: ``true``, if ``desc`` contains *either*
* ``IsAccessorDescriptor(desc)``: ``true``, if ``desc`` contains *either*
``[[Set]]`` or ``[[Get]]``
* ``IsDataDescriptor(desc)``: ``true``, if ``desc`` contains *either*
* ``IsDataDescriptor(desc)``: ``true``, if ``desc`` contains *either*
``[[Value]]`` or ``[[Writable]]``
* ``IsGenericDescriptor(desc)``: ``true`` if both
* ``IsGenericDescriptor(desc)``: ``true`` if both
``IsAccessorDescriptor(desc)`` and ``IsGenericDescriptor`` are
``false``; concretely:
@ -3362,10 +3458,10 @@ A property descriptor may not be both a data descriptor and access descriptor
``Object.defineProperty()`` may naturally contain e.g. ``"set"`` and
``"value"`` keys. In this case:
* ``defineProperty()`` uses ``ToPropertyDescriptor()`` to convert the
* ``defineProperty()`` uses ``ToPropertyDescriptor()`` to convert the
Ecmascript object into an internal property descriptor
* ``ToPropertyDescriptor()`` creates a property descriptor and throws a
* ``ToPropertyDescriptor()`` creates a property descriptor and throws a
``TypeError`` if the descriptor contains conflicting fields
``ToPropertyDescriptor()`` also coerces the values in its argument
@ -3698,7 +3794,9 @@ This leads to externally visible behavior, illustrated in the following::
Behavior in Ecmascript implementations seems to vary:
* NodeJS / V8: prints 'string' and 'object' as expected
* Rhino: prints 'object' and 'object'
* Smjs: prints 'object' and 'object'
``GetValue()`` allows the caller to skip creation of the coerced object
@ -3890,7 +3988,9 @@ we know that it is a ``Boolean`` instance, a ``Number`` instance, or a ``String`
instance (see E5 Section 9.9). The "own properties" of these are:
* ``Boolean``: none
* ``Number``: none
* ``String``: ``"length"`` and index properties for string characters
So, the coercion can be skipped safely for everything except ``String``\ s.
@ -5045,8 +5145,11 @@ The resulting algorithm is:
are:
* ``[[Value]]: V``
* ``[[Writable]]: true``
* ``[[Enumerable]]: true``
* ``[[Configurable]]: true``
14. Return.
@ -5092,7 +5195,9 @@ be created or an existing one updated.
For the possible coerced values, the own properties are:
* ``Boolean``: none
* ``Number``: none
* ``String``: ``"length"`` and index properties for string characters
These can be checked explicitly when coercing (and reject the attempt before
@ -5266,8 +5371,11 @@ Avoiding temporaries altogether:
are:
* ``[[Value]]: V``
* ``[[Writable]]: true``
* ``[[Enumerable]]: true``
* ``[[Configurable]]: true``
13. Return.
@ -5456,8 +5564,11 @@ Addressing the array ``length`` issue:
are:
* ``[[Value]]: V``
* ``[[Writable]]: true``
* ``[[Enumerable]]: true``
* ``[[Configurable]]: true``
14. If ``pendingLength`` > ``0``:
@ -5605,7 +5716,9 @@ discarded, there are only two possible user visible effects:
* The return value of ``[[Delete]]``, which is:
+ ``true``, if the property does not exist
+ ``true``, if the property exists and could be deleted
+ ``false``, if the property exists, cannot be deleted, and
``Throw`` is ``false`` (if ``Throw`` is ``true``, an error is
thrown instead)
@ -5618,7 +5731,9 @@ discarded, there are only two possible user visible effects:
The coerced temporary object can be:
* a ``Boolean`` instance: no own properties
* a ``Number`` instance: no own properties
* a ``String`` instance: has ``length`` and array indices (inside string
length) as own properties, all non-configurable
@ -5643,6 +5758,7 @@ entirely:
1. If ``P`` is length or an array index inside the ``O`` string length:
a. If ``currStrict`` is ``true``, throw a ``TypeError``
b. Else, return ``false``
2. Else, return ``true``
@ -5665,6 +5781,7 @@ Step 4 can be simplified a bit:
a. If ``P`` is length or an array index inside the ``O`` string length:
1. If ``currStrict`` is ``true``, throw a ``TypeError``
2. Else, return ``false``
5. Return ``true``
@ -6875,4 +6992,3 @@ Future work
* Review the algorithms for robustness against internal errors such as
out of memory. The order of operations should be chosen to minimize
any inconsistency in state if an internal error occurs.

Loading…
Cancel
Save