binarybana commented on a change in pull request #5328:
URL: https://github.com/apache/incubator-tvm/pull/5328#discussion_r411067781
##########
File path: rust/tvm-rt/src/object.rs
##########
@@ -0,0 +1,268 @@
+use std::convert::TryFrom;
+use std::convert::TryInto;
+use std::ffi::CString;
+use std::ptr::NonNull;
+use tvm_sys::ffi::{self, TVMObjectFree, TVMObjectRetain,
TVMObjectTypeKey2Index};
+use tvm_sys::{TVMArgValue, TVMRetValue};
+
+type Deleter<T> = unsafe extern "C" fn(object: *mut T) -> ();
+
+#[derive(Debug)]
+#[repr(C)]
+pub struct Object {
+ pub type_index: u32,
+ pub ref_count: i32,
+ pub fdeleter: Deleter<Object>,
+}
+
+unsafe extern "C" fn delete<T: IsObject>(object: *mut Object) {
+ let typed_object: *mut T = std::mem::transmute(object);
+ T::typed_delete(typed_object);
+}
+
+fn derived_from(child_type_index: u32, parent_type_index: u32) -> bool {
+ let mut is_derived = 0;
+ crate::check_call!(ffi::TVMObjectDerivedFrom(
+ child_type_index,
+ parent_type_index,
+ &mut is_derived
+ ));
+ if is_derived == 0 {
+ false
+ } else {
+ true
+ }
+}
+
+impl Object {
+ fn new(type_index: u32, deleter: Deleter<Object>) -> Object {
+ Object {
+ type_index,
+ // Note: do not touch this field directly again, this is
+ // a critical section, we write a 1 to the atomic which will now
+ // be managed by the C++ atomics.
+ // In the future we should probably use C-atomcis.
+ ref_count: 1,
+ fdeleter: deleter,
+ }
+ }
+
+ fn get_type_index<T: IsObject>() -> u32 {
+ let type_key = T::TYPE_KEY;
+ let cstring = CString::new(type_key).expect("type key must not contain
null characters");
+ if type_key == "Object" {
+ return 0;
+ } else {
+ let mut index = 0;
+ unsafe {
+ let index_ptr = std::mem::transmute(&mut index);
+ if TVMObjectTypeKey2Index(cstring.as_ptr(), index_ptr) != 0 {
+ panic!(crate::get_last_error())
+ }
+ }
+ return index;
+ }
+ }
+
+ pub fn base_object<T: IsObject>() -> Object {
+ let index = Object::get_type_index::<T>();
+ Object::new(index, delete::<T>)
+ }
+}
+
+pub unsafe trait IsObject {
+ const TYPE_KEY: &'static str;
+
+ fn as_object<'s>(&'s self) -> &'s Object;
+
+ unsafe extern "C" fn typed_delete(object: *mut Self) {
+ // let object = Box::from_raw(object);
+ // drop(object)
+ }
+}
+
+unsafe impl IsObject for Object {
+ const TYPE_KEY: &'static str = "Object";
+
+ fn as_object<'s>(&'s self) -> &'s Object {
+ self
+ }
+}
+
+// unsafe impl<T: IsObject> IsObject for ObjectPtr<T> {
+// fn as_object<'s>(&'s self) -> &'s Object {
+// unsafe { self.ptr.as_ref().as_object() }
+// }
+// }
+
+#[repr(C)]
+pub struct ObjectPtr<T> {
+ ptr: NonNull<T>,
+}
+
+impl ObjectPtr<Object> {
+ fn from_raw(object_ptr: *mut Object) -> Option<ObjectPtr<Object>> {
+ let non_null = NonNull::new(object_ptr);
+ non_null.map(|ptr| ObjectPtr { ptr })
+ }
+}
+
+impl<T> Clone for ObjectPtr<T> {
+ fn clone(&self) -> Self {
+ unsafe {
+ let raw_ptr = std::mem::transmute(self.ptr);
+ assert_eq!(TVMObjectRetain(raw_ptr), 0);
+ ObjectPtr { ptr: self.ptr }
+ }
+ }
+}
+
+impl<T> Drop for ObjectPtr<T> {
+ fn drop(&mut self) {
+ unsafe {
+ let raw_ptr = std::mem::transmute(self.ptr);
+ assert_eq!(TVMObjectFree(raw_ptr), 0)
+ }
+ }
+}
+
+impl<T: IsObject> ObjectPtr<T> {
+ pub fn new(object: T) -> ObjectPtr<T> {
+ let object_ptr = Box::new(object);
+ let ptr = NonNull::from(Box::leak(object_ptr));
+ ObjectPtr { ptr }
+ }
+
+ pub fn count(&self) -> i32 {
+ // need to do atomic read in C++
+ // ABI compatible atomics is funky/hard.
Review comment:
My understanding was that for both Rust and C++, their atomic int types
are laid out in memory identical to their non atomic counterparts, but I guess
this is not the same as guaranteeing ABI compatibility...
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]