Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow null or undefined in Reference Records #3

Open
wants to merge 194 commits into
base: master
Choose a base branch
from

Conversation

codehag
Copy link
Owner

@codehag codehag commented Jan 5, 2021

For review by @jorendorff.

I checked all locations where .[[Base]] is used. There don't appear to be locations as far as I can tell, where this change will be an issue, see https://searchfox.org/ecma262/search?q=.%5B%5BBase%5D%5D&path=

In this cases, null and undefined is handled implicitly: IsUnresolvableReference and this change wouldn't result in a change in behavior.

The same is true of IsPropertyReference, but I think we want to change it, because otherwise we would fall back on thinking this is an environment record. See the code around these instances. But, if we change to return true for null or undefined, we will be caught by ToObject as in these cases.

I am not as sure about ToObject -- this will change at which point we throw (which is, I guess, the point).

In all of these cases, we follow with an assertion that the value is an environment record

I may have missed something that needs to be changed though, let me know if that is the case.

@codehag codehag force-pushed the null-or-undefined-reference-records branch from 5e380bc to 81e5130 Compare January 5, 2021 12:41
Copy link

@jorendorff jorendorff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I can't tell if MakeSuperPropertyReference needs the same treatment. Maybe someone more familiar with the super bits of the spec can say.

  • I gather the intent is that property expressions produce property References and identifiers produce environment References—it's a static invariant.

    I think the language of the check in IsPropertyReference should be changed to:

    1. If V.[[Base]] is an Environment Record, return false; otherwise return true.
  • In GetValue, the call to "! ToObject" must be changed to "? ToObject" since it can now fail.

  • Same thing in PutValue.

  • Same thing in Evaluation for delete expressions, step 5.b.

spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
@codehag codehag force-pushed the null-or-undefined-reference-records branch from 81e5130 to 40a9b36 Compare January 5, 2021 15:09
@jorendorff
Copy link

OK, I think MakeSuperPropertyReference needs the same change, for consistency.

But there is something I'm confused about.

There are actually two cases where the RequireObjectCoercible check in MakeSuperPropertyReference could fail:

  • One is if env.GetSuperBase() returns null in step 3. I think this is what happens in this example:

    class C {
      set v(x) {
        super.v = console.log("GOT HERE");
      }
    }
    new C().v = 37;
    
  • The other is if env.GetSuperBase() returns undefined. I don't know how this is possible.

@codehag codehag force-pushed the null-or-undefined-reference-records branch from 40a9b36 to 7f38832 Compare January 5, 2021 15:16
@codehag
Copy link
Owner Author

codehag commented Jan 5, 2021

The other is if env.GetSuperBase() returns undefined. I don't know how this is possible.

I don't know if it is? In the code above env.GetSuperBase() we assert that it is not undefined, so I am not sure how we can get to that. Maybe this is some older text that made more sense before? I will see if I can get more eyes on it. I made the change in any case.

@caiolima
Copy link

I spent some time investigating the impact of such change and couldn't find anything strange on super.prop cases, nor delete or typeof operators.

The other is if env.GetSuperBase() returns undefined. I don't know how this is possible.

I don't know if it is? In the code above env.GetSuperBase() we assert that it is not undefined, so I am not sure how we can get to that. Maybe this is some older text that made more sense before? I will see if I can get more eyes on it. I made the change in any case.

Looking into MakeSuperPropertyReference we can have a clue that if we ever get env.GetSuperBase() to return undefined, it's a bug, since env.HasSuperBinding() would return false when we get [[HomeObject]] to be undefined. I'm also not able to think in a way where we could have super.prop, where super evaluates to undefined.

As a matter of clarification, I managed to make super evaluate to null with this code:

class C {
    static access() {
        super.foo = print('blah');
    }
}

Object.setPrototypeOf(C, null);
C.access();

Regarding typeof operation, since it relies on GetValue(V) and the PR includes changes to it, we should not have troubles there.
Overall, I think such change makes sense and LGTM.

h2oche and others added 7 commits July 12, 2021 22:13
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
As discussed during the March 2021 plenary, this note on "is designed to
be subclassable" can be read as an encouragement or value judgement on
whether it is desirable to subclass built-in classes like Boolean. We
don't want to actively encourage this.
…2367)

... into the if-else cascade in CreateDynamicFunction, suggested in tc39#2348 (comment)
@bakkot bakkot force-pushed the null-or-undefined-reference-records branch from 7f38832 to d4cfaf1 Compare July 18, 2021 20:09
jmdyck and others added 16 commits July 19, 2021 11:22
The note says that "the result of ToNumber will be *NaN*
if the string contains any [surrogate] code units,
whether paired or unpaired."

However, if Unicode were to define a non-BMP code point
with General_Category=Zs, that would qualify as <USP>
and thus WhiteSpace and StrWhiteSpaceChar, in which case
the note would be rendered false. That is, the ToNumber
procedure would continue to work, and would result in
non-NaN values for some strings containing surrogates.

(And if you think that the ES spec doesn't need to concern itself
with such future possibilities, note that ES 6 (2015) changed/clarified
the semantics of String.p.trim et al for precisely this case,
to say how they would deal with non-BMP white space.)

Given that the note could be invalidated by a future
edition of Unicode, I think it's a bit risky to keep it in.
Introduce the abstract operation StringToNumber
to replace the prose that expressed the procedure
for applying ToNumber to String values.
…completions (tc39#2442)

This PR also makes the prose around requirements for host hook
implementations consistent to the template "An implementation of
HostHook must conform to the following requirements:".
 - co-opts prose from Annex B description
 - dfn legacy and add emu-not-ref where appropriate
 - use dash in IDs
 - don't <dfn> legacy; clauses are what is legacy

Co-authored-by: Jordan Harband <ljharb@gmail.com>
Co-authored-by: Michael Ficarra <mficarra@shapesecurity.com>
Co-authored-by: Gus Caplan <me@gus.host>
Co-authored-by: Jordan Harband <ljharb@gmail.com>
Co-authored-by: Michael Dyck <jmdyck@ibiblio.org>
... one for TV and one for TRV.

(This duplicates 4 cases, but they're very simple.)
@codehag codehag force-pushed the null-or-undefined-reference-records branch from 24de565 to e01feba Compare August 10, 2021 10:24
jmdyck and others added 4 commits August 12, 2021 14:18
... and replace the former with the latter in TemplateCharacter.

The spec prohibits applying the B.1.2 extensions
to EscapeSequence when it appears in TemplateCharacter;
this change accomplishes that in the grammar rather than in prose.

(This makes it a little easier to 'mainline' the B.1.2 extensions
in the next commit.)
(Part of Annex B reform, see PR tc39#1595.)

B.1.2 makes 2 changes to the EscapeSequence production:
(1) It adds the rhs `NonOctalDecimalEscapeSequence`.
(2) It replaces the rhs:
        `0` [lookahead &lt;! DecimalDigit]
    with:
        LegacyOctalEscapeSequence
    where the latter nonterminal generates `0` among lots of other things.

Change 1 is straightforward, but change 2 is tricky.
In the EscapeSequence production, we can't simply replace
the `0` alternative with LegacyOctalEscapeSequence (as B.1.2 does),
because the `0` alternative must be treated differently
from everything else that LegacyOctalEscapeSequence derives.
(The `0` alternative is allowed in contexts where
everything else that LegacyOctalEscapeSequence derives is forbidden.)
So instead, we redefine LegacyOctalEscapeSequence to exclude the `0` alternative.
Specifically, the 'overlap' comes from:

    LegacyOctalEscapeSequence ::
        OctalDigit [lookahead &notin; OctalDigit]

so we replace that with:

    LegacyOctalEscapeSequence ::
        `0` [lookahead &isin; {`8`, `9`}]
        NonZeroOctalDigit [lookahead &notin; OctalDigit]

(See Issue tc39#1975 for more details.)
Resolves tc39#1975.
Co-authored-by: codehag <yulia.startsev@gmail.com>
Co-authored-by: Kevin Gibbons <bakkot@gmail.com>
@ljharb ljharb force-pushed the null-or-undefined-reference-records branch from e01feba to d09532c Compare August 15, 2021 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.