]> granicus.if.org Git - php/commitdiff
fix __clone
authorStanislav Malyshev <stas@php.net>
Mon, 19 May 2003 17:12:56 +0000 (17:12 +0000)
committerStanislav Malyshev <stas@php.net>
Mon, 19 May 2003 17:12:56 +0000 (17:12 +0000)
Zend/zend_compile.c
Zend/zend_execute.c

index 5bdffcbacd2d4fdacbd2f2bd46a47020ecde221d..9d1db6ec520af0e355f90dcd74a7681242ce9937 100644 (file)
@@ -1215,7 +1215,10 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC)
        if ((last_op->op2.op_type == IS_CONST) && (last_op->op2.u.constant.value.str.len == sizeof(ZEND_CLONE_FUNC_NAME)-1)
                && !memcmp(last_op->op2.u.constant.value.str.val, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME))) {
                last_op->opcode = ZEND_CLONE;
-               left_bracket->u.constant.value.lval = ZEND_CLONE;
+               left_bracket->op_type = IS_UNUSED;
+               zval_dtor(&last_op->op2.u.constant); 
+               SET_UNUSED(last_op->op2);
+               left_bracket->u.constant.value.lval = get_next_op_number(CG(active_op_array))-1;
                zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
                zend_do_extended_fcall_begin(TSRMLS_C); 
                return;
@@ -1328,14 +1331,22 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum
 {
        zend_op *opline;
 
-       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
-       if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
-               opline->opcode = ZEND_DO_FCALL;
-               opline->op1 = *function_name;
+               
+       if(is_method && function_name && function_name->op_type == IS_UNUSED) {
+               /* clone */
+               if(argument_list->u.constant.value.lval != 0) {
+                       zend_error(E_WARNING, "Clone method does not require arguments");
+               }
+               opline = &CG(active_op_array)->opcodes[function_name->u.constant.value.lval];
        } else {
-               opline->opcode = ZEND_DO_FCALL_BY_NAME;
-               SET_UNUSED(opline->op1);
+               opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+               if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
+                       opline->opcode = ZEND_DO_FCALL;
+                       opline->op1 = *function_name;
+               } else {
+                       opline->opcode = ZEND_DO_FCALL_BY_NAME;
+                       SET_UNUSED(opline->op1);
+               }
        }
        
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
index bed9bd8a979f6c889874a899e749f7342d44abca..5c00d7f8df5090fee3ad49b855c07bf7d2ad5f21 100644 (file)
@@ -3172,6 +3172,12 @@ int zend_clone_handler(ZEND_OPCODE_HANDLER_ARGS)
 {
        zval *obj = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
+       if(Z_TYPE_P(obj) != IS_OBJECT) {
+               zend_error(E_WARNING, "__clone method called on non-object");
+               EX_T(EX(opline)->result.u.var).var.ptr = EG(error_zval_ptr);
+               EX_T(EX(opline)->result.u.var).var.ptr->refcount++;
+               NEXT_OPCODE();
+       } 
        EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr;
        ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr);
        EX_T(EX(opline)->result.u.var).var.ptr->value.obj = Z_OBJ_HT_P(obj)->clone_obj(obj TSRMLS_CC);