Skip to content

Commit

Permalink
Fixing throwing exceptions without a memory frame, fixing possible me…
Browse files Browse the repository at this point in the history
…mory leaks in config
  • Loading branch information
phalcon committed Jun 29, 2013
1 parent 5116359 commit 7d58ea3
Show file tree
Hide file tree
Showing 21 changed files with 176 additions and 138 deletions.
4 changes: 2 additions & 2 deletions ext/acl/adapter/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ PHP_METHOD(Phalcon_Acl_Adapter_Memory, addRole){
} else {
PHALCON_CPY_WRT(role_name, role);

PHALCON_INIT_VAR(object);
PHALCON_INIT_NVAR(object);
object_init_ex(object, phalcon_acl_role_ce);
phalcon_call_method_p1_noret(object, "__construct", role);

Expand Down Expand Up @@ -358,7 +358,7 @@ PHP_METHOD(Phalcon_Acl_Adapter_Memory, addResource){
} else {
PHALCON_CPY_WRT(resource_name, resource);

PHALCON_INIT_VAR(object);
PHALCON_INIT_NVAR(object);
object_init_ex(object, phalcon_acl_resource_ce);
phalcon_call_method_p1_noret(object, "__construct", resource_name);

Expand Down
8 changes: 4 additions & 4 deletions ext/assets/collection.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ PHP_METHOD(Phalcon_Assets_Collection, addCss){
if (Z_TYPE_P(local) == IS_BOOL) {
PHALCON_CPY_WRT(collection_local, local);
} else {
PHALCON_OBS_VAR(collection_local);
PHALCON_OBS_NVAR(collection_local);
phalcon_read_property_this(&collection_local, this_ptr, SL("_local"), PH_NOISY_CC);
}
if (Z_TYPE_P(attributes) == IS_ARRAY) {
PHALCON_CPY_WRT(collection_attributes, attributes);
} else {
PHALCON_OBS_VAR(collection_attributes);
PHALCON_OBS_NVAR(collection_attributes);
phalcon_read_property_this(&collection_attributes, this_ptr, SL("_attributes"), PH_NOISY_CC);
}

Expand Down Expand Up @@ -177,13 +177,13 @@ PHP_METHOD(Phalcon_Assets_Collection, addJs){
if (Z_TYPE_P(local) == IS_BOOL) {
PHALCON_CPY_WRT(collection_local, local);
} else {
PHALCON_OBS_VAR(collection_local);
PHALCON_OBS_NVAR(collection_local);
phalcon_read_property_this(&collection_local, this_ptr, SL("_local"), PH_NOISY_CC);
}
if (Z_TYPE_P(attributes) == IS_ARRAY) {
PHALCON_CPY_WRT(collection_attributes, attributes);
} else {
PHALCON_OBS_VAR(collection_attributes);
PHALCON_OBS_NVAR(collection_attributes);
phalcon_read_property_this(&collection_attributes, this_ptr, SL("_attributes"), PH_NOISY_CC);
}

Expand Down
133 changes: 66 additions & 67 deletions ext/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,38 +287,6 @@ PHP_METHOD(Phalcon_Config, offsetUnset){
RETURN_TRUE;
}

static void array_merge_recursive_n(zval **a1, zval *a2 TSRMLS_DC)
{
HashTable *ah2;
HashPosition hp2;
zval **hd;
zval *key = NULL, *value = NULL;
zval *tmp1 = NULL, *tmp2 = NULL;

PHALCON_MM_GROW();

phalcon_is_iterable(a2, &ah2, &hp2, 0, 0);
while (zend_hash_get_current_data_ex(ah2, (void**) &hd, &hp2) == SUCCESS) {
PHALCON_GET_HKEY(key, ah2, hp2);
PHALCON_GET_HVALUE(value);

if (!phalcon_array_isset(*a1, key) || Z_TYPE_P(value) != IS_ARRAY) {
phalcon_array_update_zval(a1, key, &value, PH_COPY | PH_SEPARATE TSRMLS_CC);
}
else {
PHALCON_INIT_NVAR(tmp1);
PHALCON_INIT_NVAR(tmp2);
phalcon_array_fetch(&tmp1, *a1, key, PH_NOISY_CC);
phalcon_array_fetch(&tmp2, a2, key, PH_NOISY_CC);
array_merge_recursive_n(&tmp1, tmp2 TSRMLS_CC);
}

zend_hash_move_forward_ex(ah2, &hp2);
}

PHALCON_MM_RESTORE();
}

/**
* Merges a configuration into the current one
*
Expand All @@ -332,7 +300,7 @@ static void array_merge_recursive_n(zval **a1, zval *a2 TSRMLS_DC)
PHP_METHOD(Phalcon_Config, merge){

zval *config, *array_config, *value = NULL, *key = NULL, *active_value = NULL;
zval *other_array = NULL, *tmp = NULL;
zval *other_array = NULL;
HashTable *ah0;
HashPosition hp0;
zval **hd;
Expand All @@ -358,46 +326,77 @@ PHP_METHOD(Phalcon_Config, merge){

if (phalcon_isset_property_zval(this_ptr, key TSRMLS_CC)) {

/**
* The key is already defined in the object, we have to merge it
*/
PHALCON_OBS_NVAR(active_value);
phalcon_read_property_zval(&active_value, this_ptr, key, PH_NOISY_CC);

if (Z_TYPE_P(value) == IS_OBJECT && Z_TYPE_P(active_value) == IS_OBJECT) {
if (phalcon_method_exists_ex(active_value, SS("merge") TSRMLS_CC) == SUCCESS) { /* Path AAA in the test */
phalcon_call_method_p1_noret(active_value, "merge", value);
if (Z_TYPE_P(value) == IS_OBJECT) {

/**
* If the current value in the object is also an object, we assume it is a
* Phalcon\Config object calling merge over it
*/
if (Z_TYPE_P(active_value) == IS_OBJECT) {
if (phalcon_method_exists_ex(active_value, SS("merge") TSRMLS_CC) == SUCCESS) {
/**
* Path AAA in the test
*/
phalcon_call_method_p1_noret(active_value, "merge", value);
} else {
/**
* Path AAB in the test
*/
phalcon_update_property_zval_zval(this_ptr, key, value TSRMLS_CC);
}
zend_hash_move_forward_ex(ah0, &hp0);
continue;
}
else { /* Path AAB in the test */
phalcon_update_property_zval_zval(this_ptr, key, value TSRMLS_CC);

/**
* Merge the object with an array // Path AB in the test
*/
if (Z_TYPE_P(active_value) == IS_ARRAY) {
PHALCON_INIT_NVAR(other_array);
phalcon_call_func_p1(other_array, "get_object_vars", value);

PHALCON_INIT_NVAR(active_value);
phalcon_array_merge_recursive_n(&active_value, other_array TSRMLS_CC);
phalcon_update_property_zval_zval(this_ptr, key, active_value TSRMLS_CC);
zend_hash_move_forward_ex(ah0, &hp0);
continue;
}
} else {
/**
* Merge existing arrays with active member in this_ptr
*/
if (Z_TYPE_P(value) == IS_ARRAY) {

/**
* Merge the object with an array // Path AC in the test
*/
if (Z_TYPE_P(value) == IS_OBJECT) {
PHALCON_INIT_NVAR(other_array);
phalcon_call_func_p1(other_array, "get_object_vars", value);

PHALCON_INIT_NVAR(other_array);
phalcon_array_merge_recursive_n(&other_array, active_value TSRMLS_CC);
phalcon_update_property_zval_zval(this_ptr, key, other_array TSRMLS_CC);
zend_hash_move_forward_ex(ah0, &hp0);
continue;
}

/**
* Merge the array with an array // Path AD in the test
*/
if (Z_TYPE_P(value) == IS_OBJECT) {
PHALCON_INIT_NVAR(active_value);
phalcon_array_merge_recursive_n(&active_value, other_array TSRMLS_CC);
phalcon_update_property_zval_zval(this_ptr, key, active_value TSRMLS_CC);
zend_hash_move_forward_ex(ah0, &hp0);
continue;
}
}
}
else if (Z_TYPE_P(value) == IS_OBJECT && Z_TYPE_P(active_value) == IS_ARRAY) { /* Path AB in the test */
PHALCON_INIT_NVAR(other_array);
phalcon_call_func_p1(other_array, "get_object_vars", value);
array_merge_recursive_n(&active_value, other_array TSRMLS_CC);
phalcon_update_property_zval_zval(this_ptr, key, active_value TSRMLS_CC);
}
else if (Z_TYPE_P(value) == IS_ARRAY && Z_TYPE_P(active_value) == IS_OBJECT) { /* Path AC in the test */
PHALCON_INIT_NVAR(other_array);
phalcon_call_func_p1(other_array, "get_object_vars", active_value);
array_merge_recursive_n(&other_array, value TSRMLS_CC);
phalcon_update_property_zval_zval(this_ptr, key, other_array TSRMLS_CC);
}
else if (Z_TYPE_P(value) == IS_ARRAY && Z_TYPE_P(active_value) == IS_ARRAY) { /* Path AD in the test */
array_merge_recursive_n(&active_value, value TSRMLS_CC);
phalcon_update_property_zval_zval(this_ptr, key, active_value TSRMLS_CC);
}
else { /* Path AE in the test */
phalcon_update_property_zval_zval(this_ptr, key, value TSRMLS_CC);
}
}
else { /* Path B in the test */
/**
* The key is not defined in the object, add it
*/
phalcon_update_property_zval_zval(this_ptr, key, value TSRMLS_CC);
}
phalcon_update_property_zval_zval(this_ptr, key, value TSRMLS_CC);

zend_hash_move_forward_ex(ah0, &hp0);
}
Expand Down
4 changes: 2 additions & 2 deletions ext/db/dialect/oracle.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,10 +860,10 @@ PHP_METHOD(Phalcon_Db_Dialect_Oracle, select){
if (zend_is_true(column_alias)) {
if (PHALCON_GLOBAL(db).escape_identifiers) {
PHALCON_INIT_NVAR(column_alias_sql);
PHALCON_CONCAT_VSVVV(column_alias_sql, column_domain_sql, " ", escape_char, column_alias, escape_char);
PHALCON_CONCAT_VSVVV(column_alias_sql, column_domain_sql, " AS ", escape_char, column_alias, escape_char);
} else {
PHALCON_INIT_NVAR(column_alias_sql);
PHALCON_CONCAT_VSV(column_alias_sql, column_domain_sql, " ", column_alias);
PHALCON_CONCAT_VSV(column_alias_sql, column_domain_sql, " AS ", column_alias);
}
} else {
PHALCON_CPY_WRT(column_alias_sql, column_domain_sql);
Expand Down
2 changes: 1 addition & 1 deletion ext/http/response.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ PHP_METHOD(Phalcon_Http_Response, redirect){
PHALCON_INIT_VAR(url);
phalcon_call_method_p1(url, dependency_injector, "getshared", service);

PHALCON_INIT_VAR(header);
PHALCON_INIT_NVAR(header);
phalcon_call_method_p1(header, url, "get", location);
}

Expand Down
31 changes: 31 additions & 0 deletions ext/kernel/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ext/standard/php_array.h"

#include "kernel/main.h"
#include "kernel/memory.h"
#include "kernel/debug.h"
#include "kernel/array.h"
#include "kernel/operators.h"
Expand Down Expand Up @@ -1189,3 +1190,33 @@ void phalcon_fast_array_merge(zval *return_value, zval **array1, zval **array2 T
php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(array2), 0 TSRMLS_CC);

}

void phalcon_array_merge_recursive_n(zval **a1, zval *a2 TSRMLS_DC)
{
HashTable *ah2;
HashPosition hp2;
zval **hd;
zval *key = NULL, *value = NULL;
zval *tmp1 = NULL, *tmp2 = NULL;

phalcon_is_iterable(a2, &ah2, &hp2, 0, 0);

while (zend_hash_get_current_data_ex(ah2, (void**) &hd, &hp2) == SUCCESS) {

PHALCON_GET_HKEY(key, ah2, hp2);
PHALCON_GET_HVALUE(value);

if (!phalcon_array_isset(*a1, key) || Z_TYPE_P(value) != IS_ARRAY) {
phalcon_array_update_zval(a1, key, &value, PH_COPY | PH_SEPARATE TSRMLS_CC);
} else {
PHALCON_INIT_NVAR(tmp1);
PHALCON_INIT_NVAR(tmp2);
phalcon_array_fetch(&tmp1, *a1, key, PH_NOISY_CC);
phalcon_array_fetch(&tmp2, a2, key, PH_NOISY_CC);
phalcon_array_merge_recursive_n(&tmp1, tmp2 TSRMLS_CC);
}

zend_hash_move_forward_ex(ah2, &hp2);
}

}
3 changes: 3 additions & 0 deletions ext/kernel/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ extern int phalcon_fast_in_array(zval *needle, zval *haystack TSRMLS_DC);

/** Fast Array Merge */
extern void phalcon_fast_array_merge(zval *return_value, zval **array1, zval **array2 TSRMLS_DC);

/** Recursive merge */
extern void phalcon_array_merge_recursive_n(zval **a1, zval *a2 TSRMLS_DC);
12 changes: 9 additions & 3 deletions ext/kernel/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ void phalcon_throw_exception(zval *object TSRMLS_DC){
void phalcon_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len, int restore_stack TSRMLS_DC){

zval *object, *msg;
zend_phalcon_globals *phalcon_globals_ptr = PHALCON_VGLOBAL;

ALLOC_INIT_ZVAL(object);
object_init_ex(object, ce);

if (restore_stack) {
if (restore_stack == 1 || phalcon_globals_ptr->start_memory) {
PHALCON_INIT_VAR(msg);
} else {
ALLOC_INIT_ZVAL(msg);
Expand All @@ -62,8 +63,10 @@ void phalcon_throw_exception_string(zend_class_entry *ce, const char *message, z

zend_throw_exception_object(object TSRMLS_CC);

if (restore_stack) {
if (restore_stack == 1 || phalcon_globals_ptr->start_memory) {
phalcon_memory_restore_stack(TSRMLS_C);
} else {
zval_ptr_dtor(&msg);
}
}

Expand All @@ -73,6 +76,7 @@ void phalcon_throw_exception_string(zend_class_entry *ce, const char *message, z
void phalcon_throw_exception_zval(zend_class_entry *ce, zval *message TSRMLS_DC){

zval *object;
zend_phalcon_globals *phalcon_globals_ptr = PHALCON_VGLOBAL;

ALLOC_INIT_ZVAL(object);
object_init_ex(object, ce);
Expand All @@ -81,7 +85,9 @@ void phalcon_throw_exception_zval(zend_class_entry *ce, zval *message TSRMLS_DC)

zend_throw_exception_object(object TSRMLS_CC);

phalcon_memory_restore_stack(TSRMLS_C);
if (phalcon_globals_ptr->start_memory) {
phalcon_memory_restore_stack(TSRMLS_C);
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion ext/kernel/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

/** Exceptions */
#define PHALCON_THROW_EXCEPTION_STR(class_entry, message) phalcon_throw_exception_string(class_entry, message, sizeof(message)-1, 1 TSRMLS_CC);
#define PHALCON_THROW_EXCEPTION_STR(class_entry, message) phalcon_throw_exception_string(class_entry, message, sizeof(message)-1, -1 TSRMLS_CC);
#define PHALCON_THROW_EXCEPTION_ZVAL(class_entry, message) phalcon_throw_exception_zval(class_entry, message TSRMLS_CC);

/** Throw Exceptions */
Expand Down
4 changes: 2 additions & 2 deletions ext/mvc/collection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ PHP_METHOD(Phalcon_Mvc_Collection, _exists){
phalcon_call_method_p1(use_implicit_ids, models_manager, "isusingimplicitobjectids", this_ptr);
if (zend_is_true(use_implicit_ids)) {
ce0 = zend_fetch_class(SL("MongoId"), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
PHALCON_INIT_VAR(mongo_id);
PHALCON_INIT_NVAR(mongo_id);
object_init_ex(mongo_id, ce0);
if (phalcon_has_constructor(mongo_id TSRMLS_CC)) {
phalcon_call_method_p1_noret(mongo_id, "__construct", id);
Expand Down Expand Up @@ -1945,7 +1945,7 @@ PHP_METHOD(Phalcon_Mvc_Collection, delete){
phalcon_call_method_p1(use_implicit_ids, models_manager, "isusingimplicitobjectids", this_ptr);
if (zend_is_true(use_implicit_ids)) {
ce0 = zend_fetch_class(SL("MongoId"), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
PHALCON_INIT_VAR(mongo_id);
PHALCON_INIT_NVAR(mongo_id);
object_init_ex(mongo_id, ce0);
if (phalcon_has_constructor(mongo_id TSRMLS_CC)) {
phalcon_call_method_p1_noret(mongo_id, "__construct", id);
Expand Down
2 changes: 1 addition & 1 deletion ext/mvc/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -6186,7 +6186,7 @@ PHP_METHOD(Phalcon_Mvc_Model, __callStatic){
/**
* Get the possible real method name
*/
PHALCON_INIT_VAR(field);
PHALCON_INIT_NVAR(field);
phalcon_uncamelize(field, extra_method TSRMLS_CC);
if (!phalcon_array_isset(attributes, field)) {
PHALCON_INIT_NVAR(exception_message);
Expand Down
Loading

0 comments on commit 7d58ea3

Please sign in to comment.