From 3c78839c47cb126eb3350839f2c9f54836f3c360 Mon Sep 17 00:00:00 2001 From: Jan Cristina Date: Fri, 8 Nov 2024 23:09:07 +0100 Subject: [PATCH] fix js str decode --- feature_tests/c/include/MyString.h | 2 ++ feature_tests/cpp/include/MyString.d.hpp | 2 ++ feature_tests/cpp/include/MyString.hpp | 7 ++++++ feature_tests/dart/lib/src/MyString.g.dart | 12 ++++++++++ feature_tests/js/api/BorrowedFields.mjs | 6 ++--- .../js/api/BorrowedFieldsReturning.mjs | 2 +- .../js/api/BorrowedFieldsWithBounds.mjs | 6 ++--- feature_tests/js/api/MyString.d.ts | 2 ++ feature_tests/js/api/MyString.mjs | 17 ++++++++++++++ feature_tests/js/api/OpaqueMutexedString.mjs | 2 +- feature_tests/js/api/OptionString.mjs | 2 +- feature_tests/js/api/Utf16Wrap.mjs | 2 +- feature_tests/js/test/slices-ts.mjs | 4 ++++ feature_tests/js/test/slices-ts.mts | 5 ++++ feature_tests/js/test/slices.mjs | 23 +++++++++++-------- .../dev/diplomattest/somelib/MyString.kt | 7 ++++++ feature_tests/src/slices.rs | 4 ++++ tool/src/js/converter.rs | 4 ++-- 18 files changed, 88 insertions(+), 21 deletions(-) diff --git a/feature_tests/c/include/MyString.h b/feature_tests/c/include/MyString.h index dc4b64d37..ea59de3e0 100644 --- a/feature_tests/c/include/MyString.h +++ b/feature_tests/c/include/MyString.h @@ -29,6 +29,8 @@ void MyString_get_str(const MyString* self, DiplomatWrite* write); void MyString_string_transform(DiplomatStringView foo, DiplomatWrite* write); +DiplomatStringView MyString_borrow(const MyString* self); + void MyString_destroy(MyString* self); diff --git a/feature_tests/cpp/include/MyString.d.hpp b/feature_tests/cpp/include/MyString.d.hpp index d25985566..1dbd0fb0f 100644 --- a/feature_tests/cpp/include/MyString.d.hpp +++ b/feature_tests/cpp/include/MyString.d.hpp @@ -31,6 +31,8 @@ class MyString { inline static diplomat::result string_transform(std::string_view foo); + inline std::string_view borrow() const; + inline const diplomat::capi::MyString* AsFFI() const; inline diplomat::capi::MyString* AsFFI(); inline static const MyString* FromFFI(const diplomat::capi::MyString* ptr); diff --git a/feature_tests/cpp/include/MyString.hpp b/feature_tests/cpp/include/MyString.hpp index 1a804d60d..e95bf6734 100644 --- a/feature_tests/cpp/include/MyString.hpp +++ b/feature_tests/cpp/include/MyString.hpp @@ -28,6 +28,8 @@ namespace capi { void MyString_string_transform(diplomat::capi::DiplomatStringView foo, diplomat::capi::DiplomatWrite* write); + diplomat::capi::DiplomatStringView MyString_borrow(const diplomat::capi::MyString* self); + void MyString_destroy(MyString* self); @@ -77,6 +79,11 @@ inline diplomat::result MyString::string_trans return diplomat::Ok(std::move(output)); } +inline std::string_view MyString::borrow() const { + auto result = diplomat::capi::MyString_borrow(this->AsFFI()); + return std::string_view(result.data, result.len); +} + inline const diplomat::capi::MyString* MyString::AsFFI() const { return reinterpret_cast(this); } diff --git a/feature_tests/dart/lib/src/MyString.g.dart b/feature_tests/dart/lib/src/MyString.g.dart index e26ae92c9..5f6b447d0 100644 --- a/feature_tests/dart/lib/src/MyString.g.dart +++ b/feature_tests/dart/lib/src/MyString.g.dart @@ -61,6 +61,13 @@ final class MyString implements ffi.Finalizable { _MyString_string_transform(foo._utf8AllocIn(temp.arena), write._ffi); return write.finalize(); } + + String borrow() { + // This lifetime edge depends on lifetimes: 'a + core.List aEdges = [this]; + final result = _MyString_borrow(_ffi); + return result._toDart(aEdges); + } } @meta.RecordUse() @@ -102,3 +109,8 @@ external void _MyString_get_str(ffi.Pointer self, ffi.Pointer)>(isLeaf: true, symbol: 'MyString_string_transform') // ignore: non_constant_identifier_names external void _MyString_string_transform(_SliceUtf8 foo, ffi.Pointer write); + +@meta.RecordUse() +@ffi.Native<_SliceUtf8 Function(ffi.Pointer)>(isLeaf: true, symbol: 'MyString_borrow') +// ignore: non_constant_identifier_names +external _SliceUtf8 _MyString_borrow(ffi.Pointer self); diff --git a/feature_tests/js/api/BorrowedFields.mjs b/feature_tests/js/api/BorrowedFields.mjs index 99dfcfffc..d8b4ba518 100644 --- a/feature_tests/js/api/BorrowedFields.mjs +++ b/feature_tests/js/api/BorrowedFields.mjs @@ -83,11 +83,11 @@ export class BorrowedFields { } var structObj = {}; const aDeref = ptr; - structObj.a = new diplomatRuntime.DiplomatSliceStr(wasm, aDeref, "string16", aEdges); + structObj.a = new diplomatRuntime.DiplomatSliceStr(wasm, aDeref, "string16", aEdges).getValue(); const bDeref = ptr + 8; - structObj.b = new diplomatRuntime.DiplomatSliceStr(wasm, bDeref, "string8", aEdges); + structObj.b = new diplomatRuntime.DiplomatSliceStr(wasm, bDeref, "string8", aEdges).getValue(); const cDeref = ptr + 16; - structObj.c = new diplomatRuntime.DiplomatSliceStr(wasm, cDeref, "string8", aEdges); + structObj.c = new diplomatRuntime.DiplomatSliceStr(wasm, cDeref, "string8", aEdges).getValue(); return new BorrowedFields(structObj, internalConstructor); } diff --git a/feature_tests/js/api/BorrowedFieldsReturning.mjs b/feature_tests/js/api/BorrowedFieldsReturning.mjs index 76683025f..b80f546ec 100644 --- a/feature_tests/js/api/BorrowedFieldsReturning.mjs +++ b/feature_tests/js/api/BorrowedFieldsReturning.mjs @@ -52,7 +52,7 @@ export class BorrowedFieldsReturning { } var structObj = {}; const bytesDeref = ptr; - structObj.bytes = new diplomatRuntime.DiplomatSliceStr(wasm, bytesDeref, "string8", aEdges); + structObj.bytes = new diplomatRuntime.DiplomatSliceStr(wasm, bytesDeref, "string8", aEdges).getValue(); return new BorrowedFieldsReturning(structObj, internalConstructor); } diff --git a/feature_tests/js/api/BorrowedFieldsWithBounds.mjs b/feature_tests/js/api/BorrowedFieldsWithBounds.mjs index 851f20c7e..e492f7bb0 100644 --- a/feature_tests/js/api/BorrowedFieldsWithBounds.mjs +++ b/feature_tests/js/api/BorrowedFieldsWithBounds.mjs @@ -85,11 +85,11 @@ export class BorrowedFieldsWithBounds { } var structObj = {}; const fieldADeref = ptr; - structObj.fieldA = new diplomatRuntime.DiplomatSliceStr(wasm, fieldADeref, "string16", aEdges); + structObj.fieldA = new diplomatRuntime.DiplomatSliceStr(wasm, fieldADeref, "string16", aEdges).getValue(); const fieldBDeref = ptr + 8; - structObj.fieldB = new diplomatRuntime.DiplomatSliceStr(wasm, fieldBDeref, "string8", bEdges); + structObj.fieldB = new diplomatRuntime.DiplomatSliceStr(wasm, fieldBDeref, "string8", bEdges).getValue(); const fieldCDeref = ptr + 16; - structObj.fieldC = new diplomatRuntime.DiplomatSliceStr(wasm, fieldCDeref, "string8", cEdges); + structObj.fieldC = new diplomatRuntime.DiplomatSliceStr(wasm, fieldCDeref, "string8", cEdges).getValue(); return new BorrowedFieldsWithBounds(structObj, internalConstructor); } diff --git a/feature_tests/js/api/MyString.d.ts b/feature_tests/js/api/MyString.d.ts index 6c42f059b..e2d9609fb 100644 --- a/feature_tests/js/api/MyString.d.ts +++ b/feature_tests/js/api/MyString.d.ts @@ -19,4 +19,6 @@ export class MyString { get str(): string; static stringTransform(foo: string): string; + + borrow(): string; } \ No newline at end of file diff --git a/feature_tests/js/api/MyString.mjs b/feature_tests/js/api/MyString.mjs index 6da475162..ea01b1c64 100644 --- a/feature_tests/js/api/MyString.mjs +++ b/feature_tests/js/api/MyString.mjs @@ -141,4 +141,21 @@ export class MyString { write.free(); } } + + borrow() { + const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 8, 4, false); + + // This lifetime edge depends on lifetimes 'a + let aEdges = [this]; + + const result = wasm.MyString_borrow(diplomatReceive.buffer, this.ffiValue); + + try { + return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string8", aEdges).getValue(); + } + + finally { + diplomatReceive.free(); + } + } } \ No newline at end of file diff --git a/feature_tests/js/api/OpaqueMutexedString.mjs b/feature_tests/js/api/OpaqueMutexedString.mjs index 7f0e9d0e1..69abbaa8a 100644 --- a/feature_tests/js/api/OpaqueMutexedString.mjs +++ b/feature_tests/js/api/OpaqueMutexedString.mjs @@ -109,7 +109,7 @@ export class OpaqueMutexedString { const result = wasm.OpaqueMutexedString_dummy_str(diplomatReceive.buffer, this.ffiValue); try { - return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string8", aEdges); + return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string8", aEdges).getValue(); } finally { diff --git a/feature_tests/js/api/OptionString.mjs b/feature_tests/js/api/OptionString.mjs index d2997f5c9..a3ea4e40a 100644 --- a/feature_tests/js/api/OptionString.mjs +++ b/feature_tests/js/api/OptionString.mjs @@ -75,7 +75,7 @@ export class OptionString { if (!diplomatReceive.resultFlag) { return null; } - return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string8", aEdges); + return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string8", aEdges).getValue(); } finally { diff --git a/feature_tests/js/api/Utf16Wrap.mjs b/feature_tests/js/api/Utf16Wrap.mjs index 952c5bdd6..1bb497ea3 100644 --- a/feature_tests/js/api/Utf16Wrap.mjs +++ b/feature_tests/js/api/Utf16Wrap.mjs @@ -71,7 +71,7 @@ export class Utf16Wrap { const result = wasm.Utf16Wrap_borrow_cont(diplomatReceive.buffer, this.ffiValue); try { - return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string16", aEdges); + return new diplomatRuntime.DiplomatSliceStr(wasm, diplomatReceive.buffer, "string16", aEdges).getValue(); } finally { diff --git a/feature_tests/js/test/slices-ts.mjs b/feature_tests/js/test/slices-ts.mjs index df199fccb..a675bda02 100644 --- a/feature_tests/js/test/slices-ts.mjs +++ b/feature_tests/js/test/slices-ts.mjs @@ -8,6 +8,10 @@ test("String List", (t) => { let str = MyString.newFromFirst(["This", "is", "a", "test."]); t.is(str.str, "This"); }); +test("MyString borrow", (t) => { + let str = MyString.new_("This is a test."); + t.is(str.borrow(), "This is a test."); +}); test("Float64Vec", (t) => { let input = [1, 2, 3, 4, 5]; let data = Float64Vec.newIsize(input); diff --git a/feature_tests/js/test/slices-ts.mts b/feature_tests/js/test/slices-ts.mts index b67ab7551..bad6434f8 100644 --- a/feature_tests/js/test/slices-ts.mts +++ b/feature_tests/js/test/slices-ts.mts @@ -12,6 +12,11 @@ test("String List", (t) => { t.is(str.str, "This"); }); +test("MyString borrow", (t) => { + let str = MyString.new_("This is a test."); + t.is(str.borrow(), "This is a test."); +}); + test("Float64Vec", (t) => { let input = [1, 2, 3, 4, 5]; let data = Float64Vec.newIsize(input); diff --git a/feature_tests/js/test/slices.mjs b/feature_tests/js/test/slices.mjs index 07f6467d3..4b22a8e58 100644 --- a/feature_tests/js/test/slices.mjs +++ b/feature_tests/js/test/slices.mjs @@ -1,18 +1,23 @@ -import test from 'ava'; -import { MyString, Float64Vec} from "diplomat-wasm-js-feature-tests"; +import test from "ava"; +import { MyString, Float64Vec } from "diplomat-wasm-js-feature-tests"; test("MyString functionality", (t) => { - let str = MyString.new_("This is a test value."); - t.is(str.str, "This is a test value."); + let str = MyString.new_("This is a test value."); + t.is(str.str, "This is a test value."); }); test("String List", (t) => { - let str = MyString.newFromFirst(["This", "is", "a", "test."]); - t.is(str.str, "This"); + let str = MyString.newFromFirst(["This", "is", "a", "test."]); + t.is(str.str, "This"); +}); + +test("MyString borrow", (t) => { + let str = MyString.new_("This is a test."); + t.is(str.borrow(), "This is a test."); }); test("Float64Vec", (t) => { - let input = [1, 2, 3, 4, 5]; - let data = Float64Vec.newIsize(input); - t.deepEqual(data.borrow(), input); + let input = [1, 2, 3, 4, 5]; + let data = Float64Vec.newIsize(input); + t.deepEqual(data.borrow(), input); }); diff --git a/feature_tests/kotlin/somelib/src/main/kotlin/dev/diplomattest/somelib/MyString.kt b/feature_tests/kotlin/somelib/src/main/kotlin/dev/diplomattest/somelib/MyString.kt index 5e12e7187..9badd69b9 100644 --- a/feature_tests/kotlin/somelib/src/main/kotlin/dev/diplomattest/somelib/MyString.kt +++ b/feature_tests/kotlin/somelib/src/main/kotlin/dev/diplomattest/somelib/MyString.kt @@ -15,6 +15,7 @@ internal interface MyStringLib: Library { fun MyString_set_str(handle: Pointer, newStr: Slice): Unit fun MyString_get_str(handle: Pointer, write: Pointer): Unit fun MyString_string_transform(foo: Slice, write: Pointer): Unit + fun MyString_borrow(handle: Pointer): Slice } class MyString internal constructor ( @@ -105,5 +106,11 @@ class MyString internal constructor ( val returnString = DW.writeToString(write) return returnString } + + fun borrow(): String { + + val returnVal = lib.MyString_borrow(handle); + return PrimitiveArrayTools.getUtf8(returnVal) + } } diff --git a/feature_tests/src/slices.rs b/feature_tests/src/slices.rs index 90498a92e..23bba5f17 100644 --- a/feature_tests/src/slices.rs +++ b/feature_tests/src/slices.rs @@ -40,6 +40,10 @@ mod ffi { let _ = foo; let _ = write; } + + pub fn borrow<'a>(&'a self) -> DiplomatStrSlice<'a> { + AsRef::<[u8]>::as_ref(&self.0).into() + } } #[diplomat::opaque] diff --git a/tool/src/js/converter.rs b/tool/src/js/converter.rs index 90884f9de..7a3b74b2d 100644 --- a/tool/src/js/converter.rs +++ b/tool/src/js/converter.rs @@ -244,7 +244,7 @@ impl<'jsctx, 'tcx> TyGenContext<'jsctx, 'tcx> { ) .into(), hir::Slice::Str(_, encoding) => format!( - r#"new diplomatRuntime.DiplomatSliceStr(wasm, {variable_name}, "string{}", {edges})"#, + r#"new diplomatRuntime.DiplomatSliceStr(wasm, {variable_name}, "string{}", {edges}).getValue()"#, match encoding { hir::StringEncoding::Utf8 | hir::StringEncoding::UnvalidatedUtf8 => 8, hir::StringEncoding::UnvalidatedUtf16 => 16, @@ -257,7 +257,7 @@ impl<'jsctx, 'tcx> TyGenContext<'jsctx, 'tcx> { // We basically iterate through and read each string into the array. // TODO: Need a test for this. format!( - r#"new diplomatRuntime.DiplomatSliceStrings(wasm, {variable_name}, "string{}", {edges})"#, + r#"new diplomatRuntime.DiplomatSliceStrings(wasm, {variable_name}, "string{}", {edges}).getValue()"#, match encoding { hir::StringEncoding::Utf8 | hir::StringEncoding::UnvalidatedUtf8 => 8,