1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::convert::TryFrom;
use std::ffi::CString;
use crate::errors::Error;
use crate::external;
use tvm_sys::{ArgValue, RetValue};
mod object_ptr;
pub use object_ptr::{IsObject, Object, ObjectPtr, ObjectRef};
pub trait AsArgValue<'a> {
fn as_arg_value(&'a self) -> ArgValue<'a>;
}
impl<'a, T: 'static> AsArgValue<'a> for T
where
&'a T: Into<ArgValue<'a>>,
{
fn as_arg_value(&'a self) -> ArgValue<'a> {
self.into()
}
}
pub trait IsObjectRef:
Sized
+ Clone
+ Into<RetValue>
+ for<'a> AsArgValue<'a>
+ TryFrom<RetValue, Error = Error>
+ for<'a> TryFrom<ArgValue<'a>, Error = Error>
+ std::fmt::Debug
{
type Object: IsObject;
fn as_ptr(&self) -> Option<&ObjectPtr<Self::Object>>;
fn into_ptr(self) -> Option<ObjectPtr<Self::Object>>;
fn from_ptr(object_ptr: Option<ObjectPtr<Self::Object>>) -> Self;
fn null() -> Self {
Self::from_ptr(None)
}
fn into_arg_value<'a>(&'a self) -> ArgValue<'a> {
self.as_arg_value()
}
fn from_arg_value<'a>(arg_value: ArgValue<'a>) -> Result<Self, Error> {
Self::try_from(arg_value)
}
fn into_ret_value<'a>(self) -> RetValue {
self.into()
}
fn from_ret_value<'a>(ret_value: RetValue) -> Result<Self, Error> {
Self::try_from(ret_value)
}
fn upcast<U>(self) -> U
where
U: IsObjectRef,
Self::Object: AsRef<U::Object>,
{
let ptr = self.into_ptr().map(ObjectPtr::upcast);
U::from_ptr(ptr)
}
fn downcast<U>(self) -> Result<U, Error>
where
U: IsObjectRef,
U::Object: AsRef<Self::Object>,
{
let ptr = self.into_ptr().map(ObjectPtr::downcast);
let ptr = ptr.transpose()?;
Ok(U::from_ptr(ptr))
}
}
external! {
#[name("ir.DebugPrint")]
pub fn debug_print(object: ObjectRef) -> CString;
#[name("node.StructuralHash")]
fn structural_hash(object: ObjectRef, map_free_vars: bool) -> i64;
#[name("node.StructuralEqual")]
fn structural_equal(lhs: ObjectRef, rhs: ObjectRef, assert_mode: bool, map_free_vars: bool) -> bool;
}