Skip to content

[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

Merged
merged 1 commit into from
Oct 15, 2021

Conversation

aardappel
Copy link
Collaborator

@aardappel aardappel commented Nov 24, 2020

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

Copy link
Collaborator

@sbc100 sbc100 left a 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',
Copy link
Collaborator

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?

Copy link
Collaborator Author

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 :)

Copy link
Collaborator

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.

Copy link
Collaborator Author

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 :)

@aardappel aardappel marked this pull request as draft December 4, 2020 00:22
@aardappel aardappel force-pushed the master branch 2 times, most recently from 6e32d6b to f70b244 Compare December 4, 2020 20:46
Copy link
Collaborator

@sbc100 sbc100 left a 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!

@sbc100
Copy link
Collaborator

sbc100 commented Dec 4, 2020

If you feel like splitting of the Runtime.POINTER_SIZE -> POINTER_SIZE change that could land first? (No worries if not).

@sbc100
Copy link
Collaborator

sbc100 commented Dec 4, 2020

Is this still a draft?

@aardappel
Copy link
Collaborator Author

No, I'd rather not split that off.. and yes, still a draft until I get further along I think?

Base automatically changed from master to main March 8, 2021 23:49
aheejin added a commit to aheejin/emscripten that referenced this pull request May 6, 2021
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.
aardappel added a commit that referenced this pull request Jul 15, 2021
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
@aardappel aardappel force-pushed the master branch 8 times, most recently from 6f99f54 to 79c84d3 Compare September 13, 2021 23:27
@aardappel aardappel marked this pull request as ready for review September 23, 2021 19:21
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) }}}',
Copy link
Collaborator

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?

Copy link
Collaborator Author

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
Copy link
Collaborator

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?

Copy link
Collaborator Author

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?

Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

@@ -266,6 +266,7 @@ def inspect_headers(headers, cflags):
'-Wno-format',
'-nostdlib',
compiler_rt,
'-s', 'MEMORY64=' + str(settings.MEMORY64),
Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

Copy link
Collaborator

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:

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?

Copy link
Collaborator Author

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.

@sbc100
Copy link
Collaborator

sbc100 commented Oct 4, 2021 via email

@aardappel aardappel force-pushed the master branch 2 times, most recently from a58191f to babc881 Compare October 4, 2021 19:01
Copy link
Member

@kripken kripken left a 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),
]
Copy link
Member

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),
Copy link
Member

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.

Copy link
Collaborator Author

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
Copy link
Collaborator

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:

# 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)
Copy link
Collaborator

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),
]
Copy link
Collaborator

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

@aardappel aardappel force-pushed the master branch 2 times, most recently from fdd4d9e to 383146a Compare October 14, 2021 20:52
@kripken
Copy link
Member

kripken commented Oct 14, 2021

@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.

@aardappel
Copy link
Collaborator Author

Copy link
Member

@kripken kripken left a 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),
]
Copy link
Member

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.

@aardappel aardappel merged commit 8d424d2 into emscripten-core:main Oct 15, 2021
@kripken kripken mentioned this pull request Nov 18, 2021
kripken added a commit that referenced this pull request Nov 19, 2021
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.
mmarczell-graphisoft pushed a commit to GRAPHISOFT/emscripten that referenced this pull request Jan 5, 2022
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants