From ff4b33672a6a27d2ed68ae6602e9d29d9b7c3eb1 Mon Sep 17 00:00:00 2001 From: Xuan Huang Date: Tue, 24 Aug 2021 00:10:47 -0700 Subject: [PATCH] Add Flow libdefs for HermesInternalType Summary: Changelog: [Internal] This diff add a flow libdefs for the `HermesInternalType` to type `HermesInternal` as the first accurately typed `global` property, and filled all the type holes. Reviewed By: yungsters Differential Revision: D29986749 fbshipit-source-id: a94be7919f989b5085f6b264e55145a85020fea9 --- Libraries/Core/polyfillPromise.js | 2 +- Libraries/Core/setUpTimers.js | 6 +- flow/HermesInternalType.js | 114 ++++++++++++++++++++++++++++++ flow/global.js | 2 + 4 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 flow/HermesInternalType.js diff --git a/Libraries/Core/polyfillPromise.js b/Libraries/Core/polyfillPromise.js index 6551745bf52c5d..f83fea90248b9d 100644 --- a/Libraries/Core/polyfillPromise.js +++ b/Libraries/Core/polyfillPromise.js @@ -29,7 +29,7 @@ if (global?.HermesInternal?.hasPromise?.()) { if (typeof HermesPromise !== 'function') { console.error('HermesPromise does not exist'); } - global.HermesInternal.enablePromiseRejectionTracker( + global.HermesInternal?.enablePromiseRejectionTracker?.( require('../promiseRejectionTrackingOptions').default, ); } diff --git a/Libraries/Core/setUpTimers.js b/Libraries/Core/setUpTimers.js index d257dfa0168d96..9d2020f83641e0 100644 --- a/Libraries/Core/setUpTimers.js +++ b/Libraries/Core/setUpTimers.js @@ -21,8 +21,8 @@ if (__DEV__) { // Currently, Hermes `Promise` is implemented via Internal Bytecode. const hasHermesPromiseQueuedToJSVM = - global?.HermesInternal?.hasPromise?.() && - global?.HermesInternal?.useEngineQueue?.(); + global.HermesInternal?.hasPromise?.() === true && + global.HermesInternal?.useEngineQueue?.() === true; const hasNativePromise = isNativeFunction(Promise); const hasPromiseQueuedToJSVM = hasNativePromise || hasHermesPromiseQueuedToJSVM; @@ -83,7 +83,7 @@ if (hasPromiseQueuedToJSVM) { */ if (hasHermesPromiseQueuedToJSVM) { // Fast path for Hermes. - polyfillGlobal('queueMicrotask', () => global.HermesInternal.enqueueJob); + polyfillGlobal('queueMicrotask', () => global.HermesInternal?.enqueueJob); } else { // Polyfill it with promise (regardless it's polyfiled or native) otherwise. polyfillGlobal( diff --git a/flow/HermesInternalType.js b/flow/HermesInternalType.js new file mode 100644 index 00000000000000..61c5a9696f0657 --- /dev/null +++ b/flow/HermesInternalType.js @@ -0,0 +1,114 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +// Declarations for functionality exposed by the Hermes VM. +// +// For backwards-compatibility, code that uses such functionality must also +// check explicitly at run-time whether the object(s) and method(s) exist, and +// fail safely if not. + +/** + * HermesInternalType is an object containing functions used to interact with + * the VM in a way that is not standardized by the JS spec. + * There are limited guarantees about these functions, and they should not be + * widely used. Consult with the Hermes team before using any of these. + * There may be other visible properties on this object; however, those are + * only exposed for testing purposes: do not use them. + */ +declare type $HermesInternalType = { + // All members are optional because they may not exist when OTA'd to older + // VMs. + + +getNumGCs?: () => number, + +getGCTime?: () => number, + +getNativeCallTime?: () => number, + +getNativeCallCount?: () => number, + +getGCCPUTime?: () => number, + + /** + * Hermes can embed an "epilogue" to the bytecode file with arbitrary bytes. + * At most one epilogue will exist per bytecode module (which can be + * different than a JS module). + * Calling this function will return all such epilogues and convert the + * bytes to numbers in the range of 0-255. + */ + +getEpilogues?: () => Array>, + + /** + * Query the VM for various statistics about performance. + * There are no guarantees about what keys exist in it, but they can be + * printed for informational purposes. + * @return An object that maps strings to various types of performance + * statistics. + */ + +getInstrumentedStats?: () => {[string]: number | string, ...}, + + /** + * Query the VM for any sort of runtime properties that it wants to report. + * There are no guarantees about what keys exist in it, but they can be + * printed for informational purposes. + * @return An object that maps strings to various types of runtime properties. + */ + +getRuntimeProperties?: () => { + 'OSS Release Version': string, + 'Build': string, + [string]: mixed, + }, + + /** + * Tell Hermes that at this point the surface has transitioned from TTI to + * post-TTI. The VM can change some of its internal behavior to optimize for + * post-TTI scenarios. + * This can be called several times but will have no effect after the first + * call. + */ + +ttiReached?: () => void, + + /** + * Tell Hermes that at this point the surface has transitioned from TTRC to + * post-TTRC. The VM can change some of its internal behavior to optimize for + * post-TTRC scenarios. + * This can be called several times but will have no effect after the first + * call. + */ + +ttrcReached?: () => void, + + /** + * Query the VM to see whether or not it enabled Promise. + */ + +hasPromise?: () => boolean, + + /** + * Enable promise rejection tracking with the given options. + * The API mirrored the `promise` npm package, therefore it's typed same as + * the `enable` function of module `promise/setimmediate/rejection-tracking` + * declared in ./flow-typed/npm/promise_v8.x.x.js. + */ + +enablePromiseRejectionTracker?: ( + options: ?{ + whitelist?: ?Array, + allRejections?: ?boolean, + onUnhandled?: ?(number, mixed) => void, + onHandled?: ?(number, mixed) => void, + }, + ) => void, + + /** + * Query the VM to see whether or not it use the engine Job queue. + */ + +useEngineQueue?: () => boolean, + + /** + * Enqueue a JavaScript callback function as a Job into the engine Job queue. + */ + +enqueueJob?: >( + jobCallback: (...args: TArguments) => mixed, + ) => void, +}; diff --git a/flow/global.js b/flow/global.js index 8d7b7ee01c952f..3c32ec6796c84e 100644 --- a/flow/global.js +++ b/flow/global.js @@ -16,6 +16,8 @@ * writeability (`+`) when defining types. */ declare var global: { + +HermesInternal: ?$HermesInternalType, + // Undeclared properties are implicitly `any`. [string | symbol]: any, };