Commit | Line | Data |
43165725 |
1 | #include "mouse.h"\r |
2 | \r |
3 | static MGVTBL mouse_simple_accessor_vtbl; |
4 | \r\r |
5 | /* |
6 | static MAGIC* |
7 | mouse_accessor_get_mg(pTHX_ CV* const xsub){ |
8 | return moose_mg_find(aTHX_ (SV*)xsub, &mouse_simple_accessor_vtbl, MOOSEf_DIE_ON_FAIL); |
9 | }\r |
10 | */\r |
11 | \r |
12 | CV* |
13 | mouse_install_simple_accessor(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl){ |
14 | CV* const xsub = newXS((char*)fq_name, accessor_impl, __FILE__); |
15 | SV* const slot = newSVpvn_share(key, keylen, 0U); |
16 | MAGIC* mg; |
17 | |
18 | if(!fq_name){ |
19 | /* anonymous xsubs need sv_2mortal */ |
20 | sv_2mortal((SV*)xsub); |
21 | } |
22 | |
23 | mg = sv_magicext((SV*)xsub, slot, PERL_MAGIC_ext, &mouse_simple_accessor_vtbl, NULL, 0); |
24 | SvREFCNT_dec(slot); /* sv_magicext() increases refcnt in mg_obj */ |
25 | |
26 | /* NOTE: |
27 | * although we use MAGIC for gc, we also store slot to CvXSUBANY slot for efficiency (gfx) |
28 | */ |
29 | CvXSUBANY(xsub).any_ptr = (void*)slot; |
30 | |
31 | return xsub; |
32 | } |
33 | \r |
34 | SV* |
35 | mouse_accessor_get_self(pTHX_ I32 const ax, I32 const items, CV* const cv) { |
36 | SV* self; |
37 | |
38 | if(items < 1){ |
39 | croak("Too few arguments for %s", GvNAME(CvGV(cv))); |
40 | } |
41 | |
42 | /* NOTE: If self has GETMAGIC, $self->accessor will invoke GETMAGIC |
43 | * before calling methods, so SvGETMAGIC(self) is not necessarily needed here. |
44 | */ |
45 | |
46 | self = ST(0); |
47 | if(!IsObject(self)){ |
48 | croak("Cant call %s as a class method", GvNAME(CvGV(cv))); |
49 | } |
50 | return self; |
51 | }\r |
52 | |
53 | |
54 | XS(mouse_xs_simple_reader) |
55 | { |
56 | dVAR; dXSARGS;\r |
57 | dMOUSE_self; |
58 | SV* const slot = (SV*)XSANY.any_ptr; |
59 | SV* value; |
60 | |
61 | if (items != 1) { |
62 | croak("Expected exactly one argument"); |
63 | } |
64 | |
65 | value = mouse_instance_get_slot(self, slot); |
66 | ST(0) = value ? value : &PL_sv_undef; |
67 | XSRETURN(1); |
68 | } |
69 | |
70 | |
71 | XS(mouse_xs_simple_writer) |
72 | { |
73 | dVAR; dXSARGS; |
74 | dMOUSE_self; |
75 | SV* const slot = (SV*)XSANY.any_ptr; |
76 | \r |
77 | if (items != 2) { |
78 | croak("Expected exactly two argument"); |
79 | } |
80 | |
81 | ST(0) = mouse_instance_set_slot(self, slot, ST(1)); |
82 | XSRETURN(1); |
83 | } |
84 | |
85 | |
86 | XS(mouse_xs_simple_predicate) |
87 | { |
88 | dVAR; dXSARGS; |
89 | dMOUSE_self; |
90 | SV* const slot = (SV*)XSANY.any_ptr; |
91 | \r |
92 | if (items != 1) { |
93 | croak("Expected exactly one argument"); |
94 | } |
95 | |
96 | ST(0) = boolSV( mouse_instance_has_slot(self, slot) ); |
97 | XSRETURN(1); |
98 | }\r |