Mercurial > hg
comparison rust/hg-cpython/src/cindex.rs @ 43959:f384d68d8ea8
revlog: made C Capsule an array of function pointers
Although it's perfectly valid to put a function pointer in
a capsule, as we've been doing since the start of rust/hg-cpython,
an array of function pointers has several advantages:
- it can hold several functions. That's our main motivation here.
We plan to expose index_length() and index_node(), which will
be needed for a Rust implementation of nodemap.
- it could also have data
- (probably minor in the case of Mercurial) proper support for
architectures for which data and code pointers don't have the
same size.
Differential Revision: https://phab.mercurial-scm.org/D7543
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Wed, 27 Nov 2019 17:59:58 +0100 |
parents | 0246bbe1045d |
children | ab3fd8077f5e |
comparison
equal
deleted
inserted
replaced
43958:26cf356ae772 | 43959:f384d68d8ea8 |
---|---|
12 | 12 |
13 use cpython::{PyClone, PyObject, PyResult, Python}; | 13 use cpython::{PyClone, PyObject, PyResult, Python}; |
14 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; | 14 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; |
15 use libc::c_int; | 15 use libc::c_int; |
16 | 16 |
17 py_capsule_fn!( | 17 #[repr(C)] |
18 from mercurial.cext.parsers import index_get_parents_CAPI | 18 pub struct Revlog_CAPI { |
19 as get_parents_capi | 19 index_parents: unsafe extern "C" fn( |
20 signature ( | 20 index: *mut revlog_capi::RawPyObject, |
21 index: *mut RawPyObject, | 21 rev: c_int, |
22 rev: c_int, | 22 ps: *mut [c_int; 2], |
23 ps: *mut [c_int; 2], | 23 ) -> c_int, |
24 ) -> c_int | 24 } |
25 ); | 25 |
26 py_capsule!( | |
27 from mercurial.cext.parsers import revlog_CAPI | |
28 as revlog_capi for Revlog_CAPI); | |
26 | 29 |
27 /// A `Graph` backed up by objects and functions from revlog.c | 30 /// A `Graph` backed up by objects and functions from revlog.c |
28 /// | 31 /// |
29 /// This implementation of the `Graph` trait, relies on (pointers to) | 32 /// This implementation of the `Graph` trait, relies on (pointers to) |
30 /// - the C index object (`index` member) | 33 /// - the C index object (`index` member) |
56 /// the core API, that would be tied to `GILGuard` / `Python<'p>` | 59 /// the core API, that would be tied to `GILGuard` / `Python<'p>` |
57 /// in the case of the `cpython` crate bindings yet could leave room for other | 60 /// in the case of the `cpython` crate bindings yet could leave room for other |
58 /// mechanisms in other contexts. | 61 /// mechanisms in other contexts. |
59 pub struct Index { | 62 pub struct Index { |
60 index: PyObject, | 63 index: PyObject, |
61 parents: get_parents_capi::CapsuleFn, | 64 capi: &'static Revlog_CAPI, |
62 } | 65 } |
63 | 66 |
64 impl Index { | 67 impl Index { |
65 pub fn new(py: Python, index: PyObject) -> PyResult<Self> { | 68 pub fn new(py: Python, index: PyObject) -> PyResult<Self> { |
66 Ok(Index { | 69 Ok(Index { |
67 index: index, | 70 index: index, |
68 parents: get_parents_capi::retrieve(py)?, | 71 capi: unsafe { revlog_capi::retrieve(py)? }, |
69 }) | 72 }) |
70 } | 73 } |
71 } | 74 } |
72 | 75 |
73 impl Clone for Index { | 76 impl Clone for Index { |
74 fn clone(&self) -> Self { | 77 fn clone(&self) -> Self { |
75 let guard = Python::acquire_gil(); | 78 let guard = Python::acquire_gil(); |
76 Index { | 79 Index { |
77 index: self.index.clone_ref(guard.python()), | 80 index: self.index.clone_ref(guard.python()), |
78 parents: self.parents.clone(), | 81 capi: self.capi, |
79 } | 82 } |
80 } | 83 } |
81 } | 84 } |
82 | 85 |
83 impl Graph for Index { | 86 impl Graph for Index { |
86 if rev == WORKING_DIRECTORY_REVISION { | 89 if rev == WORKING_DIRECTORY_REVISION { |
87 return Err(GraphError::WorkingDirectoryUnsupported); | 90 return Err(GraphError::WorkingDirectoryUnsupported); |
88 } | 91 } |
89 let mut res: [c_int; 2] = [0; 2]; | 92 let mut res: [c_int; 2] = [0; 2]; |
90 let code = unsafe { | 93 let code = unsafe { |
91 (self.parents)( | 94 (self.capi.index_parents)( |
92 self.index.as_ptr(), | 95 self.index.as_ptr(), |
93 rev as c_int, | 96 rev as c_int, |
94 &mut res as *mut [c_int; 2], | 97 &mut res as *mut [c_int; 2], |
95 ) | 98 ) |
96 }; | 99 }; |