Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

properly cleanup state, add mro stuff

  • Loading branch information...
commit a84f41d90cacc648ea0aed782cda4a749c6ee938 1 parent 7b7f50f
lestrrat authored
43 mop.h
View
@@ -3,7 +3,6 @@
#include "EXTERN.h"
#include "perl.h"
-#include "mro_compat.h"
/* forward decl */
struct _map_attribute;
@@ -15,19 +14,26 @@ typedef struct _mop_attribute mop_attribute;
typedef struct _mop_instance mop_instance;
typedef struct _mop_method mop_method;
-#include "mop_attribute.h"
-#include "mop_class.h"
-#include "mop_instance.h"
-#include "mop_method.h"
-
struct mop_state {
void *obj;
unsigned int trace;
+ SV *sv;
};
typedef struct mop_state mop_state;
+/* This is used only for structural equivalence */
+struct _mop_component {
+ mop_state *state;
+};
+typedef struct _mop_component mop_component;
+
#define MOP_DEFAULT_TRACE_LEVEL 0
+#include "mop_attribute.h"
+#include "mop_class.h"
+#include "mop_instance.h"
+#include "mop_method.h"
+
#define MOP_STATE_FROM_SV(sv) \
(mg_find(SvROK(sv) ? SvRV(sv) : sv, '~')->mg_obj)
@@ -44,13 +50,36 @@ mop_init()
}
static mop_state *
-mop_state_create(void *ptr) {
+mop_state_create(void *ptr, SV *sv) {
mop_state *st;
Newxz(st, 1, mop_state);
st->obj = ptr;
st->trace = MOP_DEFAULT_TRACE_LEVEL;
+ st->sv = sv;
+ ((mop_component *) ptr)->state = st;
return st;
}
+static int
+mop_component_state_has_refs(mop_component *c)
+{
+ if (c->state) {
+ if (!PL_dirty && SvOK(c->state->sv) && SvREFCNT(c->state->sv) > 1) {
+ /* still alive, keep */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+mop_component_state_destroy(mop_component *c)
+{
+ if (c->state != NULL) {
+ PerlIO_printf(PerlIO_stderr(), " DESTROY state %p\n", c->state);
+ Safefree(c->state);
+ }
+}
+
#endif /* MOP_H */
1  mop.pm
View
@@ -1,4 +1,5 @@
package mop;
+use MRO::Compat;
use XSLoader;
our $VERSION = '0.00001';
5 mop_attribute.c
View
@@ -32,6 +32,11 @@ mop_attribute_create( char *name, char *accessor, char *reader, char *writer, ch
void
mop_attribute_destroy( mop_attribute *attr )
{
+ if (mop_component_state_has_refs((mop_component *) attr))
+ return;
+
+ mop_component_state_destroy((mop_component *) attr );
+
if (attr->associated_metaclass) {
/* if it has an associated class, then it will have to live through */
return;
3  mop_attribute.h
View
@@ -2,9 +2,10 @@
#define __MOP_ATTRIBUTE_H__
#include "EXTERN.h"
#include "perl.h"
-#include "mop.h"
struct _mop_attribute {
+ mop_state *state;
+
char *name;
char *accessor;
char *reader;
35 mop_class.c
View
@@ -4,6 +4,15 @@
#include "perl.h"
#include "mop.h"
+#define NEED_PL_parser
+#define NEED_load_module
+#define NEED_sv_2pv_flags
+#define NEED_vload_module
+#include "ppport.h"
+
+#define NEED_mro_get_linear_isa_GLOBAL
+#include "mro_compat.h"
+
#define MOP_CLASS_ATTRIBUTES_DEFAULT_MAX 8
#define MOP_CLASS_METHODS_DEFAULT_MAX 4
@@ -23,6 +32,8 @@ mop_class_create(char *name, size_t name_len)
Newxz(klass, 1, mop_class);
+ klass->state = NULL;
+
klass->attributes_max = MOP_CLASS_ATTRIBUTES_DEFAULT_MAX;
klass->attributes_size = 0;
Newxz(klass->attributes, klass->attributes_max, mop_attribute *);
@@ -44,8 +55,13 @@ mop_class_destroy (mop_class *c)
{
int i;
+ if (mop_component_state_has_refs((mop_component *) c))
+ return;
+
PerlIO_printf(PerlIO_stderr(), "DESTROY mop_class %p\n", c);
+ mop_component_state_destroy((mop_component *) c);
+
for(i = 0; i < c->attributes_size; i++) {
mop_attribute_detach_from_class(c->attributes[i]);
mop_attribute_destroy(c->attributes[i]);
@@ -86,7 +102,7 @@ mop_class_associate_metaclass( mop_class *c, char *class )
sv = newRV_noinc((SV*)hv);
(void)sv_bless(sv, gv_stashpv("mop::class", FALSE));
- st = mop_state_create(c);
+ st = mop_state_create(c, sv);
sv_magic((SV *) hv, NULL, '~', NULL, 0);
MOP_STATE_FROM_SV(sv) = (void *) st;
@@ -288,11 +304,20 @@ SV *
mop_class_construct_instance(mop_class *c, HV *params)
{
mop_instance *meta_instance;
+ AV *linearized_isa;
SV *instance;
meta_instance = mop_class_get_meta_instance( c );
instance = mop_instance_create_instance( meta_instance );
-
+
+ linearized_isa = mop_class_linearized_isa( c );
+ {
+ int i;
+ for( i = 0; i < av_len(linearized_isa); i++) {
+ PerlIO_printf(PerlIO_stderr(), "i = %d, value = %s\n", i, SvPV_nolen(*(av_fetch(linearized_isa, i, 0))));
+ }
+ }
+
return instance;
}
@@ -306,4 +331,10 @@ mop_class_get_meta_instance( mop_class *c )
return c->meta_instance;
}
+AV *
+mop_class_linearized_isa( mop_class *c )
+{
+ return mro_get_linear_isa( gv_stashpv(c->name, 0) );
+}
+
#endif /* __MOP_CLASS_C__ */
5 mop_class.h
View
@@ -2,6 +2,8 @@
#define __MOP_CLASS_H__
struct _mop_class {
+ mop_state *state;
+
char *name;
mop_attribute **attributes;
@@ -42,4 +44,7 @@ mop_class_construct_instance(mop_class *c, HV *params);
mop_instance *
mop_class_get_meta_instance( mop_class *c );
+AV *
+mop_class_linearized_isa( mop_class *c );
+
#endif /* __MOP_CLASS_H__ */
5 mop_instance.c
View
@@ -30,6 +30,11 @@ mop_instance_detach_from_class( mop_instance *instance )
void
mop_instance_destroy( mop_instance *instance )
{
+ if (mop_component_state_has_refs((mop_component *) instance))
+ return;
+
+ mop_component_state_destroy((mop_component *) instance );
+
if (instance->associated_metaclass)
return;
5 mop_instance.h
View
@@ -1,8 +1,8 @@
#ifndef __MOP_INSTANCE_H__
#define __MOP_INSTANCE_H__
-#include "mop.h"
struct _mop_instance {
+ mop_state *state;
mop_class *associated_metaclass;
char **attributes;
@@ -31,4 +31,7 @@ mop_instance_inline_set_slot_value( SV *buffer, char *instance, char *slot, char
void
mop_instance_inline_get_slot_value( SV *buffer, char *instance, char *slot );
+SV *
+mop_instance_create_instance( mop_instance *instnace );
+
#endif /* __MOP_INSTANCE_H__ */
5 mop_method.c
View
@@ -23,6 +23,11 @@ mop_method_create(char *name, char *package_name, mop_class *c, SV *body)
void
mop_method_destroy(mop_method *method)
{
+ if (mop_component_state_has_refs((mop_component *) method))
+ return;
+
+ mop_component_state_destroy((mop_component *) method );
+
if (method->associated_metaclass != NULL)
return;
2  mop_method.h
View
@@ -2,6 +2,8 @@
#define __MOP_METHOD_H__
struct _mop_method {
+ mop_state *state;
+
char *name;
char *package_name;
mop_class *associated_metaclass;
6,984 ppport.h
View
6,984 additions, 0 deletions not shown
2  typemap
View
@@ -20,7 +20,7 @@ T_MOP_OBJECT
(void)sv_bless($arg, gv_stashpv(classname, TRUE));
/* allocate mop_state struct */
- st = mop_state_create($var);
+ st = mop_state_create($var, $arg);
/* now attach $var to the HV */
/* done as two steps to avoid sv_magic SvREFCNT_inc and MGf_REFCOUNTED */
Please sign in to comment.
Something went wrong with that request. Please try again.