Skip to content

Commit

Permalink
Add default getStringData/getPropNameIdData implementation (#47530)
Browse files Browse the repository at this point in the history
Summary:

Adds the default implementation for `getStringData`/`getPropNameIdData`
for VMs that do not provide their own implementation

Changelog: [Internal]

Differential Revision: D65638889
  • Loading branch information
Chi Tsai authored and facebook-github-bot committed Nov 11, 2024
1 parent 5b609cc commit d649132
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
32 changes: 32 additions & 0 deletions packages/react-native/ReactCommon/jsi/jsi/decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,21 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
return plain_.utf16(sym);
}

void getStringData(
const jsi::String& str,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num))
override {
plain_.getStringData(str, ctx, cb);
}

void getPropNameIdData(
const jsi::PropNameID& sym,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num)) {
plain_.getPropNameIdData(sym, ctx, cb);
}

Object createObject() override {
return plain_.createObject();
};
Expand Down Expand Up @@ -690,6 +705,23 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
return RD::utf16(sym);
}

void getStringData(
const jsi::String& str,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num))
override {
Around around{with_};
RD::getStringData(str, ctx, cb);
}

void getPropNameIdData(
const jsi::PropNameID& sym,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num)) {
Around around{with_};
RD::getPropNameIdData(sym, ctx, cb);
}

Value createValueFromJsonUtf8(const uint8_t* json, size_t length) override {
Around around{with_};
return RD::createValueFromJsonUtf8(json, length);
Expand Down
16 changes: 16 additions & 0 deletions packages/react-native/ReactCommon/jsi/jsi/jsi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,22 @@ std::u16string Runtime::utf16(const String& str) {
return convertUTF8ToUTF16(utf8Str);
}

void Runtime::getStringData(
const jsi::String& str,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num)) {
auto utf16Str = utf16(str);
cb(ctx, false, utf16Str.data(), utf16Str.size());
}

void Runtime::getPropNameIdData(
const jsi::PropNameID& sym,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num)) {
auto utf16Str = utf16(sym);
cb(ctx, false, utf16Str.data(), utf16Str.size());
}

Pointer& Pointer::operator=(Pointer&& other) noexcept {
if (ptr_) {
ptr_->invalidate();
Expand Down
44 changes: 44 additions & 0 deletions packages/react-native/ReactCommon/jsi/jsi/jsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,22 @@ class JSI_EXPORT Runtime {
virtual std::u16string utf16(const String& str);
virtual std::u16string utf16(const PropNameID& sym);

/// Invokes the provided callback \p cb with the String content as either
/// ASCII or UTF16 String. It's possible for the callback to be called
/// multiple times, potentially with different types of String.
virtual void getStringData(
const jsi::String& str,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num));

/// Invokes the provided callback \p cb with the PropNameID content as either
/// ASCII or UTF16 String. It's possible for the callback to be called
/// multiple times, potentially with different types of String.
virtual void getPropNameIdData(
const jsi::PropNameID& sym,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num));

// These exist so derived classes can access the private parts of
// Value, Symbol, String, and Object, which are all friends of Runtime.
template <typename T>
Expand Down Expand Up @@ -509,6 +525,20 @@ class JSI_EXPORT PropNameID : public Pointer {
return runtime.utf16(*this);
}

/// Invokes the user provided callback to process the content in PropNameId.
/// The callback must take in three arguments: bool ascii, const void* data,
/// and size_t num, respectively. The callback is responsible for handling
/// both ASCII and UTF16 string.
template <typename CB>
void getPropNameIdData(Runtime& runtime, const CB& cb) const {
runtime.getPropNameIdData(
*this,
&cb,
[](const void* ctx, bool ascii, const void* data, size_t num) {
(*((const CB*)ctx))(ascii, data, num);
});
}

static bool compare(
Runtime& runtime,
const jsi::PropNameID& a,
Expand Down Expand Up @@ -664,6 +694,20 @@ class JSI_EXPORT String : public Pointer {
return runtime.utf16(*this);
}

/// Invokes the user provided callback to process content in String. The
/// callback must take in three arguments: bool ascii, const void* data, and
/// size_t num, respectively. The callback is responsible for handling both
/// ASCII and UTF16 string.
template <typename CB>
void getStringData(Runtime& runtime, const CB& cb) const {
runtime.getStringData(
*this,
&cb,
[](const void* ctx, bool ascii, const void* data, size_t num) {
(*((const CB*)ctx))(ascii, data, num);
});
}

friend class Runtime;
friend class Value;
};
Expand Down
28 changes: 28 additions & 0 deletions packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,34 @@ TEST_P(JSITest, UTF16Test) {
EXPECT_EQ(str.utf16(rd), u"\uFFFD\u007A");
}

TEST_P(JSITest, GetStringDataTest) {
// This Runtime Decorator is used to test the default getStringData
// implementation for VMs that do not provide their own implementation
class RD : public RuntimeDecorator<Runtime, Runtime> {
public:
RD(Runtime& rt) : RuntimeDecorator(rt) {}

void getStringData(
const String& str,
const void* ctx,
void (*cb)(const void* ctx, bool ascii, const void* data, size_t num))
override {
Runtime::getStringData(str, ctx, cb);
}
};

RD rd = RD(rt);
String str = String::createFromUtf8(rd, "hello👋");

std::u16string buf;
auto cb = [&buf](bool ascii, const void* data, size_t num) {
buf = (const char16_t*)data;
};

str.getStringData(rd, cb);
EXPECT_EQ(buf, str.utf16(rd));
}

INSTANTIATE_TEST_CASE_P(
Runtimes,
JSITest,
Expand Down

0 comments on commit d649132

Please sign in to comment.