File: mouse.h

package info (click to toggle)
libmouse-perl 2.5.11-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,160 kB
  • sloc: perl: 14,614; ansic: 218; makefile: 8
file content (287 lines) | stat: -rw-r--r-- 11,379 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#ifndef MOUSE_H
#define MOUSE_H

/* used by 'ppport.h' Devel-PPPort */
#define NEED_croak_xs_usage
#define NEED_gv_fetchpvn_flags
#define NEED_mg_findext
#define NEED_newSVpvn_flags
#define NEED_newSVpvn_share
#define NEED_SvRX
#define NEED_warner
#define NEED_grok_number
#define NEED_grok_numeric_radix

#define PERL_EUPXS_ALWAYS_EXPORT

#include "xshelper.h"

#ifndef mro_get_linear_isa
#define no_mro_get_linear_isa
#define mro_get_linear_isa(stash) mouse_mro_get_linear_isa(aTHX_ stash)
AV* mouse_mro_get_linear_isa(pTHX_ HV* const stash);
#define mro_method_changed_in(stash) ((void)++PL_sub_generation)
#endif /* !mro_get_linear_isa */

#ifndef mro_get_pkg_gen
#ifdef no_mro_get_linear_isa
#define mro_get_pkg_gen(stash) ((void)stash, PL_sub_generation)
#else
#define mro_get_pkg_gen(stash) (HvAUX(stash)->xhv_mro_meta ? HvAUX(stash)->xhv_mro_meta->pkg_gen : (U32)0)
#endif /* !no_mro_get_linear_isa */
#endif /* mro_get_package_gen */

#ifndef GvCV_set
#define GvCV_set(gv, cv) (GvCV(gv) = (cv))
#endif

#ifndef PERL_STATIC_INLINE
#ifdef NOINLINE
#define PERL_STATIC_INLINE STATIC
#elif defined(_MSC_VER)
#define PERL_STATIC_INLINE STATIC __inline
#else
#define PERL_STATIC_INLINE STATIC inline
#endif
#endif

extern SV* mouse_package;
extern SV* mouse_methods;
extern SV* mouse_name;
extern SV* mouse_coerce;

void
mouse_throw_error(SV* const metaobject, SV* const data /* not used */, const char* const fmt, ...)
    __attribute__format__(__printf__, 3, 4);

#if PERL_VERSION_LT(5,14,0)
/* workaround RT #69939 */
I32
mouse_call_sv_safe(pTHX_ SV*, I32);
#else
#define mouse_call_sv_safe Perl_call_sv
#endif

#define call_sv_safe(sv, flags)     mouse_call_sv_safe(aTHX_ sv, flags)
#define call_method_safe(m, flags)  mouse_call_sv_safe(aTHX_ newSVpvn_flags(m, strlen(m), SVs_TEMP), flags | G_METHOD)
#define call_method_safes(m, flags) mouse_call_sv_safe(aTHX_ newSVpvs_flags(m, SVs_TEMP),            flags | G_METHOD)


#define is_class_loaded(sv) mouse_is_class_loaded(aTHX_ sv)
bool mouse_is_class_loaded(pTHX_ SV*);

#define is_an_instance_of(klass, sv) mouse_is_an_instance_of(aTHX_ gv_stashpvs(klass, GV_ADD), (sv))

#define IsObject(sv)   (SvROK(sv) && SvOBJECT(SvRV(sv)))
#define IsArrayRef(sv) (SvROK(sv) && !SvOBJECT(SvRV(sv)) && SvTYPE(SvRV(sv)) == SVt_PVAV)
#define IsHashRef(sv)  (SvROK(sv) && !SvOBJECT(SvRV(sv)) && SvTYPE(SvRV(sv)) == SVt_PVHV)
#define IsCodeRef(sv)  (SvROK(sv) && !SvOBJECT(SvRV(sv)) && SvTYPE(SvRV(sv)) == SVt_PVCV)

#define mcall0(invocant, m)          mouse_call0(aTHX_ (invocant), (m))
#define mcall1(invocant, m, arg1)    mouse_call1(aTHX_ (invocant), (m), (arg1))
#define predicate_call(invocant, m)  mouse_predicate_call(aTHX_ (invocant), (m))

#define mcall0s(invocant, m)          mcall0((invocant), sv_2mortal(newSVpvs_share(m)))
#define mcall1s(invocant, m, arg1)    mcall1((invocant), sv_2mortal(newSVpvs_share(m)), (arg1))
#define predicate_calls(invocant, m)  predicate_call((invocant), sv_2mortal(newSVpvs_share(m)))


#define get_metaclass(name) mouse_get_metaclass(aTHX_ name)

SV* mouse_call0(pTHX_ SV *const self, SV *const method);
SV* mouse_call1(pTHX_ SV *const self, SV *const method, SV* const arg1);
int mouse_predicate_call(pTHX_ SV* const self, SV* const method);

SV* mouse_get_metaclass(pTHX_ SV* metaclass_name);

GV* mouse_stash_fetch(pTHX_ HV* const stash, const char* const name, I32 const namelen, I32 const create);
#define stash_fetch(s, n, l, c) mouse_stash_fetch(aTHX_ (s), (n), (l), (c))
#define stash_fetchs(s, n, c)   mouse_stash_fetch(aTHX_ (s), STR_WITH_LEN(n), (c))

void mouse_install_sub(pTHX_ GV* const gv, SV* const code_ref);

void mouse_must_defined(pTHX_ SV* const value, const char* const name);
void mouse_must_ref(pTHX_ SV* const value, const char* const name, svtype const t);

#define must_defined(sv, name)   mouse_must_defined(aTHX_ sv, name)
#define must_ref(sv, name, svt)  mouse_must_ref(aTHX_ sv, name, svt)

#define MOUSEf_DIE_ON_FAIL 0x01
MAGIC* mouse_mg_find(pTHX_ SV* const sv, const MGVTBL* const vtbl, I32 const flags);

/* MOUSE_av_at(av, ix) is the safer version of AvARRAY(av)[ix] if perl is compiled with -DDEBUGGING */
#ifdef DEBUGGING
#define MOUSE_av_at(av, ix)  mouse_av_at_safe(aTHX_ (av) , (ix))
SV* mouse_av_at_safe(pTHX_ AV* const mi, I32 const ix);
#else
#define MOUSE_av_at(av, ix) \
    (AvARRAY(av)[ix] ? AvARRAY(av)[ix] : &PL_sv_undef)
#endif

#define MOUSE_mg_obj(mg)     ((mg)->mg_obj)
#define MOUSE_mg_ptr(mg)     ((mg)->mg_ptr)
#define MOUSE_mg_len(mg)     ((mg)->mg_len)
#define MOUSE_mg_flags(mg)   ((mg)->mg_private)
#define MOUSE_mg_virtual(mg) ((mg)->mg_virtual)

#define MOUSE_mg_slot(mg)   MOUSE_mg_obj(mg)
#define MOUSE_mg_xa(mg)    ((AV*)MOUSE_mg_ptr(mg))

PERL_STATIC_INLINE MAGIC *MOUSE_get_magic(pTHX_ CV *cv, MGVTBL *vtbl)
{
#ifndef MULTIPLICITY
    PERL_UNUSED_ARG(vtbl);
    return (MAGIC*)(CvXSUBANY(cv).any_ptr);
#else
    return mg_findext((SV*)cv, PERL_MAGIC_ext, vtbl);
#endif
}

/* mouse_instance.xs stuff */
SV*  mouse_instance_create     (pTHX_ HV* const stash);
SV*  mouse_instance_clone      (pTHX_ SV* const instance);
bool mouse_instance_has_slot   (pTHX_ SV* const instance, SV* const slot);
SV*  mouse_instance_get_slot   (pTHX_ SV* const instance, SV* const slot);
SV*  mouse_instance_set_slot   (pTHX_ SV* const instance, SV* const slot, SV* const value);
SV*  mouse_instance_delete_slot(pTHX_ SV* const instance, SV* const slot);
void mouse_instance_weaken_slot(pTHX_ SV* const instance, SV* const slot);

#define has_slot(self, key)         mouse_instance_has_slot(aTHX_ self, key)
#define get_slot(self, key)         mouse_instance_get_slot(aTHX_ self, key)
#define set_slot(self, key, value)  mouse_instance_set_slot(aTHX_ self, key, value)
#define delete_slot(self, key)      mouse_instance_delete_slot(aTHX_ self, key)
#define weaken_slot(self, key)      mouse_instance_weaken_slot(aTHX_ self, key)

#define has_slots(self, key)        has_slot(self, sv_2mortal(newSVpvs_share(key)))
#define get_slots(self, key)        get_slot(self, sv_2mortal(newSVpvs_share(key)))
#define set_slots(self, key, value) set_slot(self, sv_2mortal(newSVpvs_share(key)), value)

/* mouse_simple_accessor.xs for meta object protocols */
#define INSTALL_SIMPLE_READER(klass, name) \
    INSTALL_SIMPLE_READER_WITH_KEY(klass, name, name)
#define INSTALL_SIMPLE_READER_WITH_KEY(klass, name, key) \
    (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
    #name, #key, sizeof(#key)-1, XS_Mouse_simple_reader, NULL, 0)

#define INSTALL_CLASS_HOLDER_SV(klass, name, dsv) \
    (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
    #name, #name, sizeof(#name)-1, XS_Mouse_simple_reader, (dsv), HEf_SVKEY)
#define INSTALL_CLASS_HOLDER(klass, name, ds) \
    INSTALL_CLASS_HOLDER_SV(klass, name, newSVpvs(ds))

#define INSTALL_SIMPLE_WRITER(klass, name) \
    NSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, name)
#define INSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, key) \
    (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
    #name, #key, sizeof(#key)-1, XS_Mouse_simple_writer, NULL, 0)

#define INSTALL_SIMPLE_PREDICATE(klass, name) \
    INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, name)
#define INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, key) \
    (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
    #name, #key, sizeof(#key)-1, XS_Mouse_simple_predicate, NULL, 0)

/* generate inhertiable class accessors for Mouse::Meta::Class */
#define INSTALL_INHERITABLE_CLASS_ACCESSOR(name) \
    INSTALL_INHERITABLE_CLASS_ACCESSOR_WITH_KEY(name, name)
#define INSTALL_INHERITABLE_CLASS_ACCESSOR_WITH_KEY(name, key) \
    (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::Class::" #name,\
    #key, sizeof(#key)-1, XS_Mouse_inheritable_class_accessor, NULL, 0)

CV* mouse_simple_accessor_generate(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl, void* const dptr, I32 const dlen);

XS(XS_Mouse_simple_reader);
XS(XS_Mouse_simple_writer);
XS(XS_Mouse_simple_clearer);
XS(XS_Mouse_simple_predicate);

CV* mouse_accessor_generate(pTHX_ SV* const attr, XSUBADDR_t const accessor_impl);

XS(XS_Mouse_accessor);
XS(XS_Mouse_reader);
XS(XS_Mouse_writer);

XS(XS_Mouse_inheritable_class_accessor);

/* type constraints */

int mouse_tc_check(pTHX_ SV* const tc, SV* const sv);

int mouse_tc_Any       (pTHX_ SV*, SV* const sv);
int mouse_tc_Bool      (pTHX_ SV*, SV* const sv);
int mouse_tc_Undef     (pTHX_ SV*, SV* const sv);
int mouse_tc_Defined   (pTHX_ SV*, SV* const sv);
int mouse_tc_Value     (pTHX_ SV*, SV* const sv);
int mouse_tc_Num       (pTHX_ SV*, SV* const sv);
int mouse_tc_Int       (pTHX_ SV*, SV* const sv);
int mouse_tc_Str       (pTHX_ SV*, SV* const sv);
int mouse_tc_ClassName (pTHX_ SV*, SV* const sv);
int mouse_tc_RoleName  (pTHX_ SV*, SV* const sv);
int mouse_tc_Ref       (pTHX_ SV*, SV* const sv);
int mouse_tc_ScalarRef (pTHX_ SV*, SV* const sv);
int mouse_tc_ArrayRef  (pTHX_ SV*, SV* const sv);
int mouse_tc_HashRef   (pTHX_ SV*, SV* const sv);
int mouse_tc_CodeRef   (pTHX_ SV*, SV* const sv);
int mouse_tc_RegexpRef (pTHX_ SV*, SV* const sv);
int mouse_tc_GlobRef   (pTHX_ SV*, SV* const sv);
int mouse_tc_FileHandle(pTHX_ SV*, SV* const sv);
int mouse_tc_Object    (pTHX_ SV*, SV* const sv);

CV* mouse_generate_isa_predicate_for(pTHX_ SV* const klass, const char* const predicate_name);
CV* mouse_generate_can_predicate_for(pTHX_ SV* const klass, const char* const predicate_name);

int mouse_is_an_instance_of(pTHX_ HV* const stash, SV* const instance);

/* Mouse XS Attribute object */

AV* mouse_get_xa(pTHX_ SV* const attr);
SV* mouse_xa_apply_type_constraint(pTHX_ AV* const xa, SV* value, U16 const flags);
SV* mouse_xa_set_default(pTHX_ AV* const xa, SV* const object);

enum mouse_xa_ix_t{
    MOUSE_XA_SLOT,      /* for constructors, sync to mg_obj */
    MOUSE_XA_FLAGS,     /* for constructors, sync to mg_private */
    MOUSE_XA_ATTRIBUTE,
    MOUSE_XA_INIT_ARG,
    MOUSE_XA_TC,
    MOUSE_XA_TC_CODE,

    MOUSE_XA_last
};

#define MOUSE_xa_slot(m)      MOUSE_av_at(m, MOUSE_XA_SLOT)
#define MOUSE_xa_flags(m)     SvUVX( MOUSE_av_at(m, MOUSE_XA_FLAGS) )
#define MOUSE_xa_attribute(m) MOUSE_av_at(m, MOUSE_XA_ATTRIBUTE)
#define MOUSE_xa_init_arg(m)  MOUSE_av_at(m, MOUSE_XA_INIT_ARG)
#define MOUSE_xa_tc(m)        MOUSE_av_at(m, MOUSE_XA_TC)
#define MOUSE_xa_tc_code(m)   MOUSE_av_at(m, MOUSE_XA_TC_CODE)

enum mouse_xa_flags_t{
    MOUSEf_ATTR_HAS_TC          = 0x0001,
    MOUSEf_ATTR_HAS_DEFAULT     = 0x0002,
    MOUSEf_ATTR_HAS_BUILDER     = 0x0004,
    MOUSEf_ATTR_HAS_INITIALIZER = 0x0008, /* not used */
    MOUSEf_ATTR_HAS_TRIGGER     = 0x0010,

    MOUSEf_ATTR_IS_LAZY         = 0x0020,
    MOUSEf_ATTR_IS_WEAK_REF     = 0x0040,
    MOUSEf_ATTR_IS_REQUIRED     = 0x0080,

    MOUSEf_ATTR_SHOULD_COERCE   = 0x0100,

    MOUSEf_ATTR_SHOULD_AUTO_DEREF
                                = 0x0200,
    MOUSEf_TC_IS_ARRAYREF       = 0x0400,
    MOUSEf_TC_IS_HASHREF        = 0x0800,

    MOUSEf_OTHER1               = 0x1000,
    MOUSEf_OTHER2               = 0x2000,
    MOUSEf_OTHER3               = 0x4000,
    MOUSEf_OTHER4               = 0x8000,

    MOUSEf_MOUSE_MASK           = 0xFFFF /* not used */
};

/* Mouse::Meta::Class stuff */
HV* mouse_get_namespace(pTHX_ SV* const meta); /* $meta->namespace */
#endif /* !MOUSE_H */