David-Sarah Hopwood wrote:
> /**
> * Check that a chain of property accesses starting from obj, and
> * using property names given by subsequent arguments, is guaranteed
> * to give a constant result. No getters are invoked during the check.
> *
> * This can be used to relax the condition that all accesses to captured
> * variables of a deepFrozen function are deepFrozen. For instance,
> * if a @deepFrozen function uses foo only by accessing foo.bar.baz,
> * then rather than requiring foo to be deepFrozen, we can require
> * just that foo.bar.baz gives a constant result.
> * I.e. we verify that foo is statically const, and generate a call to
> * checkConstant(foo, 'bar', 'baz') for each scope in which foo
> * might be different.
> */
> function checkConstant(obj /*, ...*/) {
The implementation of checkConstant was consistent with the comment, but
it was not quite what is needed. It's also necessary to check that the
final result of the chain of property accesses is deepFrozen. This must
be done by 'checkConstant' rather than separately by the rewritten code,
because only checkConstant has access to the 'value' fields obtained from
the data property descriptors. (Calling 'checkDeepFrozen(foo.bar.baz)'
would be incorrect since that might invoke getters.)
So, the first sentence of the comment should say "a constant result value
that is deepFrozen." A small change is also needed to the implementation:
function checkConstantAndDeepFrozen(obj /*, ...*/) {
> var i = 1;
> test: while (true) {
- if (i >= arguments.length) return;
+ if (i >= arguments.length) {
+ checkDeepFrozen(obj);
+ return;
+ }
(The other two early returns are correct since they only occur when the
current value of 'obj' is already known to be deepFrozen.)
Note that the special case checkConstantAndDeepFrozen(obj) is the same as
checkDeepFrozen(obj), so some refactoring might be in order.
--
David-Sarah Hopwood ⚥ http://davidsarah.livejournal.com
signature.asc
Description: OpenPGP digital signature
