/* Protects class' refcount, copies default properties, functions and class name */ static void zend_class_copy_ctor(zend_class_entry **pce) { zend_class_entry *ce = *pce; zend_class_entry *old_ce = ce; *pce = ce = ARENA_REALLOC(old_ce); ce->refcount = 1; if (old_ce->default_properties_table) { int i; ce->default_properties_table = emalloc(sizeof(zval) * old_ce->default_properties_count); for (i = 0; i < old_ce->default_properties_count; i++) { ZVAL_COPY_VALUE(&ce->default_properties_table[i], &old_ce->default_properties_table[i]); zend_clone_zval(&ce->default_properties_table[i], 1); } } zend_hash_clone_methods(&ce->function_table, &old_ce->function_table, old_ce, ce); /* static members */ if (old_ce->default_static_members_table) { int i; ce->default_static_members_table = emalloc(sizeof(zval) * old_ce->default_static_members_count); for (i = 0; i < old_ce->default_static_members_count; i++) { ZVAL_COPY_VALUE(&ce->default_static_members_table[i], &old_ce->default_static_members_table[i]); zend_clone_zval(&ce->default_static_members_table[i], 1); } } ce->static_members_table = ce->default_static_members_table; /* properties_info */ zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce); /* constants table */ zend_hash_clone_zval(&ce->constants_table, &old_ce->constants_table, 1); ce->constants_table.u.flags &= ~HASH_FLAG_APPLY_PROTECTION; ce->name = zend_clone_str(ce->name); /* interfaces aren't really implemented, so we create a new table */ if (ce->num_interfaces) { ce->interfaces = emalloc(sizeof(zend_class_entry *) * ce->num_interfaces); memset(ce->interfaces, 0, sizeof(zend_class_entry *) * ce->num_interfaces); } else { ce->interfaces = NULL; } if (ZEND_CE_DOC_COMMENT(ce)) { if (ZCG(accel_directives).load_comments) { ZEND_CE_DOC_COMMENT(ce) = zend_string_dup(ZEND_CE_DOC_COMMENT(ce), 0); } else { ZEND_CE_DOC_COMMENT(ce) = NULL; } } if (ce->parent) { ce->parent = ARENA_REALLOC(ce->parent); } zend_update_inherited_handler(constructor); zend_update_inherited_handler(destructor); zend_update_inherited_handler(clone); zend_update_inherited_handler(__get); zend_update_inherited_handler(__set); zend_update_inherited_handler(__call); /* 5.1 stuff */ zend_update_inherited_handler(serialize_func); zend_update_inherited_handler(unserialize_func); zend_update_inherited_handler(__isset); zend_update_inherited_handler(__unset); /* 5.2 stuff */ zend_update_inherited_handler(__tostring); /* 5.3 stuff */ zend_update_inherited_handler(__callstatic); zend_update_inherited_handler(__debugInfo); /* 5.4 traits */ if (ce->trait_aliases) { zend_trait_alias **trait_aliases; int i = 0; while (ce->trait_aliases[i]) { i++; } trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1)); i = 0; while (ce->trait_aliases[i]) { trait_aliases[i] = emalloc(sizeof(zend_trait_alias)); memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias)); trait_aliases[i]->trait_method = emalloc(sizeof(zend_trait_method_reference)); memcpy(trait_aliases[i]->trait_method, ce->trait_aliases[i]->trait_method, sizeof(zend_trait_method_reference)); if (trait_aliases[i]->trait_method) { if (trait_aliases[i]->trait_method->method_name) { trait_aliases[i]->trait_method->method_name = zend_clone_str(trait_aliases[i]->trait_method->method_name); } if (trait_aliases[i]->trait_method->class_name) { trait_aliases[i]->trait_method->class_name = zend_clone_str(trait_aliases[i]->trait_method->class_name); } } if (trait_aliases[i]->alias) { trait_aliases[i]->alias = zend_clone_str(trait_aliases[i]->alias); } i++; } trait_aliases[i] = NULL; ce->trait_aliases = trait_aliases; } if (ce->trait_precedences) { zend_trait_precedence **trait_precedences; int i = 0; while (ce->trait_precedences[i]) { i++; } trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1)); i = 0; while (ce->trait_precedences[i]) { trait_precedences[i] = emalloc(sizeof(zend_trait_precedence)); memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence)); trait_precedences[i]->trait_method = emalloc(sizeof(zend_trait_method_reference)); memcpy(trait_precedences[i]->trait_method, ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference)); trait_precedences[i]->trait_method->method_name = zend_clone_str(trait_precedences[i]->trait_method->method_name); trait_precedences[i]->trait_method->class_name = zend_clone_str(trait_precedences[i]->trait_method->class_name); if (trait_precedences[i]->exclude_from_classes) { zend_string **exclude_from_classes; int j = 0; while (trait_precedences[i]->exclude_from_classes[j].class_name) { j++; } exclude_from_classes = emalloc(sizeof(zend_string*) * (j + 1)); j = 0; while (trait_precedences[i]->exclude_from_classes[j].class_name) { exclude_from_classes[j] = zend_clone_str(trait_precedences[i]->exclude_from_classes[j].class_name); j++; } exclude_from_classes[j] = NULL; trait_precedences[i]->exclude_from_classes = (void*)exclude_from_classes; } i++; } trait_precedences[i] = NULL; ce->trait_precedences = trait_precedences; } }
static void zend_persist_class_entry(zval *zv) { zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_USER_CLASS) { memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_class_entry)); zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem)); ce = Z_PTR_P(zv) = ZCG(arena_mem); ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_class_entry))); zend_accel_store_interned_string(ce->name); zend_hash_persist(&ce->function_table, zend_persist_op_array); if (ce->default_properties_table) { int i; zend_accel_store(ce->default_properties_table, sizeof(zval) * ce->default_properties_count); for (i = 0; i < ce->default_properties_count; i++) { zend_persist_zval(&ce->default_properties_table[i]); } } if (ce->default_static_members_table) { int i; zend_accel_store(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count); for (i = 0; i < ce->default_static_members_count; i++) { zend_persist_zval(&ce->default_static_members_table[i]); } } ce->static_members_table = NULL; zend_hash_persist(&ce->constants_table, zend_persist_zval); if (ZEND_CE_FILENAME(ce)) { /* do not free! PHP has centralized filename storage, compiler will free it */ zend_accel_memdup_string(ZEND_CE_FILENAME(ce)); } if (ZEND_CE_DOC_COMMENT(ce)) { if (ZCG(accel_directives).save_comments) { zend_accel_store_string(ZEND_CE_DOC_COMMENT(ce)); } else { if (!zend_shared_alloc_get_xlat_entry(ZEND_CE_DOC_COMMENT(ce))) { zend_shared_alloc_register_xlat_entry(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT(ce)); zend_string_release(ZEND_CE_DOC_COMMENT(ce)); } ZEND_CE_DOC_COMMENT(ce) = NULL; } } zend_hash_persist(&ce->properties_info, zend_persist_property_info); if (ce->num_interfaces && ce->interfaces) { efree(ce->interfaces); } ce->interfaces = NULL; /* will be filled in on fetch */ if (ce->num_traits && ce->traits) { efree(ce->traits); } ce->traits = NULL; if (ce->trait_aliases) { int i = 0; while (ce->trait_aliases[i]) { if (ce->trait_aliases[i]->trait_method) { if (ce->trait_aliases[i]->trait_method->method_name) { zend_accel_store_interned_string(ce->trait_aliases[i]->trait_method->method_name); } if (ce->trait_aliases[i]->trait_method->class_name) { zend_accel_store_interned_string(ce->trait_aliases[i]->trait_method->class_name); } ce->trait_aliases[i]->trait_method->ce = NULL; zend_accel_store(ce->trait_aliases[i]->trait_method, sizeof(zend_trait_method_reference)); } if (ce->trait_aliases[i]->alias) { zend_accel_store_interned_string(ce->trait_aliases[i]->alias); } zend_accel_store(ce->trait_aliases[i], sizeof(zend_trait_alias)); i++; } zend_accel_store(ce->trait_aliases, sizeof(zend_trait_alias*) * (i + 1)); } if (ce->trait_precedences) { int i = 0; while (ce->trait_precedences[i]) { zend_accel_store_interned_string(ce->trait_precedences[i]->trait_method->method_name); zend_accel_store_interned_string(ce->trait_precedences[i]->trait_method->class_name); ce->trait_precedences[i]->trait_method->ce = NULL; zend_accel_store(ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference)); if (ce->trait_precedences[i]->exclude_from_classes) { int j = 0; while (ce->trait_precedences[i]->exclude_from_classes[j].class_name) { zend_accel_store_interned_string(ce->trait_precedences[i]->exclude_from_classes[j].class_name); j++; } zend_accel_store(ce->trait_precedences[i]->exclude_from_classes, sizeof(zend_class_entry*) * (j + 1)); } zend_accel_store(ce->trait_precedences[i], sizeof(zend_trait_precedence)); i++; } zend_accel_store( ce->trait_precedences, sizeof(zend_trait_precedence*) * (i + 1)); } } }
static void zend_persist_class_entry_calc(zval *zv) { zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_USER_CLASS) { ADD_ARENA_SIZE(sizeof(zend_class_entry)); ADD_INTERNED_STRING(ce->name, 0); zend_hash_persist_calc(&ce->function_table, zend_persist_op_array_calc); if (ce->default_properties_table) { int i; ADD_SIZE(sizeof(zval) * ce->default_properties_count); for (i = 0; i < ce->default_properties_count; i++) { zend_persist_zval_calc(&ce->default_properties_table[i]); } } if (ce->default_static_members_table) { int i; ADD_SIZE(sizeof(zval) * ce->default_static_members_count); for (i = 0; i < ce->default_static_members_count; i++) { zend_persist_zval_calc(&ce->default_static_members_table[i]); } } zend_hash_persist_calc(&ce->constants_table, zend_persist_zval_calc); if (ZEND_CE_FILENAME(ce)) { ADD_STRING(ZEND_CE_FILENAME(ce)); } if (ZCG(accel_directives).save_comments && ZEND_CE_DOC_COMMENT(ce)) { ADD_STRING(ZEND_CE_DOC_COMMENT(ce)); } zend_hash_persist_calc(&ce->properties_info, zend_persist_property_info_calc); if (ce->trait_aliases) { int i = 0; while (ce->trait_aliases[i]) { if (ce->trait_aliases[i]->trait_method) { if (ce->trait_aliases[i]->trait_method->method_name) { ADD_INTERNED_STRING(ce->trait_aliases[i]->trait_method->method_name, 0); } if (ce->trait_aliases[i]->trait_method->class_name) { ADD_INTERNED_STRING(ce->trait_aliases[i]->trait_method->class_name, 0); } ADD_SIZE(sizeof(zend_trait_method_reference)); } if (ce->trait_aliases[i]->alias) { ADD_INTERNED_STRING(ce->trait_aliases[i]->alias, 0); } ADD_SIZE(sizeof(zend_trait_alias)); i++; } ADD_SIZE(sizeof(zend_trait_alias*) * (i + 1)); } if (ce->trait_precedences) { int i = 0; while (ce->trait_precedences[i]) { ADD_INTERNED_STRING(ce->trait_precedences[i]->trait_method->method_name, 0); ADD_INTERNED_STRING(ce->trait_precedences[i]->trait_method->class_name, 0); ADD_SIZE(sizeof(zend_trait_method_reference)); if (ce->trait_precedences[i]->exclude_from_classes) { int j = 0; while (ce->trait_precedences[i]->exclude_from_classes[j].class_name) { ADD_INTERNED_STRING(ce->trait_precedences[i]->exclude_from_classes[j].class_name, 0); j++; } ADD_SIZE(sizeof(zend_class_entry*) * (j + 1)); } ADD_SIZE(sizeof(zend_trait_precedence)); i++; } ADD_SIZE(sizeof(zend_trait_precedence*) * (i + 1)); } } }