Only in Zend/: .libs Common subdirectories: ../php-5.2.5/Zend/RFCs and Zend/RFCs Common subdirectories: ../php-5.2.5/Zend/tests and Zend/tests Only in Zend/: zend_alloc.lo diff -u ../php-5.2.5/Zend/zend_API.h Zend/zend_API.h --- ../php-5.2.5/Zend/zend_API.h 2007-04-16 04:09:54.000000000 -0400 +++ Zend/zend_API.h 2008-04-08 08:38:30.000000000 -0400 @@ -69,7 +69,7 @@ #define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, 1, allow_null, pass_by_ref, 0, 0 }, #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ zend_arg_info name[] = { \ - { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args }, + { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args, 0, 0, 0 }, #define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \ ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1) #define ZEND_END_ARG_INFO() }; Only in Zend/: zend_API.lo Only in Zend/: zend_builtin_functions.lo diff -u ../php-5.2.5/Zend/zend_compile.c Zend/zend_compile.c --- ../php-5.2.5/Zend/zend_compile.c 2007-09-20 10:11:31.000000000 -0400 +++ Zend/zend_compile.c 2008-04-15 09:33:29.000000000 -0400 @@ -1292,26 +1292,73 @@ cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1]; cur_arg_info->name = estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len); cur_arg_info->name_len = varname->u.constant.value.str.len; - cur_arg_info->array_type_hint = 0; cur_arg_info->allow_null = 1; cur_arg_info->pass_by_reference = pass_by_reference; - + cur_arg_info->array_type_hint = 0; + cur_arg_info->type_hint = 0; + cur_arg_info->scalar_type_hint = 0; + cur_arg_info->num_type_hint = 0; + cur_arg_info->class_name = NULL; + cur_arg_info->class_name_len = 0; if (class_type->op_type != IS_UNUSED) { cur_arg_info->allow_null = 0; if (class_type->u.constant.type == IS_STRING) { - cur_arg_info->class_name = class_type->u.constant.value.str.val; - cur_arg_info->class_name_len = class_type->u.constant.value.str.len; - if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { - cur_arg_info->allow_null = 1; - } else { - zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); + if (strcmp("scalar", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->scalar_type_hint = 1; + } else if (strcmp("num", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->num_type_hint = 1; + } else if (strcmp("int", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_LONG; + } else if (strcmp("float", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_DOUBLE; + } else if (strcmp("string", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_STRING; + } else if (strcmp("bool", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_BOOL; + } else if (strcmp("object", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_OBJECT; + } else if (strcmp("resource", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_RESOURCE; + } else { + cur_arg_info->class_name = class_type->u.constant.value.str.val; + cur_arg_info->class_name_len = class_type->u.constant.value.str.len; + if (op == ZEND_RECV_INIT) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + cur_arg_info->allow_null = 1; + } else { + zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); + } + } + } + if (cur_arg_info->type_hint != 0) { + if (op == ZEND_RECV_INIT) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + cur_arg_info->allow_null = 1; + } else if (Z_TYPE(initialization->u.constant) != cur_arg_info->type_hint) { + zend_error(E_COMPILE_ERROR, "Invalid default parameter value"); + } + } + } + else if (cur_arg_info->scalar_type_hint != 0) { + if (op == ZEND_RECV_INIT) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + cur_arg_info->allow_null = 1; + } else if (Z_TYPE(initialization->u.constant) != IS_LONG && Z_TYPE(initialization->u.constant) != IS_DOUBLE && Z_TYPE(initialization->u.constant) != IS_BOOL && Z_TYPE(initialization->u.constant) != IS_STRING) { + zend_error(E_COMPILE_ERROR, "Invalid default parameter value"); + } + } + } + else if (cur_arg_info->num_type_hint != 0) { + if (op == ZEND_RECV_INIT) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + cur_arg_info->allow_null = 1; + } else if (Z_TYPE(initialization->u.constant) != IS_LONG && Z_TYPE(initialization->u.constant) != IS_DOUBLE) { + zend_error(E_COMPILE_ERROR, "Invalid default parameter value"); + } } } } else { cur_arg_info->array_type_hint = 1; - cur_arg_info->class_name = NULL; - cur_arg_info->class_name_len = 0; if (op == ZEND_RECV_INIT) { if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { cur_arg_info->allow_null = 1; @@ -1320,9 +1367,6 @@ } } } - } else { - cur_arg_info->class_name = NULL; - cur_arg_info->class_name_len = 0; } opline->result.u.EA.type |= EXT_TYPE_UNUSED; } @@ -1993,6 +2037,15 @@ && strcmp(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)!=0) { return 0; } + if (fe->common.arg_info[i].scalar_type_hint != proto->common.arg_info[i].scalar_type_hint) { + return 0; + } + if (fe->common.arg_info[i].num_type_hint != proto->common.arg_info[i].num_type_hint) { + return 0; + } + if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) { + return 0; + } if (fe->common.arg_info[i].array_type_hint != proto->common.arg_info[i].array_type_hint) { /* Only one has an array type hint and the other one doesn't */ return 0; diff -u ../php-5.2.5/Zend/zend_compile.h Zend/zend_compile.h --- ../php-5.2.5/Zend/zend_compile.h 2007-05-18 09:12:04.000000000 -0400 +++ Zend/zend_compile.h 2008-04-08 08:38:30.000000000 -0400 @@ -167,6 +167,9 @@ zend_bool pass_by_reference; zend_bool return_reference; int required_num_args; + zend_bool scalar_type_hint; + zend_bool num_type_hint; + zend_uint type_hint; } zend_arg_info; typedef struct _zend_compiled_variable { Only in Zend/: zend_compile.lo Only in Zend/: zend_config.h diff -u ../php-5.2.5/Zend/zend_constants.c Zend/zend_constants.c --- ../php-5.2.5/Zend/zend_constants.c 2007-07-27 12:29:11.000000000 -0400 +++ Zend/zend_constants.c 2008-04-08 08:38:30.000000000 -0400 @@ -135,6 +135,12 @@ c.value.type = IS_NULL; zend_register_constant(&c TSRMLS_CC); + c.name = zend_strndup(ZEND_STRL("PATCH_SCALAR_TYPE_HINTING")); + c.name_len = sizeof("PATCH_SCALAR_TYPE_HINTING"); + c.value.value.lval = 1; + c.value.type = IS_BOOL; + zend_register_constant(&c TSRMLS_CC); + c.flags = CONST_PERSISTENT; c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE")); Only in Zend/: zend_constants.c.orig Only in Zend/: zend_constants.lo Only in Zend/: zend_default_classes.lo Only in Zend/: zend_dynamic_array.lo Only in Zend/: zend_exceptions.lo Only in Zend/: zend_execute_API.lo diff -u ../php-5.2.5/Zend/zend_execute.c Zend/zend_execute.c --- ../php-5.2.5/Zend/zend_execute.c 2007-07-19 11:29:30.000000000 -0400 +++ Zend/zend_execute.c 2008-04-15 09:15:35.000000000 -0400 @@ -509,6 +532,48 @@ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC); return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC); } + } else if (cur_arg_info->scalar_type_hint) { + if (!arg) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of a scalar type", "", "none", "" TSRMLS_CC); + } + if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { + if (Z_TYPE_P(arg) == IS_OBJECT) { + if (!Z_OBJCE_P(arg)->__tostring) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of a scalar type or an object with a __toString method", "", "object without a __toString method", "" TSRMLS_CC); + } + } + else if (Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE && Z_TYPE_P(arg) != IS_BOOL && Z_TYPE_P(arg) != IS_STRING) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of a scalar type or an object with a __toString method", "", zend_zval_type_name(arg), "" TSRMLS_CC); + } + } + } else if (cur_arg_info->num_type_hint) { + if (!arg) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a number", "", "none", "" TSRMLS_CC); + } + if (Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a number", "", zend_zval_type_name(arg), "" TSRMLS_CC); + } + } else if (cur_arg_info->type_hint) { + if (!arg) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of type ", zend_get_type_by_const(cur_arg_info->type_hint), "none", "" TSRMLS_CC); + } + if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { + if (cur_arg_info->type_hint == IS_STRING) { + if (Z_TYPE_P(arg) != IS_STRING) { + if (Z_TYPE_P(arg) == IS_OBJECT) { + if (!Z_OBJCE_P(arg)->__tostring) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a string or an object with a __toString method", "", "object without a __toString method", "" TSRMLS_CC); + } + } + else { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a string or an object with a __toString method", "", zend_zval_type_name(arg), "" TSRMLS_CC); + } + } + } + else if (Z_TYPE_P(arg) != cur_arg_info->type_hint) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of type ", zend_get_type_by_const(cur_arg_info->type_hint), zend_zval_type_name(arg), "" TSRMLS_CC); + } + } } else if (cur_arg_info->array_type_hint) { if (!arg) { return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC);