amis-rpc-design/node_modules/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.h
2023-10-07 19:42:30 +08:00

145 lines
4.7 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include "JSINativeModules.h"
#include <cxxreact/JSBigString.h>
#include <cxxreact/JSExecutor.h>
#include <cxxreact/RAMBundleRegistry.h>
#include <jsi/jsi.h>
#include <functional>
#include <mutex>
#include <optional>
namespace facebook {
namespace react {
// A JSIScopedTimeoutInvoker is a trampoline-type function for introducing
// timeouts. Call the TimeoutInvoker with a function to execute, the invokee.
// The TimeoutInvoker will immediately invoke it, synchronously on the same
// thread. If the invokee fails to return after some timeout (private to the
// TimeoutInvoker), a soft error may be reported.
//
// If a soft error is reported, the second parameter errorMessageProducer will
// be invoked to produce an error message, which will be included in the soft
// error report. Note that the errorMessageProducer will be invoked
// asynchronously on a different thread.
//
// The timeout behavior does NOT cause the invokee to aborted. If the invokee
// blocks forever, so will the ScopedTimeoutInvoker (but the soft error may
// still be reported).
//
// The invokee is passed by const ref because it is executed synchronously, but
// the errorMessageProducer is passed by value because it must be copied or
// moved for async execution.
//
// Example usage:
//
// int param = ...;
// timeoutInvoker(
// [&]{ someBigWork(param); },
// [=] -> std::string {
// return "someBigWork, param " + std::to_string(param);
// })
//
using JSIScopedTimeoutInvoker = std::function<void(
const std::function<void()> &invokee,
std::function<std::string()> errorMessageProducer)>;
class BigStringBuffer : public jsi::Buffer {
public:
BigStringBuffer(std::unique_ptr<const JSBigString> script)
: script_(std::move(script)) {}
size_t size() const override {
return script_->size();
}
const uint8_t *data() const override {
return reinterpret_cast<const uint8_t *>(script_->c_str());
}
private:
std::unique_ptr<const JSBigString> script_;
};
class JSIExecutor : public JSExecutor {
public:
using RuntimeInstaller = std::function<void(jsi::Runtime &runtime)>;
JSIExecutor(
std::shared_ptr<jsi::Runtime> runtime,
std::shared_ptr<ExecutorDelegate> delegate,
const JSIScopedTimeoutInvoker &timeoutInvoker,
RuntimeInstaller runtimeInstaller);
void initializeRuntime() override;
void loadBundle(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) override;
void setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) override;
void registerBundle(uint32_t bundleId, const std::string &bundlePath)
override;
void callFunction(
const std::string &moduleId,
const std::string &methodId,
const folly::dynamic &arguments) override;
void invokeCallback(const double callbackId, const folly::dynamic &arguments)
override;
void setGlobalVariable(
std::string propName,
std::unique_ptr<const JSBigString> jsonValue) override;
std::string getDescription() override;
void *getJavaScriptContext() override;
bool isInspectable() override;
void handleMemoryPressure(int pressureLevel) override;
// An implementation of JSIScopedTimeoutInvoker that simply runs the
// invokee, with no timeout.
static void defaultTimeoutInvoker(
const std::function<void()> &invokee,
std::function<std::string()> errorMessageProducer) {
(void)errorMessageProducer;
invokee();
}
void flush() override;
private:
class NativeModuleProxy;
void bindBridge();
void callNativeModules(const jsi::Value &queue, bool isEndOfBatch);
jsi::Value nativeCallSyncHook(const jsi::Value *args, size_t count);
jsi::Value nativeRequire(const jsi::Value *args, size_t count);
jsi::Value globalEvalWithSourceUrl(const jsi::Value *args, size_t count);
std::shared_ptr<jsi::Runtime> runtime_;
std::shared_ptr<ExecutorDelegate> delegate_;
std::shared_ptr<JSINativeModules> nativeModules_;
std::shared_ptr<ModuleRegistry> moduleRegistry_;
std::once_flag bindFlag_;
std::unique_ptr<RAMBundleRegistry> bundleRegistry_;
JSIScopedTimeoutInvoker scopedTimeoutInvoker_;
RuntimeInstaller runtimeInstaller_;
std::optional<jsi::Function> callFunctionReturnFlushedQueue_;
std::optional<jsi::Function> invokeCallbackAndReturnFlushedQueue_;
std::optional<jsi::Function> flushedQueue_;
};
using Logger =
std::function<void(const std::string &message, unsigned int logLevel)>;
void bindNativeLogger(jsi::Runtime &runtime, Logger logger);
void bindNativePerformanceNow(jsi::Runtime &runtime);
double performanceNow();
} // namespace react
} // namespace facebook