From 8f51f72dc6dc39135478e3782c132b19cccbd44d Mon Sep 17 00:00:00 2001 From: Andi Gutmans Date: Mon, 26 Jul 1999 16:57:06 +0000 Subject: [PATCH] - Fix the new operator incompatibility. - I commented PHP_FUNCTION(strtotime) in datetime.c because it stopped win32 from compiling. This needs to be fixed!!! - Check out libzend to compile the tree now. --- Zend/zend-parser.y | 2 +- Zend/zend.h | 2 +- Zend/zend_compile.c | 13 +++--- Zend/zend_compile.h | 4 +- Zend/zend_execute.c | 73 +++++++++++++++++++++++++--------- ext/rpc/com/COM.c | 6 +-- ext/standard/basic_functions.c | 2 + ext/standard/datetime.c | 4 ++ tests/testobj | 1 + 9 files changed, 77 insertions(+), 30 deletions(-) diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y index f0c853d2af..0a9cbd03f0 100644 --- a/Zend/zend-parser.y +++ b/Zend/zend-parser.y @@ -367,7 +367,7 @@ expr_without_variable: T_LIST '(' { do_list_init(CLS_C); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); } | w_cvar '=' expr { do_assign(&$$, &$1, &$3 CLS_CC); } | w_cvar '=' '&' w_cvar { do_assign_ref(&$$, &$1, &$4 CLS_CC); } - | w_cvar '=' T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$2, &$1, &$3, &$4 CLS_CC); } ctor_arguments { do_end_new_object(&$4, &$3, &$6 CLS_CC); do_extended_fcall_end(CLS_C); $$ = $2;} + | T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$1, &$2 CLS_CC); } ctor_arguments { do_end_new_object(&$$, &$2, &$1, &$4 CLS_CC); do_extended_fcall_end(CLS_C);} | rw_cvar T_PLUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); } | rw_cvar T_MINUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); } | rw_cvar T_MUL_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); } diff --git a/Zend/zend.h b/Zend/zend.h index 0274c212dd..30252d022e 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -113,7 +113,7 @@ typedef struct _zend_function_entry { typedef struct _zend_property_reference { int type; /* read, write or r/w */ - zval **object; + zval *object; zend_llist elements_list; } zend_property_reference; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index de4bc12065..99411f8b10 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1352,7 +1352,7 @@ void do_pop_object(znode *object CLS_DC) } -void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC) +void do_begin_new_object(znode *new_token, znode *class_name CLS_DC) { zend_op *opline = get_next_op(CG(active_op_array) CLS_CC); unsigned char *ptr = NULL; @@ -1363,12 +1363,14 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode opline->op1 = *class_name; SET_UNUSED(opline->op2); - do_assign(result, variable, &opline->result CLS_CC); + //*result = opline->result; + //do_assign(result, variable, &opline->result CLS_CC); + new_token->u.opline_num = get_next_op_number(CG(active_op_array)); opline = get_next_op(CG(active_op_array) CLS_CC); opline->opcode = ZEND_JMP_NO_CTOR; - opline->op1 = *result; + opline->op1 = (opline-1)->result; SET_UNUSED(opline->op2); if (class_name->op_type == IS_CONST) { @@ -1376,14 +1378,14 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode } opline = get_next_op(CG(active_op_array) CLS_CC); opline->opcode = ZEND_INIT_FCALL_BY_NAME; - opline->op1 = *result; + opline->op1 = (opline-2)->result; opline->op2 = *class_name; opline->extended_value = ZEND_MEMBER_FUNC_CALL | ZEND_CTOR_CALL; zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *)); } -void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC) +void do_end_new_object(znode *result, znode *class_name, znode *new_token, znode *argument_list CLS_DC) { znode ctor_result; @@ -1394,6 +1396,7 @@ void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list do_free(&ctor_result CLS_CC); CG(active_op_array)->opcodes[new_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); + *result = CG(active_op_array)->opcodes[new_token->u.opline_num].op1; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 37f10d48f2..b71c9ad018 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -295,8 +295,8 @@ void do_push_object(znode *object CLS_DC); void do_pop_object(znode *object CLS_DC); -void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC); -void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC); +void do_begin_new_object(znode *new_token, znode *class_name CLS_DC); +void do_end_new_object(znode *result, znode *class_name, znode *new_token, znode *argument_list CLS_DC); void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index dc605f5fff..ae0b5997b3 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -152,6 +152,35 @@ static inline zval **_get_zval_ptr_ptr(znode *node, temp_variable *Ts ELS_DC) } } +static inline zval *_get_object_zval_ptr(znode *node, temp_variable *Ts, int *should_free ELS_DC) +{ + switch(node->op_type) { + case IS_TMP_VAR: + *should_free = 1; + return &Ts[node->u.var].tmp_var; + break; + case IS_VAR: + if (Ts[node->u.var].var) { + PZVAL_UNLOCK(*Ts[node->u.var].var); + *should_free = 0; + return *Ts[node->u.var].var; + } else { + *should_free = 1; + return NULL; + } + break; + case IS_UNUSED: + return NULL; + break; +#if DEBUG_ZEND + default: + zend_error(E_ERROR, "Unknown temporary variable type"); + break; +#endif + } + return NULL; +} + static inline zval **zend_fetch_property_address_inner(HashTable *ht, znode *op2, temp_variable *Ts, int type ELS_DC) { @@ -720,7 +749,7 @@ static inline void zend_fetch_property_address(znode *result, znode *op1, znode zend_property_reference property_reference; zend_overloaded_element overloaded_element; - property_reference.object = container_ptr; + property_reference.object = container; property_reference.type = type; zend_llist_init(&property_reference.elements_list, sizeof(zend_overloaded_element), NULL, 0); overloaded_element.element = *get_zval_ptr(op2, Ts, &free_op2, type); @@ -791,7 +820,7 @@ static zval get_overloaded_property(ELS_D) zval result; zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - result = (*(property_reference->object))->value.obj.ce->handle_property_get(property_reference); + result = (property_reference->object)->value.obj.ce->handle_property_get(property_reference); zend_llist_destroy(&property_reference->elements_list); @@ -805,7 +834,7 @@ static void set_overloaded_property(zval *value ELS_DC) zend_property_reference *property_reference; zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - (*(property_reference->object))->value.obj.ce->handle_property_set(property_reference, value); + (property_reference->object)->value.obj.ce->handle_property_set(property_reference, value); zend_llist_destroy(&property_reference->elements_list); @@ -818,7 +847,7 @@ static void call_overloaded_function(int arg_count, zval *return_value, HashTabl zend_property_reference *property_reference; zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - (*(property_reference->object))->value.obj.ce->handle_function_call(arg_count, return_value, list, plist, *property_reference->object, property_reference); + (property_reference->object)->value.obj.ce->handle_function_call(arg_count, return_value, list, plist, property_reference->object, property_reference); zend_llist_destroy(&property_reference->elements_list); zend_stack_del_top(&EG(overloaded_objects_stack)); @@ -844,7 +873,7 @@ void execute(zend_op_array *op_array ELS_DC) zend_function_state function_state; HashTable *calling_symbol_table; zend_function *function_being_called=NULL; - zval **object_ptr=NULL; + zval *object_ptr=NULL; #if !defined (__GNUC__) || __GNUC__ < 2 temp_variable *Ts = (temp_variable *) do_alloca(sizeof(temp_variable)*op_array->T); #else @@ -1270,7 +1299,10 @@ binary_assign_op_addr: { if (opline->extended_value & ZEND_CTOR_CALL) { /* constructor call */ - PZVAL_LOCK(*Ts[opline->op1.u.var].var); + + if (opline->op1.op_type == IS_VAR) { + PZVAL_LOCK(*Ts[opline->op1.u.var].var); + } if (opline->op2.op_type==IS_VAR) { PZVAL_LOCK(*Ts[opline->op2.u.var].var); } @@ -1286,20 +1318,23 @@ binary_assign_op_addr: { if (opline->op1.op_type != IS_UNUSED) { if (opline->op1.op_type==IS_CONST) { /* used for class_name::function() */ zend_class_entry *ce; + zval **object_ptr_ptr; if (zend_hash_find(EG(class_table), opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len+1, (void **) &ce)==FAILURE) { zend_error(E_ERROR, "Undefined class name '%s'", opline->op1.u.constant.value.str.val); } active_function_table = &ce->function_table; - if (zend_hash_find(EG(active_symbol_table), "this", sizeof("this"), (void **) &object_ptr)==FAILURE) { + if (zend_hash_find(EG(active_symbol_table), "this", sizeof("this"), (void **) &object_ptr_ptr)==FAILURE) { object_ptr=NULL; + } else { + object_ptr = *object_ptr_ptr; } } else { /* used for member function calls */ - object_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R); + object_ptr = _get_object_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); if (!object_ptr - || ((*object_ptr)->type==IS_OBJECT && (*object_ptr)->value.obj.ce->handle_function_call)) { /* overloaded function call */ + || ((object_ptr->type==IS_OBJECT) && (object_ptr->value.obj.ce->handle_function_call))) { /* overloaded function call */ zend_overloaded_element overloaded_element; zend_property_reference *property_reference; @@ -1322,10 +1357,10 @@ binary_assign_op_addr: { goto overloaded_function_call_cont; } - if ((*object_ptr)->type != IS_OBJECT) { + if (object_ptr->type != IS_OBJECT) { zend_error(E_ERROR, "Call to a member function on a non-object"); } - active_function_table = &(*object_ptr)->value.obj.ce->function_table; + active_function_table = &(object_ptr->value.obj.ce->function_table); } } else { /* function pointer */ object_ptr = NULL; @@ -1359,7 +1394,7 @@ do_fcall_common: zend_ptr_stack_push(&EG(argument_stack), (void *) opline->extended_value); if (function_state.function->type==ZEND_INTERNAL_FUNCTION) { var_uninit(&Ts[opline->result.u.var].tmp_var); - ((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list), (object_ptr?*object_ptr:NULL)); + ((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list), (object_ptr?object_ptr:NULL)); } else if (function_state.function->type==ZEND_USER_FUNCTION) { if (EG(symtable_cache_ptr)>=EG(symtable_cache)) { /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ @@ -1374,12 +1409,11 @@ do_fcall_common: if (opline->opcode==ZEND_DO_FCALL_BY_NAME && object_ptr && function_being_called->type!=ZEND_OVERLOADED_FUNCTION) { - zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr; + zval **this_ptr; - var_uninit(dummy); - INIT_PZVAL(dummy); - zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr); - zend_assign_to_variable_reference(NULL, this_ptr, object_ptr, NULL ELS_CC); + zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), NULL, sizeof(zval *), (void **) &this_ptr); + *this_ptr = object_ptr; + object_ptr->refcount++; object_ptr = NULL; } original_return_value = EG(return_value); @@ -1882,7 +1916,10 @@ send_by_ref: case ZEND_JMP_NO_CTOR: { zval *object; - PZVAL_LOCK(*Ts[opline->op1.u.var].var); + if (opline->op1.op_type == IS_VAR) { + PZVAL_LOCK(*Ts[opline->op1.u.var].var); + } + object = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); if (!object->value.obj.ce->handle_function_call && !zend_hash_exists(&object->value.obj.ce->function_table, object->value.obj.ce->name, object->value.obj.ce->name_length+1)) { diff --git a/ext/rpc/com/COM.c b/ext/rpc/com/COM.c index b817cd2f8f..3d6702763d 100644 --- a/ext/rpc/com/COM.c +++ b/ext/rpc/com/COM.c @@ -675,7 +675,7 @@ VARIANTARG _php_COM_get_property_handler(zend_property_reference *property_refer zend_overloaded_element *overloaded_property; zend_llist_element *element; pval **idispatch_handle; - pval *object = *property_reference->object; + pval *object = property_reference->object; IDispatch *i_dispatch; int type; VARIANTARG var_result; @@ -748,7 +748,7 @@ int php_COM_set_property_handler(zend_property_reference *property_reference, pv zend_overloaded_element *overloaded_property; zend_llist_element *element; pval **idispatch_handle; - pval *object = *property_reference->object; + pval *object = property_reference->object; IDispatch *i_dispatch; int type; VARIANTARG var_result; @@ -810,7 +810,7 @@ int php_COM_set_property_handler(zend_property_reference *property_reference, pv void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) { zend_overloaded_element *overloaded_property; - pval *object = *property_reference->object; + pval *object = property_reference->object; zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list.tail->data; if (zend_llist_count(&property_reference->elements_list)==1 diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 372112e6b9..6a5230c037 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -94,7 +94,9 @@ function_entry basic_functions[] = { #if HAVE_STRFTIME PHP_FE(strftime, NULL) #endif +#if !(WIN32|WINNT) PHP_FE(strtotime, NULL) +#endif PHP_FE(date, NULL) PHP_FE(gmdate, NULL) PHP_FE(getdate, NULL) diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c index 11cd604e9b..6ad11f78ad 100644 --- a/ext/standard/datetime.c +++ b/ext/standard/datetime.c @@ -65,7 +65,9 @@ static int phpday_tab[2][12] = #define isleap(year) (((year%4) == 0 && (year%100)!=0) || (year%400)==0) +#if !(WIN32|WINNT) extern PHPAPI time_t parsedate(char *p, struct timeval *now); +#endif PHP_FUNCTION(time) { @@ -556,6 +558,7 @@ PHP_FUNCTION(strftime) } #endif +#if !(WIN32|WINNT) /* {{{ proto int strtotime(string time, int now) */ PHP_FUNCTION(strtotime) { @@ -579,6 +582,7 @@ PHP_FUNCTION(strtotime) RETURN_LONG(parsedate(timep->value.str.val, NULL)); } } +#endif /* }}} */ /* diff --git a/tests/testobj b/tests/testobj index 1c2aa7f2c0..7519583cc8 100644 --- a/tests/testobj +++ b/tests/testobj @@ -8,6 +8,7 @@ class foobar { }; $foo = new foobar; // or die("Unable to construct foobar\n"); +print $foo->initialized; //$word = new COm("word.application"); //$word->visible = true; //sleep(5); -- 2.40.0