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.
36 /// Raw perl MAGIC struct, we don't actually make its contents available.
42 #[allow(clippy::len_without_is_empty)]
44 pub fn vtbl(&self) -> Option
<&MGVTBL
> {
45 unsafe { RSPL_MAGIC_virtual(self as *const MAGIC).as_ref() }
48 pub fn ptr(&self) -> *const libc
::c_char
{
49 unsafe { RSPL_MAGIC_ptr(self as *const MAGIC) }
52 pub fn len(&self) -> isize {
53 unsafe { RSPL_MAGIC_len(self as *const MAGIC) }
58 pub struct Unsupported
{
62 #[cfg(perlmod = "multiplicity")]
64 pub struct Interpreter
{
68 /// Build perl-compatible functions and fn types (`pTHX` macro equivalent).
70 /// Takes an `extern "C" fn` (with or without body) and potentially inserts the a
71 /// `*const Interpreter` as first parameter depending on the perl configuration, so it can be used
72 /// for xsub implementations.
74 macro_rules
! perl_fn
{
75 // inherited visibility
78 extern "C" fn($
($args
:tt
)*) $
(-> $re
:ty
)?
80 $
crate::perl_fn_impl
! {
83 () extern "C" fn($
($args
)*) $
(-> $re
)?
89 extern "C" fn $name
:ident $
(<($
($gen
:tt
)*)>)?
($
($args
:tt
)*) $
(-> $re
:ty
)?
90 $
(where ($
($where_clause
:tt
)*))?
95 $
crate::perl_fn_impl
! {
98 () extern "C" fn $name $
(<($
($gen
)*)>)?
($
($args
)*) $
(-> $re
)?
99 $
(where ($
($where_clause
)*))?
107 // same with 'pub' visibility
110 pub $
(($
($vis
:tt
)+))?
extern "C" fn($
($args
:tt
)*) $
(-> $re
:ty
)?
112 $
crate::perl_fn_impl
! {
115 (pub $
(($
($vis
)+))?
) extern "C" fn($
($args
)*) $
(-> $re
)?
121 pub $
(($
($vis
:tt
)+))?
122 extern "C" fn $name
:ident $
(<($
($gen
:tt
)*)>)?
($
($args
:tt
)*) $
(-> $re
:ty
)?
123 $
(where ($
($where_clause
:tt
)*))?
128 $
crate::perl_fn_impl
! {
131 (pub $
(($
($vis
)+))?
) extern "C" fn $name $
(<($
($gen
)*)>)?
($
($args
)*) $
(-> $re
)?
132 $
(where ($
($where_clause
)*))?
141 #[cfg(perlmod = "multiplicity")]
142 mod vtbl_types_impl
{
143 use super::{Interpreter, MAGIC, SV}
;
146 pub type Get
= extern "C" fn(_perl
: *const Interpreter
, sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
147 pub type Set
= extern "C" fn(_perl
: *const Interpreter
, sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
148 pub type Len
= extern "C" fn(_perl
: *const Interpreter
, sv
: *mut SV
, mg
: *mut MAGIC
) -> u32;
149 pub type Clear
= extern "C" fn(_perl
: *const Interpreter
, sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
150 pub type Free
= extern "C" fn(_perl
: *const Interpreter
, sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
151 pub type Copy
= extern "C" fn(
152 _perl
: *const Interpreter
,
156 name
: *const libc
::c_char
,
159 pub type Dup
= extern "C" fn(
160 _perl
: *const Interpreter
,
163 clone_parms
: *mut super::Unsupported
,
165 pub type Local
= extern "C" fn(_perl
: *const Interpreter
, sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
169 macro_rules
! perl_fn_impl
{
172 ($
($vis
:tt
)*) extern "C" fn($
($args
:tt
)*) $
(-> $re
:ty
)?
175 $
($vis
)* extern "C" fn(*const $
crate::ffi
::Interpreter
, $
($args
)*) $
(-> $re
)?
180 extern "C" fn $name
:ident $
(<($
($gen
:tt
)*)>)?
($
($args
:tt
)*) $
(-> $re
:ty
)?
181 $
(where ($
($where_clause
:tt
)*))?
187 $
($vis
)* extern "C" fn $name $
(<$
($gen
)*>)?
(
188 _perl
: *const $
crate::ffi
::Interpreter
,
191 $
(where $
($where_clause
)*)?
199 #[cfg(not(perlmod = "multiplicity"))]
200 mod vtbl_types_impl
{
201 use super::{Interpreter, MAGIC, SV}
;
204 pub type Get
= extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
205 pub type Set
= extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
206 pub type Len
= extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
) -> u32;
207 pub type Clear
= extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
208 pub type Free
= extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
209 pub type Copy
= extern "C" fn(
213 name
: *const libc
::c_char
,
217 extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
, clone_parms
: *mut super::Unsupported
) -> c_int
;
218 pub type Local
= extern "C" fn(sv
: *mut SV
, mg
: *mut MAGIC
) -> c_int
;
222 macro_rules
! perl_fn_impl
{
225 ($
($vis
:tt
)*) extern "C" fn($
($args
:tt
)*) $
(-> $re
:ty
)?
228 $
($vis
)* extern "C" fn($
($args
)*) $
(-> $re
)?
233 extern "C" fn $name
:ident $
(<($
($gen
:tt
)*)>)?
($
($args
:tt
)*) $
(-> $re
:ty
)?
234 $
(where ($
($where_clause
:tt
)*))?
240 $
($vis
)* extern "C" fn $name $
(<$
($gen
)*>)?
($
($args
)*) $
(-> $re
)?
241 $
(where $
($where_clause
)*)?
249 /// The types in this module depend on the configuration of your perl installation.
251 /// If the perl interpreter has been compiled with `USEMULTIPLICITY`, these methods have an
252 /// additional parameter.
254 pub use super::vtbl_types_impl
::*;
257 #[derive(Clone, Copy)]
260 pub get
: Option
<vtbl_types
::Get
>,
261 pub set
: Option
<vtbl_types
::Set
>,
262 pub len
: Option
<vtbl_types
::Len
>,
263 pub clear
: Option
<vtbl_types
::Clear
>,
264 pub free
: Option
<vtbl_types
::Free
>,
265 pub copy
: Option
<vtbl_types
::Copy
>,
266 pub dup
: Option
<vtbl_types
::Dup
>,
267 pub local
: Option
<vtbl_types
::Local
>,
271 /// Let's not expose this directly, we need there to be distinct instances of these, so they
272 /// should be created via `MGVTBL::zero()`.
273 const EMPTY
: Self = Self {
284 /// Create a new all-zeroes vtbl as perl docs suggest this is the safest way to
285 /// make sure what a `PERL_MAGIC_ext` magic actually means, as the ptr value
286 /// may be arbitrary.
290 /// This must not be deallocated as long as it is attached to a perl value, so best use this as
291 /// `const` variables, rather than dynamically allocating it.
292 pub const fn zero() -> Self {
298 #[link(name = "glue", kind = "static")]
300 pub fn RSPL_StackMark_count(this
: usize) -> usize;
302 pub fn RSPL_stack_get(offset
: usize) -> *mut SV
;
304 pub fn RSPL_croak_sv(sv
: *mut SV
) -> !;
306 pub fn RSPL_newXS_flags(
314 pub fn RSPL_SvNV(sv
: *mut SV
) -> f64;
315 pub fn RSPL_SvIV(sv
: *mut SV
) -> isize;
316 pub fn RSPL_SvPVutf8(sv
: *mut SV
, len
: *mut libc
::size_t
) -> *const libc
::c_char
;
317 pub fn RSPL_SvPV(sv
: *mut SV
, len
: *mut libc
::size_t
) -> *const libc
::c_char
;
318 /// This calls `sv_utf8_downgrade` first to avoid croaking, instead returns `NULL` on error.
319 pub fn RSPL_SvPVbyte(sv
: *mut SV
, len
: *mut libc
::size_t
) -> *const libc
::c_char
;
320 pub fn RSPL_sv_2mortal(sv
: *mut SV
) -> *mut SV
;
321 pub fn RSPL_get_undef() -> *mut SV
;
322 pub fn RSPL_get_yes() -> *mut SV
;
323 pub fn RSPL_get_no() -> *mut SV
;
324 pub fn RSPL_pop_markstack_ptr() -> usize;
325 pub fn RSPL_stack_resize_by(count
: isize);
326 pub fn RSPL_stack_shrink_to(count
: usize);
327 pub fn RSPL_stack_sp() -> *mut *mut SV
;
328 pub fn RSPL_newRV_inc(sv
: *mut SV
) -> *mut SV
;
329 pub fn RSPL_newSViv(v
: isize) -> *mut SV
;
330 pub fn RSPL_newSVuv(v
: usize) -> *mut SV
;
331 pub fn RSPL_newSVnv(v
: f64) -> *mut SV
;
332 pub fn RSPL_newSVpvn(v
: *const libc
::c_char
, len
: libc
::size_t
) -> *mut SV
;
333 pub fn RSPL_newSVpvn_utf8(v
: *const libc
::c_char
, len
: libc
::size_t
) -> *mut SV
;
334 pub fn RSPL_SvREFCNT_inc(sv
: *mut SV
) -> *mut SV
;
335 pub fn RSPL_SvREFCNT_dec(sv
: *mut SV
);
336 pub fn RSPL_is_reference(sv
: *mut SV
) -> bool
;
337 pub fn RSPL_dereference(sv
: *mut SV
) -> *mut SV
;
338 pub fn RSPL_is_array(sv
: *mut SV
) -> bool
;
339 pub fn RSPL_is_hash(sv
: *mut SV
) -> bool
;
340 pub fn RSPL_type_flags(sv
: *mut SV
) -> u32;
341 pub fn RSPL_svtype(sv
: *mut SV
) -> u32;
342 pub fn RSPL_SvOK(sv
: *mut SV
) -> bool
;
343 pub fn RSPL_SvANY(sv
: *mut SV
) -> bool
;
344 pub fn RSPL_SvTRUE(sv
: *mut SV
) -> bool
;
346 pub fn RSPL_is_defined(sv
: *mut SV
) -> bool
;
348 pub fn RSPL_newAV() -> *mut AV
;
349 pub fn RSPL_av_extend(av
: *mut AV
, len
: libc
::ssize_t
);
350 pub fn RSPL_av_push(av
: *mut AV
, sv
: *mut SV
);
351 pub fn RSPL_av_pop(av
: *mut AV
) -> *mut SV
;
352 pub fn RSPL_av_len(av
: *mut AV
) -> usize;
353 pub fn RSPL_av_fetch(av
: *mut AV
, index
: libc
::ssize_t
, lval
: i32) -> *mut *mut SV
;
355 pub fn RSPL_newHV() -> *mut HV
;
356 pub fn RSPL_HvTOTALKEYS(hv
: *mut HV
) -> usize;
357 pub fn RSPL_hv_fetch(
359 key
: *const libc
::c_char
,
363 /// Always consumes ownership of `value`.
364 pub fn RSPL_hv_store(hv
: *mut HV
, key
: *const libc
::c_char
, klen
: i32, value
: *mut SV
) -> bool
;
365 pub fn RSPL_hv_store_ent(hv
: *mut HV
, key
: *mut SV
, value
: *mut SV
) -> bool
;
366 pub fn RSPL_hv_iterinit(hv
: *mut HV
);
367 pub fn RSPL_hv_iternextsv(
369 key
: *mut *mut libc
::c_char
,
372 pub fn RSPL_hv_iternext(hv
: *mut HV
) -> *mut HE
;
373 pub fn RSPL_hv_iterkeysv(he
: *mut HE
) -> *mut SV
;
374 pub fn RSPL_hv_iterval(hv
: *mut HV
, he
: *mut HE
) -> *mut SV
;
376 pub fn RSPL_gv_stashsv(name
: *const SV
, flags
: i32) -> *mut HV
;
377 pub fn RSPL_sv_bless(sv
: *mut SV
, stash
: *mut HV
) -> *mut SV
;
380 pub fn RSPL_SAVETMPS();
381 pub fn RSPL_FREETMPS();
384 pub fn RSPL_sv_reftype(sv
: *const SV
, ob
: libc
::c_int
) -> *const libc
::c_char
;
386 pub fn RSPL_PVLV() -> u32;
387 pub fn RSPL_LvTARG(sv
: *mut SV
) -> *mut SV
;
388 //pub fn RSPL_LvTYPE(sv: *mut SV) -> u8;
389 pub fn RSPL_vivify_defelem(sv
: *mut SV
);
391 //pub fn RSPL_SvFLAGS(sv: *mut SV) -> u32;
392 pub fn RSPL_SvGETMAGIC(sv
: *mut SV
) -> bool
;
394 pub fn RSPL_sv_magicext(
398 vtbl
: Option
<&MGVTBL
>,
399 name
: *const libc
::c_char
,
402 pub fn RSPL_sv_unmagicext(sv
: *mut SV
, ty
: libc
::c_int
, vtbl
: Option
<&MGVTBL
>);
403 pub fn RSPL_mg_findext(sv
: *const SV
, ty
: libc
::c_int
, vtbl
: Option
<&MGVTBL
>) -> *const MAGIC
;
404 pub fn RSPL_MAGIC_virtual(mg
: *const MAGIC
) -> *const MGVTBL
;
405 pub fn RSPL_MAGIC_ptr(mg
: *const MAGIC
) -> *const libc
::c_char
;
406 pub fn RSPL_MAGIC_len(mg
: *const MAGIC
) -> isize;
407 pub fn RSPL_PERL_MAGIC_ext() -> libc
::c_int
;
409 pub fn RSPL_PERL_MAGIC_substr() -> libc
::c_int
;
410 pub fn RSPL_vtbl_substr() -> *const MGVTBL
;
411 pub fn RSPL_substr(orig
: *mut SV
, off
: usize, len
: usize) -> *mut SV
;
414 /// Argument marker for the stack.
415 pub struct StackMark(usize);
418 pub fn count(&self) -> usize {
419 unsafe { RSPL_StackMark_count(self.0) }
422 pub fn iter(&self) -> StackIter
{
425 end
: self.0 + 1 + self.count(),
429 /// Shrink the perl stack to this mark.
433 /// This is only valid if the mark is still valid (smaller than `PL_stack_sp`) and all values
434 /// still remaining on the stack are mortal (which should normally be the case anyway).
435 pub unsafe fn set_stack(self) {
437 RSPL_stack_shrink_to(self.0);
442 /// Iterator over the stack up to the [`StackMark`].
443 pub struct StackIter
{
448 impl Iterator
for StackIter
{
449 type Item
= crate::Scalar
;
451 fn next(&mut self) -> Option
<Self::Item
> {
457 let ptr
= RSPL_stack_get(self.at
);
462 Some(crate::Scalar
::from_raw_ref(ptr
))
468 /// Pop the current argument marker off of the argument marker stack.
472 /// Read up on `PL_markstack_ptr` in perlguts. This is equivalent to `*PL_markstack_ptr--` in C.
473 pub unsafe fn pop_arg_mark() -> StackMark
{
474 StackMark(unsafe { RSPL_pop_markstack_ptr() }
)
477 /// Push a value to the stack.
481 /// Read up on mortals and the stack and when it is legal to put a value onto it. Typically a
482 /// mortal value with no more references to it to avoid leaking if they aren't used later on.
483 pub unsafe fn stack_push_raw(value
: *mut SV
) {
485 RSPL_stack_resize_by(1);
486 *RSPL_stack_sp() = value
;
490 pub fn stack_push(value
: crate::Mortal
) {
492 stack_push_raw(value
.into_raw());
496 /// This calls perl's `croak_sv`.
500 /// This seems to perform a `longjmp` and is thus never truly safe in rust code. You really want to
501 /// limit this to the top entry point of your rust call stack in a separate `extern "C" fn` where
502 /// no rust values with `Drop` handlers or anything similar are active.
504 /// The `perlmod_macro`'s `export` attribute typically creates 2 wrapper functions of the form:
507 /// # use serde::Serialize;
510 /// # impl Serialize for Output {
511 /// # fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
512 /// # serializer.serialize_unit()
516 /// # fn code_to_extract_parameters() {}
517 /// # fn actual_rust_function(_arg: ()) -> Result<Output, String> { Ok(Output) }
519 /// pub extern "C" fn exported_name(/* pTHX parameter, */ cv: &::perlmod::ffi::CV) {
521 /// match private_implementation_name(cv) {
522 /// Ok(sv) => ::perlmod::ffi::stack_push_raw(sv),
523 /// Err(sv) => ::perlmod::ffi::croak(sv),
529 /// fn private_implementation_name(
530 /// _cv: &::perlmod::ffi::CV,
531 /// ) -> Result<*mut ::perlmod::ffi::SV, *mut ::perlmod::ffi::SV> {
532 /// let args = code_to_extract_parameters();
534 /// let result = match actual_rust_function(args) {
535 /// Ok(output) => output,
537 /// return Err(::perlmod::Value::new_string(&err.to_string())
543 /// match ::perlmod::to_value(&result) {
544 /// Ok(value) => Ok(value.into_mortal().into_raw()),
545 /// Err(err) => Err(::perlmod::Value::new_string(&err.to_string())
551 pub unsafe fn croak(sv
: *mut SV
) -> ! {
557 /// Create a pseudo-block for mortals & temps to be freed after it.
558 /// This calls `ENTER; SAVETMPS;` before and `FREETMPS; LEAVE;` after the provided closure.
559 pub fn pseudo_block
<F
, R
>(func
: F
) -> R