… | |
… | |
115 | } |
115 | } |
116 | |
116 | |
117 | void |
117 | void |
118 | attachable::sever_self () |
118 | attachable::sever_self () |
119 | { |
119 | { |
120 | if (HV *self = this->self) |
120 | if (self) |
121 | { |
121 | { |
122 | // keep a refcount because sv_unmagic might call attachable_free, |
122 | // keep a refcount because sv_unmagic might call attachable_free, |
123 | // which might clear self, causing sv_unmagic to crash on a now |
123 | // which might clear self, causing sv_unmagic to crash on a now |
124 | // invalid object. |
124 | // invalid object. |
125 | SvREFCNT_inc (self); |
125 | SvREFCNT_inc (self); |
126 | hv_clear (self); |
126 | hv_clear (self); |
127 | sv_unmagic ((SV *)self, PERL_MAGIC_ext); |
127 | sv_unmagic ((SV *)self, PERL_MAGIC_ext); |
128 | SvREFCNT_dec (self); |
128 | SvREFCNT_dec (self); |
129 | |
129 | |
130 | // self *must* be null now because thats sv_unmagic's job. |
130 | // self *must* be null now because thats sv_unmagic's job. |
131 | assert (!this->self); |
131 | assert (!self); |
|
|
132 | flags |= 0x80; // severed //D |
132 | } |
133 | } |
133 | } |
134 | } |
134 | |
135 | |
135 | void |
136 | void |
136 | attachable::optimise () |
137 | attachable::optimise () |
137 | { |
138 | { |
138 | if (self |
139 | if (self |
139 | && SvREFCNT (self) == 1 |
140 | && SvREFCNT (self) == 1 |
140 | && !HvTOTALKEYS (self)) |
141 | && !HvTOTALKEYS (self)) |
|
|
142 | flags |= 0x40,//D |
141 | sever_self (); |
143 | sever_self (); |
142 | } |
144 | } |
143 | |
145 | |
144 | // check wether the object really is dead |
146 | // check wether the object really is dead |
145 | void |
147 | void |
… | |
… | |
163 | } |
165 | } |
164 | |
166 | |
165 | if (self) |
167 | if (self) |
166 | sever_self (); |
168 | sever_self (); |
167 | |
169 | |
|
|
170 | flags |= 0x20; //D |
168 | mortals.push_back (this); |
171 | mortals.push_back (this); |
169 | } |
172 | } |
170 | |
173 | |
171 | void |
174 | void |
172 | attachable::destroy () |
175 | attachable::destroy () |
… | |
… | |
267 | |
270 | |
268 | if (!obj->self) |
271 | if (!obj->self) |
269 | { |
272 | { |
270 | obj->self = newHV (); |
273 | obj->self = newHV (); |
271 | sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); |
274 | sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); |
|
|
275 | obj->flags &= ~0xc0;//D |
|
|
276 | obj->flags |= 0x10;//D |
272 | |
277 | |
273 | // now bless the object _once_ |
278 | // now bless the object _once_ |
274 | return sv_bless (newRV_inc ((SV *)obj->self), stash); |
279 | return sv_bless (newRV_inc ((SV *)obj->self), stash); |
275 | } |
280 | } |
276 | else |
281 | else |