Skip to content
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

import("hermes-parser") changes process.exitCode #978

Closed
1 task
fisker opened this issue Apr 25, 2023 · 8 comments
Closed
1 task

import("hermes-parser") changes process.exitCode #978

fisker opened this issue Apr 25, 2023 · 8 comments
Labels
bug Something isn't working

Comments

@fisker
Copy link

fisker commented Apr 25, 2023

Bug Description

  • I have run gradle clean and confirmed this bug does not occur with JSC

Hermes version: 0.10.1
React Native version (if any):
OS version (if any): Windows
Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): x86_64

Steps To Reproduce

code example:

process.exitCode = 11;
await import("hermes-parser");
console.log(process.exitCode);
// Logs `0` instead of `11`

The Expected Behavior

Should not change process.exitCode.

Possible related to #942

@fisker fisker added the bug Something isn't working label Apr 25, 2023
@tmikov
Copy link
Contributor

tmikov commented Apr 25, 2023

This seems to be a side effect of the Emscripten glue code. A quick examination of HermesParserWASM.js narrows it down to this:

  quit_ = (status, toThrow) => {
    if (keepRuntimeAlive()) {
      process["exitCode"] = status;
      throw toThrow;
    }
    logExceptionOnExit(toThrow);
    process["exit"](status);
  };

I am not really sure what the correct approach here is. The whole Emscripten glue situation feels like a bit of a mess. This is definitely fixable, but somebody will have to really dig down and figure it out.

@pieterv
Copy link
Member

pieterv commented May 9, 2023

Hey @fisker, i had a look into this issue. Its a bit tricky since the code that has this behavior is generated by emscripten so not something we have direct control over. I haven't been able to find a emscripten setting which disables this behavior, see the code below:

Emscripten code: https://github.com/emscripten-core/emscripten/blob/3c822ef6ba6b3be58b73fd8dde4422538fdbe3dc/src/shell.js#LL260C31-L260C31
Settings: https://github.com/emscripten-core/emscripten/blob/main/src/settings.js
Current settings found here: https://github.com/facebook/hermes/blob/main/tools/hermes-parser/CMakeLists.txt

There are some options thought:

  1. emscripten allows you to override specific functions, the way this works is by creating a global that emscripten reads and overrides its own functions with, e.g. so the following code before requiring HermesParserWASM fixes the issue:
global.hermes_parser_wasm = {};
global.hermes_parser_wasm.quit = (status) => {
  if (status !== 0) {
    process.exitCode = status;
  }
};

The downside is this uses globals which won't work with mjs files (as i understand it?).

@fisker i assume you are looking at this to be able to include it in prettier v3? (i would love to see this happen so happy to help out with this work btw).

  1. i could move the emscripten generated code so it only gets called via the parse function (not as a side effect of requiring "hermes-parser"), then at the end of that function i could reset the exitCode to the code before the call if its non zero. This might be better anyway since since its not great "hermes-parser" has these side effects.

@fisker any preference? Ill try giving 2) a go.

@tmikov
Copy link
Contributor

tmikov commented May 9, 2023

@pieterv can this be addressed using -s MODULARIZE=1 and then passing options like this?

@pieterv
Copy link
Member

pieterv commented May 9, 2023

Nice! I tested this and its working, MODULARIZE=1 also has the nice sideeffect of not initializing the module on import, so module sideeffects can be deferred. Ill put up the change shortly.

pieterv added a commit to pieterv/hermes that referenced this issue May 9, 2023
Summary:
The default emscripten code overrides the `process.exitCode` value to `0` on module init. This means if someone has already set an `exitCode` it will be reset. This change fixes this by switching emscripten to use the `MODULARIZE` flag which allows us to pass in function overrides, we then pass a modified implementation of `quit` that only adds the exitCode if its non zero.

Fixes: facebook#978

Differential Revision: D45705102

fbshipit-source-id: e3b7980e491e02836a21f182a495027aa8282ffa
@fisker
Copy link
Author

fisker commented May 9, 2023

@pieterv Thank you for looking into this. Actually this is not really an issue for Prettier anymore, since we only need the visitorKeys.

The following

- import { VisitorKeys as flowVisitorKeys } from "hermes-eslint";
+ import flowVisitorKeys from "hermes-parser/dist/generated/ESTreeVisitorKeys.js";

already work for us. https://github.com/prettier/prettier/pull/14756/files#diff-26f745c3d0a653bf61c52f9adfd251e9a3fc619ec20ab1792b95e7296266edcaL3

I thought it worth to raise an issue since it took me a while to locate the problem. 😄

@pieterv
Copy link
Member

pieterv commented May 9, 2023

@fisker Oh nice, glad you were able to get unblocked!

I was wondering, is size still an issue with the prettier V3 architecture? I know this was a concern for adding hermes parser as a core parser in the past (prettier/prettier#13818), i would love to get it in at some point since we actually patch prettier in Meta to use hermes-parser since its about x10 faster than the Flow parser.

@fisker
Copy link
Author

fisker commented May 10, 2023

Unfortunately yes, people has been complainted. We can try to support it after we fix prettier/prettier#13912. No promises.

@pieterv
Copy link
Member

pieterv commented May 10, 2023

Unfortunately yes, people has been complainted

Weird i wonder why people care. The module system would be nice though! If size is a limitation maybe it would be ok to swap flow-parser for hermes-parser? flow-parser is 768 kB and hermes-parser 934 kB, so not too far off, i might be able to get hermes-parser closer to the flow size. They have equivalent features, however hermes parser doesn't need special support for Flow type comments.

pieterv added a commit to pieterv/hermes that referenced this issue May 10, 2023
…acebook#989)

Summary:
Pull Request resolved: facebook#989

The default emscripten code overrides the `process.exitCode` value to `0` on module init. This means if someone has already set an `exitCode` it will be reset. This change fixes this by switching emscripten to use the `MODULARIZE` flag which allows us to pass in function overrides, we then pass a modified implementation of `quit` that only adds the exitCode if its non zero.

Fixes: facebook#978

Differential Revision: D45705102

fbshipit-source-id: c9b5bf5c74f55d047ad07c0a81390f8ba6932dfb
pieterv added a commit to pieterv/hermes that referenced this issue May 11, 2023
…acebook#989)

Summary:
Pull Request resolved: facebook#989

The default emscripten code overrides the `process.exitCode` value to `0` on module init. This means if someone has already set an `exitCode` it will be reset. This change fixes this by switching emscripten to use the `MODULARIZE` flag which allows us to pass in function overrides, we then pass a modified implementation of `quit` that only adds the exitCode if its non zero.

Fixes: facebook#978

Differential Revision: D45705102

fbshipit-source-id: 4022b34d24994b10843161811395768cd344cea0
facebook-github-bot pushed a commit that referenced this issue Jul 27, 2023
Summary:
Original Author: pieterv@meta.com
Original Git: d1be3ff

The default emscripten code overrides the `process.exitCode` value to `0` on module init. This means if someone has already set an `exitCode` it will be reset. This change fixes this by switching emscripten to use the `MODULARIZE` flag which allows us to pass in function overrides, we then pass a modified implementation of `quit` that only adds the exitCode if its non zero.

Fixes: #978

Original Reviewed By: tmikov

Original Revision: D45705102

Reviewed By: neildhar

Differential Revision: D47690263

fbshipit-source-id: afda31d02534f5ae4bd9366b215a03101f8a7c06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants