rust: look up HgRevlogIndex_GetParents() from symbol table
authorYuya Nishihara <yuya@tcha.org>
Sun, 02 Dec 2018 22:20:38 +0900
changeset 53627 54a60968f0aa7ee74fed464b832ab6d0bbf9af74
parent 53626 b12700dd261f03071d7536c141d965a311615632
child 53628 443eb4bc41af00cafefcf235f15bad24b1ea56a1
push id1079
push usergszorc@mozilla.com
push dateMon, 10 Dec 2018 19:44:59 +0000
rust: look up HgRevlogIndex_GetParents() from symbol table And removes the unused index_get_parents_checked() function. I expect the Index struct will be turned into a pyobject type, though I haven't written any PoC-level patches yet.
mercurial/cext/revlog.c
rust/hg-direct-ffi/src/ancestors.rs
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -2705,37 +2705,25 @@ typedef struct rustlazyancestorsObjectSt
 struct rustlazyancestorsObjectStruct {
 	PyObject_HEAD
 	    /* Type-specific fields go here. */
 	    indexObject *index; /* Ref kept to avoid GC'ing the index */
 	void *iter;             /* Rust iterator */
 };
 
 /* FFI exposed from Rust code */
-rustlazyancestorsObject *
-rustlazyancestors_init(indexObject *index,
-                       /* to pass index_get_parents() */
-                       int (*)(indexObject *, Py_ssize_t, int *, int),
-                       /* intrevs vector */
-                       Py_ssize_t initrevslen, long *initrevs, long stoprev,
-                       int inclusive);
+rustlazyancestorsObject *rustlazyancestors_init(indexObject *index,
+                                                /* intrevs vector */
+                                                Py_ssize_t initrevslen,
+                                                long *initrevs, long stoprev,
+                                                int inclusive);
 void rustlazyancestors_drop(rustlazyancestorsObject *self);
 int rustlazyancestors_next(rustlazyancestorsObject *self);
 int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev);
 
-static int index_get_parents_checked(indexObject *self, Py_ssize_t rev, int *ps,
-                                     int maxrev)
-{
-	if (rev < 0 || rev >= index_length(self)) {
-		PyErr_SetString(PyExc_ValueError, "rev out of range");
-		return -1;
-	}
-	return index_get_parents(self, rev, ps, maxrev);
-}
-
 /* CPython instance methods */
 static int rustla_init(rustlazyancestorsObject *self, PyObject *args)
 {
 	PyObject *initrevsarg = NULL;
 	PyObject *inclusivearg = NULL;
 	long stoprev = 0;
 	long *initrevs = NULL;
 	int inclusive = 0;
@@ -2763,22 +2751,22 @@ static int rustla_init(rustlazyancestors
 	}
 
 	for (i = 0; i < linit; i++) {
 		initrevs[i] = PyInt_AsLong(PyList_GET_ITEM(initrevsarg, i));
 	}
 	if (PyErr_Occurred())
 		goto bail;
 
-	self->iter = rustlazyancestors_init(index, index_get_parents, linit,
-	                                    initrevs, stoprev, inclusive);
+	self->iter =
+	    rustlazyancestors_init(index, linit, initrevs, stoprev, inclusive);
 	if (self->iter == NULL) {
 		/* if this is because of GraphError::ParentOutOfRange
-		 * index_get_parents_checked() has already set the proper
-		 * ValueError */
+		 * HgRevlogIndex_GetParents() has already set the proper
+		 * exception */
 		goto bail;
 	}
 
 	free(initrevs);
 	return 0;
 
 bail:
 	free(initrevs);
--- a/rust/hg-direct-ffi/src/ancestors.rs
+++ b/rust/hg-direct-ffi/src/ancestors.rs
@@ -11,69 +11,71 @@
 
 use hg::AncestorsIterator;
 use hg::{Graph, GraphError, Revision, NULL_REVISION};
 use libc::{c_int, c_long, c_void, ssize_t};
 use std::ptr::null_mut;
 use std::slice;
 
 type IndexPtr = *mut c_void;
-type IndexParentsFn =
-    unsafe extern "C" fn(index: IndexPtr, rev: ssize_t, ps: *mut [c_int; 2], max_rev: c_int)
-        -> c_int;
+
+extern "C" {
+    fn HgRevlogIndex_GetParents(
+        op: IndexPtr,
+        rev: c_int,
+        parents: *mut [c_int; 2],
+    ) -> c_int;
+}
 
 /// A Graph backed up by objects and functions from revlog.c
 ///
 /// This implementation of the Graph trait, relies on (pointers to)
 /// - the C index object (`index` member)
 /// - the `index_get_parents()` function (`parents` member)
 pub struct Index {
     index: IndexPtr,
-    parents: IndexParentsFn,
 }
 
 impl Index {
-    pub fn new(index: IndexPtr, parents: IndexParentsFn) -> Self {
+    pub fn new(index: IndexPtr) -> Self {
         Index {
             index: index,
-            parents: parents,
         }
     }
 }
 
 impl Graph for Index {
     /// wrap a call to the C extern parents function
     fn parents(&self, rev: Revision) -> Result<(Revision, Revision), GraphError> {
         let mut res: [c_int; 2] = [0; 2];
         let code =
-            unsafe { (self.parents)(self.index, rev as ssize_t, &mut res as *mut [c_int; 2], rev) };
+            unsafe { HgRevlogIndex_GetParents(self.index, rev, &mut res as *mut [c_int; 2]) };
         match code {
             0 => Ok((res[0], res[1])),
             _ => Err(GraphError::ParentOutOfRange(rev)),
         }
     }
 }
 
 /// Wrapping of AncestorsIterator<Index> constructor, for C callers.
 ///
 /// Besides `initrevs`, `stoprev` and `inclusive`, that are converted
 /// we receive the index and the parents function as pointers
 #[no_mangle]
 pub extern "C" fn rustlazyancestors_init(
     index: IndexPtr,
-    parents: IndexParentsFn,
     initrevslen: ssize_t,
     initrevs: *mut c_long,
     stoprev: c_long,
     inclusive: c_int,
 ) -> *mut AncestorsIterator<Index> {
     assert!(initrevslen >= 0);
     unsafe {
         raw_init(
-            Index::new(index, parents),
+            Index::new(index),
             initrevslen as usize,
             initrevs,
             stoprev,
             inclusive,
         )
     }
 }