summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_compile.c27
-rw-r--r--Zend/zend_constants.c34
-rw-r--r--Zend/zend_execute_API.c13
-rw-r--r--Zend/zend_types.h1
-rw-r--r--Zend/zend_vm_def.h11
-rw-r--r--Zend/zend_vm_execute.h62
-rw-r--r--Zend/zend_vm_opcodes.c2
-rw-r--r--Zend/zend_vm_opcodes.h1
8 files changed, 82 insertions, 69 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f2de2c74d8..962bb14b42 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5975,6 +5975,22 @@ void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
return;
}
+ if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__")) {
+ zend_ast *last = CG(ast);
+
+ while (last->kind == ZEND_AST_STMT_LIST) {
+ zend_ast_list *list = zend_ast_get_list(last);
+ last = list->child[list->children-1];
+ }
+ if (last->kind == ZEND_AST_HALT_COMPILER) {
+ result->op_type = IS_CONST;
+ ZVAL_LONG(&result->u.constant,
+ Z_LVAL_P(zend_ast_get_zval(last->child[0])));
+ zend_string_release(resolved_name);
+ return;
+ }
+ }
+
opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL);
opline->op2_type = IS_CONST;
@@ -6161,12 +6177,7 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
CG(active_class_entry) &&
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
- {
- zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST,
- zend_ast_create_zval_from_str(zend_string_init("__CLASS__", sizeof("__CLASS__") - 1, 0)));
- zend_compile_const(result, const_ast);
- zend_ast_destroy(const_ast);
- }
+ zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
}
/* }}} */
@@ -6298,8 +6309,8 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
{
zval const_zv;
- ZVAL_STRING(&const_zv, "__CLASS__");
- Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX;
+ Z_STR(const_zv) = zend_string_init("__CLASS__", sizeof("__CLASS__")-1, 0);
+ Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX | (IS_CONSTANT_CLASS << Z_CONST_FLAGS_SHIFT);
zend_ast_destroy(ast);
*ast_ptr = zend_ast_create_zval(&const_zv);
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index 4ca7ef4571..bf4e26a0e8 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -231,36 +231,6 @@ static zend_constant *zend_get_special_constant(const char *name, size_t name_le
if (!EG(current_execute_data)) {
return NULL;
- } else if (name_len == sizeof("__CLASS__")-1 &&
- !memcmp(name, "__CLASS__", sizeof("__CLASS__")-1)) {
-
- /* Returned constants may be cached, so they have to be stored */
- if (EG(scope) && EG(scope)->name) {
- size_t const_name_len;
- zend_string *const_name;
-
- const_name_len = sizeof("\0__CLASS__") + EG(scope)->name->len;
- const_name = zend_string_alloc(const_name_len, 0);
- memcpy(const_name->val, "\0__CLASS__", sizeof("\0__CLASS__")-1);
- zend_str_tolower_copy(const_name->val + sizeof("\0__CLASS__")-1, EG(scope)->name->val, EG(scope)->name->len);
- if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
- c = emalloc(sizeof(zend_constant));
- memset(c, 0, sizeof(zend_constant));
- ZVAL_STR_COPY(&c->value, EG(scope)->name);
- zend_hash_add_ptr(EG(zend_constants), const_name, c);
- }
- zend_string_release(const_name);
- } else {
- zend_string *const_name = zend_string_init("\0__CLASS__", sizeof("\0__CLASS__")-1, 0);
- if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
- c = emalloc(sizeof(zend_constant));
- memset(c, 0, sizeof(zend_constant));
- ZVAL_EMPTY_STRING(&c->value);
- zend_hash_add_ptr(EG(zend_constants), const_name, c);
- }
- zend_string_release(const_name);
- }
- return c;
} else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
!memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
const char *cfilename;
@@ -465,12 +435,12 @@ zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags)
(c->flags & CONST_CS) != 0) {
key--;
- c = zend_get_special_constant(Z_STRVAL_P(key), Z_STRLEN_P(key));
+ c = NULL;
}
}
} else {
key--;
- c = zend_get_special_constant(Z_STRVAL_P(key), Z_STRLEN_P(key));
+ c = NULL;
}
}
}
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index c3bd69a5b1..556e5c60e1 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -535,8 +535,17 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
SEPARATE_ZVAL_NOREF(p);
MARK_CONSTANT_VISITED(p);
refcount = Z_REFCOUNTED_P(p) ? Z_REFCOUNT_P(p) : 1;
- const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p));
- if (!const_value) {
+ if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) {
+ ZEND_ASSERT(EG(current_execute_data));
+ if (inline_change) {
+ zend_string_release(Z_STR_P(p));
+ }
+ if (EG(scope) && EG(scope)->name) {
+ ZVAL_STR_COPY(p, EG(scope)->name);
+ } else {
+ ZVAL_EMPTY_STRING(p);
+ }
+ } else if ((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL) {
char *actual = Z_STRVAL_P(p);
if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 3f1258f7bf..0cfd8fca90 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -389,6 +389,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define IS_CONSTANT_UNQUALIFIED 0x010
#define IS_LEXICAL_VAR 0x020
#define IS_LEXICAL_REF 0x040
+#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */
#define IS_CONSTANT_IN_NAMESPACE 0x100 /* used only in opline->extended_value */
/* zval.u2.var_flags */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 995fabc17d..ab2c7b89a3 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -7363,3 +7363,14 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY)
}
}
+ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY)
+{
+ USE_OPLINE
+
+ if (EG(scope) && EG(scope)->name) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+ } else {
+ ZVAL_EMPTY_STRING(EX_VAR(opline->result.var));
+ }
+ ZEND_VM_NEXT_OPCODE();
+} \ No newline at end of file
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 3f7defc088..e5547f3e1e 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1779,7 +1779,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
}
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ if (EG(scope) && EG(scope)->name) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+ } else {
+ ZVAL_EMPTY_STRING(EX_VAR(opline->result.var));
+ }
+ ZEND_VM_NEXT_OPCODE();
+}static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -45490,31 +45500,31 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+ ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 9bc531634d..d464b9ba50 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -179,7 +179,7 @@ const char *zend_vm_opcodes_map[171] = {
"ZEND_ADD_TRAIT",
"ZEND_BIND_TRAITS",
"ZEND_SEPARATE",
- NULL,
+ "ZEND_FETCH_CLASS_NAME",
NULL,
"ZEND_DISCARD_EXCEPTION",
"ZEND_YIELD",
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 3965740fb2..86fe5590d6 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -186,6 +186,7 @@ END_EXTERN_C()
#define ZEND_ADD_TRAIT 154
#define ZEND_BIND_TRAITS 155
#define ZEND_SEPARATE 156
+#define ZEND_FETCH_CLASS_NAME 157
#define ZEND_DISCARD_EXCEPTION 159
#define ZEND_YIELD 160
#define ZEND_GENERATOR_RETURN 161