static inline zend_long *pthreads_get_guard(zend_object *zobj, zval *member) /* {{{ */ { HashTable *guards; zend_long stub, *guard; zval tmp; ZEND_ASSERT(GC_FLAGS(zobj) & IS_OBJ_USE_GUARDS); if (GC_FLAGS(zobj) & IS_OBJ_HAS_GUARDS) { guards = Z_PTR(zobj->properties_table[zobj->ce->default_properties_count]); ZEND_ASSERT(guards != NULL); if (Z_TYPE_P(member) == IS_LONG) { if ((guard = (zend_long *)zend_hash_index_find_ptr(guards, Z_LVAL_P(member))) != NULL) { return guard; } } else { if ((guard = (zend_long *)zend_hash_find_ptr(guards, Z_STR_P(member))) != NULL) { return guard; } } } else { ALLOC_HASHTABLE(guards); zend_hash_init(guards, 8, NULL, pthreads_guard_dtor, 0); ZVAL_PTR(&tmp, guards); Z_PTR(zobj->properties_table[zobj->ce->default_properties_count]) = guards; GC_FLAGS(zobj) |= IS_OBJ_HAS_GUARDS; } stub = 0; if (Z_TYPE_P(member) == IS_LONG) { return (zend_long *)zend_hash_index_add_mem(guards, Z_LVAL_P(member), &stub, sizeof(zend_ulong)); } else return (zend_long *)zend_hash_add_mem(guards, Z_STR_P(member), &stub, sizeof(zend_ulong)); }
ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref) { uint32_t idx; gc_root_buffer *newRoot; if (UNEXPECTED(GC_G(gc_protected))) { return; } GC_BENCH_INC(zval_possible_root); if (EXPECTED(GC_HAS_UNUSED())) { idx = GC_FETCH_UNUSED(); } else if (EXPECTED(GC_HAS_NEXT_UNUSED_UNDER_THRESHOLD())) { idx = GC_FETCH_NEXT_UNUSED(); } else { gc_possible_root_when_full(ref); return; } ZEND_ASSERT(GC_TYPE(ref) == IS_ARRAY || GC_TYPE(ref) == IS_OBJECT); ZEND_ASSERT(GC_INFO(ref) == 0); newRoot = GC_IDX2PTR(idx); newRoot->ref = ref; /* GC_ROOT tag is 0 */ GC_TRACE_SET_COLOR(ref, GC_PURPLE); idx = gc_compress(idx); GC_REF_SET_INFO(ref, idx | GC_PURPLE); GC_G(num_roots)++; GC_BENCH_INC(zval_buffered); GC_BENCH_INC(root_buf_length); GC_BENCH_PEAK(root_buf_peak, root_buf_length); }
static void ZEND_FASTCALL zend_string_destroy(zend_string *str) { CHECK_ZVAL_STRING(str); ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); ZEND_ASSERT(GC_REFCOUNT(str) == 0); ZEND_ASSERT(!(GC_FLAGS(str) & IS_STR_PERSISTENT)); efree(str); }
static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce) { uint idx; Bucket *p, *q; zend_ulong nIndex; zend_op_array *new_entry; ht->nTableSize = source->nTableSize; ht->nTableMask = source->nTableMask; ht->nNumUsed = 0; ht->nNumOfElements = source->nNumOfElements; ht->nNextFreeElement = source->nNextFreeElement; ht->pDestructor = ZEND_FUNCTION_DTOR; ht->u.flags = (source->u.flags & HASH_FLAG_INITIALIZED); ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { ht->arHash = (uint32_t*)&uninitialized_bucket; return; } ZEND_ASSERT(!(source->u.flags & HASH_FLAG_PACKED)); ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t))); ht->arHash = (uint32_t *)(ht->arData + ht->nTableSize); memset(ht->arHash, INVALID_IDX, sizeof(uint32_t) * ht->nTableSize); for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; nIndex = p->h & ht->nTableMask; /* Insert into hash collision list */ q = ht->arData + ht->nNumUsed; Z_NEXT(q->val) = ht->arHash[nIndex]; ht->arHash[nIndex] = ht->nNumUsed++; /* Initialize key */ q->h = p->h; ZEND_ASSERT(p->key != NULL); q->key = zend_clone_str(p->key); /* Copy data */ ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val))); new_entry = (zend_op_array*)Z_PTR(q->val); if ((void*)new_entry->scope >= ZCG(current_persistent_script)->arena_mem && (void*)new_entry->scope < (void*)((char*)ZCG(current_persistent_script)->arena_mem + ZCG(current_persistent_script)->arena_size)) { new_entry->scope = ARENA_REALLOC(new_entry->scope); /* update prototype */ if (new_entry->prototype) { new_entry->prototype = ARENA_REALLOC(new_entry->prototype); } } } }
static zend_always_inline uint32_t gc_fetch_unused(void) { uint32_t idx; gc_root_buffer *root; ZEND_ASSERT(GC_HAS_UNUSED()); idx = GC_G(unused); root = GC_IDX2PTR(idx); ZEND_ASSERT(GC_IS_UNUSED(root->ref)); GC_G(unused) = GC_LIST2IDX(root->ref); return idx; }
void *zend_shared_alloc(size_t size) { int i; unsigned int block_size = ZEND_ALIGNED_SIZE(size); #if 1 if (!ZCG(locked)) { zend_accel_error(ACCEL_LOG_ERROR, "Shared memory lock not obtained"); } #endif if (block_size > ZSMMG(shared_free)) { /* No hope to find a big-enough block */ SHARED_ALLOC_FAILED(); return NULL; } for (i = 0; i < ZSMMG(shared_segments_count); i++) { if (ZSMMG(shared_segments)[i]->size - ZSMMG(shared_segments)[i]->pos >= block_size) { /* found a valid block */ void *retval = (void *) (((char *) ZSMMG(shared_segments)[i]->p) + ZSMMG(shared_segments)[i]->pos); ZSMMG(shared_segments)[i]->pos += block_size; ZSMMG(shared_free) -= block_size; memset(retval, 0, block_size); ZEND_ASSERT(((zend_uintptr_t)retval & 0x7) == 0); /* should be 8 byte aligned */ return retval; } } SHARED_ALLOC_FAILED(); return NULL; }
static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement) { uint32_t idx, nIndex; Bucket *p; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { HT_SET_DATA_ADDR(ht, &uninitialized_bucket); return; } if (ht->nNumUsed == 0) { efree(HT_GET_DATA_ADDR(ht)); ht->nTableMask = HT_MIN_MASK; HT_SET_DATA_ADDR(ht, &uninitialized_bucket); ht->u.flags &= ~HASH_FLAG_INITIALIZED; return; } if (ht->u.flags & HASH_FLAG_PACKED) { void *data = HT_GET_DATA_ADDR(ht); zend_accel_store(data, HT_USED_SIZE(ht)); HT_SET_DATA_ADDR(ht, data); } else if (ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 2) { /* compact table */ void *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; uint32_t hash_size; if (ht->nNumUsed <= HT_MIN_SIZE) { hash_size = HT_MIN_SIZE; } else { hash_size = (uint32_t)(-(int32_t)ht->nTableMask); while (hash_size >> 1 > ht->nNumUsed) { hash_size >>= 1; } } ht->nTableMask = (uint32_t)(-(int32_t)hash_size); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ HT_SET_DATA_ADDR(ht, ZCG(mem)); ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE((hash_size * sizeof(uint32_t)) + (ht->nNumUsed * sizeof(Bucket)))); HT_HASH_RESET(ht); memcpy(ht->arData, old_buckets, ht->nNumUsed * sizeof(Bucket)); efree(old_data); for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; /* persist bucket and key */ if (p->key) { zend_accel_store_interned_string(p->key); } /* persist the data itself */ pPersistElement(&p->val); nIndex = p->h | ht->nTableMask; Z_NEXT(p->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx); } return; } else {
static int phpdbg_create_recursive_ht_watch(phpdbg_watchpoint_t *watch) { zval *zv; zend_string *key; zend_long h; ZEND_ASSERT(watch->type == WATCH_ON_HASHTABLE); ZEND_HASH_FOREACH_KEY_VAL(HT_WATCH_HT(watch), h, key, zv) { phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); new_watch->flags = PHPDBG_WATCH_RECURSIVE; new_watch->parent = watch; new_watch->parent_container = HT_WATCH_HT(watch); if (key) { new_watch->name_in_parent = key; ++GC_REFCOUNT(key); } else { new_watch->name_in_parent = strpprintf(0, ZEND_LONG_FMT, h); } new_watch->str = strpprintf(0, "%.*s%s%s%s", (int) ZSTR_LEN(watch->str) - 2, ZSTR_VAL(watch->str), (watch->flags & PHPDBG_WATCH_ARRAY) ? "[" : "->", phpdbg_get_property_key(ZSTR_VAL(new_watch->name_in_parent)), (watch->flags & PHPDBG_WATCH_ARRAY) ? "]" : ""); while (Z_TYPE_P(zv) == IS_INDIRECT) { zv = Z_INDIRECT_P(zv); } phpdbg_create_zval_watchpoint(zv, new_watch); new_watch = phpdbg_create_watchpoint(new_watch); phpdbg_create_recursive_zval_watch(new_watch); } ZEND_HASH_FOREACH_END();
static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor) { zend_class_entry *ce1; uint idx; Bucket *p; zval *t; for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; ZEND_ASSERT(p->key); t = zend_hash_add(target, p->key, &p->val); if (UNEXPECTED(t == NULL)) { if (p->key->len > 0 && p->key->val[0] == 0) { /* Mangled key - ignore and wait for runtime */ continue; } else if (!ZCG(accel_directives).ignore_dups) { t = zend_hash_find(target, p->key); goto failure; } } if (pCopyConstructor) { pCopyConstructor(&Z_PTR_P(t)); } } target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX; return; failure: ce1 = Z_PTR(p->val); CG(in_compilation) = 1; zend_set_compiled_filename(ce1->info.user.filename); CG(zend_lineno) = ce1->info.user.line_start; zend_error(E_ERROR, "Cannot redeclare class %s", ce1->name->val); }
/* {{{ proto mixed Closure::call(object $to [, mixed $parameter] [, mixed $...] ) Call closure, binding to a given object with its class as the scope */ ZEND_METHOD(Closure, call) { zval *zclosure, *newthis, closure_result; zend_closure *closure; zend_fcall_info fci; zend_fcall_info_cache fci_cache; zval *my_params; int my_param_count = 0; zend_function my_function; zend_object *newobj; if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &my_params, &my_param_count) == FAILURE) { return; } zclosure = getThis(); closure = (zend_closure *)Z_OBJ_P(zclosure); if (closure->func.common.fn_flags & ZEND_ACC_STATIC) { zend_error(E_WARNING, "Cannot bind an instance to a static closure"); return; } if (closure->func.type == ZEND_INTERNAL_FUNCTION) { /* verify that we aren't binding internal function to a wrong object */ if ((closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0 && !instanceof_function(Z_OBJCE_P(newthis), closure->func.common.scope)) { zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", closure->func.common.scope->name->val, closure->func.common.function_name->val, Z_OBJCE_P(newthis)->name->val); return; } } newobj = Z_OBJ_P(newthis); if (newobj->ce != closure->func.common.scope && newobj->ce->type == ZEND_INTERNAL_CLASS) { /* rebinding to internal class is not allowed */ zend_error(E_WARNING, "Cannot bind closure to object of internal class %s", newobj->ce->name->val); return; } /* This should never happen as closures will always be callable */ if (zend_fcall_info_init(zclosure, 0, &fci, &fci_cache, NULL, NULL) != SUCCESS) { ZEND_ASSERT(0); } fci.retval = &closure_result; fci.params = my_params; fci.param_count = my_param_count; fci.object = fci_cache.object = newobj; fci_cache.initialized = 1; my_function = *fci_cache.function_handler; /* use scope of passed object */ my_function.common.scope = Z_OBJCE_P(newthis); fci_cache.function_handler = &my_function; if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) { ZVAL_COPY_VALUE(return_value, &closure_result); } }
static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC) { zend_ulong h; uint32_t nIndex; uint32_t idx; Bucket *p; IS_CONSISTENT(ht); if (UNEXPECTED(ht->nTableMask == 0)) { CHECK_INIT(ht, 0); goto add_to_hash; } else if (ht->u.flags & HASH_FLAG_PACKED) { zend_hash_packed_to_hash(ht); } else if ((flag & HASH_ADD_NEW) == 0) { p = zend_hash_find_bucket(ht, key); if (p) { zval *data; if (flag & HASH_ADD) { return NULL; } ZEND_ASSERT(&p->val != pData); data = &p->val; if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) { data = Z_INDIRECT_P(data); } HANDLE_BLOCK_INTERRUPTIONS(); if (ht->pDestructor) { ht->pDestructor(data); } ZVAL_COPY_VALUE(data, pData); HANDLE_UNBLOCK_INTERRUPTIONS(); return data; } } ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ add_to_hash: HANDLE_BLOCK_INTERRUPTIONS(); idx = ht->nNumUsed++; ht->nNumOfElements++; if (ht->nInternalPointer == INVALID_IDX) { ht->nInternalPointer = idx; } p = ht->arData + idx; p->h = h = zend_string_hash_val(key); p->key = key; zend_string_addref(key); ZVAL_COPY_VALUE(&p->val, pData); nIndex = h & ht->nTableMask; Z_NEXT(p->val) = ht->arHash[nIndex]; ht->arHash[nIndex] = idx; HANDLE_UNBLOCK_INTERRUPTIONS(); return &p->val; }
ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC) { uint nIndex; Bucket *p; #ifdef ZEND_SIGNALS TSRMLS_FETCH(); #endif IS_CONSISTENT(ht); CHECK_INIT(ht); if (flag & HASH_NEXT_INSERT) { h = ht->nNextFreeElement; } nIndex = h & ht->nTableMask; p = ht->arBuckets[nIndex]; while (p != NULL) { if ((p->nKeyLength == 0) && (p->h == h)) { if (flag & HASH_NEXT_INSERT || flag & HASH_ADD) { return FAILURE; } ZEND_ASSERT(p->pData != pData); HANDLE_BLOCK_INTERRUPTIONS(); if (ht->pDestructor) { ht->pDestructor(p->pData); } UPDATE_DATA(ht, p, pData, nDataSize); HANDLE_UNBLOCK_INTERRUPTIONS(); if (pDest) { *pDest = p->pData; } return SUCCESS; } p = p->pNext; } p = (Bucket *) pemalloc_rel(sizeof(Bucket), ht->persistent); p->arKey = NULL; p->nKeyLength = 0; /* Numeric indices are marked by making the nKeyLength == 0 */ p->h = h; INIT_DATA(ht, p, pData, nDataSize); if (pDest) { *pDest = p->pData; } CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]); HANDLE_BLOCK_INTERRUPTIONS(); ht->arBuckets[nIndex] = p; CONNECT_TO_GLOBAL_DLLIST(p, ht); HANDLE_UNBLOCK_INTERRUPTIONS(); if ((long)h >= (long)ht->nNextFreeElement) { ht->nNextFreeElement = h < LONG_MAX ? h + 1 : LONG_MAX; } ht->nNumOfElements++; ZEND_HASH_IF_FULL_DO_RESIZE(ht); return SUCCESS; }
ZEND_API zend_object_iterator* zend_iterator_unwrap(zval *array_ptr) { ZEND_ASSERT(Z_TYPE_P(array_ptr) == IS_OBJECT); if (Z_OBJ_HT_P(array_ptr) == &iterator_object_handlers) { return (zend_object_iterator *)Z_OBJ_P(array_ptr); } return NULL; }
static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */ { ZeroMemory(osvi, sizeof(OSVERSIONINFOEX)); osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(!GetVersionEx((OSVERSIONINFO *) osvi)) { ZEND_ASSERT(0); /* Should not happen as sizeof is used. */ } }
static zend_always_inline uint32_t gc_fetch_next_unused(void) { uint32_t idx; ZEND_ASSERT(GC_HAS_NEXT_UNUSED()); idx = GC_G(first_unused); GC_G(first_unused) = GC_G(first_unused) + 1; return idx; }
/* {{{ zend_implement_aggregate */ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type) { uint32_t i; int t = -1; zend_class_iterator_funcs *funcs_ptr; if (class_type->get_iterator) { if (class_type->type == ZEND_INTERNAL_CLASS) { /* inheritance ensures the class has necessary userland methods */ return SUCCESS; } else if (class_type->get_iterator != zend_user_it_get_new_iterator) { /* c-level get_iterator cannot be changed (exception being only Traversable is implemented) */ if (class_type->num_interfaces) { ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS)); for (i = 0; i < class_type->num_interfaces; i++) { if (class_type->interfaces[i] == zend_ce_iterator) { zend_error_noreturn(E_ERROR, "Class %s cannot implement both %s and %s at the same time", ZSTR_VAL(class_type->name), ZSTR_VAL(interface->name), ZSTR_VAL(zend_ce_iterator->name)); return FAILURE; } if (class_type->interfaces[i] == zend_ce_traversable) { t = i; } } } if (t == -1) { return FAILURE; } } } if (class_type->parent && (class_type->parent->ce_flags & ZEND_ACC_REUSE_GET_ITERATOR)) { class_type->get_iterator = class_type->parent->get_iterator; class_type->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR; } else { class_type->get_iterator = zend_user_it_get_new_iterator; } funcs_ptr = class_type->iterator_funcs_ptr; if (class_type->type == ZEND_INTERNAL_CLASS) { if (!funcs_ptr) { funcs_ptr = calloc(1, sizeof(zend_class_iterator_funcs)); class_type->iterator_funcs_ptr = funcs_ptr; } funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&class_type->function_table, "getiterator", sizeof("getiterator") - 1); } else { if (!funcs_ptr) { funcs_ptr = zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs)); class_type->iterator_funcs_ptr = funcs_ptr; memset(funcs_ptr, 0, sizeof(zend_class_iterator_funcs)); } else { funcs_ptr->zf_new_iterator = NULL; } } return SUCCESS; }
ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue) { if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) { ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue))); } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) { ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue))); CHECK_ZVAL_STRING(Z_STR_P(zvalue)); ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0)); } }
ZEND_API void zval_internal_ptr_dtor(zval *zval_ptr) /* {{{ */ { if (Z_REFCOUNTED_P(zval_ptr)) { zend_refcounted *ref = Z_COUNTED_P(zval_ptr); if (GC_DELREF(ref) == 0) { if (Z_TYPE_P(zval_ptr) == IS_STRING) { zend_string *str = (zend_string*)ref; CHECK_ZVAL_STRING(str); ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); ZEND_ASSERT((GC_FLAGS(str) & IS_STR_PERSISTENT)); free(str); } else { zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects, resources or reference"); } } } }
static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full(zend_refcounted *ref) { uint32_t idx; gc_root_buffer *newRoot; ZEND_ASSERT(GC_TYPE(ref) == IS_ARRAY || GC_TYPE(ref) == IS_OBJECT); ZEND_ASSERT(GC_INFO(ref) == 0); if (GC_G(gc_enabled) && !GC_G(gc_active)) { GC_ADDREF(ref); gc_adjust_threshold(gc_collect_cycles()); if (UNEXPECTED(GC_DELREF(ref)) == 0) { rc_dtor_func(ref); return; } else if (UNEXPECTED(GC_INFO(ref))) { return; } } if (GC_HAS_UNUSED()) { idx = GC_FETCH_UNUSED(); } else if (EXPECTED(GC_HAS_NEXT_UNUSED())) { idx = GC_FETCH_NEXT_UNUSED(); } else { gc_grow_root_buffer(); if (UNEXPECTED(!GC_HAS_NEXT_UNUSED())) { return; } idx = GC_FETCH_NEXT_UNUSED(); } newRoot = GC_IDX2PTR(idx); newRoot->ref = ref; /* GC_ROOT tag is 0 */ GC_TRACE_SET_COLOR(ref, GC_PURPLE); idx = gc_compress(idx); GC_REF_SET_INFO(ref, idx | GC_PURPLE); GC_G(num_roots)++; GC_BENCH_INC(zval_buffered); GC_BENCH_INC(root_buf_length); GC_BENCH_PEAK(root_buf_peak, root_buf_length); }
ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */ { ZEND_ASSERT(GC_REFCOUNT(object) == 0); /* GC might have released this object already. */ if (UNEXPECTED(GC_TYPE(object) == IS_NULL)) { return; } /* Make sure we hold a reference count during the destructor call otherwise, when the destructor ends the storage might be freed when the refcount reaches 0 a second time */ if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) { GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED); if (object->handlers->dtor_obj != zend_objects_destroy_object || object->ce->destructor) { GC_SET_REFCOUNT(object, 1); object->handlers->dtor_obj(object); GC_DELREF(object); } } if (GC_REFCOUNT(object) == 0) { uint32_t handle = object->handle; void *ptr; ZEND_ASSERT(EG(objects_store).object_buckets != NULL); ZEND_ASSERT(IS_OBJ_VALID(EG(objects_store).object_buckets[handle])); EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object); if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED); GC_SET_REFCOUNT(object, 1); object->handlers->free_obj(object); } ptr = ((char*)object) - object->handlers->offset; GC_REMOVE_FROM_BUFFER(object); efree(ptr); ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle); } }
/* {{{ spl_add_interfaces */ void spl_add_interfaces(zval *list, zend_class_entry * pce, int allow, int ce_flags) { uint32_t num_interfaces; if (pce->num_interfaces) { ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED); for (num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) { spl_add_class_name(list, pce->interfaces[num_interfaces], allow, ce_flags); } } }
ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */ { if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) { return 1; } else if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PRIVATE) { return (c->ce == scope); } else { ZEND_ASSERT(Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PROTECTED); return zend_check_protected(c->ce, scope); } }
/* {{{ spl_add_traits */ void spl_add_traits(zval *list, zend_class_entry * pce, int allow, int ce_flags) { uint32_t num_traits; zend_class_entry *trait; for (num_traits = 0; num_traits < pce->num_traits; num_traits++) { trait = zend_fetch_class_by_name(pce->trait_names[num_traits].name, pce->trait_names[num_traits].lc_name, ZEND_FETCH_CLASS_TRAIT); ZEND_ASSERT(trait); spl_add_class_name(list, trait, allow, ce_flags); } }
static zend_always_inline void mysqlnd_arena_release(zend_arena **arena_ptr, void *checkpoint) { zend_arena *arena = *arena_ptr; while (UNEXPECTED((char*)checkpoint > arena->end) || UNEXPECTED((char*)checkpoint <= (char*)arena)) { zend_arena *prev = arena->prev; mnd_efree(arena); *arena_ptr = arena = prev; } ZEND_ASSERT((char*)checkpoint > (char*)arena && (char*)checkpoint <= arena->end); arena->ptr = (char*)checkpoint; }
static void copy_zend_constant(zval *zv) { zend_constant *c = Z_PTR_P(zv); ZEND_ASSERT(c->flags & CONST_PERSISTENT); Z_PTR_P(zv) = pemalloc(sizeof(zend_constant), 1); memcpy(Z_PTR_P(zv), c, sizeof(zend_constant)); c = Z_PTR_P(zv); c->name = zend_string_copy(c->name); if (Z_TYPE(c->value) == IS_STRING) { Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1); } }
zend_string * ion_stream_describe(ion_stream * stream) { zend_string * describe = NULL; zend_string * address_remote = NULL; zend_string * address_local = NULL; if(stream->buffer == NULL) { return zend_string_init(STRARGS("Stream"), 0); } if (stream->state & ION_STREAM_RESERVED) { switch(bufferevent_getfd(stream->buffer)) { case STDIN_FILENO: return zend_string_init(STRARGS("Stream(stdin)"), 0); case STDOUT_FILENO: return zend_string_init(STRARGS("Stream(stdout)"), 0); case STDERR_FILENO: return zend_string_init(STRARGS("Stream(stderr)"), 0); default: ZEND_ASSERT(0); } } if(stream->state & ION_STREAM_STATE_SOCKET) { if(ion_stream_is_valid_fd(stream)) { return zend_string_init(STRARGS("Stream"), 0); } address_local = ion_stream_get_name_self(stream); address_remote = ion_stream_get_name_remote(stream); if(address_remote == NULL) { address_remote = zend_string_init(STRARGS("undefined"), 0); } if(address_local == NULL) { address_remote = zend_string_init(STRARGS("undefined"), 0); } if(stream->state & ION_STREAM_FROM_PEER) { describe = strpprintf(MAX_DOMAIN_LENGTH, "Stream(%s<-%s)", address_local->val, address_remote->val); } else if(stream->state & ION_STREAM_FROM_ME) { describe = strpprintf(MAX_DOMAIN_LENGTH, "Stream(%s->%s)", address_local->val, address_remote->val); } else { describe = strpprintf(MAX_DOMAIN_LENGTH, "Stream(%s<->%s)", address_local->val, address_remote->val); } zend_string_release(address_local); zend_string_release(address_remote); return describe; } else if(stream->state & ION_STREAM_STATE_PAIR) { return zend_string_init(STRARGS("Stream(twin)"), 0); } else { return zend_string_init(STRARGS("Stream(pipe)"), 0); } }
static zend_always_inline gc_root_buffer* gc_decompress(zend_refcounted *ref, uint32_t idx) { gc_root_buffer *root = GC_IDX2PTR(idx); if (EXPECTED(GC_GET_PTR(root->ref) == ref)) { return root; } while (1) { idx += GC_MAX_UNCOMPRESSED; ZEND_ASSERT(idx < GC_G(first_unused)); root = GC_IDX2PTR(idx); if (GC_GET_PTR(root->ref) == ref) { return root; } } }
/* {{{ mysqlnd_res_meta::read_metadata */ static enum_func_status MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn, MYSQLND_RES * result) { unsigned int i = 0; MYSQLND_PACKET_RES_FIELD field_packet; DBG_ENTER("mysqlnd_res_meta::read_metadata"); conn->payload_decoder_factory->m.init_result_field_packet(&field_packet); field_packet.memory_pool = result->memory_pool; for (;i < meta->field_count; i++) { zend_ulong idx; /* We re-read metadata for PS */ ZEND_ASSERT(meta->fields[i].root == NULL); meta->fields[i].root = NULL; field_packet.metadata = &(meta->fields[i]); if (FAIL == PACKET_READ(conn, &field_packet)) { PACKET_FREE(&field_packet); DBG_RETURN(FAIL); } if (field_packet.error_info.error_no) { COPY_CLIENT_ERROR(conn->error_info, field_packet.error_info); /* Return back from CONN_QUERY_SENT */ PACKET_FREE(&field_packet); DBG_RETURN(FAIL); } if (mysqlnd_ps_fetch_functions[meta->fields[i].type].func == NULL) { DBG_ERR_FMT("Unknown type %u sent by the server. Please send a report to the developers", meta->fields[i].type); php_error_docref(NULL, E_WARNING, "Unknown type %u sent by the server. Please send a report to the developers", meta->fields[i].type); PACKET_FREE(&field_packet); DBG_RETURN(FAIL); } /* For BC we have to check whether the key is numeric and use it like this */ if ((meta->fields[i].is_numeric = ZEND_HANDLE_NUMERIC(field_packet.metadata->sname, idx))) { meta->fields[i].num_key = idx; } } PACKET_FREE(&field_packet); DBG_RETURN(PASS); }
static zend_always_inline Bucket *zend_hash_index_find_bucket(const HashTable *ht, zend_uint_t h) { uint nIndex; uint idx; Bucket *p; nIndex = h & ht->nTableMask; idx = ht->arHash[nIndex]; while (idx != INVALID_IDX) { ZEND_ASSERT(idx < ht->nTableSize); p = ht->arData + idx; if (p->h == h && !p->key) { return p; } idx = Z_NEXT(p->val); } return NULL; }
static int check_host_whitelist(url_adapt_state_ex_t *ctx) { php_url *url_parts = NULL; HashTable *allowed_hosts = ctx->type ? &BG(url_adapt_session_hosts_ht) : &BG(url_adapt_output_hosts_ht); ZEND_ASSERT(ctx->tag_type == TAG_FORM); if (ctx->attr_val.s && ZSTR_LEN(ctx->attr_val.s)) { url_parts = php_url_parse_ex(ZSTR_VAL(ctx->attr_val.s), ZSTR_LEN(ctx->attr_val.s)); } else { return SUCCESS; /* empty URL is valid */ } if (!url_parts) { return FAILURE; } if (url_parts->scheme) { /* Only http/https should be handled. A bit hacky check this here, but saves a URL parse. */ if (strcasecmp(url_parts->scheme, "http") && strcasecmp(url_parts->scheme, "https")) { php_url_free(url_parts); return FAILURE; } } if (!url_parts->host) { php_url_free(url_parts); return SUCCESS; } if (!zend_hash_num_elements(allowed_hosts) && check_http_host(url_parts->host) == SUCCESS) { php_url_free(url_parts); return SUCCESS; } if (!zend_hash_str_find(allowed_hosts, url_parts->host, strlen(url_parts->host))) { php_url_free(url_parts); return FAILURE; } php_url_free(url_parts); return SUCCESS; }