Struct Perl

Source
pub struct Perl {
    pub my_perl: *mut PerlInterpreter,
    /* private fields */
}

Fields§

§my_perl: *mut PerlInterpreter

Implementations§

Source§

impl Perl

Source

pub fn new() -> Perl

Examples found in repository?
examples/001_perl_parse_args.rs (line 8)
7fn my_test() {
8    let mut perl = Perl::new();
9    perl.parse_env_args(env::args(), env::vars());
10}
More examples
Hide additional examples
examples/000_perl_parse.rs (line 13)
12fn main() {
13    let mut perl = Perl::new();
14    
15    perl.parse(&["", "-e", r#"use strict; $foo"#], &[]);
16}
examples/100_scan_ops.rs (line 31)
30fn my_test() {
31    let mut perl = Perl::new();
32    perl.parse_env_args(env::args(), env::vars());
33    scan_ops(unsafe {*perl.my_perl}.Imain_start);
34}
examples/101_scan_ops_debug.rs (line 17)
16fn my_test() {
17    let mut perl = Perl::new();
18    perl.parse_env_args(env::args(), env::vars());
19    scan_ops(unsafe {*perl.my_perl}.Imain_start);
20}
examples/103_scan_op_tree.rs (line 30)
29fn my_test() {
30    let mut perl = Perl::new();
31    
32    perl.parse_env_args(env::args(), env::vars());
33    
34    let op = perl.get_main_root();
35    tree(op, 0);
36}
examples/104_enum_op_tree.rs (line 28)
27fn my_test() {
28    let mut perl = Perl::new();
29    perl.parse_env_args(env::args(), env::vars());
30    
31    let walker = Walker {perl: &perl, cv: perl.get_main_cv()};
32
33    walker.walk(perl.get_main_root(), 0);
34}
Source

pub fn my_perl(&self) -> &mut PerlInterpreter

Examples found in repository?
examples/110_call_method.rs (line 48)
45fn call_list_method(perl: &mut Perl, class_name: String, method_name: String, args: Vec<String>) -> Result<Vec<Sv>,String>
46{
47
48    let my_perl = perl.my_perl();
49
50    // dSP
51    let mut sp = my_perl.Istack_sp;
52
53    // ENTER
54    unsafe_perl_api!{Perl_push_scope(perl.my_perl)};
55
56    // SAVETMPS
57    unsafe_perl_api!{Perl_savetmps(perl.my_perl)};
58
59    // PUSHMARK(SP)
60    perl.pushmark(sp);
61    
62    // (... argument pushing ...)
63    // EXTEND(SP, 1+method_args.len())
64    sp = unsafe_perl_api!{Perl_stack_grow(perl.my_perl, sp, sp, (1 + args.len()).try_into().unwrap())};
65    
66    for s in [&[class_name], args.as_slice()].concat() {
67        sp_push!(sp, perl.str2svpv_mortal(s.as_str()));
68    }
69
70    // PUTBACK
71    my_perl.Istack_sp = sp;
72
73    // call_method
74    let cnt = unsafe_perl_api!{Perl_call_method(perl.my_perl, method_name.as_ptr() as *const i8, (G_METHOD_NAMED | G_LIST) as i32)};
75    
76    // SPAGAIN
77    // sp = my_perl.Istack_sp;
78    // (PUTBACK)
79
80    let res = stack_extract(&perl, cnt);
81
82    // FREETMPS
83    perl.free_tmps();
84    // LEAVE
85    unsafe_perl_api!{Perl_pop_scope(perl.my_perl)};
86    
87    Ok(res)
88}
Source

pub fn parse<S: AsRef<str>>(&mut self, args: &[S], envp: &[S]) -> i32

Examples found in repository?
examples/000_perl_parse.rs (line 15)
12fn main() {
13    let mut perl = Perl::new();
14    
15    perl.parse(&["", "-e", r#"use strict; $foo"#], &[]);
16}
More examples
Hide additional examples
examples/110_call_method.rs (lines 25-30)
16fn my_test() {
17    
18    let mut args = env::args().skip(1);
19    let inc_path = args.next().expect("Include path is required");
20    let class_name = args.next().expect("Class name is required");
21    let method_name = args.next().expect("Method name is required");
22    let method_args: Vec<String> = args.collect();
23    
24    let mut perl = Perl::new();
25    perl.parse(&[
26        "",
27        format!("-I{}", inc_path).as_str(),
28        format!("-M{}", class_name).as_str(),
29        "-e0",
30    ], &[]);
31    
32    match call_list_method(&mut perl, class_name, method_name, method_args) {
33        Ok(ary) => {
34            for item in ary {
35                println!("{:?}", item);
36            }
37        }
38        Err(e) => {
39            println!("ERROR: {:?}", e);
40        }
41    }
42}
Source

pub fn parse_env_args(&mut self, args: Args, envp: Vars) -> i32

Examples found in repository?
examples/001_perl_parse_args.rs (line 9)
7fn my_test() {
8    let mut perl = Perl::new();
9    perl.parse_env_args(env::args(), env::vars());
10}
More examples
Hide additional examples
examples/100_scan_ops.rs (line 32)
30fn my_test() {
31    let mut perl = Perl::new();
32    perl.parse_env_args(env::args(), env::vars());
33    scan_ops(unsafe {*perl.my_perl}.Imain_start);
34}
examples/101_scan_ops_debug.rs (line 18)
16fn my_test() {
17    let mut perl = Perl::new();
18    perl.parse_env_args(env::args(), env::vars());
19    scan_ops(unsafe {*perl.my_perl}.Imain_start);
20}
examples/103_scan_op_tree.rs (line 32)
29fn my_test() {
30    let mut perl = Perl::new();
31    
32    perl.parse_env_args(env::args(), env::vars());
33    
34    let op = perl.get_main_root();
35    tree(op, 0);
36}
examples/104_enum_op_tree.rs (line 29)
27fn my_test() {
28    let mut perl = Perl::new();
29    perl.parse_env_args(env::args(), env::vars());
30    
31    let walker = Walker {perl: &perl, cv: perl.get_main_cv()};
32
33    walker.walk(perl.get_main_root(), 0);
34}
examples/106_scan_allpackage.rs (line 34)
32fn my_test() {
33    let mut perl = Perl::new();
34    perl.parse_env_args(env::args(), env::vars());
35    
36    let mut seen = Seen::new();
37    seen.insert("main".to_string(), true); // To avoid main::main::main...
38    stash_subs(&perl, "", &mut seen);
39}
Source

pub fn hv_iterinit(&self, hv: *mut HV) -> i32

Examples found in repository?
examples/eg/hv_iter0.rs (line 12)
11    pub fn new(perl: &'a Perl, hv: *mut HV) -> HvIter<'a> {
12        perl.hv_iterinit(hv);
13        HvIter {perl, hv, he: std::ptr::null_mut()}
14    }
Source

pub fn hv_iternext(&self, hv: *mut HV) -> *mut HE

Examples found in repository?
examples/eg/hv_iter0.rs (line 21)
20    fn next(&mut self) -> Option<Self::Item> {
21        self.he = self.perl.hv_iternext(self.hv);
22        if !self.he.is_null() {
23            let name = self.perl.hv_iterkey(self.he);
24            let value = self.perl.hv_iterval(self.hv, self.he);
25            Some((name, value))
26        } else {
27            None
28        }
29    }
Source

pub fn hv_iterkey(&self, he: *mut HE) -> String

Examples found in repository?
examples/eg/hv_iter0.rs (line 23)
20    fn next(&mut self) -> Option<Self::Item> {
21        self.he = self.perl.hv_iternext(self.hv);
22        if !self.he.is_null() {
23            let name = self.perl.hv_iterkey(self.he);
24            let value = self.perl.hv_iterval(self.hv, self.he);
25            Some((name, value))
26        } else {
27            None
28        }
29    }
Source

pub fn _hv_iterkey(&self, he: *mut HE) -> (*const u8, usize)

Source

pub fn hv_iterval<'a>(&self, hv: *mut HV, he: *mut HE) -> *mut SV

Examples found in repository?
examples/eg/hv_iter0.rs (line 24)
20    fn next(&mut self) -> Option<Self::Item> {
21        self.he = self.perl.hv_iternext(self.hv);
22        if !self.he.is_null() {
23            let name = self.perl.hv_iterkey(self.he);
24            let value = self.perl.hv_iterval(self.hv, self.he);
25            Some((name, value))
26        } else {
27            None
28        }
29    }
Source

pub fn get_defstash(&self) -> *mut HV

Examples found in repository?
examples/105_scan_stash.rs (line 36)
30fn my_test() {
31    let mut perl = Perl::new();
32    perl.parse_env_args(env::args(), env::vars());
33    
34    // get_cvstash(perl.get_main_cv()); returns null. Why?
35    
36    let stash = perl.get_defstash();
37    
38    assert_eq!(perl.gv_stashpv("main", 0), stash);
39    
40    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
41    println!("$0 = {:?}", main_file);
42
43    let emitter = |name: &String, cv: *const libperl_sys::cv| {
44        let walker = Walker {perl: &perl, cv};
45        println!("sub {:?} file {:?}", name, CvFILE(cv));
46        walker.walk(CvROOT(cv), 0);
47        println!("");
48    };
49
50    for (name, item) in eg::hv_iter0::HvIter::new(&perl, stash) {
51
52        // ref $main::{foo} eq 'CODE'
53        if let Some(Sv::CODE(cv)) = SvRV(item).map(|sv| sv_extract(sv)) {
54            emitter(&name, cv)
55        }
56        // ref (\$main::{foo}) eq 'GLOB'
57        else if let Sv::GLOB {gv, ..} = sv_extract(item) {
58            let cv = GvCV(gv);
59            if let Some(file) = CvFILE(cv) {
60                if file == main_file {
61                    emitter(&name, cv);
62                } else {
63                    println!("name = {:?} from file {:?}", name, file);
64                }
65            }
66        }
67        
68    }
69}
Source

pub fn gv_stashpv(&self, name: &str, flags: i32) -> *mut HV

Examples found in repository?
examples/105_scan_stash.rs (line 38)
30fn my_test() {
31    let mut perl = Perl::new();
32    perl.parse_env_args(env::args(), env::vars());
33    
34    // get_cvstash(perl.get_main_cv()); returns null. Why?
35    
36    let stash = perl.get_defstash();
37    
38    assert_eq!(perl.gv_stashpv("main", 0), stash);
39    
40    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
41    println!("$0 = {:?}", main_file);
42
43    let emitter = |name: &String, cv: *const libperl_sys::cv| {
44        let walker = Walker {perl: &perl, cv};
45        println!("sub {:?} file {:?}", name, CvFILE(cv));
46        walker.walk(CvROOT(cv), 0);
47        println!("");
48    };
49
50    for (name, item) in eg::hv_iter0::HvIter::new(&perl, stash) {
51
52        // ref $main::{foo} eq 'CODE'
53        if let Some(Sv::CODE(cv)) = SvRV(item).map(|sv| sv_extract(sv)) {
54            emitter(&name, cv)
55        }
56        // ref (\$main::{foo}) eq 'GLOB'
57        else if let Sv::GLOB {gv, ..} = sv_extract(item) {
58            let cv = GvCV(gv);
59            if let Some(file) = CvFILE(cv) {
60                if file == main_file {
61                    emitter(&name, cv);
62                } else {
63                    println!("name = {:?} from file {:?}", name, file);
64                }
65            }
66        }
67        
68    }
69}
More examples
Hide additional examples
examples/eg/stash_walker0.rs (line 40)
35    pub fn walk(&mut self, pack: &str) {
36    
37        if self.seen.contains_key(pack) {return};
38        self.seen.insert(pack.to_string(), true);
39        
40        let stash = self.perl.gv_stashpv(pack, 0);
41        if stash.is_null() {return}
42
43        for (name, item) in hv_iter0::HvIter::new(&self.perl, stash) {
44
45            // ref $main::{foo} eq 'CODE'
46            if let Some(Sv::CODE(cv)) = SvRV(item).map(|sv| sv_extract(sv)) {
47                if (self.filter).map_or(true, |f| f(cv)) {
48                    (self.emitter)(&name, cv);
49                }
50            }
51            // ref (\$main::{foo}) eq 'GLOB'
52            else if let Sv::GLOB {gv, ..} = sv_extract(item) {
53                let cv = GvCV(gv);
54                if (self.filter).map_or(true, |f| f(cv)) {
55                    (self.emitter)(&name, cv);
56                }
57                if name.ends_with("::") {
58                    // println!("package name = {}", name);
59                    if let Some(pure) = name.get(..name.len() - 2) {
60                        if !self.seen.contains_key(pure) {
61                            // packages.push(String::from(pure.clone()));
62                            let mut fullpack = String::from(pack);
63                            fullpack.push_str("::");
64                            fullpack.push_str(pure);
65                            self.walk(fullpack.as_str());
66                        }
67                    }
68                }
69            }
70        }
71    }
examples/106_scan_allpackage.rs (line 51)
45fn stash_subs(perl: &Perl, pack: &str, seen: &mut Seen) {
46    println!("pack = {}", pack);
47
48    if seen.contains_key(pack) {return};
49    seen.insert(pack.to_string(), true);
50    
51    let stash = perl.gv_stashpv(pack, 0);
52    if stash.is_null() {return}
53
54    let emitter = |name: &String, cv: *const libperl_sys::cv| {
55        let walker = Walker {perl: &perl, cv};
56        println!("sub {:?} file {:?}", name, CvFILE(cv));
57        walker.walk(CvROOT(cv), 0);
58        println!("");
59    };
60
61    // let mut packages = Vec::new();
62    for (name, item) in eg::hv_iter0::HvIter::new(&perl, stash) {
63
64        // ref $main::{foo} eq 'CODE'
65        if let Some(Sv::CODE(cv)) = SvRV(item).map(|sv| sv_extract(sv)) {
66            emitter(&name, cv)
67        }
68        // ref (\$main::{foo}) eq 'GLOB'
69        else if let Sv::GLOB {gv, ..} = sv_extract(item) {
70            let cv = GvCV(gv);
71            if let Some(_file) = CvFILE(cv) {
72                emitter(&name, cv);
73            }
74            if name.ends_with("::") {
75                println!("package name = {}", name);
76                if let Some(pure) = name.get(..name.len() - 2) {
77                    if !seen.contains_key(pure) {
78                        // packages.push(String::from(pure.clone()));
79                        let mut fullpack = String::from(pack);
80                        fullpack.push_str("::");
81                        fullpack.push_str(pure);
82                        stash_subs(perl, fullpack.as_str(), seen);
83                    }
84                }
85            }
86        }
87    }
88    
89    // for pkg in packages {
90    //     stash_subs(perl, pkg.as_str(), seen);
91    // }
92}
Source

pub fn get_main_root(&self) -> *const op

Examples found in repository?
examples/103_scan_op_tree.rs (line 34)
29fn my_test() {
30    let mut perl = Perl::new();
31    
32    perl.parse_env_args(env::args(), env::vars());
33    
34    let op = perl.get_main_root();
35    tree(op, 0);
36}
More examples
Hide additional examples
examples/104_enum_op_tree.rs (line 33)
27fn my_test() {
28    let mut perl = Perl::new();
29    perl.parse_env_args(env::args(), env::vars());
30    
31    let walker = Walker {perl: &perl, cv: perl.get_main_cv()};
32
33    walker.walk(perl.get_main_root(), 0);
34}
examples/108_scan_subs_in_a_file2.rs (line 38)
13fn my_test() {
14    let mut perl = Perl::new();
15    perl.parse_env_args(env::args(), env::vars());
16    
17    let op_extractor = OpExtractor::new(&perl);
18
19    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
20    println!("$0 = {:?}", main_file);
21    
22    let filter = |cv| CvFILE(cv).map_or(false, |s| s == main_file);
23
24    let mut emitter = |name: &String, cv: *const libperl_sys::cv| {
25        println!("sub {:?}", name);
26        println!("{:#?}", op_extractor.extract(cv, CvROOT(cv)));
27        println!("");
28    };
29
30    let mut nswalker = StashWalker::new(&perl, Some(&filter), &mut emitter);
31
32    nswalker.walk("");
33    
34    let main_cv = perl.get_main_cv();
35
36    println!("#main_cv");
37    // XXX: CvROOT(main_cv) doesn't work here.
38    println!("{:#?}", op_extractor.extract(main_cv, perl.get_main_root()));
39    println!("");
40}
Source

pub fn get_main_cv(&self) -> *const cv

Examples found in repository?
examples/104_enum_op_tree.rs (line 31)
27fn my_test() {
28    let mut perl = Perl::new();
29    perl.parse_env_args(env::args(), env::vars());
30    
31    let walker = Walker {perl: &perl, cv: perl.get_main_cv()};
32
33    walker.walk(perl.get_main_root(), 0);
34}
More examples
Hide additional examples
examples/102_padname_type.rs (line 20)
14fn my_test() {
15
16    let mut perl = Perl::new();
17
18    perl.parse_env_args(env::args(), env::vars());
19    
20    let main_cv = perl.get_main_cv();
21    // print!("main_cv = {:?}\n", unsafe {*main_cv});
22
23    if let Some(padnamelist) = eg::pad0::cv_padnamelist(main_cv) {
24        println!("padnamelist = {:?}", padnamelist);
25        let mut ix: usize = 0;
26        while ix < (padnamelist.xpadnl_fill as usize) {
27            let padname = eg::pad0::padnamelist_nth(padnamelist, ix).unwrap();
28            println!("padname {} = var{{name: {:?}}}, type: {:?}"
29                     , ix
30                     , eg::pad0::PadnamePV(padname)
31                     , eg::pad0::PadnameTYPE(padname)
32            );
33            ix += 1;
34        }
35    }
36}
examples/108_scan_subs_in_a_file2.rs (line 34)
13fn my_test() {
14    let mut perl = Perl::new();
15    perl.parse_env_args(env::args(), env::vars());
16    
17    let op_extractor = OpExtractor::new(&perl);
18
19    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
20    println!("$0 = {:?}", main_file);
21    
22    let filter = |cv| CvFILE(cv).map_or(false, |s| s == main_file);
23
24    let mut emitter = |name: &String, cv: *const libperl_sys::cv| {
25        println!("sub {:?}", name);
26        println!("{:#?}", op_extractor.extract(cv, CvROOT(cv)));
27        println!("");
28    };
29
30    let mut nswalker = StashWalker::new(&perl, Some(&filter), &mut emitter);
31
32    nswalker.walk("");
33    
34    let main_cv = perl.get_main_cv();
35
36    println!("#main_cv");
37    // XXX: CvROOT(main_cv) doesn't work here.
38    println!("{:#?}", op_extractor.extract(main_cv, perl.get_main_root()));
39    println!("");
40}
Source

pub fn op_class(&self, o: *const OP) -> OPclass

Examples found in repository?
examples/eg/op0.rs (line 42)
41pub fn op_extract(perl: &Perl, cv: *const cv, o: *const op) -> Op {
42    let cls = perl.op_class(o);
43    let oc = opcode::try_from(o).unwrap();
44    match cls {
45        OPclass::OPclass_NULL => Op::NULL,
46        OPclass::OPclass_BASEOP => {
47            let op = unsafe {o.as_ref().unwrap()};
48            if let Some(pl) = cv_padnamelist(cv) {
49                if let Some(padname) = padnamelist_nth(pl, op.op_targ as usize) {
50                    return Op::OP(oc, PadnamePV(padname), PadnameTYPE(padname))
51                }
52            }
53            Op::OP(oc, None, None)
54        },
55        OPclass::OPclass_UNOP => Op::UNOP(oc/*, unsafe {(o as *const unop).as_ref()}.unwrap()*/),
56        OPclass::OPclass_BINOP => Op::BINOP(oc/*, unsafe {(o as *const binop).as_ref()}.unwrap()*/),
57        OPclass::OPclass_LOGOP => Op::LOGOP(oc/*, unsafe {(o as *const logop).as_ref()}.unwrap()*/),
58        OPclass::OPclass_LISTOP => Op::LISTOP(oc/*, unsafe {(o as *const listop).as_ref()}.unwrap()*/),
59        OPclass::OPclass_PMOP => Op::PMOP(oc/*, unsafe {(o as *const pmop).as_ref()}.unwrap()*/),
60        OPclass::OPclass_SVOP => {
61            let sv = op_sv_or(o, |op| PAD_BASE_SV(CvPADLIST(cv), op.op_targ));
62            Op::SVOP(oc, sv_extract(sv))
63        },
64        OPclass::OPclass_PADOP => {
65            let op = unsafe {(o as *const padop).as_ref()}.unwrap();
66            let sv = PAD_BASE_SV(CvPADLIST(cv), op.op_padix);
67            Op::PADOP(oc, sv_extract(sv))
68        },
69        OPclass::OPclass_PVOP => Op::PVOP(oc/*, unsafe {(o as *const pvop).as_ref()}.unwrap()*/),
70        OPclass::OPclass_LOOP => Op::LOOP(oc/*, unsafe {(o as *const loop_).as_ref()}.unwrap()*/),
71        OPclass::OPclass_COP => Op::COP(oc/*, unsafe {(o as *const cop).as_ref()}.unwrap()*/),
72        OPclass::OPclass_METHOP => {
73            if (unsafe {*o}.op_flags & OPf_KIDS as u8) != 0 {
74                Op::METHOP(oc, Name::Dynamic)
75                
76            } else {
77                let sv = op_sv_or(o, |op| PAD_BASE_SV(CvPADLIST(cv), op.op_targ));
78                Op::METHOP(oc, Name::Const(sv_extract(sv)))
79            }
80        },
81        #[cfg(perlapi_ver26)]
82        OPclass::OPclass_UNOP_AUX => Op::UNOP_AUX(oc /*, unsafe {(o as *const unop_aux).as_ref()}.unwrap()*/),
83    }
84}
More examples
Hide additional examples
examples/eg/op1.rs (line 173)
169    pub fn extract(&self, cv: *const cv, o: *const op) -> &'a Op {
170        if o.is_null() {
171            return self.ops.alloc(Op::NULL)
172        }
173        let cls = self.perl.op_class(o);
174        let oc = opcode::try_from(o).unwrap();
175        let eo = match cls {
176            OPclass::OPclass_NULL => Op::NULL,
177            OPclass::OPclass_BASEOP => {
178                let op = unsafe {o.as_ref().unwrap()};
179                let sibling = self.extract(cv, op_sibling(o as *const unop));
180                if_chain! {
181                    if let Some(pl) = cv_padnamelist(cv);
182                    if let Some(padname) = padnamelist_nth(pl, op.op_targ as usize);
183                    then {
184                        Op::OP (
185                            oc, o,
186                            Some(PadNameType {
187                                name: PadnamePV(padname), typ: PadnameTYPE(padname)
188                            }),
189                            sibling
190                        )
191                    } else {
192                        Op::OP (oc, o, None, sibling)
193                    }
194                }
195            },
196            OPclass::OPclass_UNOP => {
197                let op = unsafe {(o as *const unop).as_ref()}.unwrap();
198                Op::UNOP (
199                    oc, op,
200                    self.extract(cv, op.op_first),
201                    self.extract(cv, op_sibling(o as *const unop)),
202                )
203            },
204            OPclass::OPclass_BINOP => {
205                let op = unsafe {(o as *const binop).as_ref()}.unwrap();
206                Op::BINOP (
207                    oc, op,
208                    self.extract(cv, op.op_first),
209                    self.extract(cv, op_sibling(o as *const unop)),
210                )
211            },
212            OPclass::OPclass_LOGOP => {
213                let op = unsafe {(o as *const logop).as_ref()}.unwrap();
214                Op::LOGOP (
215                    oc, op,
216                    self.extract(cv, op.op_first),
217                    self.extract(cv, op_sibling(o as *const unop)),
218                )
219            },
220            OPclass::OPclass_LISTOP => {
221                let op = unsafe {(o as *const listop).as_ref()}.unwrap();
222                Op::LISTOP (
223                    oc, op,
224                    self.extract(cv, op.op_first),
225                    self.extract(cv, op_sibling(o as *const unop)),
226                )
227            },
228            // XXX
229            OPclass::OPclass_PMOP => Op::PMOP {opcode: oc},
230            OPclass::OPclass_SVOP => {
231                let sv = op_sv_or(o, |op| PAD_BASE_SV(CvPADLIST(cv), op.op_targ));
232                Op::SVOP (
233                    oc, sv_extract(sv),
234                    self.extract(cv, op_sibling(o as *const unop)),
235                )
236            },
237            OPclass::OPclass_PADOP => {
238                let op = unsafe {(o as *const padop).as_ref()}.unwrap();
239                let sv = PAD_BASE_SV(CvPADLIST(cv), op.op_padix);
240                Op::PADOP(oc, op, sv_extract(sv))
241            },
242            // XXX
243            OPclass::OPclass_PVOP => Op::PVOP (oc),
244            // XXX
245            OPclass::OPclass_LOOP => {
246                Op::LOOP (
247                    oc,
248                    self.extract(cv, op_sibling(o as *const unop)),
249                )
250            },
251            OPclass::OPclass_COP => {
252                // let op = unsafe {(o as *const cop).as_ref()}.unwrap();
253                Op::COP (
254                    oc,
255                    self.extract(cv, op_sibling(o as *const unop)),
256                )
257            },
258            // XXX
259            OPclass::OPclass_METHOP => {
260                if (unsafe {*o}.op_flags & OPf_KIDS as u8) != 0 {
261                    Op::METHOP (oc, Name::Dynamic)
262                        
263                } else {
264                    let sv = op_sv_or(o, |op| PAD_BASE_SV(CvPADLIST(cv), op.op_targ));
265                    Op::METHOP(oc, Name::Const(sv_extract(sv)))
266                }
267            },
268            #[cfg(perlapi_ver26)]
269            OPclass::OPclass_UNOP_AUX => {
270                let op = unsafe {(o as *const unop_aux).as_ref()}.unwrap();
271                Op::UNOP_AUX (
272                    oc,
273                    self.extract(cv, op.op_first),
274                    self.extract(cv, op_sibling(o as *const unop)),
275                )
276            }
277        };
278        
279        self.ops.alloc(eo)
280    }
Source

pub fn get_sv(&self, name: &str, flags: i32) -> *mut SV

Examples found in repository?
examples/107_scan_subs_in_a_file.rs (line 36)
32fn my_test() {
33    let mut perl = Perl::new();
34    perl.parse_env_args(env::args(), env::vars());
35    
36    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
37    println!("$0 = {:?}", main_file);
38    
39    let filter = |cv| CvFILE(cv).map_or(false, |s| s == main_file);
40
41    let mut emitter = |name: &String, cv: *const libperl_sys::cv| {
42        let walker = OpWalker {perl: &perl, cv};
43        println!("sub {:?}", name);
44        walker.walk(CvROOT(cv), 0);
45        println!("");
46    };
47
48    let mut nswalker = StashWalker::new(&perl, Some(&filter), &mut emitter);
49
50    nswalker.walk("");
51}
More examples
Hide additional examples
examples/108_scan_subs_in_a_file2.rs (line 19)
13fn my_test() {
14    let mut perl = Perl::new();
15    perl.parse_env_args(env::args(), env::vars());
16    
17    let op_extractor = OpExtractor::new(&perl);
18
19    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
20    println!("$0 = {:?}", main_file);
21    
22    let filter = |cv| CvFILE(cv).map_or(false, |s| s == main_file);
23
24    let mut emitter = |name: &String, cv: *const libperl_sys::cv| {
25        println!("sub {:?}", name);
26        println!("{:#?}", op_extractor.extract(cv, CvROOT(cv)));
27        println!("");
28    };
29
30    let mut nswalker = StashWalker::new(&perl, Some(&filter), &mut emitter);
31
32    nswalker.walk("");
33    
34    let main_cv = perl.get_main_cv();
35
36    println!("#main_cv");
37    // XXX: CvROOT(main_cv) doesn't work here.
38    println!("{:#?}", op_extractor.extract(main_cv, perl.get_main_root()));
39    println!("");
40}
examples/105_scan_stash.rs (line 40)
30fn my_test() {
31    let mut perl = Perl::new();
32    perl.parse_env_args(env::args(), env::vars());
33    
34    // get_cvstash(perl.get_main_cv()); returns null. Why?
35    
36    let stash = perl.get_defstash();
37    
38    assert_eq!(perl.gv_stashpv("main", 0), stash);
39    
40    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
41    println!("$0 = {:?}", main_file);
42
43    let emitter = |name: &String, cv: *const libperl_sys::cv| {
44        let walker = Walker {perl: &perl, cv};
45        println!("sub {:?} file {:?}", name, CvFILE(cv));
46        walker.walk(CvROOT(cv), 0);
47        println!("");
48    };
49
50    for (name, item) in eg::hv_iter0::HvIter::new(&perl, stash) {
51
52        // ref $main::{foo} eq 'CODE'
53        if let Some(Sv::CODE(cv)) = SvRV(item).map(|sv| sv_extract(sv)) {
54            emitter(&name, cv)
55        }
56        // ref (\$main::{foo}) eq 'GLOB'
57        else if let Sv::GLOB {gv, ..} = sv_extract(item) {
58            let cv = GvCV(gv);
59            if let Some(file) = CvFILE(cv) {
60                if file == main_file {
61                    emitter(&name, cv);
62                } else {
63                    println!("name = {:?} from file {:?}", name, file);
64                }
65            }
66        }
67        
68    }
69}
examples/109_scan_subs_intro1.rs (line 39)
33fn my_test() {
34    let mut perl = Perl::new();
35    perl.parse_env_args(env::args(), env::vars());
36    
37    let op_extractor = OpExtractor::new(&perl);
38
39    let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
40    println!("$0 = {:?}", main_file);
41    
42    let filter = |cv| CvFILE(cv).map_or(false, |s| s == main_file);
43
44    let mut emitter = |name: &String, cv: *const libperl_sys::cv| {
45        println!("sub {:?}", name);
46        let ast = op_extractor.extract(cv, CvROOT(cv));
47        
48        match ast {
49            Op::UNOP(opcode::OP_LEAVESUB, _
50                     , Op::LISTOP(opcode::OP_LINESEQ, _
51                                  , Op::COP(opcode::OP_NEXTSTATE, body), _), _) => {
52                println!("preamble!");
53                match body {
54                    Op::BINOP(opcode::OP_AASSIGN, _
55                              , Op::UNOP(opcode::OP_NULL, _
56                                         , Op::OP(opcode::OP_PADRANGE, _, _
57                                                  , Op::UNOP(opcode::OP_RV2AV, _
58                                                             , Op::PADOP(opcode::OP_GV, _
59                                                                         , Sv::GLOB { name: ref nm, .. })
60                                                             , _))
61                                         , lvalue)
62                              , _) if nm == "_" => {
63                        println!("first array assignment from @_, lvalue = {:?}"
64                                 , match_param_list(lvalue));
65                        
66                    }
67                    _ => {
68                        println!("first statement is not an array assignment");
69                    }
70                }
71            }
72            _ => {
73                println!("doesn't match")
74            }
75        }
76
77        println!("");
78    };
79
80    let mut nswalker = StashWalker::new(&perl, Some(&filter), &mut emitter);
81
82    nswalker.walk("");
83}
Source

pub fn str2svpv_flags(&self, buffer: &str, flags: u32) -> *mut SV

Source

pub fn str2svpv_mortal(&self, buffer: &str) -> *mut SV

Examples found in repository?
examples/110_call_method.rs (line 67)
45fn call_list_method(perl: &mut Perl, class_name: String, method_name: String, args: Vec<String>) -> Result<Vec<Sv>,String>
46{
47
48    let my_perl = perl.my_perl();
49
50    // dSP
51    let mut sp = my_perl.Istack_sp;
52
53    // ENTER
54    unsafe_perl_api!{Perl_push_scope(perl.my_perl)};
55
56    // SAVETMPS
57    unsafe_perl_api!{Perl_savetmps(perl.my_perl)};
58
59    // PUSHMARK(SP)
60    perl.pushmark(sp);
61    
62    // (... argument pushing ...)
63    // EXTEND(SP, 1+method_args.len())
64    sp = unsafe_perl_api!{Perl_stack_grow(perl.my_perl, sp, sp, (1 + args.len()).try_into().unwrap())};
65    
66    for s in [&[class_name], args.as_slice()].concat() {
67        sp_push!(sp, perl.str2svpv_mortal(s.as_str()));
68    }
69
70    // PUTBACK
71    my_perl.Istack_sp = sp;
72
73    // call_method
74    let cnt = unsafe_perl_api!{Perl_call_method(perl.my_perl, method_name.as_ptr() as *const i8, (G_METHOD_NAMED | G_LIST) as i32)};
75    
76    // SPAGAIN
77    // sp = my_perl.Istack_sp;
78    // (PUTBACK)
79
80    let res = stack_extract(&perl, cnt);
81
82    // FREETMPS
83    perl.free_tmps();
84    // LEAVE
85    unsafe_perl_api!{Perl_pop_scope(perl.my_perl)};
86    
87    Ok(res)
88}
Source

pub fn pushmark(&self, sp: *mut *mut SV)

Examples found in repository?
examples/110_call_method.rs (line 60)
45fn call_list_method(perl: &mut Perl, class_name: String, method_name: String, args: Vec<String>) -> Result<Vec<Sv>,String>
46{
47
48    let my_perl = perl.my_perl();
49
50    // dSP
51    let mut sp = my_perl.Istack_sp;
52
53    // ENTER
54    unsafe_perl_api!{Perl_push_scope(perl.my_perl)};
55
56    // SAVETMPS
57    unsafe_perl_api!{Perl_savetmps(perl.my_perl)};
58
59    // PUSHMARK(SP)
60    perl.pushmark(sp);
61    
62    // (... argument pushing ...)
63    // EXTEND(SP, 1+method_args.len())
64    sp = unsafe_perl_api!{Perl_stack_grow(perl.my_perl, sp, sp, (1 + args.len()).try_into().unwrap())};
65    
66    for s in [&[class_name], args.as_slice()].concat() {
67        sp_push!(sp, perl.str2svpv_mortal(s.as_str()));
68    }
69
70    // PUTBACK
71    my_perl.Istack_sp = sp;
72
73    // call_method
74    let cnt = unsafe_perl_api!{Perl_call_method(perl.my_perl, method_name.as_ptr() as *const i8, (G_METHOD_NAMED | G_LIST) as i32)};
75    
76    // SPAGAIN
77    // sp = my_perl.Istack_sp;
78    // (PUTBACK)
79
80    let res = stack_extract(&perl, cnt);
81
82    // FREETMPS
83    perl.free_tmps();
84    // LEAVE
85    unsafe_perl_api!{Perl_pop_scope(perl.my_perl)};
86    
87    Ok(res)
88}
Source

pub fn free_tmps(&self)

Examples found in repository?
examples/110_call_method.rs (line 83)
45fn call_list_method(perl: &mut Perl, class_name: String, method_name: String, args: Vec<String>) -> Result<Vec<Sv>,String>
46{
47
48    let my_perl = perl.my_perl();
49
50    // dSP
51    let mut sp = my_perl.Istack_sp;
52
53    // ENTER
54    unsafe_perl_api!{Perl_push_scope(perl.my_perl)};
55
56    // SAVETMPS
57    unsafe_perl_api!{Perl_savetmps(perl.my_perl)};
58
59    // PUSHMARK(SP)
60    perl.pushmark(sp);
61    
62    // (... argument pushing ...)
63    // EXTEND(SP, 1+method_args.len())
64    sp = unsafe_perl_api!{Perl_stack_grow(perl.my_perl, sp, sp, (1 + args.len()).try_into().unwrap())};
65    
66    for s in [&[class_name], args.as_slice()].concat() {
67        sp_push!(sp, perl.str2svpv_mortal(s.as_str()));
68    }
69
70    // PUTBACK
71    my_perl.Istack_sp = sp;
72
73    // call_method
74    let cnt = unsafe_perl_api!{Perl_call_method(perl.my_perl, method_name.as_ptr() as *const i8, (G_METHOD_NAMED | G_LIST) as i32)};
75    
76    // SPAGAIN
77    // sp = my_perl.Istack_sp;
78    // (PUTBACK)
79
80    let res = stack_extract(&perl, cnt);
81
82    // FREETMPS
83    perl.free_tmps();
84    // LEAVE
85    unsafe_perl_api!{Perl_pop_scope(perl.my_perl)};
86    
87    Ok(res)
88}

Trait Implementations§

Source§

impl Drop for Perl

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl Freeze for Perl

§

impl RefUnwindSafe for Perl

§

impl !Send for Perl

§

impl !Sync for Perl

§

impl Unpin for Perl

§

impl UnwindSafe for Perl

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.