Skip to content

Commit

Permalink
Avoid resetting process.exitCode when initializing HermesParserWASM (#…
Browse files Browse the repository at this point in the history
…989)

Summary:
Pull Request resolved: #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: #978

Reviewed By: tmikov

Differential Revision: D45705102

fbshipit-source-id: 915ef98348be0b6f6536ea902a8b62a10490a66b
  • Loading branch information
pieterv authored and facebook-github-bot committed May 11, 2023
1 parent ae61ae2 commit d1be3ff
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 55 deletions.
1 change: 1 addition & 0 deletions tools/hermes-parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ if (EMSCRIPTEN)
target_link_options(hermes-parser-wasm PRIVATE "SHELL: -s ALLOW_MEMORY_GROWTH=1")
target_link_options(hermes-parser-wasm PRIVATE
"SHELL: -s EXTRA_EXPORTED_RUNTIME_METHODS=[cwrap,ccall]")
target_link_options(hermes-parser-wasm PRIVATE "SHELL: -s MODULARIZE=1")
target_link_options(hermes-parser-wasm PRIVATE "SHELL: -s EXPORT_NAME=hermes_parser_wasm")
target_link_options(hermes-parser-wasm PRIVATE
"SHELL: -s BINARYEN_ASYNC_COMPILATION=0 -s SINGLE_FILE=1 -s WASM_ASYNC_COMPILATION=0")
Expand Down
138 changes: 86 additions & 52 deletions tools/hermes-parser/js/hermes-parser/src/HermesParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,90 @@ import type {HermesNode} from './HermesAST';
import type {ParserOptions} from './ParserOptions';

import HermesParserDeserializer from './HermesParserDeserializer';
import HermesParserWASM from './HermesParserWASM';

const hermesParse = HermesParserWASM.cwrap('hermesParse', 'number', [
'number',
'number',
'number',
'number',
'number',
'number',
]);

const hermesParseResult_free = HermesParserWASM.cwrap(
'hermesParseResult_free',
'void',
['number'],
);

const hermesParseResult_getError = HermesParserWASM.cwrap(
'hermesParseResult_getError',
'string',
['number'],
);

const hermesParseResult_getErrorLine = HermesParserWASM.cwrap(
'hermesParseResult_getErrorLine',
'number',
['number'],
);

const hermesParseResult_getErrorColumn = HermesParserWASM.cwrap(
'hermesParseResult_getErrorColumn',
'number',
['number'],
);

const hermesParseResult_getProgramBuffer = HermesParserWASM.cwrap(
'hermesParseResult_getProgramBuffer',
'number',
['number'],
);

const hermesParseResult_getPositionBuffer = HermesParserWASM.cwrap(
'hermesParseResult_getPositionBuffer',
'number',
['number'],
);

const hermesParseResult_getPositionBufferSize = HermesParserWASM.cwrap(
'hermesParseResult_getPositionBufferSize',
'number',
['number'],
);
import HermesParserWASMModule from './HermesParserWASM';

let HermesParserWASM;
let hermesParse;
let hermesParseResult_free;
let hermesParseResult_getError;
let hermesParseResult_getErrorLine;
let hermesParseResult_getErrorColumn;
let hermesParseResult_getProgramBuffer;
let hermesParseResult_getPositionBuffer;
let hermesParseResult_getPositionBufferSize;

/**
* Init the WASM wrapper code generated by `emscripten` to preparse the
* HermesParser WASM code.
*/
function initHermesParserWASM() {
if (HermesParserWASM != null) {
return;
}

HermesParserWASM = HermesParserWASMModule({
/**
* The emscripten version of `quit` unconditionally assigns the `status` to
* `process.exitCode` which overrides any pre-existing code that has been
* set, even if it is non zero. For our use case we never want an
* `exitCode` to be set so this override removes that functionality.
*/
quit(_status: number, toThrow: Error) {
throw toThrow;
},
});

hermesParse = HermesParserWASM.cwrap('hermesParse', 'number', [
'number',
'number',
'number',
'number',
'number',
'number',
]);

hermesParseResult_free = HermesParserWASM.cwrap(
'hermesParseResult_free',
'void',
['number'],
);

hermesParseResult_getError = HermesParserWASM.cwrap(
'hermesParseResult_getError',
'string',
['number'],
);

hermesParseResult_getErrorLine = HermesParserWASM.cwrap(
'hermesParseResult_getErrorLine',
'number',
['number'],
);

hermesParseResult_getErrorColumn = HermesParserWASM.cwrap(
'hermesParseResult_getErrorColumn',
'number',
['number'],
);

hermesParseResult_getProgramBuffer = HermesParserWASM.cwrap(
'hermesParseResult_getProgramBuffer',
'number',
['number'],
);

hermesParseResult_getPositionBuffer = HermesParserWASM.cwrap(
'hermesParseResult_getPositionBuffer',
'number',
['number'],
);

hermesParseResult_getPositionBufferSize = HermesParserWASM.cwrap(
'hermesParseResult_getPositionBufferSize',
'number',
['number'],
);
}

// Copy a string into the WASM heap and null-terminate
function copyToHeap(buffer: Buffer, addr: number) {
Expand All @@ -74,6 +106,8 @@ function copyToHeap(buffer: Buffer, addr: number) {
}

export function parse(source: string, options: ParserOptions): HermesNode {
initHermesParserWASM();

// Allocate space on heap for source text
const sourceBuffer = Buffer.from(source, 'utf8');
const sourceAddr = HermesParserWASM._malloc(sourceBuffer.length + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {
HermesToken,
HermesComment,
} from './HermesAST';
import typeof HermesParserWASM from './HermesParserWASM';
import type {HermesParserWASM} from './HermesParserWASM';
import type {ParserOptions} from './ParserOptions';

import HermesParserDecodeUTF8String from './HermesParserDecodeUTF8String';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ type INTENTIONAL_ANY = $FlowFixMe;
type JSType = 'number' | 'string' | 'array' | 'boolean';
type CBoolean = ?(number | boolean);

type HermesParserWASM = $ReadOnly<{
type WASMModuleOverrides = $ReadOnly<{
quit(status: number, toThrow: Error): void,
}>;

export type HermesParserWASM = $ReadOnly<{
HEAP8: Int8Array,
HEAP16: Int16Array,
HEAP32: Int32Array,
Expand Down Expand Up @@ -72,4 +76,4 @@ type HermesParserWASM = $ReadOnly<{
stackRestore(ptr: number): void,
}>;

declare module.exports: HermesParserWASM;
declare module.exports: WASMModuleOverrides => HermesParserWASM;

0 comments on commit d1be3ff

Please sign in to comment.