summaryrefslogtreecommitdiff
path: root/Zend/zend_opcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_opcode.c')
-rw-r--r--Zend/zend_opcode.c105
1 files changed, 66 insertions, 39 deletions
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index fe1d95737a..1566ee34cf 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -110,6 +110,23 @@ ZEND_API void destroy_zend_function(zend_function *function)
ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
ZEND_ASSERT(function->common.function_name);
zend_string_release(function->common.function_name);
+
+ if (function->common.arg_info &&
+ (function->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))) {
+ uint32_t i;
+ uint32_t num_args = function->common.num_args + 1;
+ zend_arg_info *arg_info = function->common.arg_info - 1;
+
+ if (function->common.fn_flags & ZEND_ACC_VARIADIC) {
+ num_args++;
+ }
+ for (i = 0 ; i < num_args; i++) {
+ if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
+ zend_string_release(ZEND_TYPE_NAME(arg_info[i].type));
+ }
+ }
+ free(arg_info);
+ }
}
}
@@ -125,47 +142,28 @@ ZEND_API void zend_function_dtor(zval *zv)
ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
ZEND_ASSERT(function->common.function_name);
zend_string_release(function->common.function_name);
- if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
- pefree(function, 1);
- }
- }
-}
+#ifndef ZTS
+ if ((function->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
+ !function->common.scope && function->common.arg_info) {
-ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array)
-{
- if (op_array->static_variables &&
- !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
- zend_hash_clean(op_array->static_variables);
- }
-}
+ uint32_t i;
+ uint32_t num_args = function->common.num_args + 1;
+ zend_arg_info *arg_info = function->common.arg_info - 1;
-ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce)
-{
- /* 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
- not contain objects and thus are not probelmatic */
- if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
- zend_function *func;
-
- ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
- if (func->type == ZEND_USER_FUNCTION) {
- zend_cleanup_op_array_data((zend_op_array *) func);
+ if (function->common.fn_flags & ZEND_ACC_VARIADIC) {
+ num_args++;
}
- } ZEND_HASH_FOREACH_END();
- }
- if (ce->static_members_table) {
- zval *static_members = ce->static_members_table;
- zval *p = static_members;
- zval *end = p + ce->default_static_members_count;
-
-
- ce->default_static_members_count = 0;
- ce->default_static_members_table = ce->static_members_table = NULL;
- while (p != end) {
- i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
- p++;
+ for (i = 0 ; i < num_args; i++) {
+ if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
+ zend_string_release(ZEND_TYPE_NAME(arg_info[i].type));
+ }
+ }
+ free(arg_info);
+ }
+#endif
+ if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
+ pefree(function, 1);
}
- efree(static_members);
}
}
@@ -248,6 +246,9 @@ ZEND_API void destroy_zend_class(zval *zv)
{
zend_property_info *prop_info;
zend_class_entry *ce = Z_PTR_P(zv);
+#ifndef ZTS
+ zend_function *fn;
+#endif
if (--ce->refcount > 0) {
return;
@@ -331,6 +332,15 @@ ZEND_API void destroy_zend_class(zval *zv)
}
zend_hash_destroy(&ce->properties_info);
zend_string_release(ce->name);
+#ifndef ZTS
+ ZEND_HASH_FOREACH_PTR(&ce->function_table, fn) {
+ if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
+ fn->common.scope == ce) {
+ /* reset function scope to allow arg_info removing */
+ fn->common.scope = NULL;
+ }
+ } ZEND_HASH_FOREACH_END();
+#endif
zend_hash_destroy(&ce->function_table);
if (zend_hash_num_elements(&ce->constants_table)) {
zend_class_constant *c;
@@ -433,8 +443,8 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
if (arg_info[i].name) {
zend_string_release(arg_info[i].name);
}
- if (arg_info[i].class_name) {
- zend_string_release(arg_info[i].class_name);
+ if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
+ zend_string_release(ZEND_TYPE_NAME(arg_info[i].type));
}
}
efree(arg_info);
@@ -646,6 +656,19 @@ ZEND_API int pass_two(zend_op_array *op_array)
opline->opcode = ZEND_GENERATOR_RETURN;
}
break;
+ case ZEND_SWITCH_LONG:
+ case ZEND_SWITCH_STRING:
+ {
+ /* absolute indexes to relative offsets */
+ HashTable *jumptable = Z_ARRVAL_P(CT_CONSTANT(opline->op2));
+ zval *zv;
+ ZEND_HASH_FOREACH_VAL(jumptable, zv) {
+ Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, Z_LVAL_P(zv));
+ } ZEND_HASH_FOREACH_END();
+
+ opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
+ break;
+ }
}
if (opline->op1_type == IS_CONST) {
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
@@ -703,6 +726,7 @@ ZEND_API binary_op_type get_binary_op(int opcode)
case ZEND_ASSIGN_MUL:
return (binary_op_type) mul_function;
case ZEND_POW:
+ case ZEND_ASSIGN_POW:
return (binary_op_type) pow_function;
case ZEND_DIV:
case ZEND_ASSIGN_DIV:
@@ -725,6 +749,7 @@ ZEND_API binary_op_type get_binary_op(int opcode)
case ZEND_IS_NOT_IDENTICAL:
return (binary_op_type) is_not_identical_function;
case ZEND_IS_EQUAL:
+ case ZEND_CASE:
return (binary_op_type) is_equal_function;
case ZEND_IS_NOT_EQUAL:
return (binary_op_type) is_not_equal_function;
@@ -756,4 +781,6 @@ ZEND_API binary_op_type get_binary_op(int opcode)
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
*/