Skip to content

Commit 80857f2

Browse files
empyricalfacebook-github-bot
authored andcommitted
JSBigString: Fix building on Windows (#26826)
Summary: This pull request replaces the last remaining Unix headers in `JSBigString` with their equivalent Folly Portability headers, and replaces the calls to `getpagesize()` with `sysconf(_SC_PAGESIZE)` since Folly Portability is missing that function. The work to get this building on windows was mostly done by acoates-ms, this pull request just adds the finishing touches. ## Changelog: [General] [Fixed] - Fixed `JSBigString` not compiling on Windows due to Unix-specific headers Pull Request resolved: #26826 Test Plan: Compiled with Clang and with MSVC (2017) Differential Revision: D17903214 Pulled By: cpojer fbshipit-source-id: 230f8fb410fa81d8f13d8b6ccf1147cfc70358bf
1 parent a0d8740 commit 80857f2

File tree

2 files changed

+61
-69
lines changed

2 files changed

+61
-69
lines changed

ReactCommon/cxxreact/JSBigString.cpp

+30-33
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,28 @@
55

66
#include "JSBigString.h"
77

8-
#include <fcntl.h>
9-
#include <sys/stat.h>
10-
#include <unistd.h>
11-
128
#include <glog/logging.h>
139

1410
#include <folly/Memory.h>
15-
#include <folly/portability/SysMman.h>
1611
#include <folly/ScopeGuard.h>
12+
#include <folly/portability/Fcntl.h>
13+
#include <folly/portability/SysMman.h>
14+
#include <folly/portability/SysStat.h>
15+
#include <folly/portability/Unistd.h>
1716

1817
namespace facebook {
1918
namespace react {
2019

2120
JSBigFileString::JSBigFileString(int fd, size_t size, off_t offset /*= 0*/)
22-
: m_fd { -1 }
23-
, m_data { nullptr } {
24-
folly::checkUnixError(m_fd = dup(fd),
25-
"Could not duplicate file descriptor");
21+
: m_fd{-1}, m_data{nullptr} {
22+
folly::checkUnixError(m_fd = dup(fd), "Could not duplicate file descriptor");
2623

2724
// Offsets given to mmap must be page aligned. We abstract away that
2825
// restriction by sending a page aligned offset to mmap, and keeping track
2926
// of the offset within the page that we must alter the mmap pointer by to
3027
// get the final desired offset.
3128
if (offset != 0) {
32-
const static auto ps = getpagesize();
29+
const static auto ps = sysconf(_SC_PAGESIZE);
3330
auto d = lldiv(offset, ps);
3431

3532
m_mapOff = d.quot;
@@ -69,8 +66,7 @@ static off_t maybeRemap(char *data, size_t size, int fd) {
6966
}
7067
const auto begin = data;
7168
static const uint8_t kRemapMagic[] = {
72-
0xc6, 0x1f, 0xbc, 0x03, 0xc1, 0x03, 0x19, 0x1f, 0xa1, 0xd0, 0xeb, 0x73
73-
};
69+
0xc6, 0x1f, 0xbc, 0x03, 0xc1, 0x03, 0x19, 0x1f, 0xa1, 0xd0, 0xeb, 0x73};
7470
if (::memcmp(data, kRemapMagic, sizeof(kRemapMagic)) != 0) {
7571
return 0;
7672
}
@@ -82,26 +78,26 @@ static off_t maybeRemap(char *data, size_t size, int fd) {
8278
{
8379
// System page size must be at least as granular as the remapping.
8480
// TODO: Consider fallback that reads entire file into memory.
85-
const size_t systemPS = getpagesize();
81+
const size_t systemPS = sysconf(_SC_PAGESIZE);
8682
CHECK(filePS >= systemPS)
87-
<< "filePS: " << filePS
88-
<< "systemPS: " << systemPS;
83+
<< "filePS: " << filePS << "systemPS: " << systemPS;
8984
}
9085
const off_t headerPages = read16(data);
9186
uint16_t numMappings = read16(data);
9287
size_t curFilePage = headerPages;
9388
while (numMappings--) {
9489
auto memPage = read16(data) + headerPages;
9590
auto numPages = read16(data);
96-
if (mmap(begin + memPage * filePS, numPages * filePS,
97-
PROT_READ, MAP_FILE | MAP_PRIVATE | MAP_FIXED,
98-
fd, curFilePage * filePS) == MAP_FAILED) {
99-
CHECK(false)
100-
<< " memPage: " << memPage
101-
<< " numPages: " << numPages
102-
<< " curFilePage: " << curFilePage
103-
<< " size: " << size
104-
<< " error: " << std::strerror(errno);
91+
if (mmap(
92+
begin + memPage * filePS,
93+
numPages * filePS,
94+
PROT_READ,
95+
MAP_FILE | MAP_PRIVATE | MAP_FIXED,
96+
fd,
97+
curFilePage * filePS) == MAP_FAILED) {
98+
CHECK(false) << " memPage: " << memPage << " numPages: " << numPages
99+
<< " curFilePage: " << curFilePage << " size: " << size
100+
<< " error: " << std::strerror(errno);
105101
}
106102
curFilePage += numPages;
107103
}
@@ -115,12 +111,10 @@ const char *JSBigFileString::c_str() const {
115111
}
116112
if (!m_data) {
117113
m_data =
118-
(const char *) mmap(0, m_size, PROT_READ, MAP_PRIVATE, m_fd, m_mapOff);
114+
(const char *)mmap(0, m_size, PROT_READ, MAP_PRIVATE, m_fd, m_mapOff);
119115
CHECK(m_data != MAP_FAILED)
120-
<< " fd: " << m_fd
121-
<< " size: " << m_size
122-
<< " offset: " << m_mapOff
123-
<< " error: " << std::strerror(errno);
116+
<< " fd: " << m_fd << " size: " << m_size << " offset: " << m_mapOff
117+
<< " error: " << std::strerror(errno);
124118
#ifdef WITH_FBREMAP
125119
// Remapping is only attempted when the entire file was requested.
126120
if (m_mapOff == 0 && m_pageOff == 0) {
@@ -141,16 +135,19 @@ int JSBigFileString::fd() const {
141135
return m_fd;
142136
}
143137

144-
std::unique_ptr<const JSBigFileString> JSBigFileString::fromPath(const std::string& sourceURL) {
138+
std::unique_ptr<const JSBigFileString> JSBigFileString::fromPath(
139+
const std::string &sourceURL) {
145140
int fd = ::open(sourceURL.c_str(), O_RDONLY);
146141
folly::checkUnixError(fd, "Could not open file", sourceURL);
147-
SCOPE_EXIT { CHECK(::close(fd) == 0); };
142+
SCOPE_EXIT {
143+
CHECK(::close(fd) == 0);
144+
};
148145

149146
struct stat fileInfo;
150147
folly::checkUnixError(::fstat(fd, &fileInfo), "fstat on bundle failed.");
151148

152149
return folly::make_unique<const JSBigFileString>(fd, fileInfo.st_size);
153150
}
154151

155-
} // namespace react
156-
} // namespace facebook
152+
} // namespace react
153+
} // namespace facebook

ReactCommon/cxxreact/JSBigString.h

+31-36
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@
55

66
#pragma once
77

8-
#include <fcntl.h>
9-
#include <sys/mman.h>
10-
118
#include <folly/Exception.h>
129

1310
#ifndef RN_EXPORT
14-
# ifdef _MSC_VER
15-
# define RN_EXPORT
16-
# else
17-
# define RN_EXPORT __attribute__((visibility("default")))
18-
# endif
11+
#ifdef _MSC_VER
12+
#define RN_EXPORT
13+
#else
14+
#define RN_EXPORT __attribute__((visibility("default")))
15+
#endif
1916
#endif
2017

2118
namespace facebook {
@@ -29,19 +26,19 @@ namespace react {
2926
// by CopyConstructible.
3027

3128
class JSBigString {
32-
public:
29+
public:
3330
JSBigString() = default;
3431

3532
// Not copyable
36-
JSBigString(const JSBigString&) = delete;
37-
JSBigString& operator=(const JSBigString&) = delete;
33+
JSBigString(const JSBigString &) = delete;
34+
JSBigString &operator=(const JSBigString &) = delete;
3835

3936
virtual ~JSBigString() {}
4037

4138
virtual bool isAscii() const = 0;
4239

4340
// This needs to be a \0 terminated string
44-
virtual const char* c_str() const = 0;
41+
virtual const char *c_str() const = 0;
4542

4643
// Length of the c_str without the NULL byte.
4744
virtual size_t size() const = 0;
@@ -50,24 +47,23 @@ class JSBigString {
5047
// Concrete JSBigString implementation which holds a std::string
5148
// instance.
5249
class JSBigStdString : public JSBigString {
53-
public:
54-
JSBigStdString(std::string str, bool isAscii=false)
55-
: m_isAscii(isAscii)
56-
, m_str(std::move(str)) {}
50+
public:
51+
JSBigStdString(std::string str, bool isAscii = false)
52+
: m_isAscii(isAscii), m_str(std::move(str)) {}
5753

5854
bool isAscii() const override {
5955
return m_isAscii;
6056
}
6157

62-
const char* c_str() const override {
58+
const char *c_str() const override {
6359
return m_str.c_str();
6460
}
6561

6662
size_t size() const override {
6763
return m_str.size();
6864
}
6965

70-
private:
66+
private:
7167
bool m_isAscii;
7268
std::string m_str;
7369
};
@@ -77,10 +73,8 @@ class JSBigStdString : public JSBigString {
7773
// used to construct a JSBigString in place, such as by reading from a
7874
// file.
7975
class RN_EXPORT JSBigBufferString : public JSBigString {
80-
public:
81-
JSBigBufferString(size_t size)
82-
: m_data(new char[size + 1])
83-
, m_size(size) {
76+
public:
77+
JSBigBufferString(size_t size) : m_data(new char[size + 1]), m_size(size) {
8478
// Guarantee nul-termination. The caller is responsible for
8579
// filling in the rest of m_data.
8680
m_data[m_size] = '\0';
@@ -94,27 +88,26 @@ class RN_EXPORT JSBigBufferString : public JSBigString {
9488
return true;
9589
}
9690

97-
const char* c_str() const override {
91+
const char *c_str() const override {
9892
return m_data;
9993
}
10094

10195
size_t size() const override {
10296
return m_size;
10397
}
10498

105-
char* data() {
99+
char *data() {
106100
return m_data;
107101
}
108102

109-
private:
110-
char* m_data;
103+
private:
104+
char *m_data;
111105
size_t m_size;
112106
};
113107

114108
// JSBigString interface implemented by a file-backed mmap region.
115109
class RN_EXPORT JSBigFileString : public JSBigString {
116-
public:
117-
110+
public:
118111
JSBigFileString(int fd, size_t size, off_t offset = 0);
119112
~JSBigFileString();
120113

@@ -127,14 +120,16 @@ class RN_EXPORT JSBigFileString : public JSBigString {
127120
size_t size() const override;
128121
int fd() const;
129122

130-
static std::unique_ptr<const JSBigFileString> fromPath(const std::string& sourceURL);
123+
static std::unique_ptr<const JSBigFileString> fromPath(
124+
const std::string &sourceURL);
131125

132-
private:
133-
int m_fd; // The file descriptor being mmaped
134-
size_t m_size; // The size of the mmaped region
135-
mutable off_t m_pageOff; // The offset in the mmaped region to the data.
136-
off_t m_mapOff; // The offset in the file to the mmaped region.
137-
mutable const char *m_data; // Pointer to the mmaped region.
126+
private:
127+
int m_fd; // The file descriptor being mmaped
128+
size_t m_size; // The size of the mmaped region
129+
mutable off_t m_pageOff; // The offset in the mmaped region to the data.
130+
off_t m_mapOff; // The offset in the file to the mmaped region.
131+
mutable const char *m_data; // Pointer to the mmaped region.
138132
};
139133

140-
} }
134+
} // namespace react
135+
} // namespace facebook

0 commit comments

Comments
 (0)