Skip to content

Commit 29acf39

Browse files
Googlercopybara-github
authored andcommitted
Internal Change
PiperOrigin-RevId: 823632511
1 parent 3ec56d6 commit 29acf39

File tree

7 files changed

+120
-262
lines changed

7 files changed

+120
-262
lines changed

bazel/llvm.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _llvm_loader_repository(repository_ctx):
5353
executable = False,
5454
)
5555

56-
LLVM_COMMIT_SHA = "9625cf6cc0e3e530ea0bed971d85b363f77c49d8"
56+
LLVM_COMMIT_SHA = "741ba8209c1f9bd5b1a145d9c137f5e18bfffb84"
5757

5858
def llvm_loader_repository_dependencies():
5959
# This *declares* the dependency, but it won't actually be *downloaded* unless it's used.

cc_bindings_from_rs/test/golden/composable_bridging.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Exceptions. See /LICENSE for license information.
33
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

5-
use bridge_rust::{CrubitAbi, Decoder, Encoder};
5+
use bridge_rust::{transmute_abi, CrubitAbi, Decoder, Encoder};
66
use std::mem;
77

88
pub fn returns_some_int() -> Option<i32> {
@@ -34,28 +34,28 @@ pub fn maybe_int_slice() -> Option<*const [i32]> {
3434
Some(&[1, 2, 3][..] as *const [i32])
3535
}
3636

37-
pub struct MyOptionRustAbi<T>(core::marker::PhantomData<T>);
37+
pub struct MyOptionRustAbi<A>(pub A);
3838

3939
unsafe impl<A: CrubitAbi> CrubitAbi for MyOptionRustAbi<A> {
4040
type Value = MyOptionRust<A::Value>;
4141

4242
const SIZE: usize = mem::size_of::<bool>() + A::SIZE;
4343

44-
fn encode(value: Self::Value, encoder: &mut Encoder) {
44+
fn encode(self, value: Self::Value, encoder: &mut Encoder) {
4545
if let Some(inner) = value.0 {
46-
encoder.encode_transmute(true);
47-
encoder.encode::<A>(inner);
46+
transmute_abi().encode(true, encoder);
47+
self.0.encode(inner, encoder);
4848
} else {
49-
encoder.encode_transmute(false);
49+
transmute_abi().encode(false, encoder);
5050
}
5151
}
5252

53-
unsafe fn decode(decoder: &mut Decoder) -> Self::Value {
53+
unsafe fn decode(self, decoder: &mut Decoder) -> Self::Value {
5454
// SAFETY: the caller guarantees that the buffer contains a bool, and if the bool is true,
5555
// that the buffer also contains the value.
5656
unsafe {
57-
if decoder.decode_transmute() {
58-
MyOptionRust(Some(decoder.decode::<A>()))
57+
if transmute_abi().decode(decoder) {
58+
MyOptionRust(Some(self.0.decode(decoder)))
5959
} else {
6060
MyOptionRust(None)
6161
}

examples/types/bridging/either_internal.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,26 @@ struct EitherAbi {
2727
sizeof(bool) +
2828
(LeftAbi::kSize > RightAbi::kSize ? LeftAbi::kSize : RightAbi::kSize);
2929

30-
static void Encode(Value value, crubit::Encoder& encoder) {
30+
void Encode(Value value, crubit::Encoder& encoder) && {
3131
if (value.is_left) {
32-
encoder.EncodeTransmute(true);
33-
encoder.Encode<LeftAbi>(std::move(value.left));
32+
crubit::TransmuteAbi<bool>().Encode(true, encoder);
33+
std::move(left_abi).Encode(std::move(value.left), encoder);
3434
} else {
35-
encoder.EncodeTransmute(false);
36-
encoder.Encode<RightAbi>(std::move(value.right));
35+
crubit::TransmuteAbi<bool>().Encode(false, encoder);
36+
std::move(right_abi).Encode(std::move(value.right), encoder);
3737
}
3838
}
3939

40-
static Value Decode(crubit::Decoder& decoder) {
41-
if (decoder.DecodeTransmute<bool>()) {
40+
Value Decode(crubit::Decoder& decoder) && {
41+
if (crubit::TransmuteAbi<bool>().Decode(decoder)) {
4242
return {
4343
.is_left = true,
44-
.left = decoder.Decode<LeftAbi>(),
44+
.left = std::move(left_abi).Decode(decoder),
4545
};
4646
} else {
4747
return {
4848
.is_left = false,
49-
.right = decoder.Decode<RightAbi>(),
49+
.right = std::move(right_abi).Decode(decoder),
5050
};
5151
}
5252
}

rs_bindings_from_cc/test/bridging/composable_bridging_lib.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ template <typename Abi>
3030
struct Vec3Abi {
3131
using Value = Vec3<typename Abi::Value>;
3232
static constexpr size_t kSize = Abi::kSize * 3;
33-
static void Encode(Value value, crubit::Encoder& encoder) {
34-
encoder.Encode<Abi>(std::move(value.x));
35-
encoder.Encode<Abi>(std::move(value.y));
36-
encoder.Encode<Abi>(std::move(value.z));
33+
void Encode(Value value, crubit::Encoder& encoder) && {
34+
abi.Encode(std::move(value.x), encoder);
35+
abi.Encode(std::move(value.y), encoder);
36+
abi.Encode(std::move(value.z), encoder);
3737
}
38-
static Value Decode(crubit::Decoder& decoder) {
38+
Value Decode(crubit::Decoder& decoder) && {
3939
return {
40-
.x = decoder.Decode<Abi>(),
41-
.y = decoder.Decode<Abi>(),
42-
.z = decoder.Decode<Abi>(),
40+
.x = abi.Decode(decoder),
41+
.y = abi.Decode(decoder),
42+
.z = abi.Decode(decoder),
4343
};
4444
}
4545

support/bridge.h

Lines changed: 43 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ constexpr bool is_crubit_abi = requires {
136136
// };
137137
// ```
138138
{
139-
Abi::Encode(std::declval<typename Abi::Value>(), std::declval<Encoder&>())
139+
std::declval<Abi&&>().Encode(std::declval<typename Abi::Value>(),
140+
std::declval<Encoder&>())
140141
} -> std::same_as<void>;
141142

142143
// Decodes a [`Value`], advancing the decoder's position by `kSize` bytes.
@@ -171,27 +172,19 @@ constexpr bool is_crubit_abi = requires {
171172
// The caller guarantees that the buffer's current position contains a
172173
// `Value` that was encoded with this ABI (either from Rust or C++).
173174
{
174-
Abi::Decode(std::declval<Decoder&>())
175+
std::declval<Abi&&>().Decode(std::declval<Decoder&>())
175176
} -> std::same_as<typename Abi::Value>;
176177
};
177178

178179
namespace internal {
179180

180181
template <typename Abi>
181182
requires(is_crubit_abi<Abi>)
182-
void Encode(unsigned char* buf, typename Abi::Value value);
183+
void Encode(Abi&& abi, unsigned char* buf, typename Abi::Value value);
183184

184185
template <typename Abi>
185186
requires(is_crubit_abi<Abi>)
186-
void Encode(Abi&&, unsigned char* buf, typename Abi::Value value);
187-
188-
template <typename Abi>
189-
requires(is_crubit_abi<Abi>)
190-
typename Abi::Value Decode(const unsigned char* buf);
191-
192-
template <typename Abi>
193-
requires(is_crubit_abi<Abi>)
194-
typename Abi::Value Decode(Abi&&, const unsigned char* buf);
187+
typename Abi::Value Decode(Abi&& abi, const unsigned char* buf);
195188

196189
} // namespace internal
197190

@@ -202,17 +195,6 @@ class Encoder {
202195
: remaining_bytes_(remaining_bytes), buf_(buf) {}
203196

204197
public:
205-
// Encodes a value by a provided schema.
206-
template <typename Abi>
207-
requires(is_crubit_abi<Abi>)
208-
void Encode(typename Abi::Value value) & {
209-
Abi::Encode(std::move(value), *this);
210-
}
211-
212-
// Encodes a value via `memcpy`.
213-
template <typename T>
214-
void EncodeTransmute(T value) &;
215-
216198
void* Next(size_t size) & {
217199
remaining_bytes_ -= size;
218200
return buf_ + remaining_bytes_;
@@ -221,11 +203,7 @@ class Encoder {
221203
private:
222204
template <typename Abi>
223205
requires(is_crubit_abi<Abi>)
224-
friend void internal::Encode(unsigned char* buf, typename Abi::Value value);
225-
226-
template <typename Abi>
227-
requires(is_crubit_abi<Abi>)
228-
friend void internal::Encode(Abi&&, unsigned char* buf,
206+
friend void internal::Encode(Abi&& abi, unsigned char* buf,
229207
typename Abi::Value value);
230208
// The number of bytes remaining in the buffer.
231209
size_t remaining_bytes_;
@@ -239,19 +217,6 @@ class Decoder {
239217
: remaining_bytes_(remaining_bytes), buf_(buf) {}
240218

241219
public:
242-
// Decodes a value by a provided schema. The caller must ensure that the
243-
// buffer contains a value that was encoded with the same schema.
244-
template <typename Abi>
245-
requires(is_crubit_abi<Abi>)
246-
typename Abi::Value Decode() & {
247-
return Abi::Decode(*this);
248-
}
249-
250-
// Decodes a value via `memcpy`. The caller must ensure that the buffer
251-
// contains a value that was encoded with ByTransmute.
252-
template <typename T>
253-
T DecodeTransmute() &;
254-
255220
const void* Next(size_t size) & {
256221
remaining_bytes_ -= size;
257222
return buf_ + remaining_bytes_;
@@ -260,10 +225,8 @@ class Decoder {
260225
private:
261226
template <typename Abi>
262227
requires(is_crubit_abi<Abi>)
263-
friend typename Abi::Value internal::Decode(const unsigned char* buf);
264-
template <typename Abi>
265-
requires(is_crubit_abi<Abi>)
266-
friend typename Abi::Value internal::Decode(Abi&&, const unsigned char* buf);
228+
friend typename Abi::Value internal::Decode(Abi&& abi,
229+
const unsigned char* buf);
267230
// The number of bytes remaining in the buffer.
268231
size_t remaining_bytes_;
269232
const unsigned char* buf_;
@@ -276,7 +239,7 @@ template <typename T>
276239
struct TransmuteAbi {
277240
using Value = T;
278241
static constexpr size_t kSize = sizeof(Value);
279-
static void Encode(Value value, Encoder& encoder) {
242+
void Encode(Value value, Encoder& encoder) && {
280243
// Move-construct the value into a type erased buffer, ensuring that value
281244
// is in a "moved from" state. Then copy the value into the encoder buffer.
282245
// We use an intermediate buffer and a memcpy to avoid strict aliasing
@@ -285,7 +248,7 @@ struct TransmuteAbi {
285248
alignas(Value) char buf[kSize];
286249
std::memcpy(encoder.Next(kSize), new (buf) Value(std::move(value)), kSize);
287250
}
288-
static Value Decode(Decoder& decoder) {
251+
Value Decode(Decoder& decoder) && {
289252
alignas(Value) char buf[kSize];
290253
// Copy the value from the decoder buffer into the intermediate buffer.
291254
std::memcpy(buf, decoder.Next(kSize), kSize);
@@ -294,30 +257,26 @@ struct TransmuteAbi {
294257
}
295258
};
296259

297-
template <typename T>
298-
void Encoder::EncodeTransmute(T value) & {
299-
TransmuteAbi<T>::Encode(std::move(value), *this);
300-
}
301-
302-
template <typename T>
303-
T Decoder::DecodeTransmute() & {
304-
return TransmuteAbi<T>::Decode(*this);
305-
}
306-
307260
template <typename... Abis>
308261
requires(is_crubit_abi<Abis> && ...)
309262
struct TupleAbi {
310263
using Value = std::tuple<typename Abis::Value...>;
311264
static constexpr size_t kSize = (0 + ... + Abis::kSize);
312-
static void Encode(Value value, Encoder& encoder) {
265+
void Encode(Value value, Encoder& encoder) && {
313266
std::apply(
314-
[&](typename Abis::Value&&... args) {
315-
(encoder.Encode<Abis>(args), ...);
267+
[&](auto&&... args) {
268+
return std::apply(
269+
[&](auto&&... abis) { (abis.Encode(args..., encoder), ...); },
270+
std::move(abis));
316271
},
317272
std::move(value));
318273
}
319-
static Value Decode(Decoder& decoder) {
320-
return std::make_tuple(decoder.Decode<Abis>()...);
274+
Value Decode(Decoder& decoder) && {
275+
return std::apply(
276+
[&](Abis&&... abis) {
277+
return std::make_tuple(abis.Decode(decoder)...);
278+
},
279+
std::move(abis));
321280
}
322281

323282
std::tuple<Abis...> abis;
@@ -330,14 +289,14 @@ struct PairAbi {
330289

331290
using Value = std::pair<typename Abi1::Value, typename Abi2::Value>;
332291
static constexpr size_t kSize = Abi1::kSize + Abi2::kSize;
333-
static void Encode(Value value, Encoder& encoder) {
334-
encoder.Encode<Abi1>(std::move(value.first));
335-
encoder.Encode<Abi2>(std::move(value.second));
292+
void Encode(Value value, Encoder& encoder) && {
293+
std::move(abis.first).Encode(std::move(value.first), encoder);
294+
std::move(abis.second).Encode(std::move(value.second), encoder);
336295
}
337-
static Value Decode(Decoder& decoder) {
296+
Value Decode(Decoder& decoder) && {
338297
return {
339-
.first = decoder.Decode<Abi1>(),
340-
.second = decoder.Decode<Abi2>(),
298+
.first = std::move(abis.first).Decode(decoder),
299+
.second = std::move(abis.second).Decode(decoder),
341300
};
342301
}
343302

@@ -352,19 +311,19 @@ template <typename Abi>
352311
struct OptionAbi {
353312
using Value = std::optional<typename Abi::Value>;
354313
static constexpr size_t kSize = sizeof(bool) + Abi::kSize;
355-
static void Encode(Value value, Encoder& encoder) {
314+
void Encode(Value value, Encoder& encoder) && {
356315
if (value.has_value()) {
357-
encoder.EncodeTransmute(true);
358-
encoder.Encode<Abi>(*std::move(value));
316+
TransmuteAbi<bool>().Encode(true, encoder);
317+
std::move(abi).Encode(*std::move(value), encoder);
359318
} else {
360-
encoder.EncodeTransmute(false);
319+
TransmuteAbi<bool>().Encode(false, encoder);
361320
}
362321
}
363-
static Value Decode(Decoder& decoder) {
364-
if (!decoder.DecodeTransmute<bool>()) {
322+
Value Decode(Decoder& decoder) && {
323+
if (!TransmuteAbi<bool>().Decode(decoder)) {
365324
return std::nullopt;
366325
}
367-
return decoder.Decode<Abi>();
326+
return abi.Decode(decoder);
368327
}
369328

370329
Abi abi;
@@ -379,12 +338,13 @@ template <typename T>
379338
struct BoxedAbi {
380339
using Value = T;
381340
static constexpr size_t kSize = sizeof(void*);
382-
static void Encode(Value value, Encoder& encoder) {
341+
void Encode(Value value, Encoder& encoder) && {
383342
void* box = new Value(std::move(value));
384-
encoder.EncodeTransmute(box);
343+
TransmuteAbi<void*>().Encode(box, encoder);
385344
}
386-
static Value Decode(Decoder& decoder) {
387-
Value* box = reinterpret_cast<Value*>(decoder.DecodeTransmute<void*>());
345+
Value Decode(Decoder& decoder) && {
346+
Value* box =
347+
reinterpret_cast<Value*>(TransmuteAbi<void*>().Decode(decoder));
388348
Value value(std::move(*box));
389349
delete box;
390350
return value;
@@ -395,34 +355,16 @@ namespace internal {
395355

396356
template <typename Abi>
397357
requires(is_crubit_abi<Abi>)
398-
void Encode(unsigned char* buf, typename Abi::Value value) {
358+
void Encode(Abi&& abi, unsigned char* buf, typename Abi::Value value) {
399359
Encoder encoder(Abi::kSize, buf);
400-
encoder.Encode<Abi>(std::move(value));
401-
}
402-
403-
// TODO(okabayashi): Overload for new Crubit codegen, where an instance of the
404-
// ABI is passed in. After the new codegen hits crosstool release, I will delete
405-
// other other overload and change the implementation here.
406-
template <typename Abi>
407-
requires(is_crubit_abi<Abi>)
408-
void Encode(Abi&&, unsigned char* buf, typename Abi::Value value) {
409-
Encode<Abi>(buf, std::move(value));
360+
std::forward<Abi>(abi).Encode(std::move(value), encoder);
410361
}
411362

412363
template <typename Abi>
413364
requires(is_crubit_abi<Abi>)
414-
typename Abi::Value Decode(const unsigned char* buf) {
365+
typename Abi::Value Decode(Abi&& abi, const unsigned char* buf) {
415366
Decoder decoder(Abi::kSize, buf);
416-
return decoder.Decode<Abi>();
417-
}
418-
419-
// TODO(okabayashi): Overload for new Crubit codegen, where an instance of the
420-
// ABI is passed in. After the new codegen hits crosstool release, I will delete
421-
// other other overload and change the implementation here.
422-
template <typename Abi>
423-
requires(is_crubit_abi<Abi>)
424-
typename Abi::Value Decode(Abi&&, const unsigned char* buf) {
425-
return Decode<Abi>(buf);
367+
return std::forward<Abi>(abi).Decode(decoder);
426368
}
427369

428370
} // namespace internal

0 commit comments

Comments
 (0)