Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-cpython/src/ref_sharing.rs @ 43285:ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
This patch encapsulates the access to the leaked reference to make most
leaked-ref operations safe. The only exception is leaked_ref.map(). I
couldn't figure out how to allow arbitrary map operation safely over an
unsafe static reference. See the docstring and inline comment for details.
Now leak_immutable() can be safely implemented as the PyLeakedRef owns
its inner data.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 15 Sep 2019 22:19:10 +0900 |
parents | ce6dd1cee4c8 |
children | f8c114f20d2d |
rev | line source |
---|---|
43082
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
1 // ref_sharing.rs |
42768
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:
42943
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:
42943
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:
42943
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:
42943
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:
42943
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:
42943
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:
42943
diff
changeset
|
11 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
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:
42943
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:
42943
diff
changeset
|
14 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
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:
42943
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:
42943
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:
42943
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:
42943
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:
42943
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:
42943
diff
changeset
|
21 // IN THE SOFTWARE. |
42768
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; |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
26 use cpython::{PyClone, PyObject, PyResult, Python}; |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
27 use std::cell::{Cell, Ref, RefCell, RefMut}; |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
28 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
29 /// Manages the shared state between Python and Rust |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
30 #[derive(Debug, Default)] |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
31 pub struct PySharedState { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
32 leak_count: Cell<usize>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
33 mutably_borrowed: Cell<bool>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
34 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
35 |
43175
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
36 // &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
|
37 // 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
|
38 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
|
39 |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
40 impl PySharedState { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
41 pub fn borrow_mut<'a, T>( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
42 &'a self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
43 py: Python<'a>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
44 pyrefmut: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
45 ) -> PyResult<PyRefMut<'a, T>> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
46 if self.mutably_borrowed.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
47 return Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
48 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
49 "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
|
50 mutable reference in a Python object", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
51 )); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
52 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
53 match self.leak_count.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
54 0 => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
55 self.mutably_borrowed.replace(true); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
56 Ok(PyRefMut::new(py, pyrefmut, self)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
57 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
58 // TODO |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
59 // For now, this works differently than Python references |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
60 // in the case of iterators. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
61 // Python does not complain when the data an iterator |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
62 // points to is modified if the iterator is never used |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
63 // afterwards. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
64 // Here, we are stricter than this by refusing to give a |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
65 // mutable reference if it is already borrowed. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
66 // While the additional safety might be argued for, it |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
67 // breaks valid programming patterns in Python and we need |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
68 // to fix this issue down the line. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
69 _ => Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
70 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
71 "Cannot borrow mutably while there are \ |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
72 immutable references in Python objects", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
73 )), |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
74 } |
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 |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
77 /// 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
|
78 /// artificial static lifetime. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
79 /// We need to be protected by the GIL for thread-safety. |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
80 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
81 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
82 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
83 /// 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:
42856
diff
changeset
|
84 /// extended. Do not call this function directly. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
85 pub unsafe fn leak_immutable<T>( |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
86 &self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
87 py: Python, |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
88 data: &PySharedRefCell<T>, |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
89 ) -> PyResult<(&'static T, &'static PySharedState)> { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
90 if self.mutably_borrowed.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
91 return Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
92 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
93 "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
|
94 mutable reference in Python objects", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
95 )); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
96 } |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
97 // TODO: it's weird that self is data.py_shared_state. Maybe we |
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
98 // can move stuff to PySharedRefCell? |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
99 let ptr = data.as_ptr(); |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
100 let state_ptr: *const PySharedState = &data.py_shared_state; |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
101 self.leak_count.replace(self.leak_count.get() + 1); |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
102 Ok((&*ptr, &*state_ptr)) |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
103 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
104 |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
105 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
106 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
107 /// It's unsafe to update the reference count without knowing the |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
108 /// reference is deleted. Do not call this function directly. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
109 pub unsafe fn decrease_leak_count(&self, _py: Python, mutable: bool) { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
110 if mutable { |
42943
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
111 assert_eq!(self.leak_count.get(), 0); |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
112 assert!(self.mutably_borrowed.get()); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
113 self.mutably_borrowed.replace(false); |
42943
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
114 } else { |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
115 let count = self.leak_count.get(); |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
116 assert!(count > 0); |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
117 self.leak_count.replace(count - 1); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
118 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
119 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
120 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
121 |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
122 /// `RefCell` wrapper to be safely used in conjunction with `PySharedState`. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
123 /// |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
124 /// Only immutable operation is allowed through this interface. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
125 #[derive(Debug)] |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
126 pub struct PySharedRefCell<T> { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
127 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
|
128 py_shared_state: PySharedState, |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
129 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
130 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
131 impl<T> PySharedRefCell<T> { |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
132 pub fn new(value: T) -> PySharedRefCell<T> { |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
133 Self { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
134 inner: RefCell::new(value), |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
135 py_shared_state: PySharedState::default(), |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
136 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
137 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
138 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
139 pub fn borrow(&self) -> Ref<T> { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
140 // py_shared_state isn't involved since |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
141 // - inner.borrow() would fail if self is mutably borrowed, |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
142 // - and inner.borrow_mut() would fail while self is borrowed. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
143 self.inner.borrow() |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
144 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
145 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
146 pub fn as_ptr(&self) -> *mut T { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
147 self.inner.as_ptr() |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
148 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
149 |
43174
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
150 // 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
|
151 // 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
|
152 // 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
|
153 // refuses to borrow. |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
154 pub fn borrow_mut<'a>( |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
155 &'a self, |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
156 py: Python<'a>, |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
157 ) -> PyResult<PyRefMut<'a, T>> { |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
158 self.py_shared_state.borrow_mut(py, self.inner.borrow_mut()) |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
159 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
160 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
161 |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
162 /// 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
|
163 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
|
164 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
165 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
166 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
|
167 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
168 |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
169 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
|
170 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
171 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
172 /// 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
|
173 /// would get wrong. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
174 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
|
175 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
176 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
177 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
|
178 ) -> Self { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
179 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
|
180 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
181 |
43272
00222775d59b
rust-refsharing: add missing lifetime parameter in ref_sharing
Rapha?l Gom?s <rgomes@octobus.net>
parents:
43180
diff
changeset
|
182 pub fn borrow(&self) -> Ref<'a, T> { |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
183 self.data.borrow() |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
184 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
185 |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
186 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
|
187 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
|
188 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
189 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
190 /// Returns a leaked reference. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
191 pub fn leak_immutable(&self) -> PyResult<PyLeakedRef<&'static T>> { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
192 let state = &self.data.py_shared_state; |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
193 unsafe { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
194 let (static_ref, static_state_ref) = |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
195 state.leak_immutable(self.py, self.data)?; |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
196 Ok(PyLeakedRef::new( |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
197 self.py, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
198 self.owner, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
199 static_ref, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
200 static_state_ref, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
201 )) |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
202 } |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
203 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
204 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
205 |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
206 /// 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
|
207 pub struct PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
208 inner: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
209 py_shared_state: &'a PySharedState, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
210 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
211 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
212 impl<'a, T> PyRefMut<'a, T> { |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
213 // Must be constructed by PySharedState after checking its leak_count. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
214 // Otherwise, drop() would incorrectly update the state. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
215 fn new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
216 _py: Python<'a>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
217 inner: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
218 py_shared_state: &'a PySharedState, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
219 ) -> Self { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
220 Self { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
221 inner, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
222 py_shared_state, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
223 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
224 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
225 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
226 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
227 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
|
228 type Target = RefMut<'a, T>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
229 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
230 fn deref(&self) -> &Self::Target { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
231 &self.inner |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
232 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
233 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
234 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
|
235 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
|
236 &mut self.inner |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
237 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
238 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
239 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
240 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
|
241 fn drop(&mut self) { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
242 let gil = Python::acquire_gil(); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
243 let py = gil.python(); |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
244 unsafe { |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
245 self.py_shared_state.decrease_leak_count(py, true); |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
246 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
247 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
248 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
249 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
250 /// 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
|
251 /// data members with Python. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
252 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
253 /// # Warning |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
254 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
255 /// TODO allow Python container types: for now, integration with the garbage |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
256 /// collector does not extend to Rust structs holding references to Python |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
257 /// objects. Should the need surface, `__traverse__` and `__clear__` will |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
258 /// need to be written as per the `rust-cpython` docs on GC integration. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
259 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
260 /// # Parameters |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
261 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
262 /// * `$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
|
263 /// * `$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
|
264 /// * `$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
|
265 /// 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
|
266 /// * `$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
|
267 /// 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
|
268 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
269 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
270 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
271 /// `$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
|
272 /// words, it must be an accessor to a data field of the Python object. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
273 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
274 /// # Example |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
275 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
276 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
277 /// struct MyStruct { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
278 /// inner: Vec<u32>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
279 /// } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
280 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
281 /// py_class!(pub class MyType |py| { |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
282 /// data inner: PySharedRefCell<MyStruct>; |
42768
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 /// |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
285 /// py_shared_ref!(MyType, MyStruct, inner, inner_shared); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
286 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
287 macro_rules! py_shared_ref { |
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 $name: ident, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
290 $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
|
291 $data_member: ident, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
292 $shared_accessor: ident |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
293 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
294 impl $name { |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
295 /// 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
|
296 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
297 /// 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
|
298 /// 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
|
299 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
|
300 &'a self, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
301 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
302 ) -> $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
|
303 use cpython::PythonObject; |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
304 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
|
305 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
|
306 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
|
307 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
|
308 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
309 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
310 }; |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
311 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
312 |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
313 /// Manage immutable references to `PyObject` leaked into Python iterators. |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
314 pub struct PyLeakedRef<T> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
315 inner: PyObject, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
316 data: Option<T>, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
317 py_shared_state: &'static PySharedState, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
318 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
319 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
320 // DO NOT implement Deref for PyLeakedRef<T>! Dereferencing PyLeakedRef |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
321 // without taking Python GIL wouldn't be safe. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
322 |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
323 impl<T> PyLeakedRef<T> { |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
324 /// # Safety |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
325 /// |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
326 /// The `py_shared_state` must be owned by the `inner` Python object. |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
327 // Marked as unsafe so client code wouldn't construct PyLeakedRef |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
328 // struct by mistake. Its drop() is unsafe. |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
329 pub unsafe fn new( |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
330 py: Python, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
331 inner: &PyObject, |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
332 data: T, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
333 py_shared_state: &'static PySharedState, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
334 ) -> Self { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
335 Self { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
336 inner: inner.clone_ref(py), |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
337 data: Some(data), |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
338 py_shared_state, |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
339 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
340 } |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
341 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
342 /// Returns an immutable reference to the inner value. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
343 pub fn get_ref<'a>(&'a self, _py: Python<'a>) -> &'a T { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
344 self.data.as_ref().unwrap() |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
345 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
346 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
347 /// Returns a mutable reference to the inner value. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
348 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
349 /// 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
|
350 /// `get_mut()` is useless since the inner value can't be mutated. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
351 pub fn get_mut<'a>(&'a mut self, _py: Python<'a>) -> &'a mut T { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
352 self.data.as_mut().unwrap() |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
353 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
354 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
355 /// 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
|
356 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
357 /// 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
|
358 /// iterator of that container. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
359 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
360 /// # Safety |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
361 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
362 /// 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
|
363 /// It's typically a static reference, but is valid only while the |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
364 /// corresponding `PyLeakedRef` is alive. Do not copy it out of the |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
365 /// function call. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
366 pub unsafe fn map<U>( |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
367 mut self, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
368 py: Python, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
369 f: impl FnOnce(T) -> U, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
370 ) -> PyLeakedRef<U> { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
371 // 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
|
372 // 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
|
373 // 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
|
374 // returned object back to Something<'static>. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
375 let new_data = f(self.data.take().unwrap()); |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
376 PyLeakedRef { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
377 inner: self.inner.clone_ref(py), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
378 data: Some(new_data), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
379 py_shared_state: self.py_shared_state, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
380 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
381 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
382 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
383 |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
384 impl<T> Drop for PyLeakedRef<T> { |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
385 fn drop(&mut self) { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
386 // py_shared_state should be alive since we do have |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
387 // a Python reference to the owner object. Taking GIL makes |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
388 // sure that the state is only accessed by this thread. |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
389 let gil = Python::acquire_gil(); |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
390 let py = gil.python(); |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
391 if self.data.is_none() { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
392 return; // moved to another PyLeakedRef |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
393 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
394 unsafe { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
395 self.py_shared_state.decrease_leak_count(py, false); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
396 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
397 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
398 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
399 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
400 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
401 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
402 /// 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:
42893
diff
changeset
|
403 /// 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:
42893
diff
changeset
|
404 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
405 /// # Parameters |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
406 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
407 /// * `$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:
42893
diff
changeset
|
408 /// * `$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:
42893
diff
changeset
|
409 /// * `$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:
42893
diff
changeset
|
410 /// * `$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:
42893
diff
changeset
|
411 /// 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:
42893
diff
changeset
|
412 /// * `$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:
42893
diff
changeset
|
413 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
414 /// # Example |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
415 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
416 /// ``` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
417 /// struct MyStruct { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
418 /// inner: HashMap<Vec<u8>, Vec<u8>>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
419 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
420 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
421 /// py_class!(pub class MyType |py| { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
422 /// data inner: PySharedRefCell<MyStruct>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
423 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
424 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
425 /// let leaked_ref = self.inner_shared(py).leak_immutable()?; |
42897
5ccc08d02280
rust-cpython: leverage py_shared_iterator::from_inner() where appropriate
Yuya Nishihara <yuya@tcha.org>
parents:
42896
diff
changeset
|
426 /// MyTypeItemsIterator::from_inner( |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
427 /// py, |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
428 /// unsafe { leaked_ref.map(py, |o| o.iter()) }, |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
429 /// ) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
430 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
431 /// }); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
432 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
433 /// impl MyType { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
434 /// fn translate_key_value( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
435 /// py: Python, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
436 /// res: (&Vec<u8>, &Vec<u8>), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
437 /// ) -> PyResult<Option<(PyBytes, PyBytes)>> { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
438 /// let (f, entry) = res; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
439 /// Ok(Some(( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
440 /// PyBytes::new(py, f), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
441 /// PyBytes::new(py, entry), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
442 /// ))) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
443 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
444 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
445 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
446 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
447 /// |
42895
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42894
diff
changeset
|
448 /// py_shared_iterator!( |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
449 /// MyTypeItemsIterator, |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
450 /// PyLeakedRef<HashMap<'static, Vec<u8>, Vec<u8>>>, |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
451 /// MyType::translate_key_value, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
452 /// Option<(PyBytes, PyBytes)> |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
453 /// ); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
454 /// ``` |
42895
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42894
diff
changeset
|
455 macro_rules! py_shared_iterator { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
456 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
457 $name: ident, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
458 $leaked: ty, |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
459 $success_func: expr, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
460 $success_type: ty |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
461 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
462 py_class!(pub class $name |py| { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
463 data inner: RefCell<Option<$leaked>>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
464 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
465 def __next__(&self) -> PyResult<$success_type> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
466 let mut inner_opt = self.inner(py).borrow_mut(); |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
467 if let Some(leaked) = inner_opt.as_mut() { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
468 match leaked.get_mut(py).next() { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
469 None => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
470 // replace Some(inner) by None, drop $leaked |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
471 inner_opt.take(); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
472 Ok(None) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
473 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
474 Some(res) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
475 $success_func(py, res) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
476 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
477 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
478 } else { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
479 Ok(None) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
480 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
481 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
482 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
483 def __iter__(&self) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
484 Ok(self.clone_ref(py)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
485 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
486 }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
487 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
488 impl $name { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
489 pub fn from_inner( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
490 py: Python, |
42896
74d67c645278
rust-cpython: remove Option<_> from interface of py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42895
diff
changeset
|
491 leaked: $leaked, |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
492 ) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
493 Self::create_instance( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
494 py, |
42896
74d67c645278
rust-cpython: remove Option<_> from interface of py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42895
diff
changeset
|
495 RefCell::new(Some(leaked)), |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
496 ) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
497 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
498 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
499 }; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
500 } |