version 1.1.1.1, 2012/02/21 23:47:52
|
version 1.1.1.2, 2012/05/29 12:34:36
|
Line 43 static void zend_extension_op_array_dtor_handler(zend_
|
Line 43 static void zend_extension_op_array_dtor_handler(zend_
|
} |
} |
} |
} |
|
|
static void op_array_alloc_ops(zend_op_array *op_array) | static void op_array_alloc_ops(zend_op_array *op_array, zend_uint size) |
{ |
{ |
op_array->opcodes = erealloc(op_array->opcodes, (op_array->size)*sizeof(zend_op)); | op_array->opcodes = erealloc(op_array->opcodes, size * sizeof(zend_op)); |
} |
} |
|
|
void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC) |
void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC) |
{ |
{ |
op_array->type = type; |
op_array->type = type; |
|
|
op_array->backpatch_count = 0; |
|
if (CG(interactive)) { |
if (CG(interactive)) { |
/* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants |
/* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants |
* will become invalid |
* will become invalid |
*/ |
*/ |
initial_ops_size = 8192; | initial_ops_size = INITIAL_INTERACTIVE_OP_ARRAY_SIZE; |
} |
} |
|
|
op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint)); |
op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint)); |
*op_array->refcount = 1; |
*op_array->refcount = 1; |
op_array->size = initial_ops_size; |
|
op_array->last = 0; |
op_array->last = 0; |
op_array->opcodes = NULL; |
op_array->opcodes = NULL; |
op_array_alloc_ops(op_array); | op_array_alloc_ops(op_array, initial_ops_size); |
|
|
op_array->size_var = 0; /* FIXME:??? */ |
|
op_array->last_var = 0; |
op_array->last_var = 0; |
op_array->vars = NULL; |
op_array->vars = NULL; |
|
|
Line 87 void init_op_array(zend_op_array *op_array, zend_uchar
|
Line 84 void init_op_array(zend_op_array *op_array, zend_uchar
|
op_array->brk_cont_array = NULL; |
op_array->brk_cont_array = NULL; |
op_array->try_catch_array = NULL; |
op_array->try_catch_array = NULL; |
op_array->last_brk_cont = 0; |
op_array->last_brk_cont = 0; |
op_array->current_brk_cont = -1; |
|
|
|
op_array->static_variables = NULL; |
op_array->static_variables = NULL; |
op_array->last_try_catch = 0; |
op_array->last_try_catch = 0; |
|
|
op_array->return_reference = 0; |
|
op_array->done_pass_two = 0; |
|
|
|
op_array->this_var = -1; |
op_array->this_var = -1; |
|
|
op_array->start_op = NULL; |
|
|
|
op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0; |
op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0; |
|
|
op_array->early_binding = -1; |
op_array->early_binding = -1; |
|
|
|
op_array->last_literal = 0; |
|
op_array->literals = NULL; |
|
|
|
op_array->run_time_cache = NULL; |
|
op_array->last_cache_slot = 0; |
|
|
memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*)); |
memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*)); |
|
|
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); |
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); |
Line 152 ZEND_API int zend_cleanup_function_data_full(zend_func
|
Line 149 ZEND_API int zend_cleanup_function_data_full(zend_func
|
return 0; |
return 0; |
} |
} |
|
|
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC) | static inline void cleanup_user_class_data(zend_class_entry *ce TSRMLS_DC) |
{ |
{ |
if ((*pce)->type == ZEND_USER_CLASS) { | /* Clean all parts that can contain run-time data */ |
/* Clean all parts that can contain run-time data */ | /* Note that only run-time accessed data need to be cleaned up, pre-defined data can |
/* Note that only run-time accessed data need to be cleaned up, pre-defined data can | not contain objects and thus are not probelmatic */ |
not contain objects and thus are not probelmatic */ | if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) { |
zend_hash_apply(&(*pce)->function_table, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC); | zend_hash_apply(&ce->function_table, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC); |
if ((*pce)->static_members) { | } |
zend_hash_clean((*pce)->static_members); | if (ce->static_members_table) { |
(*pce)->static_members = NULL; | int i; |
| |
| for (i = 0; i < ce->default_static_members_count; i++) { |
| if (ce->static_members_table[i]) { |
| zval_ptr_dtor(&ce->static_members_table[i]); |
| ce->static_members_table[i] = NULL; |
| } |
} |
} |
} else if (CE_STATIC_MEMBERS(*pce)) { | ce->static_members_table = NULL; |
zend_hash_destroy(CE_STATIC_MEMBERS(*pce)); | } |
FREE_HASHTABLE(CE_STATIC_MEMBERS(*pce)); | } |
| |
| static inline void cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC) |
| { |
| if (CE_STATIC_MEMBERS(ce)) { |
| int i; |
| |
| for (i = 0; i < ce->default_static_members_count; i++) { |
| zval_ptr_dtor(&CE_STATIC_MEMBERS(ce)[i]); |
| } |
| efree(CE_STATIC_MEMBERS(ce)); |
#ifdef ZTS |
#ifdef ZTS |
CG(static_members)[(zend_intptr_t)((*pce)->static_members)] = NULL; | CG(static_members_table)[(zend_intptr_t)(ce->static_members_table)] = NULL; |
#else |
#else |
(*pce)->static_members = NULL; | ce->static_members_table = NULL; |
#endif |
#endif |
} |
} |
|
} |
|
|
|
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC) |
|
{ |
|
cleanup_internal_class_data(ce TSRMLS_CC); |
|
} |
|
|
|
ZEND_API int zend_cleanup_user_class_data(zend_class_entry **pce TSRMLS_DC) |
|
{ |
|
if ((*pce)->type == ZEND_USER_CLASS) { |
|
cleanup_user_class_data(*pce TSRMLS_CC); |
|
return ZEND_HASH_APPLY_KEEP; |
|
} else { |
|
return ZEND_HASH_APPLY_STOP; |
|
} |
|
} |
|
|
|
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC) |
|
{ |
|
if ((*pce)->type == ZEND_USER_CLASS) { |
|
cleanup_user_class_data(*pce TSRMLS_CC); |
|
} else { |
|
cleanup_internal_class_data(*pce TSRMLS_CC); |
|
} |
return 0; |
return 0; |
} |
} |
|
|
|
void _destroy_zend_class_traits_info(zend_class_entry *ce) |
|
{ |
|
if (ce->num_traits > 0 && ce->traits) { |
|
efree(ce->traits); |
|
} |
|
|
|
if (ce->trait_aliases) { |
|
size_t i = 0; |
|
while (ce->trait_aliases[i]) { |
|
if (ce->trait_aliases[i]->trait_method) { |
|
if (ce->trait_aliases[i]->trait_method->method_name) { |
|
efree((char*)ce->trait_aliases[i]->trait_method->method_name); |
|
} |
|
if (ce->trait_aliases[i]->trait_method->class_name) { |
|
efree((char*)ce->trait_aliases[i]->trait_method->class_name); |
|
} |
|
efree(ce->trait_aliases[i]->trait_method); |
|
} |
|
|
|
if (ce->trait_aliases[i]->alias) { |
|
efree((char*)ce->trait_aliases[i]->alias); |
|
} |
|
|
|
efree(ce->trait_aliases[i]); |
|
i++; |
|
} |
|
|
|
efree(ce->trait_aliases); |
|
} |
|
|
|
if (ce->trait_precedences) { |
|
size_t i = 0; |
|
|
|
while (ce->trait_precedences[i]) { |
|
efree((char*)ce->trait_precedences[i]->trait_method->method_name); |
|
efree((char*)ce->trait_precedences[i]->trait_method->class_name); |
|
efree(ce->trait_precedences[i]->trait_method); |
|
|
|
if (ce->trait_precedences[i]->exclude_from_classes) { |
|
efree(ce->trait_precedences[i]->exclude_from_classes); |
|
} |
|
|
|
efree(ce->trait_precedences[i]); |
|
i++; |
|
} |
|
efree(ce->trait_precedences); |
|
} |
|
} |
|
|
ZEND_API void destroy_zend_class(zend_class_entry **pce) |
ZEND_API void destroy_zend_class(zend_class_entry **pce) |
{ |
{ |
zend_class_entry *ce = *pce; |
zend_class_entry *ce = *pce; |
Line 184 ZEND_API void destroy_zend_class(zend_class_entry **pc
|
Line 270 ZEND_API void destroy_zend_class(zend_class_entry **pc
|
} |
} |
switch (ce->type) { |
switch (ce->type) { |
case ZEND_USER_CLASS: |
case ZEND_USER_CLASS: |
zend_hash_destroy(&ce->default_properties); | if (ce->default_properties_table) { |
| int i; |
| |
| for (i = 0; i < ce->default_properties_count; i++) { |
| if (ce->default_properties_table[i]) { |
| zval_ptr_dtor(&ce->default_properties_table[i]); |
| } |
| } |
| efree(ce->default_properties_table); |
| } |
| if (ce->default_static_members_table) { |
| int i; |
| |
| for (i = 0; i < ce->default_static_members_count; i++) { |
| if (ce->default_static_members_table[i]) { |
| zval_ptr_dtor(&ce->default_static_members_table[i]); |
| } |
| } |
| efree(ce->default_static_members_table); |
| } |
zend_hash_destroy(&ce->properties_info); |
zend_hash_destroy(&ce->properties_info); |
zend_hash_destroy(&ce->default_static_members); | str_efree(ce->name); |
efree(ce->name); | |
zend_hash_destroy(&ce->function_table); |
zend_hash_destroy(&ce->function_table); |
zend_hash_destroy(&ce->constants_table); |
zend_hash_destroy(&ce->constants_table); |
if (ce->num_interfaces > 0 && ce->interfaces) { |
if (ce->num_interfaces > 0 && ce->interfaces) { |
efree(ce->interfaces); |
efree(ce->interfaces); |
} |
} |
if (ce->doc_comment) { | if (ce->info.user.doc_comment) { |
efree(ce->doc_comment); | efree((char*)ce->info.user.doc_comment); |
} |
} |
|
|
|
_destroy_zend_class_traits_info(ce); |
|
|
efree(ce); |
efree(ce); |
break; |
break; |
case ZEND_INTERNAL_CLASS: |
case ZEND_INTERNAL_CLASS: |
zend_hash_destroy(&ce->default_properties); | if (ce->default_properties_table) { |
| int i; |
| |
| for (i = 0; i < ce->default_properties_count; i++) { |
| if (ce->default_properties_table[i]) { |
| zval_internal_ptr_dtor(&ce->default_properties_table[i]); |
| } |
| } |
| free(ce->default_properties_table); |
| } |
| if (ce->default_static_members_table) { |
| int i; |
| |
| for (i = 0; i < ce->default_static_members_count; i++) { |
| zval_internal_ptr_dtor(&ce->default_static_members_table[i]); |
| } |
| free(ce->default_static_members_table); |
| } |
zend_hash_destroy(&ce->properties_info); |
zend_hash_destroy(&ce->properties_info); |
zend_hash_destroy(&ce->default_static_members); | str_free(ce->name); |
free(ce->name); | |
zend_hash_destroy(&ce->function_table); |
zend_hash_destroy(&ce->function_table); |
zend_hash_destroy(&ce->constants_table); |
zend_hash_destroy(&ce->constants_table); |
if (ce->num_interfaces > 0) { |
if (ce->num_interfaces > 0) { |
free(ce->interfaces); |
free(ce->interfaces); |
} |
} |
if (ce->doc_comment) { |
|
free(ce->doc_comment); |
|
} |
|
free(ce); |
free(ce); |
break; |
break; |
} |
} |
Line 223 void zend_class_add_ref(zend_class_entry **ce)
|
Line 343 void zend_class_add_ref(zend_class_entry **ce)
|
|
|
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC) |
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC) |
{ |
{ |
zend_op *opline = op_array->opcodes; | zend_literal *literal = op_array->literals; |
zend_op *end = op_array->opcodes+op_array->last; | zend_literal *end; |
zend_uint i; |
zend_uint i; |
|
|
if (op_array->static_variables) { |
if (op_array->static_variables) { |
Line 232 ZEND_API void destroy_op_array(zend_op_array *op_array
|
Line 352 ZEND_API void destroy_op_array(zend_op_array *op_array
|
FREE_HASHTABLE(op_array->static_variables); |
FREE_HASHTABLE(op_array->static_variables); |
} |
} |
|
|
|
if (op_array->run_time_cache) { |
|
efree(op_array->run_time_cache); |
|
} |
|
|
if (--(*op_array->refcount)>0) { |
if (--(*op_array->refcount)>0) { |
return; |
return; |
} |
} |
Line 242 ZEND_API void destroy_op_array(zend_op_array *op_array
|
Line 366 ZEND_API void destroy_op_array(zend_op_array *op_array
|
i = op_array->last_var; |
i = op_array->last_var; |
while (i > 0) { |
while (i > 0) { |
i--; |
i--; |
efree(op_array->vars[i].name); | str_efree(op_array->vars[i].name); |
} |
} |
efree(op_array->vars); |
efree(op_array->vars); |
} |
} |
|
|
while (opline<end) { | if (literal) { |
if (opline->op1.op_type==IS_CONST) { | end = literal + op_array->last_literal; |
#if DEBUG_ZEND>2 | while (literal < end) { |
printf("Reducing refcount for %x 1=>0 (destroying)\n", &opline->op1.u.constant); | zval_dtor(&literal->constant); |
#endif | literal++; |
zval_dtor(&opline->op1.u.constant); | |
} |
} |
if (opline->op2.op_type==IS_CONST) { | efree(op_array->literals); |
#if DEBUG_ZEND>2 | |
printf("Reducing refcount for %x 1=>0 (destroying)\n", &opline->op2.u.constant); | |
#endif | |
zval_dtor(&opline->op2.u.constant); | |
} | |
opline++; | |
} |
} |
efree(op_array->opcodes); |
efree(op_array->opcodes); |
|
|
if (op_array->function_name) { |
if (op_array->function_name) { |
efree(op_array->function_name); | efree((char*)op_array->function_name); |
} |
} |
if (op_array->doc_comment) { |
if (op_array->doc_comment) { |
efree(op_array->doc_comment); | efree((char*)op_array->doc_comment); |
} |
} |
if (op_array->brk_cont_array) { |
if (op_array->brk_cont_array) { |
efree(op_array->brk_cont_array); |
efree(op_array->brk_cont_array); |
Line 276 ZEND_API void destroy_op_array(zend_op_array *op_array
|
Line 393 ZEND_API void destroy_op_array(zend_op_array *op_array
|
if (op_array->try_catch_array) { |
if (op_array->try_catch_array) { |
efree(op_array->try_catch_array); |
efree(op_array->try_catch_array); |
} |
} |
if (op_array->done_pass_two) { | if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) { |
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array TSRMLS_CC); |
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array TSRMLS_CC); |
} |
} |
if (op_array->arg_info) { |
if (op_array->arg_info) { |
for (i=0; i<op_array->num_args; i++) { |
for (i=0; i<op_array->num_args; i++) { |
efree((char*)op_array->arg_info[i].name); | str_efree(op_array->arg_info[i].name); |
if (op_array->arg_info[i].class_name) { |
if (op_array->arg_info[i].class_name) { |
efree((char*)op_array->arg_info[i].class_name); | str_efree(op_array->arg_info[i].class_name); |
} |
} |
} |
} |
efree(op_array->arg_info); |
efree(op_array->arg_info); |
Line 302 zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC
|
Line 419 zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC
|
zend_uint next_op_num = op_array->last++; |
zend_uint next_op_num = op_array->last++; |
zend_op *next_op; |
zend_op *next_op; |
|
|
if (next_op_num >= op_array->size) { | if (next_op_num >= CG(context).opcodes_size) { |
if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { |
if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { |
/* we messed up */ |
/* we messed up */ |
zend_printf("Ran out of opcode space!\n" |
zend_printf("Ran out of opcode space!\n" |
"You should probably consider writing this huge script into a file!\n"); |
"You should probably consider writing this huge script into a file!\n"); |
zend_bailout(); |
zend_bailout(); |
} |
} |
op_array->size *= 4; | CG(context).opcodes_size *= 4; |
op_array_alloc_ops(op_array); | op_array_alloc_ops(op_array, CG(context).opcodes_size); |
} |
} |
|
|
next_op = &(op_array->opcodes[next_op_num]); |
next_op = &(op_array->opcodes[next_op_num]); |
Line 376 ZEND_API int pass_two(zend_op_array *op_array TSRMLS_D
|
Line 493 ZEND_API int pass_two(zend_op_array *op_array TSRMLS_D
|
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array TSRMLS_CC); |
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array TSRMLS_CC); |
} |
} |
|
|
if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && op_array->size != op_array->last) { | if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).vars_size != op_array->last_var) { |
| op_array->vars = (zend_compiled_variable *) erealloc(op_array->vars, sizeof(zend_compiled_variable)*op_array->last_var); |
| CG(context).vars_size = op_array->last_var; |
| } |
| if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).opcodes_size != op_array->last) { |
op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last); |
op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last); |
op_array->size = op_array->last; | CG(context).opcodes_size = op_array->last; |
} |
} |
|
if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).literals_size != op_array->last_literal) { |
|
op_array->literals = (zend_literal*)erealloc(op_array->literals, sizeof(zend_literal) * op_array->last_literal); |
|
CG(context).literals_size = op_array->last_literal; |
|
} |
|
|
opline = op_array->opcodes; |
opline = op_array->opcodes; |
end = opline + op_array->last; |
end = opline + op_array->last; |
while (opline < end) { |
while (opline < end) { |
if (opline->op1.op_type == IS_CONST) { | if (opline->op1_type == IS_CONST) { |
Z_SET_ISREF(opline->op1.u.constant); | opline->op1.zv = &op_array->literals[opline->op1.constant].constant; |
Z_SET_REFCOUNT(opline->op1.u.constant, 2); /* Make sure is_ref won't be reset */ | |
} |
} |
if (opline->op2.op_type == IS_CONST) { | if (opline->op2_type == IS_CONST) { |
Z_SET_ISREF(opline->op2.u.constant); | opline->op2.zv = &op_array->literals[opline->op2.constant].constant; |
Z_SET_REFCOUNT(opline->op2.u.constant, 2); | |
} |
} |
switch (opline->opcode) { |
switch (opline->opcode) { |
case ZEND_GOTO: |
case ZEND_GOTO: |
if (Z_TYPE(opline->op2.u.constant) != IS_LONG) { | if (Z_TYPE_P(opline->op2.zv) != IS_LONG) { |
zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC); |
zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC); |
} |
} |
/* break omitted intentionally */ |
/* break omitted intentionally */ |
case ZEND_JMP: |
case ZEND_JMP: |
opline->op1.u.jmp_addr = &op_array->opcodes[opline->op1.u.opline_num]; | opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num]; |
break; |
break; |
case ZEND_JMPZ: |
case ZEND_JMPZ: |
case ZEND_JMPNZ: |
case ZEND_JMPNZ: |
case ZEND_JMPZ_EX: |
case ZEND_JMPZ_EX: |
case ZEND_JMPNZ_EX: |
case ZEND_JMPNZ_EX: |
case ZEND_JMP_SET: |
case ZEND_JMP_SET: |
opline->op2.u.jmp_addr = &op_array->opcodes[opline->op2.u.opline_num]; | case ZEND_JMP_SET_VAR: |
| opline->op2.jmp_addr = &op_array->opcodes[opline->op2.opline_num]; |
break; |
break; |
} |
} |
ZEND_VM_SET_OPCODE_HANDLER(opline); |
ZEND_VM_SET_OPCODE_HANDLER(opline); |
opline++; |
opline++; |
} |
} |
| |
op_array->done_pass_two = 1; | op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO; |
return 0; |
return 0; |
} |
} |
|
|