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

Missing tests for bindings that shadow globalThis properties #4332

Open
gibson042 opened this issue Nov 23, 2024 · 0 comments
Open

Missing tests for bindings that shadow globalThis properties #4332

gibson042 opened this issue Nov 23, 2024 · 0 comments

Comments

@gibson042
Copy link
Contributor

gibson042 commented Nov 23, 2024

eval, globalThis, NaN, Infinity, undefined, etc. are valid names for bindings (i.e., they are not keywords) and exist as such on the global object (the last three as non-configurable and non-writable). However, several implementations seem to treat them specially in ways that violate the specification (as seen below for Hermes and Moddable XS and QuickJS). Test262 should have coverage for such cases, although I'm never quite sure where in the hierarchy to put this kind of broad syntax verification... maybe generated tests in test/language/reserved-words?

print('START'); const %s = 1;

This should succeed with all names except NaN/Infinity/undefined, for which there should be a SyntaxError before anything happens because ScriptEvaluation starts with GlobalDeclarationInstantiation, which tests each lexically declared name against Global Environment Record HasRestrictedGlobalProperty and enforces that «A global lexical binding may not be created that has the same name as a non-configurable property of the global object… The global property "undefined" is an example of such a property».

But Hermes fails to throw the required SyntaxError (although it does not create observable changes).

## Source
print('START');
const NaN = 1;
const Infinity = 1;
const undefined = 1;
print([NaN, Infinity, undefined].some(v => v === 1) ? 'FAIL WITH EFFECTS' : 'FAIL WITHOUT EFFECTS');

#### Hermes
START
FAIL WITHOUT EFFECTS

{ const %s = 1; print(%s === 1 ? 'PASS' : 'FAIL'); }

Within a block, there should be no restrictions on these names.

But Hermes fails to create the NaN/Infinity/undefined bindings (i.e., it does not shadow the global property), as does Moddable XS (but only when the name is undefined), and QuickJS throws a SyntaxError before evaluating anything when the name is undefined.

$ for name in eval globalThis NaN Infinity undefined; do
  eshost -six "print('START'); { const $name = 1; print($name === 1 ? 'PASS' : 'FAIL'); }"
  done
## Source
print('START'); { const eval = 1; print(eval === 1 ? 'PASS' : 'FAIL'); }

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
START
PASS

## Source
print('START'); { const globalThis = 1; print(globalThis === 1 ? 'PASS' : 'FAIL'); }

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
START
PASS

## Source
print('START'); { const NaN = 1; print(NaN === 1 ? 'PASS' : 'FAIL'); }

#### engine262, GraalJS, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
START
PASS

#### Hermes
START
FAIL

## Source
print('START'); { const Infinity = 1; print(Infinity === 1 ? 'PASS' : 'FAIL'); }

#### engine262, GraalJS, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
START
PASS

#### Hermes
START
FAIL

## Source
print('START'); { const undefined = 1; print(undefined === 1 ? 'PASS' : 'FAIL'); }

#### engine262, GraalJS, JavaScriptCore, SpiderMonkey, V8
START
PASS

#### Hermes, Moddable XS
START
FAIL

#### QuickJS

SyntaxError: invalid lexical variable name

(function(%s) { print(%s === 1 ? 'PASS' : 'FAIL'); })(1);

Use as a simple function parameter name should be allowed.

But Moddable XS does not bind the argument value to a parameter named undefined.

$ for name in eval globalThis NaN Infinity undefined; do
  eshost -six "(function($name) { print($name === 1 ? 'PASS' : 'FAIL'); })(1);"
  done
## Source
(function(eval) { print(eval === 1 ? 'PASS' : 'FAIL'); })(1);

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function(globalThis) { print(globalThis === 1 ? 'PASS' : 'FAIL'); })(1);

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function(NaN) { print(NaN === 1 ? 'PASS' : 'FAIL'); })(1);

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function(Infinity) { print(Infinity === 1 ? 'PASS' : 'FAIL'); })(1);

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function(undefined) { print(undefined === 1 ? 'PASS' : 'FAIL'); })(1);

#### engine262, GraalJS, Hermes, JavaScriptCore, QuickJS, SpiderMonkey, V8
PASS

#### Moddable XS
FAIL

(function({ %s }) { print(%s === 1 ? 'PASS' : 'FAIL'); })({ %s: 1 });

Use as a destructured function parameter name should be allowed.

But Moddable XS does not bind the argument value to a parameter named undefined.

$ for name in eval globalThis NaN Infinity undefined; do
  eshost -six "(function({ $name }) { print($name === 1 ? 'PASS' : 'FAIL'); })({ $name: 1 });"
  done
## Source
(function({ eval }) { print(eval === 1 ? 'PASS' : 'FAIL'); })({ eval: 1 });

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function({ globalThis }) { print(globalThis === 1 ? 'PASS' : 'FAIL'); })({ globalThis: 1 });

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function({ NaN }) { print(NaN === 1 ? 'PASS' : 'FAIL'); })({ NaN: 1 });

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function({ Infinity }) { print(Infinity === 1 ? 'PASS' : 'FAIL'); })({ Infinity: 1 });

#### engine262, GraalJS, Hermes, JavaScriptCore, Moddable XS, QuickJS, SpiderMonkey, V8
PASS

## Source
(function({ undefined }) { print(undefined === 1 ? 'PASS' : 'FAIL'); })({ undefined: 1 });

#### engine262, GraalJS, Hermes, JavaScriptCore, QuickJS, SpiderMonkey, V8
PASS

#### Moddable XS
FAIL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants