experimental PVLV support

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2021-06-08 11:28:01 +02:00
parent ec6f42c37e
commit 61143f5d12
5 changed files with 54 additions and 0 deletions

View File

@ -10,4 +10,16 @@ mod export {
Ok(a + b)
}
#[export]
fn test(t: Option<String>) -> Result<(), Error> {
println!("test called with {:?}", t);
Ok(())
}
#[export]
fn teststr(t: Option<&str>) -> Result<(), Error> {
println!("teststr called with {:?}", t);
Ok(())
}
}

View File

@ -107,6 +107,10 @@ extern "C" {
pub fn RSPL_LEAVE();
pub fn RSPL_sv_reftype(sv: *const SV, ob: libc::c_int) -> *const libc::c_char;
pub fn RSPL_PVLV() -> u32;
pub fn RSPL_LvTARG(sv: *mut SV) -> *mut SV;
pub fn RSPL_vivify_defelem(sv: *mut SV);
}
/// Argument marker for the stack.

View File

@ -301,6 +301,19 @@ extern const char* RSPL_sv_reftype(const SV *const sv, const int ob) {
return sv_reftype(sv, ob);
}
// We we don't need to generate the numeric value:
extern uint32_t RSPL_PVLV() {
return SVt_PVLV;
}
extern SV* RSPL_LvTARG(SV *sv) {
return LvTARG(sv);
}
extern void RSPL_vivify_defelem(SV *sv) {
Perl_vivify_defelem(aTHX_ sv);
}
/*
These make are convoluted brainfarts:
SVt_NULL undef

View File

@ -205,6 +205,10 @@ impl ScalarRef {
let ty = ffi::RSPL_svtype(self.sv());
if ty == 0 {
Type::Scalar(Flags::empty())
} else if ty == ffi::RSPL_PVLV() {
self.get_target()
.map(|s| s.ty())
.unwrap_or(Type::Other(99))
} else {
Type::Other(ty as u8)
}
@ -213,6 +217,19 @@ impl ScalarRef {
}
}
/// Dereference this PVLV.
pub fn get_target(&self) -> Option<Scalar> {
let ptr = unsafe {
ffi::RSPL_vivify_defelem(self.sv());
ffi::RSPL_LvTARG(self.sv())
};
if ptr.is_null() {
None
} else {
Some(unsafe { Scalar::from_raw_ref(ptr) })
}
}
/// Dereference this reference.
pub fn dereference(&self) -> Option<Scalar> {
let ptr = unsafe { ffi::RSPL_dereference(self.sv()) };

View File

@ -4,6 +4,7 @@ use v5.28.0;
use lib '.';
use RSPM::Bless;
use RSPM::Foo142;
my $v = RSPM::Bless->new("Hello");
$v->something();
@ -13,3 +14,10 @@ my @ret = $v->multi_return();
say "Got: ".scalar(@ret)." values: @ret";
$v->another(54);
my $param = { a => 1 };
my $s = "Hello You";
RSPM::Foo142::test(substr($s, 3, 3));
RSPM::Foo142::teststr(substr($s, 3, 3));
RSPM::Foo142::test($param->{x});
RSPM::Foo142::teststr($param->{x});