Skip to content

Add tests for ToPropertyKey called once in **= and logical assignment - #5149

Open
chicoxyzzy wants to merge 1 commit into
tc39:mainfrom
chicoxyzzy:topropertykey-once-assignment
Open

chicoxyzzy wants to merge 1 commit into
tc39:mainfrom
chicoxyzzy:topropertykey-once-assignment

Conversation

@chicoxyzzy

Copy link
Copy Markdown
Member

base[prop] op= value evaluates base[prop] to a Reference Record, then calls GetValue and PutValue on it. GetValue converts the key with ToPropertyKey and stores the result back in the record (GetValue step 3.c.i). When PutValue reaches its own conversion (PutValue step 3.c), it finds a property key and skips it, so prop's toString runs once. Since tc39/ecma262#3307 moved the conversion out of reference creation, that write-back is what keeps it to one call.

The existing "ToPropertyKey is only called once" tests cover the update operators (postfix-increment/S11.3.1_A6_T3.js and its three siblings) and eleven compound operators (compound-assignment/S11.13.2_A7.1_T4.js to S11.13.2_A7.11_T4.js). Nothing covers **=, which postdates that series, or the logical assignment operators. This adds one test for each:

  • compound-assignment/exp-topropertykey-once.js
  • logical-assignment/lgcl-and-assignment-operator-topropertykey-once.js
  • logical-assignment/lgcl-or-assignment-operator-topropertykey-once.js
  • logical-assignment/lgcl-nullish-assignment-operator-topropertykey-once.js

Each logical-assignment test takes the branch that assigns. The short-circuit branch only calls GetValue, so it can't show a second conversion.

As of October 2026, engine262, JavaScriptCore, SpiderMonkey, QuickJS, Boa, XS and GraalJS pass. V8, Hermes, Kiesel, Escargot and LibJS call toString twice and fail. These are the same engines that fail the existing S11.13.2_A7.*_T4 and S11.3.1_A6_T3 tests.

GetValue stores the converted key in the Reference Record and PutValue
reuses it, so base[prop] op= value converts prop once. The
S11.13.2_A7.*_T4 tests check this for eleven compound operators. These
tests cover **= and the &&=, ||= and ??= operators when they assign.
@chicoxyzzy
chicoxyzzy requested a review from a team as a code owner October 16, 2026 15:44
@github-actions

Copy link
Copy Markdown

4 new or modified tests were run on 7 engines.

View workflow run

Test Engine262 GraalJS JavaScriptCore QuickJS SpiderMonkey V8 XS
language/expressions/compound-assignment/exp-topropertykey-once.js ✅ ✅ ✅ ✅ ✅ ❌ ✅
language/expressions/logical-assignment/lgcl-and-assignment-operator-topropertykey-once.js ✅ ✅ ✅ ✅ ✅ ❌ ✅
language/expressions/logical-assignment/lgcl-nullish-assignment-operator-topropertykey-once.js ✅ ✅ ✅ ✅ ✅ ❌ ✅
language/expressions/logical-assignment/lgcl-or-assignment-operator-topropertykey-once.js ✅ ✅ ✅ ✅ ✅ ❌ ✅

@gibson042 gibson042 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice catch, @chicoxyzzy! The test/language/expressions/logical-assignment/lgcl-*-assignment-operator-topropertykey-once.js files look great, but I'd like less divergence in test/language/expressions/compound-assignment (although if you're willing to pull forward the relevant old-style tests in that directory, I'm for it).

@gibson042 gibson042 Nov 1, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm generally in favor of descriptive names, but I think internal consistency wins out here. Please refactor this file for alignment with S11.13.2_A7.*_T4.js and rename it to S11.13.2_A7.12_T4.js. Then, if you like, a separate commit can rename them all and/or update their contents to this approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants