Skip to content

Commit c6f1225

Browse files
tsaichienfacebook-github-bot
authored andcommitted
Add default getStringData/getPropNameIdData implementation (#47530)
Summary: Pull Request resolved: #47530 Adds the default implementation for `getStringData`/`getPropNameIdData` for VMs that do not provide their own implementation Changelog: [Internal] Reviewed By: neildhar Differential Revision: D65638889 fbshipit-source-id: 0a97569433c09ffafbd08fec5d9c9fbf5639b778
1 parent e9f2791 commit c6f1225

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

packages/react-native/ReactCommon/jsi/jsi/decorator.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,22 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
232232
return plain_.utf16(sym);
233233
}
234234

235+
void getStringData(
236+
const jsi::String& str,
237+
void* ctx,
238+
void (
239+
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
240+
plain_.getStringData(str, ctx, cb);
241+
}
242+
243+
void getPropNameIdData(
244+
const jsi::PropNameID& sym,
245+
void* ctx,
246+
void (
247+
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
248+
plain_.getPropNameIdData(sym, ctx, cb);
249+
}
250+
235251
Object createObject() override {
236252
return plain_.createObject();
237253
};
@@ -690,6 +706,24 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
690706
return RD::utf16(sym);
691707
}
692708

709+
void getStringData(
710+
const jsi::String& str,
711+
void* ctx,
712+
void (
713+
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
714+
Around around{with_};
715+
RD::getStringData(str, ctx, cb);
716+
}
717+
718+
void getPropNameIdData(
719+
const jsi::PropNameID& sym,
720+
void* ctx,
721+
void (
722+
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
723+
Around around{with_};
724+
RD::getPropNameIdData(sym, ctx, cb);
725+
}
726+
693727
Value createValueFromJsonUtf8(const uint8_t* json, size_t length) override {
694728
Around around{with_};
695729
return RD::createValueFromJsonUtf8(json, length);

packages/react-native/ReactCommon/jsi/jsi/jsi.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,22 @@ std::u16string Runtime::utf16(const String& str) {
258258
return convertUTF8ToUTF16(utf8Str);
259259
}
260260

261+
void Runtime::getStringData(
262+
const jsi::String& str,
263+
void* ctx,
264+
void (*cb)(void* ctx, bool ascii, const void* data, size_t num)) {
265+
auto utf16Str = utf16(str);
266+
cb(ctx, false, utf16Str.data(), utf16Str.size());
267+
}
268+
269+
void Runtime::getPropNameIdData(
270+
const jsi::PropNameID& sym,
271+
void* ctx,
272+
void (*cb)(void* ctx, bool ascii, const void* data, size_t num)) {
273+
auto utf16Str = utf16(sym);
274+
cb(ctx, false, utf16Str.data(), utf16Str.size());
275+
}
276+
261277
Pointer& Pointer::operator=(Pointer&& other) noexcept {
262278
if (ptr_) {
263279
ptr_->invalidate();

packages/react-native/ReactCommon/jsi/jsi/jsi.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,34 @@ class JSI_EXPORT Runtime {
402402
virtual std::u16string utf16(const String& str);
403403
virtual std::u16string utf16(const PropNameID& sym);
404404

405+
/// Invokes the provided callback \p cb with the String content in \p str.
406+
/// The callback must take in three arguments: bool ascii, const void* data,
407+
/// and size_t num, respectively. \p ascii indicates whether the \p data
408+
/// passed to the callback should be interpreted as a pointer to a sequence of
409+
/// \p num ASCII characters or UTF16 characters. Depending on the internal
410+
/// representation of the string, the function may invoke the callback
411+
/// multiple times, with a different format on each invocation. The callback
412+
/// must not access runtime functionality, as any operation on the runtime may
413+
/// invalidate the data pointers.
414+
virtual void getStringData(
415+
const jsi::String& str,
416+
void* ctx,
417+
void (*cb)(void* ctx, bool ascii, const void* data, size_t num));
418+
419+
/// Invokes the provided callback \p cb with the PropNameID content in \p sym.
420+
/// The callback must take in three arguments: bool ascii, const void* data,
421+
/// and size_t num, respectively. \p ascii indicates whether the \p data
422+
/// passed to the callback should be interpreted as a pointer to a sequence of
423+
/// \p num ASCII characters or UTF16 characters. Depending on the internal
424+
/// representation of the string, the function may invoke the callback
425+
/// multiple times, with a different format on each invocation. The callback
426+
/// must not access runtime functionality, as any operation on the runtime may
427+
/// invalidate the data pointers.
428+
virtual void getPropNameIdData(
429+
const jsi::PropNameID& sym,
430+
void* ctx,
431+
void (*cb)(void* ctx, bool ascii, const void* data, size_t num));
432+
405433
// These exist so derived classes can access the private parts of
406434
// Value, Symbol, String, and Object, which are all friends of Runtime.
407435
template <typename T>
@@ -509,6 +537,22 @@ class JSI_EXPORT PropNameID : public Pointer {
509537
return runtime.utf16(*this);
510538
}
511539

540+
/// Invokes the user provided callback to process the content in PropNameId.
541+
/// The callback must take in three arguments: bool ascii, const void* data,
542+
/// and size_t num, respectively. \p ascii indicates whether the \p data
543+
/// passed to the callback should be interpreted as a pointer to a sequence of
544+
/// \p num ASCII characters or UTF16 characters. The function may invoke the
545+
/// callback multiple times, with a different format on each invocation. The
546+
/// callback must not access runtime functionality, as any operation on the
547+
/// runtime may invalidate the data pointers.
548+
template <typename CB>
549+
void getPropNameIdData(Runtime& runtime, CB& cb) const {
550+
runtime.getPropNameIdData(
551+
*this, &cb, [](void* ctx, bool ascii, const void* data, size_t num) {
552+
(*((CB*)ctx))(ascii, data, num);
553+
});
554+
}
555+
512556
static bool compare(
513557
Runtime& runtime,
514558
const jsi::PropNameID& a,
@@ -664,6 +708,22 @@ class JSI_EXPORT String : public Pointer {
664708
return runtime.utf16(*this);
665709
}
666710

711+
/// Invokes the user provided callback to process content in String. The
712+
/// callback must take in three arguments: bool ascii, const void* data, and
713+
/// size_t num, respectively. \p ascii indicates whether the \p data passed to
714+
/// the callback should be interpreted as a pointer to a sequence of \p num
715+
/// ASCII characters or UTF16 characters. The function may invoke the callback
716+
/// multiple times, with a different format on each invocation. The callback
717+
/// must not access runtime functionality, as any operation on the runtime may
718+
/// invalidate the data pointers.
719+
template <typename CB>
720+
void getStringData(Runtime& runtime, CB& cb) const {
721+
runtime.getStringData(
722+
*this, &cb, [](void* ctx, bool ascii, const void* data, size_t num) {
723+
(*((CB*)ctx))(ascii, data, num);
724+
});
725+
}
726+
667727
friend class Runtime;
668728
friend class Value;
669729
};

packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,6 +1635,35 @@ TEST_P(JSITest, UTF16Test) {
16351635
EXPECT_EQ(str.utf16(rd), u"\uFFFD\u007A");
16361636
}
16371637

1638+
TEST_P(JSITest, GetStringDataTest) {
1639+
// This Runtime Decorator is used to test the default getStringData
1640+
// implementation for VMs that do not provide their own implementation
1641+
class RD : public RuntimeDecorator<Runtime, Runtime> {
1642+
public:
1643+
RD(Runtime& rt) : RuntimeDecorator(rt) {}
1644+
1645+
void getStringData(
1646+
const String& str,
1647+
void* ctx,
1648+
void (*cb)(void* ctx, bool ascii, const void* data, size_t num))
1649+
override {
1650+
Runtime::getStringData(str, ctx, cb);
1651+
}
1652+
};
1653+
1654+
RD rd = RD(rt);
1655+
String str = String::createFromUtf8(rd, "hello👋");
1656+
1657+
std::u16string buf;
1658+
auto cb = [&buf](bool ascii, const void* data, size_t num) {
1659+
assert(!ascii && "Default implementation is always utf16");
1660+
buf.append((const char16_t*)data, num);
1661+
};
1662+
1663+
str.getStringData(rd, cb);
1664+
EXPECT_EQ(buf, str.utf16(rd));
1665+
}
1666+
16381667
INSTANTIATE_TEST_CASE_P(
16391668
Runtimes,
16401669
JSITest,

0 commit comments

Comments
 (0)