Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/react-native/ReactCommon/cxxreact/JSBigString.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ class RN_EXPORT JSBigFileString : public JSBigString {
size_t size() const override;
int fd() const;

// Throws std::runtime_error when the file at sourceURL cannot be opened or
// read (e.g. it is missing). Callers that load files which may legitimately
// be gone at load time (such as an OS-purgeable / LRU-evictable cache) must
// catch this and degrade gracefully rather than let it surface as an
// unhandled exception.
static std::unique_ptr<const JSBigFileString> fromPath(const std::string &sourceURL);

private:
Expand Down
53 changes: 33 additions & 20 deletions packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,26 +378,39 @@ void ReactInstance::registerSegment(
const std::string& segmentPath) {
LOG(WARNING) << "Starting to run ReactInstance::registerSegment with segment "
<< segmentId;
runtimeScheduler_->scheduleWork([=](jsi::Runtime& runtime) {
TraceSection s("ReactInstance::registerSegment");
auto tag = std::to_string(segmentId);
auto script = JSBigFileString::fromPath(segmentPath);
if (script->size() == 0) {
throw std::invalid_argument(
"Empty segment registered with ID " + tag + " from " + segmentPath);
}

ReactMarker::logTaggedMarker(
ReactMarker::REGISTER_JS_SEGMENT_START, tag.c_str());
LOG(WARNING) << "Starting to evaluate segment " << segmentId
<< " in ReactInstance::registerSegment";
runtime.evaluateJavaScript(
std::move(script), getSyntheticBundlePath(segmentId));
LOG(WARNING) << "Finished evaluating segment " << segmentId
<< " in ReactInstance::registerSegment";
ReactMarker::logTaggedMarker(
ReactMarker::REGISTER_JS_SEGMENT_STOP, tag.c_str());
});
// Build the segment buffer off the JS thread: there's no need to block the
// JS thread on file I/O. The segment lives in an OS-purgeable /
// LRU-evictable on-demand cache and can already be gone by the time we get
// here, in which case fromPath throws. Catch it and return early so a
// missing segment degrades gracefully instead of surfacing as an unhandled
// exception.
std::shared_ptr<const JSBigFileString> script;
try {
script = JSBigFileString::fromPath(segmentPath);
} catch (const std::exception& e) {
LOG(ERROR) << "ReactInstance::registerSegment - could not load segment "
<< segmentId << " from " << segmentPath << ": " << e.what();
return;
}
if (script->size() == 0) {
throw std::invalid_argument(
"Empty segment registered with ID " + std::to_string(segmentId) +
" from " + segmentPath);
}
runtimeScheduler_->scheduleWork(
[script = std::move(script), segmentId](jsi::Runtime& runtime) {
TraceSection s("ReactInstance::registerSegment");
auto tag = std::to_string(segmentId);
ReactMarker::logTaggedMarker(
ReactMarker::REGISTER_JS_SEGMENT_START, tag.c_str());
LOG(WARNING) << "Starting to evaluate segment " << segmentId
<< " in ReactInstance::registerSegment";
runtime.evaluateJavaScript(script, getSyntheticBundlePath(segmentId));
LOG(WARNING) << "Finished evaluating segment " << segmentId
<< " in ReactInstance::registerSegment";
ReactMarker::logTaggedMarker(
ReactMarker::REGISTER_JS_SEGMENT_STOP, tag.c_str());
});
}

namespace {
Expand Down
Loading