static void zend_file_cache_serialize_hash(HashTable *ht, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf, serialize_callback_t func) { Bucket *p, *end; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { ht->arData = NULL; return; } if (IS_SERIALIZED(ht->arData)) { return; } SERIALIZE_PTR(ht->arData); p = ht->arData; UNSERIALIZE_PTR(p); end = p + ht->nNumUsed; while (p < end) { if (Z_TYPE(p->val) != IS_UNDEF) { SERIALIZE_STR(p->key); func(&p->val, script, info, buf); } p++; } }
static void zend_file_cache_serialize_zval(zval *zv, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { switch (Z_TYPE_P(zv)) { case IS_STRING: case IS_CONSTANT: if (!IS_SERIALIZED(Z_STR_P(zv))) { SERIALIZE_STR(Z_STR_P(zv)); } break; case IS_ARRAY: if (!IS_SERIALIZED(Z_ARR_P(zv))) { HashTable *ht; SERIALIZE_PTR(Z_ARR_P(zv)); ht = Z_ARR_P(zv); UNSERIALIZE_PTR(ht); zend_file_cache_serialize_hash(ht, script, info, buf, zend_file_cache_serialize_zval); } break; case IS_REFERENCE: if (!IS_SERIALIZED(Z_REF_P(zv))) { zend_reference *ref; SERIALIZE_PTR(Z_REF_P(zv)); ref = Z_REF_P(zv); UNSERIALIZE_PTR(ref); zend_file_cache_serialize_zval(&ref->val, script, info, buf); } break; case IS_CONSTANT_AST: if (!IS_SERIALIZED(Z_AST_P(zv))) { zend_ast_ref *ast; SERIALIZE_PTR(Z_AST_P(zv)); ast = Z_AST_P(zv); UNSERIALIZE_PTR(ast); if (!IS_SERIALIZED(ast->ast)) { ast->ast = zend_file_cache_serialize_ast(ast->ast, script, info, buf); } } break; } }
static void zend_file_cache_serialize_class_constant(zval *zv, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { if (!IS_SERIALIZED(Z_PTR_P(zv))) { zend_class_constant *c; SERIALIZE_PTR(Z_PTR_P(zv)); c = Z_PTR_P(zv); UNSERIALIZE_PTR(c); zend_file_cache_serialize_zval(&c->value, script, info, buf); if (c->ce && !IS_SERIALIZED(c->ce)) { SERIALIZE_PTR(c->ce); } if (c->doc_comment && !IS_SERIALIZED(c->doc_comment)) { SERIALIZE_STR(c->doc_comment); } } }
static void zend_file_cache_serialize_prop_info(zval *zv, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { if (!IS_SERIALIZED(Z_PTR_P(zv))) { zend_property_info *prop; SERIALIZE_PTR(Z_PTR_P(zv)); prop = Z_PTR_P(zv); UNSERIALIZE_PTR(prop); if (prop->ce && !IS_SERIALIZED(prop->ce)) { SERIALIZE_PTR(prop->ce); } if (prop->name && !IS_SERIALIZED(prop->name)) { SERIALIZE_STR(prop->name); } if (prop->doc_comment && !IS_SERIALIZED(prop->doc_comment)) { SERIALIZE_STR(prop->doc_comment); } } }
static void zend_file_cache_serialize_op_array(zend_op_array *op_array, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { if (op_array->static_variables && !IS_SERIALIZED(op_array->static_variables)) { HashTable *ht; SERIALIZE_PTR(op_array->static_variables); ht = op_array->static_variables; UNSERIALIZE_PTR(ht); zend_file_cache_serialize_hash(ht, script, info, buf, zend_file_cache_serialize_zval); } if (op_array->literals && !IS_SERIALIZED(op_array->literals)) { zval *p, *end; SERIALIZE_PTR(op_array->literals); p = op_array->literals; UNSERIALIZE_PTR(p); end = p + op_array->last_literal; while (p < end) { zend_file_cache_serialize_zval(p, script, info, buf); p++; } } if (!IS_SERIALIZED(op_array->opcodes)) { zend_op *opline, *end; SERIALIZE_PTR(op_array->opcodes); opline = op_array->opcodes; UNSERIALIZE_PTR(opline); end = opline + op_array->last; while (opline < end) { #if ZEND_USE_ABS_CONST_ADDR if (opline->op1_type == IS_CONST) { SERIALIZE_PTR(opline->op1.zv); } if (opline->op2_type == IS_CONST) { SERIALIZE_PTR(opline->op2.zv); } #endif #if ZEND_USE_ABS_JMP_ADDR switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: SERIALIZE_PTR(opline->op1.jmp_addr); break; case ZEND_JMPZNZ: /* relative extended_value don't have to be changed */ /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: SERIALIZE_PTR(opline->op2.jmp_addr); break; case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: /* relative extended_value don't have to be changed */ break; } #endif zend_serialize_opcode_handler(opline); opline++; } if (op_array->arg_info) { zend_arg_info *p, *end; SERIALIZE_PTR(op_array->arg_info); p = op_array->arg_info; UNSERIALIZE_PTR(p); end = p + op_array->num_args; if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { p--; } if (op_array->fn_flags & ZEND_ACC_VARIADIC) { end++; } while (p < end) { if (!IS_SERIALIZED(p->name)) { SERIALIZE_STR(p->name); } if (!IS_SERIALIZED(p->class_name)) { SERIALIZE_STR(p->class_name); } p++; } } if (op_array->vars) { zend_string **p, **end; SERIALIZE_PTR(op_array->vars); p = op_array->vars; UNSERIALIZE_PTR(p); end = p + op_array->last_var; while (p < end) { if (!IS_SERIALIZED(*p)) { SERIALIZE_STR(*p); } p++; } } SERIALIZE_STR(op_array->function_name); SERIALIZE_STR(op_array->filename); SERIALIZE_PTR(op_array->live_range); SERIALIZE_PTR(op_array->scope); SERIALIZE_STR(op_array->doc_comment); SERIALIZE_PTR(op_array->try_catch_array); SERIALIZE_PTR(op_array->prototype); } }
static void zend_file_cache_serialize_op_array(zend_op_array *op_array, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { if (op_array->static_variables && !IS_SERIALIZED(op_array->static_variables)) { HashTable *ht; SERIALIZE_PTR(op_array->static_variables); ht = op_array->static_variables; UNSERIALIZE_PTR(ht); zend_file_cache_serialize_hash(ht, script, info, buf, zend_file_cache_serialize_zval); } if (op_array->scope && !IS_SERIALIZED(op_array->opcodes)) { if (UNEXPECTED(zend_shared_alloc_get_xlat_entry(op_array->opcodes))) { op_array->refcount = (uint32_t*)(intptr_t)-1; SERIALIZE_PTR(op_array->literals); SERIALIZE_PTR(op_array->opcodes); SERIALIZE_PTR(op_array->arg_info); SERIALIZE_PTR(op_array->vars); SERIALIZE_STR(op_array->function_name); SERIALIZE_STR(op_array->filename); SERIALIZE_PTR(op_array->live_range); SERIALIZE_PTR(op_array->scope); SERIALIZE_STR(op_array->doc_comment); SERIALIZE_PTR(op_array->try_catch_array); SERIALIZE_PTR(op_array->prototype); return; } zend_shared_alloc_register_xlat_entry(op_array->opcodes, op_array->opcodes); } if (op_array->literals && !IS_SERIALIZED(op_array->literals)) { zval *p, *end; SERIALIZE_PTR(op_array->literals); p = op_array->literals; UNSERIALIZE_PTR(p); end = p + op_array->last_literal; while (p < end) { zend_file_cache_serialize_zval(p, script, info, buf); p++; } } if (!IS_SERIALIZED(op_array->opcodes)) { zend_op *opline, *end; SERIALIZE_PTR(op_array->opcodes); opline = op_array->opcodes; UNSERIALIZE_PTR(opline); end = opline + op_array->last; while (opline < end) { #if ZEND_USE_ABS_CONST_ADDR if (opline->op1_type == IS_CONST) { SERIALIZE_PTR(opline->op1.zv); } if (opline->op2_type == IS_CONST) { SERIALIZE_PTR(opline->op2.zv); } #else if (opline->op1_type == IS_CONST) { ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline, opline->op1); } if (opline->op2_type == IS_CONST) { ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline, opline->op2); } #endif #if ZEND_USE_ABS_JMP_ADDR switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: SERIALIZE_PTR(opline->op1.jmp_addr); break; case ZEND_JMPZNZ: /* relative extended_value don't have to be changed */ /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: SERIALIZE_PTR(opline->op2.jmp_addr); break; case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: case ZEND_SWITCH_LONG: case ZEND_SWITCH_STRING: /* relative extended_value don't have to be changed */ break; } #endif zend_serialize_opcode_handler(opline); opline++; } if (op_array->arg_info) { zend_arg_info *p, *end; SERIALIZE_PTR(op_array->arg_info); p = op_array->arg_info; UNSERIALIZE_PTR(p); end = p + op_array->num_args; if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { p--; } if (op_array->fn_flags & ZEND_ACC_VARIADIC) { end++; } while (p < end) { if (!IS_SERIALIZED(p->name)) { SERIALIZE_STR(p->name); } if (ZEND_TYPE_IS_CLASS(p->type)) { zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(p->type); zend_string *type_name = ZEND_TYPE_NAME(p->type); SERIALIZE_STR(type_name); p->type = (Z_UL(1) << (sizeof(zend_type)*8-1)) | /* type is class */ (allow_null ? (Z_UL(1) << (sizeof(zend_type)*8-2)) : Z_UL(0)) | /* type allow null */ (zend_type)type_name; } p++; } } if (op_array->vars) { zend_string **p, **end; SERIALIZE_PTR(op_array->vars); p = op_array->vars; UNSERIALIZE_PTR(p); end = p + op_array->last_var; while (p < end) { if (!IS_SERIALIZED(*p)) { SERIALIZE_STR(*p); } p++; } } SERIALIZE_STR(op_array->function_name); SERIALIZE_STR(op_array->filename); SERIALIZE_PTR(op_array->live_range); SERIALIZE_PTR(op_array->scope); SERIALIZE_STR(op_array->doc_comment); SERIALIZE_PTR(op_array->try_catch_array); SERIALIZE_PTR(op_array->prototype); } }