-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[wasm64] making JS bindings wasm64 aware #12869
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
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.
Nice!
src/runtime.js
Outdated
POINTER_SIZE: 4, | ||
QUANTUM_SIZE: 4, | ||
POINTER_SIZE: getPointerSize(), | ||
POINTER_TYPE: MEMORY64 ? 'i64' : 'i32', |
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.
get you just call getPointerType()
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.
You mean pointerType()
from parseTools.js
? Is that always available to this file? I am still unclear on how all these JS files fit together :)
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.
My understanding is that all of these files (modules.py, parseTools.js, runtime.js at least) all loaded together when processing JS so they all shared a single namespace.
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 tried, and I can't access variables from parseTools.js
here, though I might be getting it wrong :)
6e32d6b
to
f70b244
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.
I don't fully grok the makeGetValue / makeSetValue stuff bit everything else looks good!
If you feel like splitting of the |
Is this still a draft? |
No, I'd rather not split that off.. and yes, still a draft until I get further along I think? |
This reflects changes in the function signature in https://reviews.llvm.org/D101985 and also uses `from64` function defined in emscripten-core#12869. This has not been tested against wasm64 yet and I'm uploading this mainly for discussions at this point. Also in the team chat of the tools team we discussed other alternatives to `from64` function, which can be done separately and not reflected here.
There are a lot of places where pointers get cast to int, and to prepare for further Memory64 changes, those are changed to long. I chose long since it is most similar to the existing int, instead of e.g intptr_t, since long is more universal (there are many cases where the actual data stored is not a pointer). Since under wasm32 int and long are equal, this should in theory be a NFC for wasm32, making it easier to review. It also allows #12869 to be smaller
6f99f54
to
79c84d3
Compare
src/library.js
Outdated
// To support such allocations during startup, track them on __heap_base and | ||
// then when the main module is loaded it reads that value and uses it to | ||
// initialize sbrk (the main module is relocatable itself, and so it does not | ||
// have __heap_base hardcoded into it - it receives it from JS as an extern | ||
// global, basically). | ||
__heap_base: '{{{ HEAP_BASE }}}', | ||
__heap_base: '{{{ to64(HEAP_BASE) }}}', |
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 is this ok to remain as is and not use new WebAssembly.Global
but the above ones are not?
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 was already not using new WebAssembly.Global
before my change.. I have no idea why.
tools/shared.py
Outdated
@@ -230,7 +230,7 @@ def run_js_tool(filename, jsargs=[], *args, **kw): | |||
This is used by emcc to run parts of the build process that are written | |||
implemented in javascript. | |||
""" | |||
command = config.NODE_JS + [filename] + jsargs | |||
command = config.NODE_JS + ['--experimental-wasm-bigint'] + [filename] + jsargs |
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.
Is this needed for something?
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, the JS tools themselves may now contain code that uses bigints?
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.
Is that something you have added in this PR? It seems odd that that would be needed just to process the library js code.. can you point to an example?
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 have to run 64-bit test for that again to uncover that. Can we leave it in? If it's just for the tools it doesn't hurt. Or if you insist I can put it in a comment so it is easier to re-apply when we return to fixing 64-bit issues.
tools/gen_struct_info.py
Outdated
@@ -266,6 +266,7 @@ def inspect_headers(headers, cflags): | |||
'-Wno-format', | |||
'-nostdlib', | |||
compiler_rt, | |||
'-s', 'MEMORY64=' + str(settings.MEMORY64), |
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 don't think this will work. This gets run just once one first use so we don't want to depend on the settings use in that moment. If there are differences here then we would need a second set of json file and have them stored separately in the cache.
See generate_struct_info
in emscripten.py
.
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.
Ok, I guess I am not clear on how to fix this.. maybe we can discuss that offline. Or at least maybe I can just put a FIXME in there for when testing with wasm64
resumes.. so far this has worked in allowing tests to pass.
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.
The fix I think would be to have a different filename when running in 64bit mode. See:
Line 826 in bca56b3
generated_struct_info_name = 'generated_struct_info.json' |
It won't work as it stands because if you have previously built the struct_info.json with -sMEMORY64
and then try to build something without that flag .. it would use the wasm64 version of the json file.. and things be broken in horrible ways, right?
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.
Ok, so we need a generated_struct_info64.json
? I can look into how to set that up in a follow-up. I'll comment this out for now.
f82e4b5
to
5c9a07b
Compare
I mean you can put the quotes outside the `{{{ }}}` and just have
`POINTER_TYPE` inside.. avoiding the backticks (I think).
…On Mon, Oct 4, 2021 at 10:08 AM Wouter van Oortmerssen < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/runtime_safe_heap.js
<#12869 (comment)>
:
> @@ -14,7 +14,7 @@
@param {number|boolean=} noSafe */
function setValue(ptr, value, type, noSafe) {
type = type || 'i8';
- if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+ if (type.charAt(type.length-1) === '*') type = {{{ `'${POINTER_TYPE}'` }}};
That would generate i32 and it needs to generate 'i32'
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#12869 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAD55ZN7ZXBWUFMAF3OIOP3UFHNPXANCNFSM4UAGXGBQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
a58191f
to
babc881
Compare
system/lib/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
Outdated
Show resolved
Hide resolved
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.
How about splitting out the strftime and webidl binder changes (so that if we end up bisecting it doesn't reach here)? Otherwise, I think this can stay in one PR.
else: | ||
benchmarkers += [ | ||
# EmscriptenBenchmarker('Node.js', config.NODE_JS), | ||
] |
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.
Wasm64 does seem special enough to justify this, I think. And we do have a few other global params here like profiling etc.
# separately in the cache. | ||
# Whereever generated_struct_info.json is generated, there now | ||
# needs to be a generated_struct_info64.json for MEMORY64 mode. | ||
# '-s', 'MEMORY64=' + str(settings.MEMORY64), |
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 think we'd need a separate cache dir for memory64 (like for LTO), and to pass this tool a flag in that case, but I'm not sure.
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, we discussed this should be fixed in a follow-up, see #15218 (and also elsewhere in this PR)
(tm->__tm_gmtoff)/3600, | ||
abs(tm->__tm_gmtoff%3600)/60); | ||
labs(tm->__tm_gmtoff%3600)/60); // XXX EMSCRIPTEN: abs => labs |
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.
Maybe better to disable that warning rather than hack musl like this. See:
emscripten/tools/system_libs.py
Lines 682 to 688 in dfb2d09
# Disable certain warnings for code patterns that are contained in upstream musl | |
cflags += ['-Wno-ignored-attributes', | |
'-Wno-dangling-else', | |
'-Wno-unknown-pragmas', | |
'-Wno-shift-op-parentheses', | |
'-Wno-string-plus-int', | |
'-Wno-pointer-sign'] |
Also, it looks like this was removed upstream so this issue will go away once I get around to landing #13006: https://github.com/emscripten-core/musl/
@@ -359,6 +364,7 @@ def set_env(name, option_value): | |||
set_env('EMTEST_REBASELINE', options.rebaseline) | |||
set_env('EMTEST_VERBOSE', options.verbose) | |||
set_env('EMTEST_CORES', options.cores) | |||
set_env('EMTEST_FORCE64', options.force64) |
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 still needs to be resolved.. we shouldn't need the global
keyword above.
else: | ||
benchmarkers += [ | ||
# EmscriptenBenchmarker('Node.js', config.NODE_JS), | ||
] |
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.
@kripken WDYT about these changes to test_benchmark.py
fdd4d9e
to
383146a
Compare
@sbc100 benchmark changes look good to me. They aren't temporary changes, but a new mode for the runner. Makes sense to commit them I think. |
Two more:
|
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.
Ok, if you'd rather do the getPointerSize()
etc. stuff in a followup, that seems ok to me.
else: | ||
benchmarkers += [ | ||
# EmscriptenBenchmarker('Node.js', config.NODE_JS), | ||
] |
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.
+1 from me for these changes to benchmarking.
This regressed in #12869 - while adding wasm64 support we reordered how the args are added. The extra emcc args must be at the end so that they apply on top of the other ones, in particular, some tests must disable minimal runtime.
This regressed in emscripten-core#12869 - while adding wasm64 support we reordered how the args are added. The extra emcc args must be at the end so that they apply on top of the other ones, in particular, some tests must disable minimal runtime.
This is a large collection of fixes resulting from trying to run the tests under wasm64. It is not complete, i.e. does not pass all tests, and requires a specific local setup. It is unknown how much work is left to pass all of them, though this allows significant amount of code to work.
I am trying to land these changes, because, well, maintaining this large fork is getting onerous, and it would be beneficial for wasm64 related changes to be already present, even if not used.
This PR has the wasm64 tests OFF, meaning it is meant to be a NFC for wasm32, effectively.
Of course, this PR contains a lot of unrelated fixes that ideally could have been spread out over 10+ PRs, had I known what I was doing. I think it made sense to initially collect all these changes in one PR, since it was hard to tell what shape things would take, and in fact there have been large sweeping changes that I later undid, which we've now all been saved from.
The question remains, should this PR be split up, and if so, in how many PRs? I would request to not go too crazy on this, this will not be a neat PR no matter how you slice it. Then there's of course the issue that there may be dependencies.
Follow-up to the work in #12658 and #14613