util: fix inspection of module namespaces#20962
util: fix inspection of module namespaces#20962devsnek wants to merge 1 commit intonodejs:masterfrom
Conversation
b3450e9 to
e16a700
Compare
BridgeAR
left a comment
There was a problem hiding this comment.
Why did this break in 6.7? And this will likely have a minor influence on the performance.
lib/util.js
Outdated
There was a problem hiding this comment.
This should fit on a single line as before.
lib/util.js
Outdated
There was a problem hiding this comment.
Are there other possibilities for this to throw a ReferenceError?
lib/util.js
Outdated
There was a problem hiding this comment.
Why does this not throw compared to Object.keys? Because of https://www.ecma-international.org/ecma-262/6.0/#sec-enumerableownnames 5.a.i.?
There was a problem hiding this comment.
[[GetOwnProperty]] -> [[Get]] -> [[GetBindingValue]] which throws
lib/util.js
Outdated
There was a problem hiding this comment.
Please use upper cases for the first letter of a sentence.
|
@BridgeAR v8 fixed a bug where they weren't throwing a reference error and they should have been |
For reference: https://bugs.chromium.org/p/v8/issues/detail?id=7780 |
Yep, tests are passing on |
|
I suggest to take a completely different approach: I saw that there is already a custom inspect function for modules. So when calling that function it should just wrap the Btw: normally only the object should be returned instead of calling util.inspect in a custom inspect function. That reduces the overhead. In this specific case it is useful in case that call is wrapped as suggested. |
|
@BridgeAR edit: i misunderstood; module namespace objects can't have custom inspect functions |
|
Let's see how the benchmarks come out. I am not a fan of adding a lot of special handling for the namespace edge case. |
lib/util.js
Outdated
There was a problem hiding this comment.
Instead of relying on the reference error here, we might just test for types.isModuleNamespaceObject nevertheless.
|
\cc @ljharb On v8/issues/detail?id=7780 are you planning to file a spec bug? Update: I opened issue tc39/ecma262#1209. |
lib/util.js
Outdated
There was a problem hiding this comment.
☝️ the Object.getOwnPropertyNames(value) fallback should filter non-enumerable to be equiv to keys
Update:
Not required since this is now restricted to namespace objects.
There was a problem hiding this comment.
I suppose you can't have non-enumerable keys on a module namespace?
There was a problem hiding this comment.
i believe the only keys on a module namespace will ever (atm) be enumerable strings for the exports, and Symbol.toStringTag.
|
If this is going to land on older branches, we should be sure to run benchmarks for those branches first. If there are performance regressions, we should try to see about minimizing the impact (for example the try-catch will probably have a noticeable impact in node v6.x). |
|
@mscdex luckily i don't think module namespace objects exist on 6.x |
lib/util.js
Outdated
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
7d66a91 to
f056724
Compare
lib/util.js
Outdated
There was a problem hiding this comment.
\cc @bmeurer A pattern in much of Node's code is to extract try-catches into their own functions. In this case it would be named tryKeys(). Is this practice still beneficial in the V8 of today?
There was a problem hiding this comment.
iirc it hasn't been needed since like v6
There was a problem hiding this comment.
That is not necessary anymore. It used to prevent a function from optimizing and this is not the case anymore with turbofan.
|
Is there any strong -1 here or can we land this? |
|
@mmarchini ci still appears to have issues so I'm not running it yet. |
|
@devsnek regarding our infrastructure I think the issues are fixed. There are only flaky tests we need to fix now. |
lib/util.js
Outdated
There was a problem hiding this comment.
Object.keysandObject.getOwnPropertyNamesreferences should be cherry-picked above.- The
instanceof ReferenceErrorcheck will fail from errors of a different realm (context).
There was a problem hiding this comment.
for the first point, we purposely leave those as-is because some polyfills for things use them to mess with util.
for the second point, i guess types.isNativeError(err) && err.name === 'ReferenceError' would work?
There was a problem hiding this comment.
for the first point, we purposely leave those as-is because some polyfills for things use them to mess with util.
Ah cool! Do you have any examples at hand?
for the second point, i guess types.isNativeError(err) && err.name === 'ReferenceError' would work?
Yep.
There was a problem hiding this comment.
I don't know what package does it, but it was brought up during discussions about hardening core against tampering with builtin prototypes.
f056724 to
a9a0643
Compare
| } catch (err) { | ||
| if (!(err instanceof ReferenceError)) { | ||
| if (!(types.isNativeError(err) && err.name === 'ReferenceError')) { | ||
| throw err; |
There was a problem hiding this comment.
Could the error checks be simplified all up? If namespace objects can only error by throwing a reference error then we can assume that the error accessing it is because of the reference error and remove the error checks and rethrow code above. We could also simplify the initial check by doing:
try {
keys = Object.keys(value);
} catch (err) {
if (types.isModuleNamespaceObject(value)) {
keys = Object.getOwnPropertyNames(value);
} else {
throw err;
}
}Here erroring should be rare and when it does error it is likely a namespace object so the check up-front on error should be fine.
There was a problem hiding this comment.
i think its best to explicitly check if its a reference error, do you feel strongly about this?
There was a problem hiding this comment.
I dig it if code could be simpler, and still correct, that it be simpler is all.
|
This is blocking V8 6.7 landing @jdalton is it ok for this to land as is and be simplified in a follow up? |
|
Yep, yep. |
|
FreeBSD failure is a flaky and I have no idea why it's saying OSX failed. Running another one: https://ci.nodejs.org/job/node-test-pull-request/15169/ |
|
OSX should work now (thanks @refack!). 5th time's a charm! https://ci.nodejs.org/job/node-test-pull-request/15170/ |
|
CI is yellow. Landing! |
|
Landed in a25730b |
PR-URL: #20962 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Matheus Marchini <matheus@sthima.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: #20962 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Matheus Marchini <matheus@sthima.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
unbreaks 6.7 upgrade
/cc @targos i don't have 6.7 checked out or the room to do so, can you confirm this patch fixes it?
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes