#include "mouse.h"
-#define CHECK_INSTANCE(instance) STMT_START{ \
- if(!IsHashRef(instance)){ \
- croak("Invalid object instance"); \
- } \
+#define CHECK_INSTANCE(instance) STMT_START{ \
+ assert(instance); \
+ if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \
+ croak("Invalid object instance: '%"SVf"'", instance); \
+ } \
} STMT_END
SV* const trigger = mcall0s(MOUSE_mg_attribute(mg), "trigger");
dSP;
+ /* NOTE: triggers can remove value, so
+ value must be copied here,
+ revealed by Net::Google::DataAPI (DANJOU).
+ */
+ value = sv_mortalcopy(value);
+
PUSHMARK(SP);
EXTEND(SP, 2);
PUSHs(self);
PUSHs(value);
PUTBACK;
- call_sv(trigger, G_VOID | G_DISCARD);
+ call_sv_safe(trigger, G_VOID | G_DISCARD);
/* need not SPAGAIN */
+
+ assert(SvTYPE(value) != SVTYPEMASK);
}
PUSH_VALUE(value, flags);
SV*
mouse_instance_create(pTHX_ HV* const stash) {
+ SV* instance;
assert(stash);
assert(SvTYPE(stash) == SVt_PVHV);
- return sv_bless( newRV_noinc((SV*)newHV()), stash );
+ instance = sv_bless( newRV_noinc((SV*)newHV()), stash );
+ return sv_2mortal(instance);
}
SV*
mouse_instance_clone(pTHX_ SV* const instance) {
- HV* proto;
- assert(instance);
-
+ SV* proto;
CHECK_INSTANCE(instance);
- proto = newHVhv((HV*)SvRV(instance));
- return sv_bless( newRV_noinc((SV*)proto), SvSTASH(SvRV(instance)) );
+ assert(SvOBJECT(SvRV(instance)));
+
+ proto = newRV_noinc((SV*)newHVhv((HV*)SvRV(instance)));
+ sv_bless(proto, SvSTASH(SvRV(instance)));
+ return sv_2mortal(proto);
}
bool
mouse_instance_has_slot(pTHX_ SV* const instance, SV* const slot) {
- assert(instance);
assert(slot);
CHECK_INSTANCE(instance);
return hv_exists_ent((HV*)SvRV(instance), slot, 0U);
SV*
mouse_instance_get_slot(pTHX_ SV* const instance, SV* const slot) {
HE* he;
- assert(instance);
assert(slot);
CHECK_INSTANCE(instance);
he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
mouse_instance_set_slot(pTHX_ SV* const instance, SV* const slot, SV* const value) {
HE* he;
SV* sv;
- assert(instance);
assert(slot);
assert(value);
CHECK_INSTANCE(instance);
void
mouse_instance_weaken_slot(pTHX_ SV* const instance, SV* const slot) {
HE* he;
- assert(instance);
assert(slot);
CHECK_INSTANCE(instance);
he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);