first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
/*
* 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.
*/
#import <Foundation/Foundation.h>
#include <cxxreact/JSBigString.h>
namespace facebook::react {
class NSDataBigString : public JSBigString {
public:
// The NSData passed in must be be null-terminated.
NSDataBigString(NSData *data);
// The ASCII optimization is not enabled on iOS
bool isAscii() const override
{
return false;
}
const char *c_str() const override
{
return (const char *)[m_data bytes];
}
size_t size() const override
{
return m_length;
}
private:
NSData *m_data;
size_t m_length;
};
} // namespace facebook::react

View File

@@ -0,0 +1,18 @@
/*
* 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.
*/
#import "NSDataBigString.h"
namespace facebook::react {
NSDataBigString::NSDataBigString(NSData *data)
{
m_data = data;
m_length = [m_data length];
}
} // namespace facebook::react

1573
node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
/*
* 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.
*/
#include <memory>
#import <React/RCTBridgeDelegate.h>
namespace facebook::react {
class JSExecutorFactory;
} // namespace facebook::react
// This is a separate class so non-C++ implementations don't need to
// take a C++ dependency.
@protocol RCTCxxBridgeDelegate <RCTBridgeDelegate>
/**
* In the RCTCxxBridge, if this method is implemented, return a
* ExecutorFactory instance which can be used to create the executor.
* If not implemented, or returns an empty pointer, JSIExecutorFactory
* will be used with a JSCRuntime.
*/
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge;
@end

View File

@@ -0,0 +1,25 @@
/*
* 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
#ifndef RCT_REMOVE_LEGACY_ARCH
#include <jsireact/JSIExecutor.h>
namespace facebook::react {
/**
* Creates a lambda used to bind a JSIRuntime in the context of
* Apple platforms, such as console logging, performance metrics, etc.
*/
[[deprecated("This API will be removed along with the legacy architecture.")]]
JSIExecutor::RuntimeInstaller RCTJSIExecutorRuntimeInstaller(JSIExecutor::RuntimeInstaller runtimeInstallerToWrap);
} // namespace facebook::react
#endif // RCT_REMOVE_LEGACY_ARCH

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
#include "RCTJSIExecutorRuntimeInstaller.h"
#ifndef RCT_REMOVE_LEGACY_ARCH
#import <React/RCTLog.h>
#include <chrono>
namespace facebook::react {
JSIExecutor::RuntimeInstaller RCTJSIExecutorRuntimeInstaller(JSIExecutor::RuntimeInstaller runtimeInstallerToWrap)
{
return [runtimeInstaller = runtimeInstallerToWrap](jsi::Runtime &runtime) {
Logger iosLoggingBinder = [](const std::string &message, unsigned int logLevel) {
_RCTLogJavaScriptInternal(static_cast<RCTLogLevel>(logLevel), [NSString stringWithUTF8String:message.c_str()]);
};
bindNativeLogger(runtime, iosLoggingBinder);
// Wrap over the original runtimeInstaller
if (runtimeInstaller) {
runtimeInstaller(runtime);
}
};
}
} // namespace facebook::react
#endif // RCT_REMOVE_LEGACY_ARCH

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
#import <memory>
#import <string>
#import <Foundation/Foundation.h>
#import <React/RCTJavaScriptExecutor.h>
#import <cxxreact/MessageQueueThread.h>
#import <atomic>
namespace facebook::react {
class RCTMessageThread : public MessageQueueThread, public std::enable_shared_from_this<RCTMessageThread> {
public:
RCTMessageThread(NSRunLoop *runLoop, RCTJavaScriptCompleteBlock errorBlock);
~RCTMessageThread() override;
void runOnQueue(std::function<void()> && /*func*/) override;
void runOnQueueSync(std::function<void()> && /*func*/) override;
void quitSynchronous() override;
void setRunLoop(NSRunLoop *runLoop);
private:
void tryFunc(const std::function<void()> &func);
void runAsync(std::function<void()> func);
void runSync(std::function<void()> func);
CFRunLoopRef m_cfRunLoop;
RCTJavaScriptCompleteBlock m_errorBlock;
std::atomic_bool m_shutdown;
};
} // namespace facebook::react

View File

@@ -0,0 +1,112 @@
/*
* 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.
*/
#include "RCTMessageThread.h"
#include <condition_variable>
#include <mutex>
#import <React/RCTCxxUtils.h>
#import <React/RCTUtils.h>
// A note about the implementation: This class is not used
// generically. It's a thin wrapper around a run loop which
// implements a C++ interface, for use by the C++ xplat bridge code.
// This means it can make certain non-generic assumptions. In
// particular, the sync functions are only used for bridge setup and
// teardown, and quitSynchronous is guaranteed to be called.
namespace facebook::react {
RCTMessageThread::RCTMessageThread(NSRunLoop *runLoop, RCTJavaScriptCompleteBlock errorBlock)
: m_cfRunLoop([runLoop getCFRunLoop]), m_errorBlock(errorBlock), m_shutdown(false)
{
CFRetain(m_cfRunLoop);
}
RCTMessageThread::~RCTMessageThread()
{
RCTAssert(m_shutdown, @"RCTMessageThread: quitSynchronous() not called before destructor");
CFRelease(m_cfRunLoop);
}
// This is analogous to dispatch_async
void RCTMessageThread::runAsync(std::function<void()> func)
{
CFRunLoopPerformBlock(m_cfRunLoop, kCFRunLoopCommonModes, ^{
// Create an autorelease pool each run loop to prevent memory footprint from growing too large, which can lead to
// performance problems.
@autoreleasepool {
func();
}
});
CFRunLoopWakeUp(m_cfRunLoop);
}
// This is analogous to dispatch_sync
void RCTMessageThread::runSync(std::function<void()> func)
{
if (m_cfRunLoop == CFRunLoopGetCurrent()) {
func();
return;
}
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
runAsync([func = std::make_shared<std::function<void()>>(std::move(func)), &sema] {
(*func)();
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
void RCTMessageThread::tryFunc(const std::function<void()> &func)
{
NSError *error = tryAndReturnError(func);
if (error != nullptr) {
m_errorBlock(error);
}
}
void RCTMessageThread::runOnQueue(std::function<void()> &&func)
{
if (m_shutdown) {
return;
}
runAsync([sharedThis = shared_from_this(), func = std::make_shared<std::function<void()>>(std::move(func))] {
if (!sharedThis->m_shutdown) {
sharedThis->tryFunc(*func);
}
});
}
void RCTMessageThread::runOnQueueSync(std::function<void()> &&func)
{
if (m_shutdown) {
return;
}
runSync([sharedThis = shared_from_this(), func = std::move(func)] {
if (!sharedThis->m_shutdown) {
sharedThis->tryFunc(func);
}
});
}
void RCTMessageThread::quitSynchronous()
{
m_shutdown = true;
runSync([] {});
CFRunLoopStop(m_cfRunLoop);
}
void RCTMessageThread::setRunLoop(NSRunLoop *runLoop)
{
CFRelease(m_cfRunLoop);
m_cfRunLoop = [runLoop getCFRunLoop];
CFRetain(m_cfRunLoop);
}
} // namespace facebook::react

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
#ifndef RCT_REMOVE_LEGACY_ARCH
#include <functional>
#include <memory>
#import <React/RCTDefines.h>
#import <React/RCTJavaScriptExecutor.h>
#import <cxxreact/JSExecutor.h>
namespace facebook::react {
class [[deprecated("This API will be removed along with the legacy architecture.")]] RCTObjcExecutorFactory
: public JSExecutorFactory {
public:
RCTObjcExecutorFactory(id<RCTJavaScriptExecutor> jse, RCTJavaScriptCompleteBlock errorBlock);
std::unique_ptr<JSExecutor> createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> jsQueue) override;
private:
id<RCTJavaScriptExecutor> m_jse;
RCTJavaScriptCompleteBlock m_errorBlock;
};
} // namespace facebook::react
#endif // RCT_REMOVE_LEGACY_ARCH

View File

@@ -0,0 +1,150 @@
/*
* 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.
*/
#import "RCTObjcExecutor.h"
#ifndef RCT_REMOVE_LEGACY_ARCH
#import <React/RCTCxxUtils.h>
#import <React/RCTJavaScriptExecutor.h>
#import <React/RCTLog.h>
#import <React/RCTProfile.h>
#import <React/RCTUtils.h>
#import <cxxreact/JSBigString.h>
#import <cxxreact/JSExecutor.h>
#import <cxxreact/MessageQueueThread.h>
#import <cxxreact/ModuleRegistry.h>
#import <cxxreact/RAMBundleRegistry.h>
#import <folly/json.h>
#import <react/utils/FollyConvert.h>
namespace facebook::react {
namespace {
class JSEException : public std::runtime_error {
public:
JSEException(NSError *error) : runtime_error([[error description] UTF8String]) {}
};
class RCTObjcExecutor : public JSExecutor {
public:
RCTObjcExecutor(
id<RCTJavaScriptExecutor> jse,
RCTJavaScriptCompleteBlock errorBlock,
std::shared_ptr<MessageQueueThread> jsThread,
std::shared_ptr<ExecutorDelegate> delegate)
: m_jse(jse), m_errorBlock(errorBlock), m_delegate(std::move(delegate)), m_jsThread(std::move(jsThread))
{
m_jsCallback = ^(id json, NSError *error) {
if (error != nullptr) {
// Do not use "m_errorBlock" here as the bridge might be in the middle
// of invalidation as a result of error handling and "this" can be
// already deallocated.
errorBlock(error);
return;
}
m_jsThread->runOnQueue(
[this, json] { m_delegate->callNativeModules(*this, convertIdToFollyDynamic(json), true); });
};
// Synchronously initialize the executor
[jse setUp];
folly::dynamic nativeModuleConfig = folly::dynamic::array;
auto moduleRegistry = m_delegate->getModuleRegistry();
for (const auto &name : moduleRegistry->moduleNames()) {
auto config = moduleRegistry->getConfig(name);
nativeModuleConfig.push_back(config ? config->config : nullptr);
}
folly::dynamic config = folly::dynamic::object("remoteModuleConfig", std::move(nativeModuleConfig));
setGlobalVariable("__fbBatchedBridgeConfig", std::make_unique<JSBigStdString>(folly::toJson(config)));
}
void initializeRuntime() override
{
// We do nothing here since initialization is done in the constructor
}
void loadBundle(std::unique_ptr<const JSBigString> script, std::string sourceURL) override
{
RCTProfileBeginFlowEvent();
[m_jse executeApplicationScript:[NSData dataWithBytes:script->c_str() length:script->size()]
sourceURL:[[NSURL alloc] initWithString:@(sourceURL.c_str())]
onComplete:^(NSError *error) {
RCTProfileEndFlowEvent();
if (error != nullptr) {
m_errorBlock(error);
return;
}
[m_jse flushedQueue:m_jsCallback];
}];
}
void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> /*bundleRegistry*/) override
{
RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor");
}
void registerBundle(uint32_t __unused bundleId, const std::string __unused &bundlePath) override
{
RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor");
}
void callFunction(const std::string &module, const std::string &method, const folly::dynamic &arguments) override
{
[m_jse callFunctionOnModule:@(module.c_str())
method:@(method.c_str())
arguments:convertFollyDynamicToId(arguments)
callback:m_jsCallback];
}
void invokeCallback(double callbackId, const folly::dynamic &arguments) override
{
[m_jse invokeCallbackID:@(callbackId) arguments:convertFollyDynamicToId(arguments) callback:m_jsCallback];
}
virtual void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue) override
{
[m_jse injectJSONText:@(jsonValue->c_str()) asGlobalObjectNamed:@(propName.c_str()) callback:m_errorBlock];
}
virtual std::string getDescription() override
{
return [NSStringFromClass([m_jse class]) UTF8String];
}
private:
id<RCTJavaScriptExecutor> m_jse;
RCTJavaScriptCompleteBlock m_errorBlock;
std::shared_ptr<ExecutorDelegate> m_delegate;
std::shared_ptr<MessageQueueThread> m_jsThread;
RCTJavaScriptCallback m_jsCallback;
};
} // namespace
RCTObjcExecutorFactory::RCTObjcExecutorFactory(id<RCTJavaScriptExecutor> jse, RCTJavaScriptCompleteBlock errorBlock)
: m_jse(jse), m_errorBlock(errorBlock)
{
}
std::unique_ptr<JSExecutor> RCTObjcExecutorFactory::createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> jsQueue)
{
return std::unique_ptr<JSExecutor>(new RCTObjcExecutor(m_jse, m_errorBlock, jsQueue, delegate));
}
} // namespace facebook::react
#endif // RCT_REMOVE_LEGACY_ARCH