X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fengine.c;h=09dc429a2a6974b346218ff7f891cdbdf17306a4;hb=de01badbc6098fe8a2f68afef5bc984b9ed371a5;hp=a4bf0d7aced6d50e3cce84b58bf85914bd204855;hpb=8ea12c5ca367010b2d5024e68849e06af9300d61;p=m6w6%2Fext-psi diff --git a/src/engine.c b/src/engine.c index a4bf0d7..09dc429 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,5 +1,7 @@ #ifdef HAVE_CONFIG_H # include "config.h" +#else +# include "php_config.h" #endif #include "php.h" @@ -12,56 +14,12 @@ #include "calc.h" #include "marshal.h" -size_t psi_t_alignment(token_t t) +static inline void psi_do_set(zval *return_value, set_value *set) { -#define PSI_ALIGNOF(T) case PSI_T_## T: return ALIGNOF_## T ##_T; - switch (t) { - PSI_ALIGNOF(INT8); - PSI_ALIGNOF(UINT8); - PSI_ALIGNOF(INT16); - PSI_ALIGNOF(UINT16); - PSI_ALIGNOF(INT32); - PSI_ALIGNOF(UINT32); - PSI_ALIGNOF(INT64); - PSI_ALIGNOF(UINT64); - case PSI_T_FLOAT: - return ALIGNOF_FLOAT; - case PSI_T_DOUBLE: - return ALIGNOF_DOUBLE; - case PSI_T_POINTER: - case PSI_T_FUNCTION: - return ALIGNOF_VOID_P; - case PSI_T_ENUM: - return ALIGNOF_INT; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return 0; -} + decl_arg *set_arg = set->vars->vars[0]->arg; -size_t psi_t_size(token_t t) -{ -#define PSI_SIZEOF(T) case PSI_T_## T : return SIZEOF_## T ##_T; - switch (t) { - PSI_SIZEOF(INT8); - PSI_SIZEOF(UINT8); - PSI_SIZEOF(INT16); - PSI_SIZEOF(UINT16); - PSI_SIZEOF(INT32); - PSI_SIZEOF(UINT32); - PSI_SIZEOF(INT64); - PSI_SIZEOF(UINT64); - case PSI_T_FLOAT: - return SIZEOF_FLOAT; - case PSI_T_DOUBLE: - return SIZEOF_DOUBLE; - case PSI_T_POINTER: - case PSI_T_FUNCTION: - return SIZEOF_VOID_P; - case PSI_T_ENUM: - return SIZEOF_INT; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return 0; + zval_dtor(return_value); + set->func->handler(return_value, set, set_arg->let); } int psi_internal_type(impl_type *type) @@ -258,23 +216,15 @@ static inline void *psi_do_calloc(let_calloc *alloc) return mem; } -static inline impl_val *psi_let_val(token_t let_func, impl_arg *iarg, impl_val *arg_val, decl_struct *strct, void **to_free) -{ - abort(); - return arg_val; -} - -static inline impl_val *psi_let_func(let_func *func, decl_arg *darg) { - return darg->ptr = func->handler(darg->ptr, darg->type, func->var->arg, &darg->mem); -} +static inline impl_val *psi_let_func(let_func *func, decl_arg *darg); -static inline void *psi_do_let(let_stmt *let) +static inline void *psi_let_val(let_val *val, decl_arg *darg) { - decl_arg *darg = let->var->arg; + ZEND_ASSERT(darg); - switch (let->val ? let->val->kind : PSI_LET_NULL) { + switch (val ? val->kind : PSI_LET_NULL) { case PSI_LET_TMP: - memcpy(darg->ptr, deref_impl_val(let->val->data.var->arg->let, let->val->data.var), sizeof(impl_val)); + memcpy(darg->ptr, deref_impl_val(val->data.var->arg->let, val->data.var), sizeof(impl_val)); break; case PSI_LET_NULL: if (darg->var->array_size) { @@ -285,29 +235,107 @@ static inline void *psi_do_let(let_stmt *let) } break; case PSI_LET_CALLOC: - darg->val.ptr = psi_do_calloc(let->val->data.alloc); + darg->val.ptr = psi_do_calloc(val->data.alloc); darg->mem = darg->val.ptr; break; - case PSI_LET_CALLBACK: - darg->val.ptr = let->val->data.callback->decl->call.sym; - break; case PSI_LET_NUMEXP: - darg->val.zend.lval = psi_long_num_exp(let->val->data.num, NULL); + darg->val.zend.lval = psi_long_num_exp(val->data.num, NULL); + break; + case PSI_LET_CALLBACK: + darg->val.ptr = val->data.callback->decl->call.sym; break; case PSI_LET_FUNC: - if (!psi_let_func(let->val->data.func, darg)) { + if (!psi_let_func(val->data.func, darg)) { return NULL; } break; } - if (let->val && let->val->flags.one.is_reference) { + if (val && val->flags.one.is_reference) { return darg->let = &darg->ptr; } else { return darg->let = darg->ptr; } } +static void marshal_func(void *cb_ctx, impl_val **ptr, decl_arg *spec, token_t cast, zval *zv, void **tmp) { + let_vals *vals = cb_ctx; + size_t i; + + for (i = 0; i < vals->count; ++i) { + impl_var *var = locate_let_val_impl_var(vals->vals[i]); + + if (!strcmp(&var->name[1], spec->var->name)) { + *ptr = psi_let_val(vals->vals[i], spec); + *tmp = spec->mem; + break; + } + } +} + +static inline impl_val *psi_let_func_ex(let_func *func, void *dptr, decl_type *dtype, token_t itype, impl_val *ival, zval *zvalue, void **to_free) { + switch (func->type) { + case PSI_T_BOOLVAL: + return psi_let_boolval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_INTVAL: + return psi_let_intval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_FLOATVAL: + return psi_let_floatval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_STRVAL: + return psi_let_strval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_STRLEN: + return psi_let_strlen(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_PATHVAL: + return psi_let_pathval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_OBJVAL: + return psi_let_objval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_ZVAL: + return psi_let_zval(dptr, dtype, itype, ival, zvalue, to_free); + case PSI_T_VOID: + return psi_let_void(dptr, dtype, itype, ival, zvalue, to_free); + break; + case PSI_T_ARRVAL: + if (func->inner) { + decl_type *real = real_decl_type(dtype); + + if (itype != PSI_T_ARRAY) { + SEPARATE_ARG_IF_REF(zvalue); + convert_to_array(zvalue); + } + + return *to_free = psi_array_to_struct_ex(real->real.strct, Z_ARRVAL_P(zvalue), marshal_func, func->inner); + } else { + return psi_let_arrval(dptr, dtype, itype, ival, zvalue, to_free); + } + break; + default: + assert(0); + } + return NULL; +} + +static inline impl_val *psi_let_func(let_func *func, decl_arg *darg) { + impl_arg *iarg = func->var->arg; + + if (func->outer && !iarg) { + impl_arg *outer_arg = locate_let_val_impl_var(func->outer)->arg; + iarg = init_impl_arg( + init_impl_type(PSI_T_MIXED, "mixed"), + copy_impl_var(func->var), NULL); + + + if (!(iarg->_zv = zend_hash_str_find(Z_ARRVAL_P(outer_arg->_zv), &iarg->var->name[1], strlen(iarg->var->name)-1))) { + iarg->_zv = zend_hash_str_add_empty_element(Z_ARRVAL_P(outer_arg->_zv), &iarg->var->name[1], strlen(iarg->var->name)-1); + } + } + return darg->ptr = psi_let_func_ex(func, darg->ptr, darg->type, iarg->type->type, &iarg->val, iarg->_zv, &darg->mem); +} + +static inline void *psi_do_let(let_stmt *let) +{ + return psi_let_val(let->val, let->var->arg); +} + static inline void psi_do_return(zval *return_value, return_stmt *ret) { ret->set->func->handler(return_value, ret->set, ret->set->vars->vars[0]->arg->ptr); @@ -329,14 +357,15 @@ static inline void psi_do_free(free_stmt *fre) } /* FIXME: check in validate_* that free functions return scalar */ - PSI_ContextCall(&PSI_G(context), &f->decl->call, NULL); + psi_context_call(&PSI_G(context), &f->decl->call, NULL); } } -static inline void psi_clean_array_struct(let_stmt *let, decl_arg *darg) { - if (let->val->kind == PSI_LET_FUNC - && let->val->data.func->type == PSI_T_ARRVAL) { +static inline void psi_clean_array_struct(let_val *val, decl_arg *darg) { + if (val->kind == PSI_LET_FUNC + && val->data.func->type == PSI_T_ARRVAL) { decl_type *type = real_decl_type(darg->type); + decl_args *args = NULL; if (type->type == PSI_T_STRUCT) { void **ptr = (void **) ((char *) darg->mem + type->real.strct->size); @@ -344,6 +373,31 @@ static inline void psi_clean_array_struct(let_stmt *let, decl_arg *darg) { while (*ptr) { efree(*ptr++); } + args = type->real.strct->args; + } else if (type->type == PSI_T_UNION) { + void **ptr = (void **) ((char *) darg->mem + type->real.unn->size); + + if (*ptr) { + efree(*ptr); + } + args = type->real.unn->args; + } + if (args && val->data.func->inner) { + size_t i; + + for (i = 0; i < val->data.func->inner->count; ++i) { + let_val *inner = val->data.func->inner->vals[i]; + decl_var *refvar = locate_let_val_inner_ref(inner)->var; + decl_arg *subarg = locate_decl_arg(args, refvar->name); + + if (subarg) { + psi_clean_array_struct(val->data.func->inner->vals[i], subarg); + if (subarg && subarg->mem) { + efree(subarg->mem); + subarg->mem = NULL; + } + } + } } } } @@ -382,7 +436,7 @@ static inline void psi_do_clean(impl *impl) decl_arg *darg = let->var->arg; if (darg->mem) { - psi_clean_array_struct(let, darg); + psi_clean_array_struct(let->val, darg); efree(darg->mem); darg->mem = NULL; } @@ -429,6 +483,9 @@ static inline void psi_do_args(impl *impl) { case PSI_T_STRUCT: impl->decl->func->ptr = psi_array_to_struct(real->real.strct, NULL); break; + case PSI_T_UNION: + impl->decl->func->ptr = psi_array_to_union(real->real.unn, NULL); + break; } } } @@ -450,7 +507,7 @@ static inline impl_vararg *psi_do_varargs(impl *impl) { impl_arg *vaarg = va->args->args[i]; void *to_free = NULL; token_t vatype = va->name->type->type; - let_func_handler let_fn; + psi_marshal_let let_fn; if (vatype == PSI_T_MIXED) { switch (Z_TYPE_P(vaarg->_zv)) { @@ -476,7 +533,7 @@ static inline impl_vararg *psi_do_varargs(impl *impl) { /* FIXME: varargs with struct-by-value :) */ //if (!psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free)) { - if (!let_fn(&va->values[i], NULL, vaarg, &to_free)) { + if (!let_fn(&va->values[i], NULL, vaarg->type->type, &vaarg->val, vaarg->_zv, &to_free)) { return NULL; } @@ -520,7 +577,7 @@ ZEND_RESULT_CODE psi_call(zend_execute_data *execute_data, zval *return_value, i } } - PSI_ContextCall(&PSI_G(context), &impl->decl->call, va); + psi_context_call(&PSI_G(context), &impl->decl->call, va); psi_do_return(return_value, impl->stmts->ret.list[0]); for (i = 0; i < impl->stmts->set.count; ++i) { @@ -565,7 +622,7 @@ ZEND_RESULT_CODE psi_callback(let_callback *cb, void *retval, unsigned argc, voi iarg->_zv = &return_value; zend_fcall_info_call(&iarg->val.zend.cb->fci, &iarg->val.zend.cb->fcc, iarg->_zv, NULL); - /* marshal return value of the userland call */ + /* marshal return value of the userland call switch (iarg->type->type) { case PSI_T_BOOL: zend_parse_arg_bool(iarg->_zv, &iarg->val.zend.bval, NULL, 0); break; case PSI_T_LONG: zend_parse_arg_long(iarg->_zv, &iarg->val.zend.lval, NULL, 0, 1); break; @@ -573,7 +630,9 @@ ZEND_RESULT_CODE psi_callback(let_callback *cb, void *retval, unsigned argc, voi case PSI_T_DOUBLE: zend_parse_arg_double(iarg->_zv, &iarg->val.dval, NULL, 0); break; case PSI_T_STRING: zend_parse_arg_str(iarg->_zv, &iarg->val.zend.str, 0); break; } - result = cb->func->handler(retval, decl_cb->func->type, iarg, &to_free); + */ + result = psi_let_func_ex(cb->func, retval, decl_cb->func->type, 0, &iarg->val, iarg->_zv, &to_free); + // result = cb->func->handler(retval, decl_cb->func->type, iarg, &to_free); if (result != retval) { *(void **)retval = result;