- Add constructor to the zend_class_entry instead of looking it up each

- time by name.
- This will allow the next patch of being able to instantiate nested
- classes such as new foo::bar::barbara();
This commit is contained in:
Andi Gutmans 2001-11-03 11:59:14 +00:00
parent 02293b6bee
commit b87194e0c6
3 changed files with 27 additions and 8 deletions

View File

@ -267,6 +267,9 @@ typedef struct _zend_overloaded_element {
/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table
/* A lot of stuff needs shifiting around in order to include zend_compile.h here */
union _zend_function;
struct _zend_class_entry {
char type;
char *name;
@ -280,6 +283,8 @@ struct _zend_class_entry {
HashTable class_table;
zend_function_entry *builtin_functions;
union _zend_function *constructor;
/* handlers */
void (*handle_function_call)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
zval (*handle_property_get)(zend_property_reference *property_reference);

View File

@ -729,6 +729,9 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
if (is_method) {
zend_hash_update(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
if ((CG(active_class_entry)->name_length == (uint) name_len) && (!memcmp(CG(active_class_entry)->name, name, name_len))) {
CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
}
} else {
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@ -1701,6 +1704,8 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
/* copy default properties */
zend_hash_copy(&new_class_entry.default_properties, &parent_class->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
new_class_entry.constructor = parent_class->constructor;
/* copy overloaded handlers */
new_class_entry.handle_function_call = parent_class->handle_function_call;
new_class_entry.handle_property_get = parent_class->handle_property_get;
@ -1834,14 +1839,12 @@ void zend_do_begin_new_object(znode *new_token, znode *class_name TSRMLS_DC)
opline->op1 = (opline-1)->result;
SET_UNUSED(opline->op2);
if (class_name->op_type == IS_CONST) {
zval_copy_ctor(&class_name->u.constant);
}
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
opline->op1 = (opline-2)->result;
opline->op2 = *class_name;
SET_UNUSED(opline->op2);
opline->extended_value = ZEND_MEMBER_FUNC_CALL | ZEND_CTOR_CALL;
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
}

View File

@ -1510,9 +1510,21 @@ binary_assign_op_addr: {
if (EX(opline)->op1.op_type == IS_VAR) {
SELECTIVE_PZVAL_LOCK(*EX(Ts)[EX(opline)->op1.u.var].var.ptr_ptr, &EX(opline)->op1);
}
if (EX(opline)->op2.op_type == IS_VAR) {
PZVAL_LOCK(*EX(Ts)[EX(opline)->op2.u.var].var.ptr_ptr);
/* We are not handling overloaded classes right now */
EX(object).ptr = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
if (!PZVAL_IS_REF(EX(object).ptr)) {
EX(object).ptr->refcount++; /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
*this_ptr = *EX(object).ptr;
INIT_PZVAL(this_ptr);
zval_copy_ctor(this_ptr);
EX(object).ptr = this_ptr;
}
EX(fbc) = Z_OBJCE_P(EX(object).ptr)->constructor;
NEXT_OPCODE();
}
function_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
@ -2452,8 +2464,7 @@ send_by_ref:
object_zval = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
object = object_zval->value.obj.handlers->get_address(object_zval->value.obj.handle);
if (!object->ce->handle_function_call
&& !zend_hash_exists(&object->ce->function_table, object->ce->name, object->ce->name_length+1)) {
if (!object->ce->handle_function_call && !object->ce->constructor) {
EX(opline) = op_array->opcodes + EX(opline)->op2.u.opline_num;
continue;
}