summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2003-08-23 15:38:58 +0000
committerMarcus Boerger <helly@php.net>2003-08-23 15:38:58 +0000
commitfbda310a41299913e39385f15762924bde2f48cb (patch)
treec84d399d55e1f7bca9009bffab22de64931e8121
parent43334207abd34dcb444fce526d11481577b356ce (diff)
downloadphp-git-fbda310a41299913e39385f15762924bde2f48cb.tar.gz
- Flag ctor/dtor methods
- Use this to prevent memleaks when an exception gets thrown in ctors. # I added the dtor flags for consistency, atm a compareable check in # isn't necessary for destruction. But anyway i'll use this for the # Relection API too.
-rw-r--r--Zend/zend_API.c6
-rw-r--r--Zend/zend_compile.c7
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_execute.c10
4 files changed, 24 insertions, 2 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index ac459028d8..7d5745b4f7 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1241,6 +1241,12 @@ int zend_register_functions(zend_class_entry *scope, zend_function_entry *functi
scope->constructor = ctor;
scope->destructor = dtor;
scope->clone = clone;
+ if (ctor) {
+ ctor->common.fn_flags |= ZEND_ACC_CTOR;
+ }
+ if (dtor) {
+ dtor->common.fn_flags |= ZEND_ACC_DTOR;
+ }
}
return SUCCESS;
}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 9403cafa6b..b119b0a230 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2252,6 +2252,13 @@ void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRML
do_inherit_parent_constructor(ce);
+ if (ce->constructor) {
+ ce->constructor->common.fn_flags |= ZEND_ACC_CTOR;
+ }
+ if (ce->destructor) {
+ ce->destructor->common.fn_flags |= ZEND_ACC_DTOR;
+ }
+
ce->line_end = zend_get_compiled_lineno(TSRMLS_C);
/* Inherit interfaces */
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 9cb30999fa..21014202a5 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -110,6 +110,9 @@ typedef struct _zend_brk_cont_element {
#define ZEND_ACC_CHANGED 0x800
#define ZEND_ACC_IMPLICIT_PUBLIC 0x1000
+#define ZEND_ACC_CTOR 0x2000
+#define ZEND_ACC_DTOR 0x4000
+
char *zend_visibility_string(zend_uint fn_flags);
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index a9a7a9328f..aaf5b427e7 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2610,10 +2610,16 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS)
}
}
- if (should_change_scope) {
- if (EG(This)) {
+ if (EG(This)) {
+ if (EG(exception) && EX(fbc)->common.fn_flags&ZEND_ACC_CTOR) {
+ EG(This)->refcount = 1;
+ zval_ptr_dtor(&EG(This));
+ } else if (should_change_scope) {
zval_ptr_dtor(&EG(This));
}
+ }
+
+ if (should_change_scope) {
EG(This) = current_this;
EG(scope) = current_scope;
}