functor types
[m6w6/ext-psi] / src / marshal.c
index 23042a479163777ad65558e28a10d5d606c1528b..622db12bd817ce05ea02573c65fafe370541c934 100644 (file)
@@ -13,6 +13,21 @@ void psi_to_void(zval *return_value, set_value *set, impl_val *ret_val)
        RETVAL_NULL();
 }
 
+impl_val *psi_let_void(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) {
+       return tmp;
+}
+
+void psi_to_zval(zval *return_value, set_value *set, impl_val *ret_val) {
+       RETVAL_ZVAL(ret_val->ptr, 1, 0);
+}
+
+impl_val *psi_let_zval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free)
+{
+       *to_free = tmp->ptr = emalloc(sizeof(zval));
+       ZVAL_COPY_VALUE(tmp->ptr, iarg->_zv);
+       return tmp;
+}
+
 void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val)
 {
        psi_to_int(return_value, set, ret_val);
@@ -88,16 +103,17 @@ void psi_to_int(zval *return_value, set_value *set, impl_val *ret_val)
 }
 
 static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_long intval) {
-       switch (real_decl_type(type)->type) {
+       switch (real_type) {
        case PSI_T_INT8:                tmp->i8 = intval;               break;
        case PSI_T_UINT8:               tmp->u8 = intval;               break;
        case PSI_T_INT16:               tmp->i16 = intval;              break;
        case PSI_T_UINT16:              tmp->u16 = intval;              break;
        case PSI_T_INT32:               tmp->i32 = intval;              break;
        case PSI_T_UINT32:              tmp->u32 = intval;              break;
-       case PSI_T_INT:                 tmp->ival = intval;             break;
        case PSI_T_INT64:               tmp->i64 = intval;              break;
        case PSI_T_UINT64:              tmp->u64 = intval;              break;
+       case PSI_T_INT:                 tmp->ival = intval;             break;
+       case PSI_T_LONG:                tmp->lval = intval;             break;
        case PSI_T_FLOAT:               tmp->fval = intval;             break;
        case PSI_T_DOUBLE:              tmp->dval = intval;             break;
 #ifdef HAVE_LONG_DOUBLE
@@ -112,7 +128,7 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo
 impl_val *psi_let_intval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free)
 {
        zend_long intval;
-       token_t real_type = type ? real_decl_type(type)->type : PSI_T_INT;
+       token_t real_type = type ? real_decl_type(type)->type : PSI_T_LONG;
 
        if (iarg->type->type == PSI_T_INT) {
                intval = iarg->val.zend.lval;
@@ -148,7 +164,7 @@ void psi_to_double(zval *return_value, set_value *set, impl_val *ret_val)
 }
 
 static inline impl_val *psi_val_floatval(impl_val *tmp, token_t real_type, double floatval) {
-       switch (real_decl_type(type)->type) {
+       switch (real_type) {
        case PSI_T_INT8:                tmp->i8 = floatval;             break;
        case PSI_T_UINT8:               tmp->u8 = floatval;             break;
        case PSI_T_INT16:               tmp->i16 = floatval;    break;
@@ -171,7 +187,7 @@ static inline impl_val *psi_val_floatval(impl_val *tmp, token_t real_type, doubl
 impl_val *psi_let_floatval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free)
 {
        double floatval;
-       token_t real_type = type ? real_decl_type(type)->real : PSI_T_DOUBLE;
+       token_t real_type = type ? real_decl_type(type)->type : PSI_T_DOUBLE;
 
        if (iarg->type->type == PSI_T_FLOAT || iarg->type->type == PSI_T_DOUBLE) {
                floatval = iarg->val.dval;
@@ -322,7 +338,7 @@ void psi_from_zval_ex(impl_val **ptr, decl_arg *spec, token_t cast, zval *zv, vo
                val->ival = zval_get_long(zv);
                break;
        case PSI_T_STRUCT:
-               *tmp = *ptr = psi_array_to_struct(real->strct, HASH_OF(zv));
+               *tmp = *ptr = psi_array_to_struct(real->real.strct, HASH_OF(zv));
                break;
        }
 }
@@ -332,6 +348,8 @@ void psi_from_zval(impl_val *mem, decl_arg *spec, zval *zv, void **tmp)
        decl_type *type = real_decl_type(spec->type);
 
        switch (type->type) {
+       case PSI_T_FUNCTION:
+               break;
        case PSI_T_FLOAT:
                mem->fval = (float) zval_get_double(zv);
                break;
@@ -378,6 +396,32 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr)
        return mem;
 }
 
+void *psi_array_to_union(decl_union *u, HashTable *arr) {
+       size_t i;
+       char *mem = ecalloc(1, u->size + sizeof(void *));
+
+       if (arr) for (i = 0; i < u->args->count; ++i) {
+               decl_arg *darg = u->args->args[i];
+               zval *entry = zend_hash_str_find_ind(arr, darg->var->name, strlen(darg->var->name));
+
+               if (entry) {
+                       impl_val val;
+                       void *tmp = NULL;
+
+                       memset(&tmp, 0, sizeof(tmp));
+                       psi_from_zval(&val, darg, entry, &tmp);
+                       memcpy(mem, &val, darg->layout->len);
+                       if (tmp) {
+                               ((void **)(mem + u->size))[0] = tmp;
+                       }
+                       /* first found entry wins */
+                       break;
+               }
+       }
+
+       return mem;
+}
+
 void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val)
 {
        set->outer.set->func->handler(return_value, set, r_val);
@@ -476,13 +520,28 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val)
        }
 }
 
-impl_val *psi_arrval(impl_val *tmp, decl_type *type, void *val, void **to_free)
+impl_val *psi_let_arrval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free)
 {
-       HashTable *arr = (HashTable *) val;
-       decl_type *real = type ? real_decl_type(type) : NULL;
+       decl_type *real = real_decl_type(type);
+       HashTable *arr;
 
-       ZEND_ASSERT(real && real->type == PSI_T_STRUCT);
-       return *to_free = psi_array_to_struct(real->strct, arr);
+       if (iarg->type->type != PSI_T_ARRAY) {
+               SEPARATE_ARG_IF_REF(iarg->_zv);
+               convert_to_array(iarg->_zv);
+       }
+       arr = HASH_OF(iarg->_zv);
+
+       switch (real->type) {
+       case PSI_T_STRUCT:
+               *to_free = tmp = psi_array_to_struct(real->real.strct, arr);
+               break;
+       case PSI_T_UNION:
+               *to_free = tmp = psi_array_to_union(real->real.unn, arr);
+               break;
+       EMPTY_SWITCH_DEFAULT_CASE();
+       }
+
+       return tmp;
 }
 
 void psi_to_object(zval *return_value, set_value *set, impl_val *r_val)
@@ -500,17 +559,18 @@ void psi_to_object(zval *return_value, set_value *set, impl_val *r_val)
        }
 }
 
-impl_val *psi_objval(impl_val *tmp, decl_type *type, void *val, void **to_free)
+impl_val *psi_let_objval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free)
 {
-       zval *zv = (zval *) val;
        psi_object *obj;
 
-       if (!instanceof_function(Z_OBJCE_P(zv), psi_object_get_class_entry())) {
+       if (Z_TYPE_P(iarg->_zv) != IS_OBJECT
+       ||      !instanceof_function(Z_OBJCE_P(iarg->_zv), psi_object_get_class_entry())) {
                return NULL;
        }
 
-       obj = PSI_OBJ(zv, NULL);
+       obj = PSI_OBJ(iarg->_zv, NULL);
        tmp->ptr = obj->data;
 
        return tmp;
 }
+