pre-evaluate constant value on validation
authorMichael Wallner <mike@php.net>
Mon, 6 Feb 2017 10:32:13 +0000 (11:32 +0100)
committerMichael Wallner <mike@php.net>
Mon, 6 Feb 2017 10:32:13 +0000 (11:32 +0100)
src/context.c
src/types/const.c
src/types/impl_def_val.c
src/types/impl_def_val.h
src/types/impl_func.c

index b98ecc2..11b2abd 100644 (file)
@@ -284,34 +284,36 @@ zend_function_entry *psi_context_compile(struct psi_context *C)
                struct psi_const *c;
 
                while (psi_plist_get(C->consts, i++, &c)) {
-                       zc.name = zend_string_init(c->name + (c->name[0] == '\\'), strlen(c->name) - (c->name[0] == '\\'), 1);
 
-                       if (zend_get_constant(zc.name)) {
-                               zend_string_release(zc.name);
+                       if (zend_get_constant_str(c->name, strlen(c->name))) {
                                continue;
                        }
 
-                       ZVAL_NEW_STR(&zc.value, zend_string_init(c->val->text, strlen(c->val->text), 1));
+                       zc.name = zend_string_init(c->name + (c->name[0] == '\\'), strlen(c->name) - (c->name[0] == '\\'), 1);
 
                        switch (c->type->type) {
                        case PSI_T_BOOL:
-                               convert_to_boolean(&zc.value);
+                               ZVAL_BOOL(&zc.value, c->val->ival.zend.bval);
                                break;
                        case PSI_T_INT:
-                               convert_to_long(&zc.value);
+                               ZVAL_LONG(&zc.value, c->val->ival.zend.lval);
                                break;
                        case PSI_T_FLOAT:
-                               convert_to_double(&zc.value);
+                               ZVAL_DOUBLE(&zc.value, c->val->ival.dval);
                                break;
                        case PSI_T_STRING:
                        case PSI_T_QUOTED_STRING:
+                               ZVAL_NEW_STR(&zc.value, zend_string_init(c->val->text, strlen(c->val->text), 1));
                                break;
                        default:
                                assert(0);
+                               break;
                        }
+
                        zend_register_constant(&zc);
                }
        }
+
        if (C->enums) {
                size_t i = 0;
                struct psi_decl_enum *e;
index a40a0e2..449f04a 100644 (file)
@@ -31,7 +31,7 @@ struct psi_const *psi_const_init(struct psi_const_type *type, const char *name,
 {
        struct psi_const *c = calloc(1, sizeof(*c));
        c->type = type;
-       c->name = strdup(name);
+       c->name = strdup(name[0] == '\\' ? &name[1] : name);
        c->val = val;
        return c;
 }
@@ -63,6 +63,8 @@ void psi_const_dump(int fd, struct psi_const *cnst)
 
 bool psi_const_validate(struct psi_data *data, struct psi_const *c)
 {
-       /* FIXME */
+       if (!psi_impl_def_val_validate(data, c->val, c->type->type, c->type->name)) {
+               return false;
+       }
        return true;
 }
index 61c4e8b..efbd793 100644 (file)
@@ -63,10 +63,10 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr)
 }
 
 bool psi_impl_def_val_validate(struct psi_data *data,
-               struct psi_impl_def_val *def, struct psi_impl_type *type)
+               struct psi_impl_def_val *def, token_t type_t, const char *type_name)
 {
-       if (def->type != PSI_T_NULL) {
-               switch (type->type) {
+       if (def->type != PSI_T_NULL && def->text) {
+               switch (type_t) {
                case PSI_T_BOOL:
                        def->ival.zend.bval = def->type == PSI_T_TRUE ? 1 : 0;
                        break;
@@ -78,7 +78,7 @@ bool psi_impl_def_val_validate(struct psi_data *data,
                        def->ival.dval = zend_strtod(def->text, NULL);
                        break;
                case PSI_T_STRING:
-                       assert(0);
+                       /* used for consts */
                        /* no break */
                case PSI_T_QUOTED_STRING:
                        def->ival.zend.str = zend_string_init(&def->text[1], strlen(def->text) - 2, 1);
@@ -86,7 +86,7 @@ bool psi_impl_def_val_validate(struct psi_data *data,
                default:
                        data->error(data, def->token, PSI_WARNING,
                                        "Invalid default value type '%s', expected one of bool, int, double, string.",
-                                       type->name);
+                                       type_name);
                        return false;
                }
        }
index b5530bc..6688464 100644 (file)
@@ -42,6 +42,6 @@ struct psi_impl_def_val {
 struct psi_impl_def_val *psi_impl_def_val_init(token_t t, const char *text);
 void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr);
 void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val);
-bool psi_impl_def_val_validate(struct psi_data *data, struct psi_impl_def_val *def, struct psi_impl_type *type);
+bool psi_impl_def_val_validate(struct psi_data *data, struct psi_impl_def_val *def, token_t i_type_t, const char *i_type_n);
 
 #endif
index 52a8e25..b728b0c 100644 (file)
@@ -70,7 +70,7 @@ bool psi_impl_func_validate(struct psi_data *data, struct psi_impl_func *func)
        while (psi_plist_get(func->args, i++, &iarg)) {
                if (iarg->def) {
                        def = 1;
-                       if (!psi_impl_def_val_validate(data, iarg->def, iarg->type)) {
+                       if (!psi_impl_def_val_validate(data, iarg->def, iarg->type->type, iarg->type->name)) {
                                return 0;
                        }
                } else if (def) {