summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend.c2
-rw-r--r--Zend/zend_compile.c46
-rw-r--r--Zend/zend_globals.h2
3 files changed, 23 insertions, 27 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index d85135d287..3561b36af1 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -524,6 +524,8 @@ static void zend_set_default_compile_time_values(void) /* {{{ */
/* default compile-time values */
CG(short_tags) = short_tags_default;
CG(compiler_options) = compiler_options_default;
+
+ CG(rtd_key_counter) = 0;
}
/* }}} */
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 311d3d2727..43edd438bb 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -132,16 +132,11 @@ static void zend_destroy_property_info_internal(zval *zv) /* {{{ */
}
/* }}} */
-static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigned char *lex_pos) /* {{{ */
+static zend_string *zend_build_runtime_definition_key(zend_string *name, uint32_t start_lineno) /* {{{ */
{
- zend_string *result;
- char char_pos_buf[32];
- size_t char_pos_len = sprintf(char_pos_buf, "%p", lex_pos);
zend_string *filename = CG(active_op_array)->filename;
-
- /* NULL, name length, filename length, last accepting char position length */
- result = zend_string_alloc(1 + ZSTR_LEN(name) + ZSTR_LEN(filename) + char_pos_len, 0);
- sprintf(ZSTR_VAL(result), "%c%s%s%s", '\0', ZSTR_VAL(name), ZSTR_VAL(filename), char_pos_buf);
+ zend_string *result = zend_strpprintf(0, "%c%s%s:%" PRIu32 "$%" PRIx32,
+ '\0', ZSTR_VAL(name), ZSTR_VAL(filename), start_lineno, CG(rtd_key_counter)++);
return zend_new_interned_string(result);
}
/* }}} */
@@ -6124,8 +6119,11 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
return;
}
- key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
- zend_hash_update_ptr(CG(function_table), key, op_array);
+ key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
+ if (!zend_hash_add_ptr(CG(function_table), key, op_array)) {
+ zend_error_noreturn(E_ERROR,
+ "Runtime definition key collision for function %s. This is a bug", ZSTR_VAL(name));
+ }
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
@@ -6529,16 +6527,11 @@ void zend_compile_implements(zend_ast *ast) /* {{{ */
}
/* }}} */
-static zend_string *zend_generate_anon_class_name(unsigned char *lex_pos) /* {{{ */
+static zend_string *zend_generate_anon_class_name(uint32_t start_lineno) /* {{{ */
{
- zend_string *result;
- char char_pos_buf[32];
- size_t char_pos_len = sprintf(char_pos_buf, "%p", lex_pos);
zend_string *filename = CG(active_op_array)->filename;
-
- /* NULL, name length, filename length, last accepting char position length */
- result = zend_string_alloc(sizeof("class@anonymous") + ZSTR_LEN(filename) + char_pos_len, 0);
- sprintf(ZSTR_VAL(result), "class@anonymous%c%s%s", '\0', ZSTR_VAL(filename), char_pos_buf);
+ zend_string *result = zend_strpprintf(0, "class@anonymous%c%s:%" PRIu32 "$%" PRIx32,
+ '\0', ZSTR_VAL(filename), start_lineno, CG(rtd_key_counter)++);
return zend_new_interned_string(result);
}
/* }}} */
@@ -6578,7 +6571,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS);
} else {
- name = zend_generate_anon_class_name(decl->lex_pos);
+ name = zend_generate_anon_class_name(decl->start_lineno);
lcname = zend_string_tolower(name);
}
lcname = zend_new_interned_string(lcname);
@@ -6728,20 +6721,19 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
opline->extended_value = zend_alloc_cache_slot();
opline->result_type = IS_VAR;
opline->result.var = get_temporary_variable();
-
if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) {
- /* this anonymous class has been included */
- zval zv;
- ZVAL_PTR(&zv, ce);
- destroy_zend_class(&zv);
- return opline;
+ zend_error_noreturn(E_ERROR,
+ "Runtime definition key collision for %s. This is a bug", ZSTR_VAL(name));
}
} else {
- zend_string *key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
+ zend_string *key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
/* RTD key is placed after lcname literal in op1 */
zend_add_literal_string(&key);
- zend_hash_update_ptr(CG(class_table), key, ce);
+ if (!zend_hash_add_ptr(CG(class_table), key, ce)) {
+ zend_error_noreturn(E_ERROR,
+ "Runtime definition key collision for class %s. This is a bug", ZSTR_VAL(name));
+ }
opline->opcode = ZEND_DECLARE_CLASS;
if (extends_ast && toplevel
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 9a55924f42..2dc769a5ef 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -127,6 +127,8 @@ struct _zend_compiler_globals {
HashTable *delayed_variance_obligations;
HashTable *delayed_autoloads;
+
+ uint32_t rtd_key_counter;
};