mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Introduced BIND_STATIC opcode instead of FETCH_R/FETCH_W(static)+ASSIGN/ASSIGN_REF (similar to BIND_GLOBAL).
In the future we may refer to static variable by index instead of name, to eliminate hash lookup.
This commit is contained in:
parent
1234e2eb21
commit
6579e48417
@ -3746,16 +3746,10 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_
|
||||
}
|
||||
zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value);
|
||||
|
||||
opline = zend_emit_op(&result, by_ref ? ZEND_FETCH_W : ZEND_FETCH_R, &var_node, NULL);
|
||||
opline->extended_value = ZEND_FETCH_STATIC;
|
||||
|
||||
if (by_ref) {
|
||||
zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast);
|
||||
zend_emit_assign_ref_znode(fetch_ast, &result);
|
||||
} else {
|
||||
zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast);
|
||||
zend_emit_assign_znode(fetch_ast, &result);
|
||||
}
|
||||
opline = zend_emit_op(NULL, ZEND_BIND_STATIC, NULL, &var_node);
|
||||
opline->op1_type = IS_CV;
|
||||
opline->op1.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR(var_node.u.constant)));
|
||||
opline->extended_value = by_ref;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -890,7 +890,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
|
||||
/* global/local fetches */
|
||||
#define ZEND_FETCH_GLOBAL 0x00000000
|
||||
#define ZEND_FETCH_LOCAL 0x10000000
|
||||
#define ZEND_FETCH_STATIC 0x20000000
|
||||
#define ZEND_FETCH_GLOBAL_LOCK 0x40000000
|
||||
|
||||
#define ZEND_FETCH_TYPE_MASK 0x70000000
|
||||
|
@ -1537,15 +1537,6 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
|
||||
if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
|
||||
EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
|
||||
ht = &EG(symbol_table);
|
||||
} else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
|
||||
ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
if (GC_REFCOUNT(ht) > 1) {
|
||||
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(ht)--;
|
||||
}
|
||||
EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
|
||||
}
|
||||
} else {
|
||||
ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
|
||||
if (!EX(symbol_table)) {
|
||||
|
@ -1474,14 +1474,7 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
|
||||
}
|
||||
}
|
||||
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
|
||||
if (Z_CONSTANT_P(retval)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
|
||||
FREE_OP1();
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
} else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
FREE_OP1();
|
||||
}
|
||||
|
||||
@ -8028,4 +8021,55 @@ ZEND_VM_HANDLER(182, ZEND_BIND_LEXICAL, TMP, CV, REF)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_free_op free_op1, free_op2;
|
||||
HashTable *ht;
|
||||
zval *varname;
|
||||
zval *value;
|
||||
zval *variable_ptr;
|
||||
|
||||
SAVE_OPLINE();
|
||||
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
|
||||
zval_ptr_dtor(variable_ptr);
|
||||
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
ZEND_ASSERT(ht != NULL);
|
||||
if (GC_REFCOUNT(ht) > 1) {
|
||||
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(ht)--;
|
||||
}
|
||||
EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
|
||||
}
|
||||
|
||||
varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
value = zend_hash_find(ht, Z_STR_P(varname));
|
||||
|
||||
if (opline->extended_value) {
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) {
|
||||
ZVAL_NULL(variable_ptr);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
if (UNEXPECTED(!Z_ISREF_P(value))) {
|
||||
zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
|
||||
GC_REFCOUNT(ref) = 2;
|
||||
GC_TYPE_INFO(ref) = IS_REFERENCE;
|
||||
ZVAL_COPY_VALUE(&ref->val, value);
|
||||
Z_REF_P(value) = ref;
|
||||
Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
|
||||
ZVAL_REF(variable_ptr, ref);
|
||||
} else {
|
||||
Z_ADDREF_P(value);
|
||||
ZVAL_REF(variable_ptr, Z_REF_P(value));
|
||||
}
|
||||
} else {
|
||||
ZVAL_COPY(variable_ptr, value);
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
|
||||
|
@ -7199,14 +7199,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
|
||||
}
|
||||
}
|
||||
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
|
||||
if (Z_CONSTANT_P(retval)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
} else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
|
||||
}
|
||||
|
||||
@ -32486,6 +32479,57 @@ check_indirect:
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
HashTable *ht;
|
||||
zval *varname;
|
||||
zval *value;
|
||||
zval *variable_ptr;
|
||||
|
||||
SAVE_OPLINE();
|
||||
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var);
|
||||
zval_ptr_dtor(variable_ptr);
|
||||
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
ZEND_ASSERT(ht != NULL);
|
||||
if (GC_REFCOUNT(ht) > 1) {
|
||||
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(ht)--;
|
||||
}
|
||||
EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
|
||||
}
|
||||
|
||||
varname = EX_CONSTANT(opline->op2);
|
||||
value = zend_hash_find(ht, Z_STR_P(varname));
|
||||
|
||||
if (opline->extended_value) {
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) {
|
||||
ZVAL_NULL(variable_ptr);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
if (UNEXPECTED(!Z_ISREF_P(value))) {
|
||||
zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
|
||||
GC_REFCOUNT(ref) = 2;
|
||||
GC_TYPE_INFO(ref) = IS_REFERENCE;
|
||||
ZVAL_COPY_VALUE(&ref->val, value);
|
||||
Z_REF_P(value) = ref;
|
||||
Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
|
||||
ZVAL_REF(variable_ptr, ref);
|
||||
} else {
|
||||
Z_ADDREF_P(value);
|
||||
ZVAL_REF(variable_ptr, Z_REF_P(value));
|
||||
}
|
||||
} else {
|
||||
ZVAL_COPY(variable_ptr, value);
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -33627,14 +33671,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
|
||||
}
|
||||
}
|
||||
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
|
||||
if (Z_CONSTANT_P(retval)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
} else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
|
||||
}
|
||||
|
||||
@ -42016,14 +42053,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
|
||||
}
|
||||
}
|
||||
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
|
||||
if (Z_CONSTANT_P(retval)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(free_op1);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
} else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
|
||||
zval_ptr_dtor_nogc(free_op1);
|
||||
}
|
||||
|
||||
@ -49390,6 +49420,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_BIND_STATIC_SPEC_CV_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER
|
||||
};
|
||||
zend_opcode_handlers = labels;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <stdio.h>
|
||||
#include <zend.h>
|
||||
|
||||
static const char *zend_vm_opcodes_names[183] = {
|
||||
static const char *zend_vm_opcodes_names[184] = {
|
||||
"ZEND_NOP",
|
||||
"ZEND_ADD",
|
||||
"ZEND_SUB",
|
||||
@ -205,9 +205,10 @@ static const char *zend_vm_opcodes_names[183] = {
|
||||
"ZEND_ISSET_ISEMPTY_STATIC_PROP",
|
||||
"ZEND_FETCH_CLASS_CONSTANT",
|
||||
"ZEND_BIND_LEXICAL",
|
||||
"ZEND_BIND_STATIC",
|
||||
};
|
||||
|
||||
static uint32_t zend_vm_opcodes_flags[183] = {
|
||||
static uint32_t zend_vm_opcodes_flags[184] = {
|
||||
0x00000000,
|
||||
0x00000707,
|
||||
0x00000707,
|
||||
@ -391,6 +392,7 @@ static uint32_t zend_vm_opcodes_flags[183] = {
|
||||
0x00027307,
|
||||
0x00000373,
|
||||
0x00100101,
|
||||
0x00100301,
|
||||
};
|
||||
|
||||
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
|
||||
|
@ -255,7 +255,8 @@ END_EXTERN_C()
|
||||
#define ZEND_ISSET_ISEMPTY_STATIC_PROP 180
|
||||
#define ZEND_FETCH_CLASS_CONSTANT 181
|
||||
#define ZEND_BIND_LEXICAL 182
|
||||
#define ZEND_BIND_STATIC 183
|
||||
|
||||
#define ZEND_VM_LAST_OPCODE 182
|
||||
#define ZEND_VM_LAST_OPCODE 183
|
||||
|
||||
#endif
|
||||
|
@ -92,6 +92,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
|
||||
case ZEND_ASSIGN:
|
||||
case ZEND_ASSIGN_REF:
|
||||
case ZEND_BIND_GLOBAL:
|
||||
case ZEND_BIND_STATIC:
|
||||
case ZEND_SEND_VAR_EX:
|
||||
case ZEND_SEND_REF:
|
||||
case ZEND_SEND_VAR_NO_REF:
|
||||
|
@ -510,9 +510,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
|
||||
case ZEND_FETCH_LOCAL:
|
||||
fprintf(stderr, " (local)");
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
fprintf(stderr, " (static)");
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
fprintf(stderr, " (global+lock)");
|
||||
break;
|
||||
|
@ -3067,6 +3067,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
|
||||
}
|
||||
break;
|
||||
case ZEND_BIND_GLOBAL:
|
||||
case ZEND_BIND_STATIC:
|
||||
tmp = (MAY_BE_REF | MAY_BE_ANY );
|
||||
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
|
||||
break;
|
||||
|
@ -275,6 +275,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
|
||||
}
|
||||
break;
|
||||
case ZEND_BIND_GLOBAL:
|
||||
case ZEND_BIND_STATIC:
|
||||
if (opline->op1_type == IS_CV) {
|
||||
ssa_ops[k].op1_def = ssa_vars_count;
|
||||
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
|
||||
|
Loading…
Reference in New Issue
Block a user