Skip to content

Commit

Permalink
Make zend_parse_parameters share fast zpp implementation where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
hikari-no-yume committed Dec 15, 2014
1 parent 9c18ad3 commit ec84dfd
Showing 1 changed file with 45 additions and 207 deletions.
252 changes: 45 additions & 207 deletions Zend/zend_API.c
Expand Up @@ -389,265 +389,113 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
case 'L':
{
zend_long *p = va_arg(*va, zend_long *);
zend_bool *is_null = NULL;

if (check_null) {
zend_bool *p = va_arg(*va, zend_bool *);
*p = (Z_TYPE_P(arg) == IS_NULL);
is_null = va_arg(*va, zend_bool *);
}

switch (Z_TYPE_P(arg)) {
case IS_STRING:
{
double d;
int type;

if ((type = is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), p, &d, -1)) == 0) {
return "long";
} else if (type == IS_DOUBLE) {
if (zend_isnan(d)) {
return "long";
}
if (!ZEND_DOUBLE_FITS_LONG(d)) {
if (c == 'L') {
*p = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
} else {
return "long";
}
break;
}

*p = zend_dval_to_lval(d);
}
}
break;

case IS_DOUBLE:
if (zend_isnan(Z_DVAL_P(arg))) {
return "long";
}
if (!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg))) {
if (c == 'L') {
*p = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
} else {
return "long";
}
break;
}
case IS_NULL:
case IS_FALSE:
case IS_TRUE:
case IS_LONG:
convert_to_long_ex(arg);
*p = Z_LVAL_P(arg);
break;

case IS_ARRAY:
case IS_OBJECT:
case IS_RESOURCE:
default:
return "long";
if (!_z_param_long(arg, p, is_null, check_null, c == 'L')) {
return "long";
}
}
break;

case 'd':
{
double *p = va_arg(*va, double *);
zend_bool *is_null = NULL;

if (check_null) {
zend_bool *p = va_arg(*va, zend_bool *);
*p = (Z_TYPE_P(arg) == IS_NULL);
is_null = va_arg(*va, zend_bool *);
}

switch (Z_TYPE_P(arg)) {
case IS_STRING:
{
zend_long l;
int type;

if ((type = is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &l, p, -1)) == 0) {
return "double";
} else if (type == IS_LONG) {
*p = (double) l;
}
}
break;

case IS_NULL:
case IS_FALSE:
case IS_TRUE:
case IS_LONG:
case IS_DOUBLE:
convert_to_double_ex(arg);
*p = Z_DVAL_P(arg);
break;

case IS_ARRAY:
case IS_OBJECT:
case IS_RESOURCE:
default:
return "double";
if (!_z_param_double(arg, p, is_null, check_null)) {
return "double";
}
}
break;

case 'p':
case 's':
{
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
switch (Z_TYPE_P(arg)) {
case IS_NULL:
if (check_null) {
*p = NULL;
*pl = 0;
break;
}
/* break omitted intentionally */

case IS_LONG:
case IS_DOUBLE:
case IS_FALSE:
case IS_TRUE:
convert_to_string_ex(arg);
case IS_STRING:
*p = Z_STRVAL_P(arg);
*pl = Z_STRLEN_P(arg);
if (c == 'p' && CHECK_ZVAL_NULL_PATH(arg)) {
return "a valid path";
}
break;

case IS_OBJECT:
if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) {
if (c == 'p' && CHECK_ZVAL_NULL_PATH(arg)) {
return "a valid path";
}
break;
}

case IS_ARRAY:
case IS_RESOURCE:
default:
return c == 's' ? "string" : "a valid path";
if (!_z_param_string(arg, p, pl, check_null TSRMLS_CC)) {
return "string";
}
}
break;

case 'p':
{
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
if (!_z_param_path(arg, p, pl, check_null TSRMLS_CC)) {
return "a valid path";
}
}
break;

case 'P':
case 'S':
{
zend_string **str = va_arg(*va, zend_string **);
switch (Z_TYPE_P(arg)) {
case IS_NULL:
if (check_null) {
*str = NULL;
break;
}
/* break omitted intentionally */

case IS_LONG:
case IS_DOUBLE:
case IS_FALSE:
case IS_TRUE:
convert_to_string_ex(arg);
case IS_STRING:
*str = Z_STR_P(arg);
if (c == 'P' && CHECK_ZVAL_NULL_PATH(arg)) {
return "a valid path";
}
break;
if (!_z_param_path_str(arg, str, check_null TSRMLS_CC)) {
return "a valid path";
}
}
break;

case IS_OBJECT: {
if (parse_arg_object_to_str(arg, str, IS_STRING TSRMLS_CC) == SUCCESS) {
if (c == 'P' && CHECK_ZVAL_NULL_PATH(arg)) {
return "a valid path";
}
break;
}
}
case IS_ARRAY:
case IS_RESOURCE:
default:
return c == 'S' ? "string" : "a valid path";
case 'S':
{
zend_string **str = va_arg(*va, zend_string **);
if (!_z_param_str(arg, str, check_null TSRMLS_CC)) {
return "string";
}
}
break;

case 'b':
{
zend_bool *p = va_arg(*va, zend_bool *);
zend_bool *is_null = NULL;

if (check_null) {
zend_bool *p = va_arg(*va, zend_bool *);
*p = (Z_TYPE_P(arg) == IS_NULL);
is_null = va_arg(*va, zend_bool *);
}

switch (Z_TYPE_P(arg)) {
case IS_NULL:
case IS_STRING:
case IS_LONG:
case IS_DOUBLE:
case IS_FALSE:
case IS_TRUE:
convert_to_boolean_ex(arg);
*p = Z_TYPE_P(arg) == IS_TRUE;
break;

case IS_ARRAY:
case IS_OBJECT:
case IS_RESOURCE:
default:
return "boolean";
if (!_z_param_bool(arg, p, is_null, check_null TSRMLS_CC)) {
return "boolean";
}
}
break;

case 'r':
{
zval **p = va_arg(*va, zval **);
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*p = NULL;
break;
}
if (Z_TYPE_P(arg) == IS_RESOURCE) {
*p = arg;
} else {

if (!_z_param_resource(arg, p, check_null)) {
return "resource";
}
}
break;

case 'A':
case 'a':
{
zval **p = va_arg(*va, zval **);
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*p = NULL;
break;
}
if (Z_TYPE_P(arg) == IS_ARRAY || (c == 'A' && Z_TYPE_P(arg) == IS_OBJECT)) {
*p = arg;
} else {

if (!_z_param_array(arg, p, check_null, c == 'A')) {
return "array";
}
}
break;

case 'H':
case 'h':
{
HashTable **p = va_arg(*va, HashTable **);
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*p = NULL;
break;
}
if (Z_TYPE_P(arg) == IS_ARRAY) {
*p = Z_ARRVAL_P(arg);
} else if(c == 'H' && Z_TYPE_P(arg) == IS_OBJECT) {
*p = HASH_OF(arg);
if(*p == NULL) {
return "array";
}
} else {

if (!_z_param_array_ht(arg, p, check_null, c == 'H' TSRMLS_CC)) {
return "array";
}
}
Expand All @@ -673,14 +521,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
zval **p = va_arg(*va, zval **);
zend_class_entry *ce = va_arg(*va, zend_class_entry *);

if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*p = NULL;
break;
}
if (Z_TYPE_P(arg) == IS_OBJECT &&
(!ce || instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC))) {
*p = arg;
} else {
if (!_z_param_object(arg, p, ce, check_null TSRMLS_CC)) {
if (ce) {
return ce->name->val;
} else {
Expand Down Expand Up @@ -759,11 +600,8 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
case 'z':
{
zval **p = va_arg(*va, zval **);
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*p = NULL;
} else {
*p = real_arg;
}

_z_param_zval(arg, p, check_null);
}
break;

Expand Down

0 comments on commit ec84dfd

Please sign in to comment.