Browse Source

Fix a bug in inheritence from classes defined in include files, that are

inherited from require()'d files
experimetnal/RETURN_REF_PATCH
Zeev Suraski 27 years ago
parent
commit
41308d4b43
  1. 36
      Zend/zend_compile.c
  2. 2
      Zend/zend_compile.h
  3. 2
      Zend/zend_execute.c

36
Zend/zend_compile.c

@ -874,7 +874,7 @@ static void function_add_ref(zend_function *function)
}
ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table)
ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table, int allow_failure)
{
switch (opline->extended_value) {
case ZEND_DECLARE_FUNCTION: {
@ -883,7 +883,12 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
zend_hash_index_find(function_table, opline->op1.u.constant.value.lval, (void **) &function);
(*function->op_array.refcount)++;
if (zend_hash_add(function_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, function, sizeof(zend_function), NULL)==FAILURE) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare %s()", opline->op2.u.constant.value.str.val);
if (!allow_failure) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare %s()", opline->op2.u.constant.value.str.val);
}
return FAILURE;
} else {
return SUCCESS;
}
}
break;
@ -893,7 +898,12 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
zend_hash_index_find(class_table, opline->op1.u.constant.value.lval, (void **) &ce);
(*ce->refcount)++;
if (zend_hash_add(class_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, ce, sizeof(zend_class_entry), NULL)==FAILURE) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
if (!allow_failure) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
}
return FAILURE;
} else {
return SUCCESS;
}
}
break;
@ -916,7 +926,12 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
/* Obtain parent class */
if (zend_hash_find(class_table, parent_name, strlen(parent_name)+1, (void **) &parent_ce)==FAILURE) {
zend_error(E_COMPILE_ERROR, "Class %s: Cannot inherit from undefined class %s", class_name, parent_name);
if (!allow_failure) {
zend_error(E_COMPILE_ERROR, "Class %s: Cannot inherit from undefined class %s", class_name, parent_name);
}
(*ce->refcount)--;
*(class_name-1) = ':';
return FAILURE;
}
/* Perform inheritence */
@ -925,8 +940,15 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
/* Register the derived class */
if (zend_hash_add(class_table, class_name, strlen(class_name)+1, ce, sizeof(zend_class_entry), NULL)==FAILURE) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
if (allow_failure) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
}
(*ce->refcount)--;
zend_hash_destroy(&ce->function_table);
zend_hash_destroy(&ce->default_properties);
return FAILURE;
}
return SUCCESS;
}
break;
}
@ -937,7 +959,9 @@ void do_early_binding(CLS_D)
{
zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
do_bind_function_or_class(opline, CG(function_table), CG(class_table));
if (do_bind_function_or_class(opline, CG(function_table), CG(class_table), 1)==FAILURE) {
return;
}
switch (opline->extended_value) {
case ZEND_DECLARE_FUNCTION:
zend_hash_index_del(CG(function_table), opline->op1.u.constant.value.lval);

2
Zend/zend_compile.h

@ -265,7 +265,7 @@ void do_begin_dynamic_function_call(znode *function_name CLS_DC);
void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC);
void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method CLS_DC);
void do_return(znode *expr CLS_DC);
ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table);
ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table, int allow_failure);
void do_early_binding(CLS_D);
void do_pass_param(znode *param, int op, int offset CLS_DC);

2
Zend/zend_execute.c

@ -2026,7 +2026,7 @@ send_by_ref:
}
break;
case ZEND_DECLARE_FUNCTION_OR_CLASS:
do_bind_function_or_class(opline, EG(function_table), EG(class_table));
do_bind_function_or_class(opline, EG(function_table), EG(class_table), 0);
break;
case ZEND_EXT_NOP:
case ZEND_NOP:

Loading…
Cancel
Save