Replace folly::make_unique with std::make_unique (#26730)

Summary:
There is a mixed usage of `folly::make_unique` and `std::make_unique`. Soon, `folly::make_unique` may be removed (see [this PR](https://github.com/facebook/folly/pull/1150)). Since `react-native` only supports C++14-compilers and later, switch to always using `std::make_unique`.

## Changelog

[Internal] [Removed] - Replace folly::make_unique with std::make_unique
Pull Request resolved: https://github.com/facebook/react-native/pull/26730

Test Plan:
Running the existing test suite. No change in behavior is expected.

Joshua Gross: buck install -r fb4a, make sure MP Home and forced teardown works okay on android

Reviewed By: shergin

Differential Revision: D18062400

Pulled By: JoshuaGross

fbshipit-source-id: 978ca794c7e972db872a8dcc57c31bdec7451481
This commit is contained in:
Joe Loser
2019-10-22 12:21:41 -07:00
committed by Facebook Github Bot
parent 468d1a2d2e
commit ba18ee9b87
20 changed files with 412 additions and 341 deletions
+3 -1
View File
@@ -10,6 +10,8 @@
#import <React/RCTLog.h>
#import <jsi/JSCRuntime.h>
#import<memory>
namespace facebook {
namespace react {
@@ -28,7 +30,7 @@ std::unique_ptr<JSExecutor> JSCExecutorFactory::createJSExecutor(
runtimeInstaller(runtime);
}
};
return folly::make_unique<JSIExecutor>(
return std::make_unique<JSIExecutor>(
facebook::jsc::makeJSCRuntime(),
delegate,
JSIExecutor::defaultTimeoutInvoker,
+3 -2
View File
@@ -12,10 +12,11 @@
#import <React/RCTConvert.h>
#import <React/RCTFollyConvert.h>
#import <cxxreact/JsArgumentHelpers.h>
#import <folly/Memory.h>
#import "RCTCxxUtils.h"
#import <memory>
using facebook::xplat::module::CxxModule;
using namespace facebook::react;
@@ -27,7 +28,7 @@ using namespace facebook::react;
- (instancetype)initWithCxxMethod:(const CxxModule::Method &)method
{
if ((self = [super init])) {
_method = folly::make_unique<CxxModule::Method>(method);
_method = std::make_unique<CxxModule::Method>(method);
}
return self;
}
@@ -8,7 +8,6 @@
#include <../instrumentation/HermesMemoryDumper.h>
#include <HermesExecutorFactory.h>
#include <fb/fbjni.h>
#include <folly/Memory.h>
#include <hermes/Public/GCConfig.h>
#include <hermes/Public/RuntimeConfig.h>
#include <jni.h>
@@ -16,6 +15,8 @@
#include <react/jni/JSLogging.h>
#include <react/jni/JavaScriptExecutorHolder.h>
#include <memory>
namespace facebook {
namespace react {
@@ -103,7 +104,7 @@ class HermesExecutorHolder
JReactMarker::setLogPerfMarkerIfNeeded();
return makeCxxInstance(
folly::make_unique<HermesExecutorFactory>(installBindings));
std::make_unique<HermesExecutorFactory>(installBindings));
}
static jni::local_ref<jhybriddata> initHybrid(
@@ -124,7 +125,7 @@ class HermesExecutorHolder
heapDumper,
tripWireCooldownMS,
tripWireLimitBytes);
return makeCxxInstance(folly::make_unique<HermesExecutorFactory>(
return makeCxxInstance(std::make_unique<HermesExecutorFactory>(
installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig));
}
@@ -6,7 +6,6 @@
*/
#include <fb/fbjni.h>
#include <folly/Memory.h>
#include <jsi/JSCRuntime.h>
#include <jsireact/JSIExecutor.h>
#include <react/jni/JReactMarker.h>
@@ -14,6 +13,8 @@
#include <react/jni/JavaScriptExecutorHolder.h>
#include <react/jni/ReadableNativeMap.h>
#include <memory>
namespace facebook {
namespace react {
@@ -30,7 +31,7 @@ class JSCExecutorFactory : public JSExecutorFactory {
&reactAndroidLoggingHook);
react::bindNativeLogger(runtime, androidLogger);
};
return folly::make_unique<JSIExecutor>(
return std::make_unique<JSIExecutor>(
jsc::makeJSCRuntime(),
delegate,
JSIExecutor::defaultTimeoutInvoker,
@@ -56,7 +57,7 @@ class JSCExecutorHolder
// Android.
JReactMarker::setLogPerfMarkerIfNeeded();
// TODO mhorowitz T28461666 fill in some missing nice to have glue
return makeCxxInstance(folly::make_unique<JSCExecutorFactory>());
return makeCxxInstance(std::make_unique<JSCExecutorFactory>());
}
static void registerNatives() {
@@ -8,6 +8,7 @@
#include "CatalystInstanceImpl.h"
#include <condition_variable>
#include <memory>
#include <mutex>
#include <sstream>
#include <vector>
@@ -25,7 +26,6 @@
#include <cxxreact/RecoverableError.h>
#include <fb/fbjni/ByteBuffer.h>
#include <fb/log.h>
#include <folly/Memory.h>
#include <folly/dynamic.h>
#include <jni/Countable.h>
#include <jni/LocalReference.h>
@@ -93,7 +93,7 @@ CatalystInstanceImpl::initHybrid(jni::alias_ref<jclass>) {
}
CatalystInstanceImpl::CatalystInstanceImpl()
: instance_(folly::make_unique<Instance>()) {}
: instance_(std::make_unique<Instance>()) {}
CatalystInstanceImpl::~CatalystInstanceImpl() {
if (moduleMessageQueue_ != NULL) {
@@ -181,7 +181,7 @@ void CatalystInstanceImpl::initializeBridge(
instance_->initializeBridge(
std::make_unique<JInstanceCallback>(callback, moduleMessageQueue_),
jseh->getExecutorFactory(),
folly::make_unique<JMessageQueueThread>(jsQueue),
std::make_unique<JMessageQueueThread>(jsQueue),
moduleRegistry_);
}
@@ -276,7 +276,7 @@ void CatalystInstanceImpl::setGlobalVariable(
instance_->setGlobalVariable(
std::move(propName),
folly::make_unique<JSBigStdString>(std::move(jsonValue)));
std::make_unique<JSBigStdString>(std::move(jsonValue)));
}
jlong CatalystInstanceImpl::getJavaScriptContext() {
@@ -5,12 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
#include <memory>
#include <string>
#include <ReactCommon/BridgeJSCallInvoker.h>
#include <ReactCommon/CallInvokerHolder.h>
#include <fb/fbjni.h>
#include <folly/Memory.h>
#include "CxxModuleWrapper.h"
#include "JMessageQueueThread.h"
@@ -7,6 +7,8 @@
#include "JInspector.h"
#include <memory>
#ifdef WITH_INSPECTOR
namespace facebook {
@@ -80,7 +82,7 @@ jni::local_ref<jni::JArrayClass<JPage::javaobject>> JInspector::getPages() {
}
jni::local_ref<JLocalConnection::javaobject> JInspector::connect(int pageId, jni::alias_ref<JRemoteConnection::javaobject> remote) {
auto localConnection = inspector_->connect(pageId, folly::make_unique<RemoteConnection>(std::move(remote)));
auto localConnection = inspector_->connect(pageId, std::make_unique<RemoteConnection>(std::move(remote)));
return JLocalConnection::newObjectCxxArgs(std::move(localConnection));
}
@@ -12,7 +12,8 @@
#include <jsinspector/InspectorInterfaces.h>
#include <fb/fbjni.h>
#include <folly/Memory.h>
#include <memory>
namespace facebook {
namespace react {
@@ -12,7 +12,6 @@
#include <fb/fbjni.h>
#include <fb/log.h>
#include <folly/Memory.h>
#include <jsi/jsi.h>
#include "JNativeRunnable.h"
@@ -12,8 +12,8 @@
#include <fb/fbjni.h>
#include <fb/log.h>
#include <folly/Conv.h>
#include <folly/Memory.h>
#include <fstream>
#include <memory>
#include <sstream>
#include <streambuf>
#include <string>
@@ -48,7 +48,7 @@ std::unique_ptr<const JSBigString> loadScriptFromAssets(
assetName.c_str(),
AASSET_MODE_STREAMING); // Optimized for sequential read: see AssetManager.java for docs
if (asset) {
auto buf = folly::make_unique<JSBigBufferString>(AAsset_getLength(asset));
auto buf = std::make_unique<JSBigBufferString>(AAsset_getLength(asset));
size_t offset = 0;
int readbytes;
while ((readbytes = AAsset_read(asset, buf->data() + offset, buf->size() - offset)) > 0) {
@@ -15,8 +15,6 @@
#include <sys/endian.h>
#include <utility>
#include <folly/Memory.h>
using magic_number_t = uint32_t;
const magic_number_t MAGIC_FILE_HEADER = 0xFB0BD1E5;
const char* MAGIC_FILE_NAME = "UNBUNDLE";
@@ -46,7 +44,7 @@ static asset_ptr openAsset(
std::unique_ptr<JniJSModulesUnbundle> JniJSModulesUnbundle::fromEntryFile(
AAssetManager *assetManager,
const std::string& entryFile) {
return folly::make_unique<JniJSModulesUnbundle>(assetManager, jsModulesDir(entryFile));
return std::make_unique<JniJSModulesUnbundle>(assetManager, jsModulesDir(entryFile));
}
JniJSModulesUnbundle::JniJSModulesUnbundle(AAssetManager *assetManager, const std::string& moduleDirectory) :
@@ -7,11 +7,11 @@
#include "ModuleRegistryBuilder.h"
#include <memory>
#include <string>
#include <glog/logging.h>
#include <cxxreact/CxxNativeModule.h>
#include <folly/Memory.h>
namespace facebook {
namespace react {
@@ -47,14 +47,14 @@ std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
std::vector<std::unique_ptr<NativeModule>> modules;
if (javaModules) {
for (const auto& jm : *javaModules) {
modules.emplace_back(folly::make_unique<JavaNativeModule>(
modules.emplace_back(std::make_unique<JavaNativeModule>(
winstance, jm, moduleMessageQueue));
}
}
if (cxxModules) {
for (const auto& cm : *cxxModules) {
std::string moduleName = cm->getName();
modules.emplace_back(folly::make_unique<CxxNativeModule>(
modules.emplace_back(std::make_unique<CxxNativeModule>(
winstance, moduleName, cm->getProvider(moduleName), moduleMessageQueue));
}
}
@@ -13,10 +13,11 @@
#include <fb/assert.h>
#include <fb/Environment.h>
#include <folly/json.h>
#include <folly/Memory.h>
#include <jni/LocalReference.h>
#include <jni/LocalString.h>
#include <memory>
namespace facebook {
namespace react {
@@ -38,7 +39,7 @@ static std::string executeJSCallWithProxy(
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate, std::shared_ptr<MessageQueueThread>) {
return folly::make_unique<ProxyExecutor>(std::move(m_executor), delegate);
return std::make_unique<ProxyExecutor>(std::move(m_executor), delegate);
}
ProxyExecutor::ProxyExecutor(jni::global_ref<jobject>&& executorInstance,
@@ -74,7 +75,7 @@ void ProxyExecutor::loadApplicationScript(
SystraceSection t("setGlobalVariable");
setGlobalVariable(
"__fbBatchedBridgeConfig",
folly::make_unique<JSBigStdString>(folly::toJson(config)));
std::make_unique<JSBigStdString>(folly::toJson(config)));
}
static auto loadApplicationScript =
+77 -61
View File
@@ -18,7 +18,6 @@
#include "SystraceSection.h"
#include <cxxreact/JSIndexedRAMBundle.h>
#include <folly/Memory.h>
#include <folly/MoveWrapper.h>
#include <folly/json.h>
@@ -26,6 +25,7 @@
#include <condition_variable>
#include <fstream>
#include <memory>
#include <mutex>
#include <string>
@@ -46,7 +46,7 @@ void Instance::initializeBridge(
callback_ = std::move(callback);
moduleRegistry_ = std::move(moduleRegistry);
jsQueue->runOnQueueSync([this, &jsef, jsQueue]() mutable {
nativeToJsBridge_ = folly::make_unique<NativeToJsBridge>(
nativeToJsBridge_ = std::make_unique<NativeToJsBridge>(
jsef.get(), moduleRegistry_, jsQueue, callback_);
std::lock_guard<std::mutex> lock(m_syncMutex);
@@ -57,26 +57,26 @@ void Instance::initializeBridge(
CHECK(nativeToJsBridge_);
}
void Instance::loadApplication(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
void Instance::loadApplication(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
callback_->incrementPendingJSCalls();
SystraceSection s("Instance::loadApplication", "sourceURL",
sourceURL);
nativeToJsBridge_->loadApplication(std::move(bundleRegistry), std::move(string),
std::move(sourceURL));
SystraceSection s("Instance::loadApplication", "sourceURL", sourceURL);
nativeToJsBridge_->loadApplication(
std::move(bundleRegistry), std::move(string), std::move(sourceURL));
}
void Instance::loadApplicationSync(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
void Instance::loadApplicationSync(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
std::unique_lock<std::mutex> lock(m_syncMutex);
m_syncCV.wait(lock, [this] { return m_syncReady; });
SystraceSection s("Instance::loadApplicationSync", "sourceURL",
sourceURL);
nativeToJsBridge_->loadApplicationSync(std::move(bundleRegistry), std::move(string),
std::move(sourceURL));
SystraceSection s("Instance::loadApplicationSync", "sourceURL", sourceURL);
nativeToJsBridge_->loadApplicationSync(
std::move(bundleRegistry), std::move(string), std::move(sourceURL));
}
void Instance::setSourceURL(std::string sourceURL) {
@@ -86,11 +86,11 @@ void Instance::setSourceURL(std::string sourceURL) {
nativeToJsBridge_->loadApplication(nullptr, nullptr, std::move(sourceURL));
}
void Instance::loadScriptFromString(std::unique_ptr<const JSBigString> string,
std::string sourceURL,
bool loadSynchronously) {
SystraceSection s("Instance::loadScriptFromString", "sourceURL",
sourceURL);
void Instance::loadScriptFromString(
std::unique_ptr<const JSBigString> string,
std::string sourceURL,
bool loadSynchronously) {
SystraceSection s("Instance::loadScriptFromString", "sourceURL", sourceURL);
if (loadSynchronously) {
loadApplicationSync(nullptr, std::move(string), std::move(sourceURL));
} else {
@@ -110,54 +110,63 @@ bool Instance::isIndexedRAMBundle(const char *sourcePath) {
return parseTypeFromHeader(header) == ScriptTag::RAMBundle;
}
bool Instance::isIndexedRAMBundle(std::unique_ptr<const JSBigString>* script) {
bool Instance::isIndexedRAMBundle(std::unique_ptr<const JSBigString> *script) {
BundleHeader header;
strncpy(reinterpret_cast<char *>(&header), script->get()->c_str(), sizeof(header));
strncpy(
reinterpret_cast<char *>(&header),
script->get()->c_str(),
sizeof(header));
return parseTypeFromHeader(header) == ScriptTag::RAMBundle;
}
void Instance::loadRAMBundleFromString(std::unique_ptr<const JSBigString> script, const std::string& sourceURL) {
auto bundle = folly::make_unique<JSIndexedRAMBundle>(std::move(script));
void Instance::loadRAMBundleFromString(
std::unique_ptr<const JSBigString> script,
const std::string &sourceURL) {
auto bundle = std::make_unique<JSIndexedRAMBundle>(std::move(script));
auto startupScript = bundle->getStartupCode();
auto registry = RAMBundleRegistry::singleBundleRegistry(std::move(bundle));
loadRAMBundle(
std::move(registry),
std::move(startupScript),
sourceURL,
true);
loadRAMBundle(std::move(registry), std::move(startupScript), sourceURL, true);
}
void Instance::loadRAMBundleFromFile(const std::string& sourcePath,
const std::string& sourceURL,
bool loadSynchronously) {
auto bundle = folly::make_unique<JSIndexedRAMBundle>(sourcePath.c_str());
auto startupScript = bundle->getStartupCode();
auto registry = RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory());
loadRAMBundle(
void Instance::loadRAMBundleFromFile(
const std::string &sourcePath,
const std::string &sourceURL,
bool loadSynchronously) {
auto bundle = std::make_unique<JSIndexedRAMBundle>(sourcePath.c_str());
auto startupScript = bundle->getStartupCode();
auto registry = RAMBundleRegistry::multipleBundlesRegistry(
std::move(bundle), JSIndexedRAMBundle::buildFactory());
loadRAMBundle(
std::move(registry),
std::move(startupScript),
sourceURL,
loadSynchronously);
}
void Instance::loadRAMBundle(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL,
bool loadSynchronously) {
void Instance::loadRAMBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL,
bool loadSynchronously) {
if (loadSynchronously) {
loadApplicationSync(std::move(bundleRegistry), std::move(startupScript),
std::move(startupScriptSourceURL));
loadApplicationSync(
std::move(bundleRegistry),
std::move(startupScript),
std::move(startupScriptSourceURL));
} else {
loadApplication(std::move(bundleRegistry), std::move(startupScript),
std::move(startupScriptSourceURL));
loadApplication(
std::move(bundleRegistry),
std::move(startupScript),
std::move(startupScriptSourceURL));
}
}
void Instance::setGlobalVariable(std::string propName,
std::unique_ptr<const JSBigString> jsonValue) {
nativeToJsBridge_->setGlobalVariable(std::move(propName),
std::move(jsonValue));
void Instance::setGlobalVariable(
std::string propName,
std::unique_ptr<const JSBigString> jsonValue) {
nativeToJsBridge_->setGlobalVariable(
std::move(propName), std::move(jsonValue));
}
void *Instance::getJavaScriptContext() {
@@ -168,16 +177,18 @@ void *Instance::getJavaScriptContext() {
bool Instance::isInspectable() {
return nativeToJsBridge_ ? nativeToJsBridge_->isInspectable() : false;
}
bool Instance::isBatchActive() {
return nativeToJsBridge_ ? nativeToJsBridge_->isBatchActive() : false;
}
void Instance::callJSFunction(std::string &&module, std::string &&method,
folly::dynamic &&params) {
void Instance::callJSFunction(
std::string &&module,
std::string &&method,
folly::dynamic &&params) {
callback_->incrementPendingJSCalls();
nativeToJsBridge_->callFunction(std::move(module), std::move(method),
std::move(params));
nativeToJsBridge_->callFunction(
std::move(module), std::move(method), std::move(params));
}
void Instance::callJSCallback(uint64_t callbackId, folly::dynamic &&params) {
@@ -186,7 +197,9 @@ void Instance::callJSCallback(uint64_t callbackId, folly::dynamic &&params) {
nativeToJsBridge_->invokeCallback((double)callbackId, std::move(params));
}
void Instance::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
void Instance::registerBundle(
uint32_t bundleId,
const std::string &bundlePath) {
nativeToJsBridge_->registerBundle(bundleId, bundlePath);
}
@@ -194,17 +207,20 @@ const ModuleRegistry &Instance::getModuleRegistry() const {
return *moduleRegistry_;
}
ModuleRegistry &Instance::getModuleRegistry() { return *moduleRegistry_; }
ModuleRegistry &Instance::getModuleRegistry() {
return *moduleRegistry_;
}
void Instance::handleMemoryPressure(int pressureLevel) {
nativeToJsBridge_->handleMemoryPressure(pressureLevel);
}
void Instance::invokeAsync(std::function<void()>&& func) {
nativeToJsBridge_->runOnExecutorQueue([func=std::move(func)](JSExecutor *executor) {
func();
executor->flush();
});
void Instance::invokeAsync(std::function<void()> &&func) {
nativeToJsBridge_->runOnExecutorQueue(
[func = std::move(func)](JSExecutor *executor) {
func();
executor->flush();
});
}
} // namespace react
+3 -1
View File
@@ -16,6 +16,8 @@
#include <folly/portability/SysStat.h>
#include <folly/portability/Unistd.h>
#include <memory>
namespace facebook {
namespace react {
@@ -148,7 +150,7 @@ std::unique_ptr<const JSBigFileString> JSBigFileString::fromPath(
struct stat fileInfo;
folly::checkUnixError(::fstat(fd, &fileInfo), "fstat on bundle failed.");
return folly::make_unique<const JSBigFileString>(fd, fileInfo.st_size);
return std::make_unique<const JSBigFileString>(fd, fileInfo.st_size);
}
} // namespace react
+13 -14
View File
@@ -7,25 +7,24 @@
#include "JSDeltaBundleClient.h"
#include <memory>
#include <sstream>
#include <folly/Memory.h>
namespace facebook {
namespace react {
namespace {
std::string startupCode(const folly::dynamic *pre, const folly::dynamic *post) {
std::ostringstream startupCode;
std::string startupCode(const folly::dynamic *pre, const folly::dynamic *post) {
std::ostringstream startupCode;
for (auto section : {pre, post}) {
if (section != nullptr) {
startupCode << section->getString() << '\n';
}
for (auto section : {pre, post}) {
if (section != nullptr) {
startupCode << section->getString() << '\n';
}
return startupCode.str();
}
return startupCode.str();
}
} // namespace
void JSDeltaBundleClient::patchModules(const folly::dynamic *modules) {
@@ -36,7 +35,7 @@ void JSDeltaBundleClient::patchModules(const folly::dynamic *modules) {
}
}
void JSDeltaBundleClient::patch(const folly::dynamic& delta) {
void JSDeltaBundleClient::patch(const folly::dynamic &delta) {
auto const base = delta.get_ptr("base");
if (base != nullptr && base->asBool()) {
@@ -76,10 +75,10 @@ void JSDeltaBundleClient::patch(const folly::dynamic& delta) {
patchModules(modified);
}
}
}
JSModulesUnbundle::Module JSDeltaBundleClient::getModule(uint32_t moduleId) const {
JSModulesUnbundle::Module JSDeltaBundleClient::getModule(
uint32_t moduleId) const {
auto search = modules_.find(moduleId);
if (search != modules_.end()) {
return {folly::to<std::string>(search->first, ".js"), search->second};
@@ -89,7 +88,7 @@ JSModulesUnbundle::Module JSDeltaBundleClient::getModule(uint32_t moduleId) cons
}
std::unique_ptr<const JSBigString> JSDeltaBundleClient::getStartupCode() const {
return folly::make_unique<JSBigStdString>(startupCode_);
return std::make_unique<JSBigStdString>(startupCode_);
}
void JSDeltaBundleClient::clear() {
+37 -28
View File
@@ -9,37 +9,39 @@
#include <glog/logging.h>
#include <fstream>
#include <memory>
#include <sstream>
#include <folly/Memory.h>
namespace facebook {
namespace react {
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> JSIndexedRAMBundle::buildFactory() {
return [](const std::string& bundlePath){
return folly::make_unique<JSIndexedRAMBundle>(bundlePath.c_str());
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)>
JSIndexedRAMBundle::buildFactory() {
return [](const std::string &bundlePath) {
return std::make_unique<JSIndexedRAMBundle>(bundlePath.c_str());
};
}
JSIndexedRAMBundle::JSIndexedRAMBundle(const char *sourcePath) {
m_bundle = std::make_unique<std::ifstream>(sourcePath, std::ifstream::binary);
if (!m_bundle) {
throw std::ios_base::failure(
folly::to<std::string>("Bundle ", sourcePath,
"cannot be opened: ", m_bundle->rdstate()));
throw std::ios_base::failure(folly::to<std::string>(
"Bundle ", sourcePath, "cannot be opened: ", m_bundle->rdstate()));
}
init();
}
JSIndexedRAMBundle::JSIndexedRAMBundle(std::unique_ptr<const JSBigString> script) {
JSIndexedRAMBundle::JSIndexedRAMBundle(
std::unique_ptr<const JSBigString> script) {
// tmpStream is needed because m_bundle is std::istream type
// which has no member 'write'
std::unique_ptr<std::stringstream> tmpStream = std::make_unique<std::stringstream>();
std::unique_ptr<std::stringstream> tmpStream =
std::make_unique<std::stringstream>();
tmpStream->write(script->c_str(), script->size());
m_bundle = std::move(tmpStream);
if (!m_bundle) {
throw std::ios_base::failure(
folly::to<std::string>("Bundle from string cannot be opened: ", m_bundle->rdstate()));
throw std::ios_base::failure(folly::to<std::string>(
"Bundle from string cannot be opened: ", m_bundle->rdstate()));
}
init();
}
@@ -48,8 +50,8 @@ void JSIndexedRAMBundle::init() {
// read in magic header, number of entries, and length of the startup section
uint32_t header[3];
static_assert(
sizeof(header) == 12,
"header size must exactly match the input file format");
sizeof(header) == 12,
"header size must exactly match the input file format");
readBundle(reinterpret_cast<char *>(header), sizeof(header));
const size_t numTableEntries = folly::Endian::little(header[1]);
@@ -61,15 +63,17 @@ void JSIndexedRAMBundle::init() {
// read the lookup table from the file
readBundle(
reinterpret_cast<char *>(m_table.data.get()), m_table.byteLength());
reinterpret_cast<char *>(m_table.data.get()), m_table.byteLength());
// read the startup code
m_startupCode = std::unique_ptr<JSBigBufferString>(new JSBigBufferString{startupCodeSize - 1});
m_startupCode = std::unique_ptr<JSBigBufferString>(
new JSBigBufferString{startupCodeSize - 1});
readBundle(m_startupCode->data(), startupCodeSize - 1);
}
JSIndexedRAMBundle::Module JSIndexedRAMBundle::getModule(uint32_t moduleId) const {
JSIndexedRAMBundle::Module JSIndexedRAMBundle::getModule(
uint32_t moduleId) const {
Module ret;
ret.name = folly::to<std::string>(moduleId, ".js");
ret.code = getModuleCode(moduleId);
@@ -77,7 +81,8 @@ JSIndexedRAMBundle::Module JSIndexedRAMBundle::getModule(uint32_t moduleId) cons
}
std::unique_ptr<const JSBigString> JSIndexedRAMBundle::getStartupCode() {
CHECK(m_startupCode) << "startup code for a RAM Bundle can only be retrieved once";
CHECK(m_startupCode)
<< "startup code for a RAM Bundle can only be retrieved once";
return std::move(m_startupCode);
}
@@ -85,24 +90,29 @@ std::string JSIndexedRAMBundle::getModuleCode(const uint32_t id) const {
const auto moduleData = id < m_table.numEntries ? &m_table.data[id] : nullptr;
// entries without associated code have offset = 0 and length = 0
const uint32_t length = moduleData ? folly::Endian::little(moduleData->length) : 0;
const uint32_t length =
moduleData ? folly::Endian::little(moduleData->length) : 0;
if (length == 0) {
throw std::ios_base::failure(
folly::to<std::string>("Error loading module", id, "from RAM Bundle"));
folly::to<std::string>("Error loading module", id, "from RAM Bundle"));
}
std::string ret(length - 1, '\0');
readBundle(&ret.front(), length - 1, m_baseOffset + folly::Endian::little(moduleData->offset));
readBundle(
&ret.front(),
length - 1,
m_baseOffset + folly::Endian::little(moduleData->offset));
return ret;
}
void JSIndexedRAMBundle::readBundle(char *buffer, const std::streamsize bytes) const {
void JSIndexedRAMBundle::readBundle(char *buffer, const std::streamsize bytes)
const {
if (!m_bundle->read(buffer, bytes)) {
if (m_bundle->rdstate() & std::ios::eofbit) {
throw std::ios_base::failure("Unexpected end of RAM Bundle file");
}
throw std::ios_base::failure(
folly::to<std::string>("Error reading RAM Bundle: ", m_bundle->rdstate()));
throw std::ios_base::failure(folly::to<std::string>(
"Error reading RAM Bundle: ", m_bundle->rdstate()));
}
}
@@ -110,13 +120,12 @@ void JSIndexedRAMBundle::readBundle(
char *buffer,
const std::streamsize bytes,
const std::ifstream::pos_type position) const {
if (!m_bundle->seekg(position)) {
throw std::ios_base::failure(
folly::to<std::string>("Error reading RAM Bundle: ", m_bundle->rdstate()));
throw std::ios_base::failure(folly::to<std::string>(
"Error reading RAM Bundle: ", m_bundle->rdstate()));
}
readBundle(buffer, bytes);
}
} // namespace react
} // namespace facebook
} // namespace react
} // namespace facebook
+139 -119
View File
@@ -7,18 +7,19 @@
#include "NativeToJsBridge.h"
#include <folly/json.h>
#include <folly/Memory.h>
#include <folly/MoveWrapper.h>
#include <folly/json.h>
#include <glog/logging.h>
#include "Instance.h"
#include "JSBigString.h"
#include "SystraceSection.h"
#include "MethodCall.h"
#include "MessageQueueThread.h"
#include "MethodCall.h"
#include "ModuleRegistry.h"
#include "RAMBundleRegistry.h"
#include "SystraceSection.h"
#include <memory>
#ifdef WITH_FBSYSTRACE
#include <fbsystrace.h>
@@ -30,37 +31,40 @@ namespace react {
// This class manages calls from JS to native code.
class JsToNativeBridge : public react::ExecutorDelegate {
public:
JsToNativeBridge(std::shared_ptr<ModuleRegistry> registry,
std::shared_ptr<InstanceCallback> callback)
: m_registry(registry)
, m_callback(callback) {}
public:
JsToNativeBridge(
std::shared_ptr<ModuleRegistry> registry,
std::shared_ptr<InstanceCallback> callback)
: m_registry(registry), m_callback(callback) {}
std::shared_ptr<ModuleRegistry> getModuleRegistry() override {
return m_registry;
}
bool isBatchActive() {
return m_batchHadNativeModuleCalls;
}
void callNativeModules(
__unused JSExecutor& executor, folly::dynamic&& calls, bool isEndOfBatch) override {
CHECK(m_registry || calls.empty()) <<
"native module calls cannot be completed with no native modules";
__unused JSExecutor &executor,
folly::dynamic &&calls,
bool isEndOfBatch) override {
CHECK(m_registry || calls.empty())
<< "native module calls cannot be completed with no native modules";
m_batchHadNativeModuleCalls = m_batchHadNativeModuleCalls || !calls.empty();
// An exception anywhere in here stops processing of the batch. This
// was the behavior of the Android bridge, and since exception handling
// terminates the whole bridge, there's not much point in continuing.
for (auto& call : parseMethodCalls(std::move(calls))) {
m_registry->callNativeMethod(call.moduleId, call.methodId, std::move(call.arguments), call.callId);
for (auto &call : parseMethodCalls(std::move(calls))) {
m_registry->callNativeMethod(
call.moduleId, call.methodId, std::move(call.arguments), call.callId);
}
if (isEndOfBatch) {
// onBatchComplete will be called on the native (module) queue, but
// decrementPendingJSCalls will be called sync. Be aware that the bridge may still
// be processing native calls when the bridge idle signaler fires.
// decrementPendingJSCalls will be called sync. Be aware that the bridge
// may still be processing native calls when the bridge idle signaler
// fires.
if (m_batchHadNativeModuleCalls) {
m_callback->onBatchComplete();
m_batchHadNativeModuleCalls = false;
@@ -70,13 +74,15 @@ public:
}
MethodCallResult callSerializableNativeHook(
__unused JSExecutor& executor, unsigned int moduleId, unsigned int methodId,
folly::dynamic&& args) override {
return m_registry->callSerializableNativeHook(moduleId, methodId, std::move(args));
__unused JSExecutor &executor,
unsigned int moduleId,
unsigned int methodId,
folly::dynamic &&args) override {
return m_registry->callSerializableNativeHook(
moduleId, methodId, std::move(args));
}
private:
private:
// These methods are always invoked from an Executor. The NativeToJsBridge
// keeps a reference to the executor, and when destroy() is called, the
// executor is destroyed synchronously on its queue.
@@ -98,33 +104,32 @@ NativeToJsBridge::NativeToJsBridge(
// This must be called on the same thread on which the constructor was called.
NativeToJsBridge::~NativeToJsBridge() {
CHECK(*m_destroyed) <<
"NativeToJsBridge::destroy() must be called before deallocating the NativeToJsBridge!";
CHECK(*m_destroyed)
<< "NativeToJsBridge::destroy() must be called before deallocating the NativeToJsBridge!";
}
void NativeToJsBridge::loadApplication(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL) {
runOnExecutorQueue(
[this,
bundleRegistryWrap=folly::makeMoveWrapper(std::move(bundleRegistry)),
startupScript=folly::makeMoveWrapper(std::move(startupScript)),
startupScriptSourceURL=std::move(startupScriptSourceURL)]
(JSExecutor* executor) mutable {
auto bundleRegistry = bundleRegistryWrap.move();
if (bundleRegistry) {
executor->setBundleRegistry(std::move(bundleRegistry));
}
try {
executor->loadApplicationScript(std::move(*startupScript),
std::move(startupScriptSourceURL));
} catch (...) {
m_applicationScriptHasFailure = true;
throw;
}
});
bundleRegistryWrap = folly::makeMoveWrapper(std::move(bundleRegistry)),
startupScript = folly::makeMoveWrapper(std::move(startupScript)),
startupScriptSourceURL =
std::move(startupScriptSourceURL)](JSExecutor *executor) mutable {
auto bundleRegistry = bundleRegistryWrap.move();
if (bundleRegistry) {
executor->setBundleRegistry(std::move(bundleRegistry));
}
try {
executor->loadApplicationScript(
std::move(*startupScript), std::move(startupScriptSourceURL));
} catch (...) {
m_applicationScriptHasFailure = true;
throw;
}
});
}
void NativeToJsBridge::loadApplicationSync(
@@ -135,8 +140,8 @@ void NativeToJsBridge::loadApplicationSync(
m_executor->setBundleRegistry(std::move(bundleRegistry));
}
try {
m_executor->loadApplicationScript(std::move(startupScript),
std::move(startupScriptSourceURL));
m_executor->loadApplicationScript(
std::move(startupScript), std::move(startupScriptSourceURL));
} catch (...) {
m_applicationScriptHasFailure = true;
throw;
@@ -144,99 +149,110 @@ void NativeToJsBridge::loadApplicationSync(
}
void NativeToJsBridge::callFunction(
std::string&& module,
std::string&& method,
folly::dynamic&& arguments) {
std::string &&module,
std::string &&method,
folly::dynamic &&arguments) {
int systraceCookie = -1;
#ifdef WITH_FBSYSTRACE
#ifdef WITH_FBSYSTRACE
systraceCookie = m_systraceCookie++;
FbSystraceAsyncFlow::begin(
TRACE_TAG_REACT_CXX_BRIDGE,
"JSCall",
systraceCookie);
#endif
TRACE_TAG_REACT_CXX_BRIDGE, "JSCall", systraceCookie);
#endif
runOnExecutorQueue([this, module = std::move(module), method = std::move(method), arguments = std::move(arguments), systraceCookie]
(JSExecutor* executor) {
if (m_applicationScriptHasFailure) {
LOG(ERROR) << "Attempting to call JS function on a bad application bundle: " << module.c_str() << "." << method.c_str() << "()";
throw std::runtime_error("Attempting to call JS function on a bad application bundle: " + module + "." + method + "()");
}
runOnExecutorQueue([this,
module = std::move(module),
method = std::move(method),
arguments = std::move(arguments),
systraceCookie](JSExecutor *executor) {
if (m_applicationScriptHasFailure) {
LOG(ERROR)
<< "Attempting to call JS function on a bad application bundle: "
<< module.c_str() << "." << method.c_str() << "()";
throw std::runtime_error(
"Attempting to call JS function on a bad application bundle: " +
module + "." + method + "()");
}
#ifdef WITH_FBSYSTRACE
FbSystraceAsyncFlow::end(
TRACE_TAG_REACT_CXX_BRIDGE,
"JSCall",
systraceCookie);
SystraceSection s("NativeToJsBridge::callFunction", "module", module, "method", method);
#else
(void)(systraceCookie);
#endif
// This is safe because we are running on the executor's thread: it won't
// destruct until after it's been unregistered (which we check above) and
// that will happen on this thread
executor->callFunction(module, method, arguments);
});
#ifdef WITH_FBSYSTRACE
FbSystraceAsyncFlow::end(
TRACE_TAG_REACT_CXX_BRIDGE, "JSCall", systraceCookie);
SystraceSection s(
"NativeToJsBridge::callFunction", "module", module, "method", method);
#else
(void)(systraceCookie);
#endif
// This is safe because we are running on the executor's thread: it won't
// destruct until after it's been unregistered (which we check above) and
// that will happen on this thread
executor->callFunction(module, method, arguments);
});
}
void NativeToJsBridge::invokeCallback(double callbackId, folly::dynamic&& arguments) {
void NativeToJsBridge::invokeCallback(
double callbackId,
folly::dynamic &&arguments) {
int systraceCookie = -1;
#ifdef WITH_FBSYSTRACE
#ifdef WITH_FBSYSTRACE
systraceCookie = m_systraceCookie++;
FbSystraceAsyncFlow::begin(
TRACE_TAG_REACT_CXX_BRIDGE,
"<callback>",
systraceCookie);
#endif
TRACE_TAG_REACT_CXX_BRIDGE, "<callback>", systraceCookie);
#endif
runOnExecutorQueue([this, callbackId, arguments = std::move(arguments), systraceCookie]
(JSExecutor* executor) {
if (m_applicationScriptHasFailure) {
LOG(ERROR) << "Attempting to call JS callback on a bad application bundle: " << callbackId;
throw std::runtime_error("Attempting to invoke JS callback on a bad application bundle.");
}
#ifdef WITH_FBSYSTRACE
FbSystraceAsyncFlow::end(
TRACE_TAG_REACT_CXX_BRIDGE,
"<callback>",
systraceCookie);
SystraceSection s("NativeToJsBridge::invokeCallback");
#else
(void)(systraceCookie);
#endif
executor->invokeCallback(callbackId, arguments);
});
runOnExecutorQueue(
[this, callbackId, arguments = std::move(arguments), systraceCookie](
JSExecutor *executor) {
if (m_applicationScriptHasFailure) {
LOG(ERROR)
<< "Attempting to call JS callback on a bad application bundle: "
<< callbackId;
throw std::runtime_error(
"Attempting to invoke JS callback on a bad application bundle.");
}
#ifdef WITH_FBSYSTRACE
FbSystraceAsyncFlow::end(
TRACE_TAG_REACT_CXX_BRIDGE, "<callback>", systraceCookie);
SystraceSection s("NativeToJsBridge::invokeCallback");
#else
(void)(systraceCookie);
#endif
executor->invokeCallback(callbackId, arguments);
});
}
void NativeToJsBridge::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
runOnExecutorQueue([bundleId, bundlePath] (JSExecutor* executor) {
void NativeToJsBridge::registerBundle(
uint32_t bundleId,
const std::string &bundlePath) {
runOnExecutorQueue([bundleId, bundlePath](JSExecutor *executor) {
executor->registerBundle(bundleId, bundlePath);
});
}
void NativeToJsBridge::setGlobalVariable(std::string propName,
std::unique_ptr<const JSBigString> jsonValue) {
runOnExecutorQueue([propName=std::move(propName), jsonValue=folly::makeMoveWrapper(std::move(jsonValue))]
(JSExecutor* executor) mutable {
executor->setGlobalVariable(propName, jsonValue.move());
});
void NativeToJsBridge::setGlobalVariable(
std::string propName,
std::unique_ptr<const JSBigString> jsonValue) {
runOnExecutorQueue([propName = std::move(propName),
jsonValue = folly::makeMoveWrapper(std::move(jsonValue))](
JSExecutor *executor) mutable {
executor->setGlobalVariable(propName, jsonValue.move());
});
}
void* NativeToJsBridge::getJavaScriptContext() {
// TODO(cjhopman): this seems unsafe unless we require that it is only called on the main js queue.
void *NativeToJsBridge::getJavaScriptContext() {
// TODO(cjhopman): this seems unsafe unless we require that it is only called
// on the main js queue.
return m_executor->getJavaScriptContext();
}
bool NativeToJsBridge::isInspectable() {
return m_inspectable;
}
bool NativeToJsBridge::isBatchActive() {
return m_delegate->isBatchActive();
}
void NativeToJsBridge::handleMemoryPressure(int pressureLevel) {
runOnExecutorQueue([=] (JSExecutor* executor) {
runOnExecutorQueue([=](JSExecutor *executor) {
executor->handleMemoryPressure(pressureLevel);
});
}
@@ -253,23 +269,27 @@ void NativeToJsBridge::destroy() {
});
}
void NativeToJsBridge::runOnExecutorQueue(std::function<void(JSExecutor*)> task) {
void NativeToJsBridge::runOnExecutorQueue(
std::function<void(JSExecutor *)> task) {
if (*m_destroyed) {
return;
}
std::shared_ptr<bool> isDestroyed = m_destroyed;
m_executorMessageQueueThread->runOnQueue([this, isDestroyed, task=std::move(task)] {
if (*isDestroyed) {
return;
}
m_executorMessageQueueThread->runOnQueue(
[this, isDestroyed, task = std::move(task)] {
if (*isDestroyed) {
return;
}
// The executor is guaranteed to be valid for the duration of the task because:
// 1. the executor is only destroyed after it is unregistered
// 2. the executor is unregistered on this queue
// 3. we just confirmed that the executor hasn't been unregistered above
task(m_executor.get());
});
// The executor is guaranteed to be valid for the duration of the task
// because:
// 1. the executor is only destroyed after it is unregistered
// 2. the executor is unregistered on this queue
// 3. we just confirmed that the executor hasn't been unregistered above
task(m_executor.get());
});
}
} }
} // namespace react
} // namespace facebook
+19 -18
View File
@@ -7,9 +7,10 @@
#include "RAMBundleRegistry.h"
#include <folly/Memory.h>
#include <folly/String.h>
#include <memory>
namespace facebook {
namespace react {
@@ -17,44 +18,44 @@ constexpr uint32_t RAMBundleRegistry::MAIN_BUNDLE_ID;
std::unique_ptr<RAMBundleRegistry> RAMBundleRegistry::singleBundleRegistry(
std::unique_ptr<JSModulesUnbundle> mainBundle) {
return folly::make_unique<RAMBundleRegistry>(std::move(mainBundle));
return std::make_unique<RAMBundleRegistry>(std::move(mainBundle));
}
std::unique_ptr<RAMBundleRegistry> RAMBundleRegistry::multipleBundlesRegistry(
std::unique_ptr<JSModulesUnbundle> mainBundle,
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory) {
return folly::make_unique<RAMBundleRegistry>(
return std::make_unique<RAMBundleRegistry>(
std::move(mainBundle), std::move(factory));
}
RAMBundleRegistry::RAMBundleRegistry(
std::unique_ptr<JSModulesUnbundle> mainBundle,
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory):
m_factory(std::move(factory)) {
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory)
: m_factory(std::move(factory)) {
m_bundles.emplace(MAIN_BUNDLE_ID, std::move(mainBundle));
}
void RAMBundleRegistry::registerBundle(
uint32_t bundleId, std::string bundlePath) {
uint32_t bundleId,
std::string bundlePath) {
m_bundlePaths.emplace(bundleId, std::move(bundlePath));
}
JSModulesUnbundle::Module RAMBundleRegistry::getModule(
uint32_t bundleId, uint32_t moduleId) {
uint32_t bundleId,
uint32_t moduleId) {
if (m_bundles.find(bundleId) == m_bundles.end()) {
if (!m_factory) {
throw std::runtime_error(
"You need to register factory function in order to "
"support multiple RAM bundles."
);
"You need to register factory function in order to "
"support multiple RAM bundles.");
}
auto bundlePath = m_bundlePaths.find(bundleId);
if (bundlePath == m_bundlePaths.end()) {
throw std::runtime_error(
"In order to fetch RAM bundle from the registry, its file "
"path needs to be registered first."
);
"In order to fetch RAM bundle from the registry, its file "
"path needs to be registered first.");
}
m_bundles.emplace(bundleId, m_factory(bundlePath->second));
}
@@ -64,14 +65,14 @@ JSModulesUnbundle::Module RAMBundleRegistry::getModule(
return module;
}
return {
folly::to<std::string>("seg-", bundleId, '_', std::move(module.name)),
std::move(module.code),
folly::to<std::string>("seg-", bundleId, '_', std::move(module.name)),
std::move(module.code),
};
}
JSModulesUnbundle* RAMBundleRegistry::getBundle(uint32_t bundleId) const {
JSModulesUnbundle *RAMBundleRegistry::getBundle(uint32_t bundleId) const {
return m_bundles.at(bundleId).get();
}
} // namespace react
} // namespace facebook
} // namespace react
} // namespace facebook
+90 -72
View File
@@ -8,14 +8,16 @@
#include "SampleCxxModule.h"
#include <cxxreact/JsArgumentHelpers.h>
#include <folly/Memory.h>
#include <glog/logging.h>
#include <memory>
#include <thread>
using namespace folly;
namespace facebook { namespace xplat { namespace samples {
namespace facebook {
namespace xplat {
namespace samples {
std::string Sample::hello() {
LOG(WARNING) << "glog: hello, world";
@@ -26,11 +28,11 @@ double Sample::add(double a, double b) {
return a + b;
}
std::string Sample::concat(const std::string& a, const std::string& b) {
std::string Sample::concat(const std::string &a, const std::string &b) {
return a + b;
}
std::string Sample::repeat(int count, const std::string& str) {
std::string Sample::repeat(int count, const std::string &str) {
std::string ret;
for (int i = 0; i < count; i++) {
ret += str;
@@ -39,8 +41,7 @@ std::string Sample::repeat(int count, const std::string& str) {
return ret;
}
void Sample::save(std::map<std::string, std::string> dict)
{
void Sample::save(std::map<std::string, std::string> dict) {
state_ = std::move(dict);
}
@@ -49,16 +50,16 @@ std::map<std::string, std::string> Sample::load() {
}
void Sample::except() {
// TODO mhorowitz #7128529: There's no way to automatically test this
// right now.
// TODO mhorowitz #7128529: There's no way to automatically test this
// right now.
// throw std::runtime_error("oops");
}
void Sample::call_later(int msec, std::function<void()> f) {
std::thread t([=] {
std::this_thread::sleep_for(std::chrono::milliseconds(msec));
f();
});
std::this_thread::sleep_for(std::chrono::milliseconds(msec));
f();
});
t.detach();
}
@@ -67,7 +68,7 @@ double Sample::twice(double n) {
}
SampleCxxModule::SampleCxxModule(std::unique_ptr<Sample> sample)
: sample_(std::move(sample)) {}
: sample_(std::move(sample)) {}
std::string SampleCxxModule::getName() {
return "Sample";
@@ -75,90 +76,107 @@ std::string SampleCxxModule::getName() {
auto SampleCxxModule::getConstants() -> std::map<std::string, folly::dynamic> {
return {
{ "one", 1 },
{ "two", 2 },
{ "animal", "fox" },
{"one", 1},
{"two", 2},
{"animal", "fox"},
};
}
auto SampleCxxModule::getMethods() -> std::vector<Method> {
return {
Method("hello", [this] {
sample_->hello();
}),
Method("add", [this](dynamic args, Callback cb) {
LOG(WARNING) << "Sample: add => "
<< sample_->add(jsArgAsDouble(args, 0), jsArgAsDouble(args, 1));
cb({sample_->add(jsArgAsDouble(args, 0), jsArgAsDouble(args, 1))});
}),
Method("concat", [this](dynamic args, Callback cb) {
cb({sample_->concat(jsArgAsString(args, 0),
jsArgAsString(args, 1))});
}),
Method("repeat", [this](dynamic args, Callback cb) {
cb({sample_->repeat((int)jsArgAsInt(args, 0),
jsArgAsString(args, 1))});
}),
Method("save", this, &SampleCxxModule::save),
Method("load", this, &SampleCxxModule::load),
Method("call_later", [this](dynamic args, Callback cb) {
sample_->call_later((int)jsArgAsInt(args, 0), [cb] {
cb({});
});
}),
Method("except", [this] {
sample_->except();
}),
Method("twice", [this](dynamic args) -> dynamic {
return sample_->twice(jsArgAsDouble(args, 0));
}, SyncTag),
Method("syncHello", [this]() -> dynamic {
sample_->hello();
return nullptr;
}, SyncTag),
Method("addIfPositiveAsPromise", [](dynamic args, Callback cb, Callback cbError) {
auto a = jsArgAsDouble(args, 0);
auto b = jsArgAsDouble(args, 1);
if (a < 0 || b < 0) {
cbError({"Negative number!"});
} else {
cb({a + b});
}
}),
Method("addIfPositiveAsAsync", [](dynamic args, Callback cb, Callback cbError) {
auto a = jsArgAsDouble(args, 0);
auto b = jsArgAsDouble(args, 1);
if (a < 0 || b < 0) {
cbError({"Negative number!"});
} else {
cb({a + b});
}
}, AsyncTag),
Method("hello", [this] { sample_->hello(); }),
Method(
"add",
[this](dynamic args, Callback cb) {
LOG(WARNING) << "Sample: add => "
<< sample_->add(
jsArgAsDouble(args, 0), jsArgAsDouble(args, 1));
cb({sample_->add(jsArgAsDouble(args, 0), jsArgAsDouble(args, 1))});
}),
Method(
"concat",
[this](dynamic args, Callback cb) {
cb({sample_->concat(
jsArgAsString(args, 0), jsArgAsString(args, 1))});
}),
Method(
"repeat",
[this](dynamic args, Callback cb) {
cb({sample_->repeat(
(int)jsArgAsInt(args, 0), jsArgAsString(args, 1))});
}),
Method("save", this, &SampleCxxModule::save),
Method("load", this, &SampleCxxModule::load),
Method(
"call_later",
[this](dynamic args, Callback cb) {
sample_->call_later((int)jsArgAsInt(args, 0), [cb] { cb({}); });
}),
Method("except", [this] { sample_->except(); }),
Method(
"twice",
[this](dynamic args) -> dynamic {
return sample_->twice(jsArgAsDouble(args, 0));
},
SyncTag),
Method(
"syncHello",
[this]() -> dynamic {
sample_->hello();
return nullptr;
},
SyncTag),
Method(
"addIfPositiveAsPromise",
[](dynamic args, Callback cb, Callback cbError) {
auto a = jsArgAsDouble(args, 0);
auto b = jsArgAsDouble(args, 1);
if (a < 0 || b < 0) {
cbError({"Negative number!"});
} else {
cb({a + b});
}
}),
Method(
"addIfPositiveAsAsync",
[](dynamic args, Callback cb, Callback cbError) {
auto a = jsArgAsDouble(args, 0);
auto b = jsArgAsDouble(args, 1);
if (a < 0 || b < 0) {
cbError({"Negative number!"});
} else {
cb({a + b});
}
},
AsyncTag),
};
}
void SampleCxxModule::save(folly::dynamic args) {
std::map<std::string, std::string> m;
for (const auto& p : jsArgN(args, 0, &dynamic::items)) {
m.emplace(jsArg(p.first, &dynamic::asString, "map key"),
jsArg(p.second, &dynamic::asString, "map value"));
for (const auto &p : jsArgN(args, 0, &dynamic::items)) {
m.emplace(
jsArg(p.first, &dynamic::asString, "map key"),
jsArg(p.second, &dynamic::asString, "map value"));
}
sample_->save(std::move(m));
}
void SampleCxxModule::load(__unused folly::dynamic args, Callback cb) {
dynamic d = dynamic::object;
for (const auto& p : sample_->load()) {
for (const auto &p : sample_->load()) {
d.insert(p.first, p.second);
}
cb({d});
}
}}}
} // namespace samples
} // namespace xplat
} // namespace facebook
// By convention, the function name should be the same as the class name.
facebook::xplat::module::CxxModule *SampleCxxModule() {
return new facebook::xplat::samples::SampleCxxModule(
folly::make_unique<facebook::xplat::samples::Sample>());
std::make_unique<facebook::xplat::samples::Sample>());
}