-
Notifications
You must be signed in to change notification settings - Fork 30k
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
src: use new V8 API in vm module #16293
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
largely rubber stamp lgtm
src/node_contextify.cc
Outdated
ctx->global_proxy()->GetRealNamedPropertyAttributes(context, | ||
property); | ||
} | ||
Local<String> key = property->ToString(isolate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use the overload that takes a Local<Context>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/node_contextify.cc
Outdated
Local<Value> descriptor_intercepted = has.IsNothing() ? | ||
ctx->global_proxy()->GetOwnPropertyDescriptor(context, key) | ||
.ToLocalChecked() : | ||
sandbox->GetOwnPropertyDescriptor(context, key).ToLocalChecked(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd write this as an if statement. It's rather hard to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Done.
src/node_contextify.cc
Outdated
// If the property had already been defined on the sandbox or global object, | ||
// we intercept, query and return it. | ||
// Else, there is no need to intercept with first time definitions. | ||
if (!descriptor_intercepted->IsUndefined()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the conditional isn't needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? If we intercept, it signals that the property was found. I think that's not correct if the property is not present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Undefined is the default return value of API callbacks. I.e., the return value is going to be the same, with or without the IsUndefined()
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReturnValue
on the CallbackArgs
is set to undefined
, but the call to the interceptor returns true
or false
depending on whether the return value was set. This then changes the control flow, see objects.cc.
But taking a closer look, I think the logic can be substantially simplified: take the value from the sandbox if present, otherwise proceed regularly. What do you think?
src/node_contextify.cc
Outdated
} else { | ||
Local<Value> value = | ||
desc.has_value() ? desc.value() : | ||
v8::Undefined(isolate).As<Value>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fits on one line (well, two, if you count the LHS.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/node_contextify.cc
Outdated
} | ||
} | ||
|
||
printf("foo\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stray debug code, I presume?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops
src/node_contextify.cc
Outdated
@@ -65,6 +66,12 @@ using v8::WeakCallbackInfo; | |||
|
|||
namespace { | |||
|
|||
v8::Local<v8::Name> UIntToName(v8::Isolate* isolate, uint32_t index) { | |||
const char* x = std::to_string(index).c_str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this function gets called a lot (which it looks like it is), it's arguably better to use snprintf()
instead to avoid the extra allocation, or even to do manual stringification. C++17 adds std::to_chars()
but we can't use that yet, unfortunately.
It might even be worthwhile to implement this as Uint32::New(...)->ToString(...)
because that would reuse V8's number-to-string cache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if there's any larger array, this is called for every index. Using Uint32::New()->ToString()
.
src/node_contextify.cc
Outdated
bool is_function = value->IsFunction(); | ||
|
||
if (!is_declared && args.ShouldThrowOnError() && is_contextual_store && | ||
!is_function) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You fixed the style for this further up but not here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/node_contextify.cc
Outdated
} | ||
} | ||
|
||
printf("foo\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug code again.
There's a lot of duplication. Couldn't you implement them by calling UIntToName(isolate, index)
and passing the result to GlobalPropertyDefinerCallback()
, etc.?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's all duplication. Let me think about how to get rid of the code duplication while maintaining readability.
assert.strictEqual(ctx.x, undefined); // Not copied out by cloneProperty(). | ||
|
||
// This is fixed now! | ||
// assert.strictEqual(ctx.x, undefined); // Not copied out by cloneProperty(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you drop the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can drop the copyright boilerplate, we don't use it in new files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@cpojer, since this is fixing bugs/altering behavior, do you want to check if that causes problems for Jest? |
I'll run this through the jsdom test suite as well. |
5eb8aaf
to
324c912
Compare
Nits addressed, refactoring the code duplication part. Will squash afterwards. |
367473e
to
fecefd0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment about the default return value but otherwise LGTM. Nice work, Franziska and @AnnaMag.
// Still initializing | ||
if (ctx->context_.IsEmpty()) | ||
return; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some extraneous blank lines here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -7,7 +7,7 @@ const vm = require('vm'); | |||
|
|||
const ctx = vm.createContext(); | |||
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx); | |||
assert.strictEqual(ctx.x, undefined); // Not copied out by cloneProperty(). | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the blank line here?
743de90
to
03358aa
Compare
@fhinkel mind running this against Jest's version on master? |
@cpojer Jest's tests helped me find a fatal error on my side 😄
|
Can you just try |
@cpojer I'm not getting very far with Node master, opend an issue here jestjs/jest#4731. |
As mentioned in the Jest issue, using node 9 RC fails https://github.com/rvagg/node-worker-farm $ npm version
{ 'worker-farm': '1.5.0',
npm: '5.3.0',
ares: '1.13.0',
cldr: '31.0.1',
http_parser: '2.7.0',
icu: '59.1',
modules: '58',
nghttp2: '1.25.0',
node: '9.0.0-rc.0',
openssl: '1.0.2l',
tz: '2017b',
unicode: '9.0',
uv: '1.15.0',
v8: '6.1.534.42',
zlib: '1.2.11' }
|
git bisect blames f2b01cb Bisect script if anyone wants to double-check #!/bin/sh
./configure
make -j4 || exit 125 # an exit code of 125 asks "git bisect" to "skip" the current commit
# run the application and check that it produces good output
./node ../node-worker-farm/tests 2>&1 | grep 'ERR_IPC_CHANNEL_CLOSED'
if [ $? -eq 0 ]; then
exit 1
fi
exit 0 I can confirm that reverting f2b01cb makes both worker-farm's and jest's test suites pass |
@SimenB Do you mind putting your code snippets in details, as they are not related to this issue? Thanks! |
96fcee8
to
6539413
Compare
Remove the CopyProperties() hack in the vm module, i.e., Contextify. Use different V8 API methods, that allow interception of DefineProperty() and do not flatten accessor descriptors to property descriptors. Move many known issues to test cases. Factor out the last test in test-vm-context.js for nodejs#10223 into its own file, test-vm-strict-assign.js. Part of this CL is taken from a stalled PR by https://github.com/AnnaMag nodejs#13265 This PR requires a backport of https://chromium.googlesource.com/v8/v8/+/37a3a15c3e52e2146e45f41c427f24414e4d7f6f Refs: nodejs#6283 Refs: nodejs#15114 Refs: nodejs#13265 Fixes: nodejs#2734 Fixes: nodejs#10223 Fixes: nodejs#11803 Fixes: nodejs#11902
6539413
to
f7d22e5
Compare
Landed in f1d6b04 |
Remove the CopyProperties() hack in the vm module, i.e., Contextify. Use different V8 API methods, that allow interception of DefineProperty() and do not flatten accessor descriptors to property descriptors. Move many known issues to test cases. Factor out the last test in test-vm-context.js for nodejs#10223 into its own file, test-vm-strict-assign.js. Part of this CL is taken from a stalled PR by https://github.com/AnnaMag nodejs#13265 This PR requires a backport of https://chromium.googlesource.com/v8/v8/+/37a3a15c3e52e2146e45f41c427f24414e4d7f6f PR-URL: nodejs#16293 Fixes: nodejs#2734 Fixes: nodejs#10223 Fixes: nodejs#11803 Fixes: nodejs#11902 Ref: nodejs#6283 Ref: nodejs#15114 Ref: nodejs#13265 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
Nice. Thank you and @AnnaMag for doing this! |
The known issue is fixed with nodejs#16293. The text needs to call `Object.hasOwnProperty(this)` instead of `this.hasOwnProperty()`, otherwise `this` is from the wrong context is used. Add a second test case taken verbatim from issue nodejs#5350 Fixes: nodejs#5350 Refs: nodejs#16293
The known issue is fixed with nodejs#16293. The text needs to call `Object.hasOwnProperty(this)` instead of `this.hasOwnProperty()`, otherwise `this` is from the wrong context is used. Add a second test case taken verbatim from issue nodejs#5350 PR-URL: nodejs#16411 Fixes: nodejs#5350 Ref: nodejs#16293 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Remove the CopyProperties() hack in the vm module, i.e., Contextify. Use different V8 API methods, that allow interception of DefineProperty() and do not flatten accessor descriptors to property descriptors. Move many known issues to test cases. Factor out the last test in test-vm-context.js for nodejs/node#10223 into its own file, test-vm-strict-assign.js. Part of this CL is taken from a stalled PR by https://github.com/AnnaMag nodejs/node#13265 This PR requires a backport of https://chromium.googlesource.com/v8/v8/+/37a3a15c3e52e2146e45f41c427f24414e4d7f6f PR-URL: nodejs/node#16293 Fixes: nodejs/node#2734 Fixes: nodejs/node#10223 Fixes: nodejs/node#11803 Fixes: nodejs/node#11902 Ref: nodejs/node#6283 Ref: nodejs/node#15114 Ref: nodejs/node#13265 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
The known issue is fixed with nodejs/node#16293. The text needs to call `Object.hasOwnProperty(this)` instead of `this.hasOwnProperty()`, otherwise `this` is from the wrong context is used. Add a second test case taken verbatim from issue nodejs/node#5350 PR-URL: nodejs/node#16411 Fixes: nodejs/node#5350 Ref: nodejs/node#16293 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
PR-URL: nodejs/node#16409 Refs: nodejs/node#16293 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
The known issue is fixed with #16293. The text needs to call `Object.hasOwnProperty(this)` instead of `this.hasOwnProperty()`, otherwise `this` is from the wrong context is used. Add a second test case taken verbatim from issue #5350 PR-URL: #16411 Fixes: #5350 Ref: #16293 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Remove the CopyProperties() hack in the vm module, i.e., Contextify. Use different V8 API methods, that allow interception of DefineProperty() and do not flatten accessor descriptors to property descriptors. Move many known issues to test cases. Factor out the last test in test-vm-context.js for nodejs/node#10223 into its own file, test-vm-strict-assign.js. Part of this CL is taken from a stalled PR by https://github.com/AnnaMag nodejs/node#13265 This PR requires a backport of https://chromium.googlesource.com/v8/v8/+/37a3a15c3e52e2146e45f41c427f24414e4d7f6f PR-URL: nodejs/node#16293 Fixes: nodejs/node#2734 Fixes: nodejs/node#10223 Fixes: nodejs/node#11803 Fixes: nodejs/node#11902 Ref: nodejs/node#6283 Ref: nodejs/node#15114 Ref: nodejs/node#13265 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
The known issue is fixed with nodejs/node#16293. The text needs to call `Object.hasOwnProperty(this)` instead of `this.hasOwnProperty()`, otherwise `this` is from the wrong context is used. Add a second test case taken verbatim from issue nodejs/node#5350 PR-URL: nodejs/node#16411 Fixes: nodejs/node#5350 Ref: nodejs/node#16293 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
PR-URL: nodejs/node#16409 Refs: nodejs/node#16293 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This PR removes the CopyProperties() hack in the vm module, i.e., Contextify.
Instead, it uses different V8 API methods, that allow interception of
DefineProperty() and do not flatten accessor descriptors to
property descriptors.
Move many known issues to test cases. Factor out the last test in
test-vm-context.js for
#10223
into its own file, test-vm-strict-assign.js.
Part of this CL is taken from a stalled PR by
https://github.com/AnnaMag
#13265
Refs: #6283
Refs: #15114
Refs: #13265
Fixes: #2734
Fixes: #10223
Fixes: #11803
Fixes: #11902
This PR requires a backport of37a3a15 otherwise some tests will fail. Cherry pick PR.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
src
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
src