3 //! You should not use this code directly. This is used by the binding generator to implement xsubs
4 //! for exported functions.
6 /// Raw perl subroutine pointer value. This should not be used directly.
12 /// Raw scalar-ish perl value. This should not be used directly.
18 /// Raw perl array value. This should not be used directly.
24 /// Raw perl hash value. This should not be used directly.
30 /// Raw perl hash entry iterator. This should not be used directly.
37 #[link(name = "glue", kind = "static")]
39 pub fn RSPL_StackMark_count(this
: usize) -> usize;
41 pub fn RSPL_stack_get(offset
: usize) -> *mut SV
;
43 pub fn RSPL_croak_sv(sv
: *mut SV
) -> !;
44 pub fn RSPL_SvNV(sv
: *mut SV
) -> f64;
45 pub fn RSPL_SvIV(sv
: *mut SV
) -> isize;
46 pub fn RSPL_SvPVutf8(sv
: *mut SV
, len
: *mut libc
::size_t
) -> *const libc
::c_char
;
47 pub fn RSPL_SvPV(sv
: *mut SV
, len
: *mut libc
::size_t
) -> *const libc
::c_char
;
48 /// This calls `sv_utf8_downgrade` first to avoid croaking, instead returns `NULL` on error.
49 pub fn RSPL_SvPVbyte(sv
: *mut SV
, len
: *mut libc
::size_t
) -> *const libc
::c_char
;
50 pub fn RSPL_sv_2mortal(sv
: *mut SV
) -> *mut SV
;
51 pub fn RSPL_get_undef() -> *mut SV
;
52 pub fn RSPL_get_yes() -> *mut SV
;
53 pub fn RSPL_get_no() -> *mut SV
;
54 pub fn RSPL_pop_markstack_ptr() -> usize;
55 pub fn RSPL_stack_resize_by(count
: isize);
56 pub fn RSPL_stack_shrink_to(count
: usize);
57 pub fn RSPL_stack_sp() -> *mut *mut SV
;
58 pub fn RSPL_newRV_inc(sv
: *mut SV
) -> *mut SV
;
59 pub fn RSPL_newSViv(v
: isize) -> *mut SV
;
60 pub fn RSPL_newSVuv(v
: usize) -> *mut SV
;
61 pub fn RSPL_newSVnv(v
: f64) -> *mut SV
;
62 pub fn RSPL_newSVpvn(v
: *const libc
::c_char
, len
: libc
::size_t
) -> *mut SV
;
63 pub fn RSPL_newSVpvn_utf8(v
: *const libc
::c_char
, len
: libc
::size_t
) -> *mut SV
;
64 pub fn RSPL_SvREFCNT_inc(sv
: *mut SV
) -> *mut SV
;
65 pub fn RSPL_SvREFCNT_dec(sv
: *mut SV
);
66 pub fn RSPL_is_reference(sv
: *mut SV
) -> bool
;
67 pub fn RSPL_dereference(sv
: *mut SV
) -> *mut SV
;
68 pub fn RSPL_is_array(sv
: *mut SV
) -> bool
;
69 pub fn RSPL_is_hash(sv
: *mut SV
) -> bool
;
70 pub fn RSPL_type_flags(sv
: *mut SV
) -> u32;
71 pub fn RSPL_svtype(sv
: *mut SV
) -> u32;
72 pub fn RSPL_SvOK(sv
: *mut SV
) -> bool
;
73 pub fn RSPL_SvANY(sv
: *mut SV
) -> bool
;
74 pub fn RSPL_SvTRUE(sv
: *mut SV
) -> bool
;
76 pub fn RSPL_is_defined(sv
: *mut SV
) -> bool
;
78 pub fn RSPL_newAV() -> *mut AV
;
79 pub fn RSPL_av_extend(av
: *mut AV
, len
: libc
::ssize_t
);
80 pub fn RSPL_av_push(av
: *mut AV
, sv
: *mut SV
);
81 pub fn RSPL_av_pop(av
: *mut AV
) -> *mut SV
;
82 pub fn RSPL_av_len(av
: *mut AV
) -> usize;
83 pub fn RSPL_av_fetch(av
: *mut AV
, index
: libc
::ssize_t
, lval
: i32) -> *mut *mut SV
;
85 pub fn RSPL_newHV() -> *mut HV
;
86 pub fn RSPL_HvTOTALKEYS(hv
: *mut HV
) -> usize;
89 key
: *const libc
::c_char
,
93 /// Always consumes ownership of `value`.
94 pub fn RSPL_hv_store(hv
: *mut HV
, key
: *const libc
::c_char
, klen
: i32, value
: *mut SV
) -> bool
;
95 pub fn RSPL_hv_store_ent(hv
: *mut HV
, key
: *mut SV
, value
: *mut SV
) -> bool
;
96 pub fn RSPL_hv_iterinit(hv
: *mut HV
);
97 pub fn RSPL_hv_iternextsv(
99 key
: *mut *mut libc
::c_char
,
102 pub fn RSPL_hv_iternext(hv
: *mut HV
) -> *mut HE
;
103 pub fn RSPL_hv_iterkeysv(he
: *mut HE
) -> *mut SV
;
104 pub fn RSPL_hv_iterval(hv
: *mut HV
, he
: *mut HE
) -> *mut SV
;
106 pub fn RSPL_gv_stashsv(name
: *const SV
, flags
: i32) -> *mut HV
;
107 pub fn RSPL_sv_bless(sv
: *mut SV
, stash
: *mut HV
) -> *mut SV
;
110 pub fn RSPL_SAVETMPS();
111 pub fn RSPL_FREETMPS();
114 pub fn RSPL_sv_reftype(sv
: *const SV
, ob
: libc
::c_int
) -> *const libc
::c_char
;
116 pub fn RSPL_PVLV() -> u32;
117 pub fn RSPL_LvTARG(sv
: *mut SV
) -> *mut SV
;
118 //pub fn RSPL_LvTYPE(sv: *mut SV) -> u8;
119 pub fn RSPL_vivify_defelem(sv
: *mut SV
);
121 //pub fn RSPL_SvFLAGS(sv: *mut SV) -> u32;
122 pub fn RSPL_SvGETMAGIC(sv
: *mut SV
) -> bool
;
125 /// Argument marker for the stack.
126 pub struct StackMark(usize);
129 pub fn count(&self) -> usize {
130 unsafe { RSPL_StackMark_count(self.0) }
133 pub fn iter(&self) -> StackIter
{
136 end
: self.0 + 1 + self.count(),
140 /// Shrink the perl stack to this mark.
144 /// This is only valid if the mark is still valid (smaller than `PL_stack_sp`) and all values
145 /// still remaining on the stack are mortal (which should normally be the case anyway).
146 pub unsafe fn set_stack(self) {
147 RSPL_stack_shrink_to(self.0);
151 /// Iterator over the stack up to the [`StackMark`].
152 pub struct StackIter
{
157 impl Iterator
for StackIter
{
158 type Item
= crate::Scalar
;
160 fn next(&mut self) -> Option
<Self::Item
> {
166 let ptr
= RSPL_stack_get(self.at
);
171 Some(crate::Scalar
::from_raw_ref(ptr
))
177 /// Pop the current argument marker off of the argument marker stack.
181 /// Read up on `PL_markstack_ptr` in perlguts. This is equivalent to `*PL_markstack_ptr--` in C.
182 pub unsafe fn pop_arg_mark() -> StackMark
{
183 StackMark(RSPL_pop_markstack_ptr())
186 /// Push a value to the stack.
190 /// Read up on mortals and the stack and when it is legal to put a value onto it. Typically a
191 /// mortal value with no more references to it to avoid leaking if they aren't used later on.
192 pub unsafe fn stack_push_raw(value
: *mut SV
) {
193 RSPL_stack_resize_by(1);
194 *RSPL_stack_sp() = value
;
197 pub fn stack_push(value
: crate::Mortal
) {
199 stack_push_raw(value
.into_raw());
203 /// This calls perl's `croak_sv`.
207 /// This seems to perform a `longjmp` and is thus never truly safe in rust code. You really want to
208 /// limit this to the top entry point of your rust call stack in a separate `extern "C" fn` where
209 /// no rust values with `Drop` handlers or anything similar are active.
211 /// The `perlmod_macro`'s `export` attribute typically creates 2 wrapper functions of the form:
214 /// # use serde::Serialize;
216 /// # #[derive(Serialize)]
219 /// # fn code_to_extract_parameters() {}
220 /// # fn actual_rust_function(_arg: ()) -> Result<Output, String> { Ok(Output) }
222 /// pub extern "C" fn exported_name(cv: &::perlmod::ffi::CV) {
224 /// match private_implementation_name(cv) {
225 /// Ok(sv) => ::perlmod::ffi::stack_push_raw(sv),
226 /// Err(sv) => ::perlmod::ffi::croak(sv),
232 /// fn private_implementation_name(
233 /// _cv: &::perlmod::ffi::CV,
234 /// ) -> Result<*mut ::perlmod::ffi::SV, *mut ::perlmod::ffi::SV> {
235 /// let args = code_to_extract_parameters();
237 /// let result = match actual_rust_function(args) {
238 /// Ok(output) => output,
240 /// return Err(::perlmod::Value::new_string(&err.to_string())
246 /// match ::perlmod::to_value(&result) {
247 /// Ok(value) => Ok(value.into_mortal().into_raw()),
248 /// Err(err) => Err(::perlmod::Value::new_string(&err.to_string())
254 pub unsafe fn croak(sv
: *mut SV
) -> ! {
258 /// Create a pseudo-block for mortals & temps to be freed after it.
259 /// This calls `ENTER; SAVETMPS;` before and `FREETMPS; LEAVE;` after the provided closure.
260 pub fn pseudo_block
<F
, R
>(func
: F
) -> R