Mercurial > public > mercurial-scm > hg
annotate rust/hg-cpython/src/ref_sharing.rs @ 43427:b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Since the underlying value can't be mutably borrowed by PyLeaked, we don't
have to manage yet another mutably-borrowed state. We can just rely on the
RefCell implementation.
Maybe we can add try_leak_immutable(), but this patch doesn't in order to
keep the patch series not too long.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 05 Oct 2019 08:56:15 -0400 |
parents | 6f9f15a476a4 |
children | 6c0e47874217 |
rev | line source |
---|---|
43082
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
1 // ref_sharing.rs |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
2 // |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
4 // |
43082
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
5 // Permission is hereby granted, free of charge, to any person obtaining a copy |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
6 // of this software and associated documentation files (the "Software"), to |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
7 // deal in the Software without restriction, including without limitation the |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
9 // sell copies of the Software, and to permit persons to whom the Software is |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
10 // furnished to do so, subject to the following conditions: |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
11 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
12 // The above copyright notice and this permission notice shall be included in |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
13 // all copies or substantial portions of the Software. |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
14 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
21 // IN THE SOFTWARE. |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
23 //! Macros for use in the `hg-cpython` bridge library. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
24 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
25 use crate::exceptions::AlreadyBorrowed; |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
26 use cpython::{exc, PyClone, PyErr, PyObject, PyResult, Python}; |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
27 use std::cell::{Cell, Ref, RefCell, RefMut}; |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
28 use std::ops::{Deref, DerefMut}; |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
29 use std::sync::atomic::{AtomicUsize, Ordering}; |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
30 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
31 /// Manages the shared state between Python and Rust |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
32 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
33 /// `PySharedState` is owned by `PySharedRefCell`, and is shared across its |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
34 /// derived references. The consistency of these references are guaranteed |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
35 /// as follows: |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
36 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
37 /// - The immutability of `py_class!` object fields. Any mutation of |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
38 /// `PySharedRefCell` is allowed only through its `borrow_mut()`. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
39 /// - The `py: Python<'_>` token, which makes sure that any data access is |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
40 /// synchronized by the GIL. |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
41 /// - The underlying `RefCell`, which prevents `PySharedRefCell` data from |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
42 /// being directly borrowed or leaked while it is mutably borrowed. |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
43 /// - The `borrow_count`, which is the number of references borrowed from |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
44 /// `PyLeaked`. Just like `RefCell`, mutation is prohibited while `PyLeaked` |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
45 /// is borrowed. |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
46 /// - The `generation` counter, which increments on `borrow_mut()`. `PyLeaked` |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
47 /// reference is valid only if the `current_generation()` equals to the |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
48 /// `generation` at the time of `leak_immutable()`. |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
49 #[derive(Debug, Default)] |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
50 struct PySharedState { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
51 mutably_borrowed: Cell<bool>, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
52 // The counter variable could be Cell<usize> since any operation on |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
53 // PySharedState is synchronized by the GIL, but being "atomic" makes |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
54 // PySharedState inherently Sync. The ordering requirement doesn't |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
55 // matter thanks to the GIL. |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
56 borrow_count: AtomicUsize, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
57 generation: AtomicUsize, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
58 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
59 |
43175
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
60 // &PySharedState can be Send because any access to inner cells is |
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
61 // synchronized by the GIL. |
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
62 unsafe impl Sync for PySharedState {} |
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
63 |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
64 impl PySharedState { |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
65 fn borrow_mut<'a, T>( |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
66 &'a self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
67 py: Python<'a>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
68 pyrefmut: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
69 ) -> PyResult<PyRefMut<'a, T>> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
70 if self.mutably_borrowed.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
71 return Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
72 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
73 "Cannot borrow mutably while there exists another \ |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
74 mutable reference in a Python object", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
75 )); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
76 } |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
77 match self.current_borrow_count(py) { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
78 0 => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
79 self.mutably_borrowed.replace(true); |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
80 // Note that this wraps around to the same value if mutably |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
81 // borrowed more than usize::MAX times, which wouldn't happen |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
82 // in practice. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
83 self.generation.fetch_add(1, Ordering::Relaxed); |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
84 Ok(PyRefMut::new(py, pyrefmut, self)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
85 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
86 _ => Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
87 py, |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
88 "Cannot borrow mutably while immutably borrowed", |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
89 )), |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
90 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
91 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
92 |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
93 /// Return a reference to the wrapped data and its state with an |
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
94 /// artificial static lifetime. |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
95 /// We need to be protected by the GIL for thread-safety. |
42851
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
96 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
97 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
98 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
99 /// This is highly unsafe since the lifetime of the given data can be |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
100 /// extended. Do not call this function directly. |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
101 unsafe fn leak_immutable<T>( |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
102 &self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
103 py: Python, |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
104 data: Ref<T>, |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
105 ) -> PyResult<(&'static T, &'static PySharedState)> { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
106 if self.mutably_borrowed.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
107 return Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
108 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
109 "Cannot borrow immutably while there is a \ |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
110 mutable reference in Python objects", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
111 )); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
112 } |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
113 let ptr: *const T = &*data; |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
114 let state_ptr: *const PySharedState = self; |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
115 Ok((&*ptr, &*state_ptr)) |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
116 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
117 |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
118 fn current_borrow_count(&self, _py: Python) -> usize { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
119 self.borrow_count.load(Ordering::Relaxed) |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
120 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
121 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
122 fn increase_borrow_count(&self, _py: Python) { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
123 // Note that this wraps around if there are more than usize::MAX |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
124 // borrowed references, which shouldn't happen due to memory limit. |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
125 self.borrow_count.fetch_add(1, Ordering::Relaxed); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
126 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
127 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
128 fn decrease_borrow_count(&self, _py: Python) { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
129 let prev_count = self.borrow_count.fetch_sub(1, Ordering::Relaxed); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
130 assert!(prev_count > 0); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
131 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
132 |
42851
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
133 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
134 /// |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
135 /// It's up to you to make sure the reference is about to be deleted |
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
136 /// when updating the leak count. |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
137 fn decrease_leak_count(&self, py: Python, mutable: bool) { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
138 if mutable { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
139 assert_eq!(self.current_borrow_count(py), 0); |
42939
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42891
diff
changeset
|
140 assert!(self.mutably_borrowed.get()); |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
141 self.mutably_borrowed.replace(false); |
42939
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42891
diff
changeset
|
142 } else { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
143 unimplemented!(); |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
144 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
145 } |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
146 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
147 fn current_generation(&self, _py: Python) -> usize { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
148 self.generation.load(Ordering::Relaxed) |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
149 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
150 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
151 |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
152 /// Helper to keep the borrow count updated while the shared object is |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
153 /// immutably borrowed without using the `RefCell` interface. |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
154 struct BorrowPyShared<'a> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
155 py: Python<'a>, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
156 py_shared_state: &'a PySharedState, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
157 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
158 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
159 impl<'a> BorrowPyShared<'a> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
160 fn new( |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
161 py: Python<'a>, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
162 py_shared_state: &'a PySharedState, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
163 ) -> BorrowPyShared<'a> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
164 py_shared_state.increase_borrow_count(py); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
165 BorrowPyShared { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
166 py, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
167 py_shared_state, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
168 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
169 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
170 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
171 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
172 impl Drop for BorrowPyShared<'_> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
173 fn drop(&mut self) { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
174 self.py_shared_state.decrease_borrow_count(self.py); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
175 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
176 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
177 |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
178 /// `RefCell` wrapper to be safely used in conjunction with `PySharedState`. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
179 /// |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
180 /// This object can be stored in a `py_class!` object as a data field. Any |
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
181 /// operation is allowed through the `PySharedRef` interface. |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
182 #[derive(Debug)] |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
183 pub struct PySharedRefCell<T> { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
184 inner: RefCell<T>, |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
185 py_shared_state: PySharedState, |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
186 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
187 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
188 impl<T> PySharedRefCell<T> { |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
189 pub fn new(value: T) -> PySharedRefCell<T> { |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
190 Self { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
191 inner: RefCell::new(value), |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
192 py_shared_state: PySharedState::default(), |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
193 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
194 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
195 |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
196 fn borrow<'a>(&'a self, _py: Python<'a>) -> Ref<'a, T> { |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
197 // py_shared_state isn't involved since |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
198 // - inner.borrow() would fail if self is mutably borrowed, |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
199 // - and inner.borrow_mut() would fail while self is borrowed. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
200 self.inner.borrow() |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
201 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
202 |
43174
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
203 // TODO: maybe this should be named as try_borrow_mut(), and use |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
204 // inner.try_borrow_mut(). The current implementation panics if |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
205 // self.inner has been borrowed, but returns error if py_shared_state |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
206 // refuses to borrow. |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
207 fn borrow_mut<'a>(&'a self, py: Python<'a>) -> PyResult<PyRefMut<'a, T>> { |
43174
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
208 self.py_shared_state.borrow_mut(py, self.inner.borrow_mut()) |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
209 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
210 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
211 |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
212 /// Sharable data member of type `T` borrowed from the `PyObject`. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
213 pub struct PySharedRef<'a, T> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
214 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
215 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
216 data: &'a PySharedRefCell<T>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
217 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
218 |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
219 impl<'a, T> PySharedRef<'a, T> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
220 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
221 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
222 /// The `data` must be owned by the `owner`. Otherwise, the leak count |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
223 /// would get wrong. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
224 pub unsafe fn new( |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
225 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
226 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
227 data: &'a PySharedRefCell<T>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
228 ) -> Self { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
229 Self { py, owner, data } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
230 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
231 |
43272
00222775d59b
rust-refsharing: add missing lifetime parameter in ref_sharing
Rapha?l Gom?s <rgomes@octobus.net>
parents:
43180
diff
changeset
|
232 pub fn borrow(&self) -> Ref<'a, T> { |
43286
f8c114f20d2d
rust-cpython: require GIL to borrow immutable reference from PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43285
diff
changeset
|
233 self.data.borrow(self.py) |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
234 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
235 |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
236 pub fn borrow_mut(&self) -> PyResult<PyRefMut<'a, T>> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
237 self.data.borrow_mut(self.py) |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
238 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
239 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
240 /// Returns a leaked reference. |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
241 /// |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
242 /// # Panics |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
243 /// |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
244 /// Panics if this is mutably borrowed. |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
245 pub fn leak_immutable(&self) -> PyResult<PyLeaked<&'static T>> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
246 let state = &self.data.py_shared_state; |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
247 // make sure self.data isn't mutably borrowed; otherwise the |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
248 // generation number can't be trusted. |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
249 let data_ref = self.borrow(); |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
250 unsafe { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
251 let (static_ref, static_state_ref) = |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
252 state.leak_immutable(self.py, data_ref)?; |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
253 Ok(PyLeaked::new( |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
254 self.py, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
255 self.owner, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
256 static_ref, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
257 static_state_ref, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
258 )) |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
259 } |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
260 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
261 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
262 |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
263 /// Holds a mutable reference to data shared between Python and Rust. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
264 pub struct PyRefMut<'a, T> { |
43287
0df8312463ae
rust-cpython: keep Python<'a> token in PyRefMut
Yuya Nishihara <yuya@tcha.org>
parents:
43286
diff
changeset
|
265 py: Python<'a>, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
266 inner: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
267 py_shared_state: &'a PySharedState, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
268 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
269 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
270 impl<'a, T> PyRefMut<'a, T> { |
42851
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
271 // Must be constructed by PySharedState after checking its leak_count. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
272 // Otherwise, drop() would incorrectly update the state. |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
273 fn new( |
43287
0df8312463ae
rust-cpython: keep Python<'a> token in PyRefMut
Yuya Nishihara <yuya@tcha.org>
parents:
43286
diff
changeset
|
274 py: Python<'a>, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
275 inner: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
276 py_shared_state: &'a PySharedState, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
277 ) -> Self { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
278 Self { |
43287
0df8312463ae
rust-cpython: keep Python<'a> token in PyRefMut
Yuya Nishihara <yuya@tcha.org>
parents:
43286
diff
changeset
|
279 py, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
280 inner, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
281 py_shared_state, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
282 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
283 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
284 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
285 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
286 impl<'a, T> std::ops::Deref for PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
287 type Target = RefMut<'a, T>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
288 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
289 fn deref(&self) -> &Self::Target { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
290 &self.inner |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
291 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
292 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
293 impl<'a, T> std::ops::DerefMut for PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
294 fn deref_mut(&mut self) -> &mut Self::Target { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
295 &mut self.inner |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
296 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
297 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
298 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
299 impl<'a, T> Drop for PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
300 fn drop(&mut self) { |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
301 self.py_shared_state.decrease_leak_count(self.py, true); |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
302 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
303 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
304 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
305 /// Allows a `py_class!` generated struct to share references to one of its |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
306 /// data members with Python. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
307 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
308 /// # Parameters |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
309 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
310 /// * `$name` is the same identifier used in for `py_class!` macro call. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
311 /// * `$inner_struct` is the identifier of the underlying Rust struct |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
312 /// * `$data_member` is the identifier of the data member of `$inner_struct` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
313 /// that will be shared. |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
314 /// * `$shared_accessor` is the function name to be generated, which allows |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
315 /// safe access to the data member. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
316 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
317 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
318 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
319 /// `$data_member` must persist while the `$name` object is alive. In other |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
320 /// words, it must be an accessor to a data field of the Python object. |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
321 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
322 /// # Example |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
323 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
324 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
325 /// struct MyStruct { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
326 /// inner: Vec<u32>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
327 /// } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
328 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
329 /// py_class!(pub class MyType |py| { |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
330 /// data inner: PySharedRefCell<MyStruct>; |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
331 /// }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
332 /// |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
333 /// py_shared_ref!(MyType, MyStruct, inner, inner_shared); |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
334 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
335 macro_rules! py_shared_ref { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
336 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
337 $name: ident, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
338 $inner_struct: ident, |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
339 $data_member: ident, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
340 $shared_accessor: ident |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
341 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
342 impl $name { |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
343 /// Returns a safe reference to the shared `$data_member`. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
344 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
345 /// This function guarantees that `PySharedRef` is created with |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
346 /// the valid `self` and `self.$data_member(py)` pair. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
347 fn $shared_accessor<'a>( |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
348 &'a self, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
349 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
350 ) -> $crate::ref_sharing::PySharedRef<'a, $inner_struct> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
351 use cpython::PythonObject; |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
352 use $crate::ref_sharing::PySharedRef; |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
353 let owner = self.as_object(); |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
354 let data = self.$data_member(py); |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
355 unsafe { PySharedRef::new(py, owner, data) } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
356 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
357 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
358 }; |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
359 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
360 |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
361 /// Manage immutable references to `PyObject` leaked into Python iterators. |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
362 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
363 /// This reference will be invalidated once the original value is mutably |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
364 /// borrowed. |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
365 pub struct PyLeaked<T> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
366 inner: PyObject, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
367 data: Option<T>, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
368 py_shared_state: &'static PySharedState, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
369 /// Generation counter of data `T` captured when PyLeaked is created. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
370 generation: usize, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
371 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
372 |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
373 // DO NOT implement Deref for PyLeaked<T>! Dereferencing PyLeaked |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
374 // without taking Python GIL wouldn't be safe. Also, the underling reference |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
375 // is invalid if generation != py_shared_state.generation. |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
376 |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
377 impl<T> PyLeaked<T> { |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
378 /// # Safety |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
379 /// |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
380 /// The `py_shared_state` must be owned by the `inner` Python object. |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
381 fn new( |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
382 py: Python, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
383 inner: &PyObject, |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
384 data: T, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
385 py_shared_state: &'static PySharedState, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
386 ) -> Self { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
387 Self { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
388 inner: inner.clone_ref(py), |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
389 data: Some(data), |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
390 py_shared_state, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
391 generation: py_shared_state.current_generation(py), |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
392 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
393 } |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
394 |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
395 /// Immutably borrows the wrapped value. |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
396 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
397 /// Borrowing fails if the underlying reference has been invalidated. |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
398 pub fn try_borrow<'a>( |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
399 &'a self, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
400 py: Python<'a>, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
401 ) -> PyResult<PyLeakedRef<'a, T>> { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
402 self.validate_generation(py)?; |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
403 Ok(PyLeakedRef { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
404 _borrow: BorrowPyShared::new(py, self.py_shared_state), |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
405 data: self.data.as_ref().unwrap(), |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
406 }) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
407 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
408 |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
409 /// Mutably borrows the wrapped value. |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
410 /// |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
411 /// Borrowing fails if the underlying reference has been invalidated. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
412 /// |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
413 /// Typically `T` is an iterator. If `T` is an immutable reference, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
414 /// `get_mut()` is useless since the inner value can't be mutated. |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
415 pub fn try_borrow_mut<'a>( |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
416 &'a mut self, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
417 py: Python<'a>, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
418 ) -> PyResult<PyLeakedRefMut<'a, T>> { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
419 self.validate_generation(py)?; |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
420 Ok(PyLeakedRefMut { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
421 _borrow: BorrowPyShared::new(py, self.py_shared_state), |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
422 data: self.data.as_mut().unwrap(), |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
423 }) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
424 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
425 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
426 /// Converts the inner value by the given function. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
427 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
428 /// Typically `T` is a static reference to a container, and `U` is an |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
429 /// iterator of that container. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
430 /// |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
431 /// # Panics |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
432 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
433 /// Panics if the underlying reference has been invalidated. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
434 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
435 /// This is typically called immediately after the `PyLeaked` is obtained. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
436 /// In which case, the reference must be valid and no panic would occur. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
437 /// |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
438 /// # Safety |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
439 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
440 /// The lifetime of the object passed in to the function `f` is cheated. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
441 /// It's typically a static reference, but is valid only while the |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
442 /// corresponding `PyLeaked` is alive. Do not copy it out of the |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
443 /// function call. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
444 pub unsafe fn map<U>( |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
445 mut self, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
446 py: Python, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
447 f: impl FnOnce(T) -> U, |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
448 ) -> PyLeaked<U> { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
449 // Needs to test the generation value to make sure self.data reference |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
450 // is still intact. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
451 self.validate_generation(py) |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
452 .expect("map() over invalidated leaked reference"); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
453 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
454 // f() could make the self.data outlive. That's why map() is unsafe. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
455 // In order to make this function safe, maybe we'll need a way to |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
456 // temporarily restrict the lifetime of self.data and translate the |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
457 // returned object back to Something<'static>. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
458 let new_data = f(self.data.take().unwrap()); |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
459 PyLeaked { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
460 inner: self.inner.clone_ref(py), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
461 data: Some(new_data), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
462 py_shared_state: self.py_shared_state, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
463 generation: self.generation, |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
464 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
465 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
466 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
467 fn validate_generation(&self, py: Python) -> PyResult<()> { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
468 if self.py_shared_state.current_generation(py) == self.generation { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
469 Ok(()) |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
470 } else { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
471 Err(PyErr::new::<exc::RuntimeError, _>( |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
472 py, |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
473 "Cannot access to leaked reference after mutation", |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
474 )) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
475 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
476 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
477 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
478 |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
479 /// Immutably borrowed reference to a leaked value. |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
480 pub struct PyLeakedRef<'a, T> { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
481 _borrow: BorrowPyShared<'a>, |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
482 data: &'a T, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
483 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
484 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
485 impl<T> Deref for PyLeakedRef<'_, T> { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
486 type Target = T; |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
487 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
488 fn deref(&self) -> &T { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
489 self.data |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
490 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
491 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
492 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
493 /// Mutably borrowed reference to a leaked value. |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
494 pub struct PyLeakedRefMut<'a, T> { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
495 _borrow: BorrowPyShared<'a>, |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
496 data: &'a mut T, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
497 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
498 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
499 impl<T> Deref for PyLeakedRefMut<'_, T> { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
500 type Target = T; |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
501 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
502 fn deref(&self) -> &T { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
503 self.data |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
504 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
505 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
506 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
507 impl<T> DerefMut for PyLeakedRefMut<'_, T> { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
508 fn deref_mut(&mut self) -> &mut T { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
509 self.data |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
510 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
511 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
512 |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
513 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
514 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
515 /// TODO: this is a bit awkward to use, and a better (more complicated) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
516 /// procedural macro would simplify the interface a lot. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
517 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
518 /// # Parameters |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
519 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
520 /// * `$name` is the identifier to give to the resulting Rust struct. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
521 /// * `$leaked` corresponds to `$leaked` in the matching `py_shared_ref!` call. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
522 /// * `$iterator_type` is the type of the Rust iterator. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
523 /// * `$success_func` is a function for processing the Rust `(key, value)` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
524 /// tuple on iteration success, turning it into something Python understands. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
525 /// * `$success_func` is the return type of `$success_func` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
526 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
527 /// # Example |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
528 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
529 /// ``` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
530 /// struct MyStruct { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
531 /// inner: HashMap<Vec<u8>, Vec<u8>>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
532 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
533 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
534 /// py_class!(pub class MyType |py| { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
535 /// data inner: PySharedRefCell<MyStruct>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
536 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
537 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
538 /// let leaked_ref = self.inner_shared(py).leak_immutable()?; |
42891
5ccc08d02280
rust-cpython: leverage py_shared_iterator::from_inner() where appropriate
Yuya Nishihara <yuya@tcha.org>
parents:
42890
diff
changeset
|
539 /// MyTypeItemsIterator::from_inner( |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
540 /// py, |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
541 /// unsafe { leaked_ref.map(py, |o| o.iter()) }, |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
542 /// ) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
543 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
544 /// }); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
545 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
546 /// impl MyType { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
547 /// fn translate_key_value( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
548 /// py: Python, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
549 /// res: (&Vec<u8>, &Vec<u8>), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
550 /// ) -> PyResult<Option<(PyBytes, PyBytes)>> { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
551 /// let (f, entry) = res; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
552 /// Ok(Some(( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
553 /// PyBytes::new(py, f), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
554 /// PyBytes::new(py, entry), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
555 /// ))) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
556 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
557 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
558 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
559 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
560 /// |
42889
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42888
diff
changeset
|
561 /// py_shared_iterator!( |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
562 /// MyTypeItemsIterator, |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
563 /// PyLeaked<HashMap<'static, Vec<u8>, Vec<u8>>>, |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
564 /// MyType::translate_key_value, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
565 /// Option<(PyBytes, PyBytes)> |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
566 /// ); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
567 /// ``` |
42889
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42888
diff
changeset
|
568 macro_rules! py_shared_iterator { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
569 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
570 $name: ident, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
571 $leaked: ty, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
572 $success_func: expr, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
573 $success_type: ty |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
574 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
575 py_class!(pub class $name |py| { |
43426
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
576 data inner: RefCell<$leaked>; |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
577 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
578 def __next__(&self) -> PyResult<$success_type> { |
43426
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
579 let mut leaked = self.inner(py).borrow_mut(); |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
580 let mut iter = leaked.try_borrow_mut(py)?; |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
581 match iter.next() { |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
582 None => Ok(None), |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
583 Some(res) => $success_func(py, res), |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
584 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
585 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
586 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
587 def __iter__(&self) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
588 Ok(self.clone_ref(py)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
589 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
590 }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
591 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
592 impl $name { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
593 pub fn from_inner( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
594 py: Python, |
42890
74d67c645278
rust-cpython: remove Option<_> from interface of py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42889
diff
changeset
|
595 leaked: $leaked, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
596 ) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
597 Self::create_instance( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
598 py, |
43426
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
599 RefCell::new(leaked), |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
600 ) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
601 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
602 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
603 }; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
604 } |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
605 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
606 #[cfg(test)] |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
607 #[cfg(any(feature = "python27-bin", feature = "python3-bin"))] |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
608 mod test { |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
609 use super::*; |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
610 use cpython::{GILGuard, Python}; |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
611 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
612 py_class!(class Owner |py| { |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
613 data string: PySharedRefCell<String>; |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
614 }); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
615 py_shared_ref!(Owner, String, string, string_shared); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
616 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
617 fn prepare_env() -> (GILGuard, Owner) { |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
618 let gil = Python::acquire_gil(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
619 let py = gil.python(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
620 let owner = |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
621 Owner::create_instance(py, PySharedRefCell::new("new".to_owned())) |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
622 .unwrap(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
623 (gil, owner) |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
624 } |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
625 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
626 #[test] |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
627 fn test_leaked_borrow() { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
628 let (gil, owner) = prepare_env(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
629 let py = gil.python(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
630 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
631 let leaked_ref = leaked.try_borrow(py).unwrap(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
632 assert_eq!(*leaked_ref, "new"); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
633 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
634 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
635 #[test] |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
636 fn test_leaked_borrow_mut() { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
637 let (gil, owner) = prepare_env(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
638 let py = gil.python(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
639 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
640 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
641 let mut leaked_ref = leaked_iter.try_borrow_mut(py).unwrap(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
642 assert_eq!(leaked_ref.next(), Some('n')); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
643 assert_eq!(leaked_ref.next(), Some('e')); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
644 assert_eq!(leaked_ref.next(), Some('w')); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
645 assert_eq!(leaked_ref.next(), None); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
646 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
647 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
648 #[test] |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
649 fn test_leaked_borrow_after_mut() { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
650 let (gil, owner) = prepare_env(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
651 let py = gil.python(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
652 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
653 owner.string_shared(py).borrow_mut().unwrap().clear(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
654 assert!(leaked.try_borrow(py).is_err()); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
655 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
656 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
657 #[test] |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
658 fn test_leaked_borrow_mut_after_mut() { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
659 let (gil, owner) = prepare_env(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
660 let py = gil.python(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
661 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
662 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
663 owner.string_shared(py).borrow_mut().unwrap().clear(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
664 assert!(leaked_iter.try_borrow_mut(py).is_err()); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
665 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
666 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
667 #[test] |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
668 #[should_panic(expected = "map() over invalidated leaked reference")] |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
669 fn test_leaked_map_after_mut() { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
670 let (gil, owner) = prepare_env(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
671 let py = gil.python(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
672 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
673 owner.string_shared(py).borrow_mut().unwrap().clear(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
674 let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
675 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
676 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
677 #[test] |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
678 fn test_borrow_mut_while_leaked_ref() { |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
679 let (gil, owner) = prepare_env(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
680 let py = gil.python(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
681 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
682 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
683 { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
684 let _leaked_ref = leaked.try_borrow(py).unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
685 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
686 { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
687 let _leaked_ref2 = leaked.try_borrow(py).unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
688 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
689 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
690 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
691 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
692 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
693 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
694 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
695 #[test] |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
696 fn test_borrow_mut_while_leaked_ref_mut() { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
697 let (gil, owner) = prepare_env(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
698 let py = gil.python(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
699 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
700 let leaked = owner.string_shared(py).leak_immutable().unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
701 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
702 { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
703 let _leaked_ref = leaked_iter.try_borrow_mut(py).unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
704 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
705 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
706 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
707 } |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
708 |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
709 #[test] |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
710 #[should_panic(expected = "mutably borrowed")] |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
711 fn test_leak_while_borrow_mut() { |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
712 let (gil, owner) = prepare_env(); |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
713 let py = gil.python(); |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
714 let _mut_ref = owner.string_shared(py).borrow_mut(); |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
715 let _ = owner.string_shared(py).leak_immutable(); |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
716 } |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
717 } |