X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fmarshal.c;h=00c1a815254ec9de6307bd6af1e76fddc57783c5;hp=31ff9ba8f8f6fcafbafc4ffeaa36eb10cf2296d1;hb=3fa287dfd76814b2ec54991c0208a019845a3dc0;hpb=b9193a8d80bf7ea8d768b9521bcd298a03974c9d diff --git a/src/marshal.c b/src/marshal.c index 31ff9ba..00c1a81 100644 --- a/src/marshal.c +++ b/src/marshal.c @@ -1,5 +1,7 @@ #ifdef HAVE_CONFIG_H # include "config.h" +#else +# include "php_config.h" #endif #include "php.h" @@ -13,6 +15,22 @@ 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 *spec, token_t impl_type, impl_val *ival, zval *zvalue, 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 *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) +{ + *to_free = tmp->ptr = emalloc(sizeof(zval)); + ZVAL_COPY_VALUE(tmp->ptr, zvalue); + return tmp; +} + void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val) { psi_to_int(return_value, set, ret_val); @@ -39,15 +57,15 @@ static inline impl_val *psi_val_boolval(impl_val *tmp, token_t real_type, zend_b return tmp; } -impl_val *psi_let_boolval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_boolval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { zend_bool boolval; - token_t real_type = type ? real_decl_type(type)->type : PSI_T_UINT8; + token_t real_type = spec ? real_decl_type(spec)->type : PSI_T_UINT8; - if (iarg->type->type == PSI_T_BOOL) { - boolval = iarg->val.zend.bval; + if (ival && impl_type == PSI_T_BOOL) { + boolval = ival->zend.bval; } else { - boolval = zend_is_true(iarg->_zv); + boolval = zend_is_true(zvalue); } return psi_val_boolval(tmp, real_type, boolval); @@ -95,9 +113,10 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo 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 @@ -109,15 +128,15 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo return tmp; } -impl_val *psi_let_intval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_intval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { zend_long intval; - token_t real_type = type ? real_decl_type(type)->type : PSI_T_INT; + token_t real_type = spec ? real_decl_type(spec)->type : PSI_T_LONG; - if (iarg->type->type == PSI_T_INT) { - intval = iarg->val.zend.lval; + if (ival && impl_type == PSI_T_INT) { + intval = ival->zend.lval; } else { - intval = zval_get_long(iarg->_zv); + intval = zval_get_long(zvalue); } return psi_val_intval(tmp, real_type, intval); @@ -168,15 +187,15 @@ static inline impl_val *psi_val_floatval(impl_val *tmp, token_t real_type, doubl return tmp; } -impl_val *psi_let_floatval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_floatval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { double floatval; - token_t real_type = type ? real_decl_type(type)->type : PSI_T_DOUBLE; + token_t real_type = spec ? real_decl_type(spec)->type : PSI_T_DOUBLE; - if (iarg->type->type == PSI_T_FLOAT || iarg->type->type == PSI_T_DOUBLE) { - floatval = iarg->val.dval; + if (ival && (impl_type == PSI_T_FLOAT || impl_type == PSI_T_DOUBLE)) { + floatval = ival->dval; } else { - floatval = zval_get_double(iarg->_zv); + floatval = zval_get_double(zvalue); } return psi_val_floatval(tmp, real_type, floatval); @@ -221,17 +240,17 @@ void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val) convert_to_string(return_value); } -impl_val *psi_let_strval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_strval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { - if (iarg->type->type == PSI_T_STRING) { - if (iarg->val.zend.str) { - tmp->ptr = estrndup(iarg->val.zend.str->val, iarg->val.zend.str->len); + if (ival && impl_type == PSI_T_STRING) { + if (ival->zend.str) { + tmp->ptr = estrndup(ival->zend.str->val, ival->zend.str->len); *to_free = tmp->ptr; } else { tmp->ptr = ""; } } else { - zend_string *zs = zval_get_string(iarg->_zv); + zend_string *zs = zval_get_string(zvalue); tmp->ptr = estrdup(zs->val); *to_free = tmp->ptr; zend_string_release(zs); @@ -240,26 +259,27 @@ impl_val *psi_let_strval(impl_val *tmp, decl_type *type, impl_arg *iarg, void ** return tmp; } -impl_val *psi_let_pathval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_pathval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { - tmp = psi_let_strval(tmp, type, iarg, to_free); + tmp = psi_let_strval(tmp, spec, impl_type, ival, zvalue, to_free); if (SUCCESS != php_check_open_basedir(tmp->ptr)) { efree(tmp->ptr); + tmp->ptr = NULL; return *to_free = NULL; } return tmp; } -impl_val *psi_let_strlen(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_strlen(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { - if (iarg->type->type == PSI_T_STRING) { - if (iarg->val.zend.str) { - tmp->lval = iarg->val.zend.str->len; + if (ival && impl_type == PSI_T_STRING) { + if (ival->zend.str) { + tmp->lval = ival->zend.str->len; } else { tmp->lval = 0; } } else { - zend_string *zs = zval_get_string(iarg->_zv); + zend_string *zs = zval_get_string(zvalue); tmp->lval = zs->len; zend_string_release(zs); } @@ -274,7 +294,7 @@ static impl_val *iterate(impl_val *val, size_t size, unsigned i, impl_val *tmp) return tmp; } -void psi_from_zval_ex(impl_val **ptr, decl_arg *spec, token_t cast, zval *zv, void **tmp) +void psi_from_zval_ex(void *cb_ctx, impl_val **ptr, decl_arg *spec, token_t cast, zval *zv, void **tmp) { decl_type *real = real_decl_type(spec->type); impl_val *val = *ptr; @@ -282,7 +302,8 @@ void psi_from_zval_ex(impl_val **ptr, decl_arg *spec, token_t cast, zval *zv, vo switch (real->type) { default: ZEND_ASSERT(0); - /* no break */ + val->i64 = zval_get_long(zv); + break; case PSI_T_INT8: val->i8 = zval_get_long(zv); break; @@ -322,40 +343,29 @@ 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_ex(real->real.strct, HASH_OF(zv), psi_from_zval_ex, cb_ctx); break; - } -} - -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_FLOAT: - mem->fval = (float) zval_get_double(zv); + case PSI_T_UNION: + *tmp = *ptr = psi_array_to_union_ex(real->real.unn, HASH_OF(zv), psi_from_zval_ex, cb_ctx); break; - case PSI_T_DOUBLE: - mem->dval = zval_get_double(zv); + case PSI_T_FUNCTION: + /*FIXME*/ + val->ptr = NULL; break; case PSI_T_VOID: - case PSI_T_INT8: - case PSI_T_UINT8: - if (spec->var->pointer_level) { + val->ptr = NULL; + if (Z_TYPE_P(zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zv), psi_object_get_class_entry())) { + *ptr = PSI_OBJ(zv, NULL)->data; + } else { zend_string *zs = zval_get_string(zv); - *tmp = mem->ptr = estrndup(zs->val, zs->len); + *tmp = val->ptr = estrndup(zs->val, zs->len); zend_string_release(zs); - break; } - /* no break */ - default: - mem->zend.lval = zval_get_long(zv); break; } } -void *psi_array_to_struct(decl_struct *s, HashTable *arr) -{ +void *psi_array_to_struct_ex(decl_struct *s, HashTable *arr, psi_marshal_zval cb, void *cb_ctx) { size_t i, j = 0; char *mem = ecalloc(1, s->size + s->args->count * sizeof(void *)); @@ -364,12 +374,12 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) zval *entry = zend_hash_str_find_ind(arr, darg->var->name, strlen(darg->var->name)); if (entry) { - impl_val val; + impl_val val, *ptr = &val; void *tmp = NULL; - memset(&tmp, 0, sizeof(tmp)); - psi_from_zval(&val, darg, entry, &tmp); - memcpy(mem + darg->layout->pos, &val, darg->layout->len); + memset(&val, 0, sizeof(val)); + cb(cb_ctx, &ptr, darg, /*FIXME*/0, entry, &tmp); + memcpy(mem + darg->layout->pos, ptr, darg->layout->len); if (tmp) { ((void **)(mem + s->size))[j++] = tmp; } @@ -378,8 +388,42 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) return mem; } -void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val) +void *psi_array_to_struct(decl_struct *s, HashTable *arr) { + return psi_array_to_struct_ex(s, arr, psi_from_zval_ex, NULL); +} + +void *psi_array_to_union_ex(decl_union *u, HashTable *arr, psi_marshal_zval cb, void *cb_ctx) { + 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, *ptr = &val; + void *tmp = NULL; + + memset(&val, 0, sizeof(val)); + cb(cb_ctx, &ptr, darg, /*FIXME*/0, 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_array_to_union(decl_union *u, HashTable *arr) { + return psi_array_to_union_ex(u, arr, psi_from_zval_ex, NULL); +} + +void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val) { set->outer.set->func->handler(return_value, set, r_val); } @@ -396,7 +440,7 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) array_init(return_value); - if (t == PSI_T_STRUCT) { + if (t == PSI_T_STRUCT || t == PSI_T_UNION) { // decl_struct *s = real_decl_type(var->arg->type)->strct; if (set->inner && set->inner->count) { @@ -420,8 +464,8 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) } } } + return; } - return; } if (var->arg->var->array_size) { @@ -476,20 +520,23 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) } } -impl_val *psi_let_arrval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_arrval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { - decl_type *real = real_decl_type(type); + decl_type *real = real_decl_type(spec); HashTable *arr; - if (iarg->type->type != PSI_T_ARRAY) { - SEPARATE_ARG_IF_REF(iarg->_zv); - convert_to_array(iarg->_zv); + if (impl_type != PSI_T_ARRAY) { + SEPARATE_ARG_IF_REF(zvalue); + convert_to_array(zvalue); } - arr = HASH_OF(iarg->_zv); + arr = HASH_OF(zvalue); switch (real->type) { case PSI_T_STRUCT: - *to_free = tmp = psi_array_to_struct(real->strct, arr); + *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(); } @@ -501,28 +548,27 @@ void psi_to_object(zval *return_value, set_value *set, impl_val *r_val) { decl_var *var = set->vars->vars[0]; impl_val *ret_val = deref_impl_val(r_val, var); - psi_object *obj; if ((intptr_t) ret_val->ptr > (intptr_t) 0) { object_init_ex(return_value, psi_object_get_class_entry()); - obj = PSI_OBJ(return_value, NULL); - obj->data = ret_val->ptr; + PSI_OBJ(return_value, NULL)->data = ret_val->ptr; } else { RETVAL_NULL(); } } -impl_val *psi_let_objval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) +impl_val *psi_let_objval(impl_val *tmp, decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free) { psi_object *obj; - if (Z_TYPE_P(iarg->_zv) != IS_OBJECT - || !instanceof_function(Z_OBJCE_P(iarg->_zv), psi_object_get_class_entry())) { + if (Z_TYPE_P(zvalue) != IS_OBJECT + || !instanceof_function(Z_OBJCE_P(zvalue), psi_object_get_class_entry())) { return NULL; } - obj = PSI_OBJ(iarg->_zv, NULL); + obj = PSI_OBJ(zvalue, NULL); tmp->ptr = obj->data; return tmp; } +