src: update v8::Object::GetPropertyNames() usage#23660
Conversation
|
Ref: #23426 (comment) |
src/node_contextify.cc
Outdated
There was a problem hiding this comment.
V8 recommend using the MaybeLocal returning version.
(IMHO it's also cleaner then the out-param version)
There was a problem hiding this comment.
This is the MaybeLocal version.
There was a problem hiding this comment.
So why not:
MaybeLocal<Array> maybe = ctx->sandbox()->GetPropertyNames(ctx->context())
if (maybe.IsEmpty())
return;
args.GetReturnValue().Set(maybe.ToLocalChecked());There was a problem hiding this comment.
IMO, this way is easier to read and reason about (don't really have to think about Maybes).
There was a problem hiding this comment.
IMHO having an uninitialized variable is code smell, and if there's a way to avoid it, why not.
Also if (!ctx->sandbox()->GetPropertyNames(ctx->context()).ToLocal(&properties)) is a bit busy it does like 5 things...
But I leave it to the author.
There was a problem hiding this comment.
There was a problem hiding this comment.
That's IMHO an extreme example of this pattern. What's wrong with:
Maybe<Object> module = args[0]->ToObject(context);
Maybe<Object> exports = module->Get(context, env->exports_string());
Maybe<Value> exports_v = exports_v->ToObject(context);
if (module.isEmpty() || exports.isEmpty() || exports_v.isEmpty()) {
return; // Exception pending.
}The original code also has short-circuit logic, so it is tricky to reason about.
P.S. see the // Exception pending comment, can we tell what when wrong?
We have actually have several guidelines that say to avoid this:
Google's:
- Local Variables - Place a function's variables in the narrowest scope possible, and initialize variables in the declaration.
- Output Parameters -
Prefer using return values rather than output parameters. If output-only parameters are used they should appear after input parameters.
C++CG:
There was a problem hiding this comment.
What's wrong with:
It doesn’t compile … MaybeLocals sadly don’t form a full monad; you can’t actually call ->Get() or ->ToObject() on one. The idea, as I understand V8, is to force API users to return to JS as soon as possible, and not attempt to do more operations.
P.S. see the
// Exception pendingcomment, can we tell what when wrong?
No, but ideally we don’t have to care about that anyway.
It’s also a bit odd to quote Google’s style guide here… I totally see what you mean and why this pattern can be counterintuitive, but after all, this pattern is of Google’s making and V8 uses it very extensively in its own code. 😄
ES.20: Always initialize an object
I’d say that rule explicitly lists this pattern as an exception:
If you are declaring an object that is just about to be initialized from input, initializing it would cause a double initialization.
There was a problem hiding this comment.
It doesn’t compile …
MaybeLocals sadly don’t form a full monad;
I tried to read this to figure out if the values are dependant. I looked several times, but missed it. That's a red light for me.
Anyway like you say, we write code so it reads well, not writes easy. The following is linear and reads much better, with only one action per line.
Maybe<Object> module = args[0]->ToObject(context);
if (module.isEmpty()) {
return env->isolate()->ThrowException("module is empty");
}
Maybe<Object> exports = module->ToCheckedLocal()->Get(context, env->exports_string());
if (exports.isEmpty()) {
return env->isolate()->ThrowException("exports is empty");
}
Maybe<Value> exports_v = exports_v->ToCheckedLocal()->ToObject(context);
if (exports_v.isEmpty()) {
return env->isolate()->ThrowException("exports_v is empty");
}
There was a problem hiding this comment.
The ThrowException() bit is not quite how MaybeLocals work – an empty one typically means that there is already an exception pending – but that’s a fair point, yes.
To be clear, I don’t personally like the repetition there, but I wouldn’t object to anybody using individual checks for each call.
src/node_contextify.cc
Outdated
There was a problem hiding this comment.
This is the MaybeLocal version.
Use the non-deprecated version of GetPropertyNames(). PR-URL: nodejs#23660 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Use the non-deprecated version of GetPropertyNames(). PR-URL: #23660 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Use the non-deprecated version of GetPropertyNames(). PR-URL: #23660 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Use the non-deprecated version of GetPropertyNames(). PR-URL: #23660 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Use the non-deprecated version of GetPropertyNames(). PR-URL: #23660 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Use the non-deprecated version of GetPropertyNames(). PR-URL: #23660 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Use the non-deprecated version of
GetPropertyNames().Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesEDIT: CI: https://ci.nodejs.org/job/node-test-pull-request/17938/