void mysqlnd_alloc_zval_ptr_dtor(zval **zv, MYSQLND_ZVAL_CACHE * const cache) { if (!cache || Z_REFCOUNT_PP(zv) > 1 || cache->max_items == cache->free_items) { #ifndef MYSQLND_SILENT php_printf("[mysqlnd_alloc_zval_ptr_dtor %p]1 last_added-1=%p *zv=%p\n", cache->free_list->last_added, *zv); #endif /* We can't cache zval's with refcount > 1 */ zval_ptr_dtor(zv); if (cache) { if (cache->max_items == cache->free_items) { ++cache->put_full_misses; } else { ++cache->put_refcount_misses; } } } else { /* refcount is 1 and there is place. Go, cache it! */ ++cache->free_items; zval_dtor(*zv); ZVAL_NULL(*zv); *(--cache->free_list->last_added) = *zv; ++cache->put_hits; } #ifndef MYSQLND_SILENT php_printf("[mysqlnd_alloc_zval_ptr_dtor %p] free_items=%d\n", cache, cache->free_items); #endif }
/** * Updates values on arrays by long indexes only */ int phalcon_array_update_long(zval **arr, ulong index, zval **value, int flags TSRMLS_DC){ if (Z_TYPE_PP(arr) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array"); return FAILURE; } if ((flags & PH_CTOR) == PH_CTOR) { zval *new_zv; Z_DELREF_PP(value); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *value); *value = new_zv; zval_copy_ctor(new_zv); } if ((flags & PH_SEPARATE) == PH_SEPARATE) { if (Z_REFCOUNT_PP(arr) > 1) { zval *new_zv; Z_DELREF_PP(arr); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *arr); *arr = new_zv; zval_copy_ctor(new_zv); } } if ((flags & PH_COPY) == PH_COPY) { Z_ADDREF_PP(value); } return zend_hash_index_update(Z_ARRVAL_PP(arr), index, value, sizeof(zval *), NULL); }
/** * Updates values on arrays by string or long indexes */ int phalcon_array_update_zval(zval **arr, zval *index, zval **value, int flags TSRMLS_DC){ if (Z_TYPE_PP(arr) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array"); return FAILURE; } if (Z_TYPE_P(index) == IS_NULL) { convert_to_string(index); } else { if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) { convert_to_long(index); } } if ((flags & PH_CTOR) == PH_CTOR) { zval *new_zv; Z_DELREF_PP(value); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *value); *value = new_zv; zval_copy_ctor(new_zv); } if ((flags & PH_SEPARATE) == PH_SEPARATE) { if (Z_REFCOUNT_PP(arr) > 1) { zval *new_zv; Z_DELREF_PP(arr); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *arr); *arr = new_zv; zval_copy_ctor(new_zv); } } if ((flags & PH_COPY) == PH_COPY) { Z_ADDREF_PP(value); } if(Z_TYPE_P(index) == IS_STRING){ return zend_hash_update(Z_ARRVAL_PP(arr), Z_STRVAL_P(index), Z_STRLEN_P(index)+1, value, sizeof(zval *), NULL); } else { if (Z_TYPE_P(index) == IS_LONG) { return zend_hash_index_update(Z_ARRVAL_PP(arr), Z_LVAL_P(index), value, sizeof(zval *), NULL); } else { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Illegal offset type"); } } return FAILURE; }
/** * Unsets zval index from array */ int PHALCON_FASTCALL phalcon_array_unset(zval **arr, zval *index, int flags) { zval *copy; int exists, copied = 0; if (Z_TYPE_PP(arr) != IS_ARRAY) { return 0; } if (Z_TYPE_P(index) == IS_NULL) { ALLOC_INIT_ZVAL(copy); ZVAL_ZVAL(copy, index, 1, 0); convert_to_string(copy); index = copy; copied = 1; } else { if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) { ALLOC_INIT_ZVAL(copy); ZVAL_ZVAL(copy, index, 1, 0); convert_to_long(copy); index = copy; copied = 1; } } if ((flags & PH_SEPARATE) == PH_SEPARATE) { if (Z_REFCOUNT_PP(arr) > 1) { zval *new_zv; Z_DELREF_PP(arr); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *arr); *arr = new_zv; zval_copy_ctor(new_zv); } } if (Z_TYPE_P(index) == IS_STRING) { exists = zend_hash_del(Z_ARRVAL_PP(arr), Z_STRVAL_P(index), Z_STRLEN_P(index) + 1); } else { exists = zend_hash_index_del(Z_ARRVAL_PP(arr), Z_LVAL_P(index)); } if (copied) { zval_ptr_dtor(©); } return exists; }
/** * Push one or more elements onto the end of an array */ int phalcon_array_append(zval **arr, zval *value, int flags TSRMLS_DC){ if (Z_TYPE_PP(arr) == IS_ARRAY) { if((flags & PH_SEPARATE) == PH_SEPARATE){ if (Z_REFCOUNT_PP(arr) > 1) { zval *new_zv; Z_DELREF_PP(arr); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *arr); *arr = new_zv; zval_copy_ctor(new_zv); } } Z_ADDREF_P(value); return add_next_index_zval(*arr, value); } else { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array"); } return FAILURE; }
/** * Unsets long index from array */ int PHALCON_FASTCALL phalcon_array_unset_long(zval **arr, unsigned long index, int flags) { if (Z_TYPE_PP(arr) != IS_ARRAY) { return 0; } if ((flags & PH_SEPARATE) == PH_SEPARATE) { if (Z_REFCOUNT_PP(arr) > 1) { zval *new_zv; Z_DELREF_PP(arr); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *arr); *arr = new_zv; zval_copy_ctor(new_zv); } } return zend_hash_index_del(Z_ARRVAL_PP(arr), index); }
void ptask_thread_fn(void *arg) { struct ptask_ctx *ctx = (struct ptask_ctx *)arg; zval fname, retval; zval *params[1]; ZVAL_STRING(&fname, ctx->func, 0); /* create new function name zval */ params[0] = ctx->arg; TSRMLS_FETCH(); call_user_function(EG(function_table), NULL, &fname, &retval, 1, params TSRMLS_CC); /* free all memory */ Z_DELREF_PP(&(ctx->arg)); if (Z_REFCOUNT_PP(&(ctx->arg)) == 0) { zval_dtor(ctx->arg); } efree(ctx->func); efree(ctx); }
/** * Restore a memory stack applying GC to all observed variables */ static void zephir_memory_restore_stack_common(zend_zephir_globals_def *g) { size_t i; zephir_memory_entry *prev, *active_memory; zephir_symbol_table *active_symbol_table; zval *ptr; #ifndef ZEPHIR_RELEASE int show_backtrace = 0; #endif active_memory = g->active_memory; assert(active_memory != NULL); if (EXPECTED(!CG(unclean_shutdown))) { /* Clean active symbol table */ if (g->active_symbol_table) { active_symbol_table = g->active_symbol_table; if (active_symbol_table->scope == active_memory) { zend_execute_data *ex = EG(current_execute_data); //zend_hash_destroy(EG(current_execute_data)->symbol_table); //FREE_HASHTABLE(EG(current_execute_data)->symbol_table); //EG(current_execute_data)->symbol_table = active_symbol_table->symbol_table; ex->symbol_table = active_symbol_table->symbol_table; g->active_symbol_table = active_symbol_table->prev; efree(active_symbol_table); } } /* Check for non freed hash key zvals, mark as null to avoid string freeing */ for (i = 0; i < active_memory->hash_pointer; ++i) { assert(active_memory->hash_addresses[i] != NULL); if (!Z_REFCOUNTED_P(active_memory->hash_addresses[i])) continue; if (Z_REFCOUNT_P(active_memory->hash_addresses[i]) <= 1) { ZVAL_NULL(active_memory->hash_addresses[i]); } else { zval_copy_ctor(active_memory->hash_addresses[i]); } } #ifndef ZEPHIR_RELEASE for (i = 0; i < active_memory->pointer; ++i) { if (active_memory->addresses[i] != NULL) { zval *var = active_memory->addresses[i]; if (Z_TYPE_P(var) > IS_CALLABLE) { fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u [%s]\n", __func__, (int)i, var, Z_TYPE_P(var), active_memory->func); show_backtrace = 1; } if (!Z_REFCOUNTED_P(var)) { continue; } if (Z_REFCOUNT_P(var) == 0) { fprintf(stderr, "%s: observed variable #%d (%p) has 0 references, type=%d [%s]\n", __func__, (int)i, var, Z_TYPE_P(var), active_memory->func); show_backtrace = 1; } else if (Z_REFCOUNT_P(var) >= 1000000) { fprintf(stderr, "%s: observed variable #%d (%p) has too many references (%u), type=%d [%s]\n", __func__, (int)i, var, Z_REFCOUNT_P(var), Z_TYPE_P(var), active_memory->func); show_backtrace = 1; } #if 0 /* Skip this check, PDO does return variables with is_ref = 1 and refcount = 1*/ else if (Z_REFCOUNT_PP(var) == 1 && Z_ISREF_PP(var)) { fprintf(stderr, "%s: observed variable #%d (%p) is a reference with reference count = 1, type=%d [%s]\n", __func__, (int)i, *var, Z_TYPE_PP(var), active_memory->func); } #endif } } #endif /* Traverse all zvals allocated, reduce the reference counting or free them */ for (i = 0; i < active_memory->pointer; ++i) { ptr = active_memory->addresses[i]; if (EXPECTED(ptr != NULL)) { if (!Z_REFCOUNTED_P(ptr)) continue; if (Z_REFCOUNT_P(ptr) == 1) { zval_ptr_dtor(ptr); } else { Z_DELREF_P(ptr); } } } } #ifndef ZEPHIR_RELEASE active_memory->func = NULL; #endif prev = active_memory->prev; if (active_memory >= g->end_memory || active_memory < g->start_memory) { #ifndef ZEPHIR_RELEASE assert(g->active_memory->permanent == 0); #endif assert(prev != NULL); if (active_memory->hash_addresses != NULL) { efree(active_memory->hash_addresses); } if (active_memory->addresses != NULL) { efree(active_memory->addresses); } efree(g->active_memory); g->active_memory = prev; prev->next = NULL; } else { #ifndef ZEPHIR_RELEASE assert(g->active_memory->permanent == 1); #endif active_memory->pointer = 0; active_memory->hash_pointer = 0; g->active_memory = prev; } #ifndef ZEPHIR_RELEASE if (g->active_memory) { zephir_memory_entry *f = g->active_memory; if (f >= g->start_memory && f < g->end_memory - 1) { assert(f->permanent == 1); assert(f->next != NULL); if (f > g->start_memory) { assert(f->prev != NULL); } } } if (show_backtrace == 1) { zephir_print_backtrace(); } #endif }
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval) { var_dtor_entries *var_hash = (*var_hashx)->last_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); #endif if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_dtor_entries)); var_hash->used_slots = 0; var_hash->next = 0; if (!(*var_hashx)->first_dtor) { (*var_hashx)->first_dtor = var_hash; } else { ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; } (*var_hashx)->last_dtor = var_hash; } ZVAL_COPY_VALUE(&var_hash->data[var_hash->used_slots], rval); var_hash->used_slots++; }
ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_protocolbuffers_helper_zigzag_decode64, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() static void php_protocolbuffers_helper_debug_zval(zval **value TSRMLS_DC) { zval *val = *value; php_printf("{\n"); php_printf(" address: 0x%x,\n", (unsigned int)val); php_printf(" type: %d,\n", val->type); php_printf(" is_ref: %d,\n", PZVAL_IS_REF(val)); php_printf(" refcount: %d,\n", Z_REFCOUNT_PP(value)); php_printf(" value: {\n"); php_printf(" lval: %ld,\n", val->value.lval); php_printf(" double: %f,\n", val->value.dval); if (val->type == 4) { php_printf(" ht: {\n"); php_printf(" address: 0x%x,\n", (unsigned int)val->value.ht); php_printf(" num_of_elements: %d,\n", (unsigned int)val->value.ht->nNumOfElements); php_printf(" next_free_elements: %d,\n", (unsigned int)val->value.ht->nNextFreeElement); php_printf(" },\n"); } php_printf(" object: {\n"); php_printf(" handle: 0x%x,\n", val->value.obj.handle); php_printf(" handlers: 0x%x,\n", (unsigned int)val->value.obj.handlers); php_printf(" },\n"); php_printf(" }\n");
static HashTable *php_runkit_sandbox_parent_resolve_symbol_table(php_runkit_sandbox_parent_object *objval) { int i; HashTable *oldActiveSymbolTable, *result; zend_execute_data *oldCurExData; zend_execute_data *ex = EG(current_execute_data); if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(); } if (objval->self->parent_scope <= 0) { HashTable *ht = &EG(symbol_table); if (objval->self->parent_scope_name) { zval **symtable; if ((symtable = zend_hash_str_find(ht, objval->self->parent_scope_name, objval->self->parent_scope_namelen + 1)) != NULL) { if (Z_TYPE_PP(symtable) == IS_ARRAY) { ht = Z_ARRVAL_PP(symtable); } else { /* Variable exists but is not an array, * Make a dummy array that contains this var */ zval *hidden; ALLOC_INIT_ZVAL(hidden); array_init(hidden); ht = Z_ARRVAL_P(hidden); if (Z_REFCOUNT_PP(symtable) > 1 && !(*symtable)->RUNKIT_IS_REF) { zval *cv; MAKE_STD_ZVAL(cv); *cv = **symtable; zval_copy_ctor(cv); zval_ptr_dtor(symtable); INIT_PZVAL(cv); *symtable = cv; } (*symtable)->RUNKIT_IS_REF = 1; (*symtable)->RUNKIT_REFCOUNT++; // TODO fix zend_hash_update(ht, objval->self->parent_scope_name, objval->self->parent_scope_namelen + 1, (void*)symtable, sizeof(zval*), NULL); /* Store that dummy array in the sandbox's hidden properties table so that it gets cleaned up on dtor */ zend_hash_update(objval->obj.properties, "scope", sizeof("scope"), (void*)&hidden, sizeof(zval*), NULL); } } else { /* Create variable as an array */ zval *newval; ALLOC_INIT_ZVAL(newval); array_init(newval); zend_hash_update(&EG(symbol_table), objval->self->parent_scope_name, objval->self->parent_scope_namelen + 1, (void*)&newval, sizeof(zval*), NULL); ht = Z_ARRVAL_P(newval); } } return ht; } if (objval->self->parent_scope == 1) { return EG(active_symbol_table); } for(i = 1; i < objval->self->parent_scope; i++) { if (!ex->prev_execute_data) { /* Symbol table exceeded */ return &EG(symbol_table); } ex = ex->prev_execute_data; } oldActiveSymbolTable = EG(active_symbol_table); EG(active_symbol_table) = NULL; oldCurExData = EG(current_execute_data); EG(current_execute_data) = ex; zend_rebuild_symbol_table(); result = EG(active_symbol_table); EG(active_symbol_table) = oldActiveSymbolTable; EG(current_execute_data) = oldCurExData; return result; }