From: Andi Gutmans Date: Sat, 3 Nov 2001 11:59:14 +0000 (+0000) Subject: - Add constructor to the zend_class_entry instead of looking it up each X-Git-Tag: ChangeLog~437 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b87194e0c67cdc2ccc2ea2146cc815b4d4126a6b;p=php - 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(); --- diff --git a/Zend/zend.h b/Zend/zend.h index 4b055d8ace..4f3feabc3f 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -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); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 0c7ae5c161..9d31e099cc 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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 *)); } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index aed95cef97..d63a13e21c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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; }