Skip to content

Commit

Permalink
Conditionalize Promise queuing based on JobQueue flag
Browse files Browse the repository at this point in the history
Summary:
This diff expose the `JobQueue` flag to internal bytecode via
`HermesInternal.useEngineQueue` to conditionalize where Promise
Jobs are queued into.

This diff has some unfortunate noises from upstreaming rollup
changes when building Promise internal bytecode.

Reviewed By: avp

Differential Revision: D27549346

fbshipit-source-id: 0740fa6e5d2f586b77b5cc1bc7e3f56d02a6e9c5
  • Loading branch information
Huxpro authored and facebook-github-bot committed Apr 22, 2021
1 parent a4cf67f commit 27ac760
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 9 deletions.
1 change: 1 addition & 0 deletions include/hermes/VM/NativeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ NATIVE_FUNCTION(hermesInternalTTRCReached)

NATIVE_FUNCTION(hermesInternalSetPromiseRejectionTrackingHook)
NATIVE_FUNCTION(hermesInternalEnablePromiseRejectionTracker)
NATIVE_FUNCTION(hermesInternalUseEngineQueue)
NATIVE_FUNCTION(hermesInternalEnqueueJob)
NATIVE_FUNCTION(hermesInternalDrainJobs)

Expand Down
1 change: 1 addition & 0 deletions include/hermes/VM/PredefinedStrings.def
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ STR(HermesInternal, "HermesInternal")
STR(detachArrayBuffer, "detachArrayBuffer")
STR(createHeapSnapshot, "createHeapSnapshot")
STR(hasPromise, "hasPromise")
STR(useEngineQueue, "useEngineQueue")
STR(enqueueJob, "enqueueJob")
STR(drainJobs, "drainJobs")
STR(getEpilogues, "getEpilogues")
Expand Down
6 changes: 3 additions & 3 deletions lib/InternalBytecode/01-Promise.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* @nolint */ var initPromise = (function () {
/* @nolint */var initPromise = (function () {
'use strict';

var useEngineQueue = HermesInternal.useEngineQueue();
function noop() {}

// States:
Expand Down Expand Up @@ -109,7 +109,7 @@
}

function handleResolved(self, deferred) {
setImmediate(function() {
(useEngineQueue ? HermesInternal.enqueueJob : setImmediate)(function() {
var cb = self._i === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
if (self._i === 1) {
Expand Down
6 changes: 6 additions & 0 deletions lib/VM/JSLib/HermesInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,11 @@ hermesInternalHasPromise(void *, Runtime *runtime, NativeArgs args) {
return HermesValue::encodeBoolValue(runtime->hasES6Promise());
}

CallResult<HermesValue>
hermesInternalUseEngineQueue(void *, Runtime *runtime, NativeArgs args) {
return HermesValue::encodeBoolValue(runtime->useJobQueue());
}

/// \code
/// HermesInternal.enqueueJob = function (func) {}
/// \endcode
Expand Down Expand Up @@ -889,6 +894,7 @@ Handle<JSObject> createHermesInternalObject(
defineInternMethod(
P::enablePromiseRejectionTracker,
hermesInternalEnablePromiseRejectionTracker);
defineInternMethod(P::useEngineQueue, hermesInternalUseEngineQueue);

// All functions are known to be safe can be defined above this flag check.
if (!flags.enableHermesInternal) {
Expand Down
3 changes: 2 additions & 1 deletion test/hermes/hermes-internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
// setPromiseRejectionTrackingHook
// enablePromiseRejectionTracker
// enqueueJob
var SAFE_FIELDS_COUNT = 5;
// useEngineQueue
var SAFE_FIELDS_COUNT = 6;

// Check that we can disable unsafe fields of HermesInternal.
print(Object.getOwnPropertyNames(HermesInternal).length)
Expand Down
10 changes: 8 additions & 2 deletions utils/gen-promise-internal-bc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ TMP_PROMISE_DIR="${TMP_DIR}/promise"
TMP_PROMISE_JS="${TMP_PROMISE_DIR}/Promise.js"
BC_PROMISE_JS="${BC_DIR}/01-Promise.js"

NOLINT="/* @nolint */"
PATCH1=" var useEngineQueue = HermesInternal.useEngineQueue()\;"
PATCH2='(useEngineQueue ? HermesInternal.enqueueJob : setImmediate)'

gen() {
# It's tricky to ensure `sed -i` work on both GNU and macOS consistantly.
# It's tricky to ensure `sed -i` work on both GNU and macOS consistently.
# https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux
sed -i.bak '1s;^;/* @nolint */ ;' $TMP_PROMISE_JS && \
sed -i.bak "1s;^;${NOLINT};" $TMP_PROMISE_JS && \
sed -i.bak "3s;^;${PATCH1};" $TMP_PROMISE_JS && \
sed -i.bak "s/setImmediate/${PATCH2}/g" $TMP_PROMISE_JS && \
sed -i.bak '$ d' $TMP_PROMISE_JS && \
cat <<EOT >> $TMP_PROMISE_JS
});
Expand Down
6 changes: 3 additions & 3 deletions utils/promise/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"dependencies": {
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-commonjs": "~15.0.0",
"@rollup/plugin-node-resolve": "~9.0.0",
"promise": "8.0.3"
},
"scripts": {
"start": "yarn run rollup --config rollup.config.js index.js"
},
"devDependencies": {
"rollup": "^2.27.0"
"rollup": "~2.27.0"
}
}

0 comments on commit 27ac760

Please sign in to comment.