1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use std::alloc::{alloc, dealloc, Layout};
6
7 #[cxx::bridge]
8 mod ffi {
9 pub struct SomeStruct {
10 a: i32,
11 }
12 extern "Rust" {
say_hello()13 fn say_hello();
alloc_aligned()14 fn alloc_aligned();
add_two_ints_via_rust(x: i32, y: i32) -> i3215 fn add_two_ints_via_rust(x: i32, y: i32) -> i32;
allocate_via_rust() -> Box<SomeStruct>16 fn allocate_via_rust() -> Box<SomeStruct>;
allocate_huge_via_rust(size: usize, align: usize) -> bool17 fn allocate_huge_via_rust(size: usize, align: usize) -> bool;
allocate_zeroed_huge_via_rust(size: usize, align: usize) -> bool18 fn allocate_zeroed_huge_via_rust(size: usize, align: usize) -> bool;
reallocate_huge_via_rust(size: usize, align: usize) -> bool19 fn reallocate_huge_via_rust(size: usize, align: usize) -> bool;
20 }
21 }
22
say_hello()23 pub fn say_hello() {
24 println!(
25 "Hello, world - from a Rust library. Calculations suggest that 3+4={}",
26 add_two_ints_via_rust(3, 4)
27 );
28 }
29
alloc_aligned()30 pub fn alloc_aligned() {
31 let layout = unsafe { Layout::from_size_align_unchecked(1024, 512) };
32 let ptr = unsafe { alloc(layout) };
33 println!("Alloc aligned ptr: {:p}", ptr);
34 unsafe { dealloc(ptr, layout) };
35 }
36
37 #[test]
test_hello()38 fn test_hello() {
39 assert_eq!(7, add_two_ints_via_rust(3, 4));
40 }
41
add_two_ints_via_rust(x: i32, y: i32) -> i3242 pub fn add_two_ints_via_rust(x: i32, y: i32) -> i32 {
43 x + y
44 }
45
46 // The next function is used from the
47 // AllocatorTest.RustComponentUsesPartitionAlloc unit test.
allocate_via_rust() -> Box<ffi::SomeStruct>48 pub fn allocate_via_rust() -> Box<ffi::SomeStruct> {
49 Box::new(ffi::SomeStruct { a: 43 })
50 }
51
52 mod tests {
53 #[test]
test_in_mod()54 fn test_in_mod() {
55 // Always passes; just to see if tests in modules are handled correctly.
56 }
57 }
58
59 // Used from the RustLargeAllocationFailure unit tests.
allocate_huge_via_rust(size: usize, align: usize) -> bool60 pub fn allocate_huge_via_rust(size: usize, align: usize) -> bool {
61 let layout = std::alloc::Layout::from_size_align(size, align).unwrap();
62 let p = unsafe { std::alloc::alloc(layout) };
63 // Rust can optimize out allocations. By printing the pointer value we ensure
64 // the allocation actually happens (and can thus fail).
65 dbg!(p);
66 if !p.is_null() {
67 unsafe { std::alloc::dealloc(p, layout) };
68 }
69 !p.is_null()
70 }
71
72 // Used from the RustLargeAllocationFailure unit tests.
allocate_zeroed_huge_via_rust(size: usize, align: usize) -> bool73 pub fn allocate_zeroed_huge_via_rust(size: usize, align: usize) -> bool {
74 let layout = std::alloc::Layout::from_size_align(size, align).unwrap();
75 let p = unsafe { std::alloc::alloc_zeroed(layout) };
76 // Rust can optimize out allocations. By printing the pointer value we ensure
77 // the allocation actually happens (and can thus fail).
78 dbg!(p);
79 if !p.is_null() {
80 unsafe { std::alloc::dealloc(p, layout) };
81 }
82 !p.is_null()
83 }
84
85 // Used from the RustLargeAllocationFailure unit tests.
reallocate_huge_via_rust(size: usize, align: usize) -> bool86 pub fn reallocate_huge_via_rust(size: usize, align: usize) -> bool {
87 let layout = std::alloc::Layout::from_size_align(align, align).unwrap();
88 let p = unsafe { std::alloc::alloc(layout) };
89 assert!(!p.is_null());
90 let p = unsafe { std::alloc::realloc(p, layout, size) };
91 let layout = std::alloc::Layout::from_size_align(size, align).unwrap();
92 // Rust can optimize out allocations. By printing the pointer value we ensure
93 // the allocation actually happens (and can thus fail).
94 dbg!(p);
95 if !p.is_null() {
96 unsafe { std::alloc::dealloc(p, layout) };
97 }
98 !p.is_null()
99 }
100