NativeToJsBridge.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #pragma once
  8. #include <atomic>
  9. #include <functional>
  10. #include <map>
  11. #include <vector>
  12. #include <ReactCommon/CallInvoker.h>
  13. #include <cxxreact/JSExecutor.h>
  14. namespace folly {
  15. struct dynamic;
  16. }
  17. namespace facebook {
  18. namespace react {
  19. struct InstanceCallback;
  20. class JsToNativeBridge;
  21. class MessageQueueThread;
  22. class ModuleRegistry;
  23. class RAMBundleRegistry;
  24. // This class manages calls from native code to JS. It also manages
  25. // executors and their threads. All functions here can be called from
  26. // any thread.
  27. //
  28. // Except for loadBundleSync(), all void methods will queue
  29. // work to run on the jsQueue passed to the ctor, and return
  30. // immediately.
  31. class NativeToJsBridge {
  32. public:
  33. friend class JsToNativeBridge;
  34. /**
  35. * This must be called on the main JS thread.
  36. */
  37. NativeToJsBridge(
  38. JSExecutorFactory *jsExecutorFactory,
  39. std::shared_ptr<ModuleRegistry> registry,
  40. std::shared_ptr<MessageQueueThread> jsQueue,
  41. std::shared_ptr<InstanceCallback> callback);
  42. virtual ~NativeToJsBridge();
  43. /**
  44. * Executes a function with the module ID and method ID and any additional
  45. * arguments in JS.
  46. */
  47. void callFunction(
  48. std::string &&module,
  49. std::string &&method,
  50. folly::dynamic &&args);
  51. /**
  52. * Invokes a callback with the cbID, and optional additional arguments in JS.
  53. */
  54. void invokeCallback(double callbackId, folly::dynamic &&args);
  55. /**
  56. * Sets global variables in the JS Context.
  57. */
  58. void initializeRuntime();
  59. /**
  60. * Starts the JS application. If bundleRegistry is non-null, then it is
  61. * used to fetch JavaScript modules as individual scripts.
  62. * Otherwise, the script is assumed to include all the modules.
  63. */
  64. void loadBundle(
  65. std::unique_ptr<RAMBundleRegistry> bundleRegistry,
  66. std::unique_ptr<const JSBigString> startupCode,
  67. std::string sourceURL);
  68. void loadBundleSync(
  69. std::unique_ptr<RAMBundleRegistry> bundleRegistry,
  70. std::unique_ptr<const JSBigString> startupCode,
  71. std::string sourceURL);
  72. void registerBundle(uint32_t bundleId, const std::string &bundlePath);
  73. void setGlobalVariable(
  74. std::string propName,
  75. std::unique_ptr<const JSBigString> jsonValue);
  76. void *getJavaScriptContext();
  77. bool isInspectable();
  78. bool isBatchActive();
  79. void handleMemoryPressure(int pressureLevel);
  80. /**
  81. * Synchronously tears down the bridge and the main executor.
  82. */
  83. void destroy();
  84. void runOnExecutorQueue(std::function<void(JSExecutor *)> task);
  85. /**
  86. * Native CallInvoker is used by TurboModules to schedule work on the
  87. * NativeModule thread(s).
  88. */
  89. std::shared_ptr<CallInvoker> getDecoratedNativeCallInvoker(
  90. std::shared_ptr<CallInvoker> nativeInvoker);
  91. private:
  92. // This is used to avoid a race condition where a proxyCallback gets queued
  93. // after ~NativeToJsBridge(), on the same thread. In that case, the callback
  94. // will try to run the task on m_callback which will have been destroyed
  95. // within ~NativeToJsBridge(), thus causing a SIGSEGV.
  96. std::shared_ptr<bool> m_destroyed;
  97. std::shared_ptr<JsToNativeBridge> m_delegate;
  98. std::unique_ptr<JSExecutor> m_executor;
  99. std::shared_ptr<MessageQueueThread> m_executorMessageQueueThread;
  100. // Memoize this on the JS thread, so that it can be inspected from
  101. // any thread later. This assumes inspectability doesn't change for
  102. // a JSExecutor instance, which is true for all existing implementations.
  103. bool m_inspectable;
  104. // Keep track of whether the JS bundle containing the application logic causes
  105. // exception when evaluated initially. If so, more calls to JS will very
  106. // likely fail as well, so this flag can help prevent them.
  107. bool m_applicationScriptHasFailure = false;
  108. #ifdef WITH_FBSYSTRACE
  109. std::atomic_uint_least32_t m_systraceCookie = ATOMIC_VAR_INIT(0);
  110. #endif
  111. };
  112. } // namespace react
  113. } // namespace facebook