Skip to content

Commit a0192d4

Browse files
committed
C++: Fix ABI mismatch with Slice on MSVC AArch64
The second constructor of `Slice` causes the Slice to be passed differently (in different register) as a return value. So remove that constructor and use a helper function to construct a Slice
1 parent fd28676 commit a0192d4

File tree

8 files changed

+65
-86
lines changed

8 files changed

+65
-86
lines changed

api/cpp/cbindgen.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,7 @@ fn gen_corelib(
410410
string_config.export.exclude = vec!["SharedString".into()];
411411
string_config.export.body.insert(
412412
"Slice".to_owned(),
413-
" const T &operator[](int i) const { return ptr[i]; }
414-
/// Note: this doesn't initialize Slice properly, but we need to keep the struct as compatible with C
415-
constexpr Slice() = default;
416-
/// Rust uses a NonNull, so even empty slices shouldn't use nullptr
417-
constexpr Slice(const T *ptr, uintptr_t len) : ptr(ptr ? const_cast<T*>(ptr) : reinterpret_cast<T*>(sizeof(T))), len(len) {}
418-
"
419-
.to_owned(),
413+
" const T &operator[](int i) const { return ptr[i]; }".to_owned(),
420414
);
421415
cbindgen::Builder::new()
422416
.with_config(string_config)

api/cpp/include/slint-interpreter.h

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -500,10 +500,7 @@ inline Struct::Struct(std::initializer_list<std::pair<std::string_view, Value>>
500500
inline std::optional<Value> Struct::get_field(std::string_view name) const
501501
{
502502
using namespace cbindgen_private;
503-
cbindgen_private::Slice<uint8_t> name_view {
504-
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(name.data())),
505-
name.size()
506-
};
503+
cbindgen_private::Slice<uint8_t> name_view = slint::private_api::string_to_slice(name);
507504
if (cbindgen_private::Value *field_val =
508505
cbindgen_private::slint_interpreter_struct_get_field(&inner, name_view)) {
509506
return Value(std::move(field_val));
@@ -513,10 +510,7 @@ inline std::optional<Value> Struct::get_field(std::string_view name) const
513510
}
514511
inline void Struct::set_field(std::string_view name, const Value &value)
515512
{
516-
cbindgen_private::Slice<uint8_t> name_view {
517-
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(name.data())),
518-
name.size()
519-
};
513+
cbindgen_private::Slice<uint8_t> name_view = slint::private_api::string_to_slice(name);
520514
cbindgen_private::slint_interpreter_struct_set_field(&inner, name_view, value.inner);
521515
}
522516

@@ -661,11 +655,8 @@ class ComponentInstance : vtable::Dyn
661655
std::optional<Value> invoke(std::string_view name, std::span<const Value> args) const
662656
{
663657
using namespace cbindgen_private;
664-
Slice<Box<cbindgen_private::Value>> args_view {
665-
const_cast<Box<cbindgen_private::Value> *>(
666-
reinterpret_cast<const Box<cbindgen_private::Value> *>(args.data())),
667-
args.size()
668-
};
658+
Slice<Box<cbindgen_private::Value>> args_view = slint::private_api::make_slice(
659+
reinterpret_cast<const Box<cbindgen_private::Value> *>(args.data()), args.size());
669660
if (cbindgen_private::Value *rval_inner = slint_interpreter_component_instance_invoke(
670661
inner(), slint::private_api::string_to_slice(name), args_view)) {
671662
return Value(std::move(rval_inner));
@@ -796,12 +787,11 @@ class ComponentInstance : vtable::Dyn
796787
std::span<const Value> args) const
797788
{
798789
using namespace cbindgen_private;
799-
Slice<cbindgen_private::Box<cbindgen_private::Value>> args_view {
800-
const_cast<cbindgen_private::Box<cbindgen_private::Value> *>(
801-
reinterpret_cast<const cbindgen_private::Box<cbindgen_private::Value> *>(
802-
args.data())),
803-
args.size()
804-
};
790+
Slice<cbindgen_private::Box<cbindgen_private::Value>> args_view =
791+
slint::private_api::make_slice(
792+
reinterpret_cast<const cbindgen_private::Box<cbindgen_private::Value> *>(
793+
args.data()),
794+
args.size());
805795
if (cbindgen_private::Value *rval_inner =
806796
slint_interpreter_component_instance_invoke_global(
807797
inner(), slint::private_api::string_to_slice(global),

api/cpp/include/slint-testing.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,7 @@ class ElementHandle
9595
static SharedVector<ElementHandle> find_by_accessible_label(const ComponentHandle<T> &component,
9696
std::string_view label)
9797
{
98-
cbindgen_private::Slice<uint8_t> label_view {
99-
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(label.data())),
100-
label.size()
101-
};
98+
cbindgen_private::Slice<uint8_t> label_view = private_api::string_to_slice(label);
10299
auto vrc = component.into_dyn();
103100
SharedVector<ElementHandle> result;
104101
cbindgen_private::slint_testing_element_find_by_accessible_label(
@@ -112,10 +109,7 @@ class ElementHandle
112109
static SharedVector<ElementHandle> find_by_element_id(const ComponentHandle<T> &component,
113110
std::string_view element_id)
114111
{
115-
cbindgen_private::Slice<uint8_t> element_id_view {
116-
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(element_id.data())),
117-
element_id.size()
118-
};
112+
cbindgen_private::Slice<uint8_t> element_id_view = private_api::string_to_slice(element_id);
119113
auto vrc = component.into_dyn();
120114
SharedVector<ElementHandle> result;
121115
cbindgen_private::slint_testing_element_find_by_element_id(
@@ -129,10 +123,8 @@ class ElementHandle
129123
static SharedVector<ElementHandle>
130124
find_by_element_type_name(const ComponentHandle<T> &component, std::string_view type_name)
131125
{
132-
cbindgen_private::Slice<uint8_t> element_type_name_view {
133-
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(type_name.data())),
134-
type_name.size()
135-
};
126+
cbindgen_private::Slice<uint8_t> element_type_name_view =
127+
private_api::string_to_slice(type_name);
136128
auto vrc = component.into_dyn();
137129
SharedVector<ElementHandle> result;
138130
cbindgen_private::slint_testing_element_find_by_element_type_name(

api/cpp/include/slint.h

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ inline SharedVector<float> solve_box_layout(const cbindgen_private::BoxLayoutDat
117117
cbindgen_private::Slice<int> repeater_indexes)
118118
{
119119
SharedVector<float> result;
120-
cbindgen_private::Slice<uint32_t> ri { reinterpret_cast<uint32_t *>(repeater_indexes.ptr),
121-
repeater_indexes.len };
120+
cbindgen_private::Slice<uint32_t> ri =
121+
make_slice(reinterpret_cast<uint32_t *>(repeater_indexes.ptr), repeater_indexes.len);
122122
cbindgen_private::slint_solve_box_layout(&data, ri, &result);
123123
return result;
124124
}
@@ -233,9 +233,7 @@ inline SharedString translate_from_bundle(std::span<const char8_t *const> strs,
233233
{
234234
SharedString result;
235235
cbindgen_private::slint_translate_from_bundle(
236-
cbindgen_private::Slice<const char *>(
237-
const_cast<char const **>(reinterpret_cast<char const *const *>(strs.data())),
238-
strs.size()),
236+
make_slice((reinterpret_cast<char const *const *>(strs.data())), strs.size()),
239237
arguments, &result);
240238
return result;
241239
}
@@ -246,16 +244,13 @@ translate_from_bundle_with_plural(std::span<const char8_t *const> strs,
246244
cbindgen_private::Slice<SharedString> arguments, int n)
247245
{
248246
SharedString result;
249-
cbindgen_private::Slice<const char *> strs_slice(
250-
const_cast<char const **>(reinterpret_cast<char const *const *>(strs.data())),
251-
strs.size());
252-
cbindgen_private::Slice<uint32_t> indices_slice(
253-
const_cast<uint32_t *>(reinterpret_cast<const uint32_t *>(indices.data())),
254-
indices.size());
255-
cbindgen_private::Slice<uintptr_t (*)(int32_t)> plural_rules_slice(
256-
const_cast<uintptr_t (**)(int32_t)>(
257-
reinterpret_cast<uintptr_t (*const *)(int32_t)>(plural_rules.data())),
258-
plural_rules.size());
247+
cbindgen_private::Slice<const char *> strs_slice =
248+
make_slice(reinterpret_cast<char const *const *>(strs.data()), strs.size());
249+
cbindgen_private::Slice<uint32_t> indices_slice =
250+
make_slice(reinterpret_cast<const uint32_t *>(indices.data()), indices.size());
251+
cbindgen_private::Slice<uintptr_t (*)(int32_t)> plural_rules_slice =
252+
make_slice(reinterpret_cast<uintptr_t (*const *)(int32_t)>(plural_rules.data()),
253+
plural_rules.size());
259254
cbindgen_private::slint_translate_from_bundle_with_plural(
260255
strs_slice, indices_slice, plural_rules_slice, arguments, n, &result);
261256
return result;

api/cpp/include/slint_image.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,7 @@ inline Image load_image_from_embedded_data(std::span<const uint8_t> data,
284284
{
285285
cbindgen_private::types::Image img(cbindgen_private::types::Image::ImageInner_None());
286286
cbindgen_private::types::slint_image_load_from_embedded_data(
287-
slint::cbindgen_private::Slice<uint8_t> { const_cast<uint8_t *>(data.data()),
288-
data.size() },
289-
slint::cbindgen_private::Slice<uint8_t> {
290-
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(extension.data())),
291-
extension.size() },
292-
&img);
287+
make_slice(data.data(), data.size()), string_to_slice(extension), &img);
293288
return Image(img);
294289
}
295290

api/cpp/include/slint_string.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#pragma once
55
#include <string_view>
6+
#include <span>
67
#include "slint_string_internal.h"
78

89
namespace slint {
@@ -223,12 +224,27 @@ struct SharedString
223224
};
224225

225226
namespace private_api {
226-
inline cbindgen_private::Slice<uint8_t> string_to_slice(std::string_view str)
227+
228+
template<typename T>
229+
inline cbindgen_private::Slice<T> make_slice(const T *ptr, size_t len)
227230
{
228-
return cbindgen_private::Slice<uint8_t> {
229-
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(str.data())), str.size()
231+
return cbindgen_private::Slice<T> {
232+
// Rust uses a NonNull, so even empty slices shouldn't use nullptr
233+
.ptr = ptr ? const_cast<T *>(ptr) : reinterpret_cast<T *>(sizeof(T)),
234+
.len = len,
230235
};
231236
}
237+
238+
template<typename T, size_t Extent>
239+
inline cbindgen_private::Slice<std::remove_const_t<T>> make_slice(std::span<T, Extent> span)
240+
{
241+
return make_slice(span.data(), span.size());
242+
}
243+
244+
inline cbindgen_private::Slice<uint8_t> string_to_slice(std::string_view str)
245+
{
246+
return make_slice(reinterpret_cast<const uint8_t *>(str.data()), str.size());
247+
}
232248
}
233249

234250
}

api/cpp/include/slint_window.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,7 @@ class WindowAdapterRc
216216
inline std::optional<SharedString> register_font_from_data(const uint8_t *data, std::size_t len)
217217
{
218218
SharedString maybe_err;
219-
cbindgen_private::slint_register_font_from_data(
220-
&inner, { const_cast<uint8_t *>(data), len }, &maybe_err);
219+
cbindgen_private::slint_register_font_from_data(&inner, make_slice(data, len), &maybe_err);
221220
if (!maybe_err.empty()) {
222221
return maybe_err;
223222
} else {

internal/compiler/generator/cpp.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -991,12 +991,14 @@ fn embed_resource(
991991
)),
992992
..Default::default()
993993
}));
994-
let init = format!("slint::cbindgen_private::types::StaticTextures {{
994+
let init = format!(
995+
"slint::cbindgen_private::types::StaticTextures {{
995996
.size = {{ {width}, {height} }},
996997
.original_size = {{ {unscaled_width}, {unscaled_height} }},
997-
.data = slint::cbindgen_private::Slice<uint8_t>{{ {data_name} , {count} }},
998-
.textures = slint::cbindgen_private::Slice<slint::cbindgen_private::types::StaticTexture>{{ &{texture_name}, 1 }}
999-
}}");
998+
.data = slint::private_api::make_slice({data_name} , {count} ),
999+
.textures = slint::private_api::make_slice(&{texture_name}, 1)
1000+
}}"
1001+
);
10001002
declarations.push(Declaration::Var(Var {
10011003
ty: "const slint::cbindgen_private::types::StaticTextures".into(),
10021004
name: format_smolstr!("slint_embedded_resource_{}", resource.id),
@@ -1078,7 +1080,7 @@ fn embed_resource(
10781080
name: format_smolstr!("slint_embedded_resource_{}_glyphset_{}", resource.id, glyphset_index),
10791081
array_size: Some(glyphset.glyph_data.len()),
10801082
init: Some(format!("{{ {} }}", glyphset.glyph_data.iter().enumerate().map(|(glyph_index, glyph)| {
1081-
format!("{{ .x = {}, .y = {}, .width = {}, .height = {}, .x_advance = {}, .data = slint::cbindgen_private::Slice<uint8_t>{{ {}, {} }} }}",
1083+
format!("{{ .x = {}, .y = {}, .width = {}, .height = {}, .x_advance = {}, .data = slint::private_api::make_slice({}, {}) }}",
10821084
glyph.x, glyph.y, glyph.width, glyph.height, glyph.x_advance,
10831085
format!("slint_embedded_resource_{}_gs_{}_gd_{}", resource.id, glyphset_index, glyph_index),
10841086
glyph.data.len()
@@ -1101,10 +1103,7 @@ fn embed_resource(
11011103
.iter()
11021104
.enumerate()
11031105
.map(|(glyphset_index, glyphset)| format!(
1104-
"{{ .pixel_size = {}, .glyph_data = slint::cbindgen_private::Slice<slint::cbindgen_private::BitmapGlyph>{{
1105-
{}, {}
1106-
}}
1107-
}}",
1106+
"{{ .pixel_size = {}, .glyph_data = slint::private_api::make_slice({}, {}) }}",
11081107
glyphset.pixel_size, format!("slint_embedded_resource_{}_glyphset_{}", resource.id, glyphset_index), glyphset.glyph_data.len()
11091108
))
11101109
.join(", \n")
@@ -1114,14 +1113,14 @@ fn embed_resource(
11141113

11151114
let init = format!(
11161115
"slint::cbindgen_private::BitmapFont {{
1117-
.family_name = slint::cbindgen_private::Slice<uint8_t>{{ {family_name_var} , {family_name_size} }},
1118-
.character_map = slint::cbindgen_private::Slice<slint::cbindgen_private::CharacterMapEntry>{{ {charmap_var}, {charmap_size} }},
1116+
.family_name = slint::private_api::make_slice({family_name_var} , {family_name_size}),
1117+
.character_map = slint::private_api::make_slice({charmap_var}, {charmap_size}),
11191118
.units_per_em = {units_per_em},
11201119
.ascent = {ascent},
11211120
.descent = {descent},
11221121
.x_height = {x_height},
11231122
.cap_height = {cap_height},
1124-
.glyphs = slint::cbindgen_private::Slice<slint::cbindgen_private::BitmapGlyphs>{{ {glyphsets_var}, {glyphsets_size} }},
1123+
.glyphs = slint::private_api::make_slice({glyphsets_var}, {glyphsets_size}),
11251124
.weight = {weight},
11261125
.italic = {italic},
11271126
.sdf = {sdf},
@@ -1584,13 +1583,13 @@ fn generate_item_tree(
15841583
Access::Private,
15851584
Declaration::Function(Function {
15861585
name: "item_tree".into(),
1587-
signature: "() -> slint::cbindgen_private::Slice<slint::private_api::ItemTreeNode>".into(),
1586+
signature: "() -> slint::cbindgen_private::Slice<slint::private_api::ItemTreeNode>"
1587+
.into(),
15881588
is_static: true,
15891589
statements: Some(vec![
15901590
"static const slint::private_api::ItemTreeNode children[] {".to_owned(),
15911591
format!(" {} }};", item_tree_array.join(", \n")),
1592-
"return { const_cast<slint::private_api::ItemTreeNode*>(children), std::size(children) };"
1593-
.to_owned(),
1592+
"return slint::private_api::make_slice(std::span(children));".to_owned(),
15941593
]),
15951594
..Default::default()
15961595
}),
@@ -1605,8 +1604,7 @@ fn generate_item_tree(
16051604
statements: Some(vec![
16061605
"static const slint::private_api::ItemArrayEntry items[] {".to_owned(),
16071606
format!(" {} }};", item_array.join(", \n")),
1608-
"return { const_cast<slint::private_api::ItemArrayEntry*>(items), std::size(items) };"
1609-
.to_owned(),
1607+
"return slint::private_api::make_slice(std::span(items));".to_owned(),
16101608
]),
16111609
..Default::default()
16121610
}),
@@ -1803,7 +1801,7 @@ fn generate_item_tree(
18031801
.map(|l| format!("slint::private_api::string_to_slice({l:?})"))
18041802
.join(", ")
18051803
));
1806-
create_code.push(format!("slint::cbindgen_private::slint_translate_set_bundled_languages({{ languages.data(), {lang_len} }});"));
1804+
create_code.push(format!("slint::cbindgen_private::slint_translate_set_bundled_languages(slint::private_api::make_slice(std::span(languages)));"));
18071805
}
18081806

18091807
create_code.push("self->globals = &self->m_globals;".into());
@@ -3397,7 +3395,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
33973395
)
33983396
} else {
33993397
format!(
3400-
"slint::cbindgen_private::Slice<{ty}>{{ std::array<{ty}, {count}>{{ {val} }}.data(), {count} }}",
3398+
"slint::private_api::make_slice<{ty}>(std::array<{ty}, {count}>{{ {val} }}.data(), {count})",
34013399
count = values.len(),
34023400
ty = ty,
34033401
val = val.join(", ")
@@ -3511,7 +3509,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
35113509
};
35123510
format!("slint::cbindgen_private::GridLayoutCellData {cv}_array [] = {{ {c} }};\
35133511
slint::cbindgen_private::slint_reorder_dialog_button_layout({cv}_array, {r});\
3514-
slint::cbindgen_private::Slice<slint::cbindgen_private::GridLayoutCellData> {cv} {{ std::data({cv}_array), std::size({cv}_array) }}",
3512+
slint::cbindgen_private::Slice<slint::cbindgen_private::GridLayoutCellData> {cv} = slint::private_api::make_slice(std::span({cv}_array))",
35153513
r = compile_expression(roles, ctx),
35163514
cv = cells_variable,
35173515
c = cells.join(", "),
@@ -4099,13 +4097,13 @@ fn box_layout_function(
40994097
let ri = repeated_indices.as_ref().map_or(String::new(), |ri| {
41004098
write!(
41014099
push_code,
4102-
"slint::cbindgen_private::Slice<int> {ri}{{ {ri}_array.data(), {ri}_array.size() }};"
4100+
"slint::cbindgen_private::Slice<int> {ri} = slint::private_api::make_slice(std::span({ri}_array));"
41034101
)
41044102
.unwrap();
41054103
format!("std::array<int, {}> {}_array;", 2 * repeater_idx, ri)
41064104
});
41074105
format!(
4108-
"[&]{{ {} {} slint::cbindgen_private::Slice<slint::cbindgen_private::BoxLayoutCellData>{}{{cells_vector.data(), cells_vector.size()}}; return {}; }}()",
4106+
"[&]{{ {} {} slint::cbindgen_private::Slice<slint::cbindgen_private::BoxLayoutCellData>{} = slint::private_api::make_slice(std::span(cells_vector)); return {}; }}()",
41094107
ri,
41104108
push_code,
41114109
ident(cells_variable),

0 commit comments

Comments
 (0)