Commit | Line | Data |
93540011 |
1 | #include "mouse.h" |
2 | |
43165725 |
3 | static MGVTBL mouse_simple_accessor_vtbl; |
93540011 |
4 | |
43165725 |
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); |
93540011 |
9 | } |
10 | */ |
11 | |
43165725 |
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: |
93540011 |
27 | * although we use MAGIC for gc, we also store mg to CvXSUBANY for efficiency (gfx) |
43165725 |
28 | */ |
93540011 |
29 | CvXSUBANY(xsub).any_ptr = (void*)mg; |
43165725 |
30 | |
31 | return xsub; |
32 | } |
93540011 |
33 | |
43165725 |
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; |
93540011 |
51 | } |
43165725 |
52 | |
53 | |
54 | XS(mouse_xs_simple_reader) |
55 | { |
93540011 |
56 | dVAR; dXSARGS; |
43165725 |
57 | dMOUSE_self; |
93540011 |
58 | SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr); |
43165725 |
59 | SV* value; |
60 | |
61 | if (items != 1) { |
93540011 |
62 | croak("Expected exactly one argument for a reader for '%"SVf"'", slot); |
43165725 |
63 | } |
64 | |
3ea28db6 |
65 | value = mouse_instance_get_slot(aTHX_ self, slot); |
43165725 |
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; |
93540011 |
75 | SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr); |
76 | |
43165725 |
77 | if (items != 2) { |
93540011 |
78 | croak("Expected exactly two argument for a writer for '%"SVf"'", slot); |
43165725 |
79 | } |
80 | |
3ea28db6 |
81 | ST(0) = mouse_instance_set_slot(aTHX_ self, slot, ST(1)); |
43165725 |
82 | XSRETURN(1); |
83 | } |
84 | |
93540011 |
85 | XS(mouse_xs_simple_clearer) |
86 | { |
87 | dVAR; dXSARGS; |
88 | dMOUSE_self; |
89 | SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr); |
90 | SV* value; |
91 | |
92 | if (items != 1) { |
93 | croak("Expected exactly one argument for a clearer for '%"SVf"'", slot); |
94 | } |
95 | |
96 | value = mouse_instance_delete_slot(aTHX_ self, slot); |
97 | ST(0) = value ? value : &PL_sv_undef; |
98 | XSRETURN(1); |
99 | } |
43165725 |
100 | |
101 | XS(mouse_xs_simple_predicate) |
102 | { |
103 | dVAR; dXSARGS; |
104 | dMOUSE_self; |
93540011 |
105 | SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr); |
106 | |
43165725 |
107 | if (items != 1) { |
93540011 |
108 | croak("Expected exactly one argument for a predicate for '%"SVf"'", slot); |
43165725 |
109 | } |
110 | |
3ea28db6 |
111 | ST(0) = boolSV( mouse_instance_has_slot(aTHX_ self, slot) ); |
43165725 |
112 | XSRETURN(1); |
93540011 |
113 | } |