diff options
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 106 |
1 files changed, 70 insertions, 36 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 75c5a827d5..58d4cc1e50 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -108,7 +108,10 @@ static void zend_duplicate_property_info(zend_property_info *property_info) /* { static void zend_duplicate_property_info_zval(zval *zv) /* {{{ */ { - zend_duplicate_property_info((zend_property_info*)Z_PTR_P(zv)); + zend_property_info* property_info = emalloc(sizeof(zend_property_info)); + memcpy(property_info, Z_PTR_P(zv), sizeof(zend_property_info)); + Z_PTR_P(zv) = property_info; + zend_duplicate_property_info(property_info); } /* }}} */ @@ -120,7 +123,10 @@ static void zend_duplicate_property_info_internal(zend_property_info *property_i static void zend_duplicate_property_info_internal_zval(zval *zv) /* {{{ */ { - zend_duplicate_property_info_internal((zend_property_info*)Z_PTR_P(zv)); + zend_property_info* property_info = pemalloc(sizeof(zend_property_info), 1); + memcpy(property_info, Z_PTR_P(zv), sizeof(zend_property_info)); + Z_PTR_P(zv) = property_info; + zend_duplicate_property_info_internal(property_info); } /* }}} */ @@ -132,6 +138,7 @@ static void zend_destroy_property_info(zval *zv) /* {{{ */ if (property_info->doc_comment) { STR_RELEASE(property_info->doc_comment); } + efree(property_info); } /* }}} */ @@ -140,6 +147,7 @@ static void zend_destroy_property_info_internal(zval *zv) /* {{{ */ zend_property_info *property_info = Z_PTR_P(zv); STR_RELEASE(property_info->name); + free(property_info); } /* }}} */ @@ -226,7 +234,7 @@ void init_compiler(TSRMLS_D) /* {{{ */ memset(&CG(context), 0, sizeof(CG(context))); zend_init_compiler_data_structures(TSRMLS_C); zend_init_rsrc_list(TSRMLS_C); - zend_hash_init(&CG(filenames_table), 5, NULL, (dtor_func_t) free_estring, 0); + zend_hash_init(&CG(filenames_table), 5, NULL, free_string_zval, 0); zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0); CG(unclean_shutdown) = 0; } @@ -1395,12 +1403,12 @@ void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) / int ch = *Z_STRVAL(op2->u.constant); /* Free memory and use ZEND_ADD_CHAR in case of 1 character strings */ - efree(Z_STRVAL(op2->u.constant)); + STR_FREE(Z_STR(op2->u.constant)); ZVAL_LONG(&op2->u.constant, ch); opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_ADD_CHAR; } else { /* String can be empty after a variable at the end of a heredoc */ - efree(Z_STRVAL(op2->u.constant)); + STR_FREE(Z_STR(op2->u.constant)); return; } @@ -1564,7 +1572,9 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n lcname = STR_ALLOC(name->len, 0); zend_str_tolower_copy(lcname->val, name->val, name->len); lcname = zend_new_interned_string(lcname TSRMLS_CC); - if ((CG(active_op_array) = zend_hash_add_mem(&CG(active_class_entry)->function_table, lcname, &op_array, sizeof(zend_op_array))) == NULL) { + CG(active_op_array) = emalloc(sizeof(zend_op_array)); + memcpy(CG(active_op_array), &op_array, sizeof(zend_op_array)); + if (zend_hash_add_ptr(&CG(active_class_entry)->function_table, lcname, CG(active_op_array)) == NULL) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name->val, name->val); } @@ -1718,7 +1728,9 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n opline->op2_type = IS_CONST; LITERAL_STR(opline->op2, STR_COPY(lcname)); opline->extended_value = ZEND_DECLARE_FUNCTION; - CG(active_op_array) = zend_hash_update_mem(CG(function_table), Z_STR(key), &op_array, sizeof(zend_op_array)); + CG(active_op_array) = emalloc(sizeof(zend_op_array)); + memcpy(CG(active_op_array), &op_array, sizeof(zend_op_array)); + zend_hash_update_ptr(CG(function_table), Z_STR(key), CG(active_op_array)); zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); zend_init_compiler_context(TSRMLS_C); STR_RELEASE(lcname); @@ -2226,9 +2238,9 @@ void zend_resolve_class_name(znode *class_name TSRMLS_DC) /* {{{ */ if (Z_STRVAL(class_name->u.constant)[0] == '\\') { /* The STRING name has "\" prefix */ memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+1, Z_STRLEN(class_name->u.constant)-1); - Z_STR(class_name->u.constant) = STR_EREALLOC( + Z_STR(class_name->u.constant) = STR_REALLOC( Z_STR(class_name->u.constant), - Z_STRLEN(class_name->u.constant) - 1); + Z_STRLEN(class_name->u.constant) - 1, 0); if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) { zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant)); @@ -2447,14 +2459,14 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c if (is_class_member) { int old_len = Z_STRLEN(result->u.constant); length = sizeof("::")-1 + old_len + Z_STRLEN(name->u.constant); - Z_STR(result->u.constant) = STR_EREALLOC(Z_STR(result->u.constant), length); + Z_STR(result->u.constant) = STR_REALLOC(Z_STR(result->u.constant), length, 0); memcpy(&Z_STRVAL(result->u.constant)[old_len], "::", sizeof("::")-1); memcpy(&Z_STRVAL(result->u.constant)[old_len + sizeof("::")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1); STR_RELEASE(Z_STR(name->u.constant)); } else { int old_len = Z_STRLEN(result->u.constant); length = sizeof("\\")-1 + old_len + Z_STRLEN(name->u.constant); - Z_STR(result->u.constant) = STR_EREALLOC(Z_STR(result->u.constant), length); + Z_STR(result->u.constant) = STR_REALLOC(Z_STR(result->u.constant), length, 0); memcpy(&Z_STRVAL(result->u.constant)[old_len], "\\", sizeof("\\")-1); memcpy(&Z_STRVAL(result->u.constant)[old_len + sizeof("\\")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1); STR_RELEASE(Z_STR(name->u.constant)); @@ -3119,7 +3131,14 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ if ((function = zend_hash_str_find_ptr(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1)) != NULL) { /* inherit parent's constructor */ - new_function = zend_hash_str_update_mem(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1, function, sizeof(zend_function)); + if (function->type == ZEND_INTERNAL_FUNCTION) { + new_function = pemalloc(sizeof(zend_internal_function), 1); + memcpy(new_function, function, sizeof(zend_internal_function)); + } else { + new_function = emalloc(sizeof(zend_op_array)); + memcpy(new_function, function, sizeof(zend_op_array)); + } + zend_hash_str_update_ptr(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1, new_function); function_add_ref(new_function); } else { /* Don't inherit the old style constructor if we already have the new style constructor */ @@ -3135,7 +3154,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ (function = zend_hash_find_ptr(&ce->parent->function_table, lc_parent_class_name)) != NULL) { if (function->common.fn_flags & ZEND_ACC_CTOR) { /* inherit parent's constructor */ - zend_hash_update_mem(&ce->function_table, lc_parent_class_name, function, sizeof(zend_function)); + new_function = pemalloc(sizeof(zend_function), function->type == ZEND_INTERNAL_FUNCTION); + memcpy(new_function, function, sizeof(zend_function)); + zend_hash_update_ptr(&ce->function_table, lc_parent_class_name, new_function); function_add_ref(new_function); } } @@ -3162,13 +3183,24 @@ char *zend_visibility_string(zend_uint fn_flags) /* {{{ */ } /* }}} */ -static void do_inherit_method(zend_function *function) /* {{{ */ +static void do_inherit_method(zval *zv) /* {{{ */ { + zend_function *old_function = Z_PTR_P(zv); + zend_function *new_function; + + if (old_function->type == ZEND_INTERNAL_FUNCTION) { + new_function = pemalloc(sizeof(zend_internal_function), 1); + memcpy(new_function, old_function, sizeof(zend_internal_function)); + } else { + new_function = emalloc(sizeof(zend_op_array)); + memcpy(new_function, old_function, sizeof(zend_op_array)); + } /* The class entry of the derived function intentionally remains the same * as that of the parent class. That allows us to know in which context * we're running, and handle private method calls properly. */ - function_add_ref(function); + function_add_ref(new_function); + Z_PTR_P(zv) = new_function; } /* }}} */ @@ -3802,7 +3834,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (ce->type & ZEND_INTERNAL_CLASS ? zend_duplicate_property_info_internal_zval : zend_duplicate_property_info_zval), (merge_checker_func_t) do_inherit_property_access_check, ce); zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, zval_property_ctor(parent_ce, ce), 0); - zend_hash_merge_ex(&ce->function_table, &parent_ce->function_table, (copy_ctor_func_t) do_inherit_method, (merge_checker_func_t) do_inherit_method_check, ce); + zend_hash_merge_ex(&ce->function_table, &parent_ce->function_table, do_inherit_method, (merge_checker_func_t) do_inherit_method_check, ce); do_inherit_parent_constructor(ce); if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) { @@ -3871,7 +3903,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry ce->interfaces[ce->num_interfaces++] = iface; zend_hash_merge_ex(&ce->constants_table, &iface->constants_table, (copy_ctor_func_t) zval_add_ref, (merge_checker_func_t) do_inherit_constant_check, iface); - zend_hash_merge_ex(&ce->function_table, &iface->function_table, (copy_ctor_func_t) do_inherit_method, (merge_checker_func_t) do_inherit_method_check, ce); + zend_hash_merge_ex(&ce->function_table, &iface->function_table, do_inherit_method, (merge_checker_func_t) do_inherit_method_check, ce); do_implement_interface(ce, iface TSRMLS_CC); zend_do_inherit_interfaces(ce, iface TSRMLS_CC); @@ -4512,7 +4544,7 @@ ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC) /* {{{ */ ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */ { - zend_function *function; + zend_function *function, *new_function; zval *op1, *op2; if (compile_time) { @@ -4524,10 +4556,13 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, Ha } function = zend_hash_find_ptr(function_table, Z_STR_P(op1)); - if (zend_hash_add_mem(function_table, Z_STR_P(op2), function, sizeof(zend_function)) == NULL) { + new_function = emalloc(sizeof(zend_op_array)); + memcpy(new_function, function, sizeof(zend_op_array)); + if (zend_hash_add_ptr(function_table, Z_STR_P(op2), new_function) == NULL) { int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR; zend_function *old_function; + efree(new_function); if ((old_function = zend_hash_find_ptr(function_table, Z_STR_P(op2))) != NULL && old_function->type == ZEND_USER_FUNCTION && old_function->op_array.last > 0) { @@ -4540,8 +4575,8 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, Ha } return FAILURE; } else { - (*function->op_array.refcount)++; - function->op_array.static_variables = NULL; /* NULL out the unbound function */ + (*new_function->op_array.refcount)++; + new_function->op_array.static_variables = NULL; /* NULL out the unbound function */ return SUCCESS; } } @@ -5283,19 +5318,17 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal) /* {{{ */ +ZEND_API zend_string *zend_mangle_property_name(const char *src1, int src1_length, const char *src2, int src2_length, int internal) /* {{{ */ { - char *prop_name; + zend_string *prop_name; int prop_name_length; prop_name_length = 1 + src1_length + 1 + src2_length; - prop_name = pemalloc(prop_name_length + 1, internal); - prop_name[0] = '\0'; - memcpy(prop_name + 1, src1, src1_length+1); - memcpy(prop_name + 1 + src1_length + 1, src2, src2_length+1); - - *dest = prop_name; - *dest_length = prop_name_length; + prop_name = STR_ALLOC(prop_name_length, internal); + prop_name->val[0] = '\0'; + memcpy(prop_name->val + 1, src1, src1_length+1); + memcpy(prop_name->val + 1 + src1_length + 1, src2, src2_length+1); + return prop_name; } /* }}} */ @@ -5493,19 +5526,18 @@ void zend_do_fetch_property(znode *result, znode *object, const znode *property void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */ { - char *name; + zend_string *name; zend_string *cfilename; char haltoff[] = "__COMPILER_HALT_OFFSET__"; - int len; if (CG(has_bracketed_namespaces) && CG(in_namespace)) { zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } cfilename = zend_get_compiled_filename(TSRMLS_C); - zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename->val, cfilename->len, 0); - zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC); - pefree(name, 0); + name = zend_mangle_property_name(haltoff, sizeof(haltoff) - 1, cfilename->val, cfilename->len, 0); + zend_register_long_constant(name->val, name->len, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC); + STR_FREE(name); if (CG(in_namespace)) { zend_do_end_namespace(TSRMLS_C); @@ -6787,8 +6819,10 @@ int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global } /* }}} */ -static int zend_auto_global_init(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */ +static int zend_auto_global_init(zval *zv TSRMLS_DC) /* {{{ */ { + zend_auto_global *auto_global = Z_PTR_P(zv); + if (auto_global->jit) { auto_global->armed = 1; } else if (auto_global->auto_global_callback) { |