diff options
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c1596ac3ef..5c6b4a9144 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -937,6 +937,25 @@ void do_fetch_class(znode *result, znode *class_entry, znode *class_name TSRMLS_ *result = opline->result; } + +void do_fetch_class_name(znode *result, znode *class_name_entry, znode *class_name TSRMLS_DC) +{ + zend_uint length; + + if (!result) { + result = class_name_entry; + } else { + *result = *class_name_entry; + } + + length = 1 + result->u.constant.value.str.len + class_name->u.constant.value.str.len; + result->u.constant.value.str.val = erealloc(result->u.constant.value.str.val, length+1); + memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len], ":", sizeof(":")-1); + memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len+1], class_name->u.constant.value.str.val, class_name->u.constant.value.str.len+1); + STR_FREE(class_name->u.constant.value.str.val); + result->u.constant.value.str.len = length; +} + void zend_do_begin_class_member_function_call(znode *class_name, znode *function_name TSRMLS_DC) { unsigned char *ptr = NULL; @@ -1265,6 +1284,7 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce) zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); /* STATIC_MEMBERS_FIXME */ zend_hash_merge(&ce->static_members, &parent_ce->static_members, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); + zend_hash_merge(&ce->constants, &parent_ce->constants, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); zend_hash_merge(&ce->function_table, &parent_ce->function_table, (void (*)(void *)) function_add_ref, &tmp_zend_function, sizeof(zend_function), 0); ce->parent = parent_ce; if (!ce->handle_property_get) @@ -1372,6 +1392,7 @@ ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_tabl zend_hash_destroy(&ce->function_table); zend_hash_destroy(&ce->default_properties); zend_hash_destroy(&ce->static_members); + zend_hash_destroy(&ce->constants); return FAILURE; } return SUCCESS; @@ -1704,6 +1725,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod zend_hash_init(&new_class_entry.class_table, 10, NULL, ZEND_CLASS_DTOR, 0); zend_hash_init(&new_class_entry.default_properties, 10, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(&new_class_entry.constants, 10, NULL, ZVAL_PTR_DTOR, 0); new_class_entry.constructor = NULL; @@ -1731,6 +1753,9 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod /* copy static members */ zend_hash_copy(&new_class_entry.static_members, &parent_class->static_members, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + /* copy constants */ + zend_hash_copy(&new_class_entry.constants, &parent_class->constants, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + new_class_entry.constructor = parent_class->constructor; /* copy overloaded handlers */ @@ -1808,10 +1833,16 @@ void zend_do_declare_property(znode *var_name, znode *value, int declaration_typ ALLOC_ZVAL(property); *property = value->u.constant; - if (declaration_type == T_VAR) { - zend_hash_update(&CG(active_class_entry)->default_properties, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); - } else { - zend_hash_update(&CG(active_class_entry)->static_members, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); + switch (declaration_type) { + case T_VAR: + zend_hash_update(&CG(active_class_entry)->default_properties, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); + break; + case T_STATIC: + zend_hash_update(&CG(active_class_entry)->static_members, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); + break; + case T_CONST: + zend_hash_update(&CG(active_class_entry)->constants, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); + break; } } FREE_PNODE(var_name); @@ -1892,22 +1923,32 @@ void zend_do_end_new_object(znode *result, znode *new_token, znode *argument_lis } -void zend_do_fetch_constant(znode *result, znode *constant_name, int mode TSRMLS_DC) +void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode TSRMLS_DC) { switch (mode) { case ZEND_CT: - *result = *constant_name; + if (constant_container) { + do_fetch_class_name(NULL, constant_container, constant_name TSRMLS_CC); + *result = *constant_container; + } else { + *result = *constant_name; + } result->u.constant.type = IS_CONSTANT; break; - case ZEND_RT: { + case ZEND_RT: + { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_FETCH_CONSTANT; opline->result.op_type = IS_TMP_VAR; opline->result.u.var = get_temporary_variable(CG(active_op_array)); - opline->op1 = *constant_name; + if (constant_container) { + opline->op1 = *constant_container; + } else { + SET_UNUSED(opline->op1); + } + opline->op2 = *constant_name; *result = opline->result; - SET_UNUSED(opline->op2); } break; } |