Move `ScriptTag` and `RCTJSModulesUnbundle` to `cxxreact`
Reviewed By: javache Differential Revision: D4213662 fbshipit-source-id: fc2ec9717c24fe77bb022a48777049f88173ebeb
This commit is contained in:
parent
f9d80a451a
commit
5db7484e8d
|
@ -11,55 +11,6 @@
|
|||
|
||||
#import "RCTDefines.h"
|
||||
|
||||
/**
|
||||
* RCTScriptTag
|
||||
*
|
||||
* Scripts given to the JS Executors to run could be in any of the following
|
||||
* formats. They are tagged so the executor knows how to run them.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger) {
|
||||
RCTScriptString = 0,
|
||||
RCTScriptRAMBundle,
|
||||
RCTScriptBCBundle,
|
||||
} RCTScriptTag;
|
||||
|
||||
/**
|
||||
* RCTBundleHeader
|
||||
*
|
||||
* RAM bundles and BC bundles begin with headers. For RAM bundles this is
|
||||
* 4 bytes, for BC bundles this is 12 bytes. This structure holds the first 12
|
||||
* bytes from a bundle in a way that gives access to that information.
|
||||
*/
|
||||
typedef union {
|
||||
// `allBytes` is the first field so that zero-initializing the union fills
|
||||
// it completely with zeroes. Without it, only the first field of the union
|
||||
// gets zero-initialized.
|
||||
uint32_t allBytes[3];
|
||||
|
||||
uint32_t RAMMagic;
|
||||
|
||||
struct {
|
||||
uint64_t BCMagic;
|
||||
uint32_t BCVersion;
|
||||
};
|
||||
} RCTBundleHeader;
|
||||
|
||||
/**
|
||||
* RCTParseTypeFromHeader
|
||||
*
|
||||
* Takes the first 8 bytes of a bundle, and returns a tag describing the
|
||||
* bundle's format.
|
||||
*/
|
||||
RCT_EXTERN RCTScriptTag RCTParseTypeFromHeader(RCTBundleHeader header);
|
||||
|
||||
/**
|
||||
* RCTStringForScriptTag
|
||||
*
|
||||
* Convert an `RCTScriptTag` enum into a string, useful for emitting in errors
|
||||
* and diagnostic messages.
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTStringForScriptTag(RCTScriptTag tag);
|
||||
|
||||
extern NSString *const RCTJavaScriptLoaderErrorDomain;
|
||||
|
||||
NS_ENUM(NSInteger) {
|
||||
|
|
|
@ -16,38 +16,11 @@
|
|||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTMultipartDataTask.h"
|
||||
|
||||
#include <cxxreact/JSBundleType.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static uint32_t const RCTRAMBundleMagicNumber = 0xFB0BD1E5;
|
||||
static uint64_t const RCTBCBundleMagicNumber = 0xFF4865726D657300;
|
||||
|
||||
NSString *const RCTJavaScriptLoaderErrorDomain = @"RCTJavaScriptLoaderErrorDomain";
|
||||
|
||||
RCTScriptTag RCTParseTypeFromHeader(RCTBundleHeader header)
|
||||
{
|
||||
if (NSSwapLittleIntToHost(header.RAMMagic) == RCTRAMBundleMagicNumber) {
|
||||
return RCTScriptRAMBundle;
|
||||
}
|
||||
|
||||
if (NSSwapLittleLongLongToHost(header.BCMagic) == RCTBCBundleMagicNumber) {
|
||||
return RCTScriptBCBundle;
|
||||
}
|
||||
|
||||
return RCTScriptString;
|
||||
}
|
||||
|
||||
NSString *RCTStringForScriptTag(RCTScriptTag tag)
|
||||
{
|
||||
switch (tag) {
|
||||
case RCTScriptString:
|
||||
return @"String";
|
||||
case RCTScriptRAMBundle:
|
||||
return @"RAM Bundle";
|
||||
case RCTScriptBCBundle:
|
||||
return @"BC Bundle";
|
||||
}
|
||||
}
|
||||
|
||||
@implementation RCTLoadingProgress
|
||||
|
||||
- (NSString *)description
|
||||
|
@ -58,7 +31,7 @@ NSString *RCTStringForScriptTag(RCTScriptTag tag)
|
|||
if (_total > 0) {
|
||||
[desc appendFormat:@" %ld%% (%@/%@)", (long)(100 * [_done integerValue] / [_total integerValue]), _done, _total];
|
||||
}
|
||||
[desc appendString:@"…"];
|
||||
[desc appendString:@"\u2026"];
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
@ -140,7 +113,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
return nil;
|
||||
}
|
||||
|
||||
RCTBundleHeader header = {};
|
||||
facebook::react::BundleHeader header{};
|
||||
size_t readResult = fread(&header, sizeof(header), 1, bundle);
|
||||
fclose(bundle);
|
||||
if (readResult != 1) {
|
||||
|
@ -153,12 +126,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
return nil;
|
||||
}
|
||||
|
||||
RCTScriptTag tag = RCTParseTypeFromHeader(header);
|
||||
facebook::react::ScriptTag tag = facebook::react::parseTypeFromHeader(header);
|
||||
switch (tag) {
|
||||
case RCTScriptRAMBundle:
|
||||
case facebook::react::ScriptTag::RAMBundle:
|
||||
break;
|
||||
|
||||
case RCTScriptString:
|
||||
case facebook::react::ScriptTag::String:
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously
|
||||
|
@ -167,7 +140,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
}
|
||||
return nil;
|
||||
|
||||
case RCTScriptBCBundle:
|
||||
case facebook::react::ScriptTag::BCBundle:
|
||||
if (header.BCVersion != runtimeBCVersion) {
|
||||
if (error) {
|
||||
NSString *errDesc =
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#import <UIKit/UIDevice.h>
|
||||
|
||||
#import <cxxreact/JSBundleType.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTDefines.h"
|
||||
|
@ -66,7 +68,7 @@ struct RandomAccessBundleStartupCode {
|
|||
};
|
||||
|
||||
struct TaggedScript {
|
||||
const RCTScriptTag tag;
|
||||
const facebook::react::ScriptTag tag;
|
||||
const NSData *script;
|
||||
};
|
||||
|
||||
|
@ -292,7 +294,7 @@ static NSThread *newJavaScriptThread(void)
|
|||
return loadError;
|
||||
}
|
||||
|
||||
if (taggedScript.tag == RCTScriptRAMBundle) {
|
||||
if (taggedScript.tag == facebook::react::ScriptTag::RAMBundle) {
|
||||
registerNativeRequire(_context.context, self);
|
||||
}
|
||||
|
||||
|
@ -712,7 +714,7 @@ RCT_EXPORT_METHOD(setContextName:(nonnull NSString *)contextName)
|
|||
return;
|
||||
}
|
||||
|
||||
if (taggedScript.tag == RCTScriptRAMBundle) {
|
||||
if (taggedScript.tag == facebook::react::ScriptTag::RAMBundle) {
|
||||
registerNativeRequire(self.context.context, self);
|
||||
}
|
||||
|
||||
|
@ -734,13 +736,13 @@ static TaggedScript loadTaggedScript(NSData *script,
|
|||
{
|
||||
RCT_PROFILE_BEGIN_EVENT(0, @"executeApplicationScript / prepare bundle", nil);
|
||||
|
||||
RCTBundleHeader header = {};
|
||||
facebook::react::BundleHeader header{};
|
||||
[script getBytes:&header length:sizeof(header)];
|
||||
RCTScriptTag tag = RCTParseTypeFromHeader(header);
|
||||
facebook::react::ScriptTag tag = facebook::react::parseTypeFromHeader(header);
|
||||
|
||||
NSData *loadedScript = NULL;
|
||||
switch (tag) {
|
||||
case RCTScriptRAMBundle:
|
||||
case facebook::react::ScriptTag::RAMBundle:
|
||||
[performanceLogger markStartForTag:RCTPLRAMBundleLoad];
|
||||
|
||||
loadedScript = loadRAMBundle(sourceURL, error, randomAccessBundle);
|
||||
|
@ -749,11 +751,11 @@ static TaggedScript loadTaggedScript(NSData *script,
|
|||
[performanceLogger setValue:loadedScript.length forTag:RCTPLRAMStartupCodeSize];
|
||||
break;
|
||||
|
||||
case RCTScriptBCBundle:
|
||||
case facebook::react::ScriptTag::BCBundle:
|
||||
loadedScript = script;
|
||||
break;
|
||||
|
||||
case RCTScriptString: {
|
||||
case facebook::react::ScriptTag::String: {
|
||||
NSMutableData *nullTerminatedScript = [NSMutableData dataWithData:script];
|
||||
[nullTerminatedScript appendBytes:"" length:1];
|
||||
loadedScript = nullTerminatedScript;
|
||||
|
@ -785,16 +787,16 @@ static NSError *executeApplicationScript(TaggedScript taggedScript,
|
|||
JSStringRef bundleURL = jscWrapper->JSStringCreateWithUTF8CString(sourceURL.absoluteString.UTF8String);
|
||||
|
||||
switch (taggedScript.tag) {
|
||||
case RCTScriptRAMBundle:
|
||||
case facebook::react::ScriptTag::RAMBundle:
|
||||
/* fallthrough */
|
||||
case RCTScriptString: {
|
||||
case facebook::react::ScriptTag::String: {
|
||||
JSStringRef execJSString = jscWrapper->JSStringCreateWithUTF8CString((const char *)taggedScript.script.bytes);
|
||||
jscWrapper->JSEvaluateScript(ctx, execJSString, NULL, bundleURL, 0, &jsError);
|
||||
jscWrapper->JSStringRelease(execJSString);
|
||||
break;
|
||||
}
|
||||
|
||||
case RCTScriptBCBundle: {
|
||||
case facebook::react::ScriptTag::BCBundle: {
|
||||
file_ptr source(fopen(sourceURL.path.UTF8String, "r"), fclose);
|
||||
int sourceFD = fileno(source.get());
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
13E067591A70F44B002CDEE1 /* UIView+React.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067541A70F44B002CDEE1 /* UIView+React.m */; };
|
||||
13E41EEB1C05CA0B00CD8DAC /* RCTProfileTrampoline-i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 14BF717F1C04793D00C97D0C /* RCTProfileTrampoline-i386.S */; };
|
||||
13F17A851B8493E5007D4C75 /* RCTRedBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 13F17A841B8493E5007D4C75 /* RCTRedBox.m */; };
|
||||
14200DAA1AC179B3008EE6BA /* RCTJavaScriptLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */; };
|
||||
142014191B32094000CC17BA /* RCTPerformanceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 142014171B32094000CC17BA /* RCTPerformanceLogger.m */; };
|
||||
14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 14435CE21AAC4AE100FC20F4 /* RCTMap.m */; };
|
||||
14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14435CE41AAC4AE100FC20F4 /* RCTMapManager.m */; };
|
||||
|
@ -90,7 +89,6 @@
|
|||
2D3B5E9A1D9B089D00451313 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; };
|
||||
2D3B5E9B1D9B08A000451313 /* RCTFrameUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA751B3AC64F00E6CBB2 /* RCTFrameUpdate.m */; };
|
||||
2D3B5E9C1D9B08A300451313 /* RCTImageSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BB3D011BECD54500932C10 /* RCTImageSource.m */; };
|
||||
2D3B5E9D1D9B08A800451313 /* RCTJavaScriptLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */; };
|
||||
2D3B5E9E1D9B08AD00451313 /* RCTJSStackFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 008341F41D1DB34400876D9A /* RCTJSStackFrame.m */; };
|
||||
2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */; };
|
||||
2D3B5EA01D9B08B200451313 /* RCTLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4E1A601E3B00E9B192 /* RCTLog.mm */; };
|
||||
|
@ -193,6 +191,8 @@
|
|||
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; };
|
||||
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; };
|
||||
85C199EE1CD2407900DAD810 /* RCTJSCWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85C199ED1CD2407900DAD810 /* RCTJSCWrapper.mm */; };
|
||||
AC70D2E91DE489E4002E6351 /* RCTJavaScriptLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */; };
|
||||
AC70D2ED1DE48A22002E6351 /* JSBundleType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2EB1DE48A22002E6351 /* JSBundleType.cpp */; };
|
||||
B233E6EA1D2D845D00BC68BA /* RCTI18nManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B233E6E91D2D845D00BC68BA /* RCTI18nManager.m */; };
|
||||
B95154321D1B34B200FE7B80 /* RCTActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B95154311D1B34B200FE7B80 /* RCTActivityIndicatorView.m */; };
|
||||
E9B20B7B1B500126007A2DA7 /* RCTAccessibilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */; };
|
||||
|
@ -339,7 +339,6 @@
|
|||
13F17A831B8493E5007D4C75 /* RCTRedBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRedBox.h; sourceTree = "<group>"; };
|
||||
13F17A841B8493E5007D4C75 /* RCTRedBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBox.m; sourceTree = "<group>"; };
|
||||
14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptLoader.h; sourceTree = "<group>"; };
|
||||
14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJavaScriptLoader.m; sourceTree = "<group>"; };
|
||||
142014171B32094000CC17BA /* RCTPerformanceLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPerformanceLogger.m; sourceTree = "<group>"; };
|
||||
142014181B32094000CC17BA /* RCTPerformanceLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPerformanceLogger.h; sourceTree = "<group>"; };
|
||||
1436DD071ADE7AA000A5ED7D /* RCTFrameUpdate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTFrameUpdate.h; sourceTree = "<group>"; };
|
||||
|
@ -438,6 +437,10 @@
|
|||
83F15A171B7CC46900F10295 /* UIView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+Private.h"; sourceTree = "<group>"; };
|
||||
85C199EC1CD2407900DAD810 /* RCTJSCWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSCWrapper.h; sourceTree = "<group>"; };
|
||||
85C199ED1CD2407900DAD810 /* RCTJSCWrapper.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = RCTJSCWrapper.mm; sourceTree = "<group>"; };
|
||||
AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTJavaScriptLoader.mm; sourceTree = "<group>"; };
|
||||
AC70D2EB1DE48A22002E6351 /* JSBundleType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSBundleType.cpp; path = cxxreact/JSBundleType.cpp; sourceTree = "<group>"; };
|
||||
AC70D2EC1DE48A22002E6351 /* JSBundleType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSBundleType.h; path = cxxreact/JSBundleType.h; sourceTree = "<group>"; };
|
||||
AC70D2EE1DE48AC5002E6351 /* oss-compat-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "oss-compat-util.h"; path = "cxxreact/oss-compat-util.h"; sourceTree = "<group>"; };
|
||||
ACDD3FDA1BC7430D00E7DE33 /* RCTBorderStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBorderStyle.h; sourceTree = "<group>"; };
|
||||
B233E6E81D2D843200BC68BA /* RCTI18nManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTI18nManager.h; sourceTree = "<group>"; };
|
||||
B233E6E91D2D845D00BC68BA /* RCTI18nManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTI18nManager.m; sourceTree = "<group>"; };
|
||||
|
@ -665,6 +668,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
133683431D37ACA10077D0C3 /* CSSLayout */,
|
||||
AC70D2EA1DE489FC002E6351 /* cxxreact */,
|
||||
);
|
||||
name = ReactCommon;
|
||||
path = ../ReactCommon;
|
||||
|
@ -733,7 +737,7 @@
|
|||
83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */,
|
||||
83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */,
|
||||
14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */,
|
||||
14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */,
|
||||
AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */,
|
||||
008341F51D1DB34400876D9A /* RCTJSStackFrame.h */,
|
||||
008341F41D1DB34400876D9A /* RCTJSStackFrame.m */,
|
||||
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */,
|
||||
|
@ -773,6 +777,16 @@
|
|||
path = Base;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AC70D2EA1DE489FC002E6351 /* cxxreact */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AC70D2EB1DE48A22002E6351 /* JSBundleType.cpp */,
|
||||
AC70D2EC1DE48A22002E6351 /* JSBundleType.h */,
|
||||
AC70D2EE1DE48AC5002E6351 /* oss-compat-util.h */,
|
||||
);
|
||||
name = cxxreact;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -932,7 +946,6 @@
|
|||
2D3B5E9B1D9B08A000451313 /* RCTFrameUpdate.m in Sources */,
|
||||
2D3B5EE41D9B09BB00451313 /* RCTSegmentedControlManager.m in Sources */,
|
||||
2D3B5EE31D9B09B700451313 /* RCTSegmentedControl.m in Sources */,
|
||||
2D3B5E9D1D9B08A800451313 /* RCTJavaScriptLoader.m in Sources */,
|
||||
2D3B5EB71D9B091800451313 /* RCTRedBox.m in Sources */,
|
||||
2D3B5ED11D9B097500451313 /* RCTMapAnnotation.m in Sources */,
|
||||
2D3B5EAB1D9B08EC00451313 /* RCTJSCErrorHandling.m in Sources */,
|
||||
|
@ -1042,12 +1055,12 @@
|
|||
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */,
|
||||
1450FF8A1BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S in Sources */,
|
||||
13D9FEEB1CDCCECF00158BD7 /* RCTEventEmitter.m in Sources */,
|
||||
AC70D2E91DE489E4002E6351 /* RCTJavaScriptLoader.mm in Sources */,
|
||||
14F7A0EC1BDA3B3C003C6C10 /* RCTPerfMonitor.m in Sources */,
|
||||
1450FF881BCFF28A00208362 /* RCTProfileTrampoline-arm64.S in Sources */,
|
||||
13E41EEB1C05CA0B00CD8DAC /* RCTProfileTrampoline-i386.S in Sources */,
|
||||
3D37B5821D522B190042D5B5 /* RCTFont.mm in Sources */,
|
||||
13B080061A6947C200A75B9A /* RCTScrollViewManager.m in Sources */,
|
||||
14200DAA1AC179B3008EE6BA /* RCTJavaScriptLoader.m in Sources */,
|
||||
137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */,
|
||||
369123E11DDC75850095B341 /* JSCSamplingProfiler.m in Sources */,
|
||||
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */,
|
||||
|
@ -1089,6 +1102,7 @@
|
|||
83A1FE8C1B62640A00BE0E65 /* RCTModalHostView.m in Sources */,
|
||||
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */,
|
||||
1450FF871BCFF28A00208362 /* RCTProfileTrampoline-arm.S in Sources */,
|
||||
AC70D2ED1DE48A22002E6351 /* JSBundleType.cpp in Sources */,
|
||||
131B6AF51AF1093D00FFC3E0 /* RCTSegmentedControlManager.m in Sources */,
|
||||
58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */,
|
||||
191E3EBE1C29D9AF00C180A6 /* RCTRefreshControlManager.m in Sources */,
|
||||
|
|
|
@ -117,6 +117,8 @@ CXXREACT_PUBLIC_HEADERS = [
|
|||
'JSCExecutor.h',
|
||||
'JSCNativeModules.h',
|
||||
'JSCWebWorker.h',
|
||||
'JSBundleType.h',
|
||||
'JSIndexedRAMBundle.h',
|
||||
'JSModulesUnbundle.h',
|
||||
'MessageQueueThread.h',
|
||||
'MethodCall.h',
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "JSBundleType.h"
|
||||
#include "oss-compat-util.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static uint32_t constexpr RAMBundleMagicNumber = 0xFB0BD1E5;
|
||||
static uint64_t constexpr BCBundleMagicNumber = 0xFF4865726D657300;
|
||||
|
||||
ScriptTag parseTypeFromHeader(const BundleHeader& header) {
|
||||
if (littleEndianToHost(header.RAMMagic) == RAMBundleMagicNumber) {
|
||||
return ScriptTag::RAMBundle;
|
||||
}
|
||||
|
||||
if (littleEndianToHost(header.BCMagic) == BCBundleMagicNumber) {
|
||||
return ScriptTag::BCBundle;
|
||||
}
|
||||
|
||||
return ScriptTag::String;
|
||||
}
|
||||
|
||||
const char *stringForScriptTag(const ScriptTag& tag) {
|
||||
switch (tag) {
|
||||
case ScriptTag::String:
|
||||
return "String";
|
||||
case ScriptTag::RAMBundle:
|
||||
return "RAM Bundle";
|
||||
case ScriptTag::BCBundle:
|
||||
return "BC Bundle";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* ScriptTag
|
||||
*
|
||||
* Scripts given to the JS Executors to run could be in any of the following
|
||||
* formats. They are tagged so the executor knows how to run them.
|
||||
*/
|
||||
enum struct ScriptTag {
|
||||
String = 0,
|
||||
RAMBundle,
|
||||
BCBundle,
|
||||
};
|
||||
|
||||
/**
|
||||
* BundleHeader
|
||||
*
|
||||
* RAM bundles and BC bundles begin with headers. For RAM bundles this is
|
||||
* 4 bytes, for BC bundles this is 12 bytes. This structure holds the first 12
|
||||
* bytes from a bundle in a way that gives access to that information.
|
||||
*/
|
||||
union BundleHeader {
|
||||
BundleHeader() {
|
||||
std::memset(this, 0, sizeof(BundleHeader));
|
||||
}
|
||||
|
||||
uint32_t RAMMagic;
|
||||
struct {
|
||||
uint64_t BCMagic;
|
||||
uint32_t BCVersion;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* parseTypeFromHeader
|
||||
*
|
||||
* Takes the first 8 bytes of a bundle, and returns a tag describing the
|
||||
* bundle's format.
|
||||
*/
|
||||
ScriptTag parseTypeFromHeader(const BundleHeader& header);
|
||||
|
||||
/**
|
||||
* stringForScriptTag
|
||||
*
|
||||
* Convert an `ScriptTag` enum into a string, useful for emitting in errors
|
||||
* and diagnostic messages.
|
||||
*/
|
||||
const char* stringForScriptTag(const ScriptTag& tag);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "JSIndexedRAMBundle.h"
|
||||
#include "oss-compat-util.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
JSIndexedRAMBundle::JSIndexedRAMBundle(const char *sourcePath) :
|
||||
m_bundle (sourcePath, std::ios_base::in) {
|
||||
if (!m_bundle) {
|
||||
throw std::ios_base::failure(
|
||||
toString("Bundle ", sourcePath,
|
||||
"cannot be opened: ", m_bundle.rdstate()));
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
readBundle(reinterpret_cast<char *>(header), sizeof(header));
|
||||
const size_t numTableEntries = littleEndianToHost(header[1]);
|
||||
const size_t startupCodeSize = littleEndianToHost(header[2]);
|
||||
|
||||
// allocate memory for meta data and lookup table.
|
||||
m_table = ModuleTable(numTableEntries);
|
||||
m_baseOffset = sizeof(header) + m_table.byteLength();
|
||||
|
||||
// read the lookup table from the file
|
||||
readBundle(
|
||||
reinterpret_cast<char *>(m_table.data.get()), m_table.byteLength());
|
||||
|
||||
// read the startup code
|
||||
m_startupCode =
|
||||
std::make_unique<facebook::react::JSBigBufferString>(startupCodeSize);
|
||||
|
||||
readBundle(m_startupCode->data(), startupCodeSize);
|
||||
}
|
||||
|
||||
JSIndexedRAMBundle::Module JSIndexedRAMBundle::getModule(uint32_t moduleId) const {
|
||||
Module ret;
|
||||
ret.name = toString(moduleId, ".js");
|
||||
ret.code = getModuleCode(moduleId);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<const facebook::react::JSBigString> JSIndexedRAMBundle::getStartupCode() {
|
||||
CHECK(m_startupCode) << "startup code for a RAM Bundle can only be retrieved once";
|
||||
return std::move(m_startupCode);
|
||||
}
|
||||
|
||||
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 ? littleEndianToHost(moduleData->length) : 0;
|
||||
if (length == 0) {
|
||||
throw std::ios_base::failure(
|
||||
toString("Error loading module", id, "from RAM Bundle"));
|
||||
}
|
||||
|
||||
std::string ret(moduleData->length, '\0');
|
||||
readBundle(&ret.front(), length, m_baseOffset + littleEndianToHost(moduleData->offset));
|
||||
return ret;
|
||||
}
|
||||
|
||||
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(
|
||||
toString("Error reading RAM Bundle: ", m_bundle.rdstate()));
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
toString("Error reading RAM Bundle: ", m_bundle.rdstate()));
|
||||
}
|
||||
readBundle(buffer, bytes);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#include "Executor.h"
|
||||
#include "JSBundleType.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class JSBigString;
|
||||
|
||||
#include <cxxreact/JSModulesUnbundle.h>
|
||||
|
||||
class JSIndexedRAMBundle : public facebook::react::JSModulesUnbundle {
|
||||
public:
|
||||
// Throws std::runtime_error on failure.
|
||||
JSIndexedRAMBundle(const char *sourceURL);
|
||||
|
||||
// Throws std::runtime_error on failure.
|
||||
std::unique_ptr<const facebook::react::JSBigString> getStartupCode();
|
||||
// Throws std::runtime_error on failure.
|
||||
Module getModule(uint32_t moduleId) const override;
|
||||
|
||||
private:
|
||||
struct ModuleData {
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
};
|
||||
static_assert(
|
||||
sizeof(ModuleData) == 8,
|
||||
"ModuleData must not have any padding and use sizes matching input files");
|
||||
|
||||
struct ModuleTable {
|
||||
size_t numEntries;
|
||||
std::unique_ptr<ModuleData[]> data;
|
||||
ModuleTable() : numEntries(0) {};
|
||||
ModuleTable(size_t entries) :
|
||||
numEntries(entries),
|
||||
data(std::make_unique<ModuleData[]>(numEntries)) {};
|
||||
size_t byteLength() const {
|
||||
return numEntries * sizeof(ModuleData);
|
||||
}
|
||||
};
|
||||
|
||||
std::string getModuleCode(const uint32_t id) const;
|
||||
void readBundle(char *buffer, const std::streamsize bytes) const;
|
||||
void readBundle(
|
||||
char *buffer, const
|
||||
std::streamsize bytes,
|
||||
const std::ifstream::pos_type position) const;
|
||||
|
||||
mutable std::ifstream m_bundle;
|
||||
ModuleTable m_table;
|
||||
size_t m_baseOffset;
|
||||
std::unique_ptr<facebook::react::JSBigBufferString> m_startupCode;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
//TODO #14683310 remove this header as soon as RN iOS OSS links against folly
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ANDROID)
|
||||
#define USE_FOLLY_FOR_ENDIAN_SWAP 1
|
||||
#define USE_FOLLY_FOR_TO_STRING 1
|
||||
#elif defined(__has_include)
|
||||
#define USE_FOLLY_FOR_ENDIAN_SWAP __has_include(<folly/Bits.h>)
|
||||
#define USE_FOLLY_FOR_TO_STRING __has_include(<folly/String.h>)
|
||||
#else
|
||||
#define USE_FOLLY_FOR_ENDIAN_SWAP 0
|
||||
#define USE_FOLLY_FOR_TO_STRING 0
|
||||
#endif
|
||||
|
||||
#if USE_FOLLY_FOR_ENDIAN_SWAP
|
||||
#include <folly/Bits.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <cstdint>
|
||||
#include <CoreFoundation/CFByteOrder.h>
|
||||
#endif // USE_FOLLY_FOR_ENDIAN_SWAP
|
||||
|
||||
#if USE_FOLLY_FOR_TO_STRING
|
||||
#include <folly/String.h>
|
||||
#else
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#endif // USE_FOLLY_FOR_TO_STRING
|
||||
|
||||
|
||||
#if USE_FOLLY_FOR_ENDIAN_SWAP
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
template <typename T>
|
||||
inline T littleEndianToHost(T x) {
|
||||
return folly::Endian::little(x);
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
// Yes, this is horrible. #14683310
|
||||
|
||||
inline int32_t littleEndianToHost(int32_t x) {
|
||||
return CFSwapInt32LittleToHost(x);
|
||||
}
|
||||
|
||||
inline uint32_t littleEndianToHost(uint32_t x) {
|
||||
return CFSwapInt32LittleToHost(x);
|
||||
}
|
||||
|
||||
inline int64_t littleEndianToHost(int64_t x) {
|
||||
return CFSwapInt64LittleToHost(x);
|
||||
}
|
||||
|
||||
inline uint64_t littleEndianToHost(uint64_t x) {
|
||||
return CFSwapInt64LittleToHost(x);
|
||||
}
|
||||
|
||||
#endif // USE_FOLLY_FOR_ENDIAN_SWAP
|
||||
|
||||
#if USE_FOLLY_FOR_TO_STRING
|
||||
|
||||
template <typename ...Ts>
|
||||
inline std::string toString(Ts... values) {
|
||||
return folly::to<std::string>(std::forward<Ts>(values)...);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename ...Ts>
|
||||
std::string toString(const std::stringstream& buf) {
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
template <typename T, typename ...Ts>
|
||||
std::string toString(std::stringstream& buf, T value, Ts... values) {
|
||||
buf << value;
|
||||
return toString(buf, std::forward<Ts>(values)...);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
template <typename ...Ts>
|
||||
std::string toString(Ts... values) {
|
||||
std::stringstream buf{};
|
||||
return toString(buf, std::forward<Ts>(values)...);
|
||||
}
|
||||
|
||||
#endif // USE_FOLLY_FOR_TO_STRING
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
#undef USE_FOLLY_FOR_ENDIAN_SWAP
|
||||
#undef USE_FOLLY_FOR_TO_STRING
|
Loading…
Reference in New Issue